From 1fb7364c66eef0fab72c143e5c5cac0d69ca54d3 Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Fri, 6 Mar 2026 15:00:06 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0arp=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E7=9A=84=E8=BF=87=E6=9C=9F=E6=97=B6=E9=97=B4=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tun/Punchnet/Actors/ArpServerActor.swift | 52 ++++++++++++++++--- Tun/Punchnet/Actors/SDLContextActor.swift | 12 +++-- Tun/Punchnet/Actors/SDLQuicClient.swift | 6 +++ .../Policy/PolicyRequesterActor.swift | 6 +-- Tun/Punchnet/SDLMessage.swift | 2 + 5 files changed, 64 insertions(+), 14 deletions(-) diff --git a/Tun/Punchnet/Actors/ArpServerActor.swift b/Tun/Punchnet/Actors/ArpServerActor.swift index 2b12a31..745b8f9 100644 --- a/Tun/Punchnet/Actors/ArpServerActor.swift +++ b/Tun/Punchnet/Actors/ArpServerActor.swift @@ -8,18 +8,36 @@ import Foundation import Darwin actor ArpServerActor { - private var known_macs: [UInt32:Data] = [:] + // 增加缓存时间逻辑 + struct ArpEntry { + var mac: Data + var expireTime: TimeInterval + } - init() { - + 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? { - return self.known_macs[ip] + 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) { - self.known_macs[ip] = mac + let expireAt = Date().timeIntervalSince1970 + arpTTL + self.known_macs[ip] = ArpEntry(mac: mac, expireTime: expireAt) } func remove(ip: UInt32) { @@ -27,11 +45,33 @@ actor ArpServerActor { } func dropMacs(macs: [Data]) { - self.known_macs = self.known_macs.filter { !macs.contains($0.value) } + self.known_macs = self.known_macs.filter { !macs.contains($0.value.mac) } } func clear() { self.known_macs = [:] } + func arpRequest(targetIp: UInt32, use quicClient: SDLQUICClient?) throws { + 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) { + let targetIp = arpResponse.targetIp + let targetMac = arpResponse.targetMac + if !targetMac.isEmpty { + self.append(ip: targetIp, mac: targetMac) + } + } + } diff --git a/Tun/Punchnet/Actors/SDLContextActor.swift b/Tun/Punchnet/Actors/SDLContextActor.swift index 8212c60..6f3383c 100644 --- a/Tun/Punchnet/Actors/SDLContextActor.swift +++ b/Tun/Punchnet/Actors/SDLContextActor.swift @@ -97,7 +97,7 @@ actor SDLContextActor { let snapshotPublisher = SnapshotPublisher(initial: IdentitySnapshot.empty()) self.identifyStore = IdentityStore(publisher: snapshotPublisher) self.snapshotPublisher = snapshotPublisher - self.policyRequesterActor = PolicyRequesterActor(querySocketAddress: config.stunSocketAddress) + self.policyRequesterActor = PolicyRequesterActor() } public func start() { @@ -167,6 +167,8 @@ actor SDLContextActor { case .policyReponse(let policyResponse): // 处理权限的请求问题 await self.identifyStore.apply(policyResponse: policyResponse) + case .arpResponse(let arpResponse): + await self.arpServer.handleArpResponse(arpResponse: arpResponse) } } } @@ -644,9 +646,11 @@ actor SDLContextActor { } else { SDLLogger.shared.log("[SDLContext] dstIp: \(dstIp.asIpAddress()) arp query not found, broadcast", level: .debug) - // 构造arp广播 - let arpReqeust = ARPPacket.arpRequest(senderIP: networkAddr.ip, senderMAC: networkAddr.mac, targetIP: dstIp) - await self.routeLayerPacket(dstMac: ARPPacket.broadcastMac , type: .arp, data: arpReqeust.marshal()) +// // 构造arp广播 +// let arpReqeust = ARPPacket.arpRequest(senderIP: networkAddr.ip, senderMAC: networkAddr.mac, targetIP: dstIp) +// await self.routeLayerPacket(dstMac: ARPPacket.broadcastMac , type: .arp, data: arpReqeust.marshal()) + + try? await self.arpServer.arpRequest(targetIp: dstIp, use: self.quicClient) } } diff --git a/Tun/Punchnet/Actors/SDLQuicClient.swift b/Tun/Punchnet/Actors/SDLQuicClient.swift index 6945653..8180a1c 100644 --- a/Tun/Punchnet/Actors/SDLQuicClient.swift +++ b/Tun/Punchnet/Actors/SDLQuicClient.swift @@ -213,6 +213,12 @@ final class SDLQUICClient { return nil } return .policyReponse(policyResponse) + case .arpResponse: + guard let bytes = buffer.readBytes(length: buffer.readableBytes), + let arpResponse = try? SDLArpResponse(serializedBytes: bytes) else { + return nil + } + return .arpResponse(arpResponse) case .event: guard let eventVal = buffer.readInteger(as: UInt8.self), let event = SDLEventType(rawValue: eventVal), diff --git a/Tun/Punchnet/Policy/PolicyRequesterActor.swift b/Tun/Punchnet/Policy/PolicyRequesterActor.swift index 83e3d00..26bc99c 100644 --- a/Tun/Punchnet/Policy/PolicyRequesterActor.swift +++ b/Tun/Punchnet/Policy/PolicyRequesterActor.swift @@ -16,11 +16,9 @@ actor PolicyRequesterActor { // 处理各个请求的版本问题, map[identityId] = version private var versions: [UInt32: UInt32] = [:] - // 处理holer - nonisolated private let querySocketAddress: SocketAddress - init(querySocketAddress: SocketAddress) { - self.querySocketAddress = querySocketAddress + init() { + } // 提交权限请求 diff --git a/Tun/Punchnet/SDLMessage.swift b/Tun/Punchnet/SDLMessage.swift index 1612d48..416ddfb 100644 --- a/Tun/Punchnet/SDLMessage.swift +++ b/Tun/Punchnet/SDLMessage.swift @@ -124,6 +124,8 @@ enum SDLQUICInboundMessage { case peerInfo(SDLPeerInfo) case event(SDLEvent) case policyReponse(SDLPolicyResponse) + + case arpResponse(SDLArpResponse) } // 命令类型