fix dns
This commit is contained in:
parent
70f8b1c3e2
commit
20a339f6ff
@ -12,14 +12,18 @@ final class DNSLocalClient {
|
|||||||
|
|
||||||
private var connections: [NWConnection] = []
|
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>
|
public let packetFlow: AsyncStream<Data>
|
||||||
private let packetContinuation: AsyncStream<Data>.Continuation
|
private let packetContinuation: AsyncStream<Data>.Continuation
|
||||||
|
|
||||||
private let locker = NSLock()
|
private let locker = NSLock()
|
||||||
private var trackers: [UInt16: [DNSTracker]] = [:]
|
private var trackers: [UInt16: [DNSTracker]] = [:]
|
||||||
|
|
||||||
|
// 定期的任务清理
|
||||||
|
private var cleanupTask: Task<Void, Never>?
|
||||||
|
private let timeoutInterval: TimeInterval = 10.0 // 超过10秒认为丢包
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
let (stream, continuation) = AsyncStream.makeStream(of: Data.self, bufferingPolicy: .unbounded)
|
let (stream, continuation) = AsyncStream.makeStream(of: Data.self, bufferingPolicy: .unbounded)
|
||||||
@ -52,11 +56,21 @@ final class DNSLocalClient {
|
|||||||
|
|
||||||
connections.append(conn)
|
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) {
|
func query(tracker: DNSTracker, dnsPayload: Data) {
|
||||||
locker.lock()
|
locker.lock()
|
||||||
|
SDLLogger.shared.log("[DNSLocalClient] query transId: \(tracker.transactionID)")
|
||||||
self.trackers[tracker.transactionID, default: []].append(tracker)
|
self.trackers[tracker.transactionID, default: []].append(tracker)
|
||||||
locker.unlock()
|
locker.unlock()
|
||||||
|
|
||||||
@ -71,6 +85,7 @@ final class DNSLocalClient {
|
|||||||
// !!!核心:由于 AsyncStream 是流式的
|
// !!!核心:由于 AsyncStream 是流式的
|
||||||
// 谁先 yield,上层就先收到谁。
|
// 谁先 yield,上层就先收到谁。
|
||||||
// 只要上层收到了第一个有效响应并回填给系统,
|
// 只要上层收到了第一个有效响应并回填给系统,
|
||||||
|
SDLLogger.shared.log("[DNSLocalClient] get response data: \(data.count)")
|
||||||
self?.handleResponse(data: data)
|
self?.handleResponse(data: data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +106,8 @@ final class DNSLocalClient {
|
|||||||
let items = self.trackers.removeValue(forKey: tranId)
|
let items = self.trackers.removeValue(forKey: tranId)
|
||||||
locker.unlock()
|
locker.unlock()
|
||||||
|
|
||||||
|
SDLLogger.shared.log("[DNSLocalClient] transId: \(tranId) get response items: \(items?.count)")
|
||||||
|
|
||||||
items?.forEach { tracker in
|
items?.forEach { tracker in
|
||||||
let packet = Self.createDNSResponse(
|
let packet = Self.createDNSResponse(
|
||||||
payload: data,
|
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() {
|
func stop() {
|
||||||
connections.forEach { conn in
|
connections.forEach { conn in
|
||||||
conn.cancel()
|
conn.cancel()
|
||||||
}
|
}
|
||||||
self.connections.removeAll()
|
self.connections.removeAll()
|
||||||
|
|
||||||
|
self.cleanupTask?.cancel()
|
||||||
|
self.cleanupTask = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user