From: Tatsuhiro Tsujikawa Date: Sun, 10 Apr 2022 08:35:23 +0000 (+0900) Subject: ngtcp2: Allow curl to send larger UDP datagrams X-Git-Tag: curl-7_84_0~156 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8ea851b29d4beb73808b4c8cc502c0cdd33b6142;p=thirdparty%2Fcurl.git ngtcp2: Allow curl to send larger UDP datagrams 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 --- diff --git a/lib/connect.c b/lib/connect.c index a50c09a338..a0f1f17400 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -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) diff --git a/lib/vquic/ngtcp2.c b/lib/vquic/ngtcp2.c index f2acce123b..239e1d160f 100644 --- a/lib/vquic/ngtcp2.c +++ b/lib/vquic/ngtcp2.c @@ -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. */ } } }