You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by sf...@apache.org on 2012/05/28 15:10:28 UTC

svn commit: r1343239 - in /apr/apr/branches/1.4.x: ./ CHANGES network_io/unix/sockaddr.c

Author: sf
Date: Mon May 28 13:10:28 2012
New Revision: 1343239

URL: http://svn.apache.org/viewvc?rev=1343239&view=rev
Log:
Merge r1343233 and add CHANGES entry:

Improve handling of AI_ADDRCONFIG with getaddrinfo()

Using AI_ADDRCONFIG involves some unfortunate guesswork because it does not
consider loopback addresses when trying to determine if IPv4 or IPv6 is
configured (RFC 3493).

This is a problem if one actually wants to listen on or connect to the loopback
address of a protocol family that is not otherwise configured on the system.
Also, some implementations (glibc, cough) behave strangely if no other
addresses besides 127.0.0.1 and ::1 are configured.

A real fix would enhance apr_sockaddr_info_get's interface to allow the caller
to specify if he wants to use the address for listen() or connect(), and if he
wants to make the result dependant on the presence of non-loopback addresses.
Then apr_sockaddr_info_get could pass the right combination of AI_ADDRCONFIG
and AI_PASSIVE to getaddrinfo().

As a workaround, retry getaddrinfo() without AI_ADDRCONFIG in case of
EAI_ADDRFAMILY. This solves the most common problems but not all corner cases.

PR: 52709
Submitted by: Nirgal Vourgère <jmv_deb nirgal com>, Stefan Fritsch
    
Many thanks also to Aurelien Jarno for helping to debug this.

Modified:
    apr/apr/branches/1.4.x/   (props changed)
    apr/apr/branches/1.4.x/CHANGES
    apr/apr/branches/1.4.x/network_io/unix/sockaddr.c

Propchange: apr/apr/branches/1.4.x/
------------------------------------------------------------------------------
  Merged /apr/apr/trunk:r1343233

Modified: apr/apr/branches/1.4.x/CHANGES
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.4.x/CHANGES?rev=1343239&r1=1343238&r2=1343239&view=diff
==============================================================================
--- apr/apr/branches/1.4.x/CHANGES [utf-8] (original)
+++ apr/apr/branches/1.4.x/CHANGES [utf-8] Mon May 28 13:10:28 2012
@@ -1,6 +1,11 @@
                                                      -*- coding: utf-8 -*-
 Changes for APR 1.4.7
 
+  *) Fix some problems in apr_sockaddr_info_get() when trying to resolve
+     the loopback addresses of a protocol family that is not otherwise
+     configured on the system. PR 52709. [Nirgal Vourgère
+     <jmv_deb nirgal com>, Stefan Fritsch]
+
   *) Fix file not being unlocked if truncate call on a file fails.
      [Mladen Turk]
 

Modified: apr/apr/branches/1.4.x/network_io/unix/sockaddr.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.4.x/network_io/unix/sockaddr.c?rev=1343239&r1=1343238&r2=1343239&view=diff
==============================================================================
--- apr/apr/branches/1.4.x/network_io/unix/sockaddr.c (original)
+++ apr/apr/branches/1.4.x/network_io/unix/sockaddr.c Mon May 28 13:10:28 2012
@@ -356,8 +356,23 @@ static apr_status_t call_resolver(apr_so
     }
     error = getaddrinfo(hostname, servname, &hints, &ai_list);
 #ifdef HAVE_GAI_ADDRCONFIG
-    if (error == EAI_BADFLAGS && family == APR_UNSPEC) {
-        /* Retry without AI_ADDRCONFIG if it was rejected. */
+    /*
+     * Using AI_ADDRCONFIG involves some unfortunate guesswork because it
+     * does not consider loopback addresses when trying to determine if
+     * IPv4 or IPv6 is configured on a system (see RFC 3493).
+     * This is a problem if one actually wants to listen on or connect to
+     * the loopback address of a protocol family that is not otherwise
+     * configured on the system. See PR 52709.
+     * To work around some of the problems, retry without AI_ADDRCONFIG
+     * in case of EAI_ADDRFAMILY.
+     * XXX: apr_sockaddr_info_get() should really accept a flag to determine
+     * XXX: if AI_ADDRCONFIG's guesswork is wanted and if the address is
+     * XXX: to be used for listen() or connect().
+     *
+     * In case of EAI_BADFLAGS, AI_ADDRCONFIG is not supported.
+     */
+    if ((family == APR_UNSPEC) && (error == EAI_BADFLAGS
+                                   || error == EAI_ADDRFAMILY)) {
         hints.ai_flags &= ~AI_ADDRCONFIG;
         error = getaddrinfo(hostname, servname, &hints, &ai_list);
     }