// // ArpServer.swift // sdlan // // Created by 安礼成 on 2025/7/14. // import Foundation import Darwin final class ArpServer { // 增加缓存时间逻辑 struct ArpEntry { var mac: Data var expireTime: TimeInterval } private let locker = NSLock() private var packetId: UInt32 = 1 private var known_macs: [UInt32: ArpEntry] = [:] private let arpTTL: TimeInterval init(arpTTL: TimeInterval = 300) { self.arpTTL = arpTTL } func query(ip: UInt32) -> Data? { locker.lock() defer { locker.unlock() } guard let entry = known_macs[ip] else { return nil } if entry.expireTime < Date().timeIntervalSince1970 { known_macs.removeValue(forKey: ip) return nil } return entry.mac } func append(ip: UInt32, mac: Data) { locker.lock() defer { locker.unlock() } let expireAt = Date().timeIntervalSince1970 + arpTTL self.known_macs[ip] = ArpEntry(mac: mac, expireTime: expireAt) } func remove(ip: UInt32) { locker.lock() defer { locker.unlock() } self.known_macs.removeValue(forKey: ip) } func dropMacs(macs: [Data]) { locker.lock() defer { locker.unlock() } self.known_macs = self.known_macs.filter { !macs.contains($0.value.mac) } } func clear() { locker.lock() defer { locker.unlock() } self.known_macs = [:] } func arpRequest(targetIp: UInt32, use quicClient: SDLQUICClient?) throws { locker.lock() defer { locker.unlock() } guard let quicClient else { return } // 进行arp查询 var arpRequest = SDLArpRequest() arpRequest.targetIp = targetIp arpRequest.pktID = self.packetId self.packetId += 1 quicClient.send(type: .arpRequest, data: try arpRequest.serializedData()) } func handleArpResponse(arpResponse: SDLArpResponse) { locker.lock() defer { locker.unlock() } let targetIp = arpResponse.targetIp let targetMac = arpResponse.targetMac if !targetMac.isEmpty { self.append(ip: targetIp, mac: targetMac) } } }