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
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
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
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)
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)
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
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)
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)
def accept(self): self.pid = self.sock.pid self.socket_event = scheduler.add_socket(self.handle_recv, self.sock) return True
def start(self, address): self.transport.start(address) scheduler.add_socket(self.handle_recv, self.transport)
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
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
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
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
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()
def accept(self): self.socket_event = scheduler.add_socket(self.handle_recv, self.sock)
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)