记录一种曾经做过的 无聊的 园区缓存变相 提升 带宽的方案.
久远地快要忘记细节了…

the very begining

Why? 是很久以前做过的一种方案, 之后再也没有在什么地方见过的方案.

in one word

通过接入整个的园区内的网络流量, 提取出其中的对缓存资源的 HTTP 请求, 构(伪)造一个对应资源的访问内网缓存资源的 302 报文进行返回(没有进行握手等步骤), 使得用户对外网资源的访问变成对内网资源进行访问.

为什么需要?

首先, 一个园区, 如一片小区, 一座学校, 出口带宽都是有限. 其次, 网络带宽的流量分布在一天之中是有峰谷的, 大部分是集中在晚 6 点以后, 而在临晨到中午之前, 带宽处于空闲. 以及, 峰值时段, 大部分的流量是被视频下载等请求占用. 所以, 如果有能力缓存热点视频网站的热点视频资源, 并将园区内对该部分资源的访问转而访问内网, 那么便可以变相地 提升 带宽.
之前的方案实测 提升 的带宽可达 20%-60%.

如何接入流量?

  1. 一种是服务器上两个网口, 一般会需要万兆网口, 一进一出, 服务器从一口读取流量, 截获并伪造部分报文返回, 其余的放行.
  2. 另外一种则仅需配置交换机镜像流量功能导入服务器, 服务器开启混杂模式用 raw socket 读取流量进行分析.

如何提取流量信息?

接受流量的主机网卡开启混杂模式, 使用 raw socket 接受全部流量. 根据链路层->网络层->传输层->应用层, 剥离所有非 HTTP 请求. 现在还记得的步骤是,

  1. 链路层可能需要剥离 vlan tag.
  2. IP 层过滤 IP 协议, 仅留下 IPV4, 过滤请求的内网 IP(废话…)
  3. 传输层丢弃 udp(废话…), 过滤 tcp 握手阶段的所有报文
  4. 得到 HTTP 请求的数据后则几乎都是处理文本的时候了, 过滤请求方法, 请求 url, 分析请求资源的名称和后缀, 查找资源是否存在(用了 redis).

如何伪造 302 报文?

如上的 1234 步骤确定了某次 HTTP 请求是否命中了服务器的缓存, 便可以以应用层->传输层->网络层->链路层的方式, 一路构造符合要求的报文了.

如何获取热点网站的热点资源

利用峰谷时段的带宽, 下载所配置的视频网站(甚至是手机应用 apk 网站)的资源. 视频链接下载的工具可选 you-get.

Why?

  1. 为什么这种伪造的单个报文能被接收? 甚至都没有和主机建立 tcp 连接?
    因为该伪造的报文, 主机看起来和来自真正的请求的服务器的报文没区别, 而主机会更快地获取到该来自内网服务器的伪造报文, 而不是来自真正服务器的报文. 当然, 也就要求软件返回伪造的报文并返回的时间要比真实报文的返回要快……

  2. 视频分片怎么办? 因为用户拖拉视频进度条, 浏览器会发起带切片 range 信息的请求的吧?
    首先, 这还需要分析不同视频网站在处理拖拉进度条时发起的请求分片描述的是时间还是文件偏移. 然后需要写 ngx_xxx_module 进行处理, 可用 lua 来写 module, 但似乎处理速度始终没 C 来的快, 除了开发上…