I did this
Upload a large file with HTTP/3.
Lots of POLLIN event occurs but recvfrom read nothing.
It is caused by IP_RECVERR socket option [1] set for UDP socket. ngtcp2 does UDP Path MTU Discovery and it might send larger packet than the path can sustain. In this case ICMP message is received, it is resulted in POLLERR, which is translated into POLLIN by curl code. Because IP_RECVERR, the normal recvfrom call does not clear error queue, thus poll keeps returning POLLERR.
It is only cleared by recvmsg with MSG_ERRQUEUE. But it looks like there is no code in curl to do this.
[1]
|
#if defined(__linux__) && defined(IP_RECVERR) |
|
if(addr->socktype == SOCK_DGRAM) { |
|
int one = 1; |
|
switch(addr->family) { |
|
case AF_INET: |
|
(void)setsockopt(*sockfd, SOL_IP, IP_RECVERR, &one, sizeof(one)); |
|
break; |
|
case AF_INET6: |
|
(void)setsockopt(*sockfd, SOL_IPV6, IPV6_RECVERR, &one, sizeof(one)); |
|
break; |
|
} |
|
} |
|
#endif |
I expected the following
curl/libcurl version
curl master branch with ngtcp2 QUIC backend
[curl -V output]
operating system
Linux
I did this
Upload a large file with HTTP/3.
Lots of POLLIN event occurs but recvfrom read nothing.
It is caused by IP_RECVERR socket option [1] set for UDP socket. ngtcp2 does UDP Path MTU Discovery and it might send larger packet than the path can sustain. In this case ICMP message is received, it is resulted in POLLERR, which is translated into POLLIN by curl code. Because IP_RECVERR, the normal recvfrom call does not clear error queue, thus poll keeps returning POLLERR.
It is only cleared by recvmsg with MSG_ERRQUEUE. But it looks like there is no code in curl to do this.
[1]
curl/lib/connect.c
Lines 1670 to 1682 in e28edb6
I expected the following
curl/libcurl version
curl master branch with ngtcp2 QUIC backend
[curl -V output]
operating system
Linux