美文网首页
SIP协议(断更中)

SIP协议(断更中)

作者: Alexei_Wang | 来源:发表于2018-12-02 00:28 被阅读0次

    SIP协议

    Author: Alex

    First Edition: Dec 01 2018

    TextEditor: MacDown

    1. SIP消息

    SIP协议是采用UTF-8字符集来进行编码的文本协议。

    SIP协议消息分请求和响应两类,其中请求消息由客户机发往服务器,响应消息由服务器发往客户机。除选用的字符集及语法定义外,请求和响应消息均采用RFC2822定义的基本格式进行编码。请求和响应消息格式由一个起始行、若干个头字段,以及一个可选的消息体组成。其中消息体为可选项,头字段与消息体之间用空行进行分隔。请求和响应消息格式如下:

    
    SIP消息 = 起始行
    
    *消息头部(1个或多个头部)
    
    CRLF(空行)
    
    [消息体]
    
    起始行=请求行/状态行
    
    

    如上消息格式定义,“*”表示该消息头部可包含一个或多个,“[]”表示该参数为可选项。本规范规定起始行、每一个消息头部以及空行都必须使用回撤换行来表示中介,即使消息中未包含消息体可选项空行也不能省略。

    除以上字符集不同之外,SIP消息和头字段与法定义与HTTP1.1的语法定义一致。消息语法与HTTP类似,SIP协议并不是HTTP协议的拓展。

    1.1 请求(Request)

    请求消息的起始行为请求行(Request-Line)。请求格式如下所示,由方法名、请求URL和协议版本组成,各部分之间均用一个空格字符进行分隔。除此以外,亲故行必须用回车换行字符表示终结。

    Request-Line = Method[] Request-URI[] SIP-Version CRLF
    
    1. Method:文本规范共定义了6个方法,INVITE、ACK、CANCEL、OPTIONS、BYE和REGISTER消息用于发送注册请求信息,INVITE、ACK、CANCEL用于建立会话链接,BYE用于终结会话链接,OPTIONS用于查询服务器能力。本协议规定方法名必须使用大写字母。除以上6类主要消息外,SIP协议在其他文档中还定有若干方法实现协议拓展。
    1. Request-URL:指示被邀请用户的当前地址,本协议规定Request-URL中不允许出现空格及其他控制字符,且不能包含与“<>”符号之内。

    除使用“sip”和"sips"之外,Request-URI还可以使用“tel”的URL定义机制,有关“tel”的URL定义机制参见RFC2806。SIP实体可使用任何可选方法将非SIP URL翻译成SIP URI、SIPS URI或其他URI定义。

    1. SIP—Vesion:用于定义协议的当前版本号,本协议的版本号为SIP/2.0。

    1.2 响应(Response)

    响应消息的起始行为状态行(Status-Line),状态行由协议版本、状态码和与状态码相关的文本描述组成,各个部分之间用一个空格字符进行分隔。状态行的格式如下所示:

    Status-Line = SIP-Version[] Status-Code[] Reason-Phrase CRLF
    

    除状态行的尾部可使用回撤换行CRLF字符之外,状态行内不允许出现CRLF字符。

    1. Status-Code(状态码):该参数为一个3位的十进制正数,用于指示请求消息的执行响应结果。

    2. Reason-Phrase(原因):该参数用于对Status-Code参数进行简单的文本描述。客户机不必检查或显示Reason-Phrase参数。警官文本规范件使用特定字符表示Reason-Phrase,具体实现过程中Reason-Phrase仍可使用其他的文本字符。

    3. 常用状态码不赘述。

    1.3 头字段

    SIP头字段的语法和语义定义与HTTP头字段定义基本相同,有关HTTP头字段的定义和SIP头字段多行拓展的定义规则件RFC2616。RFC2616中定义的多行拓展可使用隐含的空格和折叠字符(folding),而本规范定义的多行拓展规则只能使用显示空格和折叠字符(folding),且空格和折叠字符(folding)作为消息的组成部分。

    同样,RFC2616也定义了奖具有多个参数值的统一字段拓展为具有相同字段名称的多个字段行的规则。该规则同样适用于文本协议,但具体应用时规则会有所不同。SIP协议定义的头字段语法规则如下所示:

    header = "header-name" HOCLON header-value *(COMMA header-value)
    

    如上所示,SIP头字段允许一个头字段可以定义多个参数值,且多个参数值之间用“,”字符进行分隔。当属性值不为“*”时,Contact头字段允许属性值之间用“,”字符进行分隔。

    1.3.1 头字段格式

    SIP消息的头字段格式遵循RFC2822 第2.2节所定义的通用头字段格式定义规则。头字段格式如下所示,头字段名和字段值之间用字符“:”进行分隔。

    field-name:field-value
    

    消息头字段中允许出现多个空格字符。但是,在具体实现过程中,本规范建议字段头部右侧,即字段名和":"字符之间应避免出现空格字符,而字段头部左侧,即字段和“:”之间用一个空格字符进行分隔,如下所示:

    field-name:[]field-value
    

    头字段部分可以通过增加多个空白字符或者TAB字符而进行拓展成多行,本规范规定拓展行首位的多个空白字符以及分行字符都应作为一个空白字符对待。依以上规则,一下两个头字段是相同的。

    Subject: I know you're there, pick up the phone and talk to me!
    
    Subject: I know you're there,
    
    pick up the phone
    
    and talk to me!
    

    消息头字段内不同头字段名的顺序可任意排列,但是,本规范建议于代理服务器处理相关的字段名(如Via、Route、Record-Route、Proxy-Require、Max-Forwards、Proxy-Authorization等)应尽可能排在消息头字段的前几位以加快代理服务器对消息的处理速度。相同头字段名的排列顺序也非常重要。

    等价规则好理解,不赘述。

    1.4.1 消息实体类型

    消息实体的类型必须由"Content-Type"字段进行定义,且如果消息实体采用了压缩编码方式,则相应地在“Content-Encoding”字段中定义其所采用的压缩编码算法。否则,如果消息实体未采用了压缩编码的,则“Content-Encoding”字段的内容应被忽略。在具体应用过程中,消息接受实体应将消息实体的内容作为“Content-Type”头字段值来对待。

    被协议规定消息可以承载适用"multiplart"MIMIE方式进行编码的信息单元,相关信息参见RFC2046。在具体实现中,当请求发送方需要发送消息实体部分包含MIME信息单元的请求消息时,且消息接受放在“Accept”头字段指示其不能接受MIME消息实体,则消息请求发送方应在消息中附加一个SDP部分作为非MIMIE消息实体进行发送。SIP消息可以包含二进制编码的消息实体。如果未明确指出,本文中default编码类型是UTF-8。

    1.4.2 消息实体长度

    消息实体长度由“Content-Length”头字段进行定义,单位为字节。

    本协议中规定SIP消息实体不能采用HTTP1.1中所定义的“chunked”传送编码机制。

    1.5 SIP消息帧

    SIP协议可以使用UDP或者其他不可靠的报文协议进行承载传送,且每一个豹纹携带一个请求或相应消息。

    具体实现时,如果SIP消息采用面向流的方式进行传送,则SIP消息起始行的任何CRLF字符应忽略。

    “Content-Length”头字段用于定义一个SIP消息在流中的结束位置。当SIP消息采用面向流的方式进行传送,该头字段不能被省略。

    2. 用户代理(UA)的基本行为

    用户代理(UA)表示一个终端系统。他包括两部分,用户代理客户端(UAC)和用户代理服务器端(UAS),前者产生请求,后者产生对应的相应。UAC可根据某些外部激励产生请求消息并且处理这些请求的相应消息。外部刺激可以是用户在某一图形界面上的点击按钮、也可以是某一PSTN链路上的信令信号等。UAS能接收请求消息并产生影响消息。

    当UAC发出请求,请求消息会通过一些代理服务器被转发到UAS。而UAS产生一个响应后,相应消息会以同样的方式被转发到UAC。

    UAC和UAS的处理过程与两个因素有关,即被处理的请求或相应消息是否属于某个对话(dialog)以及请求的方法。对话时一种UA之间的端到端对等关系,他由特定的SIP消息,如INVITE消息建立。

    2.1 UAC基本行为

    2.1.1 请求消息的产生

    本规范规定,由UAC产生的一个有效的SIP请求消息必须至少包含下列头字段:To、From、CSeq、Call-ID、Max-Forwards和Via头字段,他们在所有的SIP请求消息都是必选的。这六个头字段是构建SIP消息的基本单元,它们共同提供了大部分的关键的消息路由服务,包括消息的寻址、相应的路由、消息传播距离限制、消息排序,以及事务交互的唯一性标识等。另外,请求行(request line)也是必选的,它包含了请求方法、Request-URI、SIP版本信息。

    在对话外发送的请求消息包括:用INVITE消息建立起一个会话,用OPTIONS消息进行能力查询。

    2.1.1.1 Request-URI

    除REGISTER请求,本协议中所有的请求消息的初始Request-URI都应被设为To头字段的URI值。另外处于安全性考虑,UA有时可能不希望这两个头字段设为同样的值,尤其是当发端UA知道Request-URI可能会在传输中国呢改变。

    某些情况下,预设路由集的存在能影响到消息的Request-URI。预设路由集是一个有序的URI集合,它标识了一个服务器链,UAC向这个服务器链发出对话外请求消息。预设路由集通常由用户或服务供应商在UA上手工配置,或者通过某些其他的非SIP机制配置。本规范建议,在给某个UA配置一个外拨代理服务器时服务器供应商所提供的预路由集只有一个URI,即外拨代理服务器的URI。

    2.1.1.2 TO头字段

    To头字段指定请求消息的罗基接受着是用户或资源的注册地址,该低着同样是作为请求消息的目标地址。To头字段所指示的不一定为请求消息的最终接收者。它可能包含一个SIP或SIPS URI,或其他的URI方案。本协议规定,所有具体的实现过程都必须支持SIP URI方案,任何支持TLS的实现必须支持SIPS URI方案。To头字段中允许包含一个显示名称。

    UAC可以通过多种方式来构造一个请求消息的To头字段。通常经过人机接口,由用户输入或者从地址簿中选取。用户通常不会输入一个完整的URI,而只是提供一个由数字或字母组成的字符串,由UA版端并解释该字符串。如果这个字符串被用来构成一个SIP URI的用户部分,则用户名称在@符号右侧表示的主域中被解析;如果这个字符串被用来狗仔一个SIPS URI的用户部分,则用户希望进行安全的通信,同事用户名将在@符号右侧表示的主域中被解析。SIP URI中@符号右侧通常是请求发起方的主域,它使本地主域能够处理外发请求。此外,如果用户输入的是一个电话号码,且UA不会指定由某一个主域来解释该号码,这事可以使用tel URI,从而使请求消息经过的每一个主域都可以处理它。 Eg: tel:411

    请求消息的To标签标识了一个对话中的对端,如果对话没有建立,标签就不应当出现。对话之外的请求消息中可以不包含To标签(tag)。

    示例,一个有效的To头字段:

    To: Carol<sip: carol@chicago.com>
    

    2.1.1.3 From头字段

    From头字段是指示请求发起方的逻辑标识,它可能是用户的注册地址。From头字段包含一个URI和一个可选的显示名称。SIP实体用它来决定如何处理一个请求(如呼叫自动拒绝)。由于不是逻辑名称,因此From URI不包含IP地址或UA所在主机的全称域名(FQDN)。

    From头字段中允许包含一个显示名称。如果一个UAC需要隐藏自己的身份,它可以使用“ANonymous”作为显示名称和一个语法正确但是没有任何意义的URI。

    通常,某个UA产生的请求消息中的From头字段值是由用户或用户本地主域的服务器预先设置的。如果UA被多个用户所共用,那么它可以有多个可切换的用户配置文件,每一个文件中含有某一用户的URI。请求消息的接受者要对发送者进行健全,已确认发送者身份与From头字段相一致。

    示例:

    From: "Bob"<sips:bob@Biloxi.com>;tag=a48s
    
    From: sips:+12125551212@phone2net.com;tag=887s
    
    From: Anonymous <sip:c8oqz84zk7z@privacy.org>;tag=hyh8
    

    2.1.1.4 Call-ID头字段

    Call-ID 头字段是用来将消息分组的唯一标识。本协议规定,在一个对话中,UA发送的所有请求消息和响应消息都不许有同样的Call-ID。一个UA每次注册所用的Call-ID也应是一样的。

    当UAC产生一个新的对话外请求时,除非被某些方法指定,否则它必须为这个请求消息选择一个在空间和时间上都是全局唯一的Call-ID头字段。所有SIP UA都必须保证它所产生的Call-ID不会与其他UA所产生的相同。当UA收到某些失败的响应后,请求会根据响应的内容修改并重发,这些重发的请求不作为新请求处理,因而也就不需要新的Call-ID头字段。

    Call-ID的选择不需要通过人机接口和预先设定值来实现。

    示例:

    Call-ID:f81d4fae-7dec-11d0-a765-00a0c91e6f6@foo.bar.com
    

    2.1.1.5 Cseq头字段

    CSeq头字段用于标识事务并对事务进行排序。它由一个请求方法和一个序列号组成,请求方法必须与对应的请求消息类型一致。对话外的非REGISTER请求,序列号值可以时任意的。但它必须可被表示成一个32位的无符号整数,且小于2^31,只要符合以上的规则,客户端可以使用任何方式来选择Cseq头字段值。

    示例:

    CSeq: 4711 INVITE
    

    目前因为工作辞职准备读博士,暂时不做这个东西,估计几个月内是不会研究sip协议来更新了。

    相关文章

      网友评论

          本文标题:SIP协议(断更中)

          本文链接:https://www.haomeiwen.com/subject/mmpdcqtx.html