kernel version. Some distribution kernels include backports of the feature,
so check for support with your vendor.
+v4v6
+ Is an optional keyword which is supported only on most recent systems
+ including Linux kernels >= 2.4.21. It is used to bind a socket to both IPv4
+ and IPv6 when it uses the default address. Doing so is sometimes necessary
+ on systems which bind to IPv6 only by default. It has no effect on non-IPv6
+ sockets, and is overriden by the "v6only" option.
+
v6only
Is an optional keyword which is supported only on most recent systems
including Linux kernels >= 2.4.21. It is used to bind a socket to IPv6 only
when it uses the default address. Doing so is sometimes preferred to doing it
- system-wide as it is per-listener. It has no effect on non-IPv6 sockets.
+ system-wide as it is per-listener. It has no effect on non-IPv6 sockets and
+ has precedence over the "v4v6" option.
uid <uid>
Sets the owner of the UNIX sockets to the designated system uid. It can also
#define LI_O_UNLIMITED 0x0080 /* listener not subject to global limits (peers & stats socket) */
#define LI_O_TCP_FO 0x0100 /* enable TCP Fast Open (linux >= 3.6) */
#define LI_O_V6ONLY 0x0200 /* bind to IPv6 only on Linux >= 2.4.21 */
+#define LI_O_V4V6 0x0400 /* bind to IPv4/IPv6 on Linux >= 2.4.21 */
/* Note: if a listener uses LI_O_UNLIMITED, it is highly recommended that it adds its own
* maxconn setting to the global.maxsock value so that its resources are reserved.
#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));
#endif
if (bind(fd, (struct sockaddr *)&listener->addr, listener->proto->sock_addrlen) == -1) {
}
#ifdef IPV6_V6ONLY
+/* 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->addr.ss_family == AF_INET6)
+ l->options |= LI_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)
{
{ "transparent", bind_parse_transparent, 0 }, /* transparently bind to the specified addresses */
#endif
#ifdef IPV6_V6ONLY
+ { "v4v6", bind_parse_v4v6, 0 }, /* force socket to bind to IPv4+IPv6 */
{ "v6only", bind_parse_v6only, 0 }, /* force socket to bind to IPv6 only */
#endif
/* the versions with the NULL parse function*/
{ "interface", NULL, 1 },
{ "mss", NULL, 1 },
{ "transparent", NULL, 0 },
+ { "v4v6", NULL, 0 },
{ "v6only", NULL, 0 },
{ NULL, NULL, 0 },
}};