TCP 打孔 [英] TCP Hole Punching

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

问题描述

我正在尝试使用 mingw 工具链通过 Windows 套接字实现 TCP 打孔.我认为这个过程是正确的,但 似乎没有.我使用 this 作为参考.

I'm trying to implement TCP hole punching with windows socket using mingw toolchain. I think the process is right but the hole doesn't seems to take. I used this as reference.

  1. AB 连接到服务器 S
  2. S 发送给 AB 的路由器 IP + 用于连接S 的端口
  3. SB
  4. 做同样的事情
  5. A 启动 2 个线程:
    • 一个线程尝试使用S
    • 发送的信息连接到B的路由器
    • 当另一个线程连接到 S
    • 时,另一个线程正在等待用于连接到其路由器的同一端口上的传入连接
  1. A and B connect to the server S
  2. S sends to A, B's router IP + the port it used to connect to S
  3. S does the same for B
  4. A start 2 threads:
    • One thread tries connecting to B's router with the info sent by S
    • The other thread is waiting for an incoming connection on the same port used to connect to its router when it connected to S

我认为代码没有问题,因为:

I have no issue in the code I think since:

  • AB 确实获得了对方的 ip 和端口使用
  • 当他们联系服务器时,他们都在侦听用于连接到路由器的端口
  • 它们都连接到正确的 ip 和端口,但超时(代码错误 10060)
  • A and B does get each other ip and port to use
  • They are both listening on the port they used to connect to their router when they contacted the server
  • They are both connecting to the right ip and port but get timed out (code error 10060)

我遗漏了什么?

在进程资源管理器的帮助下,我看到其中一个客户端设法与对等方建立了连接.但是对方似乎没有考虑要建立的连接.

With the help of process explorer, I see that one of the client managed to establish a connection to the peer. But the peer doesn't seems to consider the connection to be made.

这是我用 Wireshark 捕获的内容.为了这个例子,服务器S和客户端A在同一台PC上.服务器 S 侦听重定向到该 PC 的特定端口 (8060).B 仍然尝试连接正确的 IP,因为它看到 S 发送的 A 的公共地址是 localhost 因此使用 S 的公共 IP 代替.(我已经用占位符替换了公共 IP)

Here is what I captured with Wireshark. For the sake of the example, the server S and the client A are on the same PC. The server S listens on a specific port (8060) redirected to that PC. B still tries to connect on the right IP because it sees that the public address of A sent by S is localhost and therefore uses the public IP of S instead. (I have replaced the public IPs by placeholders)

EDIT 2:我认为混淆是因为传入和传出连接请求数据都在同一端口上传输.这似乎弄乱了连接状态,因为我们不知道哪个套接字将从端口获取数据.如果我引用 msdn:

EDIT 2: I think the confusion is due to the fact that both incoming and outcoming connection request data are transfered on the same port. Which seems to mess up the connection state because we don't know which socket will get the data from the port. If I quote msdn:

SO_REUSEADDR 套接字选项允许套接字强制绑定到另一个套接字正在使用的端口.第二个套接字调用setsockoptoptname 参数设置为 SO_REUSEADDR 和 optval 参数设置为 TRUE 的布尔值,然后在与原装插座.第二个socket绑定成功后,绑定到该端口的所有套接字的行为是不确定的.

The SO_REUSEADDR socket option allows a socket to forcibly bind to a port in use by another socket. The second socket calls setsockopt with the optname parameter set to SO_REUSEADDR and the optval parameter set to a boolean value of TRUE before calling bind on the same port as the original socket. Once the second socket has successfully bound, the behavior for all sockets bound to that port is indeterminate.

但是 TCP 打孔技术需要在同一个端口上进行通信才能打开漏洞

But talking on the same port is required by the TCP Hole Punching technique to open up the holes !

推荐答案

开始 2 个线程:
一个线程尝试使用 S
发送的信息连接到 B 的路由器当另一个线程连接到 S

A start 2 threads:
One thread tries connecting to B's router with the info sent by S
The other thread is waiting for an incoming connection on the same port used to connect to its router when it connected to S

你不能用两个线程来做这件事,因为它只是一个操作.进行出站连接的每个 TCP 连接也在等待传入连接.您只需调用connect",然后发送出站 SYN 以建立连接并等待入站 SYN 建立连接.

You can't do this with two threads, since it's just one operation. Every TCP connection that is making an outbound connection is also waiting for an incoming connection. You simply call 'connect', and you are both sending outbound SYNs to make a connection and waiting for inbound SYNs to make a connection.

但是,您可能需要关闭与服务器的连接.当您已经从同一端口建立了连接时,您的平台可能不允许您从该端口建立 TCP 连接.因此,就像您开始 TCP 打孔一样,关闭与服务器的连接.将一个新的 TCP 套接字绑定到同一个端口,并调用 connect.

You may, however, need to close your connection to the server. Your platform likely doesn't permit you to make a TCP connection from a port when you already have an established connection from that same port. So just as you start TCP hole punching, close the connection to the server. Bind a new TCP socket to that same port, and call connect.

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

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