diff options
Diffstat (limited to 'python-client/tcprelay.py')
-rw-r--r-- | python-client/tcprelay.py | 148 |
1 files changed, 0 insertions, 148 deletions
diff --git a/python-client/tcprelay.py b/python-client/tcprelay.py deleted file mode 100644 index add200c..0000000 --- a/python-client/tcprelay.py +++ /dev/null | |||
@@ -1,148 +0,0 @@ | |||
1 | #!/usr/bin/python | ||
2 | # -*- coding: utf-8 -*- | ||
3 | # | ||
4 | # tcprelay.py - TCP connection relay for usbmuxd | ||
5 | # | ||
6 | # Copyright (C) 2009 Hector Martin "marcan" <hector@marcansoft.com> | ||
7 | # | ||
8 | # This program is free software; you can redistribute it and/or modify | ||
9 | # it under the terms of the GNU General Public License as published by | ||
10 | # the Free Software Foundation, either version 2 or version 3. | ||
11 | # | ||
12 | # This program is distributed in the hope that it will be useful, | ||
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | # GNU General Public License for more details. | ||
16 | # | ||
17 | # You should have received a copy of the GNU General Public License | ||
18 | # along with this program; if not, write to the Free Software | ||
19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | |||
21 | import usbmux | ||
22 | import SocketServer | ||
23 | import select | ||
24 | from optparse import OptionParser | ||
25 | import sys | ||
26 | import threading | ||
27 | |||
28 | class SocketRelay(object): | ||
29 | def __init__(self, a, b, maxbuf=65535): | ||
30 | self.a = a | ||
31 | self.b = b | ||
32 | self.atob = "" | ||
33 | self.btoa = "" | ||
34 | self.maxbuf = maxbuf | ||
35 | def handle(self): | ||
36 | while True: | ||
37 | rlist = [] | ||
38 | wlist = [] | ||
39 | xlist = [self.a, self.b] | ||
40 | if self.atob: | ||
41 | wlist.append(self.b) | ||
42 | if self.btoa: | ||
43 | wlist.append(self.a) | ||
44 | if len(self.atob) < self.maxbuf: | ||
45 | rlist.append(self.a) | ||
46 | if len(self.btoa) < self.maxbuf: | ||
47 | rlist.append(self.b) | ||
48 | rlo, wlo, xlo = select.select(rlist, wlist, xlist) | ||
49 | if xlo: | ||
50 | return | ||
51 | if self.a in wlo: | ||
52 | n = self.a.send(self.btoa) | ||
53 | self.btoa = self.btoa[n:] | ||
54 | if self.b in wlo: | ||
55 | n = self.b.send(self.atob) | ||
56 | self.atob = self.atob[n:] | ||
57 | if self.a in rlo: | ||
58 | s = self.a.recv(self.maxbuf - len(self.atob)) | ||
59 | if not s: | ||
60 | return | ||
61 | self.atob += s | ||
62 | if self.b in rlo: | ||
63 | s = self.b.recv(self.maxbuf - len(self.btoa)) | ||
64 | if not s: | ||
65 | return | ||
66 | self.btoa += s | ||
67 | #print "Relay iter: %8d atob, %8d btoa, lists: %r %r %r"%(len(self.atob), len(self.btoa), rlo, wlo, xlo) | ||
68 | |||
69 | class TCPRelay(SocketServer.BaseRequestHandler): | ||
70 | def handle(self): | ||
71 | print "Incoming connection to %d"%self.server.server_address[1] | ||
72 | mux = usbmux.USBMux(options.sockpath) | ||
73 | print "Waiting for devices..." | ||
74 | if not mux.devices: | ||
75 | mux.process(1.0) | ||
76 | if not mux.devices: | ||
77 | print "No device found" | ||
78 | self.request.close() | ||
79 | return | ||
80 | dev = mux.devices[0] | ||
81 | print "Connecting to device %s"%str(dev) | ||
82 | dsock = mux.connect(dev, self.server.rport) | ||
83 | lsock = self.request | ||
84 | print "Connection established, relaying data" | ||
85 | try: | ||
86 | fwd = SocketRelay(dsock, lsock, self.server.bufsize * 1024) | ||
87 | fwd.handle() | ||
88 | finally: | ||
89 | dsock.close() | ||
90 | lsock.close() | ||
91 | print "Connection closed" | ||
92 | |||
93 | class TCPServer(SocketServer.TCPServer): | ||
94 | allow_reuse_address = True | ||
95 | |||
96 | class ThreadedTCPServer(SocketServer.ThreadingMixIn, TCPServer): | ||
97 | pass | ||
98 | |||
99 | HOST = "localhost" | ||
100 | |||
101 | parser = OptionParser(usage="usage: %prog [OPTIONS] RemotePort[:LocalPort] [RemotePort[:LocalPort]]...") | ||
102 | parser.add_option("-t", "--threaded", dest='threaded', action='store_true', default=False, help="use threading to handle multiple connections at once") | ||
103 | parser.add_option("-b", "--bufsize", dest='bufsize', action='store', metavar='KILOBYTES', type='int', default=128, help="specify buffer size for socket forwarding") | ||
104 | parser.add_option("-s", "--socket", dest='sockpath', action='store', metavar='PATH', type='str', default=None, help="specify the path of the usbmuxd socket") | ||
105 | |||
106 | options, args = parser.parse_args() | ||
107 | |||
108 | serverclass = TCPServer | ||
109 | if options.threaded: | ||
110 | serverclass = ThreadedTCPServer | ||
111 | |||
112 | if len(args) == 0: | ||
113 | parser.print_help() | ||
114 | sys.exit(1) | ||
115 | |||
116 | ports = [] | ||
117 | |||
118 | for arg in args: | ||
119 | try: | ||
120 | if ':' in arg: | ||
121 | rport, lport = arg.split(":") | ||
122 | rport = int(rport) | ||
123 | lport = int(lport) | ||
124 | ports.append((rport, lport)) | ||
125 | else: | ||
126 | ports.append((int(arg), int(arg))) | ||
127 | except: | ||
128 | parser.print_help() | ||
129 | sys.exit(1) | ||
130 | |||
131 | servers=[] | ||
132 | |||
133 | for rport, lport in ports: | ||
134 | print "Forwarding local port %d to remote port %d"%(lport, rport) | ||
135 | server = serverclass((HOST, lport), TCPRelay) | ||
136 | server.rport = rport | ||
137 | server.bufsize = options.bufsize | ||
138 | servers.append(server) | ||
139 | |||
140 | alive = True | ||
141 | |||
142 | while alive: | ||
143 | try: | ||
144 | rl, wl, xl = select.select(servers, [], []) | ||
145 | for server in rl: | ||
146 | server.handle_request() | ||
147 | except: | ||
148 | alive = False | ||