0

以下代码用于将 a 转换sockaddr为 asockaddr_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:堆栈缓冲区溢出地址 0x000131810077 在 pc 0x00010a3c06d5 bp 0x7fff55ded010 sp 0x7fff55ded008 在 0x000131810077 线程 T0 处读取大小 16

我可以理解,ASAN 担心我正在阅读超出边界sockaddr以获取完整信息sockaddr_in6sockaddr即 16 字节,sockaddr_in6即 28 字节)。

但由于这个原因,我似乎无法使用 ASAN 测试我的应用程序的其余部分。任何使用withMemoryRebound都会使 ASAN 跳闸似乎有点奇怪。

我尝试以不同的方式编写它,甚至Data用作字节的容器。但我似乎总能找到触发 ASAN 的解决方案。

我的代码有问题吗?
或者我可以以某种方式忽略 ASAN 中的这个功能吗?

4

1 回答 1

0

函数返回的指针getifaddrs看起来像一个sockaddr指针,但实际上是指向sockaddr_inor的指针sockaddr_in6。通过将addressV6函数移动到 上的扩展sockaddr,内存被复制并切割成sockaddr结构的大小。在 IPv6 的情况下,有价值的地址信息会丢失。

新的(修剪过的)sockaddr永远无法转换为sockaddr_in6触发 SAN。

有关更多信息,请参阅: Swift getnameinfo unreliable results for IPv6

感谢@MartinR 帮助我解决这个问题!

于 2017-06-11T01:18:55.957 回答