1 电话是如何打通的

古时候很远的两个人如果想要交流,就要使用飞鸽或者白马等来送信,那么在网络中的两个人又用什么送信来实现交流呢。在IP电话中,这个小小的信使叫做信令。SIP信令有两种,request和response。常用的request有REGISTER 、INVITE、ACK、CANCEL、BYE、OPTIONS。而response一般都是1xx、2xx、3xx、4xx、5xx、6xx。


1.1 信使的行程

下面就是会话建立的一个过程,在这个过程中,Alice想要和Bob通信,小小的信使经过proxy这个驿站后把Alice的想法告诉了Bob,Bob想了想决定同意和Alice通信,小小的信使又原路返回把Bob的决定告诉Alice,然后Alice想要告诉Bob我已经知道你要和我通信的心意了,于是小小的信使又跑到Bob那里。类似TCP的三次握手,这样就确定了一个会话。

Alice's softphone           proxy                       Bob's softphone
192.168.126.52:57180        192.168.126.102:5060        192.168.126.52:57181

         |                          |                            |
         |      INVITE F1           |                            |		 
         |------------------------->|                            |
         |		100 Trying F2        |                            |
         |<-------------------------|                            |
         |                          |        INVITE F3           |
		 |                          |--------------------------->|
		 |                          |        180 Ringing F4      |
         |                          |<---------------------------|
         |		180 Ringing F5       |                            |
		 |<-------------------------|                            |
		 |                          |        200 OK F6           |
         |                          |<---------------------------|
		 |      200 OK F7           |                            |
         |<-------------------------|                            |		 
		 |      ACK F8              |                            |
		 |------------------------->|                            |
		 |                          |        ACK F9              |
         |                          |--------------------------->|	
         |                                                       |	
         |                                                       |			 
         |                    Media Session                      |
         |<=====================================================>|	
         |

说明:

F1:Alice打电话给Bob,发送INVITE到proxy。

F2:proxy收到Alice的INVITE后,回复100 Trying告诉Alice proxy正在处理该请求。

F3:proxy转发INVITE给Bob。

F4:Bob收到INVITE后回复180 Ringing,告诉proxy已经收到INVITE。

F5:proxy转发180 Ringing,告诉Alice Bob已经收到INVITE。

F6:Bob成功接听电话,发送200 OK给proxy。

F7:proxy转发200 OK,告诉Alcie Bob已经同意接听电话。

F8:Alice收到200 OK后发送ACK,告诉proxy Alice已经知道Bob同意了。

F9:proxy转发ACK给Bob。

整个过程的SIP包在附录中。


1.2 信封要怎么写

像传统的信封一样,SIP也需要记录收信人的姓名、收信人的地址、发信人的姓名以及发信人的地址。在SIP中,它们在这样的字段中:

From:包含请求发起者的逻辑标志,用来显示发信人的姓名。

To:是第一个并且也是最先指定请求的”逻辑”接收地,用来显示收信人的姓名。

Contact:和传统信封中发信人的地址类似,提供访问后续请求的联系方法,即是说,在通话建立后,如果想要再发送request,比如INFO,就可以发送到这个地址上。


2 proxy都做了什么?

2.1 Record-Route:请一定要经过我

如果想要后续操作仍然经过proxy,就要添加Record-Route,这样会告诉Alice凡是请求都请发给我。注意:Record-Route头域不用来路由,只是起到传递信息的作用。

2.2 Via:信令所走过的路

via标识了信令走过了哪些设备。以INVITE为例,从Alice到proxy的INVITE F1,从proxy到Bob的INVITE F3,其中关于Via的信息如下:

INVITE F1:
Via: SIP/2.0/TCP 192.168.126.52:57179;branch=z9hG4bK-524287-1---6d8b9b32b1dee257;rport

INVITE F3:
Via: SIP/2.0/TCP 192.168.126.102;branch=z9hG4bK0937.ad1f2488a2e7d2af68a6bcd907094024.1;i=c
Via: SIP/2.0/TCP 192.168.126.52:57179;received=192.168.126.52;branch=z9hG4bK-524287-1---6d8b9b32b1dee257;rport=57180

1. Alice发送INVITE时,记录信令来到了192.168.126.52:57179。

2. proxy收到INVITE时,记录信令来到了192.168.126.102。

这些记录可以让response可以原路返回。


2.3 Max-Forwards:防止迷路的计数君

信令可能会经过很多路由,如果路由太多,或者进入了死循环,信令就会迟迟到达不了目的地,而Alice就要傻傻等下去。这时,使用Max-Forwards来限制信令可以走过的最大路由数,如果达到了上限,就回复483给Alice,不会让Alice一直等下去。

以INVITE为例,从Alice到proxy的INVITE F1,从proxy到Bob的INVITE F3,其中关于Max-Forwards的信息如下:

INVITE F1:
Max-Forwards: 70

INVITE F3:
Max-Forwards: 69

上述例子中:Max-Forward最大值为70,当路过proxy后,自动减1,当Max-Forward减为0且未到目的,则回复483。

2.4 SDP:请把媒体发送到这里(使用媒体代理的情况下)

在使用媒体代理的情况下,proxy会修改SDP相关信息,告诉UA之后将媒体流发送到这个新的地方。以INVITE为例,从Alice到proxy的INVITE F1,从proxy到Bob的INVITE F3,其中关于SDP的信息如下:

INVITE F1:
o=- 13082545712077426 1 IN IP4 192.168.126.52
c=IN IP4 192.168.126.52
m=audio 50150 RTP/AVP 9 8 0 84 101

INVITE F3:
o=- 13082545712077426 1 IN IP4 192.168.126.102
c=IN IP4 192.168.126.102
m=audio 59910 RTP/AVP 9 8 0 84 101
a=nortpproxy:yes

3 响应应该怎样填写?

应答中的 From 头域必须和请求中的 From 头域相等。

应答中的 Call-ID 头域必须和请求中的 Call-ID 头域相等。

应答中的 Cseq 头域必须和请求中的 Cseq 头域相等。

应答中的 Via 头域必须和请求中的 Via 头域相等,而且顺序也必须相等。

如果请求中包含了 To tag,那么应答中的 To 头域必须和请求中的 To 头域相等。

如果请求中的 To 头域并不包含 Tag, 那么应答中的 To 头域的 URI 必须和请求中

的 To 头域的 URI 相等;此外,UAS 还必须增加一个 Tag 到 To 头域上(100 Trying除外)。


4 附录:SIP包

F1

INVITE sip:200@192.168.126.102 SIP/2.0
Via: SIP/2.0/TCP 192.168.126.52:57179;branch=z9hG4bK-524287-1---6d8b9b32b1dee257;rport
Max-Forwards: 70
Contact: <sip:400@192.168.126.52:57180;rinstance=c253e0b1bc382d30;transport=tcp>
To: <sip:200@192.168.126.102>
From: "400"<sip:400@192.168.126.102>;tag=1425661d
Call-ID: 76589ZjliMDYxMTc3NDcwZDliMjAwNDYyZGZlNzExODgwOWM
CSeq: 1 INVITE
Allow: SUBSCRIBE, NOTIFY, INVITE, ACK, CANCEL, BYE, REFER, INFO, MESSAGE
Content-Type: application/sdp
User-Agent: X-Lite 4.8.4 76589-c909bfce-W6.1
Content-Length: 245

v=0
o=- 13082545712077426 1 IN IP4 192.168.126.52
s=X-Lite release 4.8.4 stamp 76589
c=IN IP4 192.168.126.52
t=0 0
m=audio 50150 RTP/AVP 9 8 0 84 101
a=rtpmap:84 speex/16000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=sendrecv

F2

SIP/2.0 100 trying -- your call is important to us
Via: SIP/2.0/TCP 192.168.126.52:57179;branch=z9hG4bK-524287-1---6d8b9b32b1dee257;rport=57180;received=192.168.126.52
To: <sip:200@192.168.126.102>
From: "400"<sip:400@192.168.126.102>;tag=1425661d
Call-ID: 76589ZjliMDYxMTc3NDcwZDliMjAwNDYyZGZlNzExODgwOWM
CSeq: 1 INVITE
Server: kamailio (4.3.0 (x86_64/linux))
Content-Length: 0

F3

INVITE sip:200@192.168.126.52:57181;transport=TCP;rinstance=7c3f84a3df98f77a SIP/2.0
Record-Route: <sip:192.168.126.102;transport=tcp;lr;nat=yes>
Via: SIP/2.0/TCP 192.168.126.102;branch=z9hG4bK0937.ad1f2488a2e7d2af68a6bcd907094024.1;i=c
Via: SIP/2.0/TCP 192.168.126.52:57179;received=192.168.126.52;branch=z9hG4bK-524287-1---6d8b9b32b1dee257;rport=57180
Max-Forwards: 69
Contact: <sip:400@192.168.126.52:57180;rinstance=c253e0b1bc382d30;transport=tcp;alias=192.168.126.52~57180~2>
To: <sip:200@192.168.126.102>
From: "400"<sip:400@192.168.126.102>;tag=1425661d
Call-ID: 76589ZjliMDYxMTc3NDcwZDliMjAwNDYyZGZlNzExODgwOWM
CSeq: 1 INVITE
Allow: SUBSCRIBE, NOTIFY, INVITE, ACK, CANCEL, BYE, REFER, INFO, MESSAGE
Content-Type: application/sdp
User-Agent: X-Lite 4.8.4 76589-c909bfce-W6.1
Content-Length: 265

v=0
o=- 13082545712077426 1 IN IP4 192.168.126.102
s=X-Lite release 4.8.4 stamp 76589
c=IN IP4 192.168.126.102
t=0 0
m=audio 59910 RTP/AVP 9 8 0 84 101
a=rtpmap:84 speex/16000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=sendrecv
a=nortpproxy:yes

F4

SIP/2.0 180 Ringing
Via: SIP/2.0/TCP 192.168.126.102;branch=z9hG4bK0937.ad1f2488a2e7d2af68a6bcd907094024.1;i=c
Via: SIP/2.0/TCP 192.168.126.52:57179;received=192.168.126.52;branch=z9hG4bK-524287-1---6d8b9b32b1dee257;rport=57180
Record-Route: <sip:192.168.126.102;transport=tcp;lr;nat=yes>
Contact: <sip:200@192.168.126.52:57181;transport=TCP;rinstance=7c3f84a3df98f77a>
To: <sip:200@192.168.126.102>;tag=9c20bb58
From: "400"<sip:400@192.168.126.102>;tag=1425661d
Call-ID: 76589ZjliMDYxMTc3NDcwZDliMjAwNDYyZGZlNzExODgwOWM
CSeq: 1 INVITE
User-Agent: eyeBeam release 1003s stamp 31159
Content-Length: 0

F5

SIP/2.0 180 Ringing
Via: SIP/2.0/TCP 192.168.126.52:57179;received=192.168.126.52;branch=z9hG4bK-524287-1---6d8b9b32b1dee257;rport=57180
Record-Route: <sip:192.168.126.102;transport=tcp;lr;nat=yes>
Contact: <sip:200@192.168.126.52:57181;transport=TCP;rinstance=7c3f84a3df98f77a;alias=192.168.126.52~57181~2>
To: <sip:200@192.168.126.102>;tag=9c20bb58
From: "400"<sip:400@192.168.126.102>;tag=1425661d
Call-ID: 76589ZjliMDYxMTc3NDcwZDliMjAwNDYyZGZlNzExODgwOWM
CSeq: 1 INVITE
User-Agent: eyeBeam release 1003s stamp 31159
Content-Length: 0

F6

SIP/2.0 200 OK
Via: SIP/2.0/TCP 192.168.126.102;branch=z9hG4bK0937.ad1f2488a2e7d2af68a6bcd907094024.1;i=c
Via: SIP/2.0/TCP 192.168.126.52:57179;received=192.168.126.52;branch=z9hG4bK-524287-1---6d8b9b32b1dee257;rport=57180
Record-Route: <sip:192.168.126.102;transport=tcp;lr;nat=yes>
Contact: <sip:200@192.168.126.52:57181;transport=TCP;rinstance=7c3f84a3df98f77a>
To: <sip:200@192.168.126.102>;tag=9c20bb58
From: "400"<sip:400@192.168.126.102>;tag=1425661d
Call-ID: 76589ZjliMDYxMTc3NDcwZDliMjAwNDYyZGZlNzExODgwOWM
CSeq: 1 INVITE
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO
Content-Type: application/sdp
User-Agent: eyeBeam release 1003s stamp 31159
Content-Length: 244

v=0
o=- 1 2 IN IP4 192.168.126.52
s=CounterPath eyeBeam 1.5
c=IN IP4 192.168.126.52
t=0 0
m=audio 59554 RTP/AVP 0 84 101
a=fmtp:101 0-15
a=rtpmap:101 telephone-event/8000
a=sendrecv
a=x-rtp-session-id:AECB168AB3C548A8922EB5B93760A965

F7

SIP/2.0 200 OK
Via: SIP/2.0/TCP 192.168.126.52:57179;received=192.168.126.52;branch=z9hG4bK-524287-1---6d8b9b32b1dee257;rport=57180
Record-Route: <sip:192.168.126.102;transport=tcp;lr;nat=yes>
Contact: <sip:200@192.168.126.52:57181;transport=TCP;rinstance=7c3f84a3df98f77a;alias=192.168.126.52~57181~2>
To: <sip:200@192.168.126.102>;tag=9c20bb58
From: "400"<sip:400@192.168.126.102>;tag=1425661d
Call-ID: 76589ZjliMDYxMTc3NDcwZDliMjAwNDYyZGZlNzExODgwOWM
CSeq: 1 INVITE
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO
Content-Type: application/sdp
User-Agent: eyeBeam release 1003s stamp 31159
Content-Length: 264

v=0
o=- 1 2 IN IP4 192.168.126.102
s=CounterPath eyeBeam 1.5
c=IN IP4 192.168.126.102
t=0 0
m=audio 41922 RTP/AVP 0 84 101
a=fmtp:101 0-15
a=rtpmap:101 telephone-event/8000
a=sendrecv
a=x-rtp-session-id:AECB168AB3C548A8922EB5B93760A965
a=nortpproxy:yes

F8

ACK sip:200@192.168.126.52:57181;transport=TCP;rinstance=7c3f84a3df98f77a;alias=192.168.126.52~57181~2 SIP/2.0
Via: SIP/2.0/TCP 192.168.126.52:57179;branch=z9hG4bK-524287-1---a4523b3d055a4a3f;rport
Max-Forwards: 70
Route: <sip:192.168.126.102;transport=tcp;lr;nat=yes>
Contact: <sip:400@192.168.126.52:57180;rinstance=c253e0b1bc382d30;transport=tcp>
To: <sip:200@192.168.126.102>;tag=9c20bb58
From: "400"<sip:400@192.168.126.102>;tag=1425661d
Call-ID: 76589ZjliMDYxMTc3NDcwZDliMjAwNDYyZGZlNzExODgwOWM
CSeq: 1 ACK
User-Agent: X-Lite 4.8.4 76589-c909bfce-W6.1
Content-Length: 0

F9

ACK sip:200@192.168.126.52:57181;transport=TCP;rinstance=7c3f84a3df98f77a SIP/2.0
Via: SIP/2.0/TCP 192.168.126.102;branch=z9hG4bK0937.f859752293a9e7cb6a34a63f8b364a4f.0;i=c
Via: SIP/2.0/TCP 192.168.126.52:57179;received=192.168.126.52;branch=z9hG4bK-524287-1---a4523b3d055a4a3f;rport=57180
Max-Forwards: 69
Contact: <sip:400@192.168.126.52:57180;rinstance=c253e0b1bc382d30;transport=tcp;alias=192.168.126.52~57180~2>
To: <sip:200@192.168.126.102>;tag=9c20bb58
From: "400"<sip:400@192.168.126.102>;tag=1425661d
Call-ID: 76589ZjliMDYxMTc3NDcwZDliMjAwNDYyZGZlNzExODgwOWM
CSeq: 1 ACK
User-Agent: X-Lite 4.8.4 76589-c909bfce-W6.1
Content-Length: 0