Esempio n. 1
0
class SPMPClientProtocol(Protocol):
    def __init__(self, security=None):
        self._security = security
        self._responses = {}
        self._responseCondition = SimpleCondition()
        self._deserializer = SPMPPacket.Deserializer()

    def connection_made(self, transport):
        self.transport = transport

    def connection_lost(self, reason=None):
        self.transport = None

    def data_received(self, data):
        self._deserializer.update(data)
        for packet in self._deserializer.nextPackets():
            result, error = packet.result, packet.error
            if error == packet.UNSET:
                error = None
            self._responses[packet.requestId] = (result, error)
            self._responseCondition.notify()

    async def query(self, cmd, *args):
        request = SPMPPacket()
        request.generateRequestId()
        request.request = cmd
        request.args = list(args)
        request.result = ""
        self._security and self._security.addSecurityParameters(self, request)

        self.transport.write(request.__serialize__())

        cond = await self._responseCondition.awaitCondition(
            lambda: request.requestId in self._responses)
        return self._responses[request.requestId]
Esempio n. 2
0
    def __init__(self, security=None, framed=False):
        self._security = security
        self._responses = {}
        self._responseCondition = SimpleCondition()

        self._deserializer = SPMPPacket.Deserializer()
        self._framed = framed
Esempio n. 3
0
    def __init__(self, callbackAddress, callbackPort, protocolStack):
        self._callbackAddress = callbackAddress
        self._callbackPort = callbackPort
        self._dataProtocols = {}
        self._completionData = {}
        self._controlProtocols = {}
        self._connectionBackptr = {}
        self._protocolStack = protocolStack

        # asyncio condition
        self._conditionConnections = SimpleCondition()
Esempio n. 4
0
 def __init__(self, callbackAddress, callbackPort, protocolStack):
     self._callbackAddress = callbackAddress
     self._callbackPort = callbackPort
     self._dataProtocols = {}     # Holds all of the data transfer protocols (callback protocols)
     self._connectionData = {}    # Holds connection data such as connection ID, etc
     self._connectionSpawn = {}   # Maps connection Ids to data protocols
     self._connectionBackptr = {} # Reverse of connectionSpawn
     self._protocolStack = protocolStack
     
     # asyncio condition
     self._conditionConnections = SimpleCondition()
Esempio n. 5
0
 def watch(self, protocol):
     """
     For a given protocol, setup a condition to
     wait for connection made
     """
     ProtocolObservation.Listen(protocol, self)
     self.protocols[protocol] = SimpleCondition()
Esempio n. 6
0
 def __init__(self, vnicService=None, protocolStack=None, callbackAddress="127.0.0.1", callbackPort=0):
     self._stack = protocolStack
     self._vnicService = vnicService
     self._callbackService = CallbackService(callbackAddress, callbackPort, protocolStack)
     self._ready = False
     
     if not vnicService:
         self._vnicService = StandardVnicService()
         
     self._protocolReadyCondition = SimpleCondition()
Esempio n. 7
0
 def __init__(self, vnicService=None, protocolStack=None, callbackAddress="127.0.0.1", callbackPort=0):
     if isinstance(protocolStack, tuple):
         if len(protocolStack) != 2: 
             raise Exception("Protocol Stack is a factory or a factory pair")
         self._stack = protocolStack
     else:
         self._stack = protocolStack, protocolStack
     self._vnicService = vnicService
     self._callbackService = CallbackService(callbackAddress, callbackPort, self._stack)
     self._ready = False
     self._trace = traceback.extract_stack()
     self._module = self._trace[-2].filename
     
     if not vnicService:
         self._vnicService = StandardVnicService()
         
     self._protocolReadyCondition = SimpleCondition()
Esempio n. 8
0
class CallbackService:
    def __init__(self, callbackAddress, callbackPort, protocolStack):
        self._callbackAddress = callbackAddress
        self._callbackPort = callbackPort
        self._dataProtocols = {}
        self._completionData = {}
        self._controlProtocols = {}
        self._connectionBackptr = {}
        self._protocolStack = protocolStack

        # asyncio condition
        self._conditionConnections = SimpleCondition()

    def location(self):
        return (self._callbackAddress, self._callbackPort)

    def newDataConnection(self, spawnTcpPort, dataProtocol):
        self._dataProtocols[spawnTcpPort] = dataProtocol

        if spawnTcpPort in self._completionData and spawnTcpPort in self._dataProtocols:
            controlProtocol = self._completionData[spawnTcpPort][0]
            if isinstance(controlProtocol, VNICListenProtocol):
                stackFactory = self._protocolStack[1]
            else:
                stackFactory = self._protocolStack[0]
            self.buildStack(stackFactory, spawnTcpPort)

    def dataConnectionClosed(self, dataProtocol, spawnTcpPort):
        if spawnTcpPort in self._dataProtocols:
            del self._dataProtocols[spawnTcpPort]
        if dataProtocol in self._connectionBackptr:
            controlProtocol = self._connectionBackptr[dataProtocol]
            self._controlProtocols[controlProtocol].remove(dataProtocol)
            del self._connectionBackptr[dataProtocol]

    def completeCallback(self, controlProtocol, applicationProtocol,
                         spawnTcpPort, source, sourcePort, destination,
                         destinationPort):
        self._completionData[spawnTcpPort] = (controlProtocol,
                                              applicationProtocol, source,
                                              sourcePort, destination,
                                              destinationPort)

        if spawnTcpPort in self._completionData and spawnTcpPort in self._dataProtocols:
            if isinstance(controlProtocol, VNICListenProtocol):
                stackFactory = self._protocolStack[1]
            else:
                stackFactory = self._protocolStack[0]
            self.buildStack(stackFactory, spawnTcpPort)

    def buildStack(self, stackFactory, spawnTcpPort):
        controlProtocol, applicationProtocol, source, sourcePort, destination, destinationPort = self._completionData[
            spawnTcpPort]

        connectionMadeObserver.watch(applicationProtocol)

        stackProtocol = stackFactory and stackFactory() or None
        self._dataProtocols[spawnTcpPort].setPlaygroundConnectionInfo(
            stackProtocol, applicationProtocol, source, sourcePort,
            destination, destinationPort)

        self._controlProtocols[controlProtocol] = self._controlProtocols.get(
            controlProtocol, []) + [self._dataProtocols[spawnTcpPort]]
        self._connectionBackptr[
            self._dataProtocols[spawnTcpPort]] = controlProtocol
        del self._dataProtocols[spawnTcpPort]
        del self._completionData[spawnTcpPort]

        # notify that a new connection is received
        self._conditionConnections.notify()

    async def waitForConnections(self, controlProtocol, n=1):
        if not controlProtocol in self._controlProtocols:
            self._controlProtocols[controlProtocol] = []

        # now wait for the list to be big enough
        predicate = lambda: len(self._controlProtocols[controlProtocol]) >= n
        result = await self._conditionConnections.awaitCondition(predicate)
        return self._controlProtocols[controlProtocol]

    def getConnections(self, controlProtocol):
        if not controlProtocol in self._controlProtocols:
            self._controlProtocols[controlProtocol] = []
        return self._controlProtocols[controlProtocol]
Esempio n. 9
0
class CallbackService:
    def __init__(self, callbackAddress, callbackPort, protocolStack):
        self._callbackAddress = callbackAddress
        self._callbackPort = callbackPort
        self._dataProtocols = {
        }  # Holds all of the data transfer protocols (callback protocols)
        self._connectionData = {
        }  # Holds connection data such as connection ID, etc
        self._connectionSpawn = {}  # Maps connection Ids to data protocols
        self._connectionBackptr = {}  # Reverse of connectionSpawn
        self._protocolStack = protocolStack

        # asyncio condition
        self._conditionConnections = SimpleCondition()

    def location(self):
        return (self._callbackAddress, self._callbackPort)

    def tryToBuildStack(self, spawnTcpPort):
        if spawnTcpPort in self._connectionData and spawnTcpPort in self._dataProtocols:
            connectionType = self._connectionData[spawnTcpPort][1]
            if connectionType == "listen":
                stackFactory = self._protocolStack[1]
            else:
                stackFactory = self._protocolStack[0]
            self.buildStack(stackFactory, spawnTcpPort)

    def newDataConnection(self, spawnTcpPort, dataProtocol):
        logger.debug(
            "Callback service new data connection on tcp port {}".format(
                spawnTcpPort))
        self._dataProtocols[spawnTcpPort] = dataProtocol
        self.tryToBuildStack(spawnTcpPort)

    def completeCallback(self, connectionId, connectionType,
                         applicationProtocol, spawnTcpPort, source, sourcePort,
                         destination, destinationPort):
        logger.debug(
            "Callback service setting up callback for connectionID {}, spawn port {}"
            .format(connectionId, spawnTcpPort))
        self._connectionData[spawnTcpPort] = (connectionId, connectionType,
                                              applicationProtocol, source,
                                              sourcePort, destination,
                                              destinationPort)
        self.tryToBuildStack(spawnTcpPort)

    def buildStack(self, stackFactory, spawnTcpPort):
        connectionId, connectionType, applicationProtocol, source, sourcePort, destination, destinationPort = self._connectionData[
            spawnTcpPort]

        connectionMadeObserver.watch(applicationProtocol)

        stackProtocol = stackFactory and stackFactory() or None
        stackString = "[" + str(stackProtocol)
        s_p = stackProtocol and stackProtocol.higherProtocol()
        while s_p:
            stackString += "," + str(s_p)
            s_p = s_p.higherProtocol()
        stackString += "," + str(applicationProtocol) + "]"
        logger.debug(
            "Connection made on spawned port {} for stack {} {}:{} -> {}:{}".
            format(spawnTcpPort, stackString, source, sourcePort, destination,
                   destinationPort))
        self._dataProtocols[spawnTcpPort].setPlaygroundConnectionInfo(
            stackProtocol, applicationProtocol, source, sourcePort,
            destination, destinationPort)

        self._connectionSpawn[connectionId] = self._connectionSpawn.get(
            connectionId, []) + [self._dataProtocols[spawnTcpPort]]
        self._connectionBackptr[
            self._dataProtocols[spawnTcpPort]] = connectionId

        # done with these. Delete the data

        del self._dataProtocols[spawnTcpPort]
        del self._connectionData[spawnTcpPort]

        # notify that a new connection is received
        self._conditionConnections.notify()

    def dataConnectionClosed(self, dataProtocol, spawnTcpPort):
        logger.debug(
            "Connection closed for spawned port {}".format(spawnTcpPort))

        #        logger.debug("Connection closed on spawned port {} for source and destination {}:{} -> {}:{}".format(spawnTcpPort, source, sourcePort, destination, destinationPort))
        if spawnTcpPort in self._dataProtocols:
            del self._dataProtocols[spawnTcpPort]
        if spawnTcpPort in self._connectionData:
            del self._connectionData[spawnTcpPort]
        if dataProtocol in self._connectionBackptr:
            connectionId = self._connectionBackptr[dataProtocol]
            del self._connectionBackptr[dataProtocol]
            self._connectionSpawn[connectionId].remove(dataProtocol)

    async def waitForConnections(self, connectionId, n=1):
        # primarily used in awaiting the complete connection from an outbound connection
        if not connectionId in self._connectionSpawn:
            self._connectionSpawn[connectionId] = []

        # now wait for the list to be big enough
        predicate = lambda: len(self._connectionSpawn[connectionId]) >= n
        await self._conditionConnections.awaitCondition(predicate)
        return self._connectionSpawn[connectionId]

    def getConnections(self, connectionId):
        return self._connectionSpawn.get(connectionId, [])
Esempio n. 10
0
class CallbackService:
    def __init__(self, callbackAddress, callbackPort, protocolStack):
        self._callbackAddress = callbackAddress
        self._callbackPort = callbackPort
        self._dataProtocols = {}
        self._completionData = {}
        self._controlProtocols = {}
        self._connectionBackptr = {}
        self._protocolStack = protocolStack
        
        # asyncio condition
        self._conditionConnections = SimpleCondition()
        
    def location(self):
        return (self._callbackAddress, self._callbackPort)
        
    def newDataConnection(self, spawnTcpPort, dataProtocol):
        self._dataProtocols[spawnTcpPort] = dataProtocol
        
        if spawnTcpPort in self._completionData and spawnTcpPort in self._dataProtocols:
            controlProtocol = self._completionData[spawnTcpPort][0]
            if isinstance(controlProtocol, VNICListenProtocol):
                stackFactory = self._protocolStack[1]
            else:
                stackFactory = self._protocolStack[0]
            self.buildStack(stackFactory, spawnTcpPort)
        
    def dataConnectionClosed(self, dataProtocol, spawnTcpPort):
        logger.debug("Connection closed for spawned port {}".format(spawnTcpPort))

#        logger.debug("Connection closed on spawned port {} for source and destination {}:{} -> {}:{}".format(spawnTcpPort, source, sourcePort, destination, destinationPort))
        if spawnTcpPort in self._dataProtocols:
            del self._dataProtocols[spawnTcpPort]
        if dataProtocol in self._connectionBackptr:
            controlProtocol = self._connectionBackptr[dataProtocol]
            if isinstance(controlProtocol, VNICConnectProtocol):
                controlProtocol.transport.close()
                logger.debug("Closing control protocol {}".format(controlProtocol))
            self._controlProtocols[controlProtocol].remove(dataProtocol)
            del self._connectionBackptr[dataProtocol]
        
    def completeCallback(self, controlProtocol, applicationProtocol, spawnTcpPort, source, sourcePort, destination, destinationPort):
        self._completionData[spawnTcpPort] = (controlProtocol, applicationProtocol, source, sourcePort, destination, destinationPort)
        
        if spawnTcpPort in self._completionData and spawnTcpPort in self._dataProtocols:
            if isinstance(controlProtocol, VNICListenProtocol):
                stackFactory = self._protocolStack[1]
            else:
                stackFactory = self._protocolStack[0]
            self.buildStack(stackFactory, spawnTcpPort)
        
            
    def buildStack(self, stackFactory, spawnTcpPort):
        controlProtocol, applicationProtocol, source, sourcePort, destination, destinationPort = self._completionData[spawnTcpPort]
        
        connectionMadeObserver.watch(applicationProtocol)
        
        stackProtocol = stackFactory and stackFactory() or None
        stackString = "["+str(stackProtocol)
        s_p = stackProtocol and stackProtocol.higherProtocol()
        while s_p:
            stackString += ","+str(s_p)
            s_p = s_p.higherProtocol()
        stackString += "," + str(applicationProtocol) + "]"
        logger.debug("Connection made on spawned port {} for stack {} {}:{} -> {}:{}".format(spawnTcpPort, stackString, source, sourcePort, destination, destinationPort))
        self._dataProtocols[spawnTcpPort].setPlaygroundConnectionInfo(stackProtocol, applicationProtocol, 
                                                                      source, sourcePort, 
                                                                      destination, destinationPort)
        
        self._controlProtocols[controlProtocol] = self._controlProtocols.get(controlProtocol, []) + [self._dataProtocols[spawnTcpPort]]
        self._connectionBackptr[self._dataProtocols[spawnTcpPort]] = controlProtocol
        del self._dataProtocols[spawnTcpPort]
        del self._completionData[spawnTcpPort]

        # notify that a new connection is received
        self._conditionConnections.notify()

    async def waitForConnections(self, controlProtocol, n=1):
        if not controlProtocol in self._controlProtocols:
            self._controlProtocols[controlProtocol] = []
        
        # now wait for the list to be big enough
        predicate = lambda: len(self._controlProtocols[controlProtocol]) >= n
        result = await self._conditionConnections.awaitCondition(predicate)
        return self._controlProtocols[controlProtocol]
        
    def getConnections(self, controlProtocol):
        if not controlProtocol in self._controlProtocols:
            self._controlProtocols[controlProtocol] = []
        return self._controlProtocols[controlProtocol]