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

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