UDP 打孔主机特定故障 [英] UDP hole punching host-specific failure

查看:58
本文介绍了UDP 打孔主机特定故障的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I wrote a program that sets-up peer-to-peer links. The programm, which can be found at http://basyl.co.uk/code/punch/doc/files/Readme-txt.html, is in two parts: a server that runs on a public host; and a client that is used by each end of the desired peer-to-peer link.

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

I have access to two public servers: 'bonn' (home.contextshift.co.uk) and 'entropy' (home2.contextshift.co.uk)

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

  • If the server is on bonn and clients are run on bonn, entropy and my home PC (behind NAT), a punched connection from entropy can talk to my PC without problem. However, a connection from bonn to the PC fails; data from the PC reaches bonn, but data from bonn back through the NAT hole never arrives.

如果服务器再次处于熵状态,则客户端在 bonn、entropy 和我的 PC 上运行,所有客户端之间的打孔连接都可以正常工作.

If the server is on entropy and again, clients are run on bonn, entropy and my PC, punched connections work fine between all clients.

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

This is confusing as the server is not involved in the peer-to-peer data flow. If you are still with me, here is the flow:

  • 客户端-A 通过 TCP 链接连接到服务器并获得唯一令牌;
  • Client-B 通过 TCP 链接连接到服务器并获得唯一令牌;

  • Client-A connects to Server on a TCP link and gets a unique token;
  • Client-B connects to Server on a TCP link and gets a unique token;

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

Client-A and Client-B receive updates over their TCP link telling them who else is attached;

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

Client-A (or B) sends a request to the Server over a newly created UDP link passing its token and the name of Client-B;

服务器从令牌中识别出客户端 A 并通过其 TCP 链接将请求转发给客户端 B,在请求中包括 A 的 UDP 地址/端口号;

The Server identifies Client-A from the token and forwards the request to Client-B over its TCP link, including A's UDP address/port number in the request;

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

Client-A (or B) sends a confirmation to the Server over a newly created UDP link, passing its token and the name of Client-A;

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

The Server identifies Client-B from the token and forwards the request to Client-A over its TCP link, including B's UDP address/port number in the request;

A 和 B 现在拥有对方的 UDP 地址/端口,可以互相 ping 并交换数据.

A and B now have the UDP address/port of the other and can ping each other and exchange data.

如您所见,服务器从不讨论客户端为其请求创建的 UDP 链接,仅讨论 TCP 链接.

As you can see, the Server never talks on the UDP links created by the Clients for their requests, only on the TCP links.

所以总而言之,当服务器在同一台主机上时,客户端不会在特定主机上工作.关于这种行为的原因或我可以进一步调查的方法有什么建议吗?

So in summary, the client doesn't work on a particular host when the server is on the same host. Any suggestions for reasons for this behaviour or for ways I could investigate this further?

请注意,此测试是人为的,因为打孔的目的是在两个都位于 NAT 之后的主机之间进行通信.无论服务器在哪里,这实际上都有效,因此该问题可能被视为学术问题.

Note that this test is artificial because the point of the hole punching is to talk between two hosts both behind NAT. This in fact works, wherever the server is, so the problem might be considered academic.

还要注意,在编写程序之前,我尝试使用一个名为NatCheck"的公共应用程序.这也以类似的方式失败,尽管我没有对其进行太多调查 - 它需要三个公共主机,我将其修改为仅使用我的两个.当它无法工作时,我认为我以某种方式搞砸了并丢弃了该应用程序.

Note also that before writing the program, I tried using a public app called 'NatCheck'. This also failed in a similar way, although I didn't investigate it much - it required three public hosts and I modified it to use just my two. When it failed to work, I assumed that I had screwed up in some way and discarded the app.

也非常欢迎对代码提出任何意见(我可能会将其发布在代码审查网站上).

Any comments on the code also highly welcome (I will probably post it on the code review site).

推荐答案

我不能完全理解所有这些,但听起来您想使用中间服务器来发现客户端 A 和 B 的源 UDP 端口,以便A 和 B 可以同时相互发送 UDP 数据报,从而打开 NAT 规则并(最终)允许流量通过.

I can't quite follow all that, but it sounds like you want to use an intermediary server to discover the source UDP ports for Clients A and B so that A and B can simultaneously send UDP datagrams at each-other, thereby opening NAT rules and (eventually) allowing the traffic through.

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

Here's the problem: NAT can map the source port to whatever it wants. When B sends a datagram to the server, there's no guarantee that the source port seen by the server will be the same one that is used when B sends a datagram to A.

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

There are a lot of reasons why the NAT might change the port number, and a security conscious one will randomize just to prevent what you are trying to do. So while you may be able to make double punching (NAT to NAT) work sometimes, you cannot do so every time.

这篇关于UDP 打孔主机特定故障的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