SIP协议的传输层原理(解读RFC3263)

一,SIP协议简述

参加https://blog.csdn.net/qiuchangyong/article/details/50748854

简单说,就是我想给你打电话,我俩怎么建立这个对话连接,于是SIP协议就是用来约定这个行为的

 

二:RFC中的关键术语的解析

1,UAC/UAS/UA

UAC:User Agent Client用户代理客户端

UAS:User Agent Server用户代理服务端

UA:A logical entity that can act as both a user agent client and user agent server.

水鬼:何为User,我们都是用户,我们如果想要打电话怎么利用SIP协议建立连接呢?当然要有个小程序,所以这个小程序就是UA, 在建立连接的时候总有一个人是发起者,那么他就扮演了Client的角色,被访问的就是服务端

           所以UA是实体,而UAC和UAS表示的是扮演的角色

2, TU:Transaction User

SIP协议的工作方式是以事物为单位的,一旦一个人想要打电话,要经历拨号,连接,应答等,中间有多次交互,这样一整套交互就是一个事物。

事物在工作过程中就是调用传输层的协议为我发数据,所以这个TU就是位于传输层的上层,在SIP协议中扮演了和传输层打交道的那个。

这个用户包含如下三个核心(core): UAC core, UAS core, and proxy core.

这些core其实是代码层面的概念,因为要实现sip协议,肯定要为不同的功能编写函数,于是

UAC core:对于UA在行使其作为client的角色时,需要实现的功能函数

UAS core:server的角色

proxy core: 针对其proxy的功能的实现,何为proxy,类似与移动联通,我给小名打电话,中间肯定有很多proxy帮我们转发

 

三,客户端UAC的行为特点(或者是实现的要求)

1,有关状态机

我要打电话了,我首先会发送INVITE请求,在发送前,TU首先会创建一个事物,初始状态为“calling”,然后发请求,如何发?

1)如果是基于不可靠的连接,他会先起一个定时器A,时常为T1,然后发请求,如果T1时间内没有收到应答,则重发,此时定时器设置为2T1,再之后为double上一次的时间,但最长不能长于定时器B(64个T1)

2)如果是基于可靠的连接,没有定时器A,但有定时器B,因为是基于连接的,所以不怕收不到应答,但是一旦收不到,B时间到了,一样完蛋

 

2,有关连接(connection)

对于使用TCP,SCTP,或者TLS协议的,都是基于连接的,所以再进行传输之前,首先要建立连接。

对于传输层来说,需要管理这些连接,无论是自己主动发起的还是被动连接的,当然这个连接是双方一起建立的,所以对于这些连接信息,sip协议是share的。

sip协议针对每一个连接用一个index来记录,一个index由连接的远端(另一头)的地址,port,协议类型 这三元组来生成。有以下几个特点

1)对于连接的发起者index=目的ip + 目的port + 传输协议

2)对于连接的接收者index=源ip + 源port + 传输协议,

对于这些已经建立好的连接,sip的两个UA在有传输任务的时候,其实是可以复用的。但由于源port往往是随机的,所以无法复用,那么如果之前的接收者想作为发起者发送数据了

他就需要重新建立一条连接。最终,对于经常有交互的UA之间,会存在两条建立好的连接,然后不断不断的复用着

 

四,关于sip如何使用传输层的

(一),客户端发送请求

 1,客户端在构造请求报文的时候,会在 Via 字段的头域中嵌入一个"sent-by"字段,这个字段包含两部分:ip地址或域名, 端口号。这个字段用来指导服务器向哪里回应答,如果没有port,则会使用缺省端口(udp/tcp/sctp:5060; tls:5061)

      1)如果是可靠传输

          因为是基于连接的,所以从哪里接收就向哪里回应。

           但如果server接收请求后,如果连接断了,那server就会重起连接,所以发送端必须在自己"sent-by"中指定的地址:端口上时刻准备着,准备着被连接

      2)如果是不可靠的传输

          发送端嵌入了"sent-by"字段,那么你就应该在"sent-by"字段中指定的地址+port上时刻准备着,准备着接收服务端的应答

(二),客户端接收应答

当应答回来了,客户端会检查应答中的 VIa 头域中的"sent-by"字段,一般来说这个字段是来自当初请求中的该字段,所以我回检查他是否和我的配置匹配,如果不匹配则销毁之

(三),服务端接收请求

1,作为服务器,你要注意在可能的接口上做好被连接的准备。所谓可能的接口,举个例子:你对外说xx域名代表我,那么这个域名背后的ip:port一定是可以被连接,说白了就是发布出去的路,自己一定保证路是通的。

2,所有接口上的udp/tcp/sctp:5060, tls:5061必须是可以接收连接的。(不过也有例外,私网环境和一个机器上部署多实例sip服务器的场景)

3,如果一个服务器为UDP协议在一个port上listen了,那么他必须也要为TCP协议在该port上监听,那是因为当包很大时,双方可能随时切换协议进行传输。

     反之,则不必。

    而且一般来说,服务端不需要为udp监听某个地址和port,因为已经在为tcp监听了,当然也有写特殊的需求

    水鬼子:这里着实有点蒙,udp为什么要监听? tcp监听了udp就不需要了么? 原文是:

A server need not listen for UDP on a particular address and port just because it is listening on that same address and port for TCP.  
There may, of course, be other reasons why a server needs to listen for UDP on a particular address and port.

4,如果接收到的包的源ip和"sent-by"字段指定的ip不同,则server需要在Via 的头上增加一个字段,叫"received",表示实际接收包的ip,这个字段用来帮助传输层去回复应答,也就是说这个应答必须要回给接收到请求的那个源地址,说白了就是哪里收到回哪里

(四),服务端发送应答

1,如果是基于可靠传输的(比如tcp,sctp,tls),如果在发送应答时连接还在,则基于连接回复应答

                                                                               如果连接没有了,则server重新和received“建立连接,然后再send response

2,如果Via header字段中包含“maddr”参数,则需要回给列表中所有的地址,使用的端口号就是"sent-by"中指定的端口号,如果没有指定,那么就是5060端口号

3,如果基于不可靠的传输的单播传输,回应答给“received“指定的地址  和 "sent-by"中指定的端口号,如果端口号没有指定,那么就是5060

4,如果没有“received“标识,则应答会给 "sent-by"中指定的地址 + 端口号

 

猜你喜欢

转载自www.cnblogs.com/shuiguizi/p/11201224.html