diff --git a/src/calibre/gui2/actions/device.py b/src/calibre/gui2/actions/device.py index 9b406ec4bc..43d59a4a26 100644 --- a/src/calibre/gui2/actions/device.py +++ b/src/calibre/gui2/actions/device.py @@ -83,12 +83,12 @@ class ShareConnMenu(QMenu): # {{{ r(prefix + ' open server in browser', self.open_server_in_browser_action.text(), action=self.open_server_in_browser_action, group=gr) def server_state_changed(self, running): - from calibre.utils.mdns import get_external_ip, verify_ipV4_address + from calibre.utils.mdns import get_external_ip, verify_ip_address text = _('Start Content server') if running: from calibre.srv.opts import server_config opts = server_config() - listen_on = verify_ipV4_address(opts.listen_on) or get_external_ip() + listen_on = verify_ip_address(opts.listen_on) or get_external_ip() protocol = 'HTTPS' if opts.ssl_certfile and opts.ssl_keyfile else 'HTTP' try: ip_text = ' ' + _('[{ip}, port {port}, {protocol}]').format( diff --git a/src/calibre/srv/bonjour.py b/src/calibre/srv/bonjour.py index 9d638dbcbc..e4d7219add 100644 --- a/src/calibre/srv/bonjour.py +++ b/src/calibre/srv/bonjour.py @@ -22,9 +22,8 @@ class BonJour: # {{{ self.services = [] def start(self, loop): - from calibre.utils.mdns import publish, unpublish, get_external_ip, verify_ipV4_address + from calibre.utils.mdns import publish, unpublish, verify_ip_address ip_address, port = loop.bound_address[:2] - self.zeroconf_ip_address = zipa = verify_ipV4_address(ip_address) or get_external_ip() prefix = loop.opts.url_prefix or '' mdns_services = ( (self.service_name, self.service_type, port, {'path':prefix + self.path}), @@ -34,8 +33,9 @@ class BonJour: # {{{ self.services = [] for s in mdns_services: - self.services.append(publish(*s, use_ip_address=zipa, add_hostname=self.add_hostname)) - loop.log(f'OPDS feeds advertised via BonJour at: {zipa} port: {port}') + si = publish(*s, add_hostname=self.add_hostname, use_ip_address=verify_ip_address(ip_address) or None) + self.services.append(si) + loop.log(f'OPDS feeds advertised via BonJour at: {", ".join(si.parsed_addresses())} port: {port}') self.advertised_port = port self.started.set() diff --git a/src/calibre/utils/mdns.py b/src/calibre/utils/mdns.py index b492c0573f..696706b9e8 100644 --- a/src/calibre/utils/mdns.py +++ b/src/calibre/utils/mdns.py @@ -76,23 +76,27 @@ def _get_external_ip(): return ipaddr -def verify_ipV4_address(ip_address): - result = None - if ip_address != '0.0.0.0' and ip_address != '::': - # do some more sanity checks on the address - try: - socket.inet_aton(ip_address) - if len(ip_address.split('.')) == 4: - result = ip_address - except Exception: - # Not legal ip address - pass - return result - - _ext_ip = None +def verify_ip_address(addr: str) -> str: + result = '' + if addr not in ('0.0.0.0', '::'): + try: + socket.inet_pton(socket.AF_INET6, addr) + except Exception: + try: + socket.inet_pton(socket.AF_INET, addr) + except Exception: + pass + else: + if len(addr.split('.')) == 4: + result = addr + else: + result = addr + return result + + def get_external_ip(): global _ext_ip if _ext_ip is None: @@ -119,6 +123,13 @@ def start_server(): return _server +def inet_aton(addr): + try: + return socket.inet_pton(socket.AF_INET6, addr) + except: + return socket.inet_pton(socket.AF_INET, addr) + + def create_service(desc, service_type, port, properties, add_hostname, use_ip_address=None): port = int(port) try: @@ -148,7 +159,7 @@ def create_service(desc, service_type, port, properties, add_hostname, use_ip_ad return ServiceInfo( service_type, service_name, - addresses=[socket.inet_aton(local_ip),], + addresses=[inet_aton(local_ip),], port=port, properties=properties, server=server_name)