網路加速器加速方式詳細介紹;原理、技術與實現
1. 前言
網遊加速器是針對個人用戶快速連接網遊伺服器的一種服務。為了解決國內南北網路互聯瓶頸的問題,「網路加速器」廠商通過搭建多個高帶寬的雙線機房(或通過租用雙線VPS主機),並在這些機房的兩大線路中架設多個節點伺服器,然後為其編寫「網路加速器客戶端」,通過客戶端判斷用戶的網路線路類型,並將用戶應用客戶端的網路數據轉發到指定的節點伺服器,由節點伺服器轉發給用戶應用客戶端請求的真正伺服器。「網路加速器客戶端」通過自動選擇速度最快的節點伺服器進行數據轉發,以達到數據加速作用。優秀的網路加速器可以有效減少網路丟包和網路延遲。
本文基於前期對各種加速器的分析以及對其中的關鍵技術進行試驗。文章首先對互聯網上流行的網遊加速器分析結果進行簡要匯總,然後針對各種不同的加速器實現方式進行詳細實現細節的介紹。
2. 流行加速器分析
本文前期對目前流行的網遊加速器(或網路加速器)客戶端進行了一定的深度分析,了解了這些網路加速器的使用特點、應用領域以及所採用的關鍵技術。目前網路上流行的網路加速器主要有:迅游加速器、迅雷網遊加速器、盛大ET加速器、騰訊免費加速器、熊貓加速器等。
迅游加速器和迅雷網路加速器迅游版是專門針對網遊的加速器。迅雷共有兩款加速器,自研的「給力加速器」提供免費加速服務,「迅游版加速器」是與迅游合作的產品。它們在軟體UI設計和功能大致相同,使用流程也如出一轍:啟動加速功能前需要選擇指定的遊戲及其區服,注意:待加速遊戲必須是其客戶端列表中指定的遊戲,對於未指定的遊戲不能被加速。
啟動加速後加速客戶端對其全部節點伺服器進行測速(迅游加速器部署了82個節點伺服器),然後選擇速度最快的伺服器作為轉發伺服器,並在本地建立IP地址以172開頭的虛擬網卡(區域網地址)。啟動後通過抓包工具分析,所有發送到該遊戲伺服器的數據都是從該172開頭的虛擬網卡地址發出的,而不是從物理網卡地址發出。通過查看路由表,被加速的遊戲當前所使用的伺服器被增加到了路由表中,並指向了該172開頭的虛擬網卡地址。
在對迅游加速器分析過程中還發現,迅游加速器在加速過程中使用了LSP技術(一種通過在TCP/IP協議上層安裝一層用戶自定義協議,可以對WinSock2 API進行攔截的技術),並對WSAConnnect函數進行了攔截。
迅雷給力加速器也提供了四種加速模式,模式一採用的是基於LSP的代理加速方式,通過LSP技術,將用戶的網路數據直接轉發給代理伺服器,再由代理伺服器將數據轉發給真正的遊戲伺服器;模式二採用的是基於L2TP協議的VPN技術;模式三採用的是基於PPTP協議的VPN技術;模式四採用的是基於基於OpenVPN的VPN技術。這三種模式在啟動加速後都需要修改路由表,以實現針對指定目的IP的加速功能。
盛大ET加速器是一款可以針對網路遊戲加速以及語音加速的工具。ET加速器在結構設計上與迅游加速器有明顯區別,但是功能類似:僅支持對其遊戲列表中的遊戲加速、啟動加速功能後在本機建立了虛擬網卡,並添加了指向虛擬網卡地址的路由、在本機安裝了LSP協議。ET加速器啟動加速後,在「我的連接」面板里新增出現了一個名為「etaaaaaa」的網路連接。
3. 加速器實現方式概要
通過對以上加速器的分析進行參考,並查閱相關資料,目前主流的加速技術可以採用兩種方式來實現:「代理伺服器方式」和「VPN方式」。
代理伺服器方式通過部署SOCKS5代理伺服器作為加速節點,加速客戶端自動選擇最快的代理伺服器作為當前的轉發節點。在客戶端主要採用LSP技術,在用戶的主機安裝分層協議,在遊戲客戶端調用connect函數(或WSAConnect函數)試圖連接遊戲伺服器時,將連接重定向到代理伺服器,並採用SOCKS5協議規範與代理伺服器進行數據協商,由代理伺服器來連接真正的遊戲伺服器,並將遊戲伺服器的數據原封不動轉發給用戶、將用戶的數據原封不動轉發給遊戲伺服器。
VPN方式需要部署雙線VPN伺服器作為加速節點,加速客戶端自動選擇速度最快的VPN伺服器,並通過VPN撥號連接到VPN伺服器並獲取一個虛擬IP地址,同時通過修改路由表的方式,將指定進程的網路訪問路由到虛擬IP上,而其餘地址仍經過原默認路由途徑訪問。
下面就這兩種加速方式的具體實現以及重要的技術難點進行詳細分析。另外,報告中的所有代碼截圖均來自之前寫的測試程序,並測試通過;VPN加速方式由主要進行了原理的詳細介紹,並編寫了支持PPTP協議的VPN客戶端和伺服器進行了測試。
4. VPN加速方式
4.1. VPN加速概述
VPN技術常常被廣泛應用於「網遊加速技術」和「翻牆技術」中。如前面提到的迅游加速器、迅雷網遊加速器都採用到了VPN技術進行加速,而且目前主流的網遊加速器都主要是採用的VPN技術。由於VPN環境的測試需要建立VPN伺服器,本人的測試環境有限,所以只是進行了客戶端的代碼編寫並連接通過,無法做相關的代理效果的測試。下面只針對實現的流程和原理給以介紹。
4.2. VPN加速實現步驟
通過建立如下步驟,可以採用VPN技術來實現網路加速:
1. 部署雙線VPN伺服器節點;
2. 加速器客戶端啟動後選擇網路性能最好的VPN伺服器,並在客戶端進行RAS撥號,與該VPN伺服器建立隧道連接,連接建立後將會自動在本機生成一個虛擬網路地址,同時客戶端的默認路由會被修改成指向該虛擬網路地址,如果此時不進行特殊處理,客戶端的所有網路訪問將都會通過該VPN通道出去;
3. 因為網遊加速器的功能需求是僅僅針對某款遊戲進行加速,即:在知道這款遊戲連接的伺服器IP的前提下,只有發送到該伺服器IP的數據才被加速,其他網路數據應該不受影響。因此加速客戶端在建立完VPN通道以後,需要立即修改路由表:在撥號前通過修改撥號參數,使其不修改本機的默認路由表;其次,將遊戲伺服器IP增加到路由表中,並讓其指向VPN撥號建立的虛擬網路地址上。這樣,與遊戲伺服器之間的通信都走VPN通道,而其他網路數據都不受影響。
4.3 VPN加速使用的三種協議介紹
目前網路上現有的網遊加速器(或網路加速器)都使用到了三種VPN協議:PPTP、L2TP和OpenVPN。各種不同的協議在使用時可能受用戶的網路狀況的限制而無法使用,因此一般的網路加速器都會提供不同的加速模式供用戶選擇。或在啟動加速過程中根據用戶當前的網路狀況自動選擇可用的加速模式。
PPTP協議:PPTP協議是在PPP協議基礎上開發的增強型安全協議。PPTP協議中有兩個流:控制流和數據流。PPTP協議的數據流採用了GRE協議,由於該協議的特殊性,如果同一個NAT中有兩個或以上的主機同時在發送PPTP協議數據包,當數據包從外部達到NAT時,NAT將無法通過埠將數據轉發到不同的主機,因此,當使用PPTP協議時,如果用戶所在的NAT網關不支持VPN穿透功能(即支持PPTP協議的NAT編輯器,該編輯器在GRE協議的報頭使用了一個CallId用來表示NAT下的一個會話,通過CallId來模擬埠,做NAT映射),那麼內部主機只能與同一個伺服器中間建立一個會話,不能有第二個客戶端。目前,大多數NAT網關都具有PPTP NAT編輯器,能很好的支持PPTP協議。
L2TP協議:第二層隧道協議,該協議是PPTP協議和Cisco第二層轉發協議L2F的結合體。在windows建立的基於L2TP協議的VPN連接中,默認是啟用了證書方式的IPSec協議作為安全傳輸協議,IPSec協議為了保護IP數據包的完整性,會禁止任何對數據包的修改,否則修改後的數據包達到目的主機後其解密和完整性認證就會失敗,從而導致這個報文被認為是非法數據而被丟棄。而當加速器客戶端位於NAT後時,數據包在通過NAT時,NAT會對IP頭數據等進行修改,導致數據到達VPN伺服器時被認為是非法數據而丟棄。
解決該問題的一種方式是通過硬體方式:要求通信的雙方的邊界路由都支持NAT-T,基本原理是在IPSec封裝好的數據包外再進行一次UDP的數據封裝,因此,當數據包穿過NAT網關時,被修改的只是外層IP/UDP頭,而真正的IPSec數據未被修改;到目的主機時再將IP/UDP封裝去除,這樣就可以得到未被修改的IPSec數據包。
另一種方式是在L2TP協議中禁用IPSec。對於我們製作網路加速器應用來講,IPSec協議並非必須的,因此,我們可以在加速器連接中去除IPSec協議,而不影響加速功能。在Windows系統下採用RAS進行VPN連接時,若要去除IPSec協議,需要修改註冊表並重啟機器使之生效。迅游的給力加速器中就是採用這種方式。
OpenVPN模式:OpenVPN是一個基於OpenSSL加密和驗證的應用層VPN實現,能夠在NAT環境下很好的工作,是今年來新出現的一個基於開源軟體體系的VPN項目。使用OpenVPN進行連接前,需要在客戶端機器上安裝一個虛擬網卡設備,並需要客戶端修改路由表。
以上VPN協議中,除了OpenVPN的使用可以不受用戶當前網路的限制外,其他兩種方式都可能收到用戶的NAT情況影響而導致加速失敗,因此在實際應用中,各種加速器都會把這幾種模式都提供給用戶,並根據用戶的網路情況進行選擇。
4.4 VPN撥號客戶端的實現
試驗過程中對RAS撥號建立VPN連接功能進行了測試。如下客戶端實現了連接到VPN伺服器,並同時客戶端用戶輸入的「待加速地址」列表,修改路由表,已達到「僅指定IP走VPN通道」的功能,而用戶的其他網路訪問完全不受影響。
啟點加速器_國際線路安全穩定無限流量_高速自由訪問全球網路
4.5 VPN方式尚存在的問題
1. 與採用代理方式一樣,判斷與當前啟動的遊戲通訊的是哪個伺服器是個問題(原因如前所述),這裡可以用到前面描述的LSP技術,通過在connect函數中判斷欲建立連接的IP是否在當前遊戲的伺服器列表中。此時用到LSP技術並不是用於轉發,僅僅用於判斷是否加速。
2. 採用VPN方式有一個問題:如果用戶修改路由表,讓其他進程的伺服器IP(如p2p下載軟體)或默認路由表經過VPN通道的話,可能會造成VPN通道中的數據量增大,可能會影響正常的遊戲。迅游加速器也沒有對該問題進行很好的解決,早前的測試發現迅游加速功能啟動後,通過修改路由表,可以使任意客戶端進程都使用迅游的加速通道來訪問網路。
該問題的也許可以通過兩種方式來解決:一種是在客戶端限制用戶修改路由表,另一種是通過在伺服器端進行限制非遊戲伺服器相關的數據。具體實現方式有待研究。
5. 代理加速方式
5.1. 代理加速的基本原理
採用代理伺服器進行網路加速是一類使用較早的技術。目前某些網遊客戶端和網路應用程序都直接支持SOCKS5代理協議來連接其客戶端,客戶端提供設置代理伺服器IP和埠的方式供玩家來設置。然而大部分網遊客戶端並不直接支持SOCKS5代理技術。此處介紹的代理加速模式不僅支持那些無法設置SOCKS5代理的網路遊戲,即使那些可以設置SOCKS5代理的遊戲,玩家也可以不用手動去設置,而自動採用下面介紹的代理加速技術進行代理加速。
代理加速方式可以直接採用SOCKS5協議,由於SOCKS5協議有現成的伺服器程序可用,可以節省伺服器編寫時間;但是也可以自己定義一個「類SOCKS5」的代理協議,自行實現代理協商和身份驗證功能。下面的介紹將會基於自己定義代理協議的模式。
在使用代理方式加速時,LSP技術的使用是關鍵。Microsoft在Winsock2中提供了Winsock伺服器提供者(SPI),允許用戶在基礎TCP/IP協議上層插入自己定義的分層協議(LSP),當用戶通過Winsock2 API連接網路或發送網路數據時,如調用WSAConnect函數,將會首先執行到LSP協議的dll中我們定義的函數,這樣我們可以先進行處理,然後再交給真正的WSAConnect函數,這樣就會起到API Hook的作用。
要使用LSP技術,必須要將寫好的LSP協議安裝到用戶的機器上,安裝過程實際就是將DLL放入系統目錄,並在註冊表中寫入該DLL位置信息的過程。注意:安裝未簽名的LSP時,安裝過程中一般防火牆都會有警告提示。
5.2. 代理加速方式的實現概要
採用LSP方式進行網路加速需要部署SOCKS5代理伺服器作為加速節點,加速客戶端自動選擇最快的代理伺服器作為當前的轉發節點。
開發人員在客戶端需要完成的動作有:
1. 編寫我們自己的LSP協議動態庫,重新實現我們需要的相關socket函數,如connect;
2. 在用戶的主機安裝我們自己的LSP協議,這一操作可以放入我們的應用程序部署的時候完成,也可以在我們的加速器每次啟動的時候進行部署;
3. 當遊戲客戶端調用connect函數(或WSAConnect函數)試圖連接遊戲伺服器時,通過LSP將連接重定向到代理伺服器,並採用SOCKS5協議規範與代理伺服器進行數據協商,由代理伺服器來連接真正的遊戲伺服器,並將遊戲伺服器的數據原封不動轉發給用戶、同時將用戶的數據原封不動轉發給遊戲伺服器。
由於Socks5協議並不涉及協議加密,而且Socks5協議本身協商過程較長,實際在開發中,網路加速器開發商一般都不會直接採用socks協議,而是對該協議進行改造,定義自己的代理協議。
5.3. Socks5協議與LSP結合
通過LSP技術Hook到相應的套接字函數進行數據轉發之前,需要進行Socks5代理協商,即將鑒權信息告訴代理伺服器,以及告訴代理伺服器自己想連接的真正遊戲伺服器地址。代理協商完成後才能進行數據的收發。
針對不同的網路連接方式,代理協商的方式有所不同:
1. 普通阻塞方式的TCP連接最簡單,可以在hook到connect函數後直接在內部進行阻塞式的代理協商,直到協商完畢後才將connect函數返回給用戶,這時候用戶拿到的socket實際上是連接到代理伺服器的socket,當應用程序通過這個socket收發數據時,實際上是在和代理伺服器交互,而這一過程對應用程序來說是透明的,應用程序以為自己是直接在和遊戲伺服器通信。
目前的網路應用程序很少會採用阻塞方式進行TCP連接,所以這種情況應用場景比較少。
2. 非阻塞方式的TCP連接情況比較複雜,有的TCP連接的socket是可以修改阻塞選項,這樣,我們可以在connect函數的入口處判斷一下當前socket是否是非阻塞,如果是則將其改為阻塞方式,修改後以阻塞方式進行socks5代理協商,協商完畢後再將socket的阻塞方式修改為非阻塞。
3. 另一種更為複雜的非阻塞TCP連接是基於Windows非同步消息的連接,這種連接採用了WSAAsynSelect方式設置了網路消息到來時的Windows接收窗口,所有的網路數據都需要在這個窗口的消息處理函數中處理(QQ飛車的TCP連接就是採用的這種方式)。這類網路模型不能簡單採用修改socket阻塞方式的方法來解決。
解決這一問題的唯一辦法是在LSP中hook住WSAAsynSelect,在該函數中創建一個我們自己的隱藏窗口,讓網路應用程序的所有數據都轉發我們自己的窗口上來,在我們的窗口的消息處理函數中進行代理協商和網路數據轉發。
4. 對於UDP網路數據的socks5代理轉發比TCP又要稍微複雜一些,TCP只需要hook到connect和WSAAsynSelect,對於網路收發數據的send和recv函數是不需要我們自己來實現的。UDP由於是不保持連接的,因此每次發送和接收的UDP包都要包含代理協商信息,因此我們需要把RecvFrom函數和SendTo函數都hook住。
對於UDP連接,需要在應用程序發送第一個UDP包的時候進行代理協商,以後發送數據的時候按照socks5協議的規定,加上socks5頭部;收到的信息去除socks5頭部再交給應用程序。
5.4. 代理加速方式詳細實現
下面就詳細介紹每一步的具體實現方式,為了方便流程分析,這裡從LSP實現數據包轉發開始介紹,最後介紹代理伺服器的實現。
1. 利用LSP編寫DLL,實現客戶端數據包轉發功能:
編寫LSP協議並安裝到現有協議之上,需要建立基於DLL的工程,並導出WSPStartup函數,這樣當有應用程序創建套接字時,會自動執行到該WSPStartup函數。在WSPStartup函數函數中,參數信息指明了應用程序期望採用哪種協議來創建套接字(所有的協議存在於一個協議鏈中,該協議鏈也包含了我們安裝的LSP協議),我們需要在該函數中載入下層協議,並調用下層協議提供者的WSPStartup函數初始化,並修改傳遞給上層的函數表,將我們需要Hook的Winsock2函數指針的地址指向我們自己的函數。關鍵代碼如下:
如果測試程序只針對TCP數據包的轉發,只需要實現WSPConnect函數就可以了,其餘函數只需要直接調用g_NextProcTable中的默認函數就可以了。
當用戶應用程序調用connect函數或WSAConnect函數試圖進行TCP連接時,將會先進入LSP的DLL中定義的WSPConnect函數,該函數進入後我們會判斷應用程序試圖連接的伺服器IP和埠是不是我們待加速的伺服器,如果是,會執行到socksProxy函數與代理伺服器連接,並進行代理協商;如果不是待加速伺服器,則執行g_NextProcTable中原有的連接函數,此時LSP就沒有起作用,流程與不安裝LSP前的流程是一致的。
2. 安裝LSP。
要使我們上一步實現的轉發協議生效,還必須將上一步生成的DLL安裝到用戶的系統上。只有安裝了LSP,應用程序在調用ws2_32.dll中的函數時就會執行到我們的LSP的DLL中。一般來講,生成的DLL需要放入Windows/System32目錄下,一個原因是DLL路徑不能有中文等特殊字元,另一方面,如果有其他程序誤刪了該DLL,會導致整個系統無法上網的現象,還可能導致整個系統崩潰。
安裝LSP首先需要安裝協議鏈,需要將下層協議的信息拷貝過來,修改成我們需要的協議特點,並進行安裝;然後對協議鏈進行排序,將我們的協議放在協議鏈的最上層,以保證ws2_32.dll調用到的第一個協議是我們的協議。
這裡需要注意的是,當安裝了「迅游加速器」後,系統上原有安裝的分層協議將會被移到最下層,導致原有的協議無效。因此,我們在開發自己的網遊加速器時需要考慮該問題,並予以避免。
5.4. 代理方式尚存在的問題
1. 不同網路加速器廠商的LSP安裝程序相互之間可能會出現不兼容的情況,所以我們實現自己的加速LSP的時候,其他網路加速器廠商可能對我們安裝的協議干擾,如迅游在安裝和每次啟動的時候會刪除其他廠商的LSP協議;
2. 如前所述,LSP在Hook到connect函數後,在WSPConnect函數中會判斷當前連接的伺服器是否是需要被加速的目的地址。如何獲得用戶當前啟動的遊戲的IP和埠是多少是一個難點,因為一個遊戲可能連接了多個伺服器並開啟了多個埠,而真正進行通訊的只是其中一個;另一方面,通過加速客戶端啟動的進行可能並不是真正的遊戲進程(可能只是一個升級程序)。
迅游加速器可能收集了每款待加速遊戲的伺服器ip和埠,如果客戶端發送網路包的目的地址是這些ip的時候,才會針對這些目的ip地址進行加速。本人有過測試:首先獲取迅游加速器支持的某款遊戲的某個伺服器IP和埠,然後自己編寫一個客戶端不斷給該伺服器的埠發送數據,當該exe替換遊戲的exe並啟動後,從抓包結果來看,加速功能仍然有效;當從迅游列表中選擇另一款遊戲,啟動exe時仍啟動我們剛剛編寫的exe時,加速功能就失效了。因此可以推測:迅游加速器並不是通過判斷進程信息來獲取目的伺服器的(況且通過判斷進程信息來獲取目的伺服器IP並不容易實現,如前所述),而是通過用戶從列表中選擇的遊戲的名稱。
6. 總結
本文主要介紹了兩種實現網遊加速的可行的技術方案,其中提到的對其他網路遊戲加速器的分析以及具體實現細節可能會有一些不完善之處。
加速器實際實現過程中,還有關鍵一步就是判斷當前用戶的網路環境。比如用戶當前連接的伺服器是網通伺服器,更智能的做法是在加速之前提前判斷當前用戶的網路情況,如果用戶是網通用戶,則不必啟用加速功能,如果用戶是電信或其他網路,則需要給用戶提示可以啟動加速功能,並由用戶來決定是否啟用加速。
當前遊戲如果採用了P2P通信,用戶網路環境的判斷仍然需要被考慮。如QQ飛車和CF等對戰遊戲,啟動遊戲後建立了P2P連接,是否需要對這些P2P連接進行加速呢?這種情況也需要考慮用戶的當前網路環境:如果P2P雙方處於同一個NAT下,則不需要加速,如果一方是電信用戶,而另一方是網通用戶,就需要加速功能。
用戶網路環境的判斷(包括是否處於同一個NAT下的判斷)是進行網路加速器的具體實現前需要解決的技術問題。
推薦閱讀: