Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

waitress 1.0a1 doesn't work on linux without internet connectivity (DNS?) #131

Closed
ztane opened this issue Jul 6, 2016 · 5 comments
Closed

Comments

@ztane
Copy link

ztane commented Jul 6, 2016

I am using:

listen = '127.0.0.1:6543 [::1]:6543'

Now, if I do not have internet connectivity (aeroplane coding mode for example), waitress crashes with:

Traceback (most recent call last):
  File "/.../venv/lib/python3.5/site-packages/waitress/adjustments.py", line 258, in __init__
    socket.AI_PASSIVE | socket.AI_ADDRCONFIG
  File "/usr/lib/python3.5/socket.py", line 732, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -9] Address family for hostname not supported

This even though the reverses for 127.0.0.1 and ::1 are in /etc/hosts, and they are the names that are displayed on the Serving message. That is, if I change them to localhost123 and ip6-localhost123, and I have internet connectivity, waitress displays:

Serving on http://localhost123:6543
Serving on http://ip6-localhost123:6543
@ztane
Copy link
Author

ztane commented Jul 6, 2016

This is because of AI_ADDRCONFIG:

    If hints.ai_flags includes the AI_ADDRCONFIG flag, then IPv4 addresses are returned in the list pointed to by res only if the local system has at least one IPv4 address configured,  and  IPv6
    addresses are returned only if the local system has at least one IPv6 address configured.  The loopback address is not considered for this case as valid as a configured address.  This flag is
     useful on, for example, IPv4-only systems, to ensure that getaddrinfo() does not return IPv6 socket addresses that would always fail in connect(2) or bind(2).

and since there is no internet connectivity, no IP address is configured on any other interface except loopback. Perhaps it should be changed so that if AI_ADDRCONFIG fails then either

  • the lookup is tried with AI_NUMERICHOST without AI_ADDRCONFIG,
  • or the lookup itself is tried without AI_ADDRCONFIG, possibly with issuance of a warning or not...

@ztane
Copy link
Author

ztane commented Jul 6, 2016

Now I believe the correct option should be to drop AI_ADDRCONFIG altogether. The reason for using AI_ADDRCONFIG is to ensure that you're not resolving only IPv6 addresses on a machine that doesn't have IPv6 connection to outside, or IPv4 on a machine with no IPv4 connectivity. Since all of the resolved addresses are bound to, it doesn't matter whether they're only internal. The only case is if you have only IPv6 addressing inside your network with no IPv4 addressing within the network and only IPv4 addressing outside and you're binding by a hostname, or you have IPv6 completely disabled on your system, even on localhost, but getaddrinfo still offering IPv6 address for loopback interface.

@digitalresistor
Copy link
Member

I went back and forth on adding AI_ADDRCONFIG. It's probably the wrong thing to do when explicitly requesting localhost (either ::1 or 127.0.0.1) but when using a hostname that is then resolved using getaddrinfo() it is potentially the right thing to do...

For example, on OS X you could set your listen parameter to:

alexandra.network.lan:8080

Where alexandra.network.lan is your local machines name, and a DNS entry that resolves. If the DNS server has stale data due to DHCPv6 not having updated it, it's possible it will return an IPv6 address that is invalid for the machine and attempting to bind() to all results without AI_ADDRCONFIG would do the wrong thing. I'll admit it is an example of a broken local network, but it is an issue I ran into.


At this point, I can agree to dropping AI_ADDRCONFIG, if your local network is misconfigured that's not something I really should try to protect against. I will NOT be adding AI_NUMERICHOST because it disallows the use of hostnames in getaddrfinfo() and I want to allow the user to say listen = localhost:8080 and listen on whatever addresses are returned for that (generally 127.0.0.1 and ::1 unless you are on some flavour of linux that uses ip6-localhost).


Regarding the "Serving on" messages. Those are found by getting the name info for the IP address that is bound to, basically doing a reverse DNS query, including what is in /etc/hosts.

Thanks for your report, will get a fix out by the end of today! Appreciate the testing!

@ztane
Copy link
Author

ztane commented Jul 7, 2016

Ah, the AI_NUMERICHOST would have been

try:
    addressses = getaddrinfo(...|AI_ADDRCONFIG)
except:
    addresses = getaddrinfo(...|AI_NUMERICHOST)

and let the exception propagate only when both of them fail.

@digitalresistor
Copy link
Member

It's not really required though, by default getaddrinfo does the right thing when you pass it a numeric host or non-numeric. Also that still wouldn't support the use case of:

listen = localhost:8080

Because it would fail on theAI_ ADDRCONFIG when the user has no network connectivity, and it isn't a numeric host so it would fail on the AI_NUMERICHOST.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants