You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Justin Erenkrantz <ju...@erenkrantz.com> on 2003/08/14 18:14:35 UTC

Darwin and IPv6 was Re: cvs commit: httpd-2.0/server listen.c

--On Thursday, August 14, 2003 7:56 AM -0400 "John K. Sterling" 
<jo...@sterls.com> wrote:

> I'm still having problems with HEAD this morning on os X (Darwin Kernel
> Version 6.6) - is that expected?  (i'm not sure what the status is, but the
> above email implies a fix was applied).
>
> (22)Invalid argument: make_sock: could not bind to address :80
> no listening sockets available, shutting down

No, it's not expected.  ;-)

But, here's what the problem is:

- We've disabled IPv6 across the board on Darwin because getnameinfo() doesn't 
do IPv6->IPv4 mapping correctly (my rough probably incorrect remembrance of 
the thread).  The thread in question was from last October:

<http://groups.yahoo.com/group/new-httpd/message/40185>

- We're getting IPv6 addresses back from getaddrinfo() because, well, that's 
what getaddrinfo is supposed to return.  The IPv6 addresses are returned back 
to alloc_listener.

- APR_HAVE_IPV6 is 0, so the apr_sockaddr_t doesn't contain the sin6 field in 
the union.

- You'll notice that the 22 is EINVAL (*not* EHOSTUNREACH).  That's because 
the sockaddr_in6 that we copied from getaddrinfo's return list is corrupted.

So, a few suggestions:

- Trim IPv6 addresses from getaddrinfo()'s return values if APR_HAVE_IPV6 is 0.
  (Perhaps only allow PF_INET sockets values to go in there.)

- Re-enable IPv6 on Darwin, and try to come up with a better solution to the 
problem proposed last October.  (I proposed this before, but no one was 
interested.)

And, I'm not sure if this is expected or not, but binding to the IPv6 address 
on my Darwin box does *not* bind to the IPv4 interface.  In order to do that, 
we'd have to bind to each address returned from getaddrinfo().  But, we'll 
only bind to the first one.  I think that's wrong.  Or, perhaps binding to the 
IPv6 interface is supposed to bind to the IPv4 interface, but my tests on 
Darwin don't show that to hold.  Try out:

http://www.apache.org/~jerenkrantz/getaddr.c

This IPv6 code is just a complete mess.  -- justin

Re: Darwin and IPv6 was Re: cvs commit: httpd-2.0/server listen.c

Posted by Colm MacCarthaigh <co...@stdlib.net>.
On Thu, Aug 14, 2003 at 10:45:20PM -0700, Justin Erenkrantz wrote:
> --On Thursday, August 14, 2003 23:43:23 +0100 "Colm MacCarthaigh,,," 
> <co...@stdlib.net> wrote:
> 
> >good good, patch works so :) In which I'll now cc dev@apr and include
> >the neccessary autoconf voodoo to fix OSX/Darwin.
> 
> I'm not entirely sure the getnameinfo() patch is needed on current releases 
> of Darwin.  Host-based authorization *seems* to work without it.

According to my darwin sources, it definitely fixes things for them,
but is fixed with Jaguar I believe.

> Can someone please verify this to make sure I'm not doing something wrong 
> or misunderstanding what the original problem was 10 months ago or whatnot?
> 
> It's very possible this was fixed in a point release since last October. 
> If so, we can allow IPv6 on 10.2.6 and perhaps earlier versions if we can 
> get confirmation on those versions.  And, we *could* also enable it on 
> known-getnameinfo()-broken releases with this patch in place.  But, I'm not 
> really tempted to go that far.  -- justin

Well if it ever does worm it's way in, for the sake of ultra-paranioa
it really needs a ntohl() in the RHS of the assignment. IPv6 stores
everything in network-byte-order, IPv4 structures are stored locally
as host. And you never know someone might just roll out Darwin on Sparc ;p~

-- 
Colm MacCárthaigh                        Public Key: colm+pgp@stdlib.net
colm@stdlib.net					  http://www.stdlib.net/

Re: Darwin and IPv6 was Re: cvs commit: httpd-2.0/server listen.c

Posted by Colm MacCarthaigh <co...@stdlib.net>.
On Thu, Aug 14, 2003 at 10:45:20PM -0700, Justin Erenkrantz wrote:
> --On Thursday, August 14, 2003 23:43:23 +0100 "Colm MacCarthaigh,,," 
> <co...@stdlib.net> wrote:
> 
> >good good, patch works so :) In which I'll now cc dev@apr and include
> >the neccessary autoconf voodoo to fix OSX/Darwin.
> 
> I'm not entirely sure the getnameinfo() patch is needed on current releases 
> of Darwin.  Host-based authorization *seems* to work without it.

According to my darwin sources, it definitely fixes things for them,
but is fixed with Jaguar I believe.

> Can someone please verify this to make sure I'm not doing something wrong 
> or misunderstanding what the original problem was 10 months ago or whatnot?
> 
> It's very possible this was fixed in a point release since last October. 
> If so, we can allow IPv6 on 10.2.6 and perhaps earlier versions if we can 
> get confirmation on those versions.  And, we *could* also enable it on 
> known-getnameinfo()-broken releases with this patch in place.  But, I'm not 
> really tempted to go that far.  -- justin

Well if it ever does worm it's way in, for the sake of ultra-paranioa
it really needs a ntohl() in the RHS of the assignment. IPv6 stores
everything in network-byte-order, IPv4 structures are stored locally
as host. And you never know someone might just roll out Darwin on Sparc ;p~

-- 
Colm MacCárthaigh                        Public Key: colm+pgp@stdlib.net
colm@stdlib.net					  http://www.stdlib.net/

Re: Darwin and IPv6 was Re: cvs commit: httpd-2.0/server listen.c

Posted by Justin Erenkrantz <ju...@erenkrantz.com>.
--On Thursday, August 14, 2003 23:43:23 +0100 "Colm MacCarthaigh,,," 
<co...@stdlib.net> wrote:

> good good, patch works so :) In which I'll now cc dev@apr and include
> the neccessary autoconf voodoo to fix OSX/Darwin.

I'm not entirely sure the getnameinfo() patch is needed on current releases 
of Darwin.  Host-based authorization *seems* to work without it.

Can someone please verify this to make sure I'm not doing something wrong 
or misunderstanding what the original problem was 10 months ago or whatnot?

It's very possible this was fixed in a point release since last October. 
If so, we can allow IPv6 on 10.2.6 and perhaps earlier versions if we can 
get confirmation on those versions.  And, we *could* also enable it on 
known-getnameinfo()-broken releases with this patch in place.  But, I'm not 
really tempted to go that far.  -- justin

Re: Darwin and IPv6 was Re: cvs commit: httpd-2.0/server listen.c

Posted by Justin Erenkrantz <ju...@erenkrantz.com>.
--On Thursday, August 14, 2003 23:43:23 +0100 "Colm MacCarthaigh,,," 
<co...@stdlib.net> wrote:

> good good, patch works so :) In which I'll now cc dev@apr and include
> the neccessary autoconf voodoo to fix OSX/Darwin.

I'm not entirely sure the getnameinfo() patch is needed on current releases 
of Darwin.  Host-based authorization *seems* to work without it.

Can someone please verify this to make sure I'm not doing something wrong 
or misunderstanding what the original problem was 10 months ago or whatnot?

It's very possible this was fixed in a point release since last October. 
If so, we can allow IPv6 on 10.2.6 and perhaps earlier versions if we can 
get confirmation on those versions.  And, we *could* also enable it on 
known-getnameinfo()-broken releases with this patch in place.  But, I'm not 
really tempted to go that far.  -- justin

Re: Darwin and IPv6 was Re: cvs commit: httpd-2.0/server listen.c

Posted by "Colm MacCarthaigh,,," <co...@stdlib.net>.
On Thu, Aug 14, 2003 at 05:48:38PM -0400, John K. Sterling wrote:
> On Thursday, August 14, 2003, at 05:20 PM, Colm MacCarthaigh,,, wrote:
> 
> >Can you just confirm it's listening in v6 only ? the output of
> >"netstat -an | grep LISTEN" (Darwin has netstat and grep, right?)
> >should be enough.
> 
> heh.  very funny:
> 
> % netstat -an | grep LISTEN
> tcp46      0      0  *.80                   *.*                    
> LISTEN

good good, patch works so :) In which I'll now cc dev@apr and include 
the neccessary autoconf voodoo to fix OSX/Darwin.

-- 
Colm MacCárthaigh                        Public Key: colm+pgp@stdlib.net
colm@stdlib.net					  http://www.stdlib.net/

Re: Darwin and IPv6 was Re: cvs commit: httpd-2.0/server listen.c

Posted by "Colm MacCarthaigh,,," <co...@stdlib.net>.
On Thu, Aug 14, 2003 at 05:48:38PM -0400, John K. Sterling wrote:
> On Thursday, August 14, 2003, at 05:20 PM, Colm MacCarthaigh,,, wrote:
> 
> >Can you just confirm it's listening in v6 only ? the output of
> >"netstat -an | grep LISTEN" (Darwin has netstat and grep, right?)
> >should be enough.
> 
> heh.  very funny:
> 
> % netstat -an | grep LISTEN
> tcp46      0      0  *.80                   *.*                    
> LISTEN

good good, patch works so :) In which I'll now cc dev@apr and include 
the neccessary autoconf voodoo to fix OSX/Darwin.

-- 
Colm MacCárthaigh                        Public Key: colm+pgp@stdlib.net
colm@stdlib.net					  http://www.stdlib.net/

Re: 2.1 Listen Broken [Was Re: Darwin and IPv6]

Posted by Colm MacCarthaigh <co...@stdlib.net>.
On Sun, Aug 24, 2003 at 03:45:40PM -0700, Justin Erenkrantz wrote:
> I just committed a variant of your patch.  I had to add some things to get 
> it to compile on Darwin.
> 
> Please let me know how that works for you.  I know it compiles on Linux, 
> but the Linux box I have partial access to doesn't have IPv6 configured.

Works and running for me :) Thanks!

-- 
Colm MacCárthaigh                        Public Key: colm+pgp@stdlib.net
colm@stdlib.net					  http://www.stdlib.net/

Re: 2.1 Listen Broken [Was Re: Darwin and IPv6]

Posted by Justin Erenkrantz <ju...@erenkrantz.com>.
--On Sunday, August 24, 2003 4:38 AM +0100 Colm MacCarthaigh <co...@stdlib.net> 
wrote:

> Bah, it's always the way, 2 minutes after testing and then mailing
> a patch I realise there's a small slip-up. Patch without the
> stupid-obvious-bug attached :)

Heh.

I just committed a variant of your patch.  I had to add some things to get it 
to compile on Darwin.

Please let me know how that works for you.  I know it compiles on Linux, but 
the Linux box I have partial access to doesn't have IPv6 configured.

Thanks!  -- justin

Re: 2.1 Listen Broken [Was Re: Darwin and IPv6]

Posted by Colm MacCarthaigh <co...@stdlib.net>.
On Sun, Aug 24, 2003 at 04:31:07AM +0100, Colm MacCarthaigh wrote:
> So, attachted is a best-effort patch which should solve the 
> problems.

Bah, it's always the way, 2 minutes after testing and then mailing
a patch I realise there's a small slip-up. Patch without the
stupid-obvious-bug attached :)

-- 
Colm MacCárthaigh                        Public Key: colm+pgp@stdlib.net
colm@stdlib.net					  http://www.stdlib.net/

2.1 Listen Broken [Was Re: Darwin and IPv6]

Posted by Colm MacCarthaigh <co...@stdlib.net>.
On Thu, Aug 14, 2003 at 03:47:09PM -0700, Justin Erenkrantz wrote:
> I've got the patch to do multiple listeners off one Listen directive in my 
> tree and tested, but I'm currently swamped with other stuff.

Now that it's been commited, I've been trying it out and it's broken :(

Right now, httpd won't even start for me on Linux. The first problem 
is that the order of the getaddrinfo() result set is ignored. This is most
definitely not a good idea, the order is intentional. It's the only
way listening will ever work on an OS that does not support IPv6 only
sockets :)

The next problem is that v6only_setting=0 is now handled incorrectly,
with the result that we generate an addressing conflict. Right now
(after fixing the order) it tries to listen on :: which works,
and then on 0.0.0.0, which doesnt ... on platforms that don't support
V6ONLY sockets (Linux is one, but there are more).

Here's what should happen when we try to listen on all interfaces:

   1.  call getaddrinfo with PF_UNSPEC and AI_PASSIVE, get
       :: and 0.0.0.0 back in that order.

   2.  try to create a socket on ::, don't scream too loudly if it
       doesnt work.

   3.  try to set it to IPv6 only, don't scream too loudly if it
       doesnt work. 

   4.  Try to bind() and listen() to it, don't scream too loudly
       if it doesnt work.

   5.1 If 2 and 4 were successful, but 3 wasnt; Don't even try to 
       listen on 0.0.0.0.

   5.2 Otherwise try to listen on 0.0.0.0 and bomb out on error.

Now unfortunately listen.c isnt structured to make this logic easy to
implement, the only easy place to remove 0.0.0.0 from the listeners
list is alloc_listener(), but the only place to test part 4 is 
make_sock(), bummer. Solution; compromise and put it in ap_listen_open.

So, attachted is a best-effort patch which should solve the 
problems. I've tried to make it as readable as possible but
inevitably it's going to be a bit convoluted within the current
design. But that said, I think it strikes a reasonable compromise.

With the patch applied, Linux now works :)

-- 
Colm MacCárthaigh                        Public Key: colm+pgp@stdlib.net
colm@stdlib.net					  http://www.stdlib.net/

Re: Darwin and IPv6 was Re: cvs commit: httpd-2.0/server listen.c

Posted by Justin Erenkrantz <ju...@erenkrantz.com>.
--On Thursday, August 14, 2003 10:20 PM +0100 "Colm MacCarthaigh,,," 
<co...@stdlib.net> wrote:

> On Thu, Aug 14, 2003 at 04:56:48PM -0400, John K. Sterling wrote:
>> Hi Colm -
>>
>> I'm not sure what to be looking for, but i applied your patch, rebuilt
>> (with the broken_ipv6 set to 0, of course), turned on HostnameLookups,
>> and my access logs have remote hostname properly resolved.
>
> That should mean it's working fine :)

I've got the patch to do multiple listeners off one Listen directive in my 
tree and tested, but I'm currently swamped with other stuff.

I'll also take a look at this patch for getnameinfo() when I commit the other 
portions.  Thanks for the feedback!  -- justin

Re: Darwin and IPv6 was Re: cvs commit: httpd-2.0/server listen.c

Posted by "John K. Sterling" <jo...@sterls.com>.
On Thursday, August 14, 2003, at 05:20 PM, Colm MacCarthaigh,,, wrote:

> Can you just confirm it's listening in v6 only ? the output of
> "netstat -an | grep LISTEN" (Darwin has netstat and grep, right?)
> should be enough.

heh.  very funny:

% netstat -an | grep LISTEN
tcp46      0      0  *.80                   *.*                    
LISTEN


Re: Darwin and IPv6 was Re: cvs commit: httpd-2.0/server listen.c

Posted by "Colm MacCarthaigh,,," <co...@stdlib.net>.
On Thu, Aug 14, 2003 at 04:56:48PM -0400, John K. Sterling wrote:
> Hi Colm -
> 
> I'm not sure what to be looking for, but i applied your patch, rebuilt 
> (with the broken_ipv6 set to 0, of course), turned on HostnameLookups, 
> and my access logs have remote hostname properly resolved.  

That should mean it's working fine :)

> I'm running 
> Darwin Kernel Version 6.6.  Let me know if you want me to try out 
> anything else.

Can you just confirm it's listening in v6 only ? the output of
"netstat -an | grep LISTEN" (Darwin has netstat and grep, right?)
should be enough.

-- 
Colm MacCárthaigh                        Public Key: colm+pgp@stdlib.net
colm@stdlib.net					  http://www.stdlib.net/

Re: Darwin and IPv6 was Re: cvs commit: httpd-2.0/server listen.c

Posted by "John K. Sterling" <jo...@sterls.com>.
On Thursday, August 14, 2003, at 03:55 PM, Colm MacCarthaigh,,, wrote:

> Patch attached. Since I havnt got a DARWIN machine to test on I
> can't confirm it works, but it should. It works on Linux anyway
> (not that it needs to).
>
> Darwin might need some slightly different sa.[members] set to make
> getnameinfo work but it shouldnt be anything major. If someone
> with a darwin box could try it out I'd be much obliged. Turn
> HostnameLookups On to get an idea as to whether it's working or
> not.

Hi Colm -

I'm not sure what to be looking for, but i applied your patch, rebuilt 
(with the broken_ipv6 set to 0, of course), turned on HostnameLookups, 
and my access logs have remote hostname properly resolved.  I'm running 
Darwin Kernel Version 6.6.  Let me know if you want me to try out 
anything else.

sterling


Re: Darwin and IPv6 was Re: cvs commit: httpd-2.0/server listen.c

Posted by "Colm MacCarthaigh,,," <co...@stdlib.net>.
On Thu, Aug 14, 2003 at 10:41:44AM -0700, Justin Erenkrantz wrote:
> --On Thursday, August 14, 2003 6:06 PM +0100 "Colm MacCarthaigh,,," 
> <co...@stdlib.net> wrote:
> 
> >Both these things really need to happen. The first is relatively
> >trivial:
> 
> Yup, I agree.  I committed a variant of this to the tree.  (The patch you 
> submitted would only execute if the APR_IPV4_ADDR_ONLY flag or whatever 
> would be passed in.)

Good good, silly me :)

> >Until a truly AF agnostic ACL implementation can be used (see
> >http://www.stdlib.net/~colmmacc/nsd/subnet.h and the accomponying
> >subnet.c for a rough idea) the Darwin problem should be solveable
> >by checking the IN6_IS_ADDR_V4MAPPED macro, and if so ignoring
> >the first 96 bytes and passing the last 32 on.
> 
> Hmm.  Would it be possible to submit a patch for this?  I'm not entirely 
> clear where this would go.

Patch attached. Since I havnt got a DARWIN machine to test on I
can't confirm it works, but it should. It works on Linux anyway
(not that it needs to).

Darwin might need some slightly different sa.[members] set to make
getnameinfo work but it shouldnt be anything major. If someone
with a darwin box could try it out I'd be much obliged. Turn
HostnameLookups On to get an idea as to whether it's working or
not.

Basically the patch spoofs enough of a valid _in v4 type structure
to make getnameinfo work, and grabs the address itself from the
appropriate place in the mapped one.

-- 
Colm MacCárthaigh                        Public Key: colm+pgp@stdlib.net
colm@stdlib.net					  http://www.stdlib.net/

Re: Darwin and IPv6 was Re: cvs commit: httpd-2.0/server listen.c

Posted by Justin Erenkrantz <ju...@erenkrantz.com>.
--On Thursday, August 14, 2003 6:06 PM +0100 "Colm MacCarthaigh,,," 
<co...@stdlib.net> wrote:

> Both these things really need to happen. The first is relatively
> trivial:

Yup, I agree.  I committed a variant of this to the tree.  (The patch you 
submitted would only execute if the APR_IPV4_ADDR_ONLY flag or whatever would 
be passed in.)

> Until a truly AF agnostic ACL implementation can be used (see
> http://www.stdlib.net/~colmmacc/nsd/subnet.h and the accomponying
> subnet.c for a rough idea) the Darwin problem should be solveable
> by checking the IN6_IS_ADDR_V4MAPPED macro, and if so ignoring
> the first 96 bytes and passing the last 32 on.

Hmm.  Would it be possible to submit a patch for this?  I'm not entirely clear 
where this would go.

> This is the bug I was trying to get across (badly) the day before
> yesterday. The fact that getaddrinfo returns a linked list is pretty
> much ignored by alloc_listener :(

Okay, let me take a pass at trying to fix this.  I think this should be 
solvable pretty easily.

>> http://www.apache.org/~jerenkrantz/getaddr.c
>
> That has a a bug of it's own :)

Thanks.  Fixed.  ;-)  -- justin

Re: Darwin and IPv6 was Re: cvs commit: httpd-2.0/server listen.c

Posted by "John K. Sterling" <jo...@sterls.com>.
On Thursday, August 14, 2003, at 01:06 PM, Colm MacCarthaigh,,, wrote:

> .. or similar. The darwin one is complicated, but I know of at least
> 3 people running Apache on Darwin for months, all they've been doing
> is changing v6_broken to 0 in the apr configure script ;)

Yup.. that worked.  make that 4 people :)

sterling


Re: Darwin and IPv6 was Re: cvs commit: httpd-2.0/server listen.c

Posted by "Colm MacCarthaigh,,," <co...@stdlib.net>.
On Thu, Aug 14, 2003 at 09:14:35AM -0700, Justin Erenkrantz wrote:
> - Trim IPv6 addresses from getaddrinfo()'s return values if APR_HAVE_IPV6 
> is 0.
>
>  (Perhaps only allow PF_INET sockets values to go in there.)
> 
> - Re-enable IPv6 on Darwin, and try to come up with a better solution to 
> the problem proposed last October.  (I proposed this before, but no one was 
> interested.)

Both these things really need to happen. The first is relatively
trivial:

Index: sockaddr.c
===================================================================
RCS file: /home/cvspublic/apr/network_io/unix/sockaddr.c,v
retrieving revision 1.40
diff -u -r1.40 sockaddr.c
--- sockaddr.c	14 Aug 2003 00:09:28 -0000	1.40
+++ sockaddr.c	14 Aug 2003 16:39:47 -0000
@@ -599,6 +599,9 @@
         if (flags & APR_IPV6_ADDR_OK) {
             return APR_ENOTIMPL;
         }
+        if (family == AF_UNSPEC) {
+            family = AF_INET:
+        }
 #endif
     }
     

.. or similar. The darwin one is complicated, but I know of at least
3 people running Apache on Darwin for months, all they've been doing
is changing v6_broken to 0 in the apr configure script ;)

Until a truly AF agnostic ACL implementation can be used (see 
http://www.stdlib.net/~colmmacc/nsd/subnet.h and the accomponying
subnet.c for a rough idea) the Darwin problem should be solveable
by checking the IN6_IS_ADDR_V4MAPPED macro, and if so ignoring
the first 96 bytes and passing the last 32 on.

> And, I'm not sure if this is expected or not, but binding to the IPv6 
> address on my Darwin box does *not* bind to the IPv4 interface.  In order 
> to do that, we'd have to bind to each address returned from getaddrinfo().  

This is the bug I was trying to get accross (badly) the day before
yesterday. The fact that getaddrinfo returns a linked list is pretty
much ignored by alloc_listener :(

> Try out:
> 
> http://www.apache.org/~jerenkrantz/getaddr.c

That has a a bug of it's own :)

--- getaddr.c	Thu Aug 14 17:12:10 2003
+++ getaddr-new.c	Thu Aug 14 17:58:22 2003
@@ -2,6 +2,7 @@
 #include <sys/socket.h>
 #include <netdb.h>
 #include <sys/errno.h>
+#include <strings.h>
 
 int main() {
     struct addrinfo hints, *res, *res0;
@@ -42,7 +43,7 @@
             s = -1;
             continue;
         }
-        if (accept(s, &client, &addrlen) < 0) {
+        if (accept(s, res->ai_addr, &res->ai_addrlen) < 0) {
             cause = "accept";
             printf("%s %d\n", cause, errno);
             close(s);

-- 
Colm MacCárthaigh                        Public Key: colm+pgp@stdlib.net
colm@stdlib.net					  http://www.stdlib.net/