I have the following extension on sockaddr
:
extension sockaddr {
/// Indicates if this is an IPv4 address.
var isIPv4: Bool {
return sa_family == UInt8(AF_INET)
}
/// Indicates if this is an IPv6 address.
var isIPv6: Bool {
return sa_family == UInt8(AF_INET6)
}
/// Returns the address in string notation.
var address: String? {
var result: String = ""
var me = self
var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
if getnameinfo(&me, socklen_t(me.sa_len), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST) == 0 {
result = String(cString: hostname)
}
return result
}
}
In an other part of my code I'm calling getifaddrs
to get the interface addresses of the current device. The code above works fine for IPv4, but is somewhat unreliable for IPv6.
I get results like: 192.168.1.10
and fe80::e0fa:1204:100:0
When I change the line var result: String = ""
to var result: String? = nil
. The IPv6 addresses suddenly become fe80::
, the rest is cut off.
Even weirder, when I just switch the var result
and the var me = self
lines like this:
extension sockaddr {
/// Indicates if this is an IPv4 address.
var isIPv4: Bool {
return sa_family == UInt8(AF_INET)
}
/// Indicates if this is an IPv6 address.
var isIPv6: Bool {
return sa_family == UInt8(AF_INET6)
}
/// Returns the address in string notation.
var address: String? {
var me = self
var result: String = ""
var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
if getnameinfo(&me, socklen_t(me.sa_len), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST) == 0 {
result = String(cString: hostname)
}
return result
}
}
Then the function will only work for IPv4 addresses. The getnameinfo
will return 4 (FAIL).
This is during debugging, with no optimizations that I know of. It doesn't matter if I run it on a simulator or real device.
Could someone please explain why this is happening?