]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Linux IPv6 large response support.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 29 Jun 2009 13:47:48 +0000 (13:47 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 29 Jun 2009 13:47:48 +0000 (13:47 +0000)
git-svn-id: file:///svn/unbound/trunk@1689 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
services/listen_dnsport.c

index 986f3ba4c1b90f8a2cce8dfbb219f11acfb22663..69e51130b132af251b5a9c05b727c74b8ee186ec 100644 (file)
@@ -2,6 +2,8 @@
        - ldns trunk r2959 imported as tarball, because of solaris cc compile
          support for c99.  r2960 for better configure.
        - better wrongly_truncated check.
+       - On Linux, fragment IPv6 datagrams to the IPv6 minimum MTU, to
+         avoid dropped packets at routers.
 
 26 June 2009: Wouter
        - Fix EDNS fallback when EDNS works for short answers but long answers
index c6079008c198e4b3db00d706a667709c5b8d3e4d..ac9acc8464e7bab94f1670ab8c7812ebcb4e1e77 100644 (file)
@@ -92,11 +92,15 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
         socklen_t addrlen, int v6only, int* inuse, int* noproto)
 {
        int s;
-# if defined(IPV6_USE_MIN_MTU)
+#if defined(IPV6_USE_MIN_MTU)
        int on=1;
-# else
+#endif
+#ifdef IPV6_MTU
+       int mtu = IPV6_MIN_MTU;
+#endif
+#ifndef IPV6_V6ONLY
        (void)v6only;
-# endif
+#endif
        if((s = socket(family, socktype, 0)) == -1) {
                *inuse = 0;
 #ifndef USE_WINSOCK
@@ -150,21 +154,42 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
                 */
                if (setsockopt(s, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
                        (void*)&on, (socklen_t)sizeof(on)) < 0) {
-#ifndef USE_WINSOCK
+#  ifndef USE_WINSOCK
                        log_err("setsockopt(..., IPV6_USE_MIN_MTU, "
                                "...) failed: %s", strerror(errno));
                        close(s);
-#else
+#  else
                        log_err("setsockopt(..., IPV6_USE_MIN_MTU, "
                                "...) failed: %s", 
                                wsa_strerror(WSAGetLastError()));
                        closesocket(s);
-#endif
+#  endif
                        *noproto = 0;
                        *inuse = 0;
                        return -1;
                }
-# endif
+# elif defined(IPV6_MTU)
+               /*
+                * On Linux, to send no larger than 1280, the PMTUD is
+                * disabled by default for datagrams anyway, so we set
+                * the MTU to use.
+                */
+               if (setsockopt(s, IPPROTO_IPV6, IPV6_MTU,
+                       (void*)&mtu, (socklen_t)sizeof(mtu)) < 0) {
+#  ifndef USE_WINSOCK
+                       log_err("setsockopt(..., IPV6_MTU, ...) failed: %s", 
+                               strerror(errno));
+                       close(s);
+#  else
+                       log_err("setsockopt(..., IPV6_MTU, ...) failed: %s", 
+                               wsa_strerror(WSAGetLastError()));
+                       closesocket(s);
+#  endif
+                       *noproto = 0;
+                       *inuse = 0;
+                       return -1;
+               }
+# endif /* IPv6 MTU */
        }
        if(bind(s, (struct sockaddr*)addr, addrlen) != 0) {
                *noproto = 0;