TCP打孔

发布于 2024-12-26 06:54:06 字数 1760 浏览 5 评论 0原文

我正在尝试使用 mingw 工具链通过 Windows 套接字实现 TCP 打孔。我认为这个过程是正确的,但漏洞似乎并不适用。我使用作为参考。

  1. AB连接到服务器S
  2. S发送到A >B 的路由器 IP + 用于连接 S 的端口
  3. 作用相同
  4. SB A 的 启动2个线程:
    • 一个线程尝试使用 S 发送的信息连接到 B 的路由器
    • 另一个线程正在等待连接到 S 时用于连接到其路由器的同一端口上的传入连接
  5. B 时,它的路由器也会做同样的事情

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

  • AB< /strong> 确实获取对方的 ip 和端口以使用
  • 它们都在监听它们曾经使用的端口当他们联系服务器时连接到他们的路由器
  • 他们都连接到正确的IP和端口但超时(代码错误10060

我错过了什么?

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

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

wireshark

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

SO_REUSEADDR 套接字选项允许套接字强制绑定到 端口正在被另一个套接字使用。第二个套接字调用setsockopt optname 参数设置为 SO_REUSEADDR 和 optval 参数设置 在与该端口相同的端口上调用绑定之前,将其设置为布尔值 TRUE 原装插座。 一旦第二个套接字成功绑定, 绑定到该端口的所有套接字的行为是不确定的。

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

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. 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
  5. B does the same

I have no issue in the code I think since:

  • 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)

I am missing something ?

EDIT: 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.

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)

wireshark

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:

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.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

灯下孤影 2025-01-02 06:54:06

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

时,另一个线程正在等待用于连接到其路由器的同一端口上的传入连接

您不能使用两个线程执行此操作,因为这只是一个操作。每个建立出站连接的 TCP 连接也在等待传入连接。您只需调用“connect”,即可发送出站 SYN 来建立连接,并等待入站 SYN 来建立连接。

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

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

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.

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.

篱下浅笙歌 2025-01-02 06:54:06

穿越 NAT 路由器的一个简单解决方案是让您的流量遵循 NAT 已有转发算法的协议,例如 FTP。

A simple solution to traverse into NAT routers is to make your traffic follow a protocol that your NAT already has an algorithm for forwarding, such as FTP.

玻璃人 2025-01-02 06:54:06
  1. 使用Wireshark检查tcp连接请求(3-way Handhsake进程)是否正常。

  2. 确保您的监听器线程使用 select() 来多路分离描述符。

  3. sockPeerConect(用于连接其他对等点的套接字)是侦听器线程中的 FD_SET()。

  4. 确保您正在检查

     int 侦听器线程()
     {
       而(真)
       {
           FD_SET(sockPeerConn);
           FD_SET(sockServerConn);
           FD_SET(nConnectedSock);
          如果(FD_ISSET(sockPeerConect)
          {
            /// 并在里面调用accept()
            nConnectedSock = 接受( ....);
    
           }
           如果(FD_ISSET(sockServerConn)
           {
            /// 从服务器接收数据
            接收(sockServerConn);
    
           }
           如果 (FD_ISSET(nConnectedSock )
           {
            /// 从其他 Peer 接收数据
             接收(nConnectedSock);
    
           }
    
       }
      }
    

5.确保您同时启动 A 到 B 以及 B 到 A 的对等连接。
6.在连接到服务器和对等点之前启动侦听器线程,并使用单个侦听器线程来接收服务器和客户端。

  1. Use Wireshark to check tcp connection request(3-way Handhsake process) is going properly.

  2. Ensure your Listener thread is having select() to de-multiplex the descriptor.

  3. sockPeerConect(socket used to connect Other peer) is FD_SET() in Listener Thread.

  4. Ensure your are checking

     int Listener Thread()
     {
       while(true)
       {
           FD_SET(sockPeerConn);
           FD_SET(sockServerConn);
           FD_SET(nConnectedSock );
          if (FD_ISSET(sockPeerConect)
          {
            /// and calling accept() in side the
            nConnectedSock = accept( ....);
    
           }
           if (FD_ISSET(sockServerConn)
           {
            /// receive data from Server
            recv(sockServerConn );
    
           }
           if (FD_ISSET(nConnectedSock )
           {
            /// Receive data from Other Peer
             recv(nConnectedSock );
    
           }
    
       }
      }
    

5.Ensure you are simultaneously starting peer connection A to B and B to A.
6.Start your Listener Thread Prior to Connection to server and Peer and have Single Listener Thread for receiving Server and Client.

拔了角的鹿 2025-01-02 06:54:06

并非每个路由器都支持 tcp 打洞,请查看以下文章,其中详细说明:

跨网络地址转换器的点对点通信

not every router supports tcp hole punching, please check out the following paper which explains in detail:

Peer-to-Peer Communication Across Network Address Translators

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文