From: Amaury Denoyelle Date: Tue, 11 Oct 2022 14:22:18 +0000 (+0200) Subject: BUG/MINOR: quic: set IP_PKTINFO socket option for QUIC receivers only X-Git-Tag: v2.7-dev8~56 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=487d04f6d7410059b44b69d56c53be7802963bab;p=thirdparty%2Fhaproxy.git BUG/MINOR: quic: set IP_PKTINFO socket option for QUIC receivers only Move code which activates IP_PKTINFO socket option (or affiliated options) from sock_inet_bind_receiver() to quic_bind_listener() function. This change is useful for two reasons : * first, and the most important one : this activates IP_PKTINFO only for QUIC receivers. The previous version impacted all datagram receivers, used for example by log-forwarder. This should reduce memory usage for these datagram sockets which do not need this option. * second, USE_QUIC preprocessor statements are removed from src/sock_inet.c which clean up the code. IP_PKTINFO was introduced recently by the following patch : 97ecc7a8ea5339a753507c3d4e4cd83028c6d038 (quic-dev/qns) MEDIUM: quic: retrieve frontend destination address For the moment, this does not impact any stable release. However, as previous patch is scheduled for 2.6 backporting, the current change must also be backported to the same versions. --- diff --git a/src/proto_quic.c b/src/proto_quic.c index 34e22b8dc8..cf1e0ded10 100644 --- a/src/proto_quic.c +++ b/src/proto_quic.c @@ -592,7 +592,8 @@ static int quic_alloc_rxbufs_listener(struct listener *l) */ static int quic_bind_listener(struct listener *listener, char *errmsg, int errlen) { - int err = ERR_NONE; + const struct sockaddr_storage addr = listener->rx.addr; + int fd, err = ERR_NONE; char *msg = NULL; /* ensure we never return garbage */ @@ -607,6 +608,25 @@ static int quic_bind_listener(struct listener *listener, char *errmsg, int errle goto udp_return; } + /* Set IP_PKTINFO to retrieve destination address on recv. */ + fd = listener->rx.fd; + switch (addr.ss_family) { + case AF_INET: +#if defined(IP_PKTINFO) + setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one)); +#elif defined(IP_RECVDSTADDR) + setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &one, sizeof(one)); +#endif /* IP_PKTINFO || IP_RECVDSTADDR */ + break; + case AF_INET6: +#ifdef IPV6_RECVPKTINFO + setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one)); +#endif + break; + default: + break; + } + if (!quic_alloc_rxbufs_listener(listener)) { msg = "could not initialize tx/rx rings"; err |= ERR_WARN; diff --git a/src/sock_inet.c b/src/sock_inet.c index f8e872cbf1..d517e4c423 100644 --- a/src/sock_inet.c +++ b/src/sock_inet.c @@ -381,25 +381,6 @@ int sock_inet_bind_receiver(struct receiver *rx, char **errmsg) } #endif -#ifdef USE_QUIC - if (rx->proto->proto_type == PROTO_TYPE_DGRAM) { - switch (addr_inet.ss_family) { - case AF_INET: -#if defined(IP_PKTINFO) - setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one)); -#elif defined(IP_RECVDSTADDR) - setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &one, sizeof(one)); -#endif /* IP_PKTINFO || IP_RECVDSTADDR */ - break; - case AF_INET6: -#ifdef IPV6_RECVPKTINFO - setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one)); -#endif - break; - } - } -#endif /* USE_QUIC */ - if (!ext && bind(fd, (struct sockaddr *)&addr_inet, rx->proto->fam->sock_addrlen) == -1) { err |= ERR_RETRYABLE | ERR_ALERT; memprintf(errmsg, "cannot bind socket (%s)", strerror(errno));