-
Notifications
You must be signed in to change notification settings - Fork 38.6k
http: Fail initialization when any bind fails #14968
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
Conversation
|
Doesn't binding 127.0.0.1 fail if ::1 is already bound, on some systems? (Because ::1 includes 127.0.0.1 in practice.) |
No, that's definitely not true. No localhost address or subnet should include each other. so: None of these overlaps. You're mixing it up with |
|
Concept ACK The error message here also needs updating for the new behaviour: |
f128eca to
8d9f29e
Compare
|
@meshcollider thanks, updated |
|
utACK |
|
utACK would also be nicer to get this in sooner rather than later, so we get more of a chance to find out that SpatulaBSD behaves like luke thought before this ends up in a release. :) |
|
Concept ACK |
|
Travis fails when creating the cache. Could be because of the default value of |
|
|
|
I guess this has to do with Travis not supporting (even local!) IPv6 at all, so the IPv6 bind fails and it doesn't start. I suppose not being able to auto-bind on either IPv4 or IPv6 is valid if there is no such interface, at least if |
8d9f29e to
8a4b1c5
Compare
|
OK, per suggestion by @gmaxwell I've changed the logic. By default, if no explicit bind configuration is given, the This can be tested using linux network namespaces ip netns add dumb
ip netns exec dumb ip addr add 127.0.0.1/8 dev lo # adds both IPv4 and IPv6
ip netns exec dumb ip addr del ::1/128 dev lo # remove IPv6
ip netns exec dumb ip link set lo up
ip netns exec dumb src/bitcoind -regtest |
8a4b1c5 to
247ce61
Compare
|
Sigh, that still didn't solve the Travis issue though. Locally running the tests with no IPv6 localhost worked fine for me now. |
247ce61 to
a846175
Compare
src/httpserver.cpp
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needed this to prevent a leak and segfault in StopHTTPServer (because the owning evhttp is freed but the listeners are not).
7c5e478 to
515288d
Compare
Currently the HTTP server initialization (`HTTPBindAddresses`) fails only when *all* bindings fail. So if multiple binds are specified (`127.0.0.1` and `::1` by defeault) and one succeeds and the other fails, the latter is essentially ignored. This commit changes the error behavior to fail *if not all* binds could be performed, which I think is more in line with how software normally handles this and what users expect.
bfc1899 to
7b5e400
Compare
|
Unfortunately, evhttp_bind_socket_with_handle returns a 0/Success errno when listen fails. I've opened a report upstream to fix this, but obviously we can't rely on it now: libevent/libevent#738 |
|
One possible solution is to clone the evhttp code. I got it down to 65 lines: master...luke-jr:my_bind_socket_with_handle |
|
At least on Travis, the failure isn't caused by Instead, what's happening is that Added a somewhat-ugly hack on top of my branch: d2d51e7 |
|
Just noticed Travis is passing on this PR... did we lose some test coverage between 0.17 (where I'm testing it) and master? |
Strange, this worked for me, and it seems to work on Travis. As stated I've tested this (at least on Linux) in various ways. An alternative solution here (which I initially wanted to do, but this seemed like a workable suggestion at the time if of course C code didn't mess up error handling everywhere) is to test which local interfaces are available, and only
This avoids having to check error codes, and could be more robust. I might give this a try. Though I'm not sure there's a good platform-independent way of doing this. I do not think this is worth adding a forest of hacks cloning parts of code from libevent for. Better to leave it as-is then, it wasn't that bad. |
|
WAIT: it's the if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
return (NULL);I don't think we care about specific |
|
With this backported to 0.17, Travis was indeed failing on |
|
Yes, tried in #15050, really strange. I think specific error code checking is a dead end, just too fragile. Looking for a platform independent way now to check if there is a local IPv4 or local IPv6 interface without actually binding to it. Looks like we have vaguely analogous logic in |
|
Closing this for now. |
|
Just reading the libevent2 code, I did not try this, but the following may be a way to pass Instead of |
To provide context: being able to set |
Currently the HTTP server initialization (
HTTPBindAddresses) fails only when all bindings fail. So if multiple binds are specified (127.0.0.1and::1by defeault) and one succeeds and the other fails, the latter is essentially ignored.This commit changes the error behavior to fail if not all binds could be performed, which I think is more in line with how software normally handles this and what users expect.
Needs mention in release notes.