From 8d8a13d2d6e5faf881c45e9a28550a256299a3cd Mon Sep 17 00:00:00 2001 From: Brian Gontowski Date: Thu, 4 Jun 2020 20:52:53 +0900 Subject: [PATCH 1/3] Call getifaddrs and freeifaddrs dynamically on Android --- Sources/Foundation/Host.swift | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Sources/Foundation/Host.swift b/Sources/Foundation/Host.swift index 29a1297fe0..dc53c62a22 100644 --- a/Sources/Foundation/Host.swift +++ b/Sources/Foundation/Host.swift @@ -24,6 +24,30 @@ import CoreFoundation private func getnameinfo(_ addr: UnsafePointer?, _ addrlen: socklen_t, _ host: UnsafeMutablePointer?, _ hostlen: socklen_t, _ serv: UnsafeMutablePointer?, _ servlen: socklen_t, _ flags: Int32) -> Int32 { return Glibc.getnameinfo(addr, addrlen, host, Int(hostlen), serv, Int(servlen), flags) } + + // getifaddrs and freeifaddrs are not available in Android 6.0 or earlier, so call the functions dynamically. + + private typealias GetIfAddrsFunc = @convention(c) (UnsafeMutablePointer?>) -> Int32 + private func getifaddrs(_ ifap: UnsafeMutablePointer?>) -> Int32 { + var result: Int32 = 0 + if let handle = dlopen("libc.so", RTLD_NOLOAD) { + if let entry = dlsym(handle, "getifaddrs") { + result = unsafeBitCast(entry, to: GetIfAddrsFunc.self)(ifap) + } + dlclose(handle) + } + return result + } + + private typealias FreeIfAddrsFunc = @convention(c) (UnsafeMutablePointer?) -> Void + private func freeifaddrs(_ ifa: UnsafeMutablePointer?) { + if let handle = dlopen("libc.so", RTLD_NOLOAD) { + if let entry = dlsym(handle, "freeifaddrs") { + unsafeBitCast(entry, to: FreeIfAddrsFunc.self)(ifa) + } + dlclose(handle) + } + } #endif open class Host: NSObject { From 98d78580cf4bded18ccf84307960ecd4a0e40cc4 Mon Sep 17 00:00:00 2001 From: Brian Gontowski Date: Sat, 6 Jun 2020 18:23:56 +0900 Subject: [PATCH 2/3] Added additional notes about the address lookup functions on Android --- Sources/Foundation/Host.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sources/Foundation/Host.swift b/Sources/Foundation/Host.swift index dc53c62a22..ebf47a276c 100644 --- a/Sources/Foundation/Host.swift +++ b/Sources/Foundation/Host.swift @@ -25,7 +25,9 @@ import CoreFoundation return Glibc.getnameinfo(addr, addrlen, host, Int(hostlen), serv, Int(servlen), flags) } - // getifaddrs and freeifaddrs are not available in Android 6.0 or earlier, so call the functions dynamically. + // getifaddrs and freeifaddrs are not available in Android 6.0 or earlier, so call these functions dynamically. + // This only happens during the initial lookup of the addresses and then the results are cached and _resolved is marked true. + // If this API changes so these functions are called more frequently, it might be beneficial to cache the function pointers. private typealias GetIfAddrsFunc = @convention(c) (UnsafeMutablePointer?>) -> Int32 private func getifaddrs(_ ifap: UnsafeMutablePointer?>) -> Int32 { From 4b351cd72f91700bbe7b6b53344c178064419831 Mon Sep 17 00:00:00 2001 From: Brian Gontowski Date: Sat, 27 Jun 2020 07:47:24 +0900 Subject: [PATCH 3/3] Return -1 if getifaddrs is not available --- Sources/Foundation/Host.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Foundation/Host.swift b/Sources/Foundation/Host.swift index ebf47a276c..cbd03197de 100644 --- a/Sources/Foundation/Host.swift +++ b/Sources/Foundation/Host.swift @@ -31,7 +31,7 @@ import CoreFoundation private typealias GetIfAddrsFunc = @convention(c) (UnsafeMutablePointer?>) -> Int32 private func getifaddrs(_ ifap: UnsafeMutablePointer?>) -> Int32 { - var result: Int32 = 0 + var result: Int32 = -1 if let handle = dlopen("libc.so", RTLD_NOLOAD) { if let entry = dlsym(handle, "getifaddrs") { result = unsafeBitCast(entry, to: GetIfAddrsFunc.self)(ifap)