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.
This commit is contained in:
Dragan Dosen 2023-12-19 12:46:01 +01:00 committed by Willy Tarreau
parent 1582ccf9d3
commit 96c1a61136
2 changed files with 21 additions and 0 deletions

View 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_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_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_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 */ /* Bit values for rx_settings->options */
#define RX_O_FOREIGN 0x00000001 /* receives on foreign addresses */ #define RX_O_FOREIGN 0x00000001 /* receives on foreign addresses */

View File

@ -155,6 +155,26 @@ int udp_bind_listener(struct listener *listener, char *errmsg, int errlen)
if (global.tune.frontend_sndbuf) if (global.tune.frontend_sndbuf)
setsockopt(listener->rx.fd, SOL_SOCKET, SO_SNDBUF, &global.tune.frontend_sndbuf, sizeof(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); listener_set_state(listener, LI_LISTEN);
udp_return: udp_return: