]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
ngtcp2: Allow curl to send larger UDP datagrams
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Sun, 10 Apr 2022 08:35:23 +0000 (17:35 +0900)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 20 May 2022 15:50:38 +0000 (17:50 +0200)
Allow curl to send larger UDP datagram if Path MTU Discovery finds the
availability of larger path MTU.  To make it work and not to send
fragmented packet, we need to set DF bit.  That makes send(2) fail with
EMSGSIZE if UDP datagram is too large.  In that case, just let it be
lost.  This patch enables DF bit for Linux only.

Closes #8883

lib/connect.c
lib/vquic/ngtcp2.c

index a50c09a3385bf5f04d191b9312ccb5bc85f54ea0..a0f1f17400688167eec527a21490703018fec062 100644 (file)
@@ -1638,6 +1638,24 @@ CURLcode Curl_socket(struct Curl_easy *data,
   if(conn->transport == TRNSPRT_QUIC) {
     /* QUIC sockets need to be nonblocking */
     (void)curlx_nonblock(*sockfd, TRUE);
+    switch(addr->family) {
+#if defined(__linux__) && defined(IP_MTU_DISCOVER)
+    case AF_INET: {
+      int val = IP_PMTUDISC_DO;
+      (void)setsockopt(*sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &val,
+                       sizeof(val));
+      break;
+    }
+#endif
+#if defined(__linux__) && defined(IPV6_MTU_DISCOVER)
+    case AF_INET6: {
+      int val = IPV6_PMTUDISC_DO;
+      (void)setsockopt(*sockfd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &val,
+                       sizeof(val));
+      break;
+    }
+#endif
+    }
   }
 
 #if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
index f2acce123bd524192bbb2463b17be49d46bcacb6..239e1d160f6a7b960b6103470600b0f140c59c73 100644 (file)
@@ -1814,7 +1814,7 @@ static CURLcode ng_flush_egress(struct Curl_easy *data,
   int rv;
   ssize_t sent;
   ngtcp2_ssize outlen;
-  uint8_t out[NGTCP2_MAX_UDP_PAYLOAD_SIZE];
+  uint8_t out[NGTCP2_MAX_PMTUD_UDP_PAYLOAD_SIZE];
   ngtcp2_path_storage ps;
   ngtcp2_tstamp ts = timestamp();
   ngtcp2_tstamp expiry;
@@ -1924,7 +1924,10 @@ static CURLcode ng_flush_egress(struct Curl_easy *data,
       else {
         failf(data, "send() returned %zd (errno %d)", sent,
               SOCKERRNO);
-        return CURLE_SEND_ERROR;
+        if(SOCKERRNO != EMSGSIZE) {
+          return CURLE_SEND_ERROR;
+        }
+        /* UDP datagram is too large; caused by PMTUD. Just let it be lost. */
       }
     }
   }