From: Dragan Dosen Date: Tue, 19 Dec 2023 11:46:01 +0000 (+0100) Subject: MEDIUM: udp: allow to retrieve the frontend destination address X-Git-Tag: v3.0-dev1~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=96c1a61136e81003ebe119f9bd032f4b5676ef68;p=thirdparty%2Fhaproxy.git MEDIUM: udp: allow to retrieve the frontend destination address A new flag RX_F_PASS_PKTINFO is now available, whose purpose is to mark that the destination address is about to be retrieved on some listeners. The address can be retrieved from the first received datagram, and relies on the IP_PKTINFO, IP_RECVDSTADDR and IPV6_RECVPKTINFO support. --- diff --git a/include/haproxy/receiver-t.h b/include/haproxy/receiver-t.h index 0ae441eb97..90f52aae53 100644 --- a/include/haproxy/receiver-t.h +++ b/include/haproxy/receiver-t.h @@ -37,6 +37,7 @@ #define RX_F_MWORKER 0x00000004 /* keep the FD open in the master but close it in the children */ #define RX_F_MUST_DUP 0x00000008 /* this receiver's fd must be dup() from a reference; ignore socket-level ops here */ #define RX_F_NON_SUSPENDABLE 0x00000010 /* this socket cannot be suspended hence must always be unbound */ +#define RX_F_PASS_PKTINFO 0x00000020 /* pass pktinfo in received messages */ /* Bit values for rx_settings->options */ #define RX_O_FOREIGN 0x00000001 /* receives on foreign addresses */ diff --git a/src/proto_udp.c b/src/proto_udp.c index 98559745c3..7308e988b9 100644 --- a/src/proto_udp.c +++ b/src/proto_udp.c @@ -155,6 +155,26 @@ int udp_bind_listener(struct listener *listener, char *errmsg, int errlen) if (global.tune.frontend_sndbuf) setsockopt(listener->rx.fd, SOL_SOCKET, SO_SNDBUF, &global.tune.frontend_sndbuf, sizeof(global.tune.frontend_sndbuf)); + if (listener->rx.flags & RX_F_PASS_PKTINFO) { + /* set IP_PKTINFO to retrieve destination address on recv */ + switch (listener->rx.addr.ss_family) { + case AF_INET: +#if defined(IP_PKTINFO) + setsockopt(listener->rx.fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one)); +#elif defined(IP_RECVDSTADDR) + setsockopt(listener->rx.fd, IPPROTO_IP, IP_RECVDSTADDR, &one, sizeof(one)); +#endif /* IP_PKTINFO || IP_RECVDSTADDR */ + break; + case AF_INET6: +#ifdef IPV6_RECVPKTINFO + setsockopt(listener->rx.fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one)); +#endif + break; + default: + break; + } + } + listener_set_state(listener, LI_LISTEN); udp_return: