svn rev #24156: trunk/src/slave/

ghudson@MIT.EDU ghudson at MIT.EDU
Thu Jul 1 12:56:22 EDT 2010


http://src.mit.edu/fisheye/changelog/krb5/?cs=24156
Commit By: ghudson
Log Message:
ticket: 6686

In kpropd, when getting a wildcard address to listen on, try IPv6
explicitly (with AI_ADDRCONFIG specified where available, to avoid
IPv6 on hosts with no IPv6 interface) and then fall back to IPv4.
Only set IPV6_V6ONLY on the listener socket if the resulting address
is IPv6.

Note: we have mostly confirmed that OpenBSD does not have dual-stack
support, meaning that it would be better to open separate IPv4 and
IPv6 listener sockets, as we do in krb5kdc and kadmind.
Unfortunately, the complicated iprop retry-and-backoff logic makes
this less than straightforward.



Changed Files:
U   trunk/src/slave/kpropd.c
Modified: trunk/src/slave/kpropd.c
===================================================================
--- trunk/src/slave/kpropd.c	2010-06-30 21:52:07 UTC (rev 24155)
+++ trunk/src/slave/kpropd.c	2010-07-01 16:56:22 UTC (rev 24156)
@@ -235,10 +235,35 @@
     gfd = -1;
 }
 
+/* Use getaddrinfo to determine a wildcard listener address, preferring
+ * IPv6 if available. */
+static int
+get_wildcard_addr(struct addrinfo **res)
+{
+    struct addrinfo hints;
+    int error;
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_flags = AI_PASSIVE;
+#ifdef AI_ADDRCONFIG
+    /* Try to avoid IPv6 if the host has no IPv6 interface addresses. */
+    hints.ai_flags |= AI_ADDRCONFIG;
+#endif
+#ifdef KRB5_USE_INET6
+    hints.ai_family = AF_INET6;
+    error = getaddrinfo(NULL, port, &hints, res);
+    if (error == 0)
+        return 0;
+#endif
+    hints.ai_family = AF_INET;
+    return getaddrinfo(NULL, port, &hints, res);
+}
+
 int do_standalone(iprop_role iproprole)
 {
     struct  sockaddr_in     frominet;
-    struct addrinfo hints, *res;
+    struct addrinfo *res;
     int     finet, s;
     GETPEERNAME_ARG3_TYPE fromlen;
     int ret, error, val;
@@ -249,12 +274,7 @@
 
 retry:
 
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_family = AF_UNSPEC;
-    hints.ai_socktype = SOCK_STREAM;
-    hints.ai_flags = AI_PASSIVE;
-
-    error = getaddrinfo(NULL, port, &hints, &res);
+    error = get_wildcard_addr(&res);
     if (error != 0) {
         (void) fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(error));
         exit(1);
@@ -270,11 +290,12 @@
     if (setsockopt(finet, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0)
         com_err(progname, errno, "while setting SO_REUSEADDR option");
 
-#ifdef IPV6_V6ONLY
-    /* Typically, res will be the IPv6 wildcard address.  Some systems, such as
-     * the *BSDs, don't accept IPv4 connections on this address by default. */
+#if defined(KRB5_USE_INET6) && defined(IPV6_V6ONLY)
+    /* Make sure dual-stack support is enabled on IPv6 listener sockets if
+     * possible. */
     val = 0;
-    if (setsockopt(finet, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) < 0)
+    if (res->ai_family == AF_INET6 &&
+        setsockopt(finet, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) < 0)
         com_err(progname, errno, "while unsetting IPV6_V6ONLY option");
 #endif
 




More information about the cvs-krb5 mailing list