]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: udp: allow to retrieve the frontend destination address
authorDragan Dosen <ddosen@haproxy.com>
Tue, 19 Dec 2023 11:46:01 +0000 (12:46 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 2 Jan 2024 10:44:42 +0000 (11:44 +0100)
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.

include/haproxy/receiver-t.h
src/proto_udp.c

index 0ae441eb9773fcddae84a8e32082a89c13a45210..90f52aae533f1b55181ad1988da4be9202615d6f 100644 (file)
@@ -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 */
index 98559745c38f5fa336b01c0215e75c0298789be8..7308e988b9fc9ff9bdf58c08cf60ec90e7624947 100644 (file)
@@ -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: