`
zhengweizhong
  • 浏览: 73691 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

SIP路由机制解析(zz)

    博客分类:
  • IMS
阅读更多

在前面已经陆续介绍了SIP重要头域、注册流程、会话流程等SIP相关知识,现在再来介绍一下SIP中的路由机制。

总的来说,SIP中存在两种路由场景:
1,请求消息的路由
2,响应消息的路由

其中,响应消息的路由非常简单,就是完全依靠Via来完成的,具体请见我关于RFC3261中会话流程的分析。
下面我们只谈SIP请求消息的路由。

首先我们要搞清楚什么是严格路由和松散路由。

 

 

 

 

 

 


严格路由(Strict Routing):
可以理解为比较“死板”的理由机制,这种路由机制在SIP协议的前身RFC 2534中定义,其机制非常简单。
要求接收到的消息的request-URI必须是自己的URI,然后它会把第一个Route头域“弹”出来,并把其中的URI作为新的request-RUI,然后把该消息路由给该URI。

松散路由(Louse Routing,lr):
该路由机制较为灵活,也是SIP路由机制的灵魂所在,在SIP根本大典RFC 3261中定义。
下面介绍一下一个松散路由的Proxy的路由决策过程:

1,Proxy首先会检查消息的request-URI是不是自己属于自己所负责的域。如果是,它就会通过定位服务将该地址“翻译”成具体的联系地址并以此替换掉原来的request-URI;否则,它不会动request-URI。

2,Proxy检查第一个Route头域中的URI是不是自己的,如果是,则移除之。

3,前面两项都是准备工作,下面该进行真正的路由了。如果还有Route头域,则Proxy会把消息路由给该头域中的URI,否则就路由给request-URI。至于如何从下一跳URI确定出IP地址,端口以及传输协议那是另外一回事了。

对于前面的3条规则,我们可以简单总结为一句话:Route的优先级高于request-URI的。

好,了解了两种路由机制,我们再来了解一下Route和Record-Route。
如果说Via是为了给一个请求消息的响应消息留后路,那么Record-Route就是为了给该请求消息之后的请求消息留后路。
【说明】一个SIP消息每经过一个Proxy(包括主叫),都会被加上一个Via头域,当消息到达被叫后,Via头域就记录了请求消息经过的完整路径。被叫将这些Via头域原样copy到响应消息中(包括各Via的参数,以及各Via的顺序),然后下发给第一个Via中的URI,每个Proxy转发响应消息前都会把第一个Via(也就是它自己添加的Via)删除,然后将消息转发给新的第一个Via中的URI,直到消息到达主叫。

    而在一个请求消息的传输过程中,Proxy也可能(纯粹自愿,如果它希望还能接收到本次会话的后续请求消息的话)会添加一个Record-Route头域,这样当消息到达被叫后里面就有会有0个或若干个Record-Route头域。被叫会将这些Record-Route头域并入路由集,并并入自己的路由集,随后被叫在发送请求消息时就会使用该路由集构造一系列Route头域,以便对消息进行路由。
    然后,被叫会像上面对待Via头域一样,将Record-Route头域全部原样copy到响应消息中返回给主叫。
    主叫收到响应消息后也会将这些Record-Route头域并入路由集,只是它会将其反序。该会话中的后续请求消息的Route头域就会通过路由集构造。
【注意】Record-Route头域不用来路由,而只是起到传递信息的作用。
Record-Route头域不是路由集的唯一来源,路由集还可以通过手工配置等方式得到。


只是描述还是比较抽象,下面就以RFC 3261中的两个实例来解释一下。

路由示例1:

场景:
两个UE间有两个Proxy,U1 -> P1 -> P2 -> U2,并且两个Proxy都乐意添加Record-Route头域。

消息流:
【说明】由于我们在此只关心SIP路由机制,因此下面消息中跟路由机制无关的头域都省略了。

U1发出一个INVITE请求给P1(P1是U1的外拨代理服务器):
      INVITE sip:callee@domain.com SIP/2.0
      Contact: sip:caller@u1.example.com

P1不负责域domain.com,消息中也没有Route头域,因此通过DNS查询得到负责该域的Proxy的地址并且把消息转发过去。这里P1在转发前就添加了一个Record-Route头域,里面有一个lr参数,说明P1是一个松散路由器,遵循RFC3261中的路由机制。
      INVITE sip:callee@domain.com SIP/2.0
      Contact: sip:caller@u1.example.com
      Record-Route: <sip:p1.example.com;lr>
P2负责域domain.com,因此它通过定位服务得到callee@domain.com 对应的设备地址是callee@u2.domain.com ,因此用新的URI重写request-URI。消息中没有Route头域,因此它就把该消息转发给request-URI中的URI,转发前它也增加了一个Record-Route头域,并且也有lr参数。
      INVITE sip:callee@u2.domain.com SIP/2.0
      Contact: sip:caller@u1.example.com
      Record-Route: <sip:p2.domain.com;lr>
      Record-Route: <sip:p1.example.com;lr>
位于u2.domain.com的被叫收到了该INVITE消息,并且返回一个200 OK响应。其中就包括了INVITE中的Record-Route头域。
      SIP/2.0 200 OK
      Contact: sip:callee@u2.domain.com
      Record-Route: <sip:p2.domain.com;lr>
      Record-Route: <sip:p1.example.com;lr>
被叫此时也就有了自己的路由集:
      (<sip:p2.domain.com;lr>,<sip:p1.example.com;lr>)

并且它本次会话的远端目的地址设置为INVITE中Contact中的URI:caller@u1.example.com,此后被叫在该会话中的请求消息就发到这个URI。同样,被叫在200 OK响应中也携带了自己的联系地址,主叫收到该响应消息后也会把本次会话的远端目的地址设置为:callee@u2.domain.com,此后主机在该会话中的请求消息就发到这个URI。
同样,主叫也有了自己的路由集,只是跟被叫的是反序的:
      (<sip:p1.example.com;lr>,<sip:p2.domain.com;lr>)


通话完毕后,我们架设主叫先挂机,则主叫发出BYE请求:
      BYE sip:callee@u2.domain.com SIP/2.0
      Route: <sip:p1.example.com;lr>,<sip:p2.domain.com;lr>
可以看到,BYE的Route头域正是主机的路由集构造来的。
由于p1在第一个Route中,因此BYE首先发给P1。

P1收到该消息后,发现request-URI中的URI不属于自己负责的域,而消息有Route头域,并且第一个Route头域中的URI正是自己,因此删除之,并且把消息转发给新的第一个Route头域中的URI,也就是P2:
      BYE sip:callee@u2.domain.com SIP/2.0
      Route: <sip:p2.domain.com;lr>
P2收到该消息后,发现request-URI中的URI不属于自己负责的域(P2负责的是domain.com,而不是u2.domain.com),第一个Route头域中的URI正是自己,因此删除之,此时已经没有Route头域了,因此就转发给了request-URI中的URI。

被叫就会收到BYE消息:
      BYE sip:callee@u2.domain.com SIP/2.0

路由示例2:
如果说上面的示例主要关注的是路由流程,那么本示例关注的则是严格路由与松散路由的区别。

场景:
U1->P1->P2->P3->P4->U2
其中,P3是严格路由的,其余Proxy都是松散路由的,并且4个Proxy都很乐意增加Record-Route头域。

消息流:
我们直接给出了到达被叫的INVITE消息:
      INVITE sip:callee@u2.domain.com SIP/2.0
      Contact: sip:caller@u1.example.com
      Record-Route: <sip:p4.domain.com;lr>
      Record-Route: <sip:p3.middle.com>
      Record-Route: <sip:p2.example.com;lr>
      Record-Route: <sip:p1.example.com;lr>

这中间的其他消息我们就不过问了,直接看一下被叫最后发出的BYE消息大概是什么样子:
      BYE sip:caller@u1.example.com SIP/2.0
      Route: <sip:p4.domain.com;lr>
      Route: <sip:p3.middle.com>
      Route: <sip:p2.example.com;lr>
      Route: <sip:p1.example.com;lr>

因为P4在第一个Route里,因此被叫将BYE消息发给了P4。

P4收到该消息后,发现自己不负责域u1.example.com,但是第一个Route头域中的URI正是自己,因此删除之。P4还发现新的第一个Route头域中的URI是一个严格路由器,因此它把request-URI中的URI添加到最后一个Route的位置,并且将第一个Route“弹出”并且覆盖原来的request-URI。然后将消息转发给当前的request-URI,也就是P3。
      BYE sip:p3.middle.com SIP/2.0
      Route: <sip:p2.example.com;lr>
      Route: <sip:p1.example.com;lr>
      Route: <sip:caller@u1.example.com>

P3收到该消息后,直接把消息作出如下变换并且发给P2:
      BYE sip:p2.example.com;lr SIP/2.0
      Route: <sip:p1.example.com;lr>
      Route: <sip:caller@u1.example.com>
P2收到该消息后,发现消息中的request-URI是自己的,因此在进一步处理先首先对消息做如下变换:
      BYE sip:caller@u1.example.com SIP/2.0
      Route: <sip:p1.example.com;lr>
然后,P2发现自己不负责域u1.example.com,第一个Route中的URI也不是自己的,因此将消息转发给该URI,也就是P1。

P1收到该消息后,发现自己不负责域u1.example.com,但是第一个Route头域中的URI正是自己,因此删除之。消息变成下面的样子:
      BYE sip:caller@u1.example.com SIP/2.0
既然Route头域已经是空,因此P1把消息发给u1.example.com。

 

 

我们经常可以看到在Router字段中设置的SIP URI经常有一个lr的属性,例如<sip:a.b.c.d;lr>,这就是表示这个地址所在的Proxy Server是一个Loose Router,如果没有lr属性,它就是一个Strict Router。

Loose Router实际上表示Proxy Server根据的是RFC3261处理Route字段的规则,而Strict Router表示Proxy Server根据的是RFC2357处理Route字段的规则。Strict Router要求SIP消息的Request URI为其自身的地址。

1、Loose Router和Strict Router首先都会检查Router字段的第一个地址是否为自己,如果是则从Router字段中删除自己。

2、Strict Router在发往下一跳时将使用Router字段中的下一跳地址更新Request URI。

3、Loose Router首先会检查Request URI是否为自己:如果不是,则不作处理;如果是,则取出Route字段的最后一个地址作为Request URI地址,并从Route字段中删去最后一个地址。

4、Loose Router其次会检查下一跳是否为Strict Router:如果不是,则不作处理;如果是,则将Request URI添加为Route的最后一个字段,并用下一跳Strict Router的地址更新Request URI。

可以看到步骤3、4其实是Loose Router为了兼容Strict Router而做的额外工作。


IMS中的说明:
        需要指出一点,标题“IMS中松散路由(Loose Router)和严格路由(Strict Router)”建议改为“SIP中对松散路由(Loose Router)和严格路由(Strict Router)的处理 ”。楼主所说的是RFC3261中的内容。该RFC定义了SIP基本协议,而不是IMS的协议。

而对IMS而言,3GPP要求该系统中都是松散路由。详见3GPP TS24.229 v730第4.3节。当然,对那些要与非IMS网络设备打交道的IMS网元,如I-CSCF、IBCF、S-CSCF、E-CSCF,也要提供对松散路由的支持。

 

 

对RFC 3665上的3.2的例子的个人理解:
1>sip中二个端点的应用route的形成是通过proxy在处理的过程中,通过Record-Route记录来形成的,并且在200Ok后,Alice 进行ACk的时候,已经将Record-Route的记录转化到route域了。
2>Bob在第一个invite到达的时候,形成了route;Alice Alice在从Bob返回的第一个请求中学习到了路由,这里是180
3>Via字段主要用来Proxy Server使用,从RFC 3261中可以看到,主要是为了Proxy标识事务ID,还有其他的一些东西

 

 

 

 

1. SIP消息头部主要字段:

·         Request-URIRequest消息的第一行中method后面紧跟的部分就是Request-URI(本例中的sip:bob@biloxi.com)。该值在消息经过Proxy之后就有可能发生变化,变成消息路径中Next Hop的URI。

·         To包含的是最终用户的Public address,消息无论被Proxy多少次该值都不会改变。当最终用户开始回应第一个Response消息时(比如本例中的180 Ring)会在To中加上本地唯一的一个tag值。

·         From包含Request消息发起者的URI,也不会被Proxy改变;在生成Reqeust消息时就会在后面加上一个本地唯一的tag值。

·         Call-Id用来标识一个唯一的Session,整个Session期间的所有消息的Session-Id都是相同的。

·         Max-Forwards消息可被转发的最大次数,每经过一个Proxy,该值就会被减一。

·         CSeq该属性由一个整数和一个method名字两部分组成;整数部分的作用是用来对同一个Session中的Request消息进行排序的;从第一个Invite消息发出后,随后的所有Request消息(ACK和Cancel除外)中的CSeq值都依次加一。比如Alice与Bob的通话过程中Alice想修改会话的一些属性,于是她便发起第二个Invite消息,这个Invite消息中的CSeq就需要加一;在比如Alice给Bob发送了一个Invite消息,而Bob发回的200 OK发生延时,于是Alice又发送第二个Invite消息,此时对第一个Invite消息的200 OK到达,Alice根据200 OK中的CSeq便可以知道这是对第一个Invite消息的应答。Request消息Cancel和Ack中的CSeq和与之对应的Invite消息中的CSeq值是一致的。

·         Via该属性记录了消息的路由。Request消息被生成的时候只有一个Via,那就是本地的URI,此后消息每经过一个Proxy,Proxy都会在消息中插入一个Via记录下自己的URI。当最终用户发挥Response消息时,会从Request消息中拷贝所有的Via,然后按照反序进行路由,每经过一个Proxy,该Proxy就会将包含自己URI的Via删除,这样当Response消息最终到达Request发起端的时候就只剩下一个Via了。

·         Contact该属性包含了用户可以被直接找到的一个URI,Request发起方会在Request消息中加入该值,接收方会在第一个Response(该例中的180 Ring)中加入该值。利用这个URI,此后再发起Request消息时就直接发送到对方了,而无需经过Proxy,比如本例中的F12 ACK消息,由于之前通过交换Contact值,Alice知道如何能直接找到Bob,于是在第一行的SIP-URI中填上Bob所提供的Contact值,将ACK消息直接发送给Bob而无需经过Proxy,注意To中仍然是原先的值。

·         Route and Record-Route这两个属性都是有Proxy加入的;上面提到Contact属性可以让随后的Reqeust消息绕过Proxy而直接发给最终用户。有时候处于安全或者其他方面的原因,Proxy希望所有的消息都必须经过Proxy,那么这时候Proxy就需要在经过它的第一个Request消息中插入该属性记录自己的URI,这样此后的Request消息就必须按照该属性中指定的路径路由。

 

2. 对以上几个头部属性简单概括一下:

·         SIP-URI是一个Hop-to-Hop的属性,所以有可能被Proxy改变;

·         From和To属性在消息的路由过程中一直保持不变;它们在Request消息中确定,此后对端发来的所有Response消息的From和To都是原样拷贝Request消息中的From和To;

 

·         Via是用来帮助Response消息进行路由的,Contact是用来供随后的Request消息进行路由的

分享到:
评论

相关推荐

    Toxi / Oxy Pro 便携式气体检测仪参考手册 使用说明书

    Toxi Oxy Pro 便携式气体检测仪参考手册 使用说明书

    科傻模拟网优化操作-教程书

    官方的的说明书资料,部分视频说明在这里: https://www.bilibili.com/video/BV1Fz4y1d7rn/?spm_id_from=333.999.0.0&vd_source=13dc65dbb4ac9127d9af36e7b281220e

    node-v8.14.0-x64.msi

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    2023商业银行数据资产体系白皮书,主要介绍了“三位一体”数据资产体系的构成与工作机制,以及商业银行数据资产体系建设实践

    2023商业银行数据资产体系白皮书 目录 第 1 章 数据资产化与数据要素市场化相辅相成,相互促进 第 2 章 数据资产化是企业数据治理向上演进的必经之路 第 3 章 数据资产体系发展概述 第 4 章 “三位一体”数据资产体系的构思 4.1“三位一体”数据资产体系的构成与工作机制 数据资产管理 数据资产运营 数据资产评价 数据资产体系工作机制 4.2“三位一体”数据资产体系的相互作用关系 4.3“三位一体”数据资产体系的构建 4.4“三位一体”数据资产体系的优势 第 5 章 商业银行数据资产体系建设实践 5.1商业银行开展数据资产体系建设的背景和目标 5.2商业银行数据资产体系建设的工作步骤 5.3上海银行数据资产体系建设实践的主要成果 第 6 章 数据要素流通市场赋能企业数据资产化 6.1全国多层次数据要素市场的建设 6.2上海数据交易所赋能企业数据资产化 6.3数据要素流通交易市场赋能企业数据资产化的展望 第 7 章 未来演进与展望

    基于微信小程序的助农扶贫小程序

    大学生毕业设计、大学生课程设计作业

    车辆销售数据Python爬取并做数据分析,项目源码注解清晰一看就懂.zip

    车辆销售数据Python爬取并做数据分析,项目源码注解清晰一看就懂

    毕业设计:基于SSM的mysql-学生社团管理系统(源码 + 数据库 + 说明文档)

    毕业设计:基于SSM的mysql_学生社团管理系统(源码 + 数据库 + 说明文档) 第2章 主要技术和工具介绍 1 2.1 JSP语言 1 2.2 MySQL数据库 1 2.3 jsp技术 2 2.4ssm简介 3 第3章 系统分析 1 3.1可行性分析 1 3.1.1经济可行性 1 3.1.2技术可行性 1 3.1.3操作可行性 1 3.2需求分析 1 3.3业务流程分析 2 3.4数据流程分析 3 第4章 系统设计 5 4.1系统结构设计 5 4.2功能模块设计 5 4.3数据库设计 6 4.3.1数据库设计概述 6 4.3.1概念设计 6 4.3.2表设计 7 第5章 系统实现 15 5.1基本任务 15 5.2登录模块的实现 15 5.2.1首页实现 15 5.2.2管理员后台登录 16 5.3用户模块的实现 19 5.3.1注册模块及登录的实现 19 5.2.2入团模块的实现 21 5.2.3场地预约模块的实现 22 5.4管理员模块的实现 24 5.4.1系统用户管理模块的实现 24 5.4.2活动公告管理模块的实现 26 5.5社团模块的实现 28 5.5.1活动信息

    大健康零售业务O2O数字化战略规划方案.pptx

    大健康零售业务O2O数字化战略规划方案.pptx

    数据中台项目主要岗位及其职责和任务

    数据中台项目主要岗位及其职责和任务

    node-v8.0.0-linux-armv7l.tar.gz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    流程制造行业数字化智能工厂总体规划建设方案.pptx

    流程制造行业数字化智能工厂总体规划建设方案.pptx

    c语言学生成绩管理系统源码.zip

    c语言学生成绩管理系统源码.zip

    DEV-C++-5.11下载链接

    DEV-C++-5.11下载链接

    电器租赁小程序.zip

    电器租赁小程序.zip

    学生成绩管理系统 数据结构与算法课程设计 C++.zip

    学生成绩管理系统 数据结构与算法课程设计 C++

    知乎小程序算法.zip

    知乎小程序算法.zip

    基于R语言SIR传染病传播的SIR模型,很全,可直接应用仿真模拟.rar

    基于R语言SIR传染病传播的SIR模型,很全,可直接应用仿真模拟.rar

    node-v6.13.0.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v10.11.0-darwin-x64.tar.gz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    项目申报系统(Struts2+Spring+Hibernate+Jsp+Mysql5).zip

    广东工业大学工程管理

Global site tag (gtag.js) - Google Analytics