采用 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 接收窗口,所有的网络数据都需要在这个窗口的消息处理函数中处理。这类网络模型不能简单采用修改 socket 阻塞方式的方法来解决。

解决这一问题的唯一办法是在 LSP 中 hook 住 WSAAsynSelect,在该函数中创建一个我们自己的隐藏窗口,让网络应用程序的所有数据都转发我们自己的窗口上来,在我们的窗口的消息处理函数中进行代理协商和网络数据转发。

4.对于 UDP 网络数据的 socks5 代理转发比 TCP 又要稍微复杂一些,TCP 只需要 hook 到 connectWSAAsynSelect,对于网络收发数据的 sendrecv 函数是不需要我们自己来实现的。UDP 由于是不保持连接的,因此每次发送和接收的 UDP 包都要包含代理协商信息,因此我们需要把 RecvFrom 函数和 SendTo 函数都 hook 住。

对于 UDP 连接,需要在应用程序发送第一个 UDP 包的时候进行代理协商,以后发送数据的时候按照 socks5 协议的规定, 加上 socks5 头部;收到的信息去除 socks5 头部再交给应用程序。

标签: none

添加新评论