基本信息
SIP (会话发起协议) 是一种信令和呼叫控制协议 ,广泛用于在IP网络上建立、修改和终止多媒体会话,包括语音、视频和即时消息。SIP由互联网工程任务组 (IETF) 开发,定义在RFC 3261 中,已成为VoIP和统一通信的事实标准。
SIP的一些关键特性包括:
基于文本的协议 :SIP是基于文本的协议,使其易于阅读和调试。它基于请求-响应模型,类似于HTTP,并使用INVITE、ACK、BYE和CANCEL等方法来控制呼叫会话。
可扩展性和灵活性 :SIP具有高度的可扩展性,可用于小规模部署以及大型企业和运营商级环境。它可以轻松扩展新功能,使其适应各种用例和需求。
互操作性 :SIP的广泛采用和标准化确保了不同设备、应用程序和服务提供商之间更好的互操作性,促进了各种平台之间的无缝通信。
模块化设计 :SIP与其他协议(如**RTP(实时传输协议)用于媒体传输和 SDP(会话描述协议)**用于描述多媒体会话)协同工作。这种模块化设计允许更大的灵活性和与不同媒体类型和编解码器的兼容性。
代理和重定向服务器 :SIP可以使用代理和重定向服务器来促进呼叫路由,并提供呼叫转移、呼叫转接和语音邮件服务等高级功能。
状态和即时消息 :SIP不仅限于语音和视频通信。它还支持状态和即时消息,支持广泛的统一通信应用程序。
尽管SIP有许多优点,但在配置和管理时可能会很复杂,特别是在处理NAT穿越和防火墙问题时。然而,其多功能性、可扩展性和行业广泛支持使其成为VoIP和多媒体通信的热门选择。
SIP方法
在RFC 3261 中定义的核心SIP方法包括:
INVITE :用于**发起新会话(呼叫)**或修改现有会话。INVITE方法携带会话描述(通常使用SDP)以通知接收方有关提议会话的详细信息,例如媒体类型、编解码器和传输协议。
ACK :发送以确认收到 对INVITE请求的最终响应。ACK方法通过提供端到端确认来确保INVITE事务的可靠性。
BYE :用于终止已建立的会话(呼叫) 。BYE方法由会话中的任一方发送,以表示他们希望结束通信。
CANCEL :发送以取消待处理的INVITE 请求,在会话建立之前。CANCEL方法允许发送方在改变主意或接收方没有响应时中止INVITE事务。
OPTIONS :用于查询SIP服务器或用户代理的能力 。OPTIONS方法可以发送请求有关支持的方法、媒体类型或其他扩展的信息,而无需实际建立会话。
REGISTER :由用户代理用于向SIP注册服务器注册其当前位置 。REGISTER方法有助于维护用户的SIP URI与其当前IP地址之间的最新映射,从而实现呼叫路由和交付。
请注意,呼叫某人不需要使用REGISTER 。
然而,可能在进行INVITE 之前,呼叫者需要进行身份验证 ,否则将收到**401 Unauthorized
**响应。
除了这些核心方法外,还有在其他RFC中定义的几种SIP扩展方法 ,例如:
SUBSCRIBE :在RFC 6665中定义,SUBSCRIBE方法用于请求有关特定资源状态的通知 ,例如用户的状态或呼叫状态。
NOTIFY :同样在RFC 6665中定义,NOTIFY方法由服务器发送,以通知订阅的用户代理 有关监视资源状态的变化。
REFER :在RFC 3515中定义,REFER方法用于请求接收方执行转接或引用第三方 。这通常用于呼叫转接 场景。
MESSAGE :在RFC 3428中定义,MESSAGE方法用于在SIP用户代理之间发送即时消息 ,使得在SIP框架内进行基于文本的通信成为可能。
UPDATE :在RFC 3311中定义,UPDATE方法允许在不影响现有对话状态的情况下修改会话 。这对于在进行中的呼叫中更新会话参数(例如编解码器或媒体类型)非常有用。
PUBLISH :在RFC 3903中定义,PUBLISH方法由用户代理用于向服务器发布事件状态信息 ,使其对其他感兴趣方可用。
SIP响应代码
1xx(临时响应) :这些响应表示请求已被接收,服务器正在继续处理。
100 Trying: 请求已被接收,服务器正在处理。
180 Ringing: 被叫方正在被提醒,将接听电话。
183 Session Progress: 提供有关呼叫进展的信息。
2xx(成功响应) :这些响应表示请求已成功接收、理解和接受。
202 Accepted: 请求已被接受处理,但尚未完成。
3xx(重定向响应) :这些响应表示需要进一步的操作来满足请求,通常是通过联系替代资源。
300 Multiple Choices: 有多个可用选项,用户或客户端必须选择一个。
301 Moved Permanently: 请求的资源已分配新的永久URI。
302 Moved Temporarily: 请求的资源暂时可在不同的URI上获得。
305 Use Proxy: 请求必须发送到指定的代理。
4xx(客户端错误响应) :这些响应表示请求包含错误的语法或服务器无法满足请求。
400 Bad Request: 请求格式错误或无效。
401 Unauthorized: 请求需要用户身份验证。
403 Forbidden: 服务器理解请求但拒绝满足。
404 Not Found: 请求的资源在服务器上未找到。
408 Request Timeout: 服务器在准备等待的时间内未收到完整请求。
486 Busy Here: 被叫方当前忙碌,无法接听电话。
5xx(服务器错误响应) :这些响应表示服务器未能满足有效请求。
500 Internal Server Error: 服务器在处理请求时遇到错误。
501 Not Implemented: 服务器不支持满足请求所需的功能。
503 Service Unavailable: 服务器当前无法处理请求,因维护或过载。
6xx(全局失败响应) :这些响应表示请求无法被任何服务器满足。
600 Busy Everywhere: 呼叫的所有可能目的地都忙。
604 Does Not Exist Anywhere: 请求的资源在网络中不可用。
示例
SIP INVITE 示例
Copy INVITE sip:jdoe@example.com SIP/2.0
Via: SIP/2.0/UDP pc33.example.com;branch=z9hG4bK776asdhds
Max-Forwards: 70
To: John Doe <sip:jdoe@example.com>
From: Jane Smith <sip:jsmith@example.org>;tag=1928301774
Call-ID: a84b4c76e66710
CSeq: 314159 INVITE
Contact: <sip:jsmith@pc33.example.com>
User-Agent: ExampleSIPClient/1.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO
Content-Type: application/sdp
Content-Length: 142
v=0
o=jsmith 2890844526 2890842807 IN IP4 pc33.example.com
s=-
c=IN IP4 pc33.example.com
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000te
每个参数解释Request-Line : INVITE sip:jdoe@example.com SIP/2.0
- 该行指示方法(INVITE)、请求URI(sip:jdoe@example.com )和SIP版本(SIP/2.0)。
Via : Via: SIP/2.0/UDP pc33.example.com;branch=z9hG4bK776asdhds
- Via头指定传输协议(UDP)和客户端地址(pc33.example.com)。"branch"参数用于循环检测和事务匹配。
Max-Forwards : Max-Forwards: 70
- 此头字段限制请求可以被代理转发的次数,以避免无限循环。
To : To: John Doe <sip:jdoe@example.com>
- To头指定通话的接收者,包括他们的显示名称(John Doe)和SIP URI(sip:jdoe@example.com )。
From : From: Jane Smith <sip:jsmith@example.org>;tag=1928301774
- From头指定通话的发送者,包括他们的显示名称(Jane Smith)和SIP URI(sip:jsmith@example.org )。"tag"参数用于唯一标识发送者在对话中的角色。
Call-ID : Call-ID: a84b4c76e66710
- Call-ID头唯一标识两个用户代理之间的通话会话。
CSeq : CSeq: 314159 INVITE
- CSeq头包含一个序列号和请求中使用的方法。它用于将响应与请求匹配并检测乱序消息。
Contact : Contact: <sip:jsmith@pc33.example.com>
- Contact头提供发送者的直接路径,可用于后续请求和响应。
User-Agent : User-Agent: ExampleSIPClient/1.0
- User-Agent头提供有关发送者的软件或硬件的信息,包括其名称和版本。
Allow : Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO
- Allow头列出发送者支持的SIP方法。这有助于接收者了解在通信中可以使用哪些方法。
Content-Type : Content-Type: application/sdp
- Content-Type头指定消息体的媒体类型,在这种情况下为SDP(会话描述协议)。
Content-Length : Content-Length: 142
- Content-Length头指示消息体的大小(以字节为单位)。
Message Body : 消息体包含SDP会话描述,其中包括有关媒体类型、编解码器和提议会话的传输协议的信息。
o=jsmith 2890844526 2890842807 IN IP4 pc33.example.com
- 发起者和会话标识符
s=-
- 会话名称(单个连字符表示没有会话名称)
c=IN IP4 pc33.example.com
- 连接信息(网络类型、地址类型和地址)
t=0 0
- 时间信息(开始和停止时间,0 0表示会话没有边界)
m=audio 49170 RTP/AVP 0
- 媒体描述(媒体类型、端口号、传输协议和格式列表)。在这种情况下,它指定使用RTP/AVP(实时传输协议/音视频配置文件)和格式0(PCMU/8000)的音频流。
a=rtpmap:0 PCMU/8000
- 属性将格式(0)映射到编解码器(PCMU)及其时钟频率(8000 Hz)。
SIP REGISTER 示例
REGISTER方法用于会话发起协议(SIP),允许用户代理(UA),例如VoIP电话或软电话,向SIP注册服务器注册其位置 。此过程让服务器知道将传入的SIP请求路由到注册用户的位置 。注册服务器通常是SIP代理服务器或专用注册服务器的一部分。
以下是REGISTER认证过程中的SIP消息的详细示例:
Copy REGISTER sip:example.com SIP/2.0
Via : SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK776asdhds
Max-Forwards : 70
From : Alice <sip:alice@example.com>;tag=565656
To : Alice <sip:alice@example.com>
Call-ID : 1234567890@192.168.1.100
CSeq : 1 REGISTER
Contact : <sip:alice@192.168.1.100:5060>;expires=3600
Expires : 3600
Content-Length : 0
这个初始的 REGISTER 消息由 UA(Alice)发送到注册服务器。它包含重要信息,例如所需的注册持续时间(Expires)、用户的 SIP URI(sip:alice@example.com )和用户的联系地址(sip:alice@192.168.1.100:5060)。
401 Unauthorized 来自注册服务器的响应:
Copy cssCopy codeSIP/2 .0 401 Unauthorized
Via: SIP/2.0/UDP 192 .168.1.100 :5060;branch=z9hG4bK776asdhds
From: Alice <sip:alice@example .com > ;tag=565656
To: Alice <sip:alice@example .com > ;tag=7878744
Call-ID: 1234567890@192 .168.1.100
CSeq: 1 REGISTER
WWW-Authenticate: Digest realm="example.com" , nonce="abcdefghijk" , algorithm=MD5 , qop="auth"
Content-Length: 0
注册服务器以“401 Unauthorized”消息响应,其中包含“WWW-Authenticate”头。该头包含UA进行身份验证所需的信息,例如身份验证域、随机数和算法 。
Copy REGISTER sip:example.com SIP/2.0
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK776asdhds
Max-Forwards: 70
From: Alice <sip:alice@example.com>;tag=565656
To: Alice <sip:alice@example.com>
Call-ID: 1234567890@192.168.1.100
CSeq: 2 REGISTER
Contact: <sip:alice@192.168.1.100:5060>;expires=3600
Expires: 3600
Authorization: Digest username="alice", realm="example.com", nonce="abcdefghijk", uri="sip:example.com", response="65a8e2285879283831b664bd8b7f14d4", algorithm=MD5, cnonce="lmnopqrst", qop=auth, nc=00000001
Content-Length: 0
UA发送另一个REGISTER请求,这次包括**“Authorization”头,带有必要的凭据,如用户名、域、随机数和使用提供的信息和用户密码计算的响应值**。
这就是Authorization响应 的计算方式:
Copy import hashlib
def calculate_sip_md5_response ( username , password , realm , method , uri , nonce , nc , cnonce , qop ):
# 1. Calculate HA1 (concatenation of username, realm, and password)
ha1_input = f " { username } : { realm } : { password } "
ha1 = hashlib . md5 (ha1_input. encode ()). hexdigest ()
# 2. Calculate HA2 (concatenation of method and uri)
ha2_input = f " { method } : { uri } "
ha2 = hashlib . md5 (ha2_input. encode ()). hexdigest ()
# 3. Calculate the final response value (concatenation of h1, stuff and h2)
response_input = f " { ha1 } : { nonce } : { nc } : { cnonce } : { qop } : { ha2 } "
response = hashlib . md5 (response_input. encode ()). hexdigest ()
return response
# Example usage
username = "alice"
password = "mysecretpassword"
realm = "example.com"
method = "REGISTER"
uri = "sip:example.com"
nonce = "abcdefghijk"
nc = "00000001"
cnonce = "lmnopqrst"
qop = "auth"
response = calculate_sip_md5_response (username, password, realm, method, uri, nonce, nc, cnonce, qop)
print ( f "MD5 response value: { response } " )
Copy SIP/2.0 200 OK
Via : SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK776asdhds
From : Alice <sip:alice@example.com>;tag=565656
To : Alice <sip:alice@example.com>;tag=7878744
Call-ID : 1234567890@192.168.1.100
CSeq : 2 REGISTER
Contact : <sip:alice@192.168.1.100:5060>;expires=3600
Expires : 3600
Content-Length : 0
在注册服务器验证提供的凭据后,它发送一个“200 OK”响应以指示注册成功 。响应包括注册的联系信息和注册的过期时间。此时,用户代理(Alice)已成功注册到SIP注册服务器,针对Alice的传入SIP请求可以路由到适当的联系地址。
呼叫示例
虽然没有提到,但用户B需要在能够接听电话之前向代理2发送REGISTER消息 。