67 lines
2.3 KiB
Python
Executable File
67 lines
2.3 KiB
Python
Executable File
#!/usr/bin/python3
|
|
|
|
# See https://github.com/Syncplay/syncplay/issues/346 for this script's raison-d'etre.
|
|
|
|
# original: https://github.com/Syncplay/syncplay/issues/346#issuecomment-698134786
|
|
# forked for LibertaCasa by Georg Pfuetzenreuter <georg@lysergic.dev>
|
|
# notable changes: utilize IPv6
|
|
|
|
import select
|
|
import socket
|
|
import socketserver
|
|
import sys
|
|
|
|
listen_port = int(sys.argv[1])
|
|
forward_port = int(sys.argv[2])
|
|
|
|
|
|
class SyncplayRequestHandler(socketserver.BaseRequestHandler):
|
|
def handle(self):
|
|
print('Handling connection from:', self.client_address)
|
|
data = self.request.recv(1024)
|
|
if data.strip() != b'{"TLS": {"startTLS": "send"}}':
|
|
print('Bad connection header from:', self.client_address)
|
|
try:
|
|
self.request.close()
|
|
except Exception as e:
|
|
pass
|
|
return
|
|
print('Opening forwarding connection on behalf of:', self.client_address)
|
|
forwarded_conn = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
|
|
forwarded_conn.connect(('localhost', forward_port))
|
|
# Acknowledge to the client that we are ready.
|
|
self.request.sendall(b'{"TLS": {"startTLS": "true"}}\r\n')
|
|
# Start proxying.
|
|
print('Proxying started for:', self.client_address)
|
|
sockets = (self.request, forwarded_conn)
|
|
while True:
|
|
rlist, _, xlist = select.select(sockets, (), sockets)
|
|
if len(xlist):
|
|
break
|
|
for s in rlist:
|
|
if s is self.request:
|
|
forwarded_conn.sendall(self.request.recv(1024))
|
|
elif s is forwarded_conn:
|
|
self.request.sendall(forwarded_conn.recv(1024))
|
|
print('Proxying stopped for:', self.client_address)
|
|
try:
|
|
forwarded_conn.close()
|
|
except Exception as e:
|
|
pass
|
|
try:
|
|
self.request.close()
|
|
except Exception as e:
|
|
pass
|
|
|
|
|
|
class SyncplayServer(socketserver.ThreadingTCPServer):
|
|
address_family = socket.AF_INET6
|
|
|
|
def server_bind(self):
|
|
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
socketserver.ThreadingTCPServer.server_bind(self)
|
|
|
|
|
|
with SyncplayServer(('', listen_port), SyncplayRequestHandler) as server:
|
|
server.serve_forever()
|