所谓SIP服务器指的是接受SIP请求并对其作出响应的应用程序。SIP服务器不应与UAS或协议本身的client-server性质混淆,后者从客户端(请求发起方)和服务端(对请求生成应答一方)的操作角度进行描述。SIP服务器是另一种类型的实例,这里讨论的SIP服务器是逻辑实体。实际的SIP服务器实现可以包含多种服务器类型,或者在不同条件下有不同操作充当不同的服务实体。因为服务器对UA提供服务和特性,所以它们必须同时支持TCP和UDP传输。下图显示了UA、服务器和定位服务间的交互关系。注意:SIP服务器与定位服务或数据库间使用的协议通常不是SIP,这里不做讨论。

                   SIP UA、服务器与定位服务间的交互

 

代理服务器

.        SIP代理服务器(PROXY)接收UA或其它代理的请求,并为UA转发请求和应答消息。就像路由器在IP层转发IP数据包那样,SIP代理在应用层转发SIP消息。代理不是B2BUA,因为它只允许根据RFC 3261定义的严格路由规则修改请求和应答消息。这些规则保留了SIP信令的端到端透明性,同时允许代理服务器为UA执行有价值的服务和功能。

        代理服务器通常会访问数据库或定位服务,以帮助它处理请求(决定下一跳地址)。SIP协议没有定义代理与定位服务之间的接口。代理可以借助数据库来处理请求。数据库可以存储SIP的注册信息,状态呈现信息,或其它有助于定位用户位置的信息。

        代理不一定要理解SIP请求才能转发消息,任何未知请求都视为非INVITE事务,并按其处理模型执行。代理不应改变头域的顺序,一般情况下也不应该修改或删除头域。

代理服务器与UA或网关的不同体现在以下三点:

  •  代理本身不发起请求,它只响应UA的请求(CANCEL与ACK请求是这条规则的特例)。
  •  代理服务器没有媒体能力。
  •  代理服务器不解析消息包体,它只依赖于几个特定的SIP头域。

        下图展示了常见的SIP网络拓扑,我们称它为SIP梯形。在这个拓扑中,两个不同域中的一对UA通过他们各自所属域的代理服务器建立会话。梯形是指信令和媒体消息所组成的形状。在这个配置中,每个UA都配置自己的默认出局代理服务器,并通过它转发所有请求。代理服务器通常会对UA进行身份验证,并可以提取用户的配置文件,并适配出局路由服务。在域间交换过程中,用DNS SRV查询来确定外域代理服务器所处的位置。这个代理有时称作入局代理,它为被叫方提供入局路由服务。入局代理会访问当前注册信息,并能够把请求路由给被叫方。一般情况下,后续的SIP请求可以直接在两个UA间交换,除非代理服务器插入了Record-Route头域。

                                        SIP梯形

        代理服务器可以是无状态的,也可以是有状态的。无状态代理服务器仅根据消息内容处理每个SIP请求或应答消息。一旦消息被解析,处理,转发或应答之后,不存任何储消息相关的信息(比如说dialog信息)。无状态代理服务器不重传消息,不使用任何SIP定时器。注意:RFC2543中描述的使用Via头域进行无状态环回监测的机制,在RFC 3261中已经被废弃,RFC3261中强制要求所有请求消息携带Max-Forwards头域。

        有状态代理服务器跟踪记录过去收到的请求和应答,并利用这些信息处理后续请求和应答。比如说,有状态代理服务器转发请求时启动一个定时器。如果定时器触发时没有收到应答,那么代理重发请求,减轻这个任务发起UA的压力。此外,有状态代理可以对UA进行鉴权。

        最常见的SIP代理类型是事务状态代理。代理服务器只保留一个事务的状态,但仅限于事务挂起请求期间。比如说:事务状态代理收到INVITE请求时保留其状态,直到收到200 OK或失败的最终应答(比如说404 Not Found)。在此之后,它将销毁相关状态信息。这将有助于代理服务器执行有效的搜索服务,但同时把状态存储量降到最低。

         ​​​​​​搜索服务的一个典型实例是代理服务器收到INVITE请求后,同时转发给多个位置,或者分支处理请求。这种分支代理服务器跟踪每个出局的请求和对应的应答。如果定位服务或数据库查询返回多个可能位置,需要挨个尝试连接被叫,这种机制是是非常有帮助的。

下图的INVITE消息包含:

INVITE sip:support@chaos.example.org SIP/2.0

Via: SIP/2.0/UDP 45.2.32.1:5060 ;branch=z9hG4bK67865

Max-Forwards: 70

To: <sip:support@chaos.example.org>

From: A. N. Sarkovskii <sip:sarkovskii@45.2.32.1>;tag=7643545

Call-ID: 0140092501

CSeq: 1 INVITE

Subject: Bifurcation Question

Contact: <sip:sarkovskii@45.2.32.1>

Content-Type: application/sdp

Content-Length: ...

(SDP not shown)

                                           分支代理操作

 

           代理服务器收到INVITE之后,分裂出两个分支,发给两个不同的UA。两个UA开始振铃,并向Sarkovskii发回两个临时响应消息。它们是:

SIP/2.0 180 Ringing

Via: SIP/2.0/UDP 45.2.32.1:5060;branch=z9hG4bK67865

To: <sip:support@chaos.example.org>;tag=343214112

From: A. N. Sarkovskii <sip:sarkovskii@45.2.32.1>;tag=7643545

Call-ID: 0140092501

CSeq: 1 INVITE

Contact: <sip:agent42@67.42.2.1>

Content-Length: 0

和:

SIP/2.0 180 Ringing

Via: SIP/2.0/UDP 45.2.32.1:5060;branch=z9hG4bK67865

To: <sip:support@chaos.example.org>;tag=a5ff34d9ee201

From: A. N. Sarkovskii <sip:sarkovskii@45.2.32.1>;tag=7643545

Call-ID: 0140092501

CSeq: 1 INVITE Contact: <sip:agent7@67.42.2.32>

Content-Length: 0

这两个应答大体上内容是相同的,只是To tag和Contact URI有所不同。最后,其中一个UA摘机,发回200 OK应答。

 

SIP/2.0 200 OK

Via: SIP/2.0/UDP 45.2.32.1:5060;branch=z9hG4bK67865

To: <sip:support@chaos.example.org>;tag=343214112

From: A. N. Sarkovskii <sip:sarkovskii@45.2.32.1>;tag=7643545

Call-ID: 0140092501

CSeq: 1 INVITE Contact: <sip:agent42@67.42.2.1>

Content-Type: application/sdp

Content-Length: ...

(SDP not shown)

        因为有其它分支存在,所以代理向另一个UA发一条CANCEL消息来终止电话的振铃。如果两个终端都摘机应答,那么代理应当把两条200 OK消息都转发给主叫方,由主叫方来决策,通常是接受其中一个,对另一个发BYE。

        有状态代理收到INVITE时,通常会先回应一条100 Trying消息。无状态代理永远不会主动发100 Trying应答。此外,代理永远不会转发收到的100 Trying应答,它是一种单跳响应。处理TCP请求的代理必须是有状态的,因为UA认为自己使用的是可靠传输,那么后续信令路径如果有UDP节点,那么代理就必须负责信令的重传。

        信令路径中代理的数量只受Max-Forwards头域的限制,每经过一个代理,这个头域的值都会递减。如果Max-Forwards计数器减到零,那么代理把消息丢弃,同时向发起方回一条483 Too Many Hops消息。

        SIP会话定时器扩展限制了有状态代理必须维护状态信息而无需刷新re-INVITE的时间段。在初始INVITE请求中,如果携带Session-Expires头域,那么代理可以据此启动一个定时器,超时之后可以丢弃这个会话相关的信息。UA必须在定时器超时后终止通话。主叫方可以发re-INVITE消息来刷新定时器,为SIP启用一种“保活”机制。这个机制解决了BYE请求丢失或其它安全场景下状态信息应该维护多长时间的问题。

重定向服务器

        重定向服务器不会转发收到的请求,而是直接对请求作出应答。和代理服务器一样,重定向服务器利用数据库或定位服务来查找用户位置。然而,被叫的位置信息直接在重定向类应答(3XX)中回传给主叫方,在ACK之后,事务结束。下图的呼叫流程和之前的代理交换流程很相似,不同的是服务器返回重定向信息而不是代理转发请求,最终帮助Schrodinger定位Heisenberg的位置。

INVITE消息:

INVITE sip:werner.heisenberg@munich.de.example.org SIP/2.0

Via: SIP/2.0/UDP 100.101.102.103:5060 ;branch=z9hG4bK54532

Max-Forwards: 70

To: Heisenberg <sip:werner.heisenberg@munich.de.example.org>

From: E. Schrodinger <sip:schroed5244@wave.example.org>;tag=4313413

Call-ID: 734224912341371927319032

CSeq: 1 INVITE

Subject: Where are you exactly?

Contact: <sip:schroed5244@pc33.wave.example.org>

Content-Type: application/sdp

Content-Length: 150

v=0

o=schroed5244 2890844526 2890844526 IN IP4 100.101.102.103

s=

t=0 0

c=IN IP4 100.101.102.103

m=audio 49172 RTP/AVP 0

a=rtpmap:0 PCMU/8000

                             重定向服务流程

重定向服务器对INVITE消息的应答:

SIP/2.0 302 Moved Temporarily

Via: SIP/2.0/UDP 100.101.102.103:5060;branch=z9hG4bK54532

To: Heisenberg <sip:werner.heisenberg@munich.de.example.org>;tag=052500

From: E. Schrodinger <sip:schroed5244@wave.example.org>;tag=4313413

Call-ID: 734224912341371927319032

CSeq: 1 INVITE

Contact: sip:werner.heisenberg@200.201.202.203

Content-Length: 0

Schrodinger 确认收到应答:

ACK sip:werner.heisenberg@munich.de.example.org SIP/2.0

Via: SIP/2.0/UDP 100.101.102.103:5060;branch=z9hG4bK54532

Max-Forwards: 70

To: Heisenberg <sip:werner.heisenberg@munich.de.example.org>;tag=052500

From: E. Schrodinger <sip:schroed5244@wave.example.org>;tag=4313413

Call-ID: 734224912341371927319032

CSeq: 1 ACK

Content-Length: 0

        需要注意的是ACK请求中的branch ID和INVITE及302消息中的是相同的。这是因为对非2XX最终应答回应的ACK消息,被视为INVITE事务的组成部分。只有对200 OK消息的确认ACK请求才视为一个新的事务,携带新的branch ID以保证唯一性。同样的,对非2XX最终应答的ACK是跳到跳的消息,不是端到端的。

        以上消息交换结束呼叫尝试,之后,UAC生成一条新的INVITE消息,携带新的Call-ID,直接发送给Heisenberg。Heisenberg的位置信息来自上一次交换重定向服务器返回的302应答中的Contact头域。

 

INVITE sip:werner.heisenberg@200.201.202.203 SIP/2.0

Via: SIP/2.0/UDP 100.101.102.103:5060;branch=z9hG4bK92313

Max-Forwards: 70

To: Heisenberg <sip:werner.heisenberg@munich.de.example.org>

From: E. Schrodinger <sip:schroed5244@wave.example.org>;tag=13473

Call-ID: 54-67-45-23-13

CSeq: 1 INVITE Subject: Where are you exactly?

Contact: <sip:schroed5244@pc33.wave.example.org>

Content-Type: application/sdp Content-Length: 150

v=0

o=schroed5244 2890844526 2890844526 IN IP4 100.101.102.103

s=

t=0 0

c=IN IP4 100.101.102.103

m=audio 49172 RTP/AVP 0

a=rtpmap:0 PCMU/8000

        需要注意的是:上面流程中,没有发送180 Ringing消息,而是直接回应200 OK。由于1xx信息响应是可选的,如果Heisenberg的UAS自动摘机,那么这个应答是完全有效的。在PSTN中,这种场景称为快速应答。

注册服务器

        注册服务器只接受REGISTER请求,对其它方法直接回应501 Not Implemented response。然后,请求中的联系信息被提取出来,共享给同一管理域中的其它SIP服务器,比如说代理和重定向服务器。在注册请求中,To头域包含待注册资源的名称,Contact头域包含联系信息或设备的URI。注册服务器在To头域的地址记录(AOR) URI与Contact头域的设备URI之间建立一个临时的映射关系。

        注册服务器通常要求对注册UA进行鉴权,未授权用户不处理来电。(如果没有鉴权)未授权用户就能够注册其他人的SIP URI,让它指向自己的UA可以实现劫持。呼叫这个URI的来电将会转到错误的UA。根据现有的头域,UA可以使用REGISTER请求来检索当前的注册列表、清除所有注册信息,或向注册表添加新的URI。

         代理有很多种方式可以知道需要把请求分支给一组UA。一种是通过手工配置,比如通过Web页面或数据库输入信息。另一种方式是允许同一个AOR重复注册。如果多个UA注册同一AOR,那么代理可以把入局请求分发给所有注册的设备。多个注册的优先级由Contact头域中的q值控制。如果优先级相同,代理可以同时把请求分发给它们,构成并行分支。对于优先级不同的UA,代理可以根据q值串行处理,按顺序处理分支。

        要保证注册的完全安全,就必须使用TLS,因为HTTP摘要不提供所需的完整性保护。否则,攻击者可以修改通过授权的REGISTER请求中的Contact URI,让它指向另一个UA

更多推荐