]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[1534] Implement the setting
authorMichal 'vorner' Vaner <michal.vaner@nic.cz>
Thu, 16 Feb 2012 12:01:35 +0000 (13:01 +0100)
committerMichal 'vorner' Vaner <michal.vaner@nic.cz>
Thu, 16 Feb 2012 12:01:35 +0000 (13:01 +0100)
But, for some reason, it doesn't really work. The tests fail with
strange error. To be talked about on ML.

src/bin/sockcreator/sockcreator.cc
src/bin/sockcreator/tests/sockcreator_tests.cc

index be359787f11867631166f37f7404e532f92a530e..38547e4d0ef2feaa99381af8c3bf7b21051c473b 100644 (file)
@@ -164,6 +164,40 @@ handleRequest(const int input_fd, const int output_fd,
     }
 }
 
+// Sets the MTU related flags for IPv6 UDP sockets.
+// It is borrowed from bind-9 lib/isc/unix/socket.c and modified
+// to compile here.
+//
+// The function returns -2 if it fails or the socket file descriptor
+// on success (for convenience, so the result can be just returned).
+int
+mtu(int fd) {
+#ifdef IPV6_USE_MIN_MTU        /* RFC 3542, not too common yet*/
+    const int on(1);
+    // use minimum MTU
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU, &on, sizeof(on)) < 0) {
+        return (-2);
+    }
+#endif
+#ifdef IPV6_MTU
+    // Use minimum MTU on systems that don't have the IPV6_USE_MIN_MTU
+    const int mtu = 1280;
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_MTU, &mtu, sizeof(mtu)) < 0) {
+        return (-2);
+    }
+#endif
+#if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT)
+    // Turn off Path MTU discovery on IPv6/UDP sockets.
+    const int action = IPV6_PMTUDISC_DONT;
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &action,
+                   sizeof(action)) < 0) {
+
+        return (-2);
+    }
+#endif
+    return (fd);
+}
+
 } // Anonymous namespace
 
 namespace isc {
@@ -189,6 +223,10 @@ getSock(const int type, struct sockaddr* bind_addr, const socklen_t addr_len) {
     if (bind(sock, bind_addr, addr_len) == -1) {
         return (-2);
     }
+    if (type == SOCK_DGRAM && bind_addr->sa_family == AF_INET6) {
+        // Set some MTU flags on IPv6 UDP sockets.
+        return (mtu(sock));
+    }
     return (sock);
 }
 
index eccc3ed33cf684a44ee26d061425f733074bee40..989815581e05d54225edcf180b3771f6a3ed3482 100644 (file)
@@ -105,15 +105,39 @@ typedef void (*socket_check_t)(const int);
 // The other argument is the socket descriptor number.
 
 // IPv4 check
-void addressFamilySpecificCheck(const sockaddr_in*, const int) {
+void addressFamilySpecificCheck(const sockaddr_in*, const int, const int) {
 }
 
 // IPv6 check
-void addressFamilySpecificCheck(const sockaddr_in6*, const int socknum) {
+void addressFamilySpecificCheck(const sockaddr_in6*, const int socknum,
+                                const int socket_type)
+{
     int options;
     socklen_t len = sizeof(options);
-    EXPECT_EQ(0, getsockopt(socknum, IPPROTO_IPV6, IPV6_V6ONLY, &options, &len));
+    EXPECT_EQ(0, getsockopt(socknum, IPPROTO_IPV6, IPV6_V6ONLY, &options,
+                            &len));
     EXPECT_NE(0, options);
+    if (socket_type == SOCK_DGRAM) {
+    // Some more checks for UDP - MTU
+#ifdef IPV6_USE_MIN_MTU        /* RFC 3542, not too common yet*/
+        // use minimum MTU
+        EXPECT_EQ(getsockopt(socknum, IPPROTO_IPV6, IPV6_USE_MIN_MTU, &options,
+                             &len)) << strerror(errno);
+        EXPECT_NE(0, options);
+#endif
+#ifdef IPV6_MTU
+        // Use minimum MTU on systems that don't have the IPV6_USE_MIN_MTU
+        EXPECT_EQ(0, getsockopt(socknum, IPPROTO_IPV6, IPV6_MTU, &options,
+                                &len)) << strerror(errno);
+        EXPECT_EQ(1280, options);
+#endif
+#if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT)
+        // Turned off Path MTU discovery on IPv6/UDP sockets?
+        EXPECT_EQ(0, getsockopt(socknum, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
+                                &options, &len)) << strerror(errno);
+        EXPECT_EQ(IPV6_PMTUDISC_DONT, options);
+#endif
+    }
 }
 
 
@@ -147,7 +171,7 @@ void testAnyCreate(int socket_type, socket_check_t socket_check) {
     EXPECT_NE(0, options);
 
     // ...and the address-family specific tests.
-    addressFamilySpecificCheck(&addr, socket);
+    addressFamilySpecificCheck(&addr, socket, socket_type);
 
     // Tidy up and exit.
     EXPECT_EQ(0, close(socket));