MINOR: receiver: move the FOREIGN and V6ONLY options from listener to settings

The new RX_O_FOREIGN, RX_O_V6ONLY and RX_O_V4V6 options are now set into
the rx_settings part during the parsing, so that we don't need to adjust
them in each and every listener anymore. We have to keep both v4v6 and
v6only due to the precedence from v6only over v4v6.
diff --git a/src/cfgparse-tcp.c b/src/cfgparse-tcp.c
index 7346d65..0bf347b 100644
--- a/src/cfgparse-tcp.c
+++ b/src/cfgparse-tcp.c
@@ -40,26 +40,14 @@
 /* parse the "v4v6" bind keyword */
 static int bind_parse_v4v6(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
 {
-	struct listener *l;
-
-	list_for_each_entry(l, &conf->listeners, by_bind) {
-		if (l->rx.addr.ss_family == AF_INET6)
-			l->options |= LI_O_V4V6;
-	}
-
+	conf->settings.options |= RX_O_V4V6;
 	return 0;
 }
 
 /* parse the "v6only" bind keyword */
 static int bind_parse_v6only(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
 {
-	struct listener *l;
-
-	list_for_each_entry(l, &conf->listeners, by_bind) {
-		if (l->rx.addr.ss_family == AF_INET6)
-			l->options |= LI_O_V6ONLY;
-	}
-
+	conf->settings.options |= RX_O_V6ONLY;
 	return 0;
 }
 #endif
@@ -68,13 +56,7 @@
 /* parse the "transparent" bind keyword */
 static int bind_parse_transparent(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
 {
-	struct listener *l;
-
-	list_for_each_entry(l, &conf->listeners, by_bind) {
-		if (l->rx.addr.ss_family == AF_INET || l->rx.addr.ss_family == AF_INET6)
-			l->options |= LI_O_FOREIGN;
-	}
-
+	conf->settings.options |= RX_O_FOREIGN;
 	return 0;
 }
 #endif
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index fe0fdca..a842e61 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -633,7 +633,7 @@
 		setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
 #endif
 
-	if (!ext && (listener->options & LI_O_FOREIGN)) {
+	if (!ext && (listener->rx.settings->options & RX_O_FOREIGN)) {
 		switch (listener->rx.addr.ss_family) {
 		case AF_INET:
 			if (!sock_inet4_make_foreign(fd)) {
@@ -736,10 +736,17 @@
 	}
 #endif
 #if defined(IPV6_V6ONLY)
-	if (!ext && listener->options & LI_O_V6ONLY)
-                setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
-	else if (!ext && listener->options & LI_O_V4V6)
-                setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero));
+	if (!ext && 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->rx.settings->options & RX_O_V6ONLY) ||
+		    (sock_inet6_v6only_default && !(listener->rx.settings->options & RX_O_V4V6)))
+			setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
+		else
+			setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero));
+	}
 #endif
 
 	if (!ext && bind(fd, (struct sockaddr *)&listener->rx.addr, listener->rx.proto->sock_addrlen) == -1) {
diff --git a/src/proto_udp.c b/src/proto_udp.c
index 64ea639..82a9387 100644
--- a/src/proto_udp.c
+++ b/src/proto_udp.c
@@ -239,7 +239,7 @@
 		setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
 #endif
 
-	if (listener->options & LI_O_FOREIGN) {
+	if (listener->rx.settings->options & RX_O_FOREIGN) {
 		switch (addr_inet.ss_family) {
 		case AF_INET:
 			if (!sock_inet4_make_foreign(fd)) {
@@ -268,10 +268,17 @@
 	}
 #endif
 #if defined(IPV6_V6ONLY)
-	if (listener->options & LI_O_V6ONLY)
-                setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
-	else if (listener->options & LI_O_V4V6)
-                setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero));
+	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->rx.settings->options & RX_O_V6ONLY) ||
+		    (sock_inet6_v6only_default && !(listener->rx.settings->options & RX_O_V4V6)))
+			setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
+		else
+			setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero));
+	}
 #endif
 
 	if (bind(fd, (struct sockaddr *)&addr_inet, listener->rx.proto->sock_addrlen) < 0) {
diff --git a/src/sock.c b/src/sock.c
index 2ff615b..4077d69 100644
--- a/src/sock.c
+++ b/src/sock.c
@@ -369,7 +369,7 @@
 	if (l->rx.proto->sock_type == SOCK_DGRAM)
 		options |= SOCK_XFER_OPT_DGRAM;
 
-	if (l->options & LI_O_FOREIGN)
+	if (l->rx.settings->options & RX_O_FOREIGN)
 		options |= SOCK_XFER_OPT_FOREIGN;
 
 	if (l->rx.addr.ss_family == AF_INET6) {
@@ -377,8 +377,8 @@
 		 * 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)))
+		if ((l->rx.settings->options & RX_O_V6ONLY) ||
+		    (sock_inet6_v6only_default && !(l->rx.settings->options & RX_O_V4V6)))
 			options |= SOCK_XFER_OPT_V6ONLY;
 	}
 
diff --git a/src/sock_inet.c b/src/sock_inet.c
index 3f4edcb..0506c16 100644
--- a/src/sock_inet.c
+++ b/src/sock_inet.c
@@ -116,7 +116,7 @@
 	}
 }
 
-/* Returns true if the passed FD corresponds to a socket bound with LI_O_FOREIGN
+/* Returns true if the passed FD corresponds to a socket bound with RX_O_FOREIGN
  * according to the various supported socket options. The socket's address family
  * must be passed in <family>.
  */