1. freeswitch中的sip架构

freeswitch的结构图如上,蓝色箭头是调用,绿色箭头是回调。最底层的是第三方库,一个sip协议栈,实现sip信令协议,构造sip当中的各个字段。核心层主要维护跟会话,通路相关的信息,它不依赖于sip,但是会被逻辑层用到。mod_sofia是一个端点模块,它可以理解为逻辑层,实现注册、呼叫等业务,它一方面跟sip协议栈交互,调用sip协议栈去发送信令,提供回调,用于接收信令、状态变化。另一方面,它也通过核心层,构建session和channel,并且还是通过设置回调,监控通道的状态改变。

  1. 注册信令流程

注册的信令交互比较简单,就四步:

  1. sip客户端代理UA先发送register注册请求;
  2. freeswitch检查还未认证,回复401表示未认证,同时生成一个认证摘要(WWW-Authenticate),一起发送给UA。认证机制原理,暂不研究。
  3. UA收到401后,根据自己的用户名和密码,以及认证摘要,生成认证信息,然后再次发起注册请求;
  4. freeswitch检查通过后,回复200OK,注册成功。
  1. register请求

    1. register信令

register表示这是一条注册消息;

via表示sip消息的路由,如果经过多个代理服务器转发,这里会有多条记录

from表示请求端地址

to表示目的端地址

call-id表示本次会话的标识

contact表示联系人信息

cseq表示消息序号

allow表示所支持的功能

max-forwards表示可以转发多少次,防止死循环,类似TTL

user-agent表示UA的型号

expires表示本次注册的有效期,单位为秒

content-length表示消息体长度,这里0表示没有后续消息体

  1. sofia协议栈

  1. 应用层mod_sofia

之前说过,sip协议栈通知应用是通过回调sofia_event_callback

  1. void sofia_event_callback(nua_event_t event,
  2. int status,
  3. char const *phrase,
  4. nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
  5. tagi_t tags[])
  6. {
  7. sofia_dispatch_event_t *de;
  8. //sip消息是一系列nua_开头的,nua_i表示Indications消息,还有一类nua_r表示Responses消息
  9. switch(event) {
  10. case nua_i_terminated:
  11. case nua_i_invite:
  12. case nua_i_register:
  13. case nua_i_options:
  14. case nua_i_notify:
  15. case nua_i_info:
  16. ...
  17. }
  18. //invite消息,则要创建session,同时也是创建channel
  19. if (event == nua_i_invite && !sofia_private) {
  20. session = switch_core_session_request_uuid(sofia_endpoint_interface,...);
  21. switch_core_session_thread_launch(session)
  22. }
  23. //最后把sip消息投入到消息队列mod_sofia_globals.msg_queue
  24. sofia_queue_message(de);
  25. }

这里虽然对消息有一些判断,但是没有具体去处理,只有invite这个消息,会去创建session,最后是投递到消息队列mod_sofia_globals.msg_queue 。

以前讲过,这个队列主要在消息线程sofia_msg_thread_run处理,不断地从队列取出消息,然后调用sofia_process_dispatch_event去处理,这个函数里面又调用our_sofia_event_callback。

  1. our_sofia_event_callback()
  2. {
  3. switch (event) {
  4. case nua_i_register:
  5. //nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(sip->sip_contact), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
  6. //nua_handle_destroy(nh);
  7. sofia_reg_handle_sip_i_register(nua, profile, nh, &sofia_private, sip, de, tags);
  8. break;
  9. ...
  10. }
  11. }

our_sofia_event_callback只是个事件分发器,每个消息对应一个处理函数,这里我们只关心register相关的,调用sofia_reg_handle_sip_i_register处理注册消息。这个函数在sofia_reg.c,该文件专门处理注册相关。

  1. void sofia_reg_handle_sip_i_register()
  2. {
  3. //处理一些特殊的情况,比如不允许注册,则回复403,调用nua_respond可以给客户端UA发送反馈。
  4. if (!(profile->mflags & MFLAG_REGISTER)) {
  5. nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
  6. goto end;
  7. }
  8. //正常流程进入到这个函数
  9. sofia_reg_handle_register_token();
  10. }

