def __handle_register_packet(self, packet: Packet):
        """
        For registration a new node to the network at first we should make a Node with stream.add_node for'sender' and
        save it.

        Code design suggestion:
            1.For checking whether an address is registered since now or not you can use SemiNode object except Node.

        Warnings:
            1. Don't forget to ignore Register Request packets when you are a non-root peer.

        :param packet: Arrived register packet
        :type packet Packet
        :return:
        """
        register_type = self.__identify_register_type(packet)
        if self.is_root and register_type == RegisterType.REQ:
            new_node = SemiNode(packet.get_source_server_ip(),
                                packet.get_source_server_port())
            if new_node in self.registered:
                return
            self.registered.append(new_node)
            sender_address = packet.get_source_server_address()
            self.stream.add_node(sender_address, set_register_connection=True)
            register_response_packet = PacketFactory.new_register_packet(
                RegisterType.RES, self.address)
            self.stream.add_message_to_out_buff(sender_address,
                                                register_response_packet,
                                                want_register=True)
        elif register_type == RegisterType.RES:
            log('Register request ACKed by root. You are now registered.')
    def __handle_message_packet(self, packet: Packet):
        """
        Only broadcast message to the other nodes.

        Warnings:
            1. Do not forget to ignore messages from unknown sources.
            2. Make sure that you are not sending a message to a register_connection.

        :param packet: Arrived message packet

        :type packet Packet

        :return:
        """
        log(f'New message arrived: {packet.get_body()}')
        sender_address = packet.get_source_server_address()
        updated_packet = PacketFactory.new_message_packet(
            packet.get_body(), self.address)
        if self.__check_neighbour(sender_address):  # From known source
            for neighbor_address in [
                    *self.children_addresses, self.parent_address
            ]:
                if neighbor_address is not None and neighbor_address != sender_address:
                    self.stream.add_message_to_out_buff(
                        neighbor_address, updated_packet)
Esempio n. 3
0
    def run(self):
        """
		The main loop of the program.

		Code design suggestions:
			1. Parse server in_buf of the stream. ---- done
			2. Handle all packets were received from our Stream server. ---- done
			3. Parse user_interface_buffer to make message packets.  ---- done
			4. Send packets stored in nodes buffer of our Stream object. ---- done
			5. ** sleep the current thread for 2 seconds ** -------- done

		Warnings:
			1. At first check reunion daemon condition; Maybe we have a problem in this time
			   and so we should hold any actions until Reunion acceptance. ------- done
			2. In every situation checkout Advertise Response packets; even if Reunion in failure mode or not ------- done

		:return:
		"""

        while True:
            if not self.is_root:
                if self.is_client_connected:
                    input_buffer = self.stream.read_in_buf()
                    for buf in input_buffer:
                        packet = Packet(buf)
                        print('gonna print a received packet! ')
                        print(packet.__dict__)
                        self.handle_packet(packet)
                    self.stream.clear_in_buff(
                    )  # TODO buffer messages that use unvailable addreses
                    unavailable_addreses = self.stream.send_out_buf_messages()
                    if self.root_address in unavailable_addreses:
                        self.is_client_connected = False
                    for add in unavailable_addreses:
                        if add in self.successors_address:
                            self.successors_address.remove(add)
                else:
                    input_buffer = self.stream.read_in_buf()
                    for buf in input_buffer:
                        packet = Packet(buf)
                        if packet.type == PacketType.ADVERTISE:
                            self.__handle_advertise_packet(packet)
                    self.stream.clear_in_buff()
                self.handle_user_interface_buffer()
            else:
                input_buffer = self.stream.read_in_buf()
                for buf in input_buffer:
                    packet = Packet(buf)
                    print('gonna print a received packet! ')
                    print(packet.__dict__)
                    self.handle_packet(packet)

                self.stream.clear_in_buff()
                self.handle_user_interface_buffer()
                unavailable_addreses = self.stream.send_out_buf_messages()
                for add in unavailable_addreses:
                    if add in self.successors_address:
                        self.successors_address.remove(add)
            time.sleep(2)
Esempio n. 4
0
 def send_helloback(self, packet):
     if not self.is_root:
         return
     print('Sending Hello back')
     packet.body = 'RES' + packet.body[3:]
     packet.source_ip = self.address[0]
     packet.source_port = self.address[1]
     packet = Packet(packet.get_buf())
     self.send_broadcast_packet(packet)
Esempio n. 5
0
 def forward_helloback(self, packet):
     packet = self.change_header(packet)
     packet.body = packet.body[:-20]
     number_of_entries = str(int(packet.body[3:5]) - 1).zfill(2)
     packet.body = 'RES' + number_of_entries + packet.body[5:]
     packet = Packet(packet.get_buf())
     fw_address = packet.body[-20:]
     fw_address = (fw_address[:15], fw_address[15:])
     if fw_address in self.successors_address:
         self.stream.add_message_to_out_buff(fw_address, packet)
     else:
         return
Esempio n. 6
0
    def parse_in_buf(self):
        buffer = self.stream.read_in_buf()
        header_size = 20
        if len(buffer) < header_size:
            return None

        packet = Packet(buf=buffer[0:20])
        packet_length = packet.get_length()
        if len(buffer) < packet_length:
            return None
        packet = Packet(buf=buffer[0:packet_length])
        self.stream.delete_buffer(packet_length)
        return packet
