默認情況下,撥打內部用戶時,freeswitch需要該用戶注冊了才能對其發起呼叫,否則會提示-ERR USER_NOT_REGISTERED
如果使用wireshark等工具,可以在本機使用voip終端工具注冊,抓包觀察一下SIP報文。
注:如果mac上首次使用wireshark時,可能會遇到 you don't have permission to capture on that device mac 之類的權限問題,可參考網友“水麒麟灬”的文章解決。
通過抓包,可以看到大致過程如下:
這4次的報文內容類似下面這樣:
1、第1次REGISTER
Frame 1: 650 bytes on wire (5200 bits), 650 bytes captured (5200 bits) on interface lo0, id 0 Null/Loopback Internet Protocol Version 4, Src: 192.168.7.101, Dst: 192.168.7.101 User Datagram Protocol, Src Port: 5060, Dst Port: 5070 Session Initiation Protocol (REGISTER) Request-Line: REGISTER sip:192.168.7.101:5070;transport=UDP SIP/2.0 Message Header Via: SIP/2.0/UDP 192.168.7.101:5060;branch=z9hG4bK-d8754z-f407689eddfdf19c-1---d8754z-;rport Transport: UDP Sent-by Address: 192.168.7.101 Sent-by port: 5060 Branch: z9hG4bK-d8754z-f407689eddfdf19c-1---d8754z- RPort: rport Max-Forwards: 70 Contact: <sip:1000@192.168.7.101:5060;rinstance=00eb482b7d4631f5>;transport=UDP To: "jimmy"<sip:1000@192.168.7.101:5070>;transport=UDP From: "jimmy"<sip:1000@192.168.7.101:5070>;transport=UDP;tag=e45e4f61 Call-ID: ZGEwYTJkMGY1ODQ2M2Q3ZmY3YWQ3M2JkYWVhODMzNGE. [Generated Call-ID: ZGEwYTJkMGY1ODQ2M2Q3ZmY3YWQ3M2JkYWVhODMzNGE.] CSeq: 1 REGISTER Expires: 3600 Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, NOTIFY, REFER, MESSAGE, OPTIONS, INFO User-Agent: Zoiper rev.1809 Allow-Events: presence Content-Length: 0
首次注冊請求時,並未帶任何用戶名/密碼之類的認證信息。
2、FreeSwitch返回了401
Frame 2: 718 bytes on wire (5744 bits), 718 bytes captured (5744 bits) on interface lo0, id 0 Null/Loopback Internet Protocol Version 4, Src: 192.168.7.101, Dst: 192.168.7.101 User Datagram Protocol, Src Port: 5070, Dst Port: 5060 Session Initiation Protocol (401) Status-Line: SIP/2.0 401 Unauthorized Message Header Via: SIP/2.0/UDP 192.168.7.101:5060;branch=z9hG4bK-d8754z-f407689eddfdf19c-1---d8754z-;rport=5060 Transport: UDP Sent-by Address: 192.168.7.101 Sent-by port: 5060 Branch: z9hG4bK-d8754z-f407689eddfdf19c-1---d8754z- RPort: 5060 From: "jimmy" <sip:1000@192.168.7.101:5070>;transport=UDP;tag=e45e4f61 To: "jimmy" <sip:1000@192.168.7.101:5070>;transport=UDP;tag=p8878HBS6XDrB Call-ID: ZGEwYTJkMGY1ODQ2M2Q3ZmY3YWQ3M2JkYWVhODMzNGE. [Generated Call-ID: ZGEwYTJkMGY1ODQ2M2Q3ZmY3YWQ3M2JkYWVhODMzNGE.] CSeq: 1 REGISTER User-Agent: FreeSWITCH-mod_sofia/1.10.2-release~64bit Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE Supported: timer, path, replaces WWW-Authenticate: Digest realm="192.168.7.101", nonce="84af446e-92ed-418b-96c4-4ad9fee55771", algorithm=MD5, qop="auth" Authentication Scheme: Digest Realm: "192.168.7.101" Nonce Value: "84af446e-92ed-418b-96c4-4ad9fee55771" Algorithm: MD5 QOP: "auth" Content-Length: 0
注意22行的WWW-Authenticate,服務器返回了認證需要的一些信息:realm/nonce/algoritthm/qop,大致可以看出要求使用MD5算法,讓Voip客戶端根據服務端返回的信息,算一個digest值提交上來完成校驗。
3、第2次REGISTER
Frame 3: 904 bytes on wire (7232 bits), 904 bytes captured (7232 bits) on interface lo0, id 0 Null/Loopback Internet Protocol Version 4, Src: 192.168.7.101, Dst: 192.168.7.101 User Datagram Protocol, Src Port: 5060, Dst Port: 5070 Session Initiation Protocol (REGISTER) Request-Line: REGISTER sip:192.168.7.101:5070;transport=UDP SIP/2.0 Message Header Via: SIP/2.0/UDP 192.168.7.101:5060;branch=z9hG4bK-d8754z-b6526a3ade0f8d5b-1---d8754z-;rport Transport: UDP Sent-by Address: 192.168.7.101 Sent-by port: 5060 Branch: z9hG4bK-d8754z-b6526a3ade0f8d5b-1---d8754z- RPort: rport Max-Forwards: 70 Contact: <sip:1000@192.168.7.101:5060;rinstance=00eb482b7d4631f5>;transport=UDP Contact URI: sip:1000@192.168.7.101:5060;rinstance=00eb482b7d4631f5 Contact parameter: transport=UDP To: "jimmy"<sip:1000@192.168.7.101:5070>;transport=UDP SIP to display info: "jimmy" SIP to address: sip:1000@192.168.7.101:5070 SIP to address User Part: 1000 SIP to address Host Part: 192.168.7.101 SIP to address Host Port: 5070 From: "jimmy"<sip:1000@192.168.7.101:5070>;transport=UDP;tag=e45e4f61 SIP from display info: "jimmy" SIP from address: sip:1000@192.168.7.101:5070 SIP from address User Part: 1000 SIP from address Host Part: 192.168.7.101 SIP from address Host Port: 5070 SIP from tag: e45e4f61 Call-ID: ZGEwYTJkMGY1ODQ2M2Q3ZmY3YWQ3M2JkYWVhODMzNGE. [Generated Call-ID: ZGEwYTJkMGY1ODQ2M2Q3ZmY3YWQ3M2JkYWVhODMzNGE.] CSeq: 2 REGISTER Expires: 3600 Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, NOTIFY, REFER, MESSAGE, OPTIONS, INFO User-Agent: Zoiper rev.1809 [truncated]Authorization: Digest username="1000",realm="192.168.7.101",nonce="84af446e-92ed-418b-96c4-4ad9fee55771",uri="sip:192.168.7.101:5070;transport=UDP",response="de6d3ab9e4a984d1a7a62d69cd00a31a",cnonce="c7dafa660149cc55",nc=00000 Authentication Scheme: Digest Username: "1000" Realm: "192.168.7.101" Nonce Value: "84af446e-92ed-418b-96c4-4ad9fee55771" Authentication URI: "sip:192.168.7.101:5070;transport=UDP" Digest Authentication Response: "de6d3ab9e4a984d1a7a62d69cd00a31a" CNonce Value: "c7dafa660149cc55" Nonce Count: 00000001 QOP: auth Algorithm: MD5 Allow-Events: presence Content-Length: 0
可以看到,第2次注冊時,37行Authorization 帶上了username,uri 以及根據服務端要求,計算出來的response digest,以及客戶端的臨時cnonce值。
注:如果對digest計算過程感興趣的同學,可以參考 RFC3261規范及網友的文章
4、FreeSWITCH返回200
Frame 4: 704 bytes on wire (5632 bits), 704 bytes captured (5632 bits) on interface lo0, id 0 Null/Loopback Internet Protocol Version 4, Src: 192.168.7.101, Dst: 192.168.7.101 User Datagram Protocol, Src Port: 5070, Dst Port: 5060 Session Initiation Protocol (200) Status-Line: SIP/2.0 200 OK Message Header Via: SIP/2.0/UDP 192.168.7.101:5060;branch=z9hG4bK-d8754z-b6526a3ade0f8d5b-1---d8754z-;rport=5060 Transport: UDP Sent-by Address: 192.168.7.101 Sent-by port: 5060 Branch: z9hG4bK-d8754z-b6526a3ade0f8d5b-1---d8754z- RPort: 5060 From: "jimmy" <sip:1000@192.168.7.101:5070>;transport=UDP;tag=e45e4f61 SIP from display info: "jimmy" SIP from address: sip:1000@192.168.7.101:5070 SIP from address User Part: 1000 SIP from address Host Part: 192.168.7.101 SIP from address Host Port: 5070 SIP from tag: e45e4f61 To: "jimmy" <sip:1000@192.168.7.101:5070>;transport=UDP;tag=QH20aDvv363aQ SIP to display info: "jimmy" SIP to address: sip:1000@192.168.7.101:5070 SIP to address User Part: 1000 SIP to address Host Part: 192.168.7.101 SIP to address Host Port: 5070 SIP to tag: QH20aDvv363aQ Call-ID: ZGEwYTJkMGY1ODQ2M2Q3ZmY3YWQ3M2JkYWVhODMzNGE. [Generated Call-ID: ZGEwYTJkMGY1ODQ2M2Q3ZmY3YWQ3M2JkYWVhODMzNGE.] CSeq: 2 REGISTER Contact: <sip:1000@192.168.7.101:5060;rinstance=00eb482b7d4631f5>;expires=3600 Contact URI: sip:1000@192.168.7.101:5060;rinstance=00eb482b7d4631f5 Contact parameter: expires=3600 Date: Sun, 23 May 2021 10:23:16 GMT User-Agent: FreeSWITCH-mod_sofia/1.10.2-release~64bit Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE Supported: timer, path, replaces Content-Length: 0
FreeSWITCH收到提交過來的認證信息后,進行驗證,驗證通過后,返回200。(注:如校驗失敗,仍會返回401)。
大致了解注冊過程后,下面來看看SIPp如何測試這個場景:
先寫xml文件:reg.xml

