[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freedesktop-xcb
Subject:    [Xcb] =?utf-8?q?=5BPATCH=5D_Bug=3A_Can=E2=80=99t_connect_to_local?=
From:       Michael Stapelberg <michael+xcb () stapelberg ! de>
Date:       2011-08-13 19:54:05
Message-ID: 20110813215405.5818a0c1 () x200
[Download RAW message or body]

Hi,

I recently noticed that I cannot use programs which use libxcb with
DISPLAY=127.0.0.1:0 when my system has no IP addresses apart from
127.0.0.1 and ::1 on 'lo'.

A bit of debugging reveals that the problem is the flags which are
used to call getaddrinfo() in src/xcb_util.c:_xcb_open_tcp:301, namely
AI_ADDRCONFIG.

AI_ADDRCONFIG will only return IPv4 addresses if the system has an IPv4
address configured (likewise for IPv6). This also takes place when
resolving localhost (or 127.0.0.0/8 or ::1). Also, as per RFC 3493,
loopback addresses are not considered as valid addresses when
determining whether to return IPv4 or IPv6 addresses.

Basically, we have two possibilities:

1) Drop the AI_ADDRCONFIG flag. This will result in getting IPv4 *and*
   IPv6 addresses for names like "localhost" or any domain name which
   has AAAA and A records. The results will be sorted according to RFC
   3484 so that a system without a configured (and native, as in
   not-tunneled) IPv6 address will try the IPv4 record first.

   So the difference is that if the IPv4 address does not work, systems
   without IPv6 will still try to open a socket and connect via IPv6,
   which will fail immediately. Since XCB does not signal these errors
   anyways (it will only say that the X connection has some error),
   this is not a problem at all.

   The fix in this case is to just remove the AI_ADDRCONFIG flag
   entirely.

2) Drop the AI_ADDRCONFIG flag only when connecting to localhost,
   127.0.0.0/8 or [::1]. This is a work-around, but should do the trick
   for most use cases. I have attached a patch for this.

I think that 1) is the best option. It will fix the problem without any
side-effects for the user. In case you want a more conservative fix (or
work-around), use my patch for 2).

Thanks in advance,
Best regards,
Michael

PS: My use case is http://x11vis.org/ which prefers TCP connections over
    UNIX socket connections because it can identify the remote end when
    using TCP.

PPS: A related ticket (to getaddrinfo() for local addresses and the
     effects of AI_ADDRCONF) can be found at
     http://sourceware.org/bugzilla/show_bug.cgi?id=10083
[Attachment #3 (text/x-patch)]

From f6a97ee69abb944fcc4ca841e234e6a2b0db1b7f Mon Sep 17 00:00:00 2001
From: Michael Stapelberg <michael@stapelberg.de>
Date: Sat, 13 Aug 2011 21:15:56 +0200
Subject: [PATCH] tcp: Use AI_ADDRCONFIG only for non-localhost
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When a system is completely offline (no interface has an IP address but 'lo'),
xcb could not connect to localhost via TCP, e.g. connections with
DISPLAY=127.0.0.1:0 fails.

AI_ADDRCONFIG will only return IPv4 addresses if the system has an IPv4
address configured (likewise for IPv6). This also takes place when
resolving localhost (or 127.0.0.0/8 or ::1). Also, as per RFC 3493,
loopback addresses are not considered as valid addresses when
determining whether to return IPv4 or IPv6 addresses.

Therefore, we only use AI_ADDRCONFIG when host is neither localhost nor
127.* nor [::1]. This ensures that we can connect to localhost via TCP
even if we don't have global connectivity.
---
 src/xcb_util.c |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/src/xcb_util.c b/src/xcb_util.c
index fde4f85..b73c01e 100644
--- a/src/xcb_util.c
+++ b/src/xcb_util.c
@@ -278,7 +278,19 @@ static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short
 
     memset(&hints, 0, sizeof(hints));
 #ifdef AI_ADDRCONFIG
-    hints.ai_flags |= AI_ADDRCONFIG;
+    /* AI_ADDRCONFIG will only return IPv4 addresses if the system has an IPv4
+     * address configured (likewise for IPv6). This also takes place when
+     * resolving localhost (or 127.0.0.0/8 or ::1). Also, as per RFC 3493,
+     * loopback addresses are not considered as valid addresses when
+     * determining whether to return IPv4 or IPv6 addresses.
+     *
+     * Therefore, we only use AI_ADDRCONFIG when host is neither localhost nor
+     * 127.* nor [::1]. This ensures that we can connect to localhost via TCP
+     * even if we don't have global connectivity. */
+    if (strncasecmp(host, "localhost", strlen("localhost")) != 0 &&
+        strncmp(host, "127.", strlen("127.")) != 0 &&
+	strncmp(host, "[::1]", strlen("[::1]")) != 0)
+        hints.ai_flags |= AI_ADDRCONFIG;
 #endif
 #ifdef AI_NUMERICSERV
     hints.ai_flags |= AI_NUMERICSERV;
-- 
1.7.5.4



_______________________________________________
Xcb mailing list
Xcb@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xcb

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic