diff --git a/src/net/AllocatedSocketAddress.cxx b/src/net/AllocatedSocketAddress.cxx
index 8a179a72e..3deb78909 100644
--- a/src/net/AllocatedSocketAddress.cxx
+++ b/src/net/AllocatedSocketAddress.cxx
@@ -64,7 +64,7 @@ AllocatedSocketAddress::SetSize(size_type new_size) noexcept
 
 #ifdef HAVE_UN
 
-StringView
+std::string_view
 AllocatedSocketAddress::GetLocalRaw() const noexcept
 {
 	return SocketAddress(*this).GetLocalRaw();
diff --git a/src/net/AllocatedSocketAddress.hxx b/src/net/AllocatedSocketAddress.hxx
index 591723739..0c2de69b4 100644
--- a/src/net/AllocatedSocketAddress.hxx
+++ b/src/net/AllocatedSocketAddress.hxx
@@ -35,10 +35,13 @@
 
 #include <utility>
 
+#ifdef HAVE_UN
+#include <string_view>
+#endif
+
 #include <stdlib.h>
 
 struct sockaddr;
-struct StringView;
 
 class AllocatedSocketAddress {
 public:
@@ -145,7 +148,7 @@ public:
 	 * @see SocketAddress::GetLocalRaw()
 	 */
 	[[gnu::pure]]
-	StringView GetLocalRaw() const noexcept;
+	std::string_view GetLocalRaw() const noexcept;
 
 	/**
 	 * @see SocketAddress::GetLocalPath()
diff --git a/src/net/SocketAddress.cxx b/src/net/SocketAddress.cxx
index c0d1737b2..6963c50b7 100644
--- a/src/net/SocketAddress.cxx
+++ b/src/net/SocketAddress.cxx
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2021 Max Kellermann <max.kellermann@gmail.com>
+ * Copyright 2012-2022 Max Kellermann <max.kellermann@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -56,12 +56,12 @@ SocketAddress::operator==(SocketAddress other) const noexcept
 
 #ifdef HAVE_UN
 
-StringView
+std::string_view
 SocketAddress::GetLocalRaw() const noexcept
 {
 	if (IsNull() || GetFamily() != AF_LOCAL)
 		/* not applicable */
-		return nullptr;
+		return {};
 
 	const auto *sun = &CastTo<struct sockaddr_un>();
 	const auto start = (const char *)sun;
@@ -69,7 +69,7 @@ SocketAddress::GetLocalRaw() const noexcept
 	const size_t header_size = path - start;
 	if (size < size_type(header_size))
 		/* malformed address */
-		return nullptr;
+		return {};
 
 	return {path, size - header_size};
 }
@@ -84,8 +84,8 @@ SocketAddress::GetLocalPath() const noexcept
 		/* must be null-terminated */
 		raw.back() == 0 &&
 		/* there must not be any other null byte */
-		std::memchr(raw.data, 0, raw.size - 1) == nullptr
-		? raw.data
+		std::memchr(raw.data(), 0, raw.size() - 1) == nullptr
+		? raw.data()
 		: nullptr;
 }
 
@@ -131,30 +131,36 @@ SocketAddress::GetPort() const noexcept
 	}
 }
 
-static constexpr ConstBuffer<void>
+static std::span<const std::byte>
 GetSteadyPart(const struct sockaddr_in &address) noexcept
 {
-	return {&address.sin_addr, sizeof(address.sin_addr)};
+	return {
+		reinterpret_cast<const std::byte *>(&address.sin_addr),
+		sizeof(address.sin_addr),
+	};
 }
 
-static constexpr ConstBuffer<void>
+static std::span<const std::byte>
 GetSteadyPart(const struct sockaddr_in6 &address) noexcept
 {
-	return {&address.sin6_addr, sizeof(address.sin6_addr)};
+	return {
+		reinterpret_cast<const std::byte *>(&address.sin6_addr),
+		sizeof(address.sin6_addr),
+	};
 }
 
 #endif
 
-ConstBuffer<void>
+std::span<const std::byte>
 SocketAddress::GetSteadyPart() const noexcept
 {
 	if (IsNull())
-		return nullptr;
+		return {};
 
 	switch (GetFamily()) {
 #ifdef HAVE_UN
 	case AF_LOCAL:
-		return GetLocalRaw().ToVoid();
+		return std::as_bytes(std::span<const char>{GetLocalRaw()});
 #endif
 
 #ifdef HAVE_TCP
@@ -166,6 +172,6 @@ SocketAddress::GetSteadyPart() const noexcept
 #endif
 
 	default:
-		return nullptr;
+		return {};
 	}
 }
diff --git a/src/net/SocketAddress.hxx b/src/net/SocketAddress.hxx
index b143c5358..420d32939 100644
--- a/src/net/SocketAddress.hxx
+++ b/src/net/SocketAddress.hxx
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2021 Max Kellermann <max.kellermann@gmail.com>
+ * Copyright 2012-2022 Max Kellermann <max.kellermann@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,17 +32,19 @@
 
 #include "Features.hxx"
 
-#include <cstddef>
-#include <span>
-
 #ifdef _WIN32
 #include <winsock2.h> // IWYU pragma: export
 #else
 #include <sys/socket.h> // IWYU pragma: export
 #endif
 
-template<typename T> struct ConstBuffer;
-struct StringView;
+#include <cstddef>
+#include <span>
+
+#ifdef HAVE_UN
+#include <string_view>
+#endif
+
 class IPv4Address;
 
 /**
@@ -123,7 +125,7 @@ public:
 	 * nullptr if not applicable.
 	 */
 	[[gnu::pure]]
-	StringView GetLocalRaw() const noexcept;
+	std::string_view GetLocalRaw() const noexcept;
 
 	/**
 	 * Returns the local socket path or nullptr if not applicable
@@ -175,7 +177,7 @@ public:
 	 * not supported.
 	 */
 	[[gnu::pure]]
-	ConstBuffer<void> GetSteadyPart() const noexcept;
+	std::span<const std::byte> GetSteadyPart() const noexcept;
 
 	[[gnu::pure]]
 	bool operator==(const SocketAddress other) const noexcept;