Skip to content

使 UDP TCP 打洞后外部端口相同 #133

@Mythologyli

Description

@Mythologyli

目的

一些应用,如 BitTorrent,可以利用 TCP 打洞极大提升连接性 (Mythologyli/qBittorrent-NAT-TCP-Hole-Punching) 。不过,由于只进行 TCP 打洞,无法完成基于 µTP 协议 的 UDP 传入连接。

可以通过 Natter 对 UDP 和 TCP 分别进行打洞,但受 CGNAT 行为限制,难以保证打洞后外部端口相同 (heiher/natmap#53 (comment)) 。而 BitTorrent 客户端通常只向 tracker 汇报一个端口。

可能的实现思路

生日悖论类似,假设 CGNAT 在 d=65535 个空闲 TCP/UDP 端口中随机分配,每次打洞得到的外部端口不重复,如果分别进行 n 次 TCP 和 UDP 打洞,存在相同外部端口的概率为:

$P=1-(1-\frac{n}{d})(1-\frac{n}{d-1})\cdots(1-\frac{n}{d-(n-1)})$

n P
100 14.17%
200 45.79%
400 91.43%
800 99.99%

如果打洞速率为 100 次/秒(当然有点暴力了),4 秒内找到相同外部端口的概率高于 90%。也可以降低打洞速率,对很多场景而言在数分钟内成功都是可以接受的。

考虑到 CGNAT 很可能有一些固定的行为模式(例如外部端口递增),可以再对打洞方法进行优化。

可能存在的问题

  • 打洞的速率过高

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions