This commit is contained in:
anlicheng 2026-04-10 16:00:28 +08:00
parent 70f8b1c3e2
commit 20a339f6ff

View File

@ -12,8 +12,8 @@ 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
@ -21,6 +21,10 @@ final class DNSLocalClient {
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)
self.packetFlow = stream self.packetFlow = stream
@ -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
} }
} }