From 7bca61f5bbacfdf19c9e143f3829aa157d22e003 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Mon, 4 Nov 2013 23:36:00 +0100
Subject: [PATCH] event/ServerSocket: don't abort if IPv6 is not available

First check if an IPv6 socket can be created.
---
 NEWS                       |  1 +
 src/event/ServerSocket.cxx | 20 +++++++++++++++++++-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/NEWS b/NEWS
index 0d973584a..914a3449a 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ ver 0.18.1 (2013/11/??)
 * networking:
   - log UNIX domain path names instead of "localhost"
   - open listener sockets in the order they were configured
+  - don't abort if IPv6 is not available
 * filter:
   - autoconvert: fix "volume_normalization" with mp3 files
 * add missing files to source tarball
diff --git a/src/event/ServerSocket.cxx b/src/event/ServerSocket.cxx
index e1fbb34ff..781d29181 100644
--- a/src/event/ServerSocket.cxx
+++ b/src/event/ServerSocket.cxx
@@ -339,6 +339,7 @@ ServerSocket::AddPortIPv4(unsigned port)
 }
 
 #ifdef HAVE_IPV6
+
 inline void
 ServerSocket::AddPortIPv6(unsigned port)
 {
@@ -349,6 +350,22 @@ ServerSocket::AddPortIPv6(unsigned port)
 
 	AddAddress((const sockaddr &)sin, sizeof(sin));
 }
+
+/**
+ * Is IPv6 supported by the kernel?
+ */
+gcc_pure
+static bool
+SupportsIPv6()
+{
+	int fd = socket(AF_INET6, SOCK_STREAM, 0);
+	if (fd < 0)
+		return false;
+
+	close(fd);
+	return true;
+}
+
 #endif /* HAVE_IPV6 */
 
 #endif /* HAVE_TCP */
@@ -363,7 +380,8 @@ ServerSocket::AddPort(unsigned port, Error &error)
 	}
 
 #ifdef HAVE_IPV6
-	AddPortIPv6(port);
+	if (SupportsIPv6())
+		AddPortIPv6(port);
 #endif
 	AddPortIPv4(port);