From 93a0d02237bbae63ca66a6d5eff7814a1ada4fbe Mon Sep 17 00:00:00 2001 From: Greg Cotten Date: Mon, 16 Jun 2025 15:44:23 -0700 Subject: [PATCH 1/2] add support for unix "abstract namespace" addresses --- FlyingSocks/Sources/Socket+Android.swift | 18 +++++++++++++++ FlyingSocks/Sources/Socket+Glibc.swift | 18 +++++++++++++++ FlyingSocks/Sources/Socket+Musl.swift | 18 +++++++++++++++ FlyingSocks/Sources/Socket+WinSock2.swift | 18 +++++++++++++++ FlyingSocks/Sources/SocketAddress.swift | 7 +++++- FlyingSocks/Tests/SocketAddressTests.swift | 27 ++++++++++++++++++++++ 6 files changed, 105 insertions(+), 1 deletion(-) diff --git a/FlyingSocks/Sources/Socket+Android.swift b/FlyingSocks/Sources/Socket+Android.swift index b3113088..b6994b62 100644 --- a/FlyingSocks/Sources/Socket+Android.swift +++ b/FlyingSocks/Sources/Socket+Android.swift @@ -99,6 +99,24 @@ extension Socket { return addr } + static func makeAbstractNamespaceUnix(name: String) -> WinSDK.sockaddr_un { + var addr: sockaddr_un = Android.sockaddr_un() + addr.sun_family = sa_family_t(AF_UNIX) + + _ = withUnsafeMutableBytes(of: &addr.sun_path) { raw in + raw.initializeMemory(as: CChar.self, repeating: 0) + } + + let nameBytes = Array(name.utf8.prefix(107)) + nameBytes.withUnsafeBytes { src in + withUnsafeMutableBytes(of: &addr.sun_path) { dst in + dst[1 ..< 1 + src.count].copyBytes(from: src) + } + } + + return addr + } + static func socket(_ domain: Int32, _ type: Int32, _ protocol: Int32) -> FileDescriptorType { Android.socket(domain, type, `protocol`) } diff --git a/FlyingSocks/Sources/Socket+Glibc.swift b/FlyingSocks/Sources/Socket+Glibc.swift index 56103bc6..bd6a0010 100644 --- a/FlyingSocks/Sources/Socket+Glibc.swift +++ b/FlyingSocks/Sources/Socket+Glibc.swift @@ -96,6 +96,24 @@ extension Socket { return addr } + static func makeAbstractNamespaceUnix(name: String) -> Glibc.sockaddr_un { + var addr: sockaddr_un = Glibc.sockaddr_un() + addr.sun_family = sa_family_t(AF_UNIX) + + _ = withUnsafeMutableBytes(of: &addr.sun_path) { raw in + raw.initializeMemory(as: CChar.self, repeating: 0) + } + + let nameBytes = Array(name.utf8.prefix(107)) + nameBytes.withUnsafeBytes { src in + withUnsafeMutableBytes(of: &addr.sun_path) { dst in + dst[1 ..< 1 + src.count].copyBytes(from: src) + } + } + + return addr + } + static func socket(_ domain: Int32, _ type: Int32, _ protocol: Int32) -> FileDescriptorType { Glibc.socket(domain, type, `protocol`) } diff --git a/FlyingSocks/Sources/Socket+Musl.swift b/FlyingSocks/Sources/Socket+Musl.swift index 7e7ebc06..dfd074a3 100644 --- a/FlyingSocks/Sources/Socket+Musl.swift +++ b/FlyingSocks/Sources/Socket+Musl.swift @@ -96,6 +96,24 @@ extension Socket { return addr } + static func makeAbstractNamespaceUnix(name: String) -> Musl.sockaddr_un { + var addr: sockaddr_un = Musl.sockaddr_un() + addr.sun_family = sa_family_t(AF_UNIX) + + _ = withUnsafeMutableBytes(of: &addr.sun_path) { raw in + raw.initializeMemory(as: CChar.self, repeating: 0) + } + + let nameBytes = Array(name.utf8.prefix(107)) + nameBytes.withUnsafeBytes { src in + withUnsafeMutableBytes(of: &addr.sun_path) { dst in + dst[1 ..< 1 + src.count].copyBytes(from: src) + } + } + + return addr + } + static func socket(_ domain: Int32, _ type: Int32, _ protocol: Int32) -> FileDescriptorType { Musl.socket(domain, type, `protocol`) } diff --git a/FlyingSocks/Sources/Socket+WinSock2.swift b/FlyingSocks/Sources/Socket+WinSock2.swift index 41c31bcb..4421f5f5 100755 --- a/FlyingSocks/Sources/Socket+WinSock2.swift +++ b/FlyingSocks/Sources/Socket+WinSock2.swift @@ -107,6 +107,24 @@ extension Socket { return addr } + static func makeAbstractNamespaceUnix(name: String) -> WinSDK.sockaddr_un { + var addr: sockaddr_un = WinSDK.sockaddr_un() + addr.sun_family = ADDRESS_FAMILY(AF_UNIX) + + _ = withUnsafeMutableBytes(of: &addr.sun_path) { raw in + raw.initializeMemory(as: CChar.self, repeating: 0) + } + + let nameBytes = Array(name.utf8.prefix(107)) + nameBytes.withUnsafeBytes { src in + withUnsafeMutableBytes(of: &addr.sun_path) { dst in + dst[1 ..< 1 + src.count].copyBytes(from: src) + } + } + + return addr + } + static func fcntl(_ fd: FileDescriptorType, _ cmd: Int32) -> Int32 { return -1 } diff --git a/FlyingSocks/Sources/SocketAddress.swift b/FlyingSocks/Sources/SocketAddress.swift index 93df5524..789d7790 100644 --- a/FlyingSocks/Sources/SocketAddress.swift +++ b/FlyingSocks/Sources/SocketAddress.swift @@ -107,10 +107,15 @@ public extension SocketAddress where Self == sockaddr_in6 { } public extension SocketAddress where Self == sockaddr_un { - static func unix(path: String) -> Self { Socket.makeAddressUnix(path: path) } + + #if canImport(Glibc) || canImport(Musl) || canImport(Android) || canImport(WinSDK) + static func unix(abstractNamespace: String) -> Self { + Socket.makeAbstractNamespaceUnix(name: abstractNamespace) + } + #endif } #if compiler(>=6.0) diff --git a/FlyingSocks/Tests/SocketAddressTests.swift b/FlyingSocks/Tests/SocketAddressTests.swift index 39bbbfbd..c022a8c1 100644 --- a/FlyingSocks/Tests/SocketAddressTests.swift +++ b/FlyingSocks/Tests/SocketAddressTests.swift @@ -148,6 +148,23 @@ struct SocketAddressTests { ) } + #if canImport(Glibc) || canImport(Musl) || canImport(Android) || canImport(WinSDK) + @Test + func unixAbstractNamespace_IsCorrectlyDecodedFromStorage() throws { + let storage = sockaddr_un + .unix(abstractNamespace: "mygreatnamespace") + .makeStorage() + + var unix = try sockaddr_un.make(from: storage) + let path = withUnsafePointer(to: &unix.sun_path.1) { + return String(cString: $0) + } + #expect( + path == "mygreatnamespace" + ) + } + #endif + @Test func unix_ThrowsInvalidAddress_WhenFamilyIncorrect() { let storage = sockaddr_in6 @@ -183,6 +200,16 @@ struct SocketAddressTests { ) } + #if canImport(Glibc) || canImport(Musl) || canImport(Android) || canImport(WinSDK) + @Test + func unixAbstractNamespace_CheckSize() throws { + let sun = sockaddr_un.unix(abstractNamespace: "some_great_namespace") + #expect( + sun.size == socklen_t(MemoryLayout.size) + ) + } + #endif + @Test func unknown_CheckSize() throws { var sa = sockaddr() From c0f9e6a851b90f0f0a1645abe54525f12fd4de08 Mon Sep 17 00:00:00 2001 From: Greg Cotten Date: Mon, 16 Jun 2025 16:01:21 -0700 Subject: [PATCH 2/2] oops used WinSDK in Android --- FlyingSocks/Sources/Socket+Android.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FlyingSocks/Sources/Socket+Android.swift b/FlyingSocks/Sources/Socket+Android.swift index b6994b62..e9bb2d8d 100644 --- a/FlyingSocks/Sources/Socket+Android.swift +++ b/FlyingSocks/Sources/Socket+Android.swift @@ -99,7 +99,7 @@ extension Socket { return addr } - static func makeAbstractNamespaceUnix(name: String) -> WinSDK.sockaddr_un { + static func makeAbstractNamespaceUnix(name: String) -> Android.sockaddr_un { var addr: sockaddr_un = Android.sockaddr_un() addr.sun_family = sa_family_t(AF_UNIX)