SIP协议详解(中文)-3

本文详细介绍了SIP协议中请求和应答头域的分类与作用,包括To、From、Cseq、Call-ID、Max-Forwards、Via等核心头域的使用规则。内容涵盖了请求头域的产生、消息正文类型、路由及传输、用户代理行为等方面,旨在帮助读者理解SIP消息的构建和交互过程。
摘要由CSDN通过智能技术生成
 
7.3.2 头域分类。
有一些头域是仅仅在请求(或者应答)中有效的。这些头域叫做请求头域或者应答头域。如果消息中的头域与这个消息的类型不匹配(比如在应答消息中出现的请求头域),这个头域必须被忽略。20节定义了每一个头域的分类。
7.3.3 缩写格式
SIP提供了一个用缩写格式来表达通用头域名字的机制。这个有助于避免消息过大而导致通讯层无法传输(比如在UDP传输的时候超过了最大传输单元(MTU))。这个缩写格式在20节定义。
缩写格式的消息头域名字可以在不改变消息语义的情况下替代较大的消息头域名字。在单个消息中,头域名字既可以用长的格式,也可以用缩写格式。在实现中,必须同时支持对长名字和缩写名字的处理。
7.4包体
请求信息,包括这个规范以后的扩展的新请求,都可以包含一个消息正文体。对消息正文体的解释依赖域请求的方法(请求类型)。对于应答消息来说,请求方法和应答状态(response status code)决定了消息正文体的格式。所有的应答消息都可以有一个消息正文体(body)。
7.4.1 消息正文类型(MessageBodyType)
消息中的internet媒体类别必须在Content-Type头域中指明。如果消息正文(body)通过某种形式的编码(encoding),比如压缩等等,都必须在Content-Encoding 头域中指明,否则Content-Encoding域必须忽略。如果可行,消息体的字符集作为Content-type头域的值的一部分表达。

在RFC2046[11]中定义的多部分”multipart” MIME类型可以在消息体中应用。在由多部分组成的消息体发送的时候,如果接受方的实现中,包头域的Accept域中,不包含多部分的标记,那么发送方必须发送一个非多部分的session description。
SIP消息可以包含二进制的包体或者部分包体。如果发送方没有其他显示的字符集参数指出,媒体的文本”text”子类型会是缺省的字符集”UTF-8”。
7.4.2 消息体长度
在Content-Length头域中存放了包体的字节长度。第20.14节讲述了本域的详细解释。
HTTP/1.1的“chunked”传输编码方式并不适用于SIP。(备注:chuncked编码传输方式是通过把消息正文体分为一系列的块来传输的,每一块有它自己的大小标记)

7.5 分帧的SIP消息(Framing SIP Messages)
不同于HTTP的是,SIP实现可以使用UDP或者其他非可靠传输协议。每一帧包括一个请求或者应答。第18节讲述了非可靠传输的应用。
在处理以面向流的通讯为基础的SIP消息的时候,必须忽略在开始行之前的CRLF[H4.1]。
Content-Length头域用来确定每一个SIP消息在通讯流中的结束位置的。在基于面向流通讯基础上的SIP消息一定要使用这个头域。

8 一般用户代理行为
一个用户代理代表了一个终端系统。它包含一个用户代理客户端(UAC),用来产生请求的,它包含一个用户代理服务端(UAS),用来响应请求的。UAC可以由一些外部的东西来发出请求和处理应答(比如用户按了一个按钮,或者按下了一个电话键产生了一个音频信号等等)。UAS是一个能够接收请求,并且产生应答的东西,它可以根据用户输入,外部输入,程序执行结果或者其他什么机制来产生应答。

当一个UAC发送一个请求,这些请求可能通过一些PROXY(代理服务器)传递到UAS上。当UAS产生一个应答,那么这个应答就会同样的被传送到UAC。UAC和UAS的处理由两个特点。第一,基于请求或者应答是否在一个对话里,第二,基于请求的方法(method)。会话的彻底描述在第12节;哪里描述了点对点的用户代理之间的关系,并且通过一些SIP方法建立了会话,比如INVITE方法等。

在本节,我们将讨论在处理对话外的请求时,UAC和UAS的方法无关的规则。这些当然也包括用于建立会话的请求。在26节讲述了对在对话外的请求和应答的安全处理。特别时,UAS和UAC之间的互相认证的机制。通过用S/MIME加密的消息体可以提供有限的隐私保证。
8.1 UAC特性
本节讲述UAC在会话外的特性。
8.1.1 产生一个请求
一个合法的SIP请求必须至少包含如下头域:TO,FROM,Cseq,Call-ID,Max-Forwards, Via;这些字段在所有SIP请求中必须包含。这6个字段是SIP消息的基本组成部分,他们提供了用于路由用的核心信息,包含了消息的地址,响应的路由,消息传递次数,详细的顺序,事务的唯一标志。
这些头域字段是必须包含在请求行之后的,请求行包含了请求的方法,Request-URI,SIP的版本号码。
有两个在对话外的发送请求的示例(通过INVITE请求建立连接,第13节),(通过OPTIONS请求查询负载,第11节)。
8.1.1.1 Request-URI
最开始的Request-URI头域应该是TO头域的的值。但是在REGISTER方法中,有一个值得注意的不同;REGISTER方法的Request-URI头域在第10节中指出。出于隐私的原因而把这些字段的值设置成为同一个值并不太合适(尤其是如果初始的UA期望Request-URI会在传输中改变的话)。
在一些特定的情况下,预先设置的路由表(route-set)会影响消息中的Request-URI。一个预置路由表是由一串server的URI组成,这些服务器是UAC往外发送会话外请求所需要经过的。通常,他们是由用户或者服务提供商手工在UA上设置的,或者通过一些非SIP的方法自动设置。当一个提供商希望配置一个出口proxy给一个UA,我们强烈建议通过一个预置一个单个URI路由表的方式来实现,这个单个路由就是出口proxy。
当要使用预置路由表(route set),必须提供Request-URI和Route头域(在12.2.1.1节中有详细描述)(甚至在没有对话存在的时候也必须提供),并且把Request-URI当作远端目标URI。
8.1.1.2 TO
To头域是第一个并且也是最先指定请求的”逻辑”接收地,或者是这个请求的用户或者资源的address-of-record。这个域内的地址可以是也可以不是请求的最终接收者。TO头域可以用SIP或者SIPS URI,也可以用其他方式的URI(比如电话URL (RFC2806[9]))。所有的SIP实现必须支持SIP URI的实现。任何支持TLS的实现必须支持SIPS URI的实现。
To头域允许有一个显示用的姓名。
UAC可以通过无数的方法来知道在一个给定请求的时候该如何填写TO头域。通常用户会建议采用人工界面中输入的To头域,可能手工输入这个URI或者从地址本中选择(就好像outlook邮件中的to一样)。用户通常不会输入完整的URI,可能只是一个简单的字串(比如”bob”)。这就要求UA能够判断用户输入的这个到底是那个URI。一般使用用户输入的字串加上”@”标志和主机的名字组合成为SIP URI(比如sip:bob@example.com)。如果希望通讯在保密机制下进行,那么就用用户输入的字串组成SIPS URI的部分,用户输入的将加上”@”和主机的名字作为整个SIPS URI。这个主机的名字通常是请求方的主机名字,这个主机允许处理外发请求。这个很像”缩位拨号”的机制,这个机制要求请求者自身的主机能够解释这个缩位拨号一样。
如果UA不希望指定主机,那么就需要将用户输入的电话号码解释成为一个电话的URL。相当于,每一个请求经过的主机都会有机会来处理这个请求。比如,一个用户在机场可能登陆机场的代理服务器,并且通过机场的代理服务器发出一个请求。如果他输入”411”(美国本地电话本查询服务号码),这个就需要机场的外发的代理服务器进行解释和处理,而不是解释成有主机的用户。在这里,tel:411是一个正确的解释。
在会话外的请求中,不能包含To tag字段,在to头域中的tag是用来在对话中做标志的。既然对话还没有建立,那么tag就不能存在。
20.39节有进一步的描述。
下边这个例子是一个To头域的例子:
To: Carol <sip:carol@chicago.com>
8.1.1.3 From
From头域包含了请求发起者的逻辑标志,可能是用户的address-of-record。就像To头域一样,From头域也包含一个URI并且可以包含一个显示的姓名。SIP可以用这个头域来实现对请求的检查和选择一个规则进行对请求的处理(比如,自动的呼叫拒绝,凡是x人发过来的东西,一律无视)。同样的,因为From头域包含的是逻辑名字,所以From URI也可以不包含IP地址或者UA对应的主机名字FQDN。
From头域可以包含一个显示姓名。在客户身份隐藏的情况下,一个UAC应该使用显示名字”Anonymous”,连通一个语法正确,但是没有意义的URI(比如:sip:thisis@anonymous.invalid)。通常,用户或者用户的本地主机的管理人员会事先规定请求头域中的From头域的值。如果给定的UA是多个用户共同使用的,那么必须有一个URI对应身份的profile,这样才能够切用户的profile。收到请求的服务方可以根据这个用于分辩身份的URI来区分同一个UA上的不同的用户,并且根据他们的From头域来判定他们的身份。(22节有更多的验证说明)。
From域必须包含一个由UAC产生的新的”tag”参数。19.3节有tag的详细描述。20.20节有更深入的资料。
例子:
From: “Bob” <sips:bob@biloxi.com> ; tag=a48s
From: sip:+ 12125551212@phone2net.com;tag=887s
From: Anonymous <sip:c8oqz84zk7z@privacy.org>;tag=hyh8
8.1.1.4 Call-ID
Call-ID是一个在一系列消息中,区分一组消息的唯一标志。在对话中的任一UA的所有请求和所有应答的Call-ID必须一致。在UA的每次注册中,都应该是一样的。在会话外的时候,UAC发起一个新的请求,这个Call-ID头域必须由UAC产生一个全局(在时间和空间上都是)唯一的Call-ID, 除非是请求头的方法(method)指明了别的产生方式。所有的SIP UA都必须保证自己产生的Call-ID不会和其他UA产生的Call-ID重复。注意,如果是请求的重新尝试,则重新尝试的请求不被当作一个新的请求,所以不需要新的Call-ID(重新尝试的请求例如:认证冲突等等)。(见8.1.3.5)
我们强烈建议用密码乱序随机串(RFC 1750[12])来产生Call-ID。实现中,可以用类似”localid@host”这样的格式产生。Call-ID是大小写敏感的,并且通过简单字节/字节的来进行比较。
采用密码乱序随机串可以降低会话被窃听的机会,并且降低Call-ID重复的冲突。不规定或者要求使用用户界面来选择输入Call-ID头域的值。参见20.8节。
例子:
Call-ID: f81d4fae-7dec-11d0-a765-00a0c91e6bf6@foo.bar.com
8.1.1.5 Cseq
Cseq 头域是用来区分和做位事务的顺序使用的。他由一个方法(method)和一系列的顺序号码组成。方法(method)必须和请求的方法一致。对于对话外的非REGISTER请求来说,顺序号码可以是任意的。这个顺序号码必须可以由32位的无符号整数表达,必须小于2^31。只要遵循了上述指导方针,客户端可以用任意的方法来产生这个Cseq头域。12.2.1.1节讲述了在对话中如何创建Cseq
例子:
Cseq: 4711 INVITE
8.1.1.6 Max-Forwards
Max-Forwards头域用来限制请求到他的目的地中间的跳转。它包含一个每隔一个跳转就自动减一的数字。如果Max-Forwards在到达目的之前就减到0,他会报告一个483(太多的路由)错误回应。
一个UAC必须为每一个请求填写一个Max-Forwards头域,这个字段的缺省值应该是70。这个数字是保证了请求在没有环路的SIP网络中都能够送达,也保证了在有环路的时候,尽量少消耗proxy的资源。如果这个数字要变小,则必须保证UA知道整个网络的拓扑结构。
8.1.1.7 Via
Via头域是标志了用于事务传输的传输设备,并且也标志了应答送回的地址。只有当需要通过选择传输设备到达下一个节点(hop)的时候,才需要在头域中包含Via域。当UAC创建一个请求,它必须在头域中添加一个Via域。protocol 名字和protocol版本必须分别是SIP和2.0。Via头域必须包含一个分支(branch)参数。这个参数用于区分请求创建的事务。这个参数客户端和服务器都会使用。除了CANCEL和给非2xx应答的ACK以外,branch参数对UA发出的所有的请求来说,在时间和空间上必须唯一。在下边的讲解中,CANCEL请求的branch参数必须和他所取消的请求的branch参数一致。在17.1.1.3节中讲述了给非2xxx(non-2xx)应答的ACK必须和其对应的的INVITE请求有相同的branch ID。
利用branch ID参数的唯一性来作为事务的ID(transaction ID),并非RFC 2543的一部分。根据本标准产生的branch ID必须用”z9h64bK”开头。这7个字母是一个乱数cookie(定义成为7位的是为了保证旧版本的RFC2543实现不会产生这样的值),这样服务器收到请求之后,可以很方便的知道这个branch ID是否由本规范所产生的(就是说,全局唯一的)。在这样的要求下,精确的branch ID的格式必须事先有实现的定义。
Via头域中,maddr,ttl,和sent-by字段会在transport层处理请求的时候设置(18节)。Via在proxy的处理在16.6节8段和16.7节3段描述。
8.1.1.8 Contact
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值