Skip to content

Instantly share code, notes, and snippets.

@g-andrade
Created October 23, 2017 17:29
Show Gist options
  • Save g-andrade/0508d836cdb181705e62a2979a633272 to your computer and use it in GitHub Desktop.
Save g-andrade/0508d836cdb181705e62a2979a633272 to your computer and use it in GitHub Desktop.
TCP server-to-server tunnel
import select
import socket
import sys
tcp_ip = '0.0.0.0'
tcp_port1 = int(sys.argv[1])
tcp_port2 = int(sys.argv[2])
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s1.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s1.bind((tcp_ip, tcp_port1))
s1.listen(1)
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s2.bind((tcp_ip, tcp_port2))
s2.listen(1)
conns = []
conn_reciprocates = {}
while True:
inputs = [s1, s2] + conns
outputs = []
readable, writable, exceptional = select.select(inputs, outputs, inputs, 1.0)
if s1 in readable and s2 in readable:
connA, addrA = s1.accept()
connB, addrB = s2.accept()
print 'Connecting %s with %s' % (connA.getpeername(), connB.getpeername())
conns.append(connA)
conns.append(connB)
conn_reciprocates[connA] = connB
conn_reciprocates[connB] = connA
for conn in readable:
if conn in (s1, s2):
continue
rconn = conn_reciprocates[conn]
data = conn.recv(8192)
if len(data) < 1:
exceptional.append(conn)
continue
print 'Forwarded %d bytes from %s to %s' % (len(data), conn.getpeername(), rconn.getpeername())
rconn.send(data)
rexceptional = []
for conn in exceptional:
assert conn not in (s1, s2)
if conn in rexceptional: # processed already
continue
rconn = conn_reciprocates[conn]
#print 'Disconnected %s from %s' % (conn.getpeername(), rconn.getpeername())
rconn.close()
conns.remove(conn)
conns.remove(rconn)
del conn_reciprocates[conn]
del conn_reciprocates[rconn]
rexceptional.append(rconn)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment