Ejemplo n.º 1
0
    def __init__(self, protocol_id, frame_type):
        self.protocol_id = protocol_id
        self.frame_type = frame_type
        self.id = "%X" % id(self)
        self._tracing = set()
        self.tracing(*os.environ.get("AMQP_TRACE", "").split())
        self.multiline = False
        self.input = Buffer()
        self.output = Buffer(struct.pack(PROTO_HDR_FMT, "AMQP", self.protocol_id, 1, 0, 0))

        self.state = self.__proto_header
Ejemplo n.º 2
0
    def __init__(self, channel):
        self.channel = channel

        self.new_connection = self.raise_channel_not_ready
        self.close_connection = self.raise_channel_not_ready
        self.register_connection = self.raise_channel_not_ready

        self.overt_connection = None

        self._covert_buffers = {}
        self._buffer = Buffer()
        self.pending_connections = {}
        self.connections = {}

        self.on_channel_ready = Deferred()
Ejemplo n.º 3
0
class OvertGateway(protocol.ClientFactory):
    protocol = OvertConnection

    def __init__(self, channel):
        self.channel = channel

        self.new_connection = self.raise_channel_not_ready
        self.close_connection = self.raise_channel_not_ready
        self.register_connection = self.raise_channel_not_ready

        self.overt_connection = None

        self._covert_buffers = {}
        self._buffer = Buffer()
        self.pending_connections = {}
        self.connections = {}

        self.on_channel_ready = Deferred()

    def start_channel(self):
        reactor.connectTCP(self.channel.host, self.channel.port, self)

    def channel_connected(self, channel):
        self.overt_connection = channel

        log.info("Initializing overt channel...")
        d = self.overt_connection.establish_tls()
        d.addCallback(self.init_relay)

    def channel_ready(self, *args):
        log.info("Channel Ready")
        self.new_connection = self._new_connection
        self.register_connection = self._register_connection
        self.close_connection = self._close_connection

        self.on_channel_ready.callback(None)

    def connection_established(self, conn_uuid, conn_id):
        d = self.pending_connections[conn_uuid]
        d.callback(conn_id)
        del self.pending_connections[conn_uuid]

    def connection_data_received(self, connid, data):
        self.connections[connid].data_received(data)

    def connection_closed(self, connid):
        self.connections[connid].remote_closed()
        # TODO:
        # del self.connections[connid]

    def init_relay(self, *args):
        log.info("Initializing relay...")

        # if not self.channel.support_upstream:
        #     log.info("Non need, channel doesn't support upstream")
        #     self.on_channel_ready.callback(None)
        #     return

        data = self.overt_connection.channel_uuid
        self.send_covert_command(CommandFactory.initialize_relay(data),
                                 wait_for_overt=False)

    def _new_connection(self, addr, port, conn_uuid):
        command = CommandFactory.new_connection(addr, port, conn_uuid)
        self.send_covert_command(command)
        d = Deferred()
        self.pending_connections[conn_uuid] = d
        return d

    def _close_connection(self, conn_id):
        command = CommandFactory.close_connection(conn_id)
        self.send_covert_command(command)

    def _register_connection(self, connid, connection):
        self.connections[connid] = connection

    def send_overt_request(self,
                           request,
                           use_as_covert=False,
                           expected_response_size=None):
        use_as_covert = use_as_covert and self.channel.support_upstream

        covert_size = self.channel.calculate_sendable_covert_data(
            len(request)) if use_as_covert else 0

        if use_as_covert and covert_size and self._buffer.has_data():
            covert_data = self._buffer.read(covert_size)
            wrapped_data = self.channel.wrap_message(covert_data)
            log.debug("Sending {} Covert data on {}, total size: {}".format(
                len(covert_data), self.channel.host, len(wrapped_data)))
            self.overt_connection.send(
                wrapped_data, expected_response_size=expected_response_size)
        else:
            log.debug("Sending {} Overt data on {}".format(
                len(request), self.channel.host))
            self.overt_connection.send(request)

    def send_covert_data(self, data, connid, wait_for_overt=True):
        # log.debug('Sending covert data for connection: {}'.format(connid))
        message = CommandFactory.data(data, connid)
        self.send_covert_command(message, wait_for_overt=wait_for_overt)

    def send_covert_command(self, command, wait_for_overt=True):
        if wait_for_overt:
            self._buffer.write(command)
        else:
            self.overt_connection.send(self.channel.wrap_message(command))

    def raise_channel_not_ready(self, *args, **kwargs):
        raise ChannelNotReadyError("Channel has not been initialized yet")
Ejemplo n.º 4
0
class Dispatcher:
    def __init__(self, protocol_id, frame_type):
        self.protocol_id = protocol_id
        self.frame_type = frame_type
        self.id = "%X" % id(self)
        self._tracing = set()
        self.tracing(*os.environ.get("AMQP_TRACE", "").split())
        self.multiline = False
        self.input = Buffer()
        self.output = Buffer(struct.pack(PROTO_HDR_FMT, "AMQP", self.protocol_id, 1, 0, 0))

        self.state = self.__proto_header

    def tracing(self, *args, **kwargs):
        names = set(args)
        for n in kwargs:
            if kwargs[n]:
                names.add(n)
        if "err" not in kwargs:
            names.add("err")
        self._tracing = names

    def trace(self, categories, format, *args):
        if isinstance(categories, basestring):
            categories = (categories,)
        for category in categories:
            if category in self._tracing:
                prefix = "[%s %s]" % (self.id, category)
                if args:
                    message = format % args
                else:
                    message = format
                print >>sys.stderr, prefix, message.replace(os.linesep, "%s%s " % (os.linesep, prefix))
                break

    def write(self, bytes):
        self.trace("raw", "RECV: %r", bytes)
        self.input.write(bytes)
        self.state = parse(self.state)

    def closed(self):
        self.trace(("raw", "frm"), "CLOSED")

    def error(self, exc):
        pass

    def __proto_header(self):
        if self.input.pending() >= PROTO_HDR_SIZE:
            hdr = self.input.read(PROTO_HDR_SIZE)
            magic, proto, major, minor, revision = struct.unpack(PROTO_HDR_FMT, hdr)
            if (magic, proto, major, minor, revision) == ("AMQP", self.protocol_id, 1, 0, 0):
                return self.__framing
            else:
                raise ValueError("bad protocol header")

    def __framing(self):
        while True:
            f, n = decode(self.input.peek())
            if f:
                self.input.read(n)
                state = self.process_frame(f)
                if state is not None:
                    return state
            else:
                break

    def process_frame(self, f):
        body, remainder = self.type_decoder.decode(f.payload)
        body.payload = remainder
        self.trace("frm", "RECV[%s]: %s", f.channel, body.format(self.multiline))
        return getattr(self, "do_%s" % body.NAME, self.unhandled)(f.channel, body)

    def post_frame(self, channel, body):
        self.trace("frm", "SENT[%s]: %s", channel, body.format(self.multiline))
        encoded = self.type_encoder.encode(body)
        if body.payload:
            encoded += body.payload
        f = Frame(self.frame_type, channel, None, encoded)
        self.output.write(encode(f))

    def read(self, n=None):
        self.tick()
        result = self.output.read(n)
        self.trace("raw", "SENT: %r", result)
        return result

    def peek(self, n=None):
        return self.output.peek(n)

    def pending(self):
        self.tick()
        return self.output.pending()