Beispiel #1
0
    def handle_user_interface_buffer(self):
        """
		In every interval, we should parse user command that buffered from our UserInterface.
		All of the valid commands are listed below:
			1. Register:  With this command, the client send a Register Request packet to the root of the network.
			2. Advertise: Send an Advertise Request to the root of the network for finding first hope.
			3. SendMessage: The following string will be added to a new Message packet and broadcast through the network.

		Warnings:
			1. Ignore irregular commands from the user.
			2. Don't forget to clear our UserInterface buffer.
		:return:
		"""
        for message in self.user_interface.buffer:
            print('handling : ' + message)
            if message == 'Register':
                reg_packet = PacketFactory.new_register_packet(
                    "REQ", self.address, self.address)
                self.send_packet(reg_packet, self.root_address)
                self.stream.send_out_buf_messages(only_register=True)
            elif message == 'Advertise':
                advertise_packet = PacketFactory.new_advertise_packet(
                    type="REQ", source_server_address=self.address)
                self.send_advertise_packet(advertise_packet)
                self.stream.send_out_buf_messages(only_register=True)
            elif message.startswith('SendMessage'):
                to_be_sent = message.split()[1]
                message_packet = PacketFactory.new_message_packet(
                    message=to_be_sent, source_server_address=self.address)
                self.send_broadcast_packet(message_packet)
            else:
                continue

        self.user_interface.buffer.clear()
Beispiel #2
0
    def __handle_reunion_packet(self, packet):
        """
        In this function we should handle Reunion packet was just arrived.

        Reunion Hello:
            If you are root Peer you should answer with a new Reunion Hello Back packet.
            At first extract all addresses in the packet body and append them in descending order to the new packet.
            You should send the new packet to the first address in the arrived packet.
            If you are a non-root Peer append your IP/Port address to the end of the packet and send it to your parent.

        Reunion Hello Back:
            Check that you are the end node or not; If not only remove your IP/Port address and send the packet to the next
            address, otherwise you received your response from the root and everything is fine.

        Warnings:
            1. Every time adding or removing an address from packet don't forget to update Entity Number field.
            2. If you are the root, update last Reunion Hello arrival packet from the sender node and turn it on.
            3. If you are the end node, update your Reunion mode from pending to acceptance.


        :param packet: Arrived reunion packet
        :return:
        """
        nodes = PacketFactory.parse_reunion_packet_body(packet.body)

        if self.is_root:
            if packet.body[0:3] == 'RES':
                return
            self.graph.reunion_arrived(nodes[0])
            nodes.reverse()
            res_pkt = PacketFactory.new_reunion_packet('RES', self.address,
                                                       nodes)
            self.stream.add_message_to_out_buff(
                packet.get_source_server_address(), res_pkt)
            print('hello back sent to')
            print(packet.get_source_server_address())
            return
        else:
            if packet.body[0:3] == 'REQ':
                nodes.append(self.address)
                res_pkt = PacketFactory.new_reunion_packet(
                    'REQ', self.address, nodes)
                self.stream.add_message_to_out_buff(self.parent, res_pkt)
                return
            else:
                nodes = PacketFactory.parse_reunion_packet_body(packet.body)
                if not self.address_equal(nodes[0], self.address):
                    return
                if len(nodes) == 1:
                    # print('bla bla bla bla bla bla')
                    self.reunion_back_arrived()
                    return
                # print('kiiiiir')
                nodes.remove(nodes[0])
                res_pkt = PacketFactory.new_reunion_packet(
                    'RES', self.address, nodes)
                self.stream.add_message_to_out_buff(nodes[0], res_pkt)
                return

        pass
