|
|
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,
|