Blame SOURCES/audit-2.8.2-ipv6-bind.patch

7bdd34
From 659bfd369dc6810ac5349c433455c0d317482354 Mon Sep 17 00:00:00 2001
7bdd34
From: Steve Grubb <sgrubb@redhat.com>
7bdd34
Date: Tue, 17 Oct 2017 14:31:46 -0400
7bdd34
Subject: [PATCH] Fixup ipv6 server side binding
7bdd34
7bdd34
---
7bdd34
 src/auditd-listen.c | 32 ++++++++++++++++++++++++++++++++
7bdd34
 2 files changed, 33 insertions(+)
7bdd34
7bdd34
diff --git a/src/auditd-listen.c b/src/auditd-listen.c
7bdd34
index 7a5c2c6..0d1717f 100644
7bdd34
--- a/src/auditd-listen.c
7bdd34
+++ b/src/auditd-listen.c
7bdd34
@@ -914,6 +914,7 @@ int auditd_tcp_listen_init(struct ev_loop *loop, struct daemon_conf *config)
7bdd34
 	struct addrinfo hints;
7bdd34
 	char local[16];
7bdd34
 	int one = 1, rc;
7bdd34
+	int prefer_ipv6 = 0;
7bdd34
 
7bdd34
 	ev_periodic_init(&periodic_watcher, periodic_handler,
7bdd34
 			  0, config->tcp_client_max_idle, NULL);
7bdd34
@@ -929,6 +930,7 @@ int auditd_tcp_listen_init(struct ev_loop *loop, struct daemon_conf *config)
7bdd34
 	memset(&hints, '\0', sizeof(hints));
7bdd34
 	hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
7bdd34
 	hints.ai_socktype = SOCK_STREAM;
7bdd34
+	hints.ai_family = AF_UNSPEC;
7bdd34
 	snprintf(local, sizeof(local), "%ld", config->tcp_listen_port);
7bdd34
 
7bdd34
 	rc = getaddrinfo(NULL, local, &hints, &ai;;
7bdd34
@@ -937,9 +939,32 @@ int auditd_tcp_listen_init(struct ev_loop *loop, struct daemon_conf *config)
7bdd34
 		return 1;
7bdd34
 	}
7bdd34
 
7bdd34
+	{
7bdd34
+	int ipv4 = 0, ipv6 = 0;
7bdd34
 	nlsocks = 0;
7bdd34
 	runp = ai;
7bdd34
 	while (runp && nlsocks < N_SOCKS) {
7bdd34
+		// Let's take a pass through and see what we got.
7bdd34
+		if (runp->ai_family == AF_INET)
7bdd34
+			ipv4++;
7bdd34
+		else if (runp->ai_family == AF_INET6)
7bdd34
+			ipv6++;
7bdd34
+		runp = runp->ai_next;
7bdd34
+		nlsocks++;
7bdd34
+	}
7bdd34
+
7bdd34
+	if (nlsocks == 2 && ipv4 && ipv6)
7bdd34
+		prefer_ipv6 = 1;
7bdd34
+	}
7bdd34
+
7bdd34
+	nlsocks = 0;
7bdd34
+	runp = ai;
7bdd34
+	while (runp && nlsocks < N_SOCKS) {
7bdd34
+		// On linux, ipv6 sockets by default include ipv4 so
7bdd34
+		// we only need one.
7bdd34
+		if (runp->ai_family == AF_INET && prefer_ipv6)
7bdd34
+			goto next_try;
7bdd34
+			
7bdd34
 		listen_socket[nlsocks] = socket(runp->ai_family,
7bdd34
 				 runp->ai_socktype, runp->ai_protocol);
7bdd34
 		if (listen_socket[nlsocks] < 0) {
7bdd34
@@ -950,6 +975,13 @@ int auditd_tcp_listen_init(struct ev_loop *loop, struct daemon_conf *config)
7bdd34
 		/* This avoids problems if auditd needs to be restarted.  */
7bdd34
 		setsockopt(listen_socket[nlsocks], SOL_SOCKET, SO_REUSEADDR,
7bdd34
 				(char *)&one, sizeof (int));
7bdd34
+
7bdd34
+		// If we had more than 2 addresses suggested we'll
7bdd34
+		// separate the sockets.
7bdd34
+		if (!prefer_ipv6 && runp->ai_family == AF_INET6)
7bdd34
+			setsockopt(listen_socket[nlsocks], IPPROTO_IPV6,
7bdd34
+				IPV6_V6ONLY, &one, sizeof(int));
7bdd34
+
7bdd34
 		set_close_on_exec(listen_socket[nlsocks]);
7bdd34
 
7bdd34
 		if (bind(listen_socket[nlsocks], runp->ai_addr,