From dfc1f6342ada8bf581fda1c97b00ff5e3941f58d Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Tue, 21 Aug 2018 10:43:36 +0200
Subject: [PATCH] net/SocketAddress: add IsV4Mapped()

---
 src/net/SocketAddress.cxx |  6 ++++++
 src/net/SocketAddress.hxx |  6 ++++++
 src/net/ToString.cxx      | 15 ++-------------
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/src/net/SocketAddress.cxx b/src/net/SocketAddress.cxx
index 357cbb8dd..10286b69d 100644
--- a/src/net/SocketAddress.cxx
+++ b/src/net/SocketAddress.cxx
@@ -82,6 +82,12 @@ SocketAddress::IsV6Any() const noexcept
 	return GetFamily() == AF_INET6 && IPv6Address(*this).IsAny();
 }
 
+bool
+SocketAddress::IsV4Mapped() const noexcept
+{
+	return GetFamily() == AF_INET6 && IPv6Address(*this).IsV4Mapped();
+}
+
 unsigned
 SocketAddress::GetPort() const noexcept
 {
diff --git a/src/net/SocketAddress.hxx b/src/net/SocketAddress.hxx
index d7b022d97..7b0ac1b92 100644
--- a/src/net/SocketAddress.hxx
+++ b/src/net/SocketAddress.hxx
@@ -114,6 +114,12 @@ public:
 	gcc_pure
 	bool IsV6Any() const noexcept;
 
+	/**
+	 * Is this an IPv4 address mapped inside struct sockaddr_in6?
+	 */
+	gcc_pure
+	bool IsV4Mapped() const noexcept;
+
 	/**
 	 * Extract the port number.  Returns 0 if not applicable.
 	 */
diff --git a/src/net/ToString.cxx b/src/net/ToString.cxx
index 5dfd8abe9..abfbd88d5 100644
--- a/src/net/ToString.cxx
+++ b/src/net/ToString.cxx
@@ -81,24 +81,13 @@ LocalAddressToString(const struct sockaddr_un &s_un, size_t size) noexcept
 
 #if defined(HAVE_IPV6) && defined(IN6_IS_ADDR_V4MAPPED)
 
-gcc_pure
-static bool
-IsV4Mapped(SocketAddress address) noexcept
-{
-	if (address.GetFamily() != AF_INET6)
-		return false;
-
-	const auto &a6 = *(const struct sockaddr_in6 *)address.GetAddress();
-	return IN6_IS_ADDR_V4MAPPED(&a6.sin6_addr);
-}
-
 /**
  * Convert "::ffff:127.0.0.1" to "127.0.0.1".
  */
 static SocketAddress
 UnmapV4(SocketAddress src, struct sockaddr_in &buffer) noexcept
 {
-	assert(IsV4Mapped(src));
+	assert(src.IsV4Mapped());
 
 	const auto &src6 = *(const struct sockaddr_in6 *)src.GetAddress();
 	memset(&buffer, 0, sizeof(buffer));
@@ -124,7 +113,7 @@ ToString(SocketAddress address) noexcept
 
 #if defined(HAVE_IPV6) && defined(IN6_IS_ADDR_V4MAPPED)
 	struct sockaddr_in in_buffer;
-	if (IsV4Mapped(address))
+	if (address.IsV4Mapped())
 		address = UnmapV4(address, in_buffer);
 #endif