-
Notifications
You must be signed in to change notification settings - Fork 13
/
proxy.py
96 lines (83 loc) · 3.16 KB
/
proxy.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
#!/usr/bin/env python3
import queue
import os
import socket
import sys
import threading
from select import select
# returns anonymous pipes (readableFromClient, writableToClient)
def proxy(bindAddr, listenPort):
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((bindAddr, listenPort))
sock.listen(5)
socketToPipeR, socketToPipeW = os.pipe()
pipeToSocketR, pipeToSocketW = os.pipe()
stop = threading.Event()
return socketToPipeR, pipeToSocketW, stop, lambda: serve(socketToPipeW, pipeToSocketR, sock, stop)
def serve(socketToPipeW, pipeToSocketR, sock, stop):
socketToPipeW = os.fdopen(socketToPipeW, 'wb')
clientSocket = None
clientSockets = []
addr = None
pipeToSocketBuffer = []
while not stop.is_set():
fds, _, _ = select([sock, pipeToSocketR] + clientSockets, [], [])
for fd in fds:
if fd == sock:
print("new client")
if clientSocket:
print("booting old client")
clientSocket.sendall(b"Superseded. Bye!")
clientSocket.close()
clientSocket, addr = sock.accept()
clientSockets = [clientSocket]
for item in pipeToSocketBuffer:
clientSocket.sendall(item)
pipeToSocketBuffer = []
elif fd == clientSocket:
try:
data = fd.recv(4096)
except ConnectionResetError:
pass
if not data: # disconnect
clientSocket.close()
clientSocket = None
clientSockets = []
print("socket disconnected")
else:
socketToPipeW.write(data) # TODO: partial writes?
socketToPipeW.flush()
elif fd == pipeToSocketR:
data = os.read(pipeToSocketR, 4096)
if not data:
print("EOF from pipe")
break
if clientSocket:
clientSocket.sendall(data) # TODO: partial writes?
else:
pipeToSocketBuffer.append(data)
print("Gracefully shutting down in serve")
if __name__ == "__main__":
def echo(socketToPipeR, pipeToSocketW, stopFlag):
pipeToSocketW = os.fdopen(pipeToSocketW, 'wb')
try:
while not stopFlag.is_set():
data = os.read(socketToPipeR, 4096)
print(b"Got %d, sleeping" % (len(data)))
import time
time.sleep(1)
print(b"Echoing %d" % (len(data)))
pipeToSocketW.write(data)
pipeToSocketW.flush()
except KeyboardInterrupt:
stopFlag.set()
print("Gracefully shutting down in echo")
socketToPipeR, pipeToSocketW, stopFlag, work = proxy('::1', 1234)
echoThr = threading.Thread(target=echo, args=[socketToPipeR, pipeToSocketW, stopFlag])
echoThr.start()
try:
work()
except KeyboardInterrupt:
stopFlag.set()
echoThr.join()