コード例 #1
0
    def new_register_packet(type, source_server_address, address=(None, None)) -> Packet:
        """
        :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
        """
        if type not in (Packet.REQUEST, Packet.RESPONSE):
            raise ValueError("invalid type")

        if type == Packet.REQUEST:
            if not address:
                raise ValueError("address must be set in request")

            body = Packet.REQUEST + Node.parse_ip(address[0]) + Node.parse_port(address[1])

        else:
            body = Packet.RESPONSE + Packet.ACK

        return Packet(1, Packet.TYPE_REGISTER, *source_server_address, body)
コード例 #2
0
    def new_advertise_packet(type, source_server_address, neighbour: tuple=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

        """
        if type not in (Packet.REQUEST, Packet.RESPONSE):
            raise ValueError("invalid type")

        if type == Packet.REQUEST:
            body = Packet.REQUEST
        else:
            if not neighbour:
                raise ValueError("neighbour should provided for response")

            body = Packet.RESPONSE + Node.parse_ip(neighbour[0]) + Node.parse_port(neighbour[1])

        return Packet(1, Packet.TYPE_ADVERTISE, *source_server_address, body)
コード例 #3
0
    def new_reunion_packet(type, source_address, 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
        """

        if type not in (Packet.REQUEST, Packet.RESPONSE):
            raise ValueError("invalid type")

        if len(nodes_array) > 99:
            raise ValueError("too long nodes_array")

        entities = []

        for ip, port in nodes_array:
            entities.append(Node.parse_ip(ip))
            entities.append(Node.parse_port(port))

        body = type + str(len(nodes_array)).zfill(2) + ''.join(entities)

        return Packet(1, Packet.TYPE_REUNION, *source_address, body)
コード例 #4
0
    def get_source_server_ip(self):
        """

        :return: Server IP address for the sender of the packet.
        :rtype: str
        """
        return Node.parse_ip(self.source_server_ip)
コード例 #5
0
ファイル: Stream.py プロジェクト: vdblm/CN_Project
    def get_node_by_server(self, ip, port, is_register=False):
        """

        Will find the node that has IP/Port address of input.

        Warnings:
            1. Before comparing the address parse it to a standard format with Node.parse_### functions.

        :param ip: input address IP
        :param port: input address Port
        :param is_register: if the node is register node

        :return: The node that input address.
        :rtype: Node

        """

        node_address = (Node.parse_ip(ip), Node.parse_port(port))
        if is_register:
            node = self.register_nodes.get(node_address)
        else:
            node = self.nodes.get(node_address)
        # if node is None:
        #     logging.warning(
        #         'node does not exit, node: ' + str(node_address) + ' stream address: ' + str(self.get_server_address()))
        return node
コード例 #6
0
ファイル: Stream.py プロジェクト: vdblm/CN_Project
    def __init__(self, ip, port):
        """
        The Stream object constructor.

        Code design suggestion:
            1. Make a separate Thread for your TCPServer and start immediately.


        :param ip: 15 characters
        :param port: 5 characters
        """

        ip = Node.parse_ip(ip)
        port = Node.parse_port(port)

        self.server_address = (ip, port)
        self._server_in_buf = []

        # Dict for nodes {address: node object} and register nodes
        # address is (ip, port)
        self.nodes = {}
        self.register_nodes = {}

        def callback(address, queue, data):
            """
            The callback function will run when a new data received from server_buffer.

            :param address: Source address.
            :param queue: Response queue.
            :param data: The data received from the socket.
            :return:
            """
            queue.put(bytes('ACK', 'utf8'))
            self._server_in_buf.append(data)

        server = TCPServer(ip, int(port), callback)

        tcp = threading.Thread(target=server.run)
        tcp.start()
コード例 #7
0
    def parse_buffer(buf):
        """
        In this function we will make a new Packet from input buffer with struct class methods.

        :param buf: The buffer that should be parse to a validate packet format

        :return new packet
        :rtype: Packet

        """
        try:
            version = buf[0:2]
            typ = buf[2:4]
            length = buf[4:8]
            ip = buf[8:16]
            port = buf[16:20]
            body = buf[20:]
            version = unpack_from('>H', version)[0]
            type = unpack_from('>H', typ)[0]
            length = unpack_from('>I', length)[0]
            ip_tuple = unpack_from('>HHHH', ip)
            ip = ""
            for t in ip_tuple:
                ip += '.' + str(t)
            ip = ip[1:]
            port = str(unpack_from('>I', port)[0])
            ip = Node.parse_ip(ip)
            port = Node.parse_port(port)
            body = body.decode("utf-8")

            pck = [version, type, length, ip, port, body]

            return Packet(pck)
        except:
            # any error means the packet's format was wrong
            logging.warning('received packet format was wrong')
            return None
コード例 #8
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.stream = Stream(server_ip, server_port)

        self.packet_factory = PacketFactory()

        self.user_interface = UserInterface()
        self.start_user_interface()

        self.is_root = is_root
        self.address = self.stream.get_server_address()
        if is_root:
            self.root_address = self.address
        else:
            self.root_address = (Node.parse_ip(root_address[0]),
                                 Node.parse_port(root_address[1]))

        self.parent_address = None

        self.reunion_daemon = threading.Thread(target=self.run_reunion_daemon)
        if is_root:
            # dict, {peer_address: time}
            self.peer_last_reunion_hello_time = {}
            self.network_graph = NetworkGraph(self.address)
            self.reunion_daemon.start()

        else:
            self.last_sent_reunion_time = None
            self.reunion_mode = 'accept'
            # the maximum depth is 8
            self.time_interval = 8 * 2 * 2 + 4
            self.reunion_failed = False
            self.first_advertise_response = True
コード例 #9
0
def parse_address(address: str) -> tuple:
    return Node.parse_ip(address[:15]), Node.parse_port(address[15:])