-
Notifications
You must be signed in to change notification settings - Fork 9
/
punch_server.py
113 lines (100 loc) · 3.1 KB
/
punch_server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/usr/bin/env python
#
# Proof of Concept: TCP Hole Punching
# Two client connect to a server and get redirected to each other.
#
# This is the TCP server.
#
# Name : Nguyen Thanh Hiep
# 2014/06 IUH
#
import socket
import struct
import sys
import select
import string
import threading
def bytes2addr( bytes):
"""Convert a hash to an address pair."""
if len(bytes) != 6:
raise (ValueError, "invalid bytes")
host = socket.inet_ntoa( bytes[:4] )
port, = struct.unpack( "H", bytes[-2:] )
return host, port
def addr2bytes( addr):
"""Convert an address pair to a hash."""
host, port = addr
try:
host = socket.gethostbyname( host )
except (socket.gaierror, socket.error):
raise (ValueError, "invalid host")
try:
port = int(port)
except ValueError:
raise (ValueError, "invalid port")
bytes = socket.inet_aton( host )
bytes += struct.pack( "H", port )
return bytes
class ClientThread(threading.Thread):
def __init__(self,client_address,connection,threads):
threading.Thread.__init__(self)
self.client_address = client_address
self.connection = connection
self.threads = threads
print "[+] New thread started for ", client_address
def run(self):
self.client = []
print "connection from %s:%d" % self.client_address
name = self.connection.recv(32)
self.connection.send("ok" + name)
print "received name"
data = self.connection.recv(32)
local = bytes2addr(data)
self.connection.send("oklocal")
print "received local"
code = self.connection.recv(32)
self.connection.send("okcode")
print "received code"
self.client.append(self.client_address)
self.client.append(local)
self.client.append(code)
data = self.connection.recv(32)
print "--- add pool ", ":" , self.client
print "--- request received for other Request Name: ", name
no = len(self.threads)
if no % 2 == 0:
print self.threads[no-2].client
a = self.threads[no-2].client
b = self.client
print "--- thiet lap ket noi giua cac Name: ", name
self.connection.send(addr2bytes(a[0]))
self.connection.send(addr2bytes(a[1]))
self.connection.send(a[2])
self.connection.send("RE")
self.threads[no-2].connection.send(addr2bytes(b[0]))
self.threads[no-2].connection.send(addr2bytes(b[1]))
self.threads[no-2].connection.send(b[2])
self.threads[no-2].connection.send("SE")
print "--- linked ---", name
print "--- ket noi hai may thanh cong ---"
def main():
port = 8080
try:
port = int(sys.argv[1])
except (IndexError, ValueError):
pass
s = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind( ("", port) )
threads = []
while True:
s.listen(5)
print "---TCP hole punching---"
print "Listening on *:%d (tcp)" % port
print "......................."
connection, client_address = s.accept()
newthread = ClientThread(client_address, connection, threads)
newthread.start()
threads.append(newthread)
if __name__ == "__main__":
main()