我写了一个设置点对点链接的程序。该程序可以在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-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”的公共应用程序。这也以类似的方式失败,虽然我没有进行太多调查 - 它需要三个公共主机,我修改它只使用我的两个。当它无法工作时,我认为我已经搞砸了某些方式并放弃了应用程序。
对代码的任何评论也非常欢迎(我可能会在代码审查网站上发布)。
答案 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对等体之一,因此它们阻止来自它的流量。这可以解释你的问题。