Changeset 134


Ignore:
Timestamp:
05/13/12 04:54:45 (12 years ago)
Author:
atzm
Message:
  • fixed a bug, daemonize timing
File:
1 edited

Legend:

Unmodified
Added
Removed
  • etherws/trunk/etherws.py

    r133 r134  
    5656 
    5757 
     58class TapListener(threading.Thread): 
     59    daemon = True 
     60 
     61    def __init__(self, dev, debug=False): 
     62        super(TapListener, self).__init__() 
     63 
     64        self._debug = debug 
     65        self._tap = pytun.TunTapDevice(dev, pytun.IFF_TAP | pytun.IFF_NO_PI) 
     66        self._tap.up() 
     67 
     68        self._clients = [] 
     69        self._clients_lock = threading.Lock() 
     70 
     71    def register_client(self, client): 
     72        try: 
     73            self._clients_lock.acquire() 
     74            self._clients.append(client) 
     75        finally: 
     76            self._clients_lock.release() 
     77 
     78    def unregister_client(self, client): 
     79        try: 
     80            self._clients_lock.acquire() 
     81            self._clients.remove(client) 
     82        except ValueError: 
     83            pass 
     84        finally: 
     85            self._clients_lock.release() 
     86 
     87    def write(self, caller, message): 
     88        if self._debug: 
     89            sys.stderr.write('%s: %s\n' % (caller.__class__.__name__, 
     90                                           message.encode('hex'))) 
     91 
     92        try: 
     93            self._clients_lock.acquire() 
     94            clients = self._clients[:] 
     95        finally: 
     96            self._clients_lock.release() 
     97 
     98        if caller is not self: 
     99            clients.remove(caller) 
     100            self._tap.write(message) 
     101 
     102        message = base64.b64encode(message) 
     103 
     104        for c in clients: 
     105            c.write_message(message) 
     106 
     107    def run(self): 
     108        epoll = select.epoll() 
     109        epoll.register(self._tap.fileno(), select.EPOLLIN) 
     110 
     111        while True: 
     112            evts = epoll.poll(1) 
     113            for fileno, evt in evts: 
     114                self.write(self, self._tap.read(self._tap.mtu)) 
     115 
     116 
     117class EtherWebSocket(tornado.websocket.WebSocketHandler): 
     118    def __init__(self, app, req, tap, debug=False): 
     119        super(EtherWebSocket, self).__init__(app, req) 
     120        self._tap = tap 
     121        self._debug = debug 
     122 
     123    def open(self): 
     124        if self._debug: 
     125            sys.stderr.write('[%s] opened\n' % self.request.remote_ip) 
     126        self._tap.register_client(self) 
     127 
     128    def on_message(self, message): 
     129        if self._debug: 
     130            sys.stderr.write('[%s] received\n' % self.request.remote_ip) 
     131        self._tap.write(self, base64.b64decode(message)) 
     132 
     133    def on_close(self): 
     134        if self._debug: 
     135            sys.stderr.write('[%s] closed\n' % self.request.remote_ip) 
     136        self._tap.unregister_client(self) 
     137 
     138 
    58139def daemonize(nochdir=False, noclose=False): 
    59140    if os.fork() > 0: 
     
    81162 
    82163 
    83 class TapListener(threading.Thread): 
    84     daemon = True 
    85  
    86     def __init__(self, dev, debug=False): 
    87         super(TapListener, self).__init__() 
    88  
    89         self._debug = debug 
    90         self._tap = pytun.TunTapDevice(dev, pytun.IFF_TAP | pytun.IFF_NO_PI) 
    91         self._tap.up() 
    92  
    93         self._clients = [] 
    94         self._clients_lock = threading.Lock() 
    95  
    96     def register_client(self, client): 
    97         try: 
    98             self._clients_lock.acquire() 
    99             self._clients.append(client) 
    100         finally: 
    101             self._clients_lock.release() 
    102  
    103     def unregister_client(self, client): 
    104         try: 
    105             self._clients_lock.acquire() 
    106             self._clients.remove(client) 
    107         except ValueError: 
    108             pass 
    109         finally: 
    110             self._clients_lock.release() 
    111  
    112     def write(self, caller, message): 
    113         if self._debug: 
    114             sys.stderr.write('%s: %s\n' % (caller.__class__.__name__, 
    115                                            message.encode('hex'))) 
    116  
    117         try: 
    118             self._clients_lock.acquire() 
    119             clients = self._clients[:] 
    120         finally: 
    121             self._clients_lock.release() 
    122  
    123         if caller is not self: 
    124             clients.remove(caller) 
    125             self._tap.write(message) 
    126  
    127         message = base64.b64encode(message) 
    128  
    129         for c in clients: 
    130             c.write_message(message) 
    131  
    132     def run(self): 
    133         epoll = select.epoll() 
    134         epoll.register(self._tap.fileno(), select.EPOLLIN) 
    135  
    136         while True: 
    137             evts = epoll.poll(1) 
    138             for fileno, evt in evts: 
    139                 self.write(self, self._tap.read(self._tap.mtu)) 
    140  
    141  
    142 class EtherWebSocket(tornado.websocket.WebSocketHandler): 
    143     def __init__(self, app, req, tap, debug=False): 
    144         super(EtherWebSocket, self).__init__(app, req) 
    145         self._tap = tap 
    146         self._debug = debug 
    147  
    148     def open(self): 
    149         if self._debug: 
    150             sys.stderr.write('[%s] opened\n' % self.request.remote_ip) 
    151         self._tap.register_client(self) 
    152  
    153     def on_message(self, message): 
    154         if self._debug: 
    155             sys.stderr.write('[%s] received\n' % self.request.remote_ip) 
    156         self._tap.write(self, base64.b64decode(message)) 
    157  
    158     def on_close(self): 
    159         if self._debug: 
    160             sys.stderr.write('[%s] closed\n' % self.request.remote_ip) 
    161         self._tap.unregister_client(self) 
    162  
    163  
    164164def server_main(args): 
    165165    tap = TapListener(args.device, debug=args.debug) 
     
    172172    server.listen(args.port, address=args.address) 
    173173 
    174     if not args.foreground: 
    175         daemonize() 
    176  
    177174    tornado.ioloop.IOLoop.instance().start() 
    178175 
     
    193190    tap.register_client(client) 
    194191    tap.start() 
    195  
    196     if not args.foreground: 
    197         daemonize() 
    198192 
    199193    client.run_forever() 
     
    218212    args = parser.parse_args() 
    219213 
     214    if not args.foreground: 
     215        daemonize() 
     216 
    220217    if args.subcommand == 'server': 
    221218        server_main(args) 
Note: See TracChangeset for help on using the changeset viewer.