UDP打孔主机特定故障

时间:2012-03-07 01:00:57

标签: networking udp hole-punching

我写了一个设置点对点链接的程序。该程序可以在http://basyl.co.uk/code/punch/doc/files/Readme-txt.html找到,它分为两部分:一个在公共主机上运行的服务器;以及所需对等链路每端使用的客户端。

我可以访问两个公共服务器:'bonn'(home.contextshift.co.uk)和'entropy'(home2.contextshift.co.uk)

  • 如果服务器在bonn上,客户端运行在bonn,entropy和我的家用PC(在NAT后面),来自熵的打孔连接可以毫无问题地与我的PC通信。但是,从波恩到PC的连接失败了;来自PC的数据达到了波恩,但是从波恩回到NAT洞的数据永远不会到来。

  • 如果服务器处于熵状态,并且客户端在bonn,entropy和我的PC上运行,打孔连接在所有客户端之间正常工作。

这很令人困惑,因为服务器不参与对等数据流。如果你还在我身边,这就是流程:

  • Client-A在TCP链路上连接到服务器并获取唯一令牌;
  • Client-B在TCP链路上连接到服务器并获取唯一令牌;

  • 客户端A和客户端B通过其TCP链接接收更新,告知他们还有谁在附加;

  • Client-A(或B)通过新创建的UDP链接向服务器发送请求,传递其令牌和Client-B的名称;

  • 服务器从令牌中识别Client-A,并通过其TCP链路将请求转发给Client-B,包括请求中的A的UDP地址/端口号;

  • Client-A(或B)通过新创建的UDP链接向服务器发送确认,并传递其令牌和Client-A的名称;

  • 服务器从令牌中识别Client-B,并通过其TCP链路将请求转发给Client-A,包括请求中B的UDP地址/端口号;

  • A和B现在拥有另一个的UDP地址/端口,可以相互ping通并交换数据。

正如您所看到的,服务器从不谈论客户端为其请求创建的UDP链接,仅在TCP链接上。

总而言之,当服务器位于同一主机上时,客户端无法在特定主机上运行。有关此行为的原因或我可以进一步调查的方法的任何建议吗?

请注意,此测试是人为的,因为打孔的目的是在NAT后面的两台主机之间进行通话。事实上,无论服务器在哪里,这都有效,因此问题可能被视为学术问题。

另请注意,在编写程序之前,我尝试使用名为“NatCheck”的公共应用程序。这也以类似的方式失败,虽然我没有进行太多调查 - 它需要三个公共主机,我修改它只使用我的两个。当它无法工作时,我认为我已经搞砸了某些方式并放弃了应用程序。

对代码的任何评论也非常欢迎(我可能会在代码审查网站上发布)。

3 个答案:

答案 0 :(得分:3)

我不能完全遵循这一切,但听起来你想使用中间服务器来发现客户端A和B的源UDP端口,以便A和B可以同时发送UDP数据报,从而打开NAT规则并(最终)允许流量通过。

问题在于:NAT可以将源端口映射到它想要的任何端口。当B向服务器发送数据报时,不能保证服务器看到的源端口与B向A发送数据报时使用的源端口相同。

NAT可能会更改端口号的原因有很多,而安全意识的人会随机选择以防止您尝试执行此操作。因此,虽然您有时可以进行双击(NAT到NAT)工作,但每次都不能这样做。

答案 1 :(得分:1)

  

总而言之,当服务器位于同一主机上时,客户端无法在特定主机上运行。有关此行为的原因的任何建议

可能是服务器将clientA视为127.0.0.1(或者可能是不可路由的LAN地址?)而不是其公共IP地址?

如果clientB尝试使用错误的地址联系clientA,很明显为什么UDP数据报无法到达目标收件人。

  

还是我可以进一步调查的方法?

来自服务器(AKA clientA)和clientB的tcpdump的某些输出会有很大帮助。您可能希望使用-i any,也许-s 0

答案 2 :(得分:0)

the client doesn't work on a particular host when the server is on the same host

在某些极端情况下,NAT仅接受来自目标IP地址的流量:用于打孔的端口。由于它不是远程NAT-ed对等体之一,因此它们阻止来自它的流量。这可以解释你的问题。