前天晚上在家中,当我搭起熟悉的ss
梯子时, 发现不可用了T.T。登陆到控制台查看,发现国内的IP被Block了。问问身边朋友,也是一样的现象,听说是因为网络安全周?!看来只能寄希望于一周后能恢复吧....
昨天瞎逛,看到一个开源项目:udp2raw-tunnel,他实现的是将一个IP报文伪装成TCP报文,目的是穿过网络中UDP防火墙.
哈?!这难道是TCP-In-TCP
? 这玩意儿不是不可用吗?
很早以前就有人说过了:
Why TCP Over TCP Is A Bad Idea
为了将问题描述地更清楚,我还是将隧道应用的组网画出来吧:
图中主机A和主机D通过隧道进行End to End的通信,而设备B对原始报文进行加密和封装,设备C做解封装和解密。当然B和C不一定是单独的设备,它们可以就集成在主机A和主机D中。
TCP-In-TCP
的问题是: 当隧道报文在网络中丢失时,B上的TCP连接<B-C>显然会对报文进行重传,但要知道A上也有一个TCP连接<A-D>,所以A如果超时也会进行重传,而从整个网络的角度,这个重传是不必要的。但A不会理会,因为它是TCP。
TCP的设计原则是下层协议和介质是不可靠的,所以我需要自己保证。所以, TCP-In-TCP
这样的双保险完全是没有必要的。不仅没必要,还有可能造成网络中重传报文过多而拥塞。
不过也有研究说TCP-In-TCP
在一定条件下可以提高网络的有效吞吐率:
论文在此 Understanding TCP over TCP: Effects of TCP Tunneling on End-to-End Throughput and Latency
还是差不多的拓扑:
论文中将传播延时(propagation delay)考虑进来了, 得出的结论是当Ta和Tb都比较大时,使用TCP-In-TCP
隧道反而比不使用的有效吞吐量更大。为什么呢? 原因也比较好解释:当Ta和Tb比较大时,显然在A视角里的TCP连接<A-D>的RTT会比B视角里的<B-D>大不少,那么如果隧道报文在网络中丢了,B重传隧道报文,而A由于超时时间还没到,就不会重传原始报文。而如果不使用隧道,那么重传的任务就还是A的,显然B重传报文的传播延时要比A重传的大。
看上去有些道理,不过当网络条件实在不好,A的超时时间也到达后,就还是会回到之前更糟糕的情况....
所以我还是认为TCP-In-TCP
不是一个好主意..
那么, 本文开头提到的那个开源项目是怎么回事呢? 仔细看了看它的介绍,又下载了它的代码。噢,原来它真的只是伪装成了TCP报文,实际上隧道报文的外层TCP封装都是在用户态自己填充的TCP首部,然后通过raw socket
发送;而在接收端,同样使用raw socket
(关于这个,详见inet socket 与 packet socket),所以报文会提前进入raw_local_deliver
上送,而不会由TCP去接收,这样也就没有了TCP状态机那一大堆复杂的东西。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。