예제 #1
0
    def validate_config_section(self):
        """
        Validate the interface information
        """

        try:
            socket.if_nametoindex(self.name)
        except OSError:
            raise ValueError("Interface {} not found".format(self.name))

        interface_addresses = [
            IPv6Address(addr_info['addr'].split('%')[0])
            for addr_info in netifaces.ifaddresses(self.name).get(
                netifaces.AF_INET6, [])
        ]

        # Pick the first link-local address as reply-from if none is specified in the configuration
        if not self.section.reply_from:
            for address in interface_addresses:
                if address.is_link_local:
                    self.section.reply_from = address
                    break

            if not self.section.reply_from:
                raise ValueError(
                    "No link-local address found on interface {}".format(
                        self.name))

        else:
            # Validate what the user supplied
            if not self.section.reply_from.is_link_local:
                raise ValueError(
                    "The reply-from address must be a link-local address")

            if self.section.reply_from not in interface_addresses:
                raise ValueError(
                    "Cannot find reply-from address {} on interface {}".format(
                        self.section.reply_from, self.name))

        # Pick the first global unicast address as link-address if none is specified in the configuration
        if not self.section.link_address:
            for address in interface_addresses:
                if is_global_unicast(address):
                    self.section.link_address = address
                    break

            if not self.section.link_address:
                # Use the unspecified address is we couldn't find anything
                self.section.link_address = IPv6Address('::')

        else:
            # Validate what the user supplied (we don't really care if it exists, it's just extra information for the
            # option handlers
            if not is_global_unicast(self.section.link_address):
                raise ValueError(
                    "The link-address must be a global unicast address")
예제 #2
0
    def validate_config_section(self):
        """
        Validate the interface information
        """

        try:
            socket.if_nametoindex(self.name)
        except OSError:
            raise ValueError("Interface {} not found".format(self.name))

        interface_addresses = [IPv6Address(addr_info['addr'].split('%')[0])
                               for addr_info
                               in netifaces.ifaddresses(self.name).get(netifaces.AF_INET6, [])]

        # Pick the first link-local address as reply-from if none is specified in the configuration
        if not self.section.reply_from:
            for address in interface_addresses:
                if address.is_link_local:
                    self.section.reply_from = address
                    break

            if not self.section.reply_from:
                raise ValueError("No link-local address found on interface {}".format(self.name))

        else:
            # Validate what the user supplied
            if not self.section.reply_from.is_link_local:
                raise ValueError("The reply-from address must be a link-local address")

            if self.section.reply_from not in interface_addresses:
                raise ValueError("Cannot find reply-from address {} on interface {}".format(self.section.reply_from,
                                                                                            self.name))

        # Pick the first global unicast address as link-address if none is specified in the configuration
        if not self.section.link_address:
            for address in interface_addresses:
                if is_global_unicast(address):
                    self.section.link_address = address
                    break

            if not self.section.link_address:
                # Use the unspecified address is we couldn't find anything
                self.section.link_address = IPv6Address('::')

        else:
            # Validate what the user supplied (we don't really care if it exists, it's just extra information for the
            # option handlers
            if not is_global_unicast(self.section.link_address):
                raise ValueError("The link-address must be a global unicast address")
예제 #3
0
 def test_is_global_unicast(self):
     self.assertTrue(is_global_unicast(IPv6Address('2001:db8::1')))
     self.assertTrue(is_global_unicast(IPv6Address('fc00::1')))
     self.assertTrue(is_global_unicast(IPv6Address('fd00::1')))
     self.assertTrue(is_global_unicast(IPv6Address('dead::beef')))
     self.assertFalse(is_global_unicast(IPv6Address('::')))
     self.assertFalse(is_global_unicast(IPv6Address('::1')))
     self.assertFalse(is_global_unicast(IPv6Address('fe80::1')))
     self.assertFalse(is_global_unicast(IPv6Address('ff02::1')))
예제 #4
0
 def test_is_global_unicast(self):
     self.assertTrue(is_global_unicast(IPv6Address('2001:db8::1')))
     self.assertTrue(is_global_unicast(IPv6Address('fc00::1')))
     self.assertTrue(is_global_unicast(IPv6Address('fd00::1')))
     self.assertTrue(is_global_unicast(IPv6Address('dead::beef')))
     self.assertFalse(is_global_unicast(IPv6Address('::')))
     self.assertFalse(is_global_unicast(IPv6Address('::1')))
     self.assertFalse(is_global_unicast(IPv6Address('fe80::1')))
     self.assertFalse(is_global_unicast(IPv6Address('ff02::1')))
예제 #5
0
    def __init__(self, interface_name: str, listen_socket: socket.socket, global_address: IPv6Address = None,
                 marks: Iterable[str] = None, max_connections: int = 10, allow_from: Iterable[IPv6Network] = None):
        """
        Initialise TCP listener.

        :param interface_name: The name of the interface
        :param listen_socket: The socket we are listening on, may be a unicast or multicast socket
        :param global_address: The global address on the listening interface
        :param marks: Marks attached to this listener
        """
        self.interface_name = interface_name
        self.interface_id = interface_name.encode('utf-8')
        self.marks = list(marks or [])
        self.max_connections = max_connections
        self.allow_from = list(allow_from or [])

        # Make sure the listening socket is non-blocking
        self.listen_socket = listen_socket
        self.listen_socket.setblocking(False)

        # Check that we have IPv6 TCP sockets
        if self.listen_socket.family != socket.AF_INET6 or self.listen_socket.proto != socket.IPPROTO_TCP:
            raise ListeningSocketError("TCP Listen sockets have to be IPv6 TCP sockets")

        listen_sockname = self.listen_socket.getsockname()

        # Check that we are on the right port
        if listen_sockname[1] != SERVER_PORT:
            raise ListeningSocketError("TCP Listen sockets have to be on port {}".format(SERVER_PORT))

        self.interface_index = listen_sockname[3]
        self.listen_address = IPv6Address(listen_sockname[0].split('%')[0])

        if global_address:
            self.global_address = global_address
        elif is_global_unicast(self.listen_address):
            self.global_address = self.listen_address
        else:
            raise ListeningSocketError("Cannot determine global address on interface {}".format(self.interface_name))

        # We only support fixed address binding
        if self.listen_address.is_unspecified:
            raise ListeningSocketError("This server only supports listening on explicit address, not on wildcard")

        # Create a manager for the locks
        self.manager = multiprocessing.Manager()

        # Keep weak references to sockets so we can see how many are still alive
        self.open_sockets = weakref.WeakSet()
예제 #6
0
    def validate_config_section(self):
        """
        Validate the interface information
        """
        # Validate what the user supplied
        if not is_global_unicast(self.name):
            raise ValueError("The listener address must be a global unicast address")

        for interface_name in netifaces.interfaces():
            interface_addresses = [IPv6Address(addr_info['addr'].split('%')[0])
                                   for addr_info
                                   in netifaces.ifaddresses(interface_name).get(netifaces.AF_INET6, [])]

            if self.name in interface_addresses:
                self.found_interface = interface_name
                break

        if not self.found_interface:
            raise ValueError("Cannot find address {} on any interface".format(self.name))
예제 #7
0
    def validate_config_section(self):
        """
        Validate the interface information
        """
        # Validate what the user supplied
        if not is_global_unicast(self.name) and self.name != IPv6Address('::1'):
            raise ValueError("The listener address must be a global unicast address")

        for interface_name in netifaces.interfaces():
            interface_addresses = [IPv6Address(addr_info['addr'].split('%')[0])
                                   for addr_info
                                   in netifaces.ifaddresses(interface_name).get(netifaces.AF_INET6, [])]

            if self.name in interface_addresses:
                self.found_interface = interface_name
                break

        if not self.found_interface:
            raise ValueError("Cannot find address {} on any interface".format(self.name))