Esempio n. 1
0
    def accept(self, sid):
        if self.state != STATE_READY:
            raise RuntimeError("PRUDP socket can only be used once")

        host, port = self.remote_address()
        logger.info("Accepting PRUDP connection from %s:%i", host, port)

        self.state = STATE_ACCEPTING

        self.local_port = sid

        self.stream.accept()
        self.socket_event = scheduler.add_socket(self.handle_packet,
                                                 self.stream)

        while self.state == STATE_ACCEPTING:
            scheduler.update()

        if self.state != STATE_CONNECTED:
            return False

        logger.debug("PRUDP connection accepted successfully")

        self.start_ping()
        return True
Esempio n. 2
0
    def connect(self, host, port, sid, payload=b""):
        if self.state != STATE_READY:
            raise RuntimeError("PRUDP socket can only be used once")

        self.state = STATE_CONNECTING

        logger.info("Connecting to %s:%i:%i", host, port, sid)

        if not self.stream.connect(host, port):
            self.cleanup()
            return None

        self.local_port = 0xF
        if self.transport_type != self.settings.TRANSPORT_UDP:
            self.local_port = 0x1F

        self.remote_port = sid

        syn_packet = PRUDPPacket(TYPE_SYN, FLAG_NEED_ACK)
        syn_packet.connection_signature = bytes(self.stream.signature_size())
        syn_ack = self.send_packet(syn_packet, block=True)
        if not syn_ack:
            logger.error("SYN handshake failed")
            self.cleanup()
            return None

        self.remote_signature = syn_ack.connection_signature

        self.local_session_id = random.randint(0, 0xFF)
        if self.transport_type == self.settings.TRANSPORT_UDP:
            self.local_signature = secrets.token_bytes(
                self.stream.signature_size())
        else:
            self.local_signature = hmac.new(self.signature_key,
                                            self.signature_key +
                                            self.remote_signature,
                                            digestmod=hashlib.md5).digest()

        connect_packet = PRUDPPacket(TYPE_CONNECT,
                                     FLAG_RELIABLE | FLAG_NEED_ACK)
        connect_packet.connection_signature = self.local_signature
        connect_packet.payload = payload
        connect_ack = self.send_packet(connect_packet, block=True)
        if not connect_ack:
            logger.error("CONNECT handshake failed")
            self.cleanup()
            return None

        logger.debug("Connection established successfully")

        self.remote_session_id = connect_ack.session_id
        self.state = STATE_CONNECTED

        self.start_ping()

        self.socket_event = scheduler.add_socket(self.handle_packet,
                                                 self.stream)
        return connect_ack.payload
Esempio n. 3
0
    def connect(self, host, port, stream_id):
        if self.state != self.READY:
            raise RuntimeError("PRUDP socket may only be used once")

        logger.info("Connecting to %s:%i:%i", host, port, stream_id)
        self.state = self.CONNECTING

        self.remote_port = stream_id

        self.local_port = 0xF
        if self.transport_type == self.settings.TRANSPORT_WEBSOCKET:
            self.local_port = 0x1F

        if not self.sock.connect(host, port):
            logger.error("Socket connection failed")
            self.state = self.DISCONNECTED
            return False

        self.timeout_event = scheduler.add_timeout(self.handle_silence_timeout,
                                                   self.silence_timeout)
        self.socket_event = scheduler.add_socket(self.handle_recv, self.sock)

        syn_packet = PRUDPPacket(TYPE_SYN, FLAG_NEED_ACK)
        syn_packet.signature = bytes(self.packet_encoder.signature_size())
        self.send_packet(syn_packet)
        if not self.wait_ack(syn_packet):
            logger.error("SYN handshake failed")
            return False

        self.local_session_id = random.randint(0, 0xFF)
        if self.transport_type == self.settings.TRANSPORT_UDP:
            self.source_signature = secrets.token_bytes(
                self.packet_encoder.signature_size())
        else:
            self.source_signature = hmac.HMAC(
                self.signature_key,
                self.signature_key + self.target_signature).digest()

        connect_packet = PRUDPPacket(TYPE_CONNECT,
                                     FLAG_RELIABLE | FLAG_NEED_ACK)
        connect_packet.signature = self.source_signature
        connect_packet.payload = self.build_connection_request()

        self.send_packet(connect_packet)
        if not self.wait_ack(connect_packet):
            logger.error("CONNECT handshake failed")
            return False

        self.packet_id_in += 1

        self.ping_event = scheduler.add_timeout(self.handle_ping,
                                                self.ping_timeout, True)

        logger.info("PRUDP connection OK")
        self.state = self.CONNECTED
        return True
Esempio n. 4
0
    def __init__(self, cls, sock):
        self.cls = cls
        self.sock = sock

        self.buffer = b""
        self.state = self.state_header
        self.result = RESULT_INCOMPLETE
        self.message = self.cls()
        self.messages = []
        self.callback = None

        self.event = scheduler.add_socket(self.process, self.sock)
Esempio n. 5
0
    def prepare(self):
        self.session_start = time.monotonic()

        for port in range(0xC000, 0xC004):
            try:
                self.socket.bind("", port)
                break
            except OSError as e:
                if e.errno != errno.EADDRINUSE:
                    raise e
        else:
            raise RuntimeError("Couldn't find a free port to bind UDP socket")

        self.event = scheduler.add_socket(self.handle_recv, self.socket)
Esempio n. 6
0
    def accept(self, stream_id):
        if self.state != self.READY:
            raise RuntimeError("PRUDP socket may only be used once")

        self.state = self.ACCEPTING

        self.local_port = stream_id

        self.timeout_event = scheduler.add_timeout(self.handle_silence_timeout,
                                                   self.silence_timeout)
        self.socket_event = scheduler.add_socket(self.handle_recv, self.sock)

        next(self.packet_id_out)

        while self.state == self.ACCEPTING:
            scheduler.update()
        return self.state == self.CONNECTED
Esempio n. 7
0
    def prepare(self, identification_info):
        logger.info("Initializing PIA session")
        self.create_protocols()

        self.transport.prepare()

        location = self.prepare_station_location()

        connection_info = StationConnectionInfo(location)

        self.my_station = self.stations.create()
        self.my_station.connection_state = ConnectionState.CONNECTED
        self.my_station.address = self.transport.local_address()
        self.my_station.connection_info = connection_info
        self.my_station.identification_info = identification_info
        self.my_station.id = self.build_station_id()

        self.event = scheduler.add_socket(self.handle_recv, self.transport)
Esempio n. 8
0
    def start(self):
        self.s = UDPSocket()
        self.s.bind(self.broadcast[0], self.broadcast[1])

        self.event = scheduler.add_socket(self.handle_recv, self.s)
Esempio n. 9
0
	def accept(self):
		self.pid = self.sock.pid
		self.socket_event = scheduler.add_socket(self.handle_recv, self.sock)
		return True
Esempio n. 10
0
	def start(self, address):
		self.transport.start(address)
		scheduler.add_socket(self.handle_recv, self.transport)
Esempio n. 11
0
 def accept(self):
     if self.sock.server_ticket:
         self.pid = self.sock.server_ticket.source_pid
     self.socket_event = scheduler.add_socket(self.handle_recv, self.sock)
     return True
Esempio n. 12
0
    def connect(self, host, port, payload=b""):
        if not self.client.connect(host, port, payload):
            raise ConnectionError("Connection failed")

        self.socket_event = scheduler.add_socket(self.handle_recv, self.client)
        return self.client.connect_response
Esempio n. 13
0
    def connect(self, host, port, payload=b""):
        if self.state != self.DISCONNECTED:
            raise RuntimeError("Socket was not disconnected")

        logger.info("Connecting to %s:%i", host, port)
        self.state = self.CONNECTING

        self.encryption.set_key(self.DEFAULT_KEY)
        self.secure_key = b""

        self.server_signature = b""
        self.client_signature = b""
        self.connect_response = b""

        self.packets = []
        self.packet_queue = {}
        self.fragment_buffer = b""
        self.packet_id_out = itertools.count()
        self.packet_id_in = 1
        self.session_id = 0

        self.packet_encoder.reset()
        if self.transport_type == self.settings.TRANSPORT_UDP:
            self.s = socket.Socket(socket.TYPE_UDP)
        elif self.transport_type == self.settings.TRANSPORT_TCP:
            self.s = socket.Socket(socket.TYPE_TCP)
        else:
            self.s = websocket.WebSocket()

        if not self.s.connect(host, port):
            logger.error("Socket connection failed")
            self.state = self.DISCONNECTED
            return False

        self.ack_events = {}
        self.ping_event = None
        self.timeout_event = scheduler.add_timeout(self.handle_silence_timeout,
                                                   self.silence_timeout)
        self.socket_event = scheduler.add_socket(self.handle_recv, self.s)

        self.send_packet(self.syn_packet)
        if not self.wait_ack(self.syn_packet):
            logger.error("PRUDP connection failed")
            return False

        self.session_id = random.randint(0, 0xFF)
        if self.transport_type == self.settings.TRANSPORT_UDP:
            self.client_signature = bytes([
                random.randint(0, 0xFF)
                for i in range(self.packet_encoder.signature_size())
            ])
        else:
            self.client_signature = hmac.HMAC(
                self.signature_key,
                self.signature_key + self.server_signature).digest()
        self.connect_packet.signature = self.client_signature
        self.connect_packet.payload = payload

        self.send_packet(self.connect_packet)
        if not self.wait_ack(self.connect_packet):
            logger.error("PRUDP connection failed")
            return False

        self.ping_event = scheduler.add_timeout(self.handle_ping,
                                                self.ping_timeout, True)

        logger.info("PRUDP connection OK")
        self.state = self.CONNECTED
        return True
Esempio n. 14
0
    def connect(self, host, port):
        if not self.sock.connect(host, port):
            return False

        self.socket_event = scheduler.add_socket(self.handle_recv, self.sock)
        return True
Esempio n. 15
0
	def start(self, addr):
		self.socket = P2PSocket()
		self.socket.bind(addr[0], addr[1])
		scheduler.add_socket(self.handle_recv, self.socket)
		
		self.session_start = time.monotonic()
Esempio n. 16
0
 def accept(self):
     self.socket_event = scheduler.add_socket(self.handle_recv, self.sock)
Esempio n. 17
0
	def prepare(self):
		version = self.settings.get("pia.message_version")
		self.encoder = MessageEncoders[version]()
		
		self.transport.prepare()
		self.event = scheduler.add_socket(self.handle_recv, self.transport)