- Timestamp:
- 05/13/12 21:17:45 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
etherws/trunk/etherws.py
r137 r138 44 44 import sys 45 45 import base64 46 import select47 46 import argparse 48 47 import threading … … 56 55 57 56 58 class TapListener(threading.Thread): 59 daemon = True 60 57 class TapHandler(object): 61 58 def __init__(self, dev, debug=False): 62 super(TapListener, self).__init__()63 64 59 self._debug = debug 60 self._clients = [] 65 61 self._tap = pytun.TunTapDevice(dev, pytun.IFF_TAP | pytun.IFF_NO_PI) 66 self._tap_lock = threading.Lock() 67 68 self._clients = [] 69 self._clients_lock = threading.Lock() 70 71 try: 72 self._tap_lock.acquire() 73 self._tap.up() 74 finally: 75 self._tap_lock.release() 62 self._tap.up() 63 self._write_lock = threading.Lock() 64 65 def fileno(self): 66 return self._tap.fileno() 76 67 77 68 def register_client(self, client): 78 try: 79 self._clients_lock.acquire() 80 self._clients.append(client) 81 finally: 82 self._clients_lock.release() 69 self._clients.append(client) 83 70 84 71 def unregister_client(self, client): 85 try: 86 self._clients_lock.acquire() 87 self._clients.remove(client) 88 except ValueError: 89 pass 90 finally: 91 self._clients_lock.release() 72 self._clients.remove(client) 92 73 93 74 def write(self, caller, message): … … 97 78 98 79 try: 99 self._ clients_lock.acquire()80 self._write_lock.acquire() 100 81 101 82 clients = self._clients[:] … … 103 84 if caller is not self: 104 85 clients.remove(caller) 105 try: 106 self._tap_lock.acquire() 107 self._tap.write(message) 108 finally: 109 self._tap_lock.release() 86 self._tap.write(message) 110 87 111 88 message = base64.b64encode(message) … … 115 92 116 93 finally: 117 self._clients_lock.release() 118 119 def run(self): 120 epoll = select.epoll() 121 122 try: 123 self._tap_lock.acquire() 124 epoll.register(self._tap.fileno(), select.EPOLLIN) 125 finally: 126 self._tap_lock.release() 127 128 while True: 129 evts = epoll.poll(1) 130 for fileno, evt in evts: 131 try: 132 self._tap_lock.acquire() 133 data = self._tap.read(self._tap.mtu) 134 finally: 135 self._tap_lock.release() 136 self.write(self, data) 94 self._write_lock.release() 95 96 def __call__(self, fd, events): 97 self.write(self, self._tap.read(self._tap.mtu)) 137 98 138 99 … … 144 105 145 106 def open(self): 146 if self._debug:147 sys.stderr.write('[%s] opened\n' % self.request.remote_ip)148 107 self._tap.register_client(self) 149 108 150 109 def on_message(self, message): 151 if self._debug:152 sys.stderr.write('[%s] received\n' % self.request.remote_ip)153 110 self._tap.write(self, base64.b64decode(message)) 154 111 155 112 def on_close(self): 156 if self._debug:157 sys.stderr.write('[%s] closed\n' % self.request.remote_ip)158 113 self._tap.unregister_client(self) 159 114 … … 185 140 186 141 def server_main(args): 187 tap = TapListener(args.device, debug=args.debug) 188 tap.start() 189 142 tap = TapHandler(args.device, debug=args.debug) 190 143 app = tornado.web.Application([ 191 144 (args.path, EtherWebSocket, {'tap': tap, 'debug': args.debug}), … … 194 147 server.listen(args.port, address=args.address) 195 148 196 tornado.ioloop.IOLoop.instance().start() 149 ioloop = tornado.ioloop.IOLoop.instance() 150 ioloop.add_handler(tap.fileno(), tap, ioloop.READ) 151 ioloop.start() 197 152 198 153 … … 201 156 websocket.enableTrace(True) 202 157 203 tap = Tap Listener(args.device, debug=args.debug)158 tap = TapHandler(args.device, debug=args.debug) 204 159 client = websocket.WebSocketApp(args.uri) 205 160 client.write_message = client.send 206 161 client.on_message = lambda s, m: tap.write(client, base64.b64decode(m)) 207 208 if args.debug:209 client.on_error = lambda s, e: sys.stderr.write(str(e) + '\n')210 client.on_close = lambda s: sys.stderr.write('closed\n')211 212 162 tap.register_client(client) 213 tap.start() 214 215 client.run_forever() 163 164 t = threading.Thread(target=client.run_forever) 165 t.setDaemon(True) 166 t.start() 167 168 ioloop = tornado.ioloop.IOLoop.instance() 169 ioloop.add_handler(tap.fileno(), tap, ioloop.READ) 170 ioloop.start() 216 171 217 172
Note: See TracChangeset
for help on using the changeset viewer.