|
NAT解決方案
NAT如今已是被廣泛使用的網路技術,用來解決IP不足的問題。然而H.323
設計上並非NAT friendly,意即一般簡單的網址轉換無法適用於H.323協定。
欲解決此問題一般有兩種作法,一是修改NAT使其具備H.323的轉換能力。另
一是修改通訊協定使其能夠穿越NAT。GnuGK中我完整的實作了兩種技術。
GnuGK可轉送Q.931、H.245、RTP/RTCP以及T.120的訊息。在此模式下通
訊雙方沒有任何直接的流量通過,因此又稱為H.323 Proxy。若將H.323 Proxy
圖2. NAT示意圖
安裝在NAT上即可解決H.323無法穿過NAT的問題。
不過這種作法需要修改NAT本身,在實務上有時不可行。因此我們研發了
新的技術,在不修改NAT的情況下,僅要在gatekeeper和endpoint端略作修改
即可。這個技術包含了幾個重點:
1. 偵測是否NAT端點:GnuGK會比較註冊訊息(RRQ)的來源IP和RRQ本
身包含的callSignalAddress是否相同。若不同的話即表示端點位於NAT
之後。GnuGK 會針對此種端點,將其訊息中包含的IP資訊轉換為NAT
IP。
2. RTP/RTCP 的穿越:H.323 使用RTP/RTCP 來傳送聲音或影像資料,而
RTP/RTCP使用UDP。由於一般NAT對UDP的穿越有條件限制。假設某
一端點的IP A,從port B送出封包,經由NAT轉換為IP C,port D,而
目的地是IP X,port Y。一般的條件(port restricted NAT)會要求回送的封
包,來源必須是IP X,port Y,送至IP C,port D。如此NAT才會轉送回
IP A,port B。GnuGK在轉送RTP/RTCP封包時會設法滿足該條件,使得
RTP/RTCP封包可順利穿越NAT。
利用以上兩個技術,已可使一般位於NAT之後的端點直接註冊到GnuGK
並對外撥打電話。然而欲接電話的話,這樣仍不夠。因為H.323 使用TCP
建立通訊連線,但一般NAT無法處理由外至內的TCP請求。因此需要修改
端點,要加上以下兩種技術:
3. Q.931 Penetration:位於NAT之後的端點在註冊成功後,先發起由內至外
的TCP連線至GnuGK,稱為NAT Connection。當其它端點要呼叫該端點
時,GnuGK會利用已存在的NAT Connection傳送Q.931 Setup至該端點。
4. H.245 Reverting:位於NAT之後的端點若送出h245Address以建立H.245
控制通道,GnuGK在收到後,會改發Q.931 Facility startH245的訊息給該
圖3. Q.931 Penetration示意圖
端點。該端點收到後要改從內部向外建立H.245的通道。由於TCP連線
的方向跟原本正常的程序剛好相反,因此稱為反轉(reverting)。
以上兩個技術在業界實屬創新發明。呈祺資訊已在台灣、日本和美國等
地申請專利當中。
規格/使用/設計/測試報告:
1.規格:
平台:Linux, FreeBSD, Solaris, Windows等。
編譯器:UNIX-like 系統:gcc 2.96 or 3.2以上;Windows:VC6以上。
系統記憶體:256MB以上為佳。
硬碟空間:50MB以上為佳。
必須安裝:PWLib-1.2.13, OpenH323-1.9.3 以上。
其它函式庫或程式:可選擇安裝MySQL、OpenLDAP、OpenSSL等。
2.系統設計:
採用多執行緒架構,以平行處理各種請求與不同的工作。程式啟始時,完成初
始化和必要的檢查之後,隨即分支出數個執行緒,處理不同的請求。主執行緒則
成為RasServer,產生RasListener 監聽RAS的請求。
在收到RAS請求後,RasServer 利用物件工廠產生對應的RasMsg物件,並且檢
查是否有某個RAS處理器在等待(攔截)該訊息。若有的話就將該物件交由該處理
器負責;否則,檢查該訊息是否與正在處理中的訊息重複,若是的話將它交給正
在處理重複訊息的執行緒處理;否則,將該物件交給另一(新的)執行緒處理。該
執行緒將呼叫RasMsg物件的Process虛擬函式來處理該訊息。
TCPServer 執行緒處理所有TCP 連線請求,並將之分配到其餘執行緒處理;
GkStatus執行緒處理狀態埠(status port)的輸入,分析是否為合法指令並做適當處
理;在信號路由模式下,還會產生一個至數個ProxyHandler執行緒處理信號(call
signalling)的改寫與轉送;HouseKeeping執行緒則檢查註冊和通話是否逾時,以及
處理一些資源的回收與清除。
3.安裝方式:
GnuGK可在Windows和各種UNIX-like的系統上編譯執行。為簡化起見,以下
所述以Linux平台為主。編譯前需先安裝PWLib和OpenH323函式庫。
解壓縮:tar zxvf gnugk-2.2.tar.gz
cd gnugk
./configure
make
其中./configure可加上參數以啟用或停用某些功能特性。如要加上RADIUS
支援,可加上--enable-radius參數。輸入./configure --help可以列出所有參
數。最後產生的執行檔位於src/obj_linux_x86_r/gnugk。
4.執行:
首先,建立一設定檔gnugk.ini如下所示:
[Gatekeeper::Main]
Fourtytwo=42
TimeToLive=600
[RoutedMode]
; call signalling (Q.931) routed
GKRouted=1
; control channel (H.245) routed
H245Routed=1
; use 1721 as the port of call signalling
CallSignalPort=1721
[Proxy]
Enable=0
[GkStatus::Auth]
rule=allow
執行指令
$ ./src/obj_linux_x86_r/gnugk -c gnugk.ini -o gk.log -ttt
表示以gnugk.ini為設定檔(-c所指定),debug level 為3(3個-t),並將訊息記
錄至gk.log(-o所指定)。關於設定檔各種參數的意義和設定方法,請參考附件
二的第四章。
輸入指令
$ telnet localhost 7000
可看到類似如下訊息:
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Version:
Gatekeeper(GNU) Version(2.2beta2) Ext(pthreads=1) Build(Oct 17 2003, 16:38:28) Sys(
Linux i686 2.4.20-8smp)
Large fd_set(8192) enabled
GkStatus: Version(2.0) Ext()
Toolkit: Version(1.0) Ext(basic)
Startup: Mon, 20 Oct 2003 14:27:41 +0800 Running: 0 days 00:00:17
;
表示程式執行成功。7000 port是GnuGK預設的狀態埠,可從這裡監看程式運
作的狀態,並控制或調整程式的執行。細節請參考附件二的第五章。
5.測試:
程式執行成功後,可註冊各種H.323端點上去並互撥電話。底下以ohphone這
支程式為例(可從http://www.openh323.org/code.html取得)。這是一支指令列的
H.323客戶端程式,很適合拿來測試用。
首先,註冊兩個端點上去,號碼分別是600和601。開兩個console視窗,分別
輸入下列指令:
$ ohphone -g localhost -u 600 --listenport 1800 -l
$ ohphone -g localhost -u 601 --listenport 1801 -l
此時可從GnuGK的狀態埠上看到如下訊息,表示註冊成功:
GCF|127.0.0.1|600:dialedDigits|terminal;
RCF|127.0.0.1:1800|600:dialedDigits|terminal|1635_endp;
GCF|127.0.0.1|601:dialedDigits|terminal;
RCF|127.0.0.1:1801|601:dialedDigits|terminal|1634_endp;
從600撥打電話給601:
Listening interfaces : ALL:1800
Gatekeeper set: cwhuangGK@localhost.localdomain
Waiting for incoming calls for "600"
Command ? c 601
600 is calling host 601
Command ? Ringing phone for "127.0.0.1" ...
在601的console上按Y表示接電話:
Listening interfaces : ALL:1801
Gatekeeper set: cwhuangGK@localhost.localdomain
Waiting for incoming calls for "601"
Command ? Incoming call from "600 [127.0.0.1]" at Mon, 20 Oct 2003 14:56:15 +0800,
answer call (Y/n)? Y
Call with "600 [127.0.0.1]" established.
Accepting call.
表示電話已接通,可開始講話。在狀態埠上可看到如下訊息:
ACF|127.0.0.1:1800|7377_endp|14990|601:dialedDigits|600:dialedDigits|false;
ACF|127.0.0.1:1801|7378_endp|14990|601:dialedDigits|600 [127.0.0.1]:h323_ID|true;
在任一ohphone的console上輸入H指令表示掛斷:
Command ? H
Hanging up call.
Command ? Call with "600 [127.0.0.1]" completed, duration 0:11
此時可從狀態埠上看到通話明細(Call Detail Record):
CDR|1|84 53 7c 2a 38 01 d8 11 8a ac 00 0c 6e cb e0 42|11|Mon, 20 Oct 2003 14:56:19 +0800
|Mon, 20 Oct 2003 14:56:30 +0800|127.0.0.1:1800|7377_endp|127.0.0.1:1801|7378_endp
|601:dialedDigits|600:dialedDigits|cwhuangGK;
DCF|127.0.0.1|7377_endp|14990|normalDrop;
DCF|127.0.0.1|7378_endp|14990|normalDrop;
更多的使用說明和範例,請參考附件二。
與其它類似軟體的比較:
名稱作者網址是否為開放
源碼軟體
OpenGatekeeper Egoboo
http://www.egoboo.com/
http://www.opengatekeeper.org/ 是(MPL)
OpenH323Proxy Marco Polci,
Roman Skvirsky
http://openh323proxy.sourceforge.net/ 是(MPL)
OpenGK Equivalence Pty Ltd.
http://www.equival.com.au/
http://www.openh323.org/code.html 是(MPL)
說明如下:
OpenGatekeeper:由Egoboo公司所主導,具備RAS、Q.931和H.245路由
模式和Neighboring等基本功能。但不含H.235安全認證,也無法連接資料
庫。
OpenH323Proxy:由OpenGatekeeper衍生而來,加上H.323 Proxy的功能。
OpenGK:由開發OpenH323的同一組織Equivalence Pty Ltd.所發展,主要
用來測試OpenH323的RAS stack。功能很陽春。
功能比較如下:
功能OpenGatekeeper OpenH323Proxy OpenGK GnuGK
License MPL MPL MPL GPL
RAS Y Y Y Y
路由模式
Q.931
H.245
RTP/RTCP
FastStart
Y
Y
N
N
Y
Y
Y
N
N
N
N
N
Y
Y
Y
Y
H.235 N N Y Y
Neighboring Y Y N Y
GK Hierarchy N N N Y
Alternate GK N N N Y
CDR N N N Y
Status Port N N Y Y
Database Backend N N N Y
NAT Traversal N N N Y
其他補充說明:
1.附件說明:
? 附件一:檔案icos2003-paper.html,是我在2003開放源碼國際研討會上介
紹GNU Gatekeeper計畫的文件。收錄在ICOS 2003論文集當中。
? 附件二:檔案manual-zh.html,GNU Gatekeeper使用參考手冊。包含完整
的安裝、使用和設定說明。
2.參考資料
? GNU Gatekeeper計畫主網站:http://www.gnugk.org/
? 提供GnuGK各式諮詢服務的公司或個人列表:
http://www.gnugk.org/consulting.html
? GnuGK相容設備列表:http://www.gnugk.org/interoperability.html
? 其他應用GnuGK的成功故事:http://www.gnugk.org/gnugk-success.html
? H.323的市場現況:http://www.tmcnet.com/it/0803/0803f-Cisco.htm
|