Example #1
0
    def deserialise(stream):
        # Read target instance
        instance = InstanceReference.deserialise(stream)

        # Read TTL and number of instances
        ttl, blacklist_count = struct.unpack("!BB", stream.read(2))

        # Return query
        return PathQuery(instance, ttl - 1, [InstanceReference.deserialise(stream) for x in range(blacklist_count)])
Example #2
0
    def __mcast_listen(self):
        while True:
            # Receive the next discovery datagram
            datagram, sender = self.__mcast_socket.recvfrom(InstanceReference.SERIALISED_SIZE + 16)

            if(datagram[:14] != b"LibPeer2-IPv4:"):
                continue

            # Get advertised port number
            port = struct.unpack("!H", datagram[14:16])[0]

            # Create peer info
            info = IPv4PeerInfo(sender[0], port)

            # Create the instance reference
            instance_reference = InstanceReference.deserialise(BytesIO(datagram[16:]))

            # Is the instance one we advertise?
            if(instance_reference in self.__advertised_instances):
                # Yes, skip
                continue

            # Create the advertisement
            advertisement = Advertisement(instance_reference, info)

            # Send to the application
            self.incoming_advertisment.on_next(advertisement)
Example #3
0
    def deserialise(stream):
        # Read number of instances
        count = struct.unpack("!B", stream.read(1))[0]

        # Return announcement
        return Announcement(
            [InstanceReference.deserialise(stream) for x in range(count)])
Example #4
0
    def __init__(self, raw_frame: bytes):
        self.__raw_frame = raw_frame

        # Read stream copy to get information
        stream = self.to_stream()

        # Check magic number
        if (stream.read(len(Frame.MAGIC_NUMBER)) != Frame.MAGIC_NUMBER):
            raise Exception(
                "Provided raw frame does not start with magic number")

        # Get frame destination
        self.target = InstanceReference.deserialise(stream)

        # Get frame origin
        self.origin = InstanceReference.deserialise(stream)

        # Get path info
        self.via = PathInfo.deserialise(stream)
Example #5
0
    def deserialise(stream):
        # Read instance
        instance = InstanceReference.deserialise(stream)

        # Read flags
        flags = struct.unpack("!B", stream.read(1))[0]

        # Read peer info
        info = PeerInfo.deserialise(stream)

        # Return query
        return PathNode(instance, flags, info)
Example #6
0
    def deserialise(stream, instances: Dict[InstanceReference, Instance]):
        # Does the stream start with the magic number?
        magic = stream.read(len(Frame.MAGIC_NUMBER))
        if (magic != Frame.MAGIC_NUMBER):
            # Raise an error
            raise IOError(
                "Stream did not start with frame magic number: {}".format(
                    str(magic)))

        # Read the destination
        destination = InstanceReference.deserialise(stream)

        # Read the origin
        origin = InstanceReference.deserialise(stream)

        # Do we have an instance matching the destination of this packet?
        if (destination not in instances):
            # Raise an error
            raise IOError(
                "Received frame does not belong to any current instances")

        # Read the via field
        via = PathInfo.deserialise(stream)

        # The remainder of the stream is the encrypted payload
        encrypted = stream.read()

        # Create a sealed box for decryption
        box = SealedBox(instances[destination].private_key)

        # Decrypt the message
        signed = box.decrypt(encrypted)

        # Read the payload into a buffer
        payload = BytesIO(origin.verification_key.verify(signed))

        # Create the object
        return Frame(destination, origin, via, payload), instances[destination]
Example #7
0
    def advertise(self, instance_reference: InstanceReference):
        # Prepare a message
        message = b"LibPeer2-IPv4:"

        # Write our port number
        message += struct.pack("!H", self.__port)

        # Write the instance reference
        message += instance_reference.serialise().read()

        # Send the message
        self.__mcast_socket.sendto(message, ("224.0.0.3", 1199))

        # Save the advertised instance
        self.__advertised_instances.add(instance_reference)
Example #8
0
    def deserialise(data):
        buffer = BytesIO(data)

        # Read the instance reference
        instance_reference = InstanceReference.deserialise(buffer)

        # Read number of connection methods
        method_count = struct.unpack("!B", buffer.read(1))[0]

        # Read connection methods
        methods = []
        for i in range(method_count):
            methods.append(PeerInfo.deserialise(buffer))

        # Return new InstanceInformation object
        return InstanceInformation(instance_reference, methods)
Example #9
0
    def __listen(self):
        while True:
            try:
                # Receive the next datagram
                datagram, sender = self.__socket.recvfrom(65536)

                # Put the datagram into a buffer
                buffer = BytesIO(datagram)

                # Create peer info
                info = IPv4PeerInfo(sender[0], sender[1])

                # Read the datagram type
                dgram_type = buffer.read(1)

                # Regular data packet
                if(dgram_type == DGRAM_DATA):                    
                    # Create a new receiption
                    receiption = Receiption(buffer, info, self)

                    # Pass up
                    self.incoming_receiption.on_next(receiption)

                elif(dgram_type == DGRAM_INQUIRE):
                    # Respond with instance information
                    for instance in self.__advertised_instances:
                        # Send the instance information as a single datagram
                        self.__socket.sendto(DGRAM_INSTANCE + instance.serialise().read(), sender)

                elif(dgram_type == DGRAM_INSTANCE):
                    # Create the instance reference
                    instance_reference = InstanceReference.deserialise(buffer)

                    # Is the instance one we advertise?
                    if(instance_reference in self.__advertised_instances):
                        # Yes, skip
                        continue

                    # Create the advertisement
                    advertisement = Advertisement(instance_reference, info)

                    # Send to the application
                    self.incoming_advertisment.on_next(advertisement)

            except Exception as e:
                Log.error("Exception on incoming packet: {}".format(e))
Example #10
0
    def deserialise(stream):
        # Read the identifier
        identifier = stream.read(16)

        # Get the header
        header = stream.read(5)

        # Unpack
        hops, max_replies, data_len, return_path_size = struct.unpack("!BBHB", header)

        # Initialise the return path array
        return_path = []

        # Deserialise the return path
        for i in range(return_path_size):
            return_path.append(InstanceReference.deserialise(stream))

        # Read the query data
        data = stream.read(data_len)

        # Return the object
        return Query(data, max_replies, hops, return_path, identifier)
Example #11
0
    def deserialise(stream):
        # What is this in reply to?
        in_reply_to = stream.read(16)

        # Get the header
        header = stream.read(5)

        # Unpack
        data_len, path_size = struct.unpack("!LB", header)

        # Initialise the path array
        path = []

        # Deserialise the return path
        for i in range(path_size):
            path.append(InstanceReference.deserialise(stream))

        # Read the query data
        data = stream.read(data_len)

        # Return the object
        return Answer(data, path, in_reply_to)
Example #12
0
 def deserialise(stream):
     count = struct.unpack("!B", stream.read(1))[0]
     repeaters = [InstanceReference.deserialise(stream) for i in range(count)]
     return PathInfo(repeaters)
Example #13
0
 def reference(self) -> InstanceReference:
     return InstanceReference(self.signing_key.verify_key,
                              self.private_key.public_key)