Skip to content

HTTP/3: Busy loop due to IP_RECVERR #9209

@tatsuhiro-t

Description

@tatsuhiro-t

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

#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

Metadata

Metadata

Assignees

No one assigned

    Labels

    HTTP/3h3 or quic related

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions