Skip to content

Commit

Permalink
Merge bitcoin#30245: net: Allow -proxy=[::1] on nodes with IPV6 lo only
Browse files Browse the repository at this point in the history
23333b7 net: Allow DNS lookups on nodes with IPV6 lo only (Max Edwards)

Pull request description:

  This is similar to (but does not fix) bitcoin#13155 which I believe is the same issue but in libevent.

  The issue is on a host that has IPV6 enabled but only a loopback IP address `-proxy=[::1]` will fail as `[::1]` is not considered valid by `getaddrinfo` with `AI_ADDRCONFIG` flag. I think the loopback interface should be considered valid and we have a functional test that will try to test this: `feature_proxy.py`.

  To replicate the issue, run `feature_proxy.py` inside a docker container that has IPV6 loopback ::1 address without specifically giving that container an external IPV6 address. This should be the default with recent versions of docker. IPV6 on loopback interface was enabled in docker engine 26 and later ([https://docs.docker.com/engine/release-notes/26.0/#bug-fixes-and-enhancements-2](https://docs.docker.com/engine/release-notes/26.0/#bug-fixes-and-enhancements-2)).

  `AI_ADDRCONFIG` was introduced to prevent slow DNS lookups on systems that were IPV4 only.

  References:

  Man section on `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 ex‐
         ample, IPv4-only systems, to ensure that getaddrinfo() does not return IPv6 socket addresses that would always fail in connect(2) or bind(2).
  ```

  [AI_ADDRCONFIG considered harmful Wiki entry by Fedora](https://fedoraproject.org/wiki/QA/Networking/NameResolution/ADDRCONFIG)

  [Mozilla discussing slow DNS without AI_ADDRCONFIG and also localhost issues with it](https://bugzilla.mozilla.org/show_bug.cgi?id=467497)

ACKs for top commit:
  achow101:
    ACK 23333b7
  tdb3:
    ACK 23333b7
  pinheadmz:
    ACK 23333b7

Tree-SHA512: 5ecd8c72d1e1c28e3ebff07346381d74eaddef98dca830f6d3dbf098380562fa68847d053c0d84cc8ed19a45148ceb5fb244e4820cf63dccb10ab3db53175020
  • Loading branch information
achow101 committed Jul 18, 2024
2 parents 0cac457 + 23333b7 commit ec74f45
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/netbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ std::vector<CNetAddr> WrappedGetAddrInfo(const std::string& name, bool allow_loo
ai_hint.ai_protocol = IPPROTO_TCP;
// We don't care which address family (IPv4 or IPv6) is returned
ai_hint.ai_family = AF_UNSPEC;

// If we allow lookups of hostnames, use the AI_ADDRCONFIG flag to only
// return addresses whose family we have an address configured for.
//
Expand All @@ -61,7 +62,17 @@ std::vector<CNetAddr> WrappedGetAddrInfo(const std::string& name, bool allow_loo
addrinfo* ai_res{nullptr};
const int n_err{getaddrinfo(name.c_str(), nullptr, &ai_hint, &ai_res)};
if (n_err != 0) {
return {};
if ((ai_hint.ai_flags & AI_ADDRCONFIG) == AI_ADDRCONFIG) {
// AI_ADDRCONFIG on some systems may exclude loopback-only addresses
// If first lookup failed we perform a second lookup without AI_ADDRCONFIG
ai_hint.ai_flags = (ai_hint.ai_flags & ~AI_ADDRCONFIG);
const int n_err_retry{getaddrinfo(name.c_str(), nullptr, &ai_hint, &ai_res)};
if (n_err_retry != 0) {
return {};
}
} else {
return {};
}
}

// Traverse the linked list starting with ai_trav.
Expand Down

0 comments on commit ec74f45

Please sign in to comment.