如何使用LSP对应用程序的网络数据进行转发

发表于2015-04-30
评论4 1.23w浏览

什么是网游加速器

网游加速器是针对个人用户快速连接网游服务器的一种服务。为了解决国内南北网络互联瓶颈的问题,“网络加速器”厂商通过搭建多个高带宽的双线机房(或通过租用双线VPS主机),并在这些机房的两大线路中架设多个节点服务器,然后为其编写“网络加速器客户端”,通过客户端判断用户的网络线路类型,并将用户应用客户端的网络数据转发到指定的节点服务器,由节点服务器转发给用户应用客户端请求的真正服务器。“网络加速器客户端”通过自动选择速度最快的节点服务器进行数据转发,以达到数据加速作用。优秀的网络加速器可以有效减少网络丢包和网络延迟。

 

网游加速器现状

目前网络上流行的网络加速器主要有:迅游加速器迅雷网游加速器、盛大ET加速器、LavaVPN、NetPas等。

 

大多数情况下网游加速器都提供了两种加速模式:通过LSP进行转发,以及通过VPN通道传输游戏网络数据。

 

一种是采用基于LSP的代理加速方式。LSP全称为Layered Service Provider,即分层服务提供者,LSP本身是以DLL方式提供,通过Windows提供的安装API,以第三方服务者的方式插入到客户应用程序(游戏)和Winsock2 DLL之间,从而起到拦截套接字相关函数的目的。通过LSP技术,可以将用户的网络数据直接转发给代理服务器,再由代理服务器将数据转发给真正的游戏服务器;

 

第二种是利用VPN方式。通过将玩家的客户端连接到VPN服务器,并将指定游戏的网络访问路由到该VPN通道。上述网络加速器用到的VPN技术主要基于L2TP协议、基于PPTP协议和基于开源OpenVPN三种模式。

 

需要指出的是,以上提到的技术仅仅是涉及到在如何在玩家的客户端进行数据转发,而加速效果的好坏往往是取决于加速服务器的部署:对于LSP加速方式是代理服务器,而VPN方式下则是VPN服务器了。

 

本文主要对LSP方式下的网络游戏加速技术进行详细介绍。

 

如何使用LSP对应用程序的网络数据进行转发?

采用LSP方式进行网络加速需要部署SOCKS5代理服务器作为加速节点,加速客户端自动选择最快的代理服务器作为当前的转发节点。

 

开发人员在客户端需要完成的动作有:

1.编写我们自己的LSP协议动态库,重新实现我们需要的相关socket函数,如connect;

 

2.在用户的主机安装我们自己的LSP协议,这一操作可以放入我们的应用程序部署的时候完成,也可以在我们的加速器每次启动的时候进行部署;

 

3.当游戏客户端调用connect函数(或WSAConnect函数)试图连接游戏服务器时,通过LSP将连接重定向到代理服务器,并采用SOCKS5协议规范与代理服务器进行数据协商,由代理服务器来连接真正的游戏服务器,并将游戏服务器的数据原封不动转发给用户、同时将用户的数据原封不动转发给游戏服务器。

 

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头部再交给应用程序。

 

后记

通过LSP进行代理转发加速,仍存在一些需要解决的细节问题:比如怎么做到只针对指定的进程进行转发,而其他进程不受影响、如何判断用户是否需要进行加速,即在用户网络状况较好的情况下不进行代理转发,等等。这些内容属于辅助功能的范畴。

 

“通过LSP+Socks5协议进行网络数据的代理转发技术”已经成功应用到QQ飞车客户端网络加速插件中,并在仙侠传、御龙在天和LOL中试验成功。

 

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引