增加arp请求的过期时间处理

This commit is contained in:
anlicheng 2026-03-06 15:00:06 +08:00
parent 6ae15dc286
commit 1fb7364c66
5 changed files with 64 additions and 14 deletions

View File

@ -8,18 +8,36 @@ import Foundation
import Darwin import Darwin
actor ArpServerActor { 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? { 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) { 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) { func remove(ip: UInt32) {
@ -27,11 +45,33 @@ actor ArpServerActor {
} }
func dropMacs(macs: [Data]) { 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() { func clear() {
self.known_macs = [:] 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)
}
}
} }

View File

@ -97,7 +97,7 @@ actor SDLContextActor {
let snapshotPublisher = SnapshotPublisher(initial: IdentitySnapshot.empty()) let snapshotPublisher = SnapshotPublisher(initial: IdentitySnapshot.empty())
self.identifyStore = IdentityStore(publisher: snapshotPublisher) self.identifyStore = IdentityStore(publisher: snapshotPublisher)
self.snapshotPublisher = snapshotPublisher self.snapshotPublisher = snapshotPublisher
self.policyRequesterActor = PolicyRequesterActor(querySocketAddress: config.stunSocketAddress) self.policyRequesterActor = PolicyRequesterActor()
} }
public func start() { public func start() {
@ -167,6 +167,8 @@ actor SDLContextActor {
case .policyReponse(let policyResponse): case .policyReponse(let policyResponse):
// //
await self.identifyStore.apply(policyResponse: policyResponse) await self.identifyStore.apply(policyResponse: policyResponse)
case .arpResponse(let arpResponse):
await self.arpServer.handleArpResponse(arpResponse: arpResponse)
} }
} }
} }
@ -644,9 +646,11 @@ actor SDLContextActor {
} }
else { else {
SDLLogger.shared.log("[SDLContext] dstIp: \(dstIp.asIpAddress()) arp query not found, broadcast", level: .debug) SDLLogger.shared.log("[SDLContext] dstIp: \(dstIp.asIpAddress()) arp query not found, broadcast", level: .debug)
// arp广 // // arp广
let arpReqeust = ARPPacket.arpRequest(senderIP: networkAddr.ip, senderMAC: networkAddr.mac, targetIP: dstIp) // let arpReqeust = ARPPacket.arpRequest(senderIP: networkAddr.ip, senderMAC: networkAddr.mac, targetIP: dstIp)
await self.routeLayerPacket(dstMac: ARPPacket.broadcastMac , type: .arp, data: arpReqeust.marshal()) // await self.routeLayerPacket(dstMac: ARPPacket.broadcastMac , type: .arp, data: arpReqeust.marshal())
try? await self.arpServer.arpRequest(targetIp: dstIp, use: self.quicClient)
} }
} }

View File

@ -213,6 +213,12 @@ final class SDLQUICClient {
return nil return nil
} }
return .policyReponse(policyResponse) 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: case .event:
guard let eventVal = buffer.readInteger(as: UInt8.self), guard let eventVal = buffer.readInteger(as: UInt8.self),
let event = SDLEventType(rawValue: eventVal), let event = SDLEventType(rawValue: eventVal),

View File

@ -16,11 +16,9 @@ actor PolicyRequesterActor {
// , map[identityId] = version // , map[identityId] = version
private var versions: [UInt32: UInt32] = [:] private var versions: [UInt32: UInt32] = [:]
// holer
nonisolated private let querySocketAddress: SocketAddress
init(querySocketAddress: SocketAddress) { init() {
self.querySocketAddress = querySocketAddress
} }
// //

View File

@ -124,6 +124,8 @@ enum SDLQUICInboundMessage {
case peerInfo(SDLPeerInfo) case peerInfo(SDLPeerInfo)
case event(SDLEvent) case event(SDLEvent)
case policyReponse(SDLPolicyResponse) case policyReponse(SDLPolicyResponse)
case arpResponse(SDLArpResponse)
} }
// //