Original Reference:Understanding SIP traces
大部分为直译,少部分意译,以注解的形式包含一些补充,英文好建议看原帖,本人水平有限,翻译不准确的地方烦请批评指教。
一些有用的学习参考:
https://www.cs.columbia.edu/sip/
https://www.cs.columbia.edu/sip/syntax/
https://blog.csdn.net/alwaysrun/article/details/107621509
https://blog.csdn.net/alwaysrun/article/details/111768003
SIP trace 提供解决SIP(Session Initiation Protocol,会话初始协议)中继,SIP端点和其他SIP相关问题的关键信息。
本文尝试使用一种实用的方法来分解SIP交互的每个组件。我们将查看各种Log、SIP消息、报头(Header)、SDP信息,并试图弄清楚在SIP语音呼叫事务中发生了什么。
故障排除的一个关键要素是:要解决问题,你需要了解问题,了解它是如何工作的,然后才能使其恢复正常。
在cisco IOS路由器上对sip解决方案进行故障排除时常用的一个调试方法是:Debug ccsip messages
为了理解这个调试产生的输出,我们需要理解在sip语音呼叫期间交换的关键/基本sip消息:
我们将在尝试理解调试时查看这些消息,这些信息是了解情况的关键。他们帮助我们理解所说的语言,这样我们就不会像一个在巴黎不会说法语的人一样迷路了。
好了,语法说够了,让我们开始吧!准备好了吗?
INVITE是一个SIP请求方法,在SIP规范文档RFC3261中描述了6种SIP方法:INVITE
、REGISTER
、BYE
、ACK
、CANCEL
和OPTIONS
,这是SIP中最初的六个方法。
INVITE方法用于在用户代理(UA,user agent,拥有SIP协议能力的终端设备称为用户代理)中建立媒体会话(media session)。在电话中,它类似于ISDN中的设置消息。
注:
对于UA来说,只要有user就行了,这个user虽然大部分时候是人,也可以不是人,比如另一个需要SIP服务的上层协议。
User Agent分Client和Server,UAC--User Agent Client,UAS--User Agent Server。实际上在一个会话当中,一个User Agent可以同时扮演UAC和UAS的角色:
UAC用于发起请求(request),而UAS用于产生响应(response)。
INVITE消息通常有一个消息体,其中包含了呼叫方(caller)的媒体信息。消息体也可以包含其他的会话信息,例如提前提议(early offer)下的资源列表。如果INVITE消息不包含媒体信息,则ACK包含UAC的媒体信息。
注:
在SIP(Session Initiation Protocol)中,Early Offer是一种呼叫建立过程中的协商方式。它指的是在呼叫建立阶段,被叫方可以在接听呼叫前向主叫方发送一个包含SDP(Session Description Protocol)信息的SIP消息,以便在呼叫建立时协商媒体流的相关参数,例如编解码器、传输协议等。
Early Offer也可以被称为“提前提议”,它与“延迟提议”(Delayed Offer)相对应。在Delayed Offer模式下,主叫方会先向被叫方发送一个SIP INVITE请求,等待被叫方响应后再发送包含SDP信息的SIP消息。这种模式通常用于需要进行媒体流加密或者需要进行媒体流转发等场景。
总之,Early Offer是一种可以提高呼叫建立速度和降低网络延迟的协商方式,但需要注意其对网络带宽和性能的影响。
为了区分主叫,被叫号码,媒体信息和资源包含在INVITE消息中,SIP INVITE消息使用标头,它是INVITE消息中的关键参数,我们将查看它们来弄清楚正在发生的事情。
让我们来看一下来自CUCM的一个示例SIP追踪 。注意这与调试ccsip消息在CUBE网关上产生的结果非常相似。
以下是该追踪的呼叫设置:
CUCM----------sip trunk------>CUBE---------SIP Trunk--------------->ITSP
(10.105.80.114) (10.105.80.174)
带SDP的INVITE消息:
INVITE sip:[email protected]:5060 SIP/2.0
Via: SIP/2.0/UDP 10.105.80.114:5060;branch=z9hG4bK98e4117d52a6
From: "Solihull" ;tag=25526~ffa80926-5fac-4dd6-b405-2dbbc56ae9a2-551664735
To:
Date: Mon, 02 Apr 2012 18:12:31 GMT
Call-ID: [email protected]
Supported: timer,resource-priority,replaces
Min-SE: 1800
User-Agent: Cisco-CUCM8.6
Allow: INVITE, OPTIONS, INFO, BYE, CANCEL, ACK, PRACK, UPDATE, REFER, SUBSCRIBE, NOTIFY
CSeq: 101 INVITE
Expires: 180
Allow-Events: presence, kpml
Supported: X-cisco-srtp-fallback
Supported: Geolocation
Call-Info: ;method="NOTIFY;Event=telephone-event;Duration=500"
Cisco-Guid: 1752700672-0000065536-0000007823-0237529354
Session-Expires: 84600
Contact:
Max-Forwards: 70
Content-Length: 0
Content-Type: application/sdp
Content-Length: 238
v=0
o=CiscoSystemsCCM-SIP 811669 1 IN IP4 10.105.40.14
s=SIP Call
c=IN IP4 10.133.92.102
t=0 0
m=audio 25268 RTP/AVP 18 101
a=rtpmap:18 G729/8000
a=ptime:20
a=fmtp:18 annexb=no
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
我们现在来剖析一下上面的信息,我们可以看到在INVITE信息中有非常多的标头:
Via
To
From
Call-ID
CSeq
Contact
Max-Forwards
Expires
…
INVITE sip:[email protected]:5060 SIP/2.0
这是这个trace的第一部分,通常被称为Request-URI,它展示了四个关键内容:
1.被叫号码
2.负责被叫号码的设备或者被叫号码将通过(routed,路由or转接?)的设备
3.SIP端口号
4.SIP版本
这里我们看到被叫号码是:14107584528207
负责路由到该号码的网关是10.105.80.174
SIP协议端口为5060,版本为2.0
Via: SIP/2.0/UDP 10.105.80.114:5060;branch=z9hG4bK98e4117d52a6
Via报头字段用来记录请求所采用的SIP路由,并用于将响应路由回始发方。生成请求的UA在Via报头字段中记录自己的地址。
这里我们看到CUCM是生成此邀请的UA,并在呼叫中标记自己的IP,这有助于识别呼叫的来源。Via报头字段包含协议名称,版本号和传输(SIP/2.0/UDP, SIP/2.0/TCP等)
Via报头包含所谓的发送域(sent-by field)。如:10.105.80.114:5060,这是所需的响应将被发送到的地方。
在SIP中,响应遵循Via报头,除了像ACK和BYE这种发送给联系人报头(contact header)的将来的请求。
From: sip:[email protected];tag=25526~ffa80926-5fac-4dd6-b405-2dbbc56ae9a2-551664735
To: sip:[email protected] Date: Mon, 02 Apr 2012 18:12:31 GMT 时间报头,SIP消息的关键组件,其告诉我们SIP请求的时间。 Call-ID: [email protected] Call-ID报头字段是用于跟踪特定SIP会话的标识符。请求的发起者创建一个本地唯一的字符串。一些较旧的实现还在字符串中添加了“@”及其主机名。生成建立INVITE的会话发起方生成唯一的Call-ID和From标签。 Call ID是故障排除中使用的关键组件之一。每个UA生成自己的Call ID。因此,当呼叫来自CUCM时,CUCM生成自己的呼叫id,而当呼叫来自CUBE时,CUBE生成自己的呼叫id。 CSeq: 101 INVITE 命令序列(command sequence),即CSeq报头字段,是每个请求中必需的报头字段。CSeq报头字段包含一个对每个请求递增的十进制数。通常对于每个新请求,它都会增加1,但CANCEL和ACK请求除外,它们使用它所引用的INVITE请求的CSeq号。UASs使用CSeq计数来确定乱序(out-of-sequence)请求或区分新请求(不同的CSeq)或重传(相同的CSeq)。UAC使用CSeq报头字段来匹配对它引用的请求响应 User-Agent: Cisco-CUCM8.6 SDP扩展和属性 应用程序/SDP报头中使用的SDP扩展列出了主叫方愿意接收、协商或支持会话的媒体能力。下表显示了该测试调用中的SDP属性以及每个属性/扩展的含义。请注意,RFC 3264[17]规定包含“a=rtpmap”的属性应该用于每个媒体字段 让我们看看下面的媒体属性: Audio:表示这是一个音频通话,我们也可以在视频通话的情况下使用m=video 25268:用于呼叫的动态RTP端口 RTP/AVP:表示列出的每个配置文件的RTP/AVP配置文件编号。下面解释了配置文件编号: 现在我们已经了解了sip报头和消息的基础知识,让我们用它来理解下面的sip跟踪。 ITSP: 10.10.33.132 1. 在CUBE上接收来自ITSP的入站呼叫。这个邀请是用SDP发送的。注意,此呼叫的入站分支将具有唯一的呼叫ID,显示呼叫的起源,如下所示。 根据我们对追踪的理解,我们看到呼叫来自一个名为Broadworks的设备,该设备发布G711a, G711u, G729,并使用rtp-nte进行DTMF。我们还看到CUBE要将其RTP流传输到的IP地址 2. 发送给CUCM的新邀请 当CUBE接收到INVITE消息后,会根据配置的拨号对等体(dial peers)向CUCM发送INVITE消息。 注意:这个新的邀请是用一个新的CALL-ID发送的。这对于理解事情的顺序非常重要,尤其是在故障排除问题时。我们还可以看到CUBE发布了它所有的SDP属性、编解码器、dtmf支持、fax等。 3.接下来,CUBE向ITSP发送一个TRYING。Trying简单地说就是:我正在找你所请求的号码。 4. 接下来,CUBE接收来自CUCM的TRYING,CALL-ID帮助我们了解这些响应来自哪里。 5. 接下来,CUBE从CUCM接收RINGING,这通知CUBE被叫终端正在振铃 6. CUBE将此消息转发给主叫方 7. 现在CUBE接收到来自CUCM的200 OK。请注意,SDP的一些元素已经改变 8. CUBE向CUCM发送ACK以确认最后的200 OK消息 9. 然后CUBE基于从CUCM接收到的信息向ITSP发送带有用于呼叫的SDP属性的200 OK。 10. 然后CUBE接收一个ACK 11. 最后通话结束。在进行故障排除时,呼叫终止的方向很重要。在本例中,我们可以看到CUBE接收到BYE,这是用于呼叫终止的sip方法。但是谁发送了BYE,是CUCM还是ITSP…答案在Call-ID中。当我们调用时,可以看到call - id是来自ITSP的腿。所以我们看到呼叫是从ITSP端终止的。 接下来一个重要的事情是cause code,通话终止的原因。 这里我们看到一个常见的呼叫终止Cause=16。 ① Q: 当手机取消注册时…你会得到这个 Q: 无论您在inbound dial-peer的语音类编解码器(voice-class codec)上配置什么,区域设置都会生效。这是因为当发送 200 ok 时,CUCM 将发送端点和 CUBE 之间定义的编解码器作为编解码器。然后 CUBE 将其传递给 ITSP。 +++OUTBOUND LEG++++ 在outbound方向上: 如果编解码器是硬编码的…如果其设置为 g711,则将从 ITSP 获取 g711 响应,并且该编解码器将用于call。 如果您在 ITSP 和 CUCM 之间有 CUBNE。那么ITSP和CUCM之间就不能直接协商。你不需要透明编解码器(Codec transparency)来让CUCM 决定在inbound方向使用哪个编解码器。CUCM 将始终按照上面说的那样执行此操作。Codec transparency仅支持H.323-to-H.323 呼叫 丢包、抖动和延迟始终为零。有什么原因吗? 例如在第一个INVITE中,没有消息正文,因此我们的内容长度为“0” 在下一个INVITE中,我们在INVITE中有一个消息体(SDP),因此我们有一个内容类型(这将告诉我们在消息体中有什么样的内容),然后是内容长度 对于你的下一个问题: CUBE和CUCM是B2BUA。这意味着它们既可以发起请求,又可以同时提供对请求的响应。B2BUA结合了UAC和UAS的功能。UAC是发起请求的用户代理客户端,而UAS是生成请求响应的用户代理服务器。 代理服务器会中继请求和响应,因此CUBE不是代理服务器。代理在大多数情况下只是充当客户机和终止服务器之间的中间人。 CUCM不是典型的注册服务器。它执行注册服务器的一些功能。典型的注册服务器(也称为注册服务器)接受SIP注册请求;所有其他请求都会收到501 Not Implemented响应。但就像我说的,CUCM做的不仅仅是接受sip REGISTER请求
From和To报头字段显示了SIP请求的始发者和目的地。
需要注意的是:
To和From报头字段在响应消息中并不会像大家预期的那样翻转,这是因为这两个报头字段是被定义来指示请求(request)的方向而不是消息发送的方向。From标头中显示
此报头标识发起此请求/响应的UA。在这个跟踪中,我们可以看到上面的UA是CUCM 8.6版本。用户代理报头有助于识别请求/响应的发起者。
SDP:Session Description Protocol,是一种会话描述协议,用于描述多媒体会话的参数。
SDP Parameter
Name
v=0
Version Number
o=CiscoSystemsCCM-SIP 811669 1 IN IP4 10.105.40.14
Origin
s=SIP Call
Call Subject
c=IN IP4 10.133.92.102
Connection/IP address for RTP stream
t=0 0
time
m=audio 25268 RTP/AVP 18 101
Media
a=rtpmap:18 G729/8000
Attributes-media
a=ptime:20
Attributes-Packetization
a=rtpmap:101 telephone-event/8000
Dtmf attributes
a=fmtp:101 0-15
Dtmf tones
m=audio 25268 RTP/AVP 18 0 8 101
这一行定义了将用于调用的媒体属性。
二、解析SIP追踪
呼叫流程如下所示:
PSTN-------->ITSP------->CUBE---------->CUCM-------->IP PHONE
CUBE:10.100.0.74
CUCM:10.100.0.14Received:
INVITE sip:[email protected]:5060 SIP/2.0
Via: SIP/2.0/UDP 10.10.33.24:5070;branch=z9hG4bK9377fo00cg5ha7l0g3t0.1
From:
002791: Jun 6 16:07:28.394: //260863/8C38FA5E95E3/SIP/Msg/ccsipDisplayMsg:
Sent:
INVITE sip:[email protected]:5060 SIP/2.0
Via: SIP/2.0/TCP 10.100.0.74:5060;branch=z9hG4bK7953C1859
Remote-Party-ID:
002792: Jun 6 16:07:28.394: //260862/8C38FA5E95E3/SIP/Msg/ccsipDisplayMsg:
Sent:
SIP/2.0 100 Trying
Via: SIP/2.0/UDP 10.10.33.24:5070;branch=z9hG4bK9377fo00cg5ha7l0g3t0.1
From:
002793: Jun 6 16:07:28.396: //260863/8C38FA5E95E3/SIP/Msg/ccsipDisplayMsg:
Received:
SIP/2.0 100 Trying
Via: SIP/2.0/TCP 10.100.0.74:5060;branch=z9hG4bK7953C1859
From:
002794: Jun 6 16:07:28.412: //260863/8C38FA5E95E3/SIP/Msg/ccsipDisplayMsg:
Received:
SIP/2.0 180 Ringing
Via: SIP/2.0/TCP 10.100.0.74:5060;branch=z9hG4bK7953C1859
From:
002795: Jun 6 16:07:28.412: //260862/8C38FA5E95E3/SIP/Msg/ccsipDisplayMsg:
Sent:
SIP/2.0 180 Ringing
Via: SIP/2.0/UDP 10.10.33.24:5070;branch=z9hG4bK9377fo00cg5ha7l0g3t0.1
From:
Parameter
Explaintion
c=IN IP4 10.100.20.10
IP address to send RTP stream to
t=0 0
Duration of the call
m=audio 16730 RTP/AVP 18 101
Codec to use for call and DTMF type to use
a=rtpmap:18 G729/8000
Codec = G729
002796: Jun 6 16:07:28.556: //260863/8C38FA5E95E3/SIP/Msg/ccsipDisplayMsg:
Received:
SIP/2.0 200 OK
Via: SIP/2.0/TCP 10.100.0.74:5060;branch=z9hG4bK7953C1859
From:
002797: Jun 6 16:07:28.556: //260863/8C38FA5E95E3/SIP/Msg/ccsipDisplayMsg:
Sent:
ACK sip:[email protected]:5060;transport=tcp SIP/2.0
Via: SIP/2.0/TCP 10.100.0.74:5060;branch=z9hG4bK7953DC95
From:
Sent:
SIP/2.0 200 OK
Via: SIP/2.0/TCP 10.100.0.14:5060;branch=z9hG4bK198a0b7ee5d33c
From:
002803: Jun 6 16:07:28.594: //-1/xxxxxxxxxxxx/SIP/Msg/ccsipDisplayMsg:
Received:
ACK sip:[email protected]:5060 SIP/2.0
Via: SIP/2.0/UDP 10.10.33.24:5070;branch=z9hG4bKfj8rji3008r0m4lbg7e0.1
From:
CSeq: 558267842 BYE
Reason: Q.850;cause=16
Received:
BYE sip:[email protected]:5060 SIP/2.0
Via: SIP/2.0/UDP 10.10.33.24:5070;branch=z9hG4bKfj8rji3008r0m4lbg7e0cd1hhq713.1
From:
三、评论与回复
Q:
我在第7步有一个问题,从CUCM收到200 OK
c = IP4 10.110.0.20 ------------------------ IP地址发送RTP流
但我看到在SDP中有c= in IP4 10.100.20.10,
我想这只是打错了??
A:
是的,这是个错别字。我会改正的。我很高兴它帮助了你,谢谢你的反馈
有一个问题,如果SIP话机未注册,CUCM会生成什么消息?
A:
SIP 取消注册是通过发送 REGISTER 消息来执行的,该消息的 Contact 标头包含“expires=0”参数,或者 Expires 标头的值为 0
因此,仍然使用 REGISTER 方法,但过期标头将设置为 0。
例如
当手机第一次注册时,您会得到这个REGISTER sip:titan-pub.sipnet5.com SIP/2.0
Via: SIP/2.0/UDP 5.5.5.7:58632;branch=z9hG4bK-d8754z-da08d10e221f1f0f-1---d8754z-;rport
Max-Forwards: 70
Contact:
REGISTER sip:titan-pub.sipnet5.com SIP/2.0
Via: SIP/2.0/UDP 5.5.5.7:58632;branch=z9hG4bK-d8754z-da08d10e221f1f0f-1---d8754z-;rport
Max-Forwards: 70
Contact:
如果我正确理解了要求:
2.我们希望ITSP和CUCM之间直接进行编解码协商
我们可以在dial-peers中使用“编解码器透明”来让 CUCM 决定编解码器吗?
A:
呼叫的方向决定了谁影响编解码器的选择。
+++INBOUND LEG+++++
在INBOUND LEG上:
将使用向 ITSP 通告的编解码器,因为 ITSP 是根据通告的编解码器决定使用哪种编解码器的一方。因此,对于语音类编解码器,列表中的首选编解码器将由 ITSP 选择,并将用于无论电话上的区域设置如何,都会呼叫多维数据集网关。
如果是 g729 那么它将是 g729…
Q:
一个小小的疑问是,BYE消息中有一个RTP信息。P-RTP-Stat: PS=295,OS=5900,PR=292,OR=5840,PL=0,JI=0,LA=0,DU=5
A:
是的,这是为呼叫提供呼叫统计信息。这有助于解决呼叫质量问题。这通常在BYE消息中发送。
为0可能是因为没有延迟、抖动或数据包丢失。所以没什么好担心的。这意味着你有一个很好的网络
Q:
如果我理解错了,你能让我改正吗?
Supported: replaces ----------------- (This command is supported and can be configured. Correct?)
Supported: sdp-anat
m=audio 29588 RTP/AVP 0 19
a=rtpmap:19 CN/8000
a=inactive
A:
Supported报头用于定义UAC支持的任何sip扩展。Replace报头用于在逻辑上用新的SIP对话(SIP dialog)替换现有的SIPdialog。这用于一些像 “Attended Transfer” and "Call Pickup"之类的特性。
Q:
Content-length的意义是什么?如果Content-length为0或任何其他值,则含义是什么?
CUBE在这里充当代理服务器吗?
CUCM会做注册服务器的功能,对吧?
A:
Content-Length用于表示消息体中八位字节的个数。Content-Length: 0表示没有消息正文。这通常用于指示消息中是否存在SDP(在sip INVITE的情况下)Received:
INVITE sip:[email protected]:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.10.14:5060;branch=z9hG4bK39e91a3ffb2b83
From:
Sent:
INVITE sip:[email protected]:5070 SIP/2.0
Via: SIP/2.0/UDP 192.168.10.200:5060;branch=z9hG4bK10D68412602
Remote-Party-ID: