增加ipv6的支持
This commit is contained in:
parent
df7753cda7
commit
ca148acc87
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user