diff options
author | Willy Tarreau <w@1wt.eu> | 2020-09-01 15:12:08 +0200 |
---|---|---|
committer | Willy Tarreau <w@1wt.eu> | 2020-09-01 15:43:09 +0200 |
commit | 4aa835d24c7120f89a9ad7956fa0a69e22fb92c2 (patch) | |
tree | 41d6cb39c6ffddc98d0d8cfdf3d58cd0646d6bf8 | |
parent | ac3cb36455607c594d3127b0a8fc745aa00c50c3 (diff) | |
download | haproxy-4aa835d24c7120f89a9ad7956fa0a69e22fb92c2.tar.gz |
MINOR: receiver: add the foreign and v6only flags
The new RX_O_FOREIGN and RX_O_V6ONLY flags are now derived from the
listener at the moment the ->bind() call is made. It's difficult to
do it earlier because the keyword parsers are called one at a time
without context so it's not possible to know whether v6only and v4v6
conflict for example, nor is it easy to know when all keywords were
parsed. But fixing the receiver before starting it is fine.
-rw-r--r-- | include/haproxy/receiver-t.h | 2 | ||||
-rw-r--r-- | src/proto_tcp.c | 13 | ||||
-rw-r--r-- | src/sock.c | 13 |
3 files changed, 18 insertions, 10 deletions
diff --git a/include/haproxy/receiver-t.h b/include/haproxy/receiver-t.h index 36841ac11..c56a27473 100644 --- a/include/haproxy/receiver-t.h +++ b/include/haproxy/receiver-t.h @@ -32,6 +32,8 @@ /* Bit values for receiver->options */ #define RX_O_BOUND 0x00000001 /* receiver already bound */ #define RX_O_INHERITED 0x00000002 /* inherited FD from the parent process (fd@) */ +#define RX_O_FOREIGN 0x00000004 /* receives on foreign addresses */ +#define RX_O_V6ONLY 0x00000008 /* binds to IPv6 addresses only */ /* This describes a receiver with all its characteristics (address, options, etc) */ struct receiver { diff --git a/src/proto_tcp.c b/src/proto_tcp.c index db997fda2..4431a6f15 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -577,6 +577,19 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen) if (listener->rx.options & RX_O_BOUND) goto bound; + if (listener->options & LI_O_FOREIGN) + listener->rx.options |= RX_O_FOREIGN; + + if (listener->rx.addr.ss_family == AF_INET6) { + /* Prepare to match the v6only option against what we really want. Note + * that sadly the two options are not exclusive to each other and that + * v6only is stronger than v4v6. + */ + if ((listener->options & LI_O_V6ONLY) || + (sock_inet6_v6only_default && !(listener->options & LI_O_V4V6))) + listener->rx.options |= RX_O_V6ONLY; + } + if (listener->rx.fd == -1) listener->rx.fd = sock_find_compatible_fd(listener); diff --git a/src/sock.c b/src/sock.c index 6e078c0ff..3aa72832e 100644 --- a/src/sock.c +++ b/src/sock.c @@ -372,18 +372,11 @@ int sock_find_compatible_fd(const struct listener *l) if (l->rx.addr.ss_family == AF_CUST_UDP4 || l->rx.addr.ss_family == AF_CUST_UDP6) options |= SOCK_XFER_OPT_DGRAM; - if (l->options & LI_O_FOREIGN) + if (l->rx.options & RX_O_FOREIGN) options |= SOCK_XFER_OPT_FOREIGN; - if (l->rx.addr.ss_family == AF_INET6) { - /* Prepare to match the v6only option against what we really want. Note - * that sadly the two options are not exclusive to each other and that - * v6only is stronger than v4v6. - */ - if ((l->options & LI_O_V6ONLY) || - (sock_inet6_v6only_default && !(l->options & LI_O_V4V6))) - options |= SOCK_XFER_OPT_V6ONLY; - } + if (l->rx.options & RX_O_V6ONLY) + options |= SOCK_XFER_OPT_V6ONLY; if (l->rx.interface) if_namelen = strlen(l->rx.interface); |