用于在多个 TCP 连接之间拆分 TCP 或 UDP 连接的隧道
你什么时候想把一个 TCP 连接拆分成多个?通常你使用一个 隧道 达到 恰恰相反 .我的用例是绕过移动网络中的带宽限制,因此使用 SIM 卡进行了测试,计划中没有剩余数据[1].
这 隧道 被写在 高朗 因为它足够快,并且通常用于网络工具。 cli 几乎不可用,因为在我测试不同的方法时,大多数选项都经过重新设计。
最初有“flings”和“lassos”,用于拆分传出(flinged)和传入(lassoed)的连接数,但这是一个不必要的抽象,因为最好用目的地标记数据包,尽管主要目的是为传出和传入连接提供不同的速率限制,因此向上/向下之间的更高级别分离似乎很实用。
客户端必须实例化所有连接,因为我们假设服务器无法打开传出连接。当客户端接收到来自用户应用程序的连接时,它会与服务器建立所需的连接池,无论它接收到什么数据,它都会根据用户定义的限制将其拆分到专用连接中。
然后将数据包发送到服务器,服务器必须将它们重构为正确的顺序,因为不同的 TCP 连接可以随时完成数据流(不遵守发送顺序, 因为路由 ),然后转发到接收应用程序。
当达到每个连接配置的数据限制时,连接关闭并打开新连接,类似于 影袜 代理跨不同流隧道传输数据,目的是屏蔽数据流的行为,除了我们的隧道尽可能频繁地这样做。
这里的目的是控制每个连接应该处理多少数据。就我们的目的而言,它永远不会超出通常是 MTU 窗口大小。您可以将 MTU 视为在整个网络中传输的一段数据的上限,这是我们的目标,因为我们希望绕过门控网络的带宽速率限制。要限制客户端可以通过的数据量,您需要 数数 对的?如果您的逻辑适用于类似do-while
收到packet
如果received_packets
+ packet
> user_limit
断开连接
别的
继续流媒体
那么你需要 至少 收到一个packet
.我不确定这是否是实际发生的情况,或者我的隧道工作的原因是另一个。也许甚至可以检查第一个数据包,但从设计的角度来看,这意味着您必须检查 每一个 单个连接,这会使系统更容易受到 DOS 攻击,是的,我的隧道可以轻松用作高效的 DOS/Stress 工具,因为您可以将数据拆分为非常小的数据包(这意味着 TCP 连接将具有很高的回收压力) ) 并拥有一个您喜欢的大连接池。
对不同端口的测试还表明,只有通过 一些 端口,并且端口之间的限制不断不同,443
给一个更高的窗户,周围20kb
,猜测是因为TLS
握手需要更多数据,并且这些速率限制会根据一天中的时间而变化[2].
我尝试了擦除编码,希望能增加数据吞吐量。通过使用纠删码库和编码/解码数据本身,以及通过覆盖 康普 协议高于我的拆分协议。尝试 KCP 似乎是一种倒退的方法,因为它用更好的延迟来换取更低的吞吐量,但我最初的假设是我的瓶颈是在传输过程中连接断开,这会导致大量损坏的数据包,所以我本可以实现更高的带纠错的吞吐量。
事实证明,这只是对客户端可以通过网络发送的 TCP 连接数的速率限制,因此只是 DOS 保护,我无能为力。 X 数量的连接后任何SYN
尝试停止收到应得的ACK
,填补积压并最终使隧道停滞。试验和错误表明,它之间是可能的4-8
[3] 连接在任何给定时间打开,并且 MTU 为500-1000
字节,你至少可以保持稳定的流128kbps
,如果不需要恒定流,您可以通过以下方式在更短的时间内实现更高的速度 爆裂 许多按需连接。
相反,一个(真)DNS
隧道只能勉强推56kbps
并且很快就会受到限制,因为我认为大量的 DNS 请求看起来比 TCP 请求更可疑。我们必须指定一个true DNS 隧道对虚假子域上的(传出)数据进行编码,并对通过查询 DNS 记录接收到的(传入)数据进行解码,而有时 DNS 隧道可以被认为是通过 DNS 端口的原始 UDP 连接,这可能在过去的某个时候是 DNS 服务器允许并正确转发。
我不确定我是否达到了目标 公用事业 明智的做法是,因为运行这种隧道会使您的手机非常热,并浪费大量电池,但是将其作为备用连接可以令人放心……如果我真的不屑于让它足够稳定:)
[1] | 通常当sim卡没有更多数据浏览网页时,网页请求重定向到捕获网关(告诉您购买更多数据) |
[2] | 移动数据计划可以在夜间提供更好的连接 |
[3] | 这个数字与常见的核心数有些一致,可能会让您怀疑内核以某种方式限制了连接,我们隧道打开连接的情况绝对不寻常,但调整 linux 旋钮从来没有给我带来更好的结果。 |