class RouterServerHandler( object ) : (INITIAL,REGISTERED,CONNECTING,CLOSED) = range(4) def __init__( self, sock, reactor, routerState ) : self.rpcConn = RPCConnection( sock, reactor ) self.reactor = reactor self.routerState = routerState self.rpcConn.setCloseCallback( self.close ) self.rpcConn.setRequestCallback( self._onRequest ) self.requestTable = {} for msg in 'Ping Register Connect Accept'.split() : self.requestTable[msg] = getattr( self, '_do%s' % msg ) self.routerState.handlers[self] = 1 self.state = self.INITIAL self._lastActiveTime = time() def close( self ) : self.rpcConn.close() del self.routerState.handlers[self] if self.state == self.REGISTERED : del self.routerState.registered[self.routerId] elif self.state == self.CONNECTING : del self.routerState.connecting[self.connectionId] self.state = self.CLOSED def lastActiveTime( self ) : return self._lastActiveTime def sendIncoming( self, connectionId ) : assert self.state == self.REGISTERED self.rpcConn.oneway( connectionId ) def _onRequest( self, payload, ctx ) : self._lastActiveTime = time() try : assert type(payload) is list assert len(payload) >= 1 msg = payload.pop( 0 ) assert type(msg) is str handler = self.requestTable.get( msg ) assert handler is not None except : ctx.response( [-1] ) return handler( payload, ctx ) def _doPing( self, args, ctx ) : try : peerAddr = self.rpcConn.getSock().getpeername() except sock_error : ctx.response( [-1] ) return ctx.response( (0,peerAddr) ) def _doRegister( self, args, ctx ) : try : assert self.state == self.INITIAL assert len(args) == 0 except : ctx.response( (-1,'') ) return while True : routerId = rand_bytes( 20 ) if routerId not in self.routerState.registered : break self.routerId = routerId self.state = self.REGISTERED self.routerState.registered[routerId] = self ctx.response( (0,self.routerId) ) def _doConnect( self, args, ctx ) : try : assert self.state == self.INITIAL assert len(args) == 1 routerId = args[0] assert type(routerId) is str handler = self.routerState.registered.get( routerId ) assert handler is not None except : ctx.response( [-1] ) return while True : connectionId = rand_bytes( 20 ) if connectionId not in self.routerState.connecting : break self.connectionId = connectionId self.connectCtx = ctx self.state = self.CONNECTING self.routerState.connecting[connectionId] = self handler.sendIncoming( connectionId ) def finishConnect( self ) : assert self.state == self.CONNECTING self.connectCtx.response( [0] ) del self.routerState.connecting[self.connectionId] del self.routerState.handlers[self] sock = self.rpcConn.getSock() pendingWrite = self.rpcConn.getPendingWrite() self.rpcConn.shutdown() self.state = self.CLOSED return (sock,pendingWrite) def _doAccept( self, args, ctx ) : try : assert self.state == self.INITIAL assert len(args) == 1 connectionId = args[0] assert type(connectionId) is str handler = self.routerState.connecting.get( connectionId ) assert handler is not None except : ctx.response( [-1] ) return sock1,pendingWrite1 = handler.finishConnect() ctx.response( [0] ) del self.routerState.handlers[self] sock2 = self.rpcConn.getSock() pendingWrite2 = self.rpcConn.getPendingWrite() self.rpcConn.shutdown() self.state = self.CLOSED BridgeInitiator( sock1, pendingWrite1, sock2, pendingWrite2, self.reactor, self.routerState )