Beispiel #3
0
    def __init__(self,
                 server_ip,
                 server_port,
                 is_root=False,
                 root_address=None):
        """
        The Peer object constructor.

        Code design suggestions:
            1. Initialise a Stream object for our Peer.
            2. Initialise a PacketFactory object.
            3. Initialise our UserInterface for interaction with user commandline.
            4. Initialise a Thread for handling reunion daemon.

        Warnings:
            1. For root Peer we need a NetworkGraph object.
            2. In root Peer start reunion daemon as soon as possible.
            3. In client Peer we need to connect to the root of the network, Don't forget to set this connection
               as a register_connection.


        :param server_ip: Server IP address for this Peer that should be pass to Stream.
        :param server_port: Server Port address for this Peer that should be pass to Stream.
        :param is_root: Specify that is this Peer root or not.
        :param root_address: Root IP/Port address if we are a client.

        :type server_ip: str
        :type server_port: int
        :type is_root: bool
        :type root_address: tuple
        """
        self._is_root = is_root

        self.stream = Stream(server_ip, server_port)

        self.parent = None

        self.packets = []
        self.neighbours = []
        self.flagg = True

        self.reunion_accept = True
        self.reunion_daemon_thread = threading.Thread(
            target=self.run_reunion_daemon)
        self.reunion_sending_time = time.time()
        self.reunion_pending = False

        self._user_interface = UserInterface()

        self.packet_factory = PacketFactory()

        if self._is_root:
            self.network_nodes = []
            self.registered_nodes = []
            self.network_graph = NetworkGraph(
                GraphNode((server_ip, str(server_port).zfill(5))))
            self.reunion_daemon_thread.start()
        else:
            self.root_address = root_address
            self.stream.add_node(root_address, set_register_connection=True)
Beispiel #4
0
    def run(self):
        """
        The main loop of the program.

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

        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.
            2. In every situation checkout Advertise Response packets; even is Reunion in failure mode or not

        :return:
        """
        while True:
            if self.is_root:
                pass
            else:
                pass

            if self.counter > 0 or True:
                received_bufs = self.stream.read_in_buf()
                received_packets = [
                    PacketFactory.parse_buffer(buf) for buf in received_bufs
                ]
                for packet in received_packets:
                    self.handle_packet(packet)

                self.stream.clear_in_buff()
                self.stream.send_out_buf_messages()
                self.handle_user_interface_buffer()

            if self.reunion_timer == 0 and self.joined and not self.reunion_on_fly:
                self.reunion_on_fly = True
                reunion_req_packet = PacketFactory.new_reunion_packet(
                    type='REQ',
                    source_address=self.server_address,
                    nodes_array=[self.server_address])
                self.stream.add_message_to_out_buff(
                    address=self.parent_address,
                    message=reunion_req_packet.buf)
                self.print_function("Sent Reunion Packet to Parent: " +
                                    str(self.parent_address))

            if not self.reunion_on_fly and self.reunion_timer > 0:
                self.reunion_timer -= self.timer_interval * 10

            self.counter += self.timer_interval * 10
            if self.counter == 4 * 10:
                self.counter = 0
            if self.is_root:
                for gnode in self.graph.nodes:
                    gnode.reunion_timer += self.timer_interval * 10
            time.sleep(self.timer_interval)
Beispiel #5
0
    def __handle_advertise_packet(self, packet):
        """
        For advertising peers in the network, It is peer discovery message.

        Request:
            We should act as the root of the network and reply with a neighbour address in a new Advertise Response packet.

        Response:
            When an Advertise Response packet type arrived we should update our parent peer and send a Join packet to the
            new parent.

        Code design suggestion:
            1. Start the Reunion daemon thread when the first Advertise Response packet received.
            2. When an Advertise Response message arrived, make a new Join packet immediately for the advertised address.

        Warnings:
            1. Don't forget to ignore Advertise Request packets when you are a non-root peer.
            2. The addresses which still haven't registered to the network can not request any peer discovery message.
            3. Maybe it's not the first time that the source of the packet sends Advertise Request message. This will happen
               in rare situations like Reunion Failure. Pay attention, don't advertise the address to the packet sender
               sub-tree.
            4. When an Advertise Response packet arrived update our Peer parent for sending Reunion Packets.

        :param packet: Arrived register packet

        :type packet Packet

        :return:
        """
        if (packet.body[0:3] == 'RES') and (not self.is_root):
            self.children.clear()
            self.stream.remove_not_reg_nodes()
            self.parent = Node.parse_address(
                (packet.body[3:18], packet.body[18:23]))
            succ = self.stream.add_node(self.parent)
            if not succ:
                return
            join = PacketFactory.new_join_packet(self.address)
            self.stream.add_message_to_out_buff(self.parent, join)
            self.is_connected = True
            self.r_h_b_received = True
            self.since_last = 0
            # now we are connected
        elif (packet.body[0:3] == 'REQ') and (self.is_root):
            if not self.graph.is_registered(
                    packet.get_source_server_address()):
                return
            address = self.graph.find_live_node(
                packet.get_source_server_address()).get_address()
            if address is None:
                return
            self.graph.add_node(packet.sender_ip, packet.sender_port, address)
            res_pkt = PacketFactory.new_advertise_packet(
                'RES', self.address, address)
            self.stream.add_message_to_out_buff(
                packet.get_source_server_address(), res_pkt)
        pass
Beispiel #6
0
    def handle_user_command(self, command):
        """

        :param command:
        :type command: str
        :return:
        """
        command = command.lower()
        if command.startswith("register"):
            if self.registered:
                self.print_function(
                    "You have been registered before and F**K KHAJE POOR")
            else:
                register_req_packet = PacketFactory.new_register_packet(
                    type='REQ',
                    source_server_address=self.server_address,
                    address=self.root_address)
                # Adding root node to peer's stream
                self.stream.add_node(server_address=self.root_address,
                                     set_register_connection=True)
                self.stream.add_message_to_out_buff(
                    address=self.root_address, message=register_req_packet.buf)
                self.print_function("{} sent register request".format(
                    self.server_address))
        elif command.startswith("advertise"):
            if not self.registered:
                self.print_function(
                    "{} must register first to advertise".format(
                        str(self.server_address)))
            elif self.advertised:
                self.print_function("You have advertised before")
            else:
                advertise_req_packet = PacketFactory.new_advertise_packet(
                    type='REQ', source_server_address=self.server_address)
                self.stream.add_message_to_out_buff(
                    address=self.root_address,
                    message=advertise_req_packet.buf)
                self.print_function("{} sent advertise packet".format(
                    str(self.server_address)))

        elif command.startswith("message"):
            if self.joined:
                message = command[8:]
                broadcast_message_packet = PacketFactory.new_message_packet(
                    message=message, source_server_address=self.server_address)
                self.print_function("{} is broadcasting message: {}".format(
                    str(self.server_address), message))
                self.send_broadcast_packet(broadcast_message_packet,
                                           "F**K KHAJE POOR")
            else:
                self.print_function(
                    "You must join the network before broadcasting a message")
        elif command.startswith('disconnect'):
            self.running = False
        else:
            self.print_function("Unknown command received: {}".format(command))
Beispiel #7
0
    def __init__(self,
                 server_ip,
                 server_port,
                 is_root=False,
                 root_address=None):
        """
        The Peer object constructor.

        Code design suggestions:
            1. Initialise a Stream object for our Peer.
            2. Initialise a PacketFactory object.
            3. Initialise our UserInterface for interaction with user commandline.
            4. Initialise a Thread for handling reunion daemon.

        Warnings:
            1. For root Peer, we need a NetworkGraph object.
            2. In root Peer, start reunion daemon as soon as possible.
            3. In client Peer, we need to connect to the root of the network, Don't forget to set this connection
               as a register_connection.


        :param server_ip: Server IP address for this Peer that should be pass to Stream.
        :param server_port: Server Port address for this Peer that should be pass to Stream.
        :param is_root: Specify that is this Peer root or not.
        :param root_address: Root IP/Port address if we are a client.

        :type server_ip: str
        :type server_port: int
        :type is_root: bool
        :type root_address: tuple
        """
        #   self.root_address = (SemiNode.parse_ip(root_address[0]),SemiNode.parse_port(root_address[1]))
        self.root_address = root_address
        self.stream = Stream(server_ip, server_port)
        self.packet_factory = PacketFactory()
        self.user_interfarce = UserInterface()
        self.server_ip = SemiNode.parse_ip(server_ip)
        self.server_port = SemiNode.parse_port(str(server_port))
        self.is_root = is_root
        self.flag = False
        # self.root_address = (SemiNode.parse_ip(root_address[0]), SemiNode.parse_port(root_address[1]))

        self.neighbours = []
        if self.is_root:
            print("from root in init")
            self.root_node = GraphNode(self.stream.get_server_address())
            self.network_graph = NetworkGraph(self.root_node)
            self.reunions_arrival_time = dict()
        else:
            print("from peer in init")
            self.stream.add_node(root_address, set_register_connection=True)
            #  self.graph_node = GraphNode((server_ip, server_port))
            self.reunion_mode = None
            self.last_reunion_sent_time = None
        self.t = threading.Thread(target=self.run_reunion_daemon)
Beispiel #8
0
    def __handle_advertise_packet(self, packet):
        """
		For advertising peers in the network, It is peer discovery message.

		Request:
			We should act as the root of the network and reply with a neighbour address in a new Advertise Response packet.

		Response:
			When an Advertise Response packet type arrived we should update our parent peer and send a Join packet to the
			new parent.

		Code design suggestion:
			1. Start the Reunion daemon thread when the first Advertise Response packet received.
			2. When an Advertise Response message arrived, make a new Join packet immediately for the advertised address.

		Warnings:
			1. Don't forget to ignore Advertise Request packets when you are a non-root peer.
			2. The addresses which still haven't registered to the network can not request any peer discovery message.
			3. Maybe it's not the first time that the source of the packet sends Advertise Request message. This will happen
			   in rare situations like Reunion Failure. Pay attention, don't advertise the address to the packet sender
			   sub-tree.
			4. When an Advertise Response packet arrived update our Peer parent for sending Reunion Packets.

		:param packet: Arrived register packet

		:type packet Packet

		:return:
		"""
        if self.is_root:
            sender_address = packet.get_source_server_address()
            neighbour = self.__get_neighbour(sender_address)
            self.network_graph.add_node(sender_address[0], sender_address[1],
                                        neighbour.address)
            print("Someone has requested a neighbour")
            print(
                f'gave {neighbour.address} to {sender_address} as a neighbour')
            if self.__check_registered(
                    sender_address) and neighbour is not None:
                adv_packet = PacketFactory.new_advertise_packet(
                    "RES", self.address, neighbour=neighbour.address)
                self.send_packet(adv_packet, sender_address)
        elif packet.body.startswith('RES'):
            reunion_thread = threading.Thread(target=self.run_reunion_daemon)
            reunion_thread.start()
            join_pckt = PacketFactory.new_join_packet(self.address)
            self.client_predecessor_address = (packet.body[-20:-5],
                                               packet.body[-5:])
            print("I've found a father! " +
                  str(self.client_predecessor_address))
            self.stream.add_node(self.client_predecessor_address)
            self.send_packet(join_pckt, self.client_predecessor_address)
            self.is_client_connected = True
        else:
            return
Beispiel #9
0
    def __handle_reunion_packet_client(self, packet):
        body = packet.get_body()
        if not self.joined:
            self.print_function(
                "{} has no parent to redirect reunion request to".format(
                    self.server_address))
            return
        if body[:3] == "REQ":
            nodes_address_list = []
            n_nodes = int(body[3:5])
            for i in range(n_nodes):
                ip = body[5 + 20 * i:5 + 15 + 20 * i]
                port = body[20 + 20 * i:20 + 5 + 20 * i]
                nodes_address_list.append((ip, port))
            reunion_sender_node = self.graph.find_node(
                nodes_address_list[0][0], nodes_address_list[0][1])
            nodes_address_list.append(self.server_address)
            reunion_response_packet = PacketFactory.new_reunion_packet(
                type="REQ",
                source_address=self.server_address,
                nodes_array=nodes_address_list)
            self.stream.add_message_to_out_buff(
                self.parent_address, message=reunion_response_packet.buf)
            self.print_function(
                "{} received Reunion from {} and reunion request sent to parent"
                .format(str(self.server_address), str(reunion_sender_node)))
        else:
            n_nodes = int(body[3:5])
            if n_nodes == 1:
                target_ip = body[5:20]
                target_port = body[20:25]
                if (target_ip, target_port) == self.server_address:
                    self.reunion_on_fly = False
                    self.reunion_timer = 4 * 10
            else:
                nodes_address_list = []
                n_nodes = int(body[3:5])
                for i in range(1, n_nodes):
                    nodes_address_list.append((body[5 + 20 * i:20 + 20 * i],
                                               body[20 + 20 * i:25 + 20 * i]))

                reunion_response_packet = PacketFactory.new_reunion_packet(
                    type='RES',
                    source_address=self.server_address,
                    nodes_array=nodes_address_list)
                target_ip = body[25:40]
                target_port = body[40:45]
                target_address = (target_ip, target_port)
                self.stream.add_message_to_out_buff(
                    target_address, reunion_response_packet.buf)
                self.print_function(
                    "{} redirected reunion response to {}".format(
                        self.server_address, target_address))
Beispiel #10
0
    def __init__(self, server_ip, server_port, is_root=False, root_address=None, gui=False, interface=None):
        """
        The Peer object constructor.

        Code design suggestions:
            1. Initialise a Stream object for our Peer.
            2. Initialise a PacketFactory object.
            3. Initialise our UserInterface for interaction with user commandline.
            4. Initialise a Thread for handling reunion daemon.

        Warnings:
            1. For root Peer, we need a NetworkGraph object.
            2. In root Peer, start reunion daemon as soon as possible.
            3. In client Peer, we need to connect to the root of the network, Don't forget to set this connection
               as a register_connection.


        :param server_ip: Server IP address for this Peer that should be pass to Stream.
        :param server_port: Server Port address for this Peer that should be pass to Stream.
        :param is_root: Specify that is this Peer root or not.
        :param root_address: Root IP/Port address if we are a client.

        :type server_ip: str
        :type server_port: int
        :type is_root: bool
        :type root_address: tuple
        """
        self.has_gui = gui

        self.ip = Node.parse_ip(server_ip)
        self.port = server_port
        self.stream = Stream(server_ip, server_port)
        self.packet_factory = PacketFactory()

        self.interface = interface
        self.parse_interface_thread = threading.Thread(target=self.handle_user_interface_buffer, daemon=True)

        self.is_root = is_root
        self.root_address = root_address
        self.reunion_daemon = threading.Thread(target=self.run_reunion_daemon, daemon=True)
        if is_root:
            root_node = GraphNode((server_ip, server_port))
            self.network_graph = NetworkGraph(root_node)

        if not is_root:
            try:
                self.stream.add_node(root_address, True)
            except LostConnection as lc:
                print("Couldn't connect to root")
            self.father_address = None
            self.send_reunion_timer = 4
            self.last_reunion_back = 0
            self.is_alive = False
    def run(self):
        """
        The main loop of the program.

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

        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.
            2. In every situation checkout Advertise Response packets; even is Reunion in failure mode or not

        :return:
        """
        try:
            while True:
                in_buff = self.stream.read_in_buf()
                for message in in_buff:
                    packet = PacketFactory.parse_buffer(message)
                    self.handle_packet(packet)
                self.stream.clear_in_buff()
                self.handle_user_interface_buffer()
                self.stream.send_out_buf_messages(
                    self.reunion_mode == ReunionMode.FAILED)
                time.sleep(2)
        except KeyboardInterrupt:
            log('KeyboardInterrupt')
            try:
                sys.exit(0)
            except SystemExit:
                os._exit(0)
