libevent / libevent/libevent

windows: issue with ipv6 address detection

Open
#1,041 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

os:windows
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.