From d87f5e23e2e5a5d5cc3d5671f681e374847b4842 Mon Sep 17 00:00:00 2001 From: Ralf Habacker Date: Sat, 31 Jan 2015 13:34:26 +0100 Subject: [PATCH] Detect ipv6 support and return related error message on creating or connection to a dbus server. --- dbus/dbus-sysdeps-win.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 4 deletions(-) diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index 68fa72b..6539796 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -669,6 +669,45 @@ _dbus_connect_named_pipe (const char *path, #endif /** + * @returns #FALSE if no ipv6 support has been found + */ +dbus_bool_t _dbus_has_ipv6() +{ + static dbus_bool_t first = TRUE; + static dbus_bool_t has_ipv6 = TRUE; + + if(first) + { + struct addrinfo hints; + struct addrinfo *ai = 0; + int temp = INVALID_SOCKET; + + _DBUS_ZERO (hints); + + hints.ai_family = AF_INET6; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + if (getaddrinfo("::1", NULL, &hints, &ai) != 0 || !ai) + has_ipv6 = FALSE; + + if (has_ipv6 && (temp = socket (AF_INET6, SOCK_STREAM, 0)) == INVALID_SOCKET) + has_ipv6 = FALSE; + + if (has_ipv6 && bind (temp, ai->ai_addr, ai->ai_addrlen) == SOCKET_ERROR) + has_ipv6 = FALSE; + + if (temp != INVALID_SOCKET) + closesocket(temp); + if (ai) + freeaddrinfo(ai); + + first = FALSE; + } + return has_ipv6; +} + +/** * @returns #FALSE if no memory */ dbus_bool_t @@ -1516,11 +1555,21 @@ _dbus_connect_tcp_socket_with_nonce (const char *host, _DBUS_ZERO (hints); if (!family) - hints.ai_family = AF_UNSPEC; + hints.ai_family = _dbus_has_ipv6() ? AF_UNSPEC : AF_INET; else if (!strcmp(family, "ipv4")) hints.ai_family = AF_INET; else if (!strcmp(family, "ipv6")) - hints.ai_family = AF_INET6; + { + if (_dbus_has_ipv6()) + hints.ai_family = AF_INET6; + else + { + dbus_set_error (error, + DBUS_ERROR_INVALID_ARGS, + "No ipv6 support available", ""); + return -1; + } + } else { dbus_set_error (error, @@ -1666,11 +1715,21 @@ _dbus_listen_tcp_socket (const char *host, _DBUS_ZERO (hints); if (!family) - hints.ai_family = AF_INET; + hints.ai_family = _dbus_has_ipv6() ? AF_UNSPEC : AF_INET; else if (!strcmp(family, "ipv4")) hints.ai_family = AF_INET; else if (!strcmp(family, "ipv6")) - hints.ai_family = AF_INET6; + { + if (_dbus_has_ipv6()) + hints.ai_family = AF_INET6; + else + { + dbus_set_error (error, + DBUS_ERROR_INVALID_ARGS, + "No ipv6 support available", ""); + return -1; + } + } else { dbus_set_error (error, -- 1.8.4.5