Skip to content

Commit

Permalink
windows DNS resolution: handle IPv6
Browse files Browse the repository at this point in the history
related: #5176, #4421
  • Loading branch information
SomberNight committed Mar 25, 2019
1 parent 9161d3a commit 9b0773c
Showing 1 changed file with 26 additions and 16 deletions.
42 changes: 26 additions & 16 deletions electrum/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,30 +516,40 @@ def _set_proxy(self, proxy: Optional[dict]):

@staticmethod
def _fast_getaddrinfo(host, *args, **kwargs):
def needs_dns_resolving(host2):
def needs_dns_resolving(host):
try:
ipaddress.ip_address(host2)
ipaddress.ip_address(host)
return False # already valid IP
except ValueError:
pass # not an IP
if str(host) in ('localhost', 'localhost.',):
return False
return True
try:
if needs_dns_resolving(host):
answers = dns.resolver.query(host)
addr = str(answers[0])
else:
addr = host
except dns.exception.DNSException as e:
# dns failed for some reason, e.g. dns.resolver.NXDOMAIN
# this is normal. Simply report back failure:
raise socket.gaierror(11001, 'getaddrinfo failed') from e
except BaseException as e:
# Possibly internal error in dnspython :( see #4483
def resolve_with_dnspython(host):
# try IPv6
try:
answers = dns.resolver.query(host, dns.rdatatype.AAAA)
return str(answers[0])
except dns.exception.DNSException as e:
pass
except BaseException as e:
print_error(f'dnspython failed to resolve dns (AAAA) with error: {e}')
# try IPv4
try:
answers = dns.resolver.query(host, dns.rdatatype.A)
return str(answers[0])
except dns.exception.DNSException as e:
# dns failed for some reason, e.g. dns.resolver.NXDOMAIN
# this is normal. Simply report back failure:
raise socket.gaierror(11001, 'getaddrinfo failed') from e
except BaseException as e:
# Possibly internal error in dnspython :( see #4483
print_error(f'dnspython failed to resolve dns (A) with error: {e}')
# Fall back to original socket.getaddrinfo to resolve dns.
print_error('dnspython failed to resolve dns with error:', e)
addr = host
return host
addr = host
if needs_dns_resolving(host):
addr = resolve_with_dnspython(host)
return socket._getaddrinfo(addr, *args, **kwargs)

@log_exceptions
Expand Down

2 comments on commit 9b0773c

@cculianu
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious -- why IPv6 fist? I read the issue referenced but I can't actually figure out why it should go first -- in the case where there's a single stack (just IPv4) this code will return the IPv6 hostname... which can be problematic for lots of setups...

@SomberNight
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why IPv6 first?

the whole point is to prefer IPv6 if available

in the case where there's a single stack (just IPv4) this code will return the IPv6 hostname

ah you're right. I had tested on a system with IPv6 enabled; and on a system with IPv6 disabled, and all looked fine, but on the IPv6 disabled system I was inadvertently filtering out all AAAA records from DNS responses, which led me to miss this

should be fixed in c4fb58c

Thanks.

Please sign in to comment.