def Leave(self): """ sends Leave message to RS to rescind the registration of this peers P2PServer """ self.server.stop() msg = Message() msg.method = MethodTypes.Leave.name msg.version = Message.VERSION msg.payload = "{}{}{}".format(self.server.host, SEP, self.server.port) msg.headers[Headers.Cookie.name] = self.server.cookie status = None with socket(AF_INET, SOCK_STREAM) as conn: try: conn.connect(RS) send(conn, msg) response = Response().from_bytes(recv(conn)) status = response.status if int(status) == Status.Success.value: self.logger.info( "[Client] Successfully left P2P-DI system") else: self.logger.error("[CLIENT] Failed to leave P2P-DI system") self.start() except error as se: self.logger.error("[CLIENT] Socket error: {}".format(se)) except Exception as e: self.logger.error( "[CLIENT] Error while attempting to leave P2P-DI system: {}" .format(e)) return status
def GetRFC(self, peer, rfc): """ sends GetRFC message to an active peer requesting a specific RFC of interest """ msg = Message() msg.method = MethodTypes.GetRFC.name msg.version = Message.VERSION msg.payload = rfc new_rfc = {} with socket(AF_INET, SOCK_STREAM) as conn: try: host, port = peer.split(':') conn.connect((host, int(port))) send(conn, msg) response = Response().from_bytes(recv(conn)) if response.payload: new_rfc = response.payload self.logger.info( "[CLIENT] {} new RFC fetched from peer {}".format(1, peer)) except error as se: self.logger.error("[CLIENT] Socket error: {}".format(se)) except Exception as e: self.logger.error( "[CLIENT] Error while fetching new RFCs from peer {}: {}". format(peer, e)) return new_rfc
def PQuery(self): """ sends PQuery message RS to get the list of active peers """ msg = Message() msg.method = MethodTypes.PQuery.name msg.version = Message.VERSION msg.payload = "{}{}{}".format(self.server.host, SEP, self.server.port) msg.headers[Headers.Cookie.name] = self.server.cookie peers = [] with socket(AF_INET, SOCK_STREAM) as conn: try: conn.connect(RS) send(conn, msg) response = Response().from_bytes(recv(conn)) if response.payload: peers = response.payload.split(SEP) self.logger.info("[CLIENT] {} active peer(s) found".format( len(peers))) except error as se: self.logger.error("[CLIENT] Socket error: {}".format(se)) except Exception as e: self.logger.error( "[CLIENT] Error while retrieving active peers: {}".format( e)) raise CriticalError return peers
def _socket_error_test(self): """ connects to socket and fails the requests """ client = socket.socket() client.connect(RS) time.sleep(2) msg = Message() msg.method = "Unknown" msg.headers = {} msg.version = Message.VERSION msg.payload = "Invalid message" send(client, msg) data = ServerResponse().from_bytes(recv(client)) self.fail_buffer.append(str(data)) client.close()
def _socket_connect_test(self): """ connects to a server socket """ client = socket.socket() client.connect(RS) time.sleep(4) msg = Message() msg.method = MethodTypes.Register.name msg.headers = {} msg.version = Message.VERSION msg.payload = "nick-name{}{}".format(Message.SR_FIELDS, random.randint(7000, 8000)) send(client, msg) response = ServerResponse().from_bytes(recv(client)) self.assertTrue(Headers.Cookie.name in response.headers) msg.headers[Headers.Cookie.name] = response.headers[ Headers.Cookie.name] msg.method = MethodTypes.KeepAlive.name send(client, msg) ServerResponse().from_bytes(recv(client)) msg.method = MethodTypes.Leave.name send(client, msg) data = ServerResponse().from_bytes(recv(client)) self.buffer.append(str(data)) client.close()
def _socket_cookie_test(self): """ connects to socket and fails the requests """ client = socket.socket() client.connect(RS) time.sleep(3) msg = Message() msg.method = MethodTypes.Register.name msg.headers = {} msg.version = Message.VERSION msg.payload = "nick-name{}{}".format(Message.SR_FIELDS, random.randint(7000, 8000)) send(client, msg) ServerResponse().from_bytes(recv(client)) msg.method = MethodTypes.KeepAlive.name send(client, msg) response = ServerResponse().from_bytes(recv(client)) self.assertEqual(int(response.status), ResponseStatus.Forbidden.value) client.close()
def KeepAlive(self): """ sends KeepAlive message to RS """ msg = Message() msg.method = MethodTypes.KeepAlive.name msg.headers = {Headers.Cookie.name: self.cookie} msg.version = Message.VERSION msg.payload = "{}{}{}".format(self.host, SEP, self.port) with socket(AF_INET, SOCK_STREAM) as conn: try: conn.connect(RS) send(conn, msg) response = Response().from_bytes(recv(conn)) if int(response.status) == 403: raise ForbiddenError(response.payload) self.logger.info("TTL extended") except ForbiddenError as e: self.logger.error(e) except error as se: self.logger.error("[CLIENT] Socket error: {}".format(se)) except Exception as e: self.logger.error("Error while extending TTL: {}".format(e))
def Register(self): """ sends Register message to RS """ msg = Message() msg.method = MethodTypes.Register.name msg.headers = {} msg.version = Message.VERSION msg.payload = "{}{}{}".format(self.host, SEP, self.port) with socket(AF_INET, SOCK_STREAM) as conn: try: conn.connect(RS) send(conn, msg) response = Response().from_bytes(recv(conn)) cookie = response.headers.get(Headers.Cookie.name, None) if not cookie: raise Exception("Cookie not received from RS") self.cookie = cookie self.platform_peer.registered = True self.logger.info("Peer registered") except error as se: self.logger.error("Socket error: {}".format(se)) except Exception as e: self.logger.error("Error while registering Peer: {}".format(e))
def RFCQuery(self, peer): """ sends RFCQuery message to an active peer to get its RFC Index """ msg = Message() msg.method = MethodTypes.RFCQuery.name msg.version = Message.VERSION index = dict() with socket(AF_INET, SOCK_STREAM) as conn: try: host, port = peer.split(':') conn.connect((host, int(port))) send(conn, msg) response = Response().from_bytes(recv(conn)) if response.payload: index = defaultdict(set, literal_eval(response.payload)) self.logger.info( "[CLIENT] RFC Index retrieved from peer {}".format(peer)) except error as se: self.logger.error("[CLIENT] Socket error: {}".format(se)) except Exception as e: self.logger.error( "[CLIENT] Error while retrieving RFC Index from peer {}: {}" .format(peer, e)) return index
def start(self, timeout=inf): """ starts the server """ self._on_start() self.conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.conn.setblocking(0) self.conn.bind((self.host, self.port)) self.conn.listen(5) inputs = [self.conn] outputs = [] timeout = time.time() + timeout self.logger.info("Started server on (%s, %s)" % (self.host, self.port)) while not self.stopped and inputs and time.time() < timeout: try: # listen for connections readable, writeable, exceptional = select.select(inputs, outputs, inputs, Server.INTERVAL) # reconcile state self._reconcile() for s in readable: if s is self.conn: conn, client = s.accept() self.logger.info("Accepted connection from %s" % str(client)) inputs.append(conn) self.messages[conn] = queue.Queue() self._new_connection_callback(conn) else: data = recv(s) if data: self.logger.info( "Received message {} from {}:{}".format(data, s.getpeername()[0], s.getpeername()[1])) if s not in outputs: outputs.append(s) self._new_message_callback(s, data) else: if s in outputs: outputs.remove(s) inputs.remove(s) s.close() del self.messages[s] for s in writeable: try: next_msg = self.messages[s].get_nowait() except queue.Empty: outputs.remove(s) except KeyError: pass else: send(s, next_msg) for s in exceptional: inputs.remove(s) for s in outputs: outputs.remove(s) s.close() del self.messages[s] except OSError as e: if e.errno == errno.EBADF: self.stopped = True continue raise e else: self.logger.info("Server running on {}:{} stopped".format(self.host, self.port)) self.stop()