第三章 SIPv6 Translator系統實作原理
3.1 SIP-ALG實作方法一
在初期開發 SIP-ALG 模組過程中,為了方便程式除錯與驗證程式的正確性,程式
(本章指的是 SIP-ALG 程式)一開始會先從輸入緩衝區讀入 SIP 訊息,然後再解析 SIP 訊息的結構,並儲存到一個資料結構中,之後即可對 SIP 與 SDP 的欄位內容進行處理。
程式最後再將資料結構中的 SIP 訊息依照 RFC3261 所定義的格式寫入輸出緩衝區,我 們稱此為 SIP-ALG 實作方法一。圖 3-1 詳列 SIP-ALG 實作方法一的程式流程。
步驟○1 :由於 ALG Dispatcher 將 SIP 封包在輸入緩衝區的記憶體位址以及 SIP 封包轉 換後在輸出緩衝區的記憶體位址當作參數傳進本程式,因此一開始程式直接
Start
1. RequestLineHandler () Is SIPStartLine Request
Line?
1. Search the specific Header
FieldName fromSIPMessageHeader .
2. SIP Header Field Handler (1) ContactHandler () (2) FromHandler() (3) ToHandler() (4) ViaHandler()
(5) RecordRouteHandler () (6) RouteHandler()
Is
SIPMessageBodyType
SDP ?
1. SDP Field Handler
(1). ConnectionFieldHandler () (2). OriginFieldHandler
2. ContentLengthHandler ()
End 1. Write the modified
SIPmessage to
Output Buffer.
2. Return the modified Length to ALG Dispatcher
Yes
1. Read SIP message from Input Buffer .
2. Parse and Store (1). Request/Status Line (2). Message Header (3). Message Body into struct SIPMessage .
1
(a) Structure SIP Message
(b) Process SIP Start Line
(c) Process SIP Message Header
(d) Process SIP Message Body
圖 3-1 SIP-ALG 實作方法一流程圖
INVITE sip:0944400001@3ffe:3600:2::140.113.1.2 … SIP Message Type
INVITE_REQUEST
SIP First Line (Request/Status Line)
SIP Message Body SIP Message Header
Call-ID From
…
sip:0944600001@3ffe:3600:1::3
To sip:0944400001@3ffe:3600:2::140.113.1.3 …
….
….
Field Name Field Value
SDP
SIP Message Body Type
SIP Message Body Content
v o
….
…
… IN IP6 3ffe:3600:1::3 c IN IP6 3ffe:3600:1::3
….
Field Name Field Value
圖 3-2 struct SIPMessage 資料結構之範例
從輸入緩衝區讀入此 SIP 訊息,並以一個 SIPMessage 資料結構來儲存 SIP 訊息的結構(如圖 3-2 所示)。在 SIPMessage 資料結構中,包括 enum
SIPMessageType、SIPStartLine 字串、SIPMessageHeader 資料結構以及 SIPMessageBody 資料結構。SIPMessageType 儲存兩項資訊,第一項說
明此 SIP 訊息的方法,第二項說明此 SIP 訊息為 SIP 要求或 SIP 回應。在圖 3-2 範例中,INVITE_REQUEST 表示此 SIP 訊息是方法為 INVITE 的 SIP 要 求訊息。SIPStartLine 字串用來儲存 SIP 訊息中第一行資訊。若 SIP 訊息為 SIP 要求訊息,則 SIPStartLine 字串儲存著 SIP 要求的 Request Line。若 SIP 訊息為 SIP 回應,則 SIPStartLine 字串儲存著 SIP 回應的 Status Line。SIPMessageHeader 資料結構用來儲存 SIP 訊息標頭欄位,因為 SIP 標頭欄
位的個數不固定,此資料結構以串列結構來儲存每一筆 SIP 標頭欄位。每個 標頭欄位分別用 FieldName 字串與 FieldValue 字串儲存著欄位型態與欄位內 容 。 SIPMessageBody 資 料 結 構 儲 存 SIP 訊 息 主 體 , 分 別 以
SIPMessageBodyType 字串與 SIPMessageBodyContent 資料結構來儲存
SIP 訊息主體的型態與內容。由 SIP 標頭中 Content-Type 標頭欄位可知 SIP 訊 息主體的類型,若 SIP 訊息主體為 SDP,則 SIPMessageBodyType 儲存著 字串“SDP”,並以 SIPMessageBodyContent 資料結構以串列資料結構儲存 每一筆 SDP 欄位內容,每個欄位分別用 FieldName 字串與 FieldValue 字串 儲存著欄位型態與欄位內容。步驟○2 :程式從 SIPMessageType 判斷是否為 Request Line。若是,則執行步驟○3 。 若否,則跳到步驟○4 進一步處理 SIP 訊息標頭欄位。
步驟○3 :RequestLineHandler 函式找出 Request Line 中 Request-URI 的 IP 位址部份 作轉換。
步驟○4:程式針對 SIPMessageHeader 資料結構內的 FieldName 字串進行搜尋工作,
判斷 Contact、From、To、Via、Record-Route 以及 Route 等六種特定標頭欄位 是否存在,若存在則分別呼叫 ContactHandler、FromHandler、ToHandler、
ViaHandler、RecordRouteHandler 以及 RouteHandler 函式針對欄位內的
IP 作轉換。此步驟針對特定 SIP 標頭欄位完成轉換工作。步驟○5 :程式從 SIPMessageBodyType 字串從判斷 SIP 訊息主體是否為 SDP,若是 則執行步驟○6 。若否則跳到步驟○7 。
步驟○6 :程式在 SIPMessageBodyContent 資料結構內搜尋 FieldName 字串,找出 c 與 o 欄 位 , 並 且 分 別 呼 叫 ConnectionFieldHandler 以 及
OriginFieldHandler 函式對 c 與 o 欄位內的 IP 位址進行轉換。最後,呼叫
步驟○7:程式將 SIPMessage 資料結構轉換為 RFC3261 定義的 SIP 訊息格式,寫入輸 出緩衝區中。最後並回傳 SIP 訊息轉換後所改變的長度。