Skip to content

Commit be711b6

Browse files
committed
Fix tcp proxy for allow keep alive connections (also allowed proxy database connections)
1 parent 8cd5431 commit be711b6

File tree

3 files changed

+23
-29
lines changed

3 files changed

+23
-29
lines changed
-1.3 KB
Binary file not shown.
-2.74 KB
Binary file not shown.

src/proxy.py

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from socketserver import BaseRequestHandler, TCPServer, ThreadingMixIn
2-
from socket import socket, AF_INET, SOCK_STREAM, gethostbyname, error
2+
from socket import socket, AF_INET, SOCK_STREAM, gethostbyname, error, timeout
33
import threading
44
import logging
55
from enum import Enum, auto
@@ -21,6 +21,7 @@ class TcpProxySockHandler(BaseRequestHandler):
2121
PROXY_HOST = None
2222
PROXY_PORT = None
2323
Logger = logging.getLogger("TcpProxyHandler")
24+
CONNECTION_ACTIVE = True
2425

2526
def handle(self):
2627
# self.request is the TCP socket connected to the client
@@ -30,46 +31,38 @@ def handle(self):
3031
# Try to connect to the server and send data
3132
try:
3233
sock.connect((self.PROXY_HOST, self.PROXY_PORT))
33-
self.transferData(self.request, sock)
34-
# Receive data from the server
35-
self.Logger.info("Receive data: %s <- %s:%s" %(self.client_address[0], self.PROXY_HOST, self.PROXY_PORT))
36-
self.transferData(sock, self.request)
34+
35+
requestThread = threading.Thread(target=self.transfer_data, args=(self.request, sock))
36+
requestThread.daemon = True
37+
requestThread.start()
38+
39+
self.transfer_data(sock, self.request)
40+
3741
finally:
3842
sock.close()
43+
self.CONNECTION_ACTIVE = False
44+
self.Logger.info("Connection %s -> %s:%s closed" %(self.client_address[0], self.PROXY_HOST, self.PROXY_PORT))
3945

40-
def transferData(self, sock1 : socket, sock2 : socket, max_read_try = 10, receive_message_length = 2048):
41-
read_try = 0
42-
last_try = False
43-
sock1.setblocking(0)
46+
def transfer_data(self, sock1 : socket, sock2 : socket, receive_message_length = 2048):
47+
#setup socket receive timeout
48+
sock1.settimeout(5.0)
4449
while True:
4550
try:
51+
if not self.CONNECTION_ACTIVE or self.server.SHUTDOWN_REQUESTED:
52+
return
4653
msg = sock1.recv(receive_message_length)
4754
if not msg:
48-
return
55+
break
4956
sock2.sendall(msg)
50-
51-
read_try = 0
52-
if last_try and len(msg) > 0:
53-
last_try = False
54-
if len(msg) < (receive_message_length / 2):
55-
if last_try:
56-
return
57-
else:
58-
last_try = True
59-
except error as e:
60-
if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
61-
raise e
62-
if read_try > max_read_try:
63-
return
64-
read_try += 1
65-
time.sleep(0.1)
66-
continue
57+
except timeout:
58+
pass
59+
self.CONNECTION_ACTIVE = False
6760

6861
class ThreadedTCPServer(ThreadingMixIn, TCPServer):
69-
pass
62+
SHUTDOWN_REQUESTED = False
7063

7164
class ProxyServer():
72-
65+
7366
def __init__(self, proxy_host, proxy_port, type=ProxyType.TCP):
7467
if(type != ProxyType.TCP):
7568
raise NotImplementedError("Only TCP Proxy implemented")
@@ -93,5 +86,6 @@ def start(self):
9386
self.logger.info("Starting %s proxy to %s:%s", self.type, self.proxy_host, self.proxy_port)
9487

9588
def stop(self):
89+
self.server.SHUTDOWN_REQUESTED = True
9690
self.server.shutdown()
9791
self.logger.info("Stopping %s proxy to %s:%s", self.type, self.proxy_host, self.proxy_port)

0 commit comments

Comments
 (0)