On Thu, Jun 19, 2008 at 9:56 PM, Sob <s...@hisoftware.cz> wrote:
> Hello,
>
> while experimenting with httpd and IPv6 on WinXP, I found out that it's not
> working well.
> In short, the code expects that IPv4 mapped addresses and IPV6_V6ONLY socket
> option are supported. This is not true for NTs < 6.0. They have IPv4 and
> IPv6 as two separate stacks and therefore all IPv6 sockets always behave as
> V6ONLY and no IPv4 mapped addresses are possible. Unfortunately the
> IPV6_V6ONLY option is not understood, so if the code tries to set it, if
> fails with OS error. APR seems to be the best place where it can be fixed.
>
> The attached patch modifies apr_socket_opt_set(). When the requested option
> is APR_IPV6_V6ONLY, it checks Windows version and if it's less than Vista,
> it does not call setsockopt(), but instead it calls directly
> apr_set_option() and pretends that the option was set. Then it returns
> APR_SUCCESS or APR_ENOTIMPL depending on if it was requested to set or unset
> the option.
> I'm not exactly sure about returning APR_ENOTIMPL, but httpd would fail with
> anything else. At first I just set "on = 1;" and let the original
> apr_set_option() use it, but that wasn't right, because it always returned
> APR_SUCCESS and some application other than httpd can depend on the result
> and in case it requested to unset the option, returning APR_SUCCESS would be
> wrong. Httpd doesn't really care about the result and checks the state later
> using apr_socket_opt_get(). That's why always calling apr_set_option(sock,
> APR_IPV6_V6ONLY, 1) is important. If omited, it would be possible (if
> compiled with IPv4 mapped addresses support) for apr_socket_opt_get() to
> return 0 (= socket can accept both IPv4 and 6), but that's not possible on
> these older Windows and if some code is depending on it, it may fail (like
> current httpd).
>
> Sob

See also http://msdn.microsoft.com/en-us/library/ms738574%28v=vs.85%29.aspx

< Vista: socket option not supported, but behaves as if it is hard-coded to 1
>= Vista: socket option works, and IPV6_V6ONLY=1 is the default state

Suggested changes to the patch:

Move "apr_set_option(sock, APR_IPV6_V6ONLY, 1);" to creation of the
socket, and make it unconditional (old or new Windows).  That allows
apr_socket_opt_get() to work even if apr_socket_opt_set() isn't called
first.*  (This reflects the default setting of 1 on levels of Windows
that support the option, as documented above and confirmed on Windows
7.)

Add the default definition of IPV6_V6ONLY right in sockopt.c.  It
won't be needed anywhere else.

Thoughts?

FWIW, I'm aware that some folks who have tested different IPv6
scenarios on old/new Windows boxes are using about the same code that
Sob has posted.

*This issue of socket_opt_get() before socket_opt_set() seems to be a
wider issue with APR.  There are a few options which must pass through
to the OS to retrieve, but we don't do that.

Reply via email to