增加ipv6的支持

This commit is contained in:
anlicheng 2026-04-15 17:43:43 +08:00
parent df7753cda7
commit ca148acc87
2 changed files with 68 additions and 14 deletions

View File

@ -14,6 +14,7 @@
//
import Foundation
import Network
public struct NetworkInterface {
public let name: String
@ -71,5 +72,69 @@ public struct NetworkInterfaceManager {
return interfaces
}
// IPv6
public static func getPublicIPv6Address() -> String? {
return self.getPublicIPv6Interface()?.ip
}
// IPv6
public static func getPublicIPv6Interface() -> NetworkInterface? {
let interfaces = self.getInterfaces()
return interfaces.first { interface in
!interface.name.hasPrefix("utun")
&& self.isPublicIPv6(interface.ip)
}
}
/// IPv6 IPv6
public static func isPublicIPv6(_ ipString: String) -> Bool {
let normalizedIp = String(ipString.split(separator: "%", maxSplits: 1, omittingEmptySubsequences: false).first ?? "")
guard let ipv6 = IPv6Address(normalizedIp) else {
return false
}
return self.isPublicIPv6(ipv6.rawValue)
}
/// 16 IPv6 IPv6
public static func isPublicIPv6(_ raw: Data) -> Bool {
guard raw.count == 16 else {
return false
}
let bytes = [UInt8](raw)
// 1. unspecified ::
if bytes.allSatisfy({ $0 == 0 }) {
return false
}
// 2. loopback ::1
if bytes.dropLast().allSatisfy({ $0 == 0 }) && bytes[15] == 1 {
return false
}
// 3. multicast ff00::/8
if bytes[0] == 0xFF {
return false
}
// 4. link-local fe80::/10
// 0xFE 10
if bytes[0] == 0xFE && (bytes[1] & 0xC0) == 0x80 {
return false
}
// 5. ULA fc00::/7
// 7 1111110
if (bytes[0] & 0xFE) == 0xFC {
return false
}
// 6. 2000::/3
// 3 001
return (bytes[0] & 0xE0) == 0x20
}
}

View File

@ -550,20 +550,9 @@ actor SDLContextActor {
}
private func makeCurrentV6Info() -> SDLV6Info? {
guard let port = self.udpHoleV6LocalAddress?.port else {
return nil
}
let interfaces = NetworkInterfaceManager.getInterfaces()
let interface = interfaces.first { interface in
interface.ip.contains(":")
&& !interface.name.hasPrefix("utun")
&& !interface.ip.hasPrefix("fe80:")
&& interface.ip != "::"
}
guard let interface,
let ipData = SDLUtil.ipv6StrToData(interface.ip) else {
guard let port = self.udpHoleV6LocalAddress?.port,
let ip = NetworkInterfaceManager.getPublicIPv6Address(),
let ipData = SDLUtil.ipv6StrToData(ip) else {
return nil
}