Beispiel #12
0
    def __handle_message_packet(self, 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:
        """
        if not self.child_or_parent(packet.get_source_server_address()):
            return
        message = packet.get_body()
        self.ui.display_message('Broadcast Message: ' + message)
        res_pkt = PacketFactory.new_message_packet(message, self.address)
        print('trying to send packet to:')
        for address in self.children:
            if not self.address_equal(address,
                                      packet.get_source_server_address()):
                self.stream.add_message_to_out_buff(address, res_pkt)
                print(address)
        if (not self.is_root) and (self.parent is not Node):
            if self.address_equal(self.parent,
                                  packet.get_source_server_address()):
                return
            print(self.parent)
            self.stream.add_message_to_out_buff(self.parent, res_pkt)
    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)
Beispiel #14
0
    def __handle_message_packet(self, 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:
        """
        source_address = packet.get_source_server_address()
        if self.__check_neighbour(source_address):
            self.print_function("{} received broadcast message: {}".format(
                self.server_address, packet.get_body()))
            broadcast_message_packet = PacketFactory.new_message_packet(
                message=packet.get_body(),
                source_server_address=self.server_address)
            self.send_broadcast_packet(broadcast_message_packet,
                                       exclude_address=source_address)
        else:
            self.print_function(
                "Broadcast packet received from KHAJE POOR. wut??")
Beispiel #15
0
    def __handle_reunion_packet_root(self, packet):
        body = packet.get_body()
        if body[:3] == "REQ":
            packet_source_address = packet.get_source_server_address()
            if self.graph.find_node(packet_source_address[0],
                                    packet_source_address[1]) is None:
                self.print_function(
                    "Root received reunion from {} which is not in graph".
                    format(packet_source_address))
            nodes_address_list = []
            n_nodes = int(body[3:5])
            for i in range(n_nodes):
                ip = body[5 + 20 * i:5 + 15 + 20 * i]
                port = body[20 + 20 * i:20 + 5 + 20 * i]
                nodes_address_list.append((ip, port))
            reunion_sender_node = self.graph.find_node(
                nodes_address_list[0][0], nodes_address_list[0][1])
            self.print_function(
                "Root received Reunion from {} and reunion response sent".
                format(str(reunion_sender_node)))
            nodes_address_list.reverse()
            reunion_sender_node.reunion_timer = 0
            reunion_response_packet = PacketFactory.new_reunion_packet(
                type="RES",
                source_address=self.root_address,
                nodes_array=nodes_address_list)
            self.stream.add_message_to_out_buff(
                packet_source_address, message=reunion_response_packet.buf)

        else:
            self.print_function(
                "Root received reunion response. Wtf? F**K KHAJE POOR")
 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_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.')
Beispiel #18
0
 def __handle_advertise_packet_root(self, packet):
     if packet.get_body()[:3] == "REQ":
         packet_source_address = packet.get_source_server_address()
         if not self.__check_registered(packet_source_address):
             self.print_function(
                 "Advertise request received from unregistered client {}".
                 format(str(packet_source_address)))
         else:
             if self.graph.find_node(packet_source_address[0],
                                     packet_source_address[1]) is not None:
                 self.print_function(
                     "Advertise request received from a client in graph {}".
                     format(str(packet_source_address)))
             else:
                 father_node = self.graph.find_live_node("F**K KHAJE POOR")
                 print("Father found", father_node.address)
                 self.graph.add_node(ip=packet_source_address[0],
                                     port=packet_source_address[1],
                                     father_address=father_node.address)
                 self.graph.turn_on_node(packet_source_address)
                 register_response_packet = PacketFactory.new_advertise_packet(
                     type='RES',
                     source_server_address=self.server_address,
                     neighbour=father_node.address)
                 self.stream.add_message_to_out_buff(
                     address=packet_source_address,
                     message=register_response_packet.buf)
                 self.registered_peers_address[packet_source_address] = 1
                 self.print_function(
                     "Advertise request received from {} and register response sent"
                     .format(packet_source_address))
     else:
         self.print_function(
             "Root received advertise response. Wtf? F**K KHAJE POOR")
Beispiel #19
0
 def send_register(self):
     if not self.is_root:
         pkt = PacketFactory.new_register_packet('REQ', self.address,
                                                 self.address)
         # self.ui.display_pkt(PacketFactory.parse_buffer(pkt))
         self.stream.add_message_to_out_buff(self.root_address, pkt)
     pass
Beispiel #20
0
 def send_reunion(self):
     if not self.is_connected:
         return
     pkt = PacketFactory.new_reunion_packet('REQ', self.address,
                                            [self.address])
     self.stream.add_message_to_out_buff(self.parent, pkt)
     self.since_last = 0
     self.r_h_b_received = False
 def handle_advertise_command(self) -> None:
     advertise_packet = PacketFactory.new_advertise_packet(
         AdvertiseType.REQ, self.address)
     self.stream.add_message_to_out_buff(self.root_address,
                                         advertise_packet,
                                         want_register=True)
     log(f'Advertise packet added to out buff of Node({self.root_address}).'
         )
 def __register(self) -> None:
     if self.stream.add_node(self.root_address,
                             set_register_connection=True):
         register_packet = PacketFactory.new_register_packet(
             RegisterType.REQ, self.address)
         self.stream.add_message_to_out_buff(self.root_address,
                                             register_packet,
                                             want_register=True)
         log(f'Register packet added to out buff of Node({self.root_address}).'
             )
Beispiel #23
0
    def read_stream_in_buffer(self):
        buffers = self.stream.read_in_buf()
        for buffer in buffers:
            print(buffer)
            packet = PacketFactory.parse_buffer(buffer)
            if packet is None:
                continue
            if packet.length + 20 != len(buffer):
                continue
            self.handle_packet(packet)

        self.stream.clear_in_buff()
Beispiel #24
0
 def send_message(self, s):
     if not self.is_connected:
         return
     print('sending mesaage to:')
     pkt = PacketFactory.new_message_packet(s, self.address)
     for address in self.children:
         print(address)
         self.stream.add_message_to_out_buff(address, pkt)
     if not (self.is_root) and (self.address is not None):
         print(self.parent)
         self.stream.add_message_to_out_buff(self.parent, pkt)
     pass
 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 __run_non_root_reunion_daemon(self):
     time_between_last_hello_and_last_hello_back = self.last_hello_time - self.last_hello_back_time
     log(f'Time between last hello and last hello back: {time_between_last_hello_and_last_hello_back}'
         )
     if self.last_hello_time - self.last_hello_back_time > MAX_PENDING_TIME:
         log('Seems like we are disconnected from the root. Trying to reconnect...'
             )
         self.reunion_mode = ReunionMode.FAILED
         self.__handle_advertise_command()  # Send new Advertise packet
         time.sleep(3)
     else:
         log(f'Sending new Reunion Hello packet.')
         packet = PacketFactory.new_reunion_packet(ReunionType.REQ,
                                                   self.address,
                                                   [self.address])
         self.stream.add_message_to_out_buff(self.parent_address, packet)
         self.last_hello_time = time.time()
 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)
Beispiel #28
0
    def __handle_advertise_packet_client(self, packet):
        if packet.get_body()[:3] == 'RES':
            parent_address = (packet.get_body()[3:18],
                              packet.get_body()[18:23])

            self.advertised = True
            if parent_address != self.root_address:
                self.stream.add_node(server_address=parent_address,
                                     set_register_connection=False)
            join_packet = PacketFactory.new_join_packet(
                source_server_address=self.server_address)
            self.stream.add_message_to_out_buff(address=parent_address,
                                                message=join_packet.buf)
            self.parent_address = parent_address
            self.joined = True
            self.print_function(
                "Advertise response received from root. Client {} sent join request to {}"
                .format(str(self.server_address), str(parent_address)))
        else:
            self.print_function(
                "Client received advertise request. Wtf? F**K KHAJE POOR")
Beispiel #29
0
 def __handle_register_packet_root(self, packet):
     if packet.get_body()[:3] == "REQ":
         packet_source_address = packet.get_source_server_address()
         if self.__check_registered(packet_source_address):
             self.print_function(
                 "Duplicate register request received from {}".format(
                     str(packet_source_address)))
         else:
             self.stream.add_node(server_address=packet_source_address,
                                  set_register_connection=True)
             register_response_packet = PacketFactory.new_register_packet(
                 type='RES', source_server_address=self.server_address)
             self.stream.add_message_to_out_buff(
                 address=packet.get_source_server_address(),
                 message=register_response_packet.buf)
             self.registered_peers_address[packet_source_address] = 1
             self.print_function(
                 "Register request received from {} and register response sent"
                 .format(packet_source_address))
     else:
         self.print_function(
             "Root received register response. Wtf? F**K KHAJE POOR")
Beispiel #30
0
    def __handle_register_packet(self, 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:
        """
        source_address = (packet.sender_ip, packet.sender_port)
        if self.is_root and (not self.__check_registered(source_address)):
            self.graph.register(source_address)
            self.stream.add_node(source_address, True)
            res_pkt = PacketFactory.new_register_packet('RES', self.address)
            self.stream.add_message_to_out_buff(source_address, res_pkt)
        pass