TCP打孔问题

Geo*_*ard 7 python sockets tcp hole-punching

我试图使用本文中概述的原理为Python 3中的防火墙编写基本的TCP打孔器.但是我无法连接任何东西.这是代码:

#!/usr/bin/python3

import sys
import socket
import _thread as thread

def client():
    c = socket.socket()

    c.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    c.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)

    c.bind((socket.gethostbyname(socket.gethostname()), int(sys.argv[3])))
    while(c.connect_ex((sys.argv[1], int(sys.argv[2])))):
        pass
    print("connected!")
    thread.interrupt_main()

def server():
    c = socket.socket()

    c.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    c.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)

    c.bind((socket.gethostbyname(socket.gethostname()), int(sys.argv[3])))
    c.listen(5)
    c.accept()
    print("connected!")
    thread.interrupt_main()

def main():
    thread.start_new_thread(client, ())
    thread.start_new_thread(server, ())

    while True:
        pass

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

我决定在我的本地计算机上尝试打孔器,这样我就可以捕获两个实例发送的所有流量.我首先建立了一个环回防火墙:

iptables -A INPUT -i lo -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i lo -j DROP
Run Code Online (Sandbox Code Playgroud)

然后我发布了两个脚本副本:

left$ ./tcphole.py localhost 20012 20011
Run Code Online (Sandbox Code Playgroud)

right$ ./tcphole.py localhost 20011 20012
Run Code Online (Sandbox Code Playgroud)

根据Wireshark的说法,我可以看到SYN数据包是双向传输的:

Wireshark捕获

但没有任何东西打印"连接!" 我究竟做错了什么?

Geo*_*ard 6

结果证明答案非常简单:如果数据包RELATED没有到达相同的 IP 地址,则不会考虑这些数据包!

bind行更改为

c.bind('', int(sys.argv[3])))
Run Code Online (Sandbox Code Playgroud)

''绑定到环回地址)完全解决了这个问题。