摘要:針對SIP服務在部署中出現的“單點失效”、“性能瓶頸”以及P2P的標準化與互聯互通、NAT穿越、安全與授權和用戶移動性等問題,提出了基于P2P技術的SIP服務網絡的結構。給出了實現方案,重點分析了P2P-SIP網絡處理注冊和呼叫的流程。
關鍵詞:SIP;P2P;Chord算法;P2P-SIP Node
引言
SIP(session Initiation Protoc01)是一個類似于HTTP和SMTP的基于文本的信令協議,主要被用來開發和實現VoIP、語音,視頻會議、文本聊天、即時消息、交互游戲等業務的系統和終端。SIP服務器在運行的過程中也存在一些不足,最典型的是“單點失效”和“性能瓶頸”問題。
P2P(peer-to-peer)是一種基于對等的計算模型和基于對等的應用層重疊網絡架構。純P2P模式的應用系統只存在對等的客戶端。P2P充分利用了客戶端的內容、計算、帶寬等資源,其擴展性極強。但也存在一些缺陷:標準化與互聯互通問題、NAT穿越問題、安全和授權問題和用戶移動性問題。
P2P和SIP在某些方面的功能是互補的,本項目用P2P(Point to Point,點對點)機制解決了上述SIP的兩個問題。本文把網絡節點分為超級和普通兩種。超級節點通過P2P機制互聯,為普通節點提供注冊服務。當超級節點失效時,它所管理的普通節點會注冊到其他超級節點上,避免了“單點失效”。當網絡處理能力不夠時,部分普通節點會轉換成超級節點以增大網絡容量,打破了“性能瓶頸”。
1 基于SlP的P2P的Chord算法
Chord是結構化的oveday。所謂overlay,是指P2P系統在物理連接的基礎上構建的邏輯網絡。而結構化的overlay,是指在overlay中,特定的資源由特定的節點管理;對資源的查詢,就是根據某種路由規則,找到管理該資源的特定節點。Chord使用SHA-1哈希算法,哈希值為m個比特。2m個可能值分布在圓周上,稱做Chord環,如圖1所示。

圖1中N表示節點,N后的數字是該節點的哈希值,一般通過哈希節點的IP地址得到。K表示資源,K后的數字是該資源的哈希值。Chord用在SIP中時,K應該是SIP URI,例如sip:baogxm@163.com。在Chord中,每個節點都負責管理一段哈希空問——順時針方向上之前一個節點到自己的范圍,哈希值落在該空間中的資源K的信息由本節點保存。例如節點N32就負責管理資源K24和K30的信息(圖1中指向N32的實線箭頭所示)。
比如節點N8要詢問資源K30的信息時,N8首先要找到負責管理K30的節點N32。最簡單的做法是N8詢問順時針方向緊隨其后的節點,叫做N8的后繼節點(successor),即N14。如果N14不負責K30,則N14詢問自己的successor,即N21。該操作反復進行,直至找到負責K30的節點N32為止。
2 基于Chord算法的P2P-SIP體系結構
在IETF的設計中,每個SIP節點同時也是P2P節點。節點間地位平等。這種設計要求對現有SIP設備做重大改動,而且無法將SIP服務作商業化運營。本項目的設計充分考慮到SIP服務的商業化和電信級運營要求,在不改動現有終端設備的情況下,只對現有SIP服務器的軟件做很小改動。(為區別于傳統的SIP服務器,把P2P化的SIP服務器叫做P2P-SIP Node,簡稱PN。)其體系結構如圖2所示。
在P2P-SIP網絡中,原來管理一個域的單臺服務器變成多臺PN,PN之間通過P2P機制互聯,彼此分擔負載。PN可以承擔原來服務中壓力最大的部分,比如注冊、代理和計費。用戶連接到任一PN,都可以有效使用服務。部分PN下線或故障不會影響到P2P-SIP網絡的正常運行。要擴大P2P-SIP網絡的容量,只需加入新的PN。PN在地理上分散到各處,邏輯上可以是環形的(chord協議)、矩陣的(cAN協議)、網狀的(Pastry協議和Tapestry協議)。PN分為兩層。上面是SIP層,處理標準的SIP信令;下面是P2P層,使用特定的機制(本文的設計選用Chord協議)互聯各個PN的P2P層并維持它們之間的聯系。P2P層提供給SIP層的應用程序編程接口(API)只有函數find_responsible_pn(user)(該函數返回負責管理該user的PN的IP地址和端口)。基本的PN至少包括注冊和代理兩種功能。由于P2P-SIP網絡是動態的,所以負責管理某個用戶的PN在不同時段可能是不同的。為進行商業運營,可以部署全局認證服務器、全局賬務服務器和網管服務器等等,用于管理全部的用戶和所有的PN。其他的服務(比如語音和視頻會議、語音郵箱、PSTN落地(即呼叫座機和手機)、自動和人工語音應答等)可以部署在PN上,也可以作為單臺服務器或服務器網絡的形式接入P2P-SIP網絡。
3 P2P-SlP網絡的實現
3.1 PN的工作機理
在PN的配置文件中設有一個配置項,其值是“IP地址:端口”或“域名:端口”的形式。若存在多個值時,以空格分開。其值也可以為空(表示本PN是P2P-SIP網絡的第一個節點)。值格式錯誤時,忽略該值。
PN啟動時,如果發現配置項的值為空,PN的Chord層就新建一個Chord環。如果配置項存在一個或多個值,Chord層就依次向這些值發送請求直至收到成功應答。如果最終沒有收到成功應答,就提示錯誤或者新建一個Chord環。PN進入P2P-SIP網絡后,即PN的Chord層加入到Chord環中,需要從其successor處拷貝一份用戶注冊信息。
PN正常退出P2P-SIP網絡時,需要將自己管理的用戶注冊信息發給自己的successor。非正常退出時,P2P-SIP網絡會暫時丟失部分用戶的注冊信息。為保證注冊過的用戶始終可達,可以讓PN周期性地將它管理的用戶注冊信息通告自己的successor,甚至successor的successor。
P2P-S1P網絡的維護是PN的Chord層來做的。每個PN的Chord層都周期性地更新自己的successor.predecessor和finger表,從而及時地了解網絡的變化。
3.2請求處理過程
按照RFC3261的規定,SIP服務器(主要指代理服務器)處理請求時與請求的方法無關。下面我們通過詳細描述用戶的注冊和呼叫過程,來說明P2P-SIP網絡中PN處理請求的實現方法。
3.2.1用戶注冊過程
對用戶而言,注冊到P2P-SIP網絡的過程和注冊到SIP網絡的過程是相同的。只是在P2P-SIP網絡中,PN收到注冊請求時,并不立即記錄該條注冊信息,而是先調用函數find_responsible_pn(user)。如果返回的地址是PN自己,這才記錄下用戶注冊信息;如果返回的地址是其他PN,則PN會把注冊請求轉發給相應的PN。最終,注冊請求會被轉發到負責處理它的PN處,處理后產生的應答按原路返回。其步驟如下:
(1)終端發注冊請求
IP地址為210.41.35.199的SIP終端準備好REGISTER請求,發給P2P-SIP網絡中任一PN(假設Key為69的PN。)。如圖3中M1所示。SIP終端可以通過多種方式獲得PN的IP地址和端口。比如用戶手動指定,或者使用終端默認的PN,或者使用終端上次進入P2P-SIP網絡時更新的PN列表。
(2)PN轉發請求
Key值為69的PN收到REGISTER請求后,取得請求中To頭域里的SIP URI——表示注冊的信息屬于哪個用戶,調用find_responsible_pn(user)。返回值應該是“IP地址:端口”字符串。將返回值同本機“IP地址:端口”作比較,如果相同,則本機負責處理該請求,之后的處理流程遵循SIP標準;如果不同,就轉發REGISTER請求到該“IP地址:端口”。 在本例中,SIP URI對應的哈希值假定是17,PN的Chord層會查找到負責處理該請求的PN Key值是32,find_responsible_pn(user)返回該PN的“ip地址:端口”——210.41.35.200:5060。PN的SIP層判斷該值發現不是自己,就將注冊請求轉發到該“ip地址:端口”,如圖3中M2所示。

(3)PN接受注冊,返回應答
Key值為32的PN收到REGISTER請求后,取得請求中To頭域里的SIP URI,調用find_responsible_pn(user)。返回值是210.41.35.200:5060,比較后發現是自己,說明自己負責管理該用戶,負責處理該用戶的注冊請求。之后的處理流程遵循SIP標準。假定注冊成功,PN返回200 OK應答。如圖3中M3所示。應答的返回遵循SIP標準,根據Via頭域按原路返回,不需要查找路徑,不會使用Chord層的操作。
(4)SIP終端收到應答,完成注冊
Key值為69的PN收到來自210.41.35.200:5060的應答,按照SIP標準處理,把應答發給192.168.13.63:5060。如圖3中M4所示。SIP終端收到200 OK應答,完成注冊。
3.2.2用戶呼叫過程
在p2P-SIpt網絡中,PN收到INVITE請求,進行必要處理后,取出請求中To頭域里的SIP URI(表示呼叫哪個用戶),調用find_responsible_pn(user)。如果返回值是PN自己,說明PN負責管理To頭域所標識的用戶,PN具有該用戶的注冊信息,之后的處理按SIP標準流程;如果不是,則PN將INVITE請求轉發給find_responsible_pn(user)返回的“IP地址:端口”。具體的呼叫過程如圖4所示。

(1)IP發起呼叫
IP地址為210.41.35.199的用戶要呼叫用戶。userA可以把請求發給P2P-SIP網絡中任一PN。考慮到要在P2P-SIP網絡上提供增值業務(比如計費),userA把INVITE請求發給管理它的PN更合適一點。在本例中是IP為210.41.35.195,Key值為0的PN。如圖4中M1所示。
(2)PN轉發請求到PN
Key值為0的PN收到INVITE請求后,取得請求中To頭域里的SIP URI,調用find_responsible_pn(user)。返回值是210.41.35.200:5060。比較后發現不是自己,將請求轉發給210.41.35.200:5060。如圖4中M2所示。
(3)PN轉發請求到被叫
IP地址為210.41.35.200的PN收到該請求,進行相同的處理。發現返回值是自己,說明PN管理該用戶,擁有該用戶的注冊請求。之后的處理流程遵循SIP標準,即在本地取得用戶userB的當前地址,然后轉發請求到該地址。如圖4中M3所示。
(4)被叫接受呼叫,返回應答
用戶userB所在的SIP終端收到該請求,按照SIP標準進行處理。假定userB接受呼叫請求,則返回200 OK應答。如圖4中M4所示。
(5)應答沿原路返回
應答的返回遵循SIP標準,根據Via頭域按原路返回,不需要查找路徑,不會使用Chord層的操作。如圖4中M5、M6所示。
(6)主叫收到應答,發出確認,建立呼叫
用戶userA所在的SIP終端收到200 OK應答,用ACK請求進行確認。ACK請求不經過P2P-SIP網絡,直接發給用戶userB所在的SIP終端。如圖4中M7所示。用戶userB所在的SIP終端收到ACK確認請求,呼叫建立。結束通話時,userB和userA直接交換SIP信令,不經過P2P-SIP網絡。
4 結束語
本文通過對原有的SIP軟交換平臺的改造,在PN上實現了注冊、呼叫和計費功能;同時也提供了具有語音郵箱和自動應答功能的單臺媒體服務器接入P2P-SIP網絡的實現技術。