一、SIP支持的传输协议-UDP、TCP、TLS
SIP是一个应用层的会话协议,与一般协议不同的是,SIP协议可以同时支持各种传输协议。
SIP支持UDP传输:UDP是一个无连接的协议,且不提供可靠性。在UDP上建立SIP连接存在不可靠性。
SIP支持TCP传输:增加了SIP报文和语音传输的可靠性,通过TCP协议自身的特点为基于SIP的VoIP通信提供了面向连接和可靠的传输。SIP使用TCP传输协议后,SIP协议可以不需要考虑报文丢失和重传问题。
SIP支持TLS(Transport Layer Security,传输层安全)传输:SIP支持TCP传输仅仅保证了SIP报文和语音传输的可靠性,而SIP支持TLS传输则保证了SIP报文传输的安全性。
以上三种传输协议各具特点,用户可以根据实际的应用环境采用不同的传输协议。
sip:的缺省传输协议是 UDP;sips:的缺省传输协议是TCP。tcp默认5060,tcp+tls5061;tcps5061
TCP传输示例:
REGISTER sip:192.168.110.237:20101;transport=tcp SIP/2.0
Via: SIP/2.0/TCP 192.168.110.247:50250;rport;branch=z9hG4bKPjda05353a7a96446799361429235bc0e5;alias
Max-Forwards: 70
From: <sip:32100045@192.168.110.237>;tag=6c33309d840849cf89aeffac78fe505e
To: <sip:32100045@192.168.110.237>
Call-ID: 3548dbde40f943d2bdaf41d727049ffc
CSeq: 54023 REGISTER
Supported: outbound, path
Contact: <sip:32100045@192.168.110.247:50250;transport=TCP;ob>;reg-id=1;+sip.instance="<urn:uuid:00000000-0000-0000-0000-000041d7c640>"
Expires: 30
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Content-Length: 0
二、SIP选择传输协议
SIP支持多种传输协议,所以必须有一种管理它们的办法。
实现这一目标有两种方法。
第一种是通过SIP URI显式说明。
URI 描述中,transport=tcp或transport=sctp ( RFC 4168)的存在说明这个URI所选定的传输协议。注意:对于TLS传输来说,应当使用SIPS URI方案,虽然有些非标准的实现中会用transport=tls参数描述。如果有transport=udp就使用UDP。
第二种,URI中没有transport参数,那么采用以下规则决定传输协议:
- 如果URI中有数字IP地址,那么SIP URI应当使用UDP协议,SIPS URI使用TCP协议。
- 如果URI中没有数字地址,但有端口号,那么SIP URI应当使用UDP协议,SIPS URI使用TCP协议。
- Via中sent-by参数,具体参考下面via参数的具体说明。
三、Via和Contact参数
Via
Via该字段用于指示请求历经的路径。它可以防止请求消息传送产生环路,并确保响应和请求消息选择同样的路径,以保证通过防火墙或满足其它特定的选路要求。
发起请求的客户必须将其自身的主机名或网络地址插入请求的Via字段,如果未采用缺省端口号,还需插入此端口号。在请求前传过程中,每个代理服务器必须将其自身地址作为一个新的Via字段加在已有的Via字段之前。如果代理服务器收到一个请求,发现其自身地址位于Via头部中,则必须回送响应“检测到环路”。
格式:
Via=("Via"|"v")":" 1#(send-protocol send-by *(";" via-params)[comment])
via-params=via-hidden|via-ttl|via-maddr|via-received|via-branch|via-extension
via-hidden="hidden"
via-ttl="ttl" "="ttl
via-maddr="maddr" "="maddr
via-received="received" "="host[:port]
via-brance="branch" "="token
via-extension=token["="(token|quoted-string)]
send-protocol=protocol-bane"/"protocol-version"/"transport
protocol-name
参数说明:
transport:发送协议格式,协议名和协议版本的缺省值分别为SIP和UDP。
sent-by:发送方为通常的发送方主机和端口号。
via-hidden:隐藏参数就是关键词"hidden",如有此参数,表示该字段已由上游代理予以加密,以提供隐私服务。
via-ttl:生存期参数,格式 ttl=xxx。
via-maddr:多播地址参数,格式maddr=xxx。生存期参数与多播地址参数配用。
via-received:接收方标记,格式received=host[:port]。
via-branch:分支参数用于代理服务器并行分发请求时标记各个分支,当响应到达时,代理可判定是哪一分支的响应。
Contact
Contact通用头域可出现在INVITE、ACK和REGISTER请求中,1XX、2XX、3XX和485响应中。通常,它提供了一个URL,用户可以通过此URL来进行进一步的通信。INVITE和ACK请求:Contact域表明请求从哪个位置发起。Contact(m) 包含一个 SIP 或 SIPS URI,它表示联系 Alice 的直接路由,它由绝对域名称(FQDN)中的用户名组成。选用 FQDN 的时候,许多终端系统没有注册域名,因此允许 IP地址。
Via 头字段告诉其它元素向哪里发送响应,而 Contact 头字段告诉其它元素以后向哪里发送请求。
四、tcp在sip上实现
首先作为UAC和UAS和作为Proxy的概念上是不同的。那么那UAC来说,UAC需要主动连接UAS,即UAC通讯层打开一个连接。TCP使用长连接,并且不同事务共享这些连接。
UAC发送请求到UAS,UAS进行匹配处理;UAS处理完毕发送应答。理论上,UAS应该在通常的连接上发送应答,如果连接不存在,服务端需要创建一个连接来发送应答。如果存在”received”参数,就用对应的在”received”参数中指定的IP地址。如果存在”sent-by”参数,那么就用”sent-by”指定的port,如果不存在,那么就用缺省的port。