作者:gnuhpc
出處:http://www.cnblogs.com/gnuhpc/
1.目標
兼容標准、易用性、效率達到> 1000 tps 、占用空間< 1 MB、可移植、支持Windows、並且SIP安全
2.應用
嵌入式電話、軟終端、網關、代理、B2BUA、IM/狀態服務器、客戶端。
3.特性
支持協議:UDP, TCP, TLS, IPv6
SIP協議:RFC3261全兼容
懶惰解析器:當應用程序請求時僅僅解析頭部。
編程特性:面向對象接口,支持單線程和多線程
異步DNS,並且支持NAPTR/SRV
平台: Windows, Linux,BSD, Solaris, QNX, OS/X
支持Multi-homed hosts,即a host
with multiple addresses
安全方面: MIME & S/MIME
方便開發方面:User Agent Library (DUM)
可擴展性上有所實現。
4.支持的RFC及草案
Supported RFCs:
– 2327: SDP
– 2617: HTTP Digest
– 2782: DNS SRV
– 2915: DNS NAPTR
– 2976: sip INFO
– 3261: sip
– 3263: Locating sip servers
– 3265: subscribe/notify
– 3420: sipfrag
– 3325: network asserted id
– 3428: sip MESSAGE
– 3326: reason header
– 3515: sip REFER
– 3581: symmetric response
In Development
– 3323: Privacy mechanism
– 3262: Reliable provisional
– 3264: Offer/Answer
– 3266: IPv6 in SDP
– 3311: UPDATE
– draft-simple-winfo
– draft-sip-session-timer
– draft-sip-caller-prefs
Drafts: (partial list)
– draft-impp-srv, draft-simple-presence
– draft-sip-replaces, draft-sip-referredby
– Draft-sip-connect-reuse
– draft-sip-join, sip-gruu
– sip-publish, sipping-mwi
5.架構
6.代碼下載編譯(Ubuntu9.04環境)
1)外部庫:
Gnu Perfect Hash :哈希功能產生器。sudo apt-get install gperf
Open SSL :使用DTLS時。sudo apt-get install libssl-dev
POPT : 用於解析命令行的庫。sudo apt-get install libpopt0 libpopt-dev
Perl Compatible Regular Expression Library : Perl的增則表達式庫。sudo apt-get install libpcre3-dev
Berkeley DB :一個小型數據庫產品, Repro,——Resiprocate Proxy使用。sudo apt-get install libdb4.2++-dev
Boost : 使用TFM (the testing framework)。sudo apt-get install libboost-dev
總結起來,在ubuntu環境下的要安裝的命令是:sudo aptitude update; sudo aptitude install subversion g++ gperf libssl-dev libpopt-dev libpcre3-dev libdb4.2++-dev libboost-dev
2)SVN獲取代碼
SVN 獲取resiproctae代碼: svn checkout https://svn.resiprocate.org/rep/resiprocate/main resiprocate 在你當前目錄下就會有一個resiprocate子目錄。
3)構建
cd resoprocate
./configure
你會被問到一些問題,你只需要按回車就能選定默認的方式。在問到 時需要進行如下修改(你可以看看你的這個文件在哪):
Where is db_cxx.h?
[/usr/include/db4] /usr/include
Where is popt.h?
[/usr/local/include] /usr/include
Where is libpopt?
[/usr/local/lib] /usr/lib
當然你也可以通過一個菜單項的東西進行編譯: ./configure -m ,只要 你的終端支持 vt100-style 。具體的一些編譯參數可以參見 Configuration Options
然后:sudo make
使用sudo確保一些不必要的權限問題。
Trouble Shooting:
你要是發現bad interpeter 這樣的錯誤信息,那八成是你在Windows下SVN出的代碼導致的format問題,建議刪除后在Linux下進行重新的svn checkout
4)測試
首先先裝一個抓包分析軟件:wireshark
在ubuntu9.04時安裝該軟件,運行時會出現bus error的問題,據說是和某個版本的GTK沖突……后來我升級到了9.10就ok了。注意在啟動時,命令行啟動要用sudo,否則會出現找不到網絡設備的問題: sudo wireshark &
會出現提示說有危險,這個可以忽略。
在filter里面輸入sip,然后按apply鍵。
運行: resiprocate/resip/stack/test/testClient debug 'sip:user1@localhost;transport=udp'
可以看到抓到幾個INVITE包。
在工具欄選擇“ Telephony” ->“ VoIP calls” , 可以看到一個呼叫發起。
環境:ubuntu9.10 IP:192.168.1.100
一.配置測試Linphone
Linphone是一個比較著名的開源軟件,作為測試終端,我們需要先安裝配置好它。
安裝:sudo apt-get install linphone
運行后首先設置一個默認賬戶,其他選擇默認選項即可:
1.打開終端。
2.在命令行提示符處輸入 sipomatic。
3.啟動 Linphone。
4.輸入 sip:robot@192.168.1.100:5064 作為 SIP 地址並單擊致電或應答。
5.如果 Linphone 配置正確,則聽到電話鈴聲,稍后將聽到一個簡短聲明。
二.測試resiprocate下的testClient
首先運行wireshark,設定好監聽本地端口,然后在filter中填入sip以抓取SIP消息包
然后運行在resiprocate下的/resip/stack/test里面的testClient,具體命令行為:
./testClient debug 'sip:gnuhpc@192.168.1.100;transport=udp'
此時會有響鈴聲,你可以選擇接受,接收后Client會發送BYE消息終止,然后再INVITE,此時你可以再選擇Decline,從wireshark下看抓包就可以看到一些信令交互了
三.測試resiprocate下的testServer
運行在resiprocate下的/resip/stack/test里面的testServer,具體命令行為:
./testServer debug 5 udp
啟動一個UAS,現在我們使用Linphone作為UAC向<sip:testServer@192.168.1.100:5070>發起一個呼叫。
通過Linphone的狀態欄我們看到呼叫被接受,然后我們掛機。
我們可以完整的看到信令交互。
代碼分析:
[cpp:collapse] + expand sourceview plaincopy
終端中打印的調試信息
warmbupt@pchuang:/windows/MyCode/resiprocate$ resip/stack/test/testServer debug 5 udp
Choosing Debug level since string was not understood: debug
DEBUG | 20100223-223126.561 | testServer | RESIP | 3077773008 | ssl/Security.cxx:867 | BaseSecurity::BaseSecurity
INFO | 20100223-223126.562 | testServer | RESIP:DNS | 3077773008 | dns/AresDns.cxx:190 | DNS initialization: found 2 name servers
INFO | 20100223-223126.562 | testServer | RESIP:DNS | 3077773008 | dns/AresDns.cxx:193 | name server: 202.102.224.68
INFO | 20100223-223126.562 | testServer | RESIP:DNS | 3077773008 | dns/AresDns.cxx:193 | name server: 202.102.227.68
DEBUG | 20100223-223126.562 | testServer | RESIP | 3077773008 | Compression.cxx:40 | COMPRESSION SUPPORT NOT COMPILED IN
DEBUG | 20100223-223126.562 | testServer | RESIP | 3077773008 | Compression.cxx:43 | Compression configuration object created; algorithm = 0
DEBUG | 20100223-223126.563 | testServer | RESIP:TRANSPORT | 3077773008 | TransportSelector.cxx:93 | No compression library available
DEBUG | 20100223-223126.563 | testServer | RESIP:TRANSPORT | 3077773008 | InternalTransport.cxx:86 | Creating fd=3 V4/UDP
DEBUG | 20100223-223126.563 | testServer | RESIP:TRANSPORT | 3077773008 | InternalTransport.cxx:94 | Binding to 0.0.0.0
INFO | 20100223-223126.563 | testServer | RESIP:TRANSPORT | 3077773008 | UdpTransport.cxx:48 | Creating UDP transport host= port=5070 ipv4=1
DEBUG | 20100223-223126.563 | testServer | RESIP:TRANSPORT | 3077773008 | UdpTransport.cxx:62 | No compression library available: Transport: [ V4 0.0.0.0:5070 UDP target domain=unspecified mFlowKey=3 ]
DEBUG | 20100223-223126.563 | testServer | RESIP:DNS | 3077773008 | DnsUtil.cxx:434 | Considering: lo -> 127.0.0.1 flags=0x49
DEBUG | 20100223-223126.563 | testServer | RESIP:DNS | 3077773008 | DnsUtil.cxx:444 | ignore because: interface is loopback
DEBUG | 20100223-223126.563 | testServer | RESIP:DNS | 3077773008 | DnsUtil.cxx:434 | Considering: wlan0 -> 192.168.1.107 flags=0x1043
DEBUG | 20100223-223126.563 | testServer | RESIP:DNS | 3077773008 | DnsUtil.cxx:463 | using this
DEBUG | 20100223-223126.563 | testServer | RESIP | 3077773008 | SipStack.cxx:225 | Adding domain alias: 127.0.0.1:5070
DEBUG | 20100223-223126.563 | testServer | RESIP | 3077773008 | SipStack.cxx:225 | Adding domain alias: 192.168.1.107:5070
DEBUG | 20100223-223126.563 | testServer | RESIP:TRANSPORT | 3077773008 | TransportSelector.cxx:196 | Adding transport: [ V4 0.0.0.0:5070 UDP target domain=unspecified mFlowKey=0 ]
INFO | 20100223-223126.563 | testServer | RESIP:TEST | 3077770096 | testServer.cxx:37 | This is the Server
DEBUG | 20100223-223133.933 | testServer | RESIP:TRANSPORT | 3077770096 | Transport.cxx:287 | incoming from: [ V4 192.168.1.107:5060 UDP target domain=unspecified mFlowKey=3 ]
DEBUG | 20100223-223133.933 | testServer | RESIP | 3077770096 | Helper.cxx:375 | Helper::makeResponse(SipReq: INVITE testServer@192.168.1.107:5070 tid=437909975 cseq=INVITE contact=warmbupt@192.168.1.107:5060 / 20 from(wire) code=100 reason=
DEBUG | 20100223-223133.933 | testServer | RESIP:TRANSACTION | 3077770096 | TimerQueue.cxx:85 | Adding timer: Timer Trying tid=437909975 ms=80
DEBUG | 20100223-223133.933 | testServer | RESIP:TRANSACTION | 3077770096 | TransactionState.cxx:2145 | Send to default TU:
INVITE sip:testServer@192.168.1.107:5070 SIP/2.0
Via: SIP/2.0/UDP 192.168.1.107:5060;rport=5060;branch=z9hG4bK437909975
Max-Forwards: 70
Contact: <sip:warmbupt@192.168.1.107:5060>
To: <sip:testServer@192.168.1.107:5070>
From: <sip:warmbupt@192.168.1.107>;tag=1530548280
Call-ID: 1226925604
CSeq: 20 INVITE
Subject: Phone call
Content-Type: application/sdp
User-Agent: Linphone/3.1.2 (eXosip2/3.3.0)
Content-Length: 294
v=0
o=warmbupt 123456 654321 IN IP4 192.168.1.107
s=A conversation
c=IN IP4 192.168.1.107
t=0 0
m=audio 7078 RTP/AVP 111 110 0 8 101
a=rtpmap:111 speex/16000/1
a=rtpmap:110 speex/8000/1
a=rtpmap:0 PCMU/8000/1
a=rtpmap:8 PCMA/8000/1
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-11
DEBUG | 20100223-223133.933 | testServer | RESIP | 3077770096 | SipStack.cxx:502 | RECV: SipReq: INVITE testServer@192.168.1.107:5070 tid=437909975 cseq=INVITE contact=warmbupt@192.168.1.107:5060 / 20 from(wire)
ERR | 20100223-223133.933 | testServer | RESIP:TEST | 3077770096 | testServer.cxx:63 | Server received: INVITE
DEBUG | 20100223-223133.933 | testServer | RESIP | 3077770096 | Helper.cxx:375 | Helper::makeResponse(SipReq: INVITE testServer@192.168.1.107:5070 tid=437909975 cseq=INVITE contact=warmbupt@192.168.1.107:5060 / 20 from(wire) code=180 reason=
ERR | 20100223-223133.933 | testServer | RESIP:TEST | 3077770096 | testServer.cxx:69 | Sent 180
DEBUG | 20100223-223133.933 | testServer | RESIP | 3077770096 | SipStack.cxx:319 | SEND: SipResp: 180 tid=437909975 cseq=INVITE contact=fluffy@pchuang.cn.ibm.com:5070 / 20 from(tu)
DEBUG | 20100223-223133.933 | testServer | RESIP | 3077770096 | Helper.cxx:375 | Helper::makeResponse(SipReq: INVITE testServer@192.168.1.107:5070 tid=437909975 cseq=INVITE contact=warmbupt@192.168.1.107:5060 / 20 from(wire) code=200 reason=
ERR | 20100223-223133.934 | testServer | RESIP:TEST | 3077770096 | testServer.cxx:74 | Sent 200
DEBUG | 20100223-223133.934 | testServer | RESIP | 3077770096 | SipStack.cxx:319 | SEND: SipResp: 200 tid=437909975 cseq=INVITE contact=fluffy@pchuang.cn.ibm.com:5070 / 20 from(tu)
DEBUG | 20100223-223133.934 | testServer | RESIP:TRANSPORT | 3077770096 | InternalTransport.cxx:86 | Creating fd=4 V4/UDP
DEBUG | 20100223-223133.934 | testServer | RESIP:TRANSPORT | 3077770096 | TransportSelector.cxx:566 | Looked up source for destination: [ V4 192.168.1.107:5060 UDP target domain=unspecified mFlowKey=3 ] -> [ V4 192.168.1.107:0 UDP target domain=unspecified mFlowKey=3 ] sent-by=192.168.1.107 sent-port=5060
DEBUG | 20100223-223133.934 | testServer | RESIP:TRANSPORT | 3077770096 | TransportSelector.cxx:945 | Transmitting to [ V4 192.168.1.107:5060 UDP target domain=unspecified mFlowKey=3 ] tlsDomain= via [ V4 192.168.1.107:5070 UDP target domain=unspecified mFlowKey=3 ]
SIP/2.0 180 Ringing
Via: SIP/2.0/UDP 192.168.1.107:5060;rport=5060;branch=z9hG4bK437909975
Contact: <sip:fluffy@pchuang.cn.ibm.com:5070;transport=UDP>
To: <sip:testServer@192.168.1.107:5070>;tag=2c609410
From: <sip:warmbupt@192.168.1.107>;tag=1530548280
Call-ID: 1226925604
CSeq: 20 INVITE
Content-Length: 0
sigcomp id=
DEBUG | 20100223-223133.934 | testServer | RESIP:TRANSPORT | 3077770096 | Transport.cxx:213 | Adding message to tx buffer to: [ V4 192.168.1.107:5060 UDP target domain=unspecified mFlowKey=3 ]
DEBUG | 20100223-223133.934 | testServer | RESIP:TRANSPORT | 3077770096 | TransportSelector.cxx:566 | Looked up source for destination: [ V4 192.168.1.107:5060 UDP target domain=unspecified mFlowKey=3 ] -> [ V4 192.168.1.107:0 UDP target domain=unspecified mFlowKey=3 ] sent-by=192.168.1.107 sent-port=5060
DEBUG | 20100223-223133.934 | testServer | RESIP:TRANSPORT | 3077770096 | TransportSelector.cxx:945 | Transmitting to [ V4 192.168.1.107:5060 UDP target domain=unspecified mFlowKey=3 ] tlsDomain= via [ V4 192.168.1.107:5070 UDP target domain=unspecified mFlowKey=3 ]
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.1.107:5060;rport=5060;branch=z9hG4bK437909975
Contact: <sip:fluffy@pchuang.cn.ibm.com:5070;transport=UDP>
To: <sip:testServer@192.168.1.107:5070>;tag=2c609410
From: <sip:warmbupt@192.168.1.107>;tag=1530548280
Call-ID: 1226925604
CSeq: 20 INVITE
Content-Length: 0
sigcomp id=
DEBUG | 20100223-223133.934 | testServer | RESIP:TRANSPORT | 3077770096 | Transport.cxx:213 | Adding message to tx buffer to: [ V4 192.168.1.107:5060 UDP target domain=unspecified mFlowKey=3 ]
DEBUG | 20100223-223133.934 | testServer | RESIP:TRANSACTION | 3077770096 | TimerQueue.cxx:85 | Adding timer: Timer StaleServer tid=437909975 ms=32000
DEBUG | 20100223-223134.002 | testServer | RESIP:TRANSPORT | 3077770096 | Transport.cxx:287 | incoming from: [ V4 127.0.1.1:5060 UDP target domain=unspecified mFlowKey=3 ]
DEBUG | 20100223-223134.002 | testServer | RESIP:TRANSACTION | 3077770096 | TransactionState.cxx:2145 | Send to default TU:
ACK sip:fluffy@pchuang.cn.ibm.com:5070;transport=UDP SIP/2.0
Via: SIP/2.0/UDP 192.168.1.107:5060;rport=5060;branch=z9hG4bK471088285;received=127.0.1.1
Max-Forwards: 70
Contact: <sip:warmbupt@192.168.1.107:5060>
To: <sip:testServer@192.168.1.107:5070>;tag=2c609410
From: <sip:warmbupt@192.168.1.107>;tag=1530548280
Call-ID: 1226925604
CSeq: 20 ACK
User-Agent: Linphone/3.1.2 (eXosip2/3.3.0)
Content-Length: 0
DEBUG | 20100223-223134.002 | testServer | RESIP | 3077770096 | SipStack.cxx:502 | RECV: SipReq: ACK fluffy@pchuang.cn.ibm.com:5070 tid=471088285 cseq=ACK contact=warmbupt@192.168.1.107:5060 / 20 from(wire)
ERR | 20100223-223134.002 | testServer | RESIP:TEST | 3077770096 | testServer.cxx:63 | Server received: ACK
DEBUG | 20100223-223140.898 | testServer | RESIP:TRANSPORT | 3077770096 | Transport.cxx:287 | incoming from: [ V4 127.0.1.1:5060 UDP target domain=unspecified mFlowKey=3 ]
DEBUG | 20100223-223140.898 | testServer | RESIP | 3077770096 | Helper.cxx:375 | Helper::makeResponse(SipReq: BYE fluffy@pchuang.cn.ibm.com:5070 tid=2023412367 cseq=BYE contact=warmbupt@192.168.1.107:5060 / 21 from(wire) code=100 reason=
DEBUG | 20100223-223140.899 | testServer | RESIP:TRANSACTION | 3077770096 | TimerQueue.cxx:85 | Adding timer: Timer Trying tid=2023412367 ms=3500
DEBUG | 20100223-223140.899 | testServer | RESIP:TRANSACTION | 3077770096 | TransactionState.cxx:2145 | Send to default TU:
BYE sip:fluffy@pchuang.cn.ibm.com:5070;transport=UDP SIP/2.0
Via: SIP/2.0/UDP 192.168.1.107:5060;rport=5060;branch=z9hG4bK2023412367;received=127.0.1.1
Max-Forwards: 70
Contact: <sip:warmbupt@192.168.1.107:5060>
To: <sip:testServer@192.168.1.107:5070>;tag=2c609410
From: <sip:warmbupt@192.168.1.107>;tag=1530548280
Call-ID: 1226925604
CSeq: 21 BYE
User-Agent: Linphone/3.1.2 (eXosip2/3.3.0)
Content-Length: 0
DEBUG | 20100223-223140.899 | testServer | RESIP | 3077770096 | SipStack.cxx:502 | RECV: SipReq: BYE fluffy@pchuang.cn.ibm.com:5070 tid=2023412367 cseq=BYE contact=warmbupt@192.168.1.107:5060 / 21 from(wire)
ERR | 20100223-223140.899 | testServer | RESIP:TEST | 3077770096 | testServer.cxx:63 | Server received: BYE
DEBUG | 20100223-223140.899 | testServer | RESIP | 3077770096 | Helper.cxx:375 | Helper::makeResponse(SipReq: BYE fluffy@pchuang.cn.ibm.com:5070 tid=2023412367 cseq=BYE contact=warmbupt@192.168.1.107:5060 / 21 from(wire) code=200 reason=
ERR | 20100223-223140.899 | testServer | RESIP:TEST | 3077770096 | testServer.cxx:81 | Sent 200 to BYE
DEBUG | 20100223-223140.899 | testServer | RESIP | 3077770096 | SipStack.cxx:319 | SEND: SipResp: 200 tid=2023412367 cseq=BYE contact=fluffy@pchuang.cn.ibm.com:5070 / 21 from(tu)
DEBUG | 20100223-223140.899 | testServer | RESIP:TRANSACTION | 3077770096 | TimerQueue.cxx:85 | Adding timer: Timer J tid=2023412367 ms=32000
DEBUG | 20100223-223140.899 | testServer | RESIP:TRANSPORT | 3077770096 | TransportSelector.cxx:566 | Looked up source for destination: [ V4 127.0.1.1:5060 UDP target domain=unspecified mFlowKey=3 ] -> [ V4 127.0.1.1:0 UDP target domain=unspecified mFlowKey=3 ] sent-by=192.168.1.107 sent-port=5060
DEBUG | 20100223-223140.899 | testServer | RESIP:TRANSPORT | 3077770096 | TransportSelector.cxx:945 | Transmitting to [ V4 127.0.1.1:5060 UDP target domain=unspecified mFlowKey=3 ] tlsDomain= via [ V4 127.0.1.1:5070 UDP target domain=unspecified mFlowKey=3 ]
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.1.107:5060;rport=5060;branch=z9hG4bK2023412367;received=127.0.1.1
Contact: <sip:fluffy@pchuang.cn.ibm.com:5070;transport=UDP>
To: <sip:testServer@192.168.1.107:5070>;tag=2c609410
From: <sip:warmbupt@192.168.1.107>;tag=1530548280
Call-ID: 1226925604
CSeq: 21 BYE
Content-Length: 0
sigcomp id=
DEBUG | 20100223-223140.899 | testServer | RESIP:TRANSPORT | 3077770096 | Transport.cxx:213 | Adding message to tx buffer to: [ V4 127.0.1.1:5060 UDP target domain=unspecified mFlowKey=3 ]