windows: issue with ipv6 address detection
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 12k
- Forks
- 3.5k
- Avg merge
- 12h 55m
- Merged PRs (30d)
- 6
Description
I'm currently seeing an issue where libevent is misidentifying ip6 addresses (i.e ::1) as ipv4. This is only happening on Windows, and was preventing our RPC server from binding to an ipv6 address. The PR were with the project-specific fix and explanation is here: https://github.com/bitcoin/bitcoin/pull/19375.
We are using evhttp_bind_socket_with_handle() to create an RPC server, and try and bind to 127.0.0.1 and ::1 by default. This works for all platforms, except for Windows, which would always fail to bind to ::1. You'd see lines like:
2020-06-24T01:49:04Z libevent: getaddrinfo: nodename nor servname provided, or not known
in our debug log.
Our call into libevent starts with evhttp_bind_socket_with_handle():
evhttp_bind_socket_with_handle()
bind_socket()
make_addrinfo()
evutil_getaddrinfo()
if #USE_NATIVE_GETADDRINFO
#ifndef AI_ADDRCONFIG
evutil_adjust_hints_for_addrconfig_()
evutil_check_interfaces()
evutil_check_ifaddrs()
evutil_found_ifaddr()
// miss identifies ipv6 as ipv4?
#endif
evutil_getaddrinfo_common_()
The problem seems to be falling into "#ifndef AI_ADDRCONFIG" and calling evutil_adjust_hints_for_addrconfig_():
#ifndef AI_ADDRCONFIG
/* Not every system has AI_ADDRCONFIG, so fake it. */
if (hints.ai_family == PF_UNSPEC &&
(hints.ai_flags & EVUTIL_AI_ADDRCONFIG)) {
evutil_adjust_hints_for_addrconfig_(&hints);
}
#endif
At this point, hints gets adjusted in such a way, that by the time you get to evutil_found_ifaddr() ipv6 addresses are mis-identified as ipv4. My knowledge of libevent is not good enough to know exactly why this is happening.
These AI_ definitions are available on Windows, however, only from Vista (0x0600) onwards, see here.
Our fix is just to set -D_WIN32_WINNT=0x0601 when building libevent (we require >= Windows 7 at runtime), which means the AI_ definitions are available at compile time, as they are included from ws2tcpip.h before WIN32_WINNT is later undef'd and set to 0x501 (XP) in evutil.c.
I'm not sure what the supported versions of Windows are for libevent, so obviously changing those defines isn't necessarily a solution here, but I'm happy to help improve this if it's deemed an issue.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in evutil.c at the WIN32_WINNT definition, the #ifndef AI_ADDRCONFIG path, evutil_adjust_hints_for_addrconfig(), and evutil_found_ifaddr(). Compare the Windows build configuration with the reported Windows 7 workaround and trace how ::1 is classified; done means the Windows path no longer treats IPv6 as IPv4 and evhttp_bind_socket_with_handle() can bind to ::1.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- networking, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100