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