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")
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")
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')))
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()
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))
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))