From: Michal 'vorner' Vaner Date: Thu, 16 Feb 2012 12:01:35 +0000 (+0100) Subject: [1534] Implement the setting X-Git-Tag: trac2351_base~226^2~116^2~166^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a0f1ca23cd394e0d94845ecc08c35e56bf313b01;p=thirdparty%2Fkea.git [1534] Implement the setting But, for some reason, it doesn't really work. The tests fail with strange error. To be talked about on ML. --- diff --git a/src/bin/sockcreator/sockcreator.cc b/src/bin/sockcreator/sockcreator.cc index be359787f1..38547e4d0e 100644 --- a/src/bin/sockcreator/sockcreator.cc +++ b/src/bin/sockcreator/sockcreator.cc @@ -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); } diff --git a/src/bin/sockcreator/tests/sockcreator_tests.cc b/src/bin/sockcreator/tests/sockcreator_tests.cc index eccc3ed33c..989815581e 100644 --- a/src/bin/sockcreator/tests/sockcreator_tests.cc +++ b/src/bin/sockcreator/tests/sockcreator_tests.cc @@ -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));