二、SIP中的请求和回复

1. 请求

请求是SIP协议中最基本的概念之一,SIP协议中信息交互的基本机制为请求-响应机制。
对于一个请求而言,需要其他参数的辅助来完善请求的信息,这些信息包括,请求的来源,请求的目的地址,请求的类型等,这些参数在SIP协议中被统称为SIP头域。

1.1 请求类型

请求的类型决定了这个请求的功能,请求所需完成的工作等。在SIP协议中决定请求类型的参数为Method参数。Method可以指定的值有:ACK,INVITE,BYE等。通过这个参数接收到SIP请求的实体可以完成对应的操作,然后发送的处理的结果,这个结果一般被称为响应。

1.2 请求的来源地址

在请求中需要标明请求的来源地址,从而可以使请求的接收者可以针对这个请求发送响应的回复,另外也可以帮助请求的接收者确认请求的合法性。在SIP请求中,完成这一功能的头域有很多,只是侧重点不同。有以下头域可以完成这些功能:

  • Via头域:标明了请求的上一个来源地址,这个地址可以为一个账号或者IP地址等信息。
  • From头域:标明请求实际发起者的地址。
  • Contact头域:标明目标设备可以去联系的地址。
  • Record-Route头域:这个头域用来收集路由,所以表示的是请求的之前通过的所有路由的地址。

1.3 请求的目的地址

在请求需要标明请求的目的地址,从而确定接收请求并且处理请求的一方。在SIP请求中完成这一功能的也有多个头域:

  • To头域:标明请求的实际目标地址
  • Request-URI:在旧版本的SIP协议中,这个值的功能为标明请求的下一跳地址,在RFC3261中标明的是请求的实际目的地址。这个头域需要和Route头域一起作用。
  • Route头域:标明请求的每一跳的目的地址。
    下面是为了说明这一概念做的说明:Request-URIRoute头域的作用问题需要通过严格路由和松散路由的概念才能说明。

2. 响应

除了特殊请求ACK之外,其余所有请求都有响应。在SIP协议中请求和响应组成了transaction。

2.1 响应类型

对于一个请求来说,根据接收请求之后的处理情况,响应也具有不同的类型。标明响应类型的参数为Status-code。响应的类型主要分为6种类型如下所示:

  • 1XX响应
    1XX响应为临时响应,临时响应在一般的情况下不会对通话状态造成影响,只是通知请求的处理状态。
  • 2XX响应
    2XX响应一般都标明请求执行成功,特例是CACEL请求,在CANCEL请求中,2XX响应只是标明了匹配到了对应的INVITE请求。
  • 3XX响应
    3XX响应为重定向响应。告知请求需要转发给其他地址。
  • 4XX响应
    4XX响应一般说明SIP请求有问题。同时错误一般由请求发起者本身造成或者和服务器上的配置不符合造成。
  • 5XX响应
    5XX响应标明当前服务器出现错误。
  • 6XX响应
    全局错误响应。造成该响应的有600全局忙碌,603断线,604不存在等原因。

2.2 响应的来源地址

在一个SIP的响应中,有一些头域又来指明响应的来源。这些头域为:

  • To头域:这个头域在SIP请求中用来标明请求的实际目标地址,而在响应中这个头域的值和SIP请求中的相同,用来说明这是响应的来源地址。
  • contact头域:该头域用来表示可以去联系的地址,在根据响应类别的不同会有所变化,例如在2xx响应中指的是响应的来源地址,而在3XX响应中表示的是重定向的新地址。所以对于这个头域来说,仅仅视为响应的来源地址是不准确的。
  • Record-Route头域:这个头域用来收集路由,所以表示的是响应的之前通过的所有路由的地址。

2.3 响应的目标地址

在一个SIP响应中,有多个头域可以用来表示响应的目标地址:

  • Route头域:标明响应每一跳的目的地址。
  • From头域:标明响应的实际目标地址,这个地址可以为实际IP,也可以是账号和域名的组合。
  • Via头域:这个头域也用来标记响应的每一跳的目的地址。

在响应中可以看到有两个头域用来对标记响应每一跳的目的地址。那么如果出现二者出现冲突,Via头域的优先级高于Route头域

实质上,这和Via头域以及Route头域的来源有关。对于Via头域而言,其来源是在请求的每一跳的过程中,由proxy将自己的信息添加到这个头域。请求在到达目标地址生成响应之后,会将这个头域复写到响应中,所以Via头域标明了对应的请求达到目标地址的路由信息。由于Via头域的这个特性,在SIP中饭也被用来判断路由是否成环。

Route头域是在INVITE请求的发送过程和对应的2XX响应的接收过程中,由Record-Route头域收集响应的路由信息,形成路由集后,在之后的请求和响应中会将路由集的信息放到Route头域中,从而有效减少寻找路由的时间。

Route头域Via头域的形成过程可以看到,Via头域的实时性比Route头域更强,所以优先级也更高。

还需要说明的一点是,在RFC3261中明确指出在Dialog建立之后,route-set不允许再被改变,虽然在后续的请求或者响应中会携带Record-Route头域,但是这一头域不会对route-set造成影响。详见RFC3261。

说到优先级问题,主要的优先级顺序如下:Via头域>Route头域>请求的Contact头域>From头域

3. 头域

在SIP消息中有很多头域。常用的头域有:

  • 1) Via头域:
    Via头域的其来源是在请求的每一跳的过程中,由proxy将自己的信息添加到这个头域。请求在到达目标地址生成响应之后,会将这个头域复写到响应中,所以Via头域标明了对应的请求达到目标地址的路由信息。由于Via头域的这个特性,在SIP中饭也被用来判断路由是否成环。branch参数也是这个头域的值的一部分。

  • 2)From头域:
    标明请求的实际发出者的地址。From tag标记。需要注意的一点是,在一个初始INVITE请求发出之后,From头域中就会被携带上对应的值以及From tag标记。

  • 3)To头域:
    标明请求实际接收者的地址。To tag标记。在初始INVITE请求中,会携带该头域,但是不会出现To tag标记。该标记会在非100的1XX临时响应中携带。

  • 4)Call-ID头域:
    和From tag以及To tag共同对一个Dialog进行标记。盖头域的值也在初始INVITE请求中就已经存在
    一个dialog需要使用Call-ID头域、To头域、From头域的原因

  • 由于在SIP协议中,INVITE请求会被派生(即一个SIP账号上绑定了多个地址),所以To tag标记了会话的实际响应者。
  • 对于From tag而言,标记了请求的实际发出者,如果一个SIP账号上绑定了多个地址,而这多个地址中有两台设备同时发出了请求,并且请求的Call-ID头域相同,那么该值就可以起到区分的作用。
  • 对于Call-ID来说,这个值实际上负责标记一个dialog,侧重点在dialog本身,即这个值唯一确认一个dialog,但是不负责标记dialog中的请求的接收者和发起者。
  • 5)Cseq头域:
    这个头域的值由两部分组成,一部分是数字,在每发出一个新请求时,这个数字就增加1,另外一部分是请求的方法名。和branch参数相类似,Cseq头域也用来对Transaction进行区分,不同的是,Cseq所标记的请求是需要处理的请求,即不会对ACK在序列号上进行区分,而branch参数负责对所有Transaction进行区分,包括INVITE请求2XX响应的ACK。Cseq头域的数字位初始值随机,只需保证初始值范围正确即可。

  • 6)Contact头域:
    该头域指明,可以去联系的地址。在注册请求中的响应中,该头域包含了注册为同一个名字的设备的相关信息。

  • 7)Route头域:
    指示在传输过程中,下一个路由的地址,有时需要和Request-URI一起进行处理。

  • 8)Record-Route头域:
    负责收集请求在传输过程中经过的路由。在初始INVITE请求和对应的响应中,还回去对路由集进行设置。

  • 9)Max-Forward头域:
    请求的剩余的跳数。

  • 10)Allow头域:
    该头域指明允许的请求类型。

你可能感兴趣的:(二、SIP中的请求和回复)