fix dns
This commit is contained in:
parent
70f8b1c3e2
commit
20a339f6ff
@ -12,14 +12,18 @@ final class DNSLocalClient {
|
||||
|
||||
private var connections: [NWConnection] = []
|
||||
|
||||
// 准备多个公共 DNS
|
||||
private let dnsServers = ["114.114.114.114", "223.5.5.5", "8.8.8.8"]
|
||||
|
||||
// 阿里云 + 腾讯云
|
||||
private let dnsServers = ["223.5.5.5", "119.29.29.29"]
|
||||
|
||||
public let packetFlow: AsyncStream<Data>
|
||||
private let packetContinuation: AsyncStream<Data>.Continuation
|
||||
|
||||
private let locker = NSLock()
|
||||
private var trackers: [UInt16: [DNSTracker]] = [:]
|
||||
|
||||
// 定期的任务清理
|
||||
private var cleanupTask: Task<Void, Never>?
|
||||
private let timeoutInterval: TimeInterval = 10.0 // 超过10秒认为丢包
|
||||
|
||||
init() {
|
||||
let (stream, continuation) = AsyncStream.makeStream(of: Data.self, bufferingPolicy: .unbounded)
|
||||
@ -52,11 +56,21 @@ final class DNSLocalClient {
|
||||
|
||||
connections.append(conn)
|
||||
}
|
||||
|
||||
// 启动清理循环
|
||||
self.cleanupTask = Task { [weak self] in
|
||||
while !Task.isCancelled {
|
||||
// 每隔 cleanupTick 秒运行一次
|
||||
try? await Task.sleep(nanoseconds: 5 * 1_000_000_000)
|
||||
self?.performCleanup()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 并发查询:对所有服务器广播
|
||||
func query(tracker: DNSTracker, dnsPayload: Data) {
|
||||
locker.lock()
|
||||
SDLLogger.shared.log("[DNSLocalClient] query transId: \(tracker.transactionID)")
|
||||
self.trackers[tracker.transactionID, default: []].append(tracker)
|
||||
locker.unlock()
|
||||
|
||||
@ -71,6 +85,7 @@ final class DNSLocalClient {
|
||||
// !!!核心:由于 AsyncStream 是流式的
|
||||
// 谁先 yield,上层就先收到谁。
|
||||
// 只要上层收到了第一个有效响应并回填给系统,
|
||||
SDLLogger.shared.log("[DNSLocalClient] get response data: \(data.count)")
|
||||
self?.handleResponse(data: data)
|
||||
}
|
||||
|
||||
@ -91,6 +106,8 @@ final class DNSLocalClient {
|
||||
let items = self.trackers.removeValue(forKey: tranId)
|
||||
locker.unlock()
|
||||
|
||||
SDLLogger.shared.log("[DNSLocalClient] transId: \(tranId) get response items: \(items?.count)")
|
||||
|
||||
items?.forEach { tracker in
|
||||
let packet = Self.createDNSResponse(
|
||||
payload: data,
|
||||
@ -103,11 +120,33 @@ final class DNSLocalClient {
|
||||
}
|
||||
}
|
||||
|
||||
private func performCleanup() {
|
||||
locker.lock()
|
||||
defer {
|
||||
locker.unlock()
|
||||
}
|
||||
|
||||
// 遍历所有 ID,过滤掉过期的 tracker
|
||||
let now = Date()
|
||||
for (id, list) in trackers {
|
||||
let validItems = list.filter { now.timeIntervalSince($0.createdAt) < timeoutInterval }
|
||||
|
||||
if validItems.isEmpty {
|
||||
trackers.removeValue(forKey: id)
|
||||
} else {
|
||||
trackers[id] = validItems
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func stop() {
|
||||
connections.forEach { conn in
|
||||
conn.cancel()
|
||||
}
|
||||
self.connections.removeAll()
|
||||
|
||||
self.cleanupTask?.cancel()
|
||||
self.cleanupTask = nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user