示例#1
0
 def connection_lost(self, exc):
     self.log.warning("Session {:08x} list to {}:{}".format(
         self.session_id, *self.peername))
     self.client.transport.write(
         compose(Command.dead, self.session_id, None))
     self.client.del_session(self.session_id)
     self.transport.close()
示例#2
0
 def tcp_open(conn):
     if conn.exception() is not None:
         with suppress(KeyError):
             del self.buffers[sid]
         self.del_session(sid)
         self.transport.write(
             compose(Command.dead, sid, None))
示例#3
0
 def successful(listener: ListenerTCP):
     self.listener = listener
     msg = data[4:]
     self.log.info("Created TCP Listener on port {}".format(port))
     self.log.info("Client INIT: {}".format(msg.decode()))
     self.transport.write(
         compose(Command.init,
                 0,
                 struct.pack(">L", mode) + b"Successfully created a listener.")
     )
示例#4
0
 def heartbeat(self):
     try:
         self.log.info("Heartbeat")
         self.transport.write(compose(Command.beat, 0, None))
     except Exception as e:
         print(e)
         self.log.critical(e)
         self.transport.close()
     else:
         yield from asyncio.sleep(30)
         asyncio.ensure_future(self.heartbeat(), loop=self.loop)
示例#5
0
 def connection_made(self, transport):
     """
     Established a connection to the Oblique server.
     :param transport:
     :return:
     """
     self.transport = transport
     asyncio.ensure_future(self.heartbeat(), loop=self.loop)
     info = "Forwarding to {}:{}".format(self.host, self.port)
     self.transport.write(
         compose(Command.init, 0,
                 struct.pack(">L", self.mode) + info.encode()))
示例#6
0
 def data_received(self, data: bytes) -> None:
     """
     Data received from a listener. Forward it out the server's connection to the client
     along with the session ID
     :param data: data sent by the endpoint protocol
     :return: None
     """
     self.log.debug("Session {:08x} received {} bytes".format(
         self.session_id, len(data)))
     pkt = compose(Command.data, self.session_id, data)
     self.log.info("Sendng to {}:{}".format(
         *self.server.transport.get_extra_info("peername")))
     self.server.transport.write(pkt)
示例#7
0
    def connection_made(self, transport: asyncio.Transport) -> None:
        """
        A TCP connection was received from an endpoint

        :param transport: endpoint transport provided by asyncio
        :return: None
        """
        self.transport = transport
        self.peername = transport.get_extra_info("peername")
        self.server.transport.write(
            compose(Command.open, self.session_id, None))
        self.log.info("Connection Open: Session {:08x}: {}:{}".format(
            self.session_id, *self.peername))
示例#8
0
    def connection_lost(self, exc: Exception) -> None:
        """
        Connection from the endpoint lost. Inform the client and delete the session ID

        :param exc: exception provided by asyncio
        :return: None
        """
        self.log.warning("Session {:08x} disconnected from {}:{}".format(
            self.session_id, *self.peername))
        self.server.del_session(self.session_id)
        self.server.transport.write(
            compose(Command.dead, self.session_id, None))
        self.transport.close()
示例#9
0
    def connection_made(self, transport: asyncio.Transport) -> None:
        """
        Connection made from the repeater to the destination host/port

        :param transport: transport provided by asyncio
        :return:
        """
        self.transport = transport
        self.peername = transport.get_extra_info("peername")
        self.log.info("Session {:08x} made to {}:{}".format(
            self.session_id, *self.peername))
        self.client.add_session(self.session_id, self)
        self.client.transport.write(
            compose(Command.open, self.session_id, None))
示例#10
0
    def try_send(self,
                 session_id: int,
                 data: bytes = None,
                 retries: int = 3,
                 delay: float = 0.25):
        """
        Attempt to send data through a repeater. If no session exists, connection may not have fully opened.
        Retry (3 times by default).

        :param session_id: the repeater session ID
        :param data: data
        :param retries: number of retries to attempt
        :param delay: delay, in milliseconds, between attempts
        :return:
        """

        if retries == 0:
            self.log.info(
                "Max Retries. Session {:08x} unavailable.".format(session_id))
            del self.buffers[session_id]
            self.del_session(session_id)
            self.transport.write(compose(Command.dead, session_id, None))
            return

        if data is not None:
            self.buffers[session_id].append(data)

        repeater = self.get_session(session_id)
        if repeater is None:
            self.log.info("Retrying Session {:08x}...".format(session_id))
            self.loop.call_later(delay, self.try_send, session_id, None,
                                 retries - 1)
            return

        for buf in self.buffers[session_id]:
            try:
                repeater.send(buf)
            except Exception as e:
                self.log.error(e)

        self.buffers[session_id].clear()
示例#11
0
    def data_received(self, data: bytes) -> None:
        """
        Data received from the client
        :param data: data supplied by asyncio
        :return: None
        """
        self.log.debug("{} bytes received".format(len(data)))
        try:
            for (cmd, sid, data) in parse(data):
                if cmd == Command.dead:
                    self.log.warning("Session {:08x} dead.".format(sid))
                    sess = self.get_session(sid)
                    if sess:
                        sess.close()
                        self.del_session(sid)
                    return

                if cmd == Command.init:
                    self.log.debug("INIT received from Client {}:{}".format(*self.peername))
                    if sid != 0:
                        self.transport.write(compose(Command.invalid, 0, None))
                        self.transport.close()
                        return

                    mode = struct.unpack(">L", data[:4])[0]
                    if mode == Mode.tcp:
                        done = False
                        while not done:
                            port = random.randint(1025, 65535)
                            try:
                                def successful(listener: ListenerTCP):
                                    self.listener = listener
                                    msg = data[4:]
                                    self.log.info("Created TCP Listener on port {}".format(port))
                                    self.log.info("Client INIT: {}".format(msg.decode()))
                                    self.transport.write(
                                        compose(Command.init,
                                                0,
                                                struct.pack(">L", mode) + b"Successfully created a listener.")
                                    )

                                fut = asyncio.ensure_future(
                                    self.loop.create_server(partial(ListenerTCP, self), host="", port=port)
                                )

                                fut.add_done_callback(successful)
                            except OSError:
                                pass
                            else:
                                done = True

                if cmd == Command.data:
                    self.log.info("Received {} bytes on session {:08x}".format(len(data), sid))
                    if sid not in self.sessions:
                        self.transport.write(compose(Command.invalid, sid, None))
                        return
                    session = self.get_session(sid)
                    if session:
                        print("Server ID", id(self.sessions))
                        session.send(data)

        except ValueError as e:
            self.log.critical("Error: {}".format(e))
            self.transport.write(compose(Command.invalid, 0, None))
            self.transport.close()
            return
示例#12
0
 def data_received(self, data):
     self.log.debug("Session {:08x} received {} bytes".format(
         self.session_id, len(data)))
     pkt = compose(Command.data, self.session_id, data)
     self.client.transport.write(pkt)