Esempio n. 1
0
    def __call__(self):
        if self.server_conn:
            self._initiate_server_conn()

        preamble = self.client_conn.rfile.read(24)
        self.client_conn.h2.initiate_connection()
        self.client_conn.h2.receive_data(preamble)
        self.client_conn.send(self.client_conn.h2.data_to_send())

        while True:
            r = ssl_read_select(self.active_conns, 1)
            for conn in r:
                source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn
                other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn
                is_server = (conn == self.server_conn.connection)

                with source_conn.h2.lock:
                    try:
                        raw_frame = b''.join(
                            http2_read_raw_frame(source_conn.rfile))
                    except:
                        for stream in self.streams.values():
                            stream.zombie = time.time()
                        return

                    events = source_conn.h2.receive_data(raw_frame)
                    source_conn.send(source_conn.h2.data_to_send())

                    for event in events:
                        if not self._handle_event(event, source_conn,
                                                  other_conn, is_server):
                            return

            self._cleanup_streams()
Esempio n. 2
0
    def __call__(self):
        if self.server_conn:
            self._initiate_server_conn()

        preamble = self.client_conn.rfile.read(24)
        self.client_conn.h2.initiate_connection()
        self.client_conn.h2.receive_data(preamble)
        self.client_conn.send(self.client_conn.h2.data_to_send())

        while True:
            r = ssl_read_select(self.active_conns, 1)
            for conn in r:
                source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn
                other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn
                is_server = (conn == self.server_conn.connection)

                with source_conn.h2.lock:
                    try:
                        raw_frame = b''.join(http2_read_raw_frame(source_conn.rfile))
                    except:
                        # read frame failed: connection closed
                        self._kill_all_streams()
                        return

                    incoming_events = source_conn.h2.receive_data(raw_frame)
                    source_conn.send(source_conn.h2.data_to_send())

                    for event in incoming_events:
                        if not self._handle_event(event, source_conn, other_conn, is_server):
                            # connection terminated: GoAway
                            self._kill_all_streams()
                            return

            self._cleanup_streams()
Esempio n. 3
0
    def __call__(self):
        client = self.client_conn.connection
        server = self.server_conn.connection
        conns = [client, server]

        try:
            while not self.channel.should_exit.is_set():
                r = tcp.ssl_read_select(conns, 1)
                for conn in r:
                    source_conn = self.client_conn if conn == client else self.server_conn
                    other_conn = self.server_conn if conn == client else self.client_conn
                    is_server = (conn == self.server_conn.connection)

                    frame = websockets.Frame.from_file(source_conn.rfile)

                    if not self._handle_frame(frame, source_conn, other_conn,
                                              is_server):
                        return
        except (socket.error, netlib.exceptions.TcpException, SSL.Error) as e:
            self.log(
                "WebSockets connection closed unexpectedly by {}: {}".format(
                    "server" if is_server else "client", repr(e)), "info")
        except Exception as e:  # pragma: no cover
            raise exceptions.ProtocolException(
                "Error in WebSockets connection: {}".format(repr(e)))
Esempio n. 4
0
    def __call__(self):
        if self.server_conn:
            self._initiate_server_conn()

        preamble = self.client_conn.rfile.read(24)
        self.client_conn.h2.initiate_connection()
        self.client_conn.h2.receive_data(preamble)
        self.client_conn.send(self.client_conn.h2.data_to_send())

        while True:
            r = ssl_read_select(self.active_conns, 1)
            for conn in r:
                source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn
                other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn
                is_server = (conn == self.server_conn.connection)

                with source_conn.h2.lock:
                    try:
                        raw_frame = b''.join(http2_read_raw_frame(source_conn.rfile))
                    except:
                        for stream in self.streams.values():
                            stream.zombie = time.time()
                        return

                    events = source_conn.h2.receive_data(raw_frame)
                    source_conn.send(source_conn.h2.data_to_send())

                    for event in events:
                        if not self._handle_event(event, source_conn, other_conn, is_server):
                            return

            self._cleanup_streams()
Esempio n. 5
0
    def __call__(self):
        self.connect()

        buf = memoryview(bytearray(self.chunk_size))

        client = self.client_conn.connection
        server = self.server_conn.connection
        conns = [client, server]

        try:
            while True:
                r = ssl_read_select(conns, 10)
                for conn in r:
                    dst = server if conn == client else client

                    size = conn.recv_into(buf, self.chunk_size)
                    if not size:
                        conns.remove(conn)
                        # Shutdown connection to the other peer
                        if isinstance(conn, SSL.Connection):
                            # We can't half-close a connection, so we just close everything here.
                            # Sockets will be cleaned up on a higher level.
                            return
                        else:
                            dst.shutdown(socket.SHUT_WR)

                        if len(conns) == 0:
                            return
                        continue

                    tcp_message = TcpMessage(
                        self.client_conn, self.server_conn,
                        self.client_conn if dst == server else self.server_conn,
                        self.server_conn if dst == server else self.client_conn,
                        buf[:size].tobytes())
                    self.channel.ask("tcp_message", tcp_message)
                    dst.sendall(tcp_message.message)

                    if self.logging:
                        # log messages are prepended with the client address,
                        # hence the "weird" direction string.
                        if dst == server:
                            direction = "-> tcp -> {}".format(repr(self.server_conn.address))
                        else:
                            direction = "<- tcp <- {}".format(repr(self.server_conn.address))
                        data = clean_bin(tcp_message.message)
                        self.log(
                            "{}\r\n{}".format(direction, data),
                            "info"
                        )

        except (socket.error, TcpException, SSL.Error) as e:
            six.reraise(
                ProtocolException,
                ProtocolException("TCP connection closed unexpectedly: {}".format(repr(e))),
                sys.exc_info()[2]
            )
Esempio n. 6
0
    def __call__(self):
        self.connect()

        buf = memoryview(bytearray(self.chunk_size))

        client = self.client_conn.connection
        server = self.server_conn.connection
        conns = [client, server]

        try:
            while not self.channel.should_exit.is_set():
                r = ssl_read_select(conns, 10)
                for conn in r:
                    dst = server if conn == client else client

                    size = conn.recv_into(buf, self.chunk_size)
                    if not size:
                        conns.remove(conn)
                        # Shutdown connection to the other peer
                        if isinstance(conn, SSL.Connection):
                            # We can't half-close a connection, so we just close everything here.
                            # Sockets will be cleaned up on a higher level.
                            return
                        else:
                            dst.shutdown(socket.SHUT_WR)

                        if len(conns) == 0:
                            return
                        continue

                    tcp_message = TcpMessage(
                        self.client_conn, self.server_conn, self.client_conn if
                        dst == server else self.server_conn, self.server_conn
                        if dst == server else self.client_conn,
                        buf[:size].tobytes())
                    self.channel.ask("tcp_message", tcp_message)
                    dst.sendall(tcp_message.message)

                    if self.logging:
                        # log messages are prepended with the client address,
                        # hence the "weird" direction string.
                        if dst == server:
                            direction = "-> tcp -> {}".format(
                                repr(self.server_conn.address))
                        else:
                            direction = "<- tcp <- {}".format(
                                repr(self.server_conn.address))
                        data = clean_bin(tcp_message.message)
                        self.log("{}\r\n{}".format(direction, data), "info")

        except (socket.error, TcpException, SSL.Error) as e:
            six.reraise(
                ProtocolException,
                ProtocolException(
                    "TCP connection closed unexpectedly: {}".format(repr(e))),
                sys.exc_info()[2])
Esempio n. 7
0
    def __call__(self):
        if self.server_conn:
            self._initiate_server_conn()

        preamble = self.client_conn.rfile.read(24)
        self.client_conn.h2.initiate_connection()
        self.client_conn.h2.receive_data(preamble)
        self.client_conn.send(self.client_conn.h2.data_to_send())

        while True:
            r = ssl_read_select(self.active_conns, 1)
            for conn in r:
                source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn
                other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn
                is_server = (conn == self.server_conn.connection)

                with source_conn.h2.lock:
                    try:
                        raw_frame = b''.join(
                            http2_read_raw_frame(source_conn.rfile))
                    except:
                        for stream in self.streams.values():
                            stream.zombie = time.time()
                        return

                    frame, _ = hyperframe.frame.Frame.parse_frame_header(
                        raw_frame[:9])

                    if is_server:
                        list = self.server_reset_streams
                    else:
                        list = self.client_reset_streams
                    if frame.stream_id in list:
                        # this frame belongs to a reset stream - just ignore it
                        if isinstance(
                                frame,
                                hyperframe.frame.HeadersFrame) or isinstance(
                                    frame, hyperframe.frame.ContinuationFrame):
                            # we need to keep the hpack-decoder happy too
                            source_conn.h2.decoder.decode(raw_frame[9:])
                        continue

                    events = source_conn.h2.receive_data(raw_frame)
                    source_conn.send(source_conn.h2.data_to_send())

                    for event in events:
                        if not self._handle_event(event, source_conn,
                                                  other_conn, is_server):
                            return

            self._cleanup_streams()
Esempio n. 8
0
    def __call__(self):
        self.connect()

        if not self.ignore:
            flow = TCPFlow(self.client_conn, self.server_conn, self)
            self.channel.ask("tcp_open", flow)

        buf = memoryview(bytearray(self.chunk_size))

        client = self.client_conn.connection
        server = self.server_conn.connection
        conns = [client, server]

        try:
            while not self.channel.should_exit.is_set():
                r = ssl_read_select(conns, 10)
                for conn in r:
                    dst = server if conn == client else client

                    size = conn.recv_into(buf, self.chunk_size)
                    if not size:
                        conns.remove(conn)
                        # Shutdown connection to the other peer
                        if isinstance(conn, SSL.Connection):
                            # We can't half-close a connection, so we just close everything here.
                            # Sockets will be cleaned up on a higher level.
                            return
                        else:
                            dst.shutdown(socket.SHUT_WR)

                        if len(conns) == 0:
                            return
                        continue

                    tcp_message = TCPMessage(dst == server,
                                             buf[:size].tobytes())
                    if not self.ignore:
                        flow.messages.append(tcp_message)
                        self.channel.ask("tcp_message", flow)
                    dst.sendall(tcp_message.content)

        except (socket.error, TcpException, SSL.Error) as e:
            if not self.ignore:
                flow.error = Error(
                    "TCP connection closed unexpectedly: {}".format(repr(e)))
                self.channel.tell("tcp_error", flow)
        finally:
            if not self.ignore:
                self.channel.tell("tcp_close", flow)
Esempio n. 9
0
    def __call__(self):
        self._initiate_server_conn()
        self._complete_handshake()

        client = self.client_conn.connection
        server = self.server_conn.connection
        conns = [client, server]

        try:
            while True:
                r = tcp.ssl_read_select(conns, 1)
                for conn in r:
                    source_conn = self.client_conn if conn == client else self.server_conn
                    other_conn = self.server_conn if conn == client else self.client_conn
                    is_server = (conn == self.server_conn.connection)

                    with source_conn.h2.lock:
                        try:
                            raw_frame = b''.join(
                                http2.read_raw_frame(source_conn.rfile))
                        except:
                            # read frame failed: connection closed
                            self._kill_all_streams()
                            return

                        if source_conn.h2.state_machine.state == h2.connection.ConnectionState.CLOSED:
                            self.log(
                                "HTTP/2 connection entered closed state already",
                                "debug")
                            return

                        incoming_events = source_conn.h2.receive_data(
                            raw_frame)
                        source_conn.send(source_conn.h2.data_to_send())

                        for event in incoming_events:
                            if not self._handle_event(event, source_conn,
                                                      other_conn, is_server):
                                # connection terminated: GoAway
                                self._kill_all_streams()
                                return

                    self._cleanup_streams()
        except Exception as e:  # pragma: no cover
            self.log(repr(e), "info")
            self.log(traceback.format_exc(), "debug")
            self._kill_all_streams()
Esempio n. 10
0
    def __call__(self):
        if self.server_conn:
            self._initiate_server_conn()

        preamble = self.client_conn.rfile.read(24)
        self.client_conn.h2.initiate_connection()
        self.client_conn.h2.receive_data(preamble)
        self.client_conn.send(self.client_conn.h2.data_to_send())

        while True:
            r = ssl_read_select(self.active_conns, 1)
            for conn in r:
                source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn
                other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn
                is_server = conn == self.server_conn.connection

                with source_conn.h2.lock:
                    try:
                        raw_frame = b"".join(http2_read_raw_frame(source_conn.rfile))
                    except:
                        for stream in self.streams.values():
                            stream.zombie = time.time()
                        return

                    frame, _ = hyperframe.frame.Frame.parse_frame_header(raw_frame[:9])

                    if is_server:
                        list = self.server_reset_streams
                    else:
                        list = self.client_reset_streams
                    if frame.stream_id in list:
                        # this frame belongs to a reset stream - just ignore it
                        if isinstance(frame, hyperframe.frame.HeadersFrame) or isinstance(
                            frame, hyperframe.frame.ContinuationFrame
                        ):
                            # we need to keep the hpack-decoder happy too
                            source_conn.h2.decoder.decode(raw_frame[9:])
                        continue

                    events = source_conn.h2.receive_data(raw_frame)
                    source_conn.send(source_conn.h2.data_to_send())

                    for event in events:
                        if not self._handle_event(event, source_conn, other_conn, is_server):
                            return

            self._cleanup_streams()
Esempio n. 11
0
    def __call__(self):
        self.connect()

        if not self.ignore:
            flow = TCPFlow(self.client_conn, self.server_conn, self)
            self.channel.ask("tcp_open", flow)

        buf = memoryview(bytearray(self.chunk_size))

        client = self.client_conn.connection
        server = self.server_conn.connection
        conns = [client, server]

        try:
            while not self.channel.should_exit.is_set():
                r = ssl_read_select(conns, 10)
                for conn in r:
                    dst = server if conn == client else client

                    size = conn.recv_into(buf, self.chunk_size)
                    if not size:
                        conns.remove(conn)
                        # Shutdown connection to the other peer
                        if isinstance(conn, SSL.Connection):
                            # We can't half-close a connection, so we just close everything here.
                            # Sockets will be cleaned up on a higher level.
                            return
                        else:
                            dst.shutdown(socket.SHUT_WR)

                        if len(conns) == 0:
                            return
                        continue

                    tcp_message = TCPMessage(dst == server, buf[:size].tobytes())
                    if not self.ignore:
                        flow.messages.append(tcp_message)
                        self.channel.ask("tcp_message", flow)
                    dst.sendall(tcp_message.content)

        except (socket.error, TcpException, SSL.Error) as e:
            if not self.ignore:
                flow.error = Error("TCP connection closed unexpectedly: {}".format(repr(e)))
                self.channel.tell("tcp_error", flow)
        finally:
            if not self.ignore:
                self.channel.tell("tcp_close", flow)
Esempio n. 12
0
    def __call__(self):
        if self.server_conn:
            self._initiate_server_conn()

        preamble = self.client_conn.rfile.read(24)
        self.client_conn.h2.initiate_connection()
        self.client_conn.h2.receive_data(preamble)
        self.client_conn.send(self.client_conn.h2.data_to_send())

        try:
            while True:
                r = tcp.ssl_read_select(self.active_conns, 1)
                for conn in r:
                    source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn
                    other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn
                    is_server = (conn == self.server_conn.connection)

                    with source_conn.h2.lock:
                        try:
                            raw_frame = b''.join(
                                http2.framereader.http2_read_raw_frame(
                                    source_conn.rfile))
                        except:
                            # read frame failed: connection closed
                            self._kill_all_streams()
                            return

                        incoming_events = source_conn.h2.receive_data(
                            raw_frame)
                        source_conn.send(source_conn.h2.data_to_send())

                        for event in incoming_events:
                            if not self._handle_event(event, source_conn,
                                                      other_conn, is_server):
                                # connection terminated: GoAway
                                self._kill_all_streams()
                                return

                    self._cleanup_streams()
        except Exception as e:  # pragma: no cover
            self.log(repr(e), "info")
            self.log(traceback.format_exc(), "debug")
            self._kill_all_streams()
Esempio n. 13
0
    def __call__(self):
        self._initiate_server_conn()
        self._complete_handshake()

        client = self.client_conn.connection
        server = self.server_conn.connection
        conns = [client, server]

        try:
            while True:
                r = tcp.ssl_read_select(conns, 1)
                for conn in r:
                    source_conn = self.client_conn if conn == client else self.server_conn
                    other_conn = self.server_conn if conn == client else self.client_conn
                    is_server = (conn == self.server_conn.connection)

                    with source_conn.h2.lock:
                        try:
                            raw_frame = b''.join(http2.read_raw_frame(source_conn.rfile))
                        except:
                            # read frame failed: connection closed
                            self._kill_all_streams()
                            return

                        if source_conn.h2.state_machine.state == h2.connection.ConnectionState.CLOSED:
                            self.log("HTTP/2 connection entered closed state already", "debug")
                            return

                        incoming_events = source_conn.h2.receive_data(raw_frame)
                        source_conn.send(source_conn.h2.data_to_send())

                        for event in incoming_events:
                            if not self._handle_event(event, source_conn, other_conn, is_server):
                                # connection terminated: GoAway
                                self._kill_all_streams()
                                return

                    self._cleanup_streams()
        except Exception as e:  # pragma: no cover
            self.log(repr(e), "info")
            self.log(traceback.format_exc(), "debug")
            self._kill_all_streams()
Esempio n. 14
0
    def __call__(self):
        if self.server_conn:
            self._initiate_server_conn()

        preamble = self.client_conn.rfile.read(24)
        self.client_conn.h2.initiate_connection()
        self.client_conn.h2.receive_data(preamble)
        self.client_conn.send(self.client_conn.h2.data_to_send())

        try:
            while True:
                r = tcp.ssl_read_select(self.active_conns, 1)
                for conn in r:
                    source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn
                    other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn
                    is_server = (conn == self.server_conn.connection)

                    with source_conn.h2.lock:
                        try:
                            raw_frame = b''.join(http2.framereader.http2_read_raw_frame(source_conn.rfile))
                        except:
                            # read frame failed: connection closed
                            self._kill_all_streams()
                            return

                        incoming_events = source_conn.h2.receive_data(raw_frame)
                        source_conn.send(source_conn.h2.data_to_send())

                        for event in incoming_events:
                            if not self._handle_event(event, source_conn, other_conn, is_server):
                                # connection terminated: GoAway
                                self._kill_all_streams()
                                return

                    self._cleanup_streams()
        except Exception as e:  # pragma: no cover
            self.log(repr(e), "info")
            self.log(traceback.format_exc(), "debug")
            self._kill_all_streams()
Esempio n. 15
0
    def __call__(self):
        client = self.client_conn.connection
        server = self.server_conn.connection
        conns = [client, server]

        try:
            while not self.channel.should_exit.is_set():
                r = tcp.ssl_read_select(conns, 1)
                for conn in r:
                    source_conn = self.client_conn if conn == client else self.server_conn
                    other_conn = self.server_conn if conn == client else self.client_conn
                    is_server = (conn == self.server_conn.connection)

                    frame = websockets.Frame.from_file(source_conn.rfile)

                    if not self._handle_frame(frame, source_conn, other_conn, is_server):
                        return
        except (socket.error, netlib.exceptions.TcpException, SSL.Error) as e:
            self.log("WebSockets connection closed unexpectedly by {}: {}".format(
                "server" if is_server else "client", repr(e)), "info")
        except Exception as e:  # pragma: no cover
            raise exceptions.ProtocolException("Error in WebSockets connection: {}".format(repr(e)))