我们从协议包反推,这里应该在哪个地方判断没有认证,然后回复401,所以可以搜索SIP_401_UNAUTHORIZED,这个宏,可以找到三处,然后进行log跟踪,就可以知道在哪里判断未认证了。这里应该是判断有没有authorization字段,调用sofia_reg_auth_challenge,在该函数回复401。

这就是注册的第一阶段,收到register消息后,创建session,判断未认证,回复401。

  1. 回复01 unauthorized

    1. 401信令

status-code:服务器回复401表示未认证

WWW-Authenticate:服务端会生成认证摘要,一起发送给UA。

  1. 应用层mod_sofia
  1. void sofia_reg_auth_challenge(sofia_profile_t *profile, nua_handle_t *nh, sofia_dispatch_event_t *de,
  2. sofia_regtype_t regtype, const char *realm, int stale, long exptime)
  3. {
  4. switch_uuid_t uuid;
  5. char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
  6. char *sql, *auth_str;
  7. msg_t *msg = NULL;
  8. sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
  9. auth_str = switch_mprintf("Digest realm=\"%q\", nonce=\"%q\",%s algorithm=MD5, qop=\"auth\"", realm, uuid_str, stale ? " stale=true," : "");
  10. if (regtype == REG_REGISTER) {
  11. nua_respond(nh, SIP_401_UNAUTHORIZED, TAG_IF(msg, NUTAG_WITH_THIS_MSG(msg)), SIPTAG_WWW_AUTHENTICATE_STR(auth_str), TAG_END());
  12. else if (regtype == REG_INVITE) {
  13. nua_respond(nh, SIP_407_PROXY_AUTH_REQUIRED,
  14. TAG_IF(msg, NUTAG_WITH_THIS_MSG(msg)),
  15. SIPTAG_PROXY_AUTHENTICATE_STR(auth_str), TAG_END());
  16. }
  17. switch_safe_free(auth_str);
  18. }

这里除了回复401给客户端UA,还要插入数据表sip_authentication。

  1. 协议栈

  1. 带认证register

    1. 协议

UA收到401后,重新发起注册请求,并带上根据摘要和用户名、密码生成的认证信息。

    1. mod_sofia
  1. sofia_reg_handle_register_token()
  2. {
  3. authorization = sip->sip_authorization;
  4. if (authorization) {
  5. char *v_contact_str = NULL;
  6. const char *username = "unknown";
  7. const char *realm = reg_host;
  8. if ((auth_res = sofia_reg_parse_auth(profile, authorization, sip, de, sip->sip_request->rq_method_name,
  9. key, keylen, network_ip, network_port, v_event, exptime, regtype, to_user, &auth_params, ®_count, user_xml)) == AUTH_STALE) {
  10. stale = 1;
  11. if (auth_res != AUTH_OK && auth_res != AUTH_RENEWED && !stale) {
  12. if (auth_res == AUTH_FORBIDDEN) {
  13. nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
  14. forbidden = 1;
  15. else {
  16. nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
  17. }
  18. }
  19. nua_respond(nh, SIP_200_OK...)
  20. }

收到带认证的register消息,流程大体一样,只是到了这里对认证进行校验。认证成功后回复200OK。如果认证不通过,则回复403 forbidden。

freeswitch系列31注册流程相关推荐

  1. freeswitch系列四 通过实例学习sip协议的注册、呼叫、挂断流程

    1. 概述 本文通过tcpdump对真实环境里的软电话的注册.呼叫.挂断流程进行抓包,通过真实的例子学习SIP协议.本文主要包括以下方面: A. 详解软电话的注册时的SIP包和流程图 B. 详解软电话 ...

  2. openresty开发系列31--openresty执行流程

    openresty开发系列31--openresty执行流程 我们先看个例子 location /test {     set $a 32;     echo $a;     set $a 56;   ...

  3. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(17)-注册用户功能的细节处理(各种验证)...

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(17)-注册用户功能的细节处理(各种验证) ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框 ...

  4. 软件质量管理体系 type:pdf_昆明医疗器械软件注册流程,软件评估_上海峦灵

    首页 > 新闻中心 发布时间:2020-11-01 07:14:30 导读:上海峦灵为您提供昆明医疗器械软件注册流程,软件评估的相关知识与详情: (二投诉的事实不确凿.不充分或者与事实不符的;内 ...

  5. 零撸项目-Star Network注册流程

    大家好!我是面具少年,本次主要讲解 Star Network注册流程 Star Network. 本项目仅零撸,不建议投资,内容仅供参考. 具有支付功能的社交 DeFi(去中心化金融)网络,是未来的去 ...

  6. 基于GBT28181:SIP协议组件开发-----------第三篇SIP注册流程分析实现

    原创文章,引用请保证原文完整性,尊重作者劳动,原文地址http://www.cnblogs.com/qq1269122125/p/3941172.html,qq:1269122125. 上两章节简要的 ...

  7. 基于GBT28181:SIP协议组件开发-----------第四篇SIP注册流程eXosip2实现(一)

    原创文章,引用请保证原文完整性,尊重作者劳动,原文地址http://www.cnblogs.com/qq1269122125/p/3945294.html. 上章节讲解了利用自主开发的组件SIP组件l ...

  8. 目前互联网最详细的5G注册流程

    经过一个多月的详细分析<5G技术详解系列>的第一个课题:5G注册流程终于分析完成,不知道你有没有豁然开朗的感觉.我在分析的过程中也学到了很多,之前很多没注意到的细节,这次在整理成材料时也搞 ...

  9. 公司海外邮箱注册指南,外贸公司邮箱注册流程

    外贸公司邮箱,海外收发使用是必要的,展会.出差都需要一款兼具国际业务往来与高端品质的邮箱. 163vip.com是TOM的vip邮箱,五大套餐满足了不同人群对于群发.容量.账号名称.国际收发.邮件备份 ...

最新文章

  1. Emai乱码——解决的“迂回”战术
  2. 实现IFrame的自适应高度
  3. POJ - 1062 昂贵的聘礼
  4. NB模组基本AT指令
  5. 三种Cache写入方式原理简介
  6. [Matlab] 变量名与字符串的互相转换的正确方法
  7. CLR线程池的作用与原理浅析
  8. sql加上唯一索引后批量插入_MySQL批量插入遇上唯一索引避免方法
  9. 【爬虫】根据水文资料(水位/流量)爬取地理空间数据云遥感影像信息
  10. php实现分时线图,分时图均价线公式?看懂了便可掌握股票的买卖点
  11. Python 批量修改文件名称测试
  12. 计算机ps移动是什么键,ps快捷键都有哪些 移动工具V等
  13. 数据库第九章习题作业
  14. 产品策划流程体系、工具
  15. WPS之Excel表格如何设置下拉选项
  16. [NOI2017]蔬菜
  17. 招商头条:2018成都快递业中西部第一;合肥高新区30个项目签约125亿;芯盾时代完成3亿元融资
  18. Stacked DeBERT
  19. Android修改ro.debuggable 的四种方法
  20. Top 50 Most Popular APIs on RapidAPI (2018)

热门文章

  1. ios手机怎么连接adb命令_ios手机怎么连接adb命令_Mac连接Adb
  2. 健康菜谱微信小程序+项目前后台源码(JavaSSM+Mysql)
  3. CMake中file的使用
  4. Computer Vision—计算机视觉 (一)
  5. tomcat-命令窗口乱码
  6. 硬件工程师--医疗器械
  7. Autodesk的照片建模云服务—Autodesk ReCap 360 photo
  8. 工厂模式--简单工厂模式--抽象工厂模式
  9. lambda学习视频和stream学习视频(Java8 Lambda表达式视频教程)-Java爬虫-网络购物的正确打开方式
  10. 对于跳过Google应用SetupWizard.apk以及其他设备软件包名