以下代码用于将sockaddr
转换为sockaddr_in6
以获取IPv6地址:
extension sockaddr {
private var addressV6: String {
var me = self
var buffer = [Int8](repeating: 0, count: Int(INET6_ADDRSTRLEN))
withUnsafePointer(to: &me) {
$0.withMemoryRebound(to: sockaddr_in6.self, capacity: 1) {
var addrV6 = $0.pointee.sin6_addr
inet_ntop(AF_INET6, &addrV6, &buffer, socklen_t(INET6_ADDRSTRLEN))
}
}
return String(cString: buffer)
}
}
当我使用 Address Sanitizer 在 Xcode 9 beta 中运行代码时,执行会在此行停止:
var addrV6 = $0.pointee.sin6_addr
带有以下消息(加上大量内存信息):
AddressSanitizer: stack-buffer-overflow on address 0x000131810077 at pc 0x00010a3c06d5 bp 0x7fff55ded010 sp 0x7fff55ded008 READ of size 16 at 0x000131810077 thread T0
我可以理解,ASAN 担心我读取的内容超出了 sockaddr
的边界,以获取完整的 sockaddr_in6
(sockaddr
> 为 16 字节,sockaddr_in6
为 28 字节)。
但因此我似乎无法使用 ASAN 测试我的应用程序的其余部分。任何使用 withMemoryRebound
都会使 ASAN 出错,这似乎有点奇怪。
我尝试以不同的方式编写它,甚至使用Data
作为字节的容器。但我似乎总是最终得到一个触发 ASAN 的解决方案。
我的代码有问题吗?
或者我可以以某种方式忽略 ASAN 中的这个功能吗?
最佳答案
getifaddrs
返回的指针函数看起来像 sockaddr
指针但实际上是指向 sockaddr_in
的指针或sockaddr_in6
。通过移动addressV6
函数 sockaddr
上的扩展,内存被复制并剪切为 sockaddr
的大小结构。如果使用 IPv6,有值(value)的地址信息将会丢失。
新的(已修剪)sockaddr
永远无法转换为 sockaddr_in6
触发 SAN。
欲了解更多信息,请参阅: Swift getnameinfo unreliable results for IPv6
感谢@MartinR 帮助我解决这个问题!
关于swift - Xcode Address Sanitizer 与 sockaddr 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44426911/