Esempio n. 7
0
 def forward_hello(self, packet, is_mine=False):
     if is_mine:
         self.stream.add_message_to_out_buff(
             self.client_predecessor_address, packet)
     else:
         print('Forwarding a Hello that is not mine')
         packet = self.change_header(packet)
         packet.body += str(self.address[0]) + str(self.address[1])
         new_number_of_elements = int(packet.body[3:5]) + 1
         packet.body = 'REQ' + str(new_number_of_elements).zfill(
             2) + packet.body[5:]
         packet = Packet(packet.get_buf())
         self.stream.add_message_to_out_buff(
             self.client_predecessor_address, packet)
 def __pass_reunion_hello_back(self, packet: Packet):
     new_addresses = packet.get_addresses()[1:]
     next_node_address = new_addresses[0]
     log(f'HelloBack packet passed down to Node({next_node_address}).')
     passed_packet = PacketFactory.new_reunion_packet(
         ReunionType.RES, self.address, new_addresses)
     self.stream.add_message_to_out_buff(next_node_address, passed_packet)
 def __handle_reunion_hello_back(self, packet: Packet):
     if packet.get_addresses()[-1] == self.address:
         # It's our hello back!
         self.last_hello_back_time = time.time()
         log('We received our HelloBack.')
     else:
         self.__pass_reunion_hello_back(packet)
 def __handle_advertise_response(self, packet: Packet) -> None:
     self.last_hello_time = time.time()
     self.last_hello_back_time = time.time()
     parent_address = packet.get_advertised_address()
     log(f'Trying to join Node({parent_address})...')
     self.parent_address = parent_address
     join_packet = PacketFactory.new_join_packet(self.address)
     self.stream.add_node(
         parent_address)  # Add a non_register Node to stream to the parent
     log(f'Join Request added to out buf on Node({parent_address}).')
     self.stream.add_message_to_out_buff(parent_address, join_packet)
     self.reunion_mode = ReunionMode.ACCEPTANCE
     if not self.reunion_daemon.is_alive():
         self.reunion_daemon.start()
    def __handle_join_packet(self, packet: Packet):
        """
        When a Join packet received we should add a new node to our nodes array.
        In reality, there is a security level that forbids joining every node to our network.

        :param packet: Arrived register packet.


        :type packet Packet

        :return:
        """
        new_member_address = packet.get_source_server_address()
        log(f'New JOIN packet from Node({new_member_address}).')
        self.stream.add_node(new_member_address)
        self.children_addresses.append(new_member_address)
 def __handle_advertise_request(self, packet: Packet) -> None:
     sender_address = packet.get_source_server_address()
     sender_semi_node = SemiNode(sender_address[0], sender_address[1])
     if sender_semi_node not in self.registered:
         log(f'Advertise Request from unregistered source({sender_address}).'
             )
         return
     advertised_address = self.__get_neighbour(sender_address)
     log(f'Advertising Node({advertised_address}) to Node({sender_address}).'
         )
     advertise_response_packet = PacketFactory.new_advertise_packet(
         AdvertiseType.RES, self.address, advertised_address)
     self.stream.add_message_to_out_buff(sender_address,
                                         advertise_response_packet,
                                         want_register=True)
     # Add to network_graph
     self.network_graph.add_node(sender_semi_node.get_ip(),
                                 sender_semi_node.get_port(),
                                 advertised_address)
 def __identify_reunion_type(self, packet: Packet) -> ReunionType:
     reunion_type = packet.get_body()[:3]
     return ReunionType(reunion_type)
Esempio n. 14
0
 def change_header(self, packet):
     packet.source_ip, packet.source_port = self.address[0], self.address[1]
     packet = Packet(packet.get_buf())
     return packet
 def __identify_advertise_type(self, packet: Packet) -> AdvertiseType:
     advertise_type = packet.get_body()[:3]
     return AdvertiseType(advertise_type)
 def __identify_register_type(self, packet: Packet) -> RegisterType:
     register_type = packet.get_body()[:3]
     return RegisterType(register_type)
 def __respond_to_reunion(self, packet: Packet):
     reversed_addresses = packet.get_addresses_in_reverse()
     response_packet = PacketFactory.new_reunion_packet(
         ReunionType.RES, self.address, reversed_addresses)
     next_node_address = reversed_addresses[0]
     self.stream.add_message_to_out_buff(next_node_address, response_packet)
 def __update_last_reunion(self, packet: Packet):
     sender_address = packet.get_addresses()[0]
     next_node = packet.get_addresses()[-1]
     self.network_graph.keep_alive(sender_address)
     log(f'New Hello from Node({sender_address}).')
     log(f'HelloBack added to out buf of Node({next_node})')
 def __format_reunion_hello_addresses_on_pass(
         self, packet: Packet) -> List[Address]:
     addresses = packet.get_addresses()
     addresses.append(self.address)
     return addresses
 def __validate_received_packet(packet: Packet) -> bool:
     if packet.get_length() != len(packet.get_body()):
         return False
     # TODO: More conditions
     return True