syncplay/syncplay-proxy/syncplay-proxy

63 lines
2.2 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:
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:
pass
try:
self.request.close()
except:
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()