def new_message_packet(message, source_server_address): """ Packet for sending a broadcast message to the whole network. :param message: Our message :param source_server_address: Server address of the packet sender. :type message: str :type source_server_address: tuple :return: New Message packet. :rtype: Packet """ p_version = 1 p_type = 4 # message packet p_length = len(message) p_ip, p_port = source_server_address b_version = utils.int_to_bytes(p_version, 2) b_type = utils.int_to_bytes(p_type, 2) b_length = utils.int_to_bytes(p_length, 4) b_ip = utils.ip_to_bytes(p_ip) b_port = utils.int_to_bytes(int(p_port), 4) header_bytes = b_version + b_type + b_length + b_ip + b_port # Body body = message body_bytes = body.encode() packet_bytes = bytearray(header_bytes + body_bytes) return Packet(packet_bytes)
def new_join_packet(source_server_address): """ :param source_server_address: Server address of the packet sender. :type source_server_address: tuple :return New join packet. :rtype Packet """ # Packet Header info p_version = 1 p_type = 3 # advertise packet p_length = 4 p_ip, p_port = source_server_address b_version = utils.int_to_bytes(p_version, 2) b_type = utils.int_to_bytes(p_type, 2) b_length = utils.int_to_bytes(p_length, 4) b_ip = utils.ip_to_bytes(p_ip) b_port = utils.int_to_bytes(int(p_port), 4) header_bytes = b_version + b_type + b_length + b_ip + b_port body = 'JOIN' body_bytes = body.encode() packet_bytes = bytearray(header_bytes + body_bytes) return Packet(packet_bytes)
def new_advertise_packet(type, source_server_address, neighbour=None): """ :param type: Type of Advertise packet :param source_server_address Server address of the packet sender. :param neighbour: The neighbour for advertise response packet; The format is like ('192.168.001.001', '05335'). :type type: str :type source_server_address: tuple :type neighbour: tuple :return New advertise packet. :rtype Packet """ # Packet Header info p_version = 1 p_type = 2 # advertise packet p_length = 3 if type == 'RES': p_length = 3 + 20 elif type == 'REQ': p_length = 3 p_ip, p_port = source_server_address b_version = utils.int_to_bytes(p_version, 2) b_type = utils.int_to_bytes(p_type, 2) b_length = utils.int_to_bytes(p_length, 4) b_ip = utils.ip_to_bytes(p_ip) b_port = utils.int_to_bytes(int(p_port), 4) header_bytes = b_version + b_type + b_length + b_ip + b_port # packet body body = '' if type == 'RES': body += type if neighbour is not None: body = body + neighbour[0] + neighbour[1] else: print( "there's a problem... the neighbour address in the advertise response can't be None." ) elif type == 'REQ': body = type body_bytes = body.encode() packet_bytes = bytearray(header_bytes + body_bytes) return Packet(packet_bytes)
def new_reunion_packet(type: str, source_address: (str, str), nodes_array: list): """ :param type: Reunion Hello (REQ) or Reunion Hello Back (RES) :param source_address: IP/Port address of the packet sender. :param nodes_array: [(ip0, port0), (ip1, port1), ...] It is the path to the 'destination'. :type type: str :type source_address: tuple :type nodes_array: list :return New reunion packet. :rtype Packet """ # Packet Header info p_version = 1 p_type = 5 # reunion packet p_length = 5 + 20 * len(nodes_array) p_ip, p_port = source_address b_version = utils.int_to_bytes(p_version, 2) b_type = utils.int_to_bytes(p_type, 2) b_length = utils.int_to_bytes(p_length, 4) b_ip = utils.ip_to_bytes(p_ip) b_port = utils.int_to_bytes(int(p_port), 4) header_bytes = b_version + b_type + b_length + b_ip + b_port number_of_entries = len(nodes_array) p_num_of_entries = '{0:02d}'.format(number_of_entries) # pack body # fmt = '3s' + '2s' # for i in range(number_of_entries): # fmt += '15s' + '5s' body = type + p_num_of_entries # todo: double check this... if type == 'REQ': for i in range(len(nodes_array)): body += nodes_array[i][0] + nodes_array[i][1] elif type == 'RES': for i in range(len(nodes_array) - 1, -1, -1): body += nodes_array[i][0] + nodes_array[i][1] body_bytes = body.encode() packet_bytes = bytearray(header_bytes + body_bytes) return Packet(packet_bytes)
def new_register_packet(type, source_server_address, address=(None, None)): """ :param type: Type of Register packet :param source_server_address: Server address of the packet sender. :param address: If 'type' is 'request' we need an address; The format is like ('192.168.001.001', '05335'). :type type: str :type source_server_address: tuple :type address: tuple :return New Register packet. :rtype Packet """ # Packet Header info p_version = 1 p_type = 1 # register packet p_length = 23 if type == 'REQ': p_length = 3 + 20 elif type == 'RES': p_length = 6 p_ip, p_port = source_server_address b_version = utils.int_to_bytes(p_version, 2) b_type = utils.int_to_bytes(p_type, 2) b_length = utils.int_to_bytes(p_length, 4) b_ip = utils.ip_to_bytes(p_ip) b_port = utils.int_to_bytes(int(p_port), 4) header_bytes = b_version + b_type + b_length + b_ip + b_port # Body body = type if type == 'REQ': if address is not None: body = body + address[0] + address[1] else: print( "there's a problem... the address in the register request can't be None." ) elif type == 'RES': body += 'ACK' body_bytes = body.encode() packet_bytes = bytearray(header_bytes + body_bytes) return Packet(packet_bytes)
def get_buf(self): """ In this function, we will make our final buffer that represents the Packet with the Struct class methods. :return The parsed packet to the network format. :rtype: bytearray """ b_version = utils.int_to_bytes(self.version, 2) b_type = utils.int_to_bytes(self.type, 2) b_length = utils.int_to_bytes(self.length, 4) b_ip = utils.ip_to_bytes(self.ip) b_port = utils.int_to_bytes(int(self.port), 4) b_body = self.body.encode() if utils.DEBUG: if bytearray(b_version + b_type + b_length + b_ip + b_port + b_body) == self.buf: print("DDD::U did it right! :))") return bytearray(b_version + b_type + b_length + b_ip + b_port + b_body)