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
This commit is contained in:
Tatsuhiro Tsujikawa 2022-04-10 17:35:23 +09:00 committed by Daniel Stenberg
parent 7f2e1d345a
commit 8ea851b29d
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 23 additions and 2 deletions

View 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)

View 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. */
}
}
}