Skip to content

也聊 SIP 协议

Published: at 05:40 AM

与 UDP HTTP 协议等相比,SIP 协议相对比较“冷门”,但实际生活中还是会接触到,比如你打400电话,或是接到机器人电话,可能背后都有 SIP 的参与。由于笔者水平有限,无法保证都正确,想全面了解 SIP 推荐看官方文档 RFC 3261。

SIP 协议

SIP(Session Initiation Protocol, 会话初始协议)是一种用于在IP网络上建立、修改和终止多媒体会话(如语音通话、视频会议、即时消息等)的信令协议。它主要用于解决在 VoIP(Voice over IP)或其他实时通信应用中,如何建立、管理和终止会话的问题。

特点

通过上面的介绍大家对SIP应该有个基础的印象,我们看下实际报文:

INVITE sip:Administrator@192.168.2.218 SIP/2.0
Via: SIP/2.0/UDP 192.168.31.178:62837;branch=z9hG4bK.8WiAEUPjC;rport
From: <sip:alice@192.168.31.178>;tag=4tYbJ32O3
To: sip:Administrator@192.168.2.218
CSeq: 20 INVITE
Call-ID: q~Nno8HNkb
Max-Forwards: 70
Supported: replaces, outbound, gruu, path, record-aware
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO, PRACK, UPDATE
Content-Type: application/sdp
Content-Length: 551
Contact: <sip:192.168.2.2:62837;transport=udp>;+org.linphone.specs="conference/1.0,lime"
User-Agent: Linphone-Desktop/5.2.6

v=0
o=alice 3510 667 IN IP4 192.168.31.178
s=Talk
c=IN IP4 192.168.31.178
t=0 0
a=rtcp-xr:rcvr-rtt=all:10000 stat-summary=loss,dup,jitt,TTL voip-metrics
a=record:off
m=audio 49328 RTP/AVP 96 97 98 0 8 18 101 99 100
a=rtpmap:96 opus/48000/2
a=fmtp:96 useinbandfec=1
a=rtpmap:97 speex/16000
a=fmtp:97 vbr=on
a=rtpmap:98 speex/8000
a=fmtp:98 vbr=on
a=fmtp:18 annexb=yes
a=rtpmap:101 telephone-event/48000
a=rtpmap:99 telephone-event/16000
a=rtpmap:100 telephone-event/8000
a=rtcp:60905
a=rtcp-fb:* trr-int 5000
a=rtcp-fb:* ccm tmmbr

下面我们逐行分析

INVITE sip:Administrator@192.168.2.218 SIP/2.0

INVITE 发起新会话指令,sip:Administrator@192.168.2.218 为目标用户,SIP/2.0表示使用协议SIP/2.0。

Via: SIP/2.0/UDP 192.168.31.178:62837;branch=z9hG4bK.8WiAEUPjC;rport

Via 头部:指示请求的传输路径,SIP/2.0/UDP 192.168.31.178:62837 通过SIP/2.0 UDP协议,经过192.168.31.178:62837。

From: <sip:alice@192.168.31.178>;tag=4tYbJ32O3 From 头部:指示请求的发起者,alice为用户标识,IP为192.168.31.178。

To: sip:Administrator@192.168.2.218 To 头部:表示请求的接收者。sip:Administrator@192.168.2.218 是被呼叫方的 URI。

CSeq: 20 INVITE CSeq 头部:指示请求的序列号和类型。20 是序列号,INVITE是请求的方法类型。此序列号用于匹配请求和响应,确保它们的顺序。

Call-ID: q~Nno8HNkb Call-ID 头部:用于唯一标识一个会话。该ID应在整个会话中保持不变。

Max-Forwards: 70 Max-Forwards 头部:指示请求在路由中可以经过的最大代理数量。每经过一个代理,此值减一,达到零时请求会被丢弃。

Supported: replaces, outbound, gruu, path, record-aware

Supported 头部:列出了被请求方支持的特性和扩展,例如:

Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO, PRACK, UPDATE

Allow 头部:列出发起方支持的方法,表示可以在会话中使用的 SIP 方法。

Content-Type: application/sdp

Content-Type 头部:指示报文体的类型为 SDP(Session Description Protocol),用于描述会话的媒体参数

Content-Length: 551

Content-Length 头部:指示消息体的长度,单位为字节。

Contact: <sip:192.168.2.2:62837;transport=udp>;+org.linphone.specs="conference/1.0,lime"

Contact 头部:提供了可以用来联系发起者的 URI。此处的 URI 是一个可能用于后续通信的地址。+org.linphone.specs 提供了与 Linphone 客户端相关的扩展信息。

User-Agent: Linphone-Desktop/5.2.6

User-Agent 头部:表示发起请求的客户端软件和版本,这里是 Linphone 的桌面版本。

总的来说:alice@192.168.31.178 向 Administrator@192.168.2.218 发起呼叫,SIP 消息body为SDP协议,这里为媒体协商。

对等性

由于SIP支持在UDP传输,UDP本身是无连接的,在网络通的情况可以直接进行呼叫。通常我们用alice呼叫bob做示例,这里我本地Mac为alice@192.168.31.178,目标Windows主机Administrator@192.168.2.218。

呼叫流程:

alice                 Administrator
|                     |
|    INVITE           |
|-------------------->|
|    100 Trying       |
|<--------------------|
|    180 Ringing      |
|<--------------------|
|    200 OK           |
|<--------------------|
|    ACK              |
|-------------------->|
|                     |
|<---RTP------------->|
|<---RTP------------->|
|<---RTP------------->|
|    ...              |
|                     |
|    BYE              |
|-------------------->|
|    200 OK           |
|-------------------->|
|                     |

抓个包

SIP点对点呼叫

  1. alice 向 Administrator 发起呼叫
  2. Administrator 响应 100 Trying,表示正常尝试呼叫
  3. 180 Ringing 表示 Administrator 已响铃
  4. 200 OK 表示呼叫建立成功
  5. ACK 确认呼叫建立
  6. BYE alice 挂机
  7. 200 OK(BYE) 回应 BYE 指令

背靠背代理

虽然 SIP 可以点对点呼叫,但实际网络环境复杂,除非是局域网内,大多数都是无法完成点对点呼叫(可能涉及 NA T相关),这是需要一个 SIP 代理作为中转。

alice 呼叫 bob,实际先和背靠背代理建立了呼叫,这里是 FreeSWITCH,FreeSWITCH 呼叫 bob,bob 接通电话后,FreeSWITCH 将两通电话桥接起来,这样就实现了 alice 到 bob 的通话。关于 FreeSWITCH 后续文章还会介绍到。

背靠背呼叫流程:

                      FreeSWITCH
   alice             (B2BUA Server)             bob
     |                    | |                    |
     |      INVITE     F1 | |                    |
     |------------------->| |                    |
     |    100 Trying   F2 | |                    |
     |<-------------------| |       INVITE    F3 |
     |                    | |------------------->|
     |                    | |    100 Trying   F4 |
     |                    | |<-------------------|
     |                    | |    180 Ringing  F5 |
     |   180 Ringing   F6 | |<-------------------|
     |<-------------------| |                    |
     |                    | |       200 OK    F7 |
     |      200 OK     F8 | |<-------------------|
     |<-------------------| |         ACK     F9 |
     |         ACK    F10 | |------------------->|
     |------------------->| |                    |
     |      RTP Media     | |      RTP Media     |
     |<==================>| |<==================>|
     |        BYE     F11 | |                    |
     |------------------->| |        BYE     F12 |
     |      200 OK    F13 | |------------------->|
     |<-------------------| |       200 OK   F14 |
     |                    | |<-------------------|
     |                    | |                    |

补充

SDP(Session Description Protocol,会话描述协议)是一种用于描述多媒体会话的标准格式。SIP协议消息body即SDP协议,在呼叫中主要用于协商媒体。

RTP(Real-time Transport Protocol,实时传输协议)是一种用于在IP网络上实时传输音频和视频数据的网络协议。SIP确认了会话,SDP确认了语音编码,RTP为实际语音传输。

RTP通常运行在UDP上,相对于丢包,语音对实时性要求更高。

参考