Example #1
0
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 )
Example #2
0
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 )