1 <?xml version="1.0" encoding="ISO-8859-1" ?> 2 <!DOCTYPE scenario SYSTEM "sipp.dtd"> 3 4 <scenario name="register"> 5 <send retrans="500"> 6 <![CDATA[ 7 REGISTER sip:[remote_ip] SIP/2.0 8 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] 9 Max-Forwards: 70 10 Contact: sip:[field0]@[local_ip]:[local_port] 11 To: [field0] <sip:[field0]@[remote_ip]:[remote_port]> 12 From: [field0] <sip:[field0]@[local_ip]:[local_port]>;tag=[call_number] 13 Call-ID: [call_id] 14 CSeq: 1 REGISTER 15 Expires: 3600 16 User-Agent: SIPp 17 Content-Length: 0 18 ]]> 19 </send> 20 21 <recv response="401" auth="true"> 22 </recv> 23 24 <send retrans="500"> 25 <![CDATA[ 26 REGISTER sip:[field0]@[remote_ip]:[remote_port] SIP/2.0 27 Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] 28 Max-Forwards: 70 29 Contact: sip:[field0]@[local_ip]:[local_port] 30 [field1] 31 To: [field0] <sip:[field0]@[remote_ip]:[remote_port]> 32 From: [field0] <sip:[field0]@[local_ip]:[local_port]>;tag=[call_number] 33 Call-ID: [call_id] 34 CSeq: 2 REGISTER 35 Expires: 3600 36 User-Agent: SIPp 37 Content-Length: [len] 38 ]]> 39 </send> 40 41 <recv response="200"> 42 </recv> 43 44 <!-- Keep the call open for a while in case the 200 is lost to be --> 45 <!-- able to retransmit it if we receive the 200 again. --> 46 <timewait milliseconds="500"/> 47 48 <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/> 49 <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> 50 </scenario>
第1次REGISTER的SIP內容好寫,但是第2次時,最終計算出來的response md5值如何處理,難道要自己算嗎?當然不用!
SIPp已經按照規范,內部實現了這個digest的計算過程,只需要參考SIPp文檔 中的“SIP authentication”,第2次發起REGISTER時,把username放在單獨的一行中即可(xml中的第30行)
最終執行時, SIPp會根據類似下面的csv文件:reg.csv
SEQUENTIAL 1000;[authentication username=1000 password=1234] 1001;[authentication username=1001 password=1234] 1002;[authentication username=1002 password=1234] 1003;[authentication username=1003 password=1234] 1004;[authentication username=1004 password=1234] 1005;[authentication username=1005 password=1234] 1006;[authentication username=1006 password=1234] 1007;[authentication username=1007 password=1234] 1008;[authentication username=1008 password=1234] 1009;[authentication username=1009 password=1234] 1010;[authentication username=1010 password=1234] 1011;[authentication username=1011 password=1234] 1012;[authentication username=1012 password=1234] 1013;[authentication username=1013 password=1234] 1014;[authentication username=1014 password=1234] 1015;[authentication username=1015 password=1234] 1016;[authentication username=1016 password=1234] 1017;[authentication username=1017 password=1234] 1018;[authentication username=1018 password=1234] 1019;[authentication username=1019 password=1234]
動態從該文件中,取出username及password,然后計算出digest值,發給FreeSWITCH。
運行一下:
sipp 192.168.7.101:5070 -sf reg.xml -inf reg.csv -d 1000 -trace_err -m 20 -aa
注:其中192.168.7.101:5070 為FreeSWITCH的ip和端口。
順利的話,會看出類似上面的結果 ,freeswitch中也可以通過命令驗證:
可以看到20個用戶注冊成功,挑其中1個用戶1001看下詳情:
EXP括號里的內容為過期時間,Auth-User為用戶名,Agent可以看到是通過是SIPp注冊的。
最后提醒一下:需要注冊的用戶,必須是FreeSWITCH中創建好的用戶,如果不存在的用戶,比如:8888
SEQUENTIAL 8888;[authentication username=8888 password=1234]
測試時,FreeSWITCH會返回403
SIP/2.0 403 Forbidden Via: SIP/2.0/UDP 192.168.7.101:5061;branch=z9hG4bK-48936-1-2 From: 8888 <sip:8888@192.168.7.101:5061>;tag=1 To: 8888 <sip:8888@192.168.7.101:5070>;tag=07jyp9tgU8r2c Call-ID: 1-48936@192.168.7.101 CSeq: 2 REGISTER User-Agent: FreeSWITCH-mod_sofia/1.10.2-release~64bit Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE Supported: timer, path, replaces Content-Length: 0
從FreeSWITCH控制台,也能觀察到錯誤輸入: