博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一个简单的代理需要考虑的内容

Posted on 2016-04-08 13:37  bw_0927  阅读(217)  评论(0)    收藏  举报

http://blog.csdn.net/solstice/article/details/6462552

 

TCP 中继器

在实现 socks4a proxy 之前,我们先写一个功能更简单的网络程序—— TCP 中继器 (TCP relay),或者叫做穷人的 tcpdump (poor man's tcpdump)。

一般情况下,客户端程序直接连接服务端,如下图。有时候,我们想在 client 和 server 之间放一个中继器 (relay),把 client 与 server 之间的通信内容记录下来。这时用 tcpdump 是最方便省事的,但是 tcpdump 需要 root 权限,万一没有 root 密码呢?穷人有穷人的办法,自己写一个 relay,让 client 连接 relay,再让 relay 连接 server,如下图中的 T 型结构,relay 扮演了类似 proxy 的角色。

relay

TcpRelay 是我们自己写的,可以动动手脚。除了记录通信内容,还可以制造延时,或者故意翻转 1 bit 数据以模拟 router 硬件故障。

TcpRelay 的功能(业务逻辑)看上去很简单,无非是把连接 C 上收到的数据发给连接 S,同时把连接 S 上收到的数据发给连接 C。但仔细考虑起来,细节其实不那么简单:

  • 建立连接。为了真实模拟 client,TcpRelay 在 accept 连接 C 之后才向 server 发起连接 S,那么在 S 建立起来之前,从 C 收到数据怎么办?要不要暂存起来?
  • 并发连接的管理。上图中只画出了一个 client,实际上 TcpRelay 可以服务多个 clients,左右两边这些并发连接如何管理,如何防止串话(cross talk)?
  • 连接断开。Client 和 Server 都可能主动断开连接。当 Client 主动断开连接 C 时,TcpRelay 应该立刻断开 S。当 Server 主动断开连接 S 时,TcpRelay 应立刻断开 C。这样才能比较精确地模拟 Client 和 Server 的行为。在关闭连接的刹那,又有新的 client 连接进来,复用了刚刚 close 的 fd 号码,会不会造成串话? 万一 Client 和 Server 几乎同时主动断开连接,TcpRelay 如何应对?
  • 速度不匹配。如果连接 C 的带宽是 100KB/s,而连接 S 的带宽是 10MB/s,不巧 Server 是个 chargen 服务,会全速发送数据,那么会不会撑爆 TcpRelay 的 buffer?如何限速?特别是在使用 non-blocking IO 和 level-trigger polling 的时候如何限制读取数据的速度?