Bug 52884

Summary: "localhost" leads to start failure
Product: Apache httpd-2 Reporter: Tianyin Xu <tixu>
Component: AllAssignee: Apache HTTPD Bugs Mailing List <bugs>
Status: NEW ---    
Severity: normal CC: adrian.fita, tixu
Priority: P2    
Version: 2.4.1   
Target Milestone: ---   
Hardware: PC   
OS: Linux   

Description Tianyin Xu 2012-03-12 09:51:21 UTC
On my computer (Ubuntu 10.04), when listening to "localhost:port" like

Listen localhost:80

Apache-httpd will report the following error and fail to start with the following error messages:

(98)Address already in use: AH00072: make_sock: could not bind to address 127.0.0.1:80
no listening sockets available, shutting down
AH00015: Unable to open logs

This error message is very confusing because 127.0.0.1:80 is not being used at all. Interestingly, if you directly change localhost to 127.0.0.1, i.e., 

Listen 127.0.0.1:80

Then, everything is fine.

By tracing the code, I find the root cause is that the bind() operation is done for two times. And, of course, it failed at the 2nd time because the 1st time it had successed.

Further tracing why it bind() two times, I finally find that it's because of the function call getaddrinfo() in the function: call_resolver() in srclib/apr/network_io/unix/sockaddr.c

When fed with "localhost", the result set, i.e., ai_list will have two elements. Thus, Apache tries to bind() based on these two elements and leads to the failure. However, it only has one element when fed with "127.0.0.1". I have to say this is really a strange behavior.

I don't know whether this problem happens on the other platform. But if it happens, it really confuses users a lot and takes a lot of time and efforts.

One simple solution is to add a patch that transfer "localhost" to "127.0.0.1" directly in ap_set_listener() in server/listen.c

Thanks!
Comment 1 Stefan Fritsch 2012-03-12 10:03:56 UTC
This may be related to PR 52709 in APR.
Comment 2 Tianyin Xu 2012-03-13 00:51:19 UTC
(In reply to comment #1)
> This may be related to PR 52709 in APR.

Thanks, Stefan!

But it seems different with my case. Their case is because of "eth0 as only IPv6". 

I checked my network configuration. I have both IPv4 & IPv6 for my eth0. I suspected this problem is caused by the IPv6 stuff, but I tested on my colleague's machine which also has IPv4 & IPv6. On his machine, this problem didn't exist.

Hmmm... it's really a strange problem...:( Maybe I should go to bugzilla APR?
Comment 3 Joe Orton 2012-08-17 14:18:40 UTC
I can reproduce this, it is another weird AI_ADDRCONFIG getaddinfo() thing.

Using people.apache.org/~jorton/gai.c

$ ./gai localhost
getaddrinfo("localhost", NULL, {.family=AF_UNSPEC, .hints=0}) = 0:
 family=10, proto= 6 inet6: addr=::1, port=0, flowinfo=0
 family= 2, proto= 6 inet4: addr=127.0.0.1, port=0
$ ./gai -a localhost
getaddrinfo("localhost", NULL, {.family=AF_UNSPEC, .hints=0|AI_ADDRCONFIG}) = 0:
 family= 2, proto= 6 inet4: addr=127.0.0.1, port=0
 family= 2, proto= 6 inet4: addr=127.0.0.1, port=0

... where /etc/hosts has both "localhost" and "localhost.domain" mapping to 127.0.0.1.

Google says there is some... "disagreement" about whether this is app/libc/distro problem.  Sigh.  I guess we could work around it in APR by ignoring duplicate addresses.
Comment 4 adrian.fita 2018-11-09 12:32:34 UTC
I encountered this same issue when I disabled ipv6 on RHEL (following the article at https://access.redhat.com/solutions/8709), but I did not comment/removed the line with "::1 localhost" from /etc/hosts.