TCP tunnel的困惑和解决

周末我做了一个简易到竟然不能登堂入室的玩具,我希望级连多段TCP,分别使用不同的拥塞控制算法,是的,我不想改一行代码。

我希望用现在已经存在的东西,通过不同的排列组合达到不同的效果,这个思路和那些重复造轮子的卷客们完全不同。

在高性能领域,高贵的人们通常鄙视Linux内核协议栈实现的任何功能,比如他们鄙视iptables,他们鄙视nf_conntrack…然而其实这些很low的东西已经可以解决80%的问题了,而这80%的问题正是高贵的卷客们视而不见的,同时这也是高贵的卷客们内卷的现象,或者原因。

我写了一个全世界最差劲最low的TCP中继,它在:
https://github.com/marywangran/tcptunnel-relay

一开始,我发现了一个问题,一个处理路径太长,会导致延时增加,吞吐陡降,于是我用buffer缩短了处理路径:
在这里插入图片描述
一开始我就觉得用TCP运输IP数据报就有问题,你要有边界不是吗?我用Length|Payload定义协议,首先写入一个长度,然后写入Payload,我就是这么做的。

然而到了后来,愚昧的我发现我犯了一个低级错误,我实在太傻了。

我为什么要分别两次写入长度和Payload呢?为什么就不能在offset不为0的地方读入IP数据报呢?这样:

n, err := tun.Read(packet[4:])
binary.LittleEndian.PutUint32(packet[0:4], uint32(n))
// 当然了,这里缺一个buffer!缺一个buffer!缺一个buffer!
conn.Write(packet[0:n + 4])

这样就省了一次系统调用开销。并且我真的我这样试了,效果展现。这是那些带着领带的经理所不能理解的。具体参见:
https://github.com/marywangran/tcptunnel-relay/blob/main/edge2.go

我试着用Java写了一版这个,然而处理tuntap设备时出现了麻烦,不得不用native方法。这是事情虽然简单,但及其麻烦,所以只有作罢,Java版本在:
https://github.com/marywangran/tcptunnel-java

浙江温州皮鞋湿,下雨进水不会胖。

Guess you like

Origin blog.csdn.net/dog250/article/details/118526586