fix policy

This commit is contained in:
anlicheng 2026-05-19 22:55:14 +08:00
parent c6773f0050
commit 3ab82a13b5
4 changed files with 96 additions and 63 deletions

View File

@ -94,12 +94,8 @@ actor SDLContextActor {
nonisolated private let provider: NEPacketTunnelProvider nonisolated private let provider: NEPacketTunnelProvider
// //
private let identifyStore: IdentityStore
private var updatePolicyTask: Task<Void, Never>? private var updatePolicyTask: Task<Void, Never>?
private let snapshotPublisher: SnapshotPublisher<IdentitySnapshot> private let policyService: PolicyService
// Flow : 180
private let flowSessionManager = SDLFlowSessionManager(sessionTimeout: 180)
// stunRequest // stunRequest
private var stunRequestTask: Task<Void, Never>? private var stunRequestTask: Task<Void, Never>?
@ -115,9 +111,7 @@ actor SDLContextActor {
self.arpServer = ArpServer() self.arpServer = ArpServer()
// //
let snapshotPublisher = SnapshotPublisher(initial: IdentitySnapshot.empty()) self.policyService = PolicyService(identityId: config.identityId)
self.identifyStore = IdentityStore(publisher: snapshotPublisher)
self.snapshotPublisher = snapshotPublisher
} }
public func start() async { public func start() async {
@ -152,13 +146,12 @@ actor SDLContextActor {
await self.arpServer.stop() await self.arpServer.stop()
await self.sessionManager.clear() await self.sessionManager.clear()
self.flowSessionManager.clear()
self.stunRequestTask?.cancel() self.stunRequestTask?.cancel()
self.stunRequestTask = nil self.stunRequestTask = nil
self.updatePolicyTask?.cancel() self.updatePolicyTask?.cancel()
self.updatePolicyTask = nil self.updatePolicyTask = nil
await self.policyService.clear()
let packetReaderService = self.packetReaderService let packetReaderService = self.packetReaderService
self.packetReaderService = nil self.packetReaderService = nil
@ -268,7 +261,7 @@ extension SDLContextActor {
await self.handleEvent(event: event) await self.handleEvent(event: event)
case .policyReponse(let policyResponse): case .policyReponse(let policyResponse):
// //
await self.identifyStore.applyPolicyResponse(policyResponse) await self.policyService.identifyStore.applyPolicyResponse(policyResponse)
case .arpResponse(let arpResponse): case .arpResponse(let arpResponse):
SDLLogger.log("[SDLContext] get arp response: \(arpResponse)") SDLLogger.log("[SDLContext] get arp response: \(arpResponse)")
await self.arpServer.handleArpResponse(arpResponse: arpResponse) await self.arpServer.handleArpResponse(arpResponse: arpResponse)
@ -327,10 +320,7 @@ extension SDLContextActor {
while true { while true {
try await Task.sleep(for: .seconds(300)) try await Task.sleep(for: .seconds(300))
SDLLogger.log("[SDLContext] updatePolicyTask execute") SDLLogger.log("[SDLContext] updatePolicyTask execute")
let requests = await self.identifyStore.makeBatchPolicyRequests(dstIdentityID: self.config.identityId) await self.policyService.updatePolicy(superService: self.superService)
for request in requests {
await self.superService?.send(type: .policyRequest, data: request)
}
} }
} catch let err { } catch let err {
SDLLogger.log("[SDLContext] updatePolicyTask stop with err: \(err)") SDLLogger.log("[SDLContext] updatePolicyTask stop with err: \(err)")
@ -490,14 +480,12 @@ extension SDLContextActor {
return .init( return .init(
networkAddress: self.config.networkAddress, networkAddress: self.config.networkAddress,
dataCipher: self.dataCipher, dataCipher: self.dataCipher,
snapshotPublisher: self.snapshotPublisher, policyService: self.policyService)
flowSessionManager: self.flowSessionManager
)
} }
private func handleHoleData(data: SDLData) async throws { private func handleHoleData(data: SDLData) async throws {
let processor = self.makeHoleDataProcessor() let processor = self.makeHoleDataProcessor()
guard let plan = try processor.makeProcessingPlan(data: data) else { guard let plan = try await processor.makeProcessingPlan(data: data) else {
return return
} }
@ -516,7 +504,7 @@ extension SDLContextActor {
SDLLogger.log("[SDLContext] hole identity: \(identityID), allow, data count: \(packetData.count)", for: .trace) SDLLogger.log("[SDLContext] hole identity: \(identityID), allow, data count: \(packetData.count)", for: .trace)
case .requestPolicy(let srcIdentityID): case .requestPolicy(let srcIdentityID):
SDLLogger.log("[SDLContext] not found identity: \(srcIdentityID) ruleMap", for: .debug) SDLLogger.log("[SDLContext] not found identity: \(srcIdentityID) ruleMap", for: .debug)
if let queryData = await self.identifyStore.makePolicyRequest(srcIdentityId: srcIdentityID, dstIdentityId: self.config.identityId) { if let queryData = await self.policyService.identifyStore.makePolicyRequest(srcIdentityId: srcIdentityID, dstIdentityId: self.config.identityId) {
await self.superService?.send(type: .policyRequest, data: queryData) await self.superService?.send(type: .policyRequest, data: queryData)
} }
case .none: case .none:
@ -692,7 +680,7 @@ extension SDLContextActor {
// FlowSession // FlowSession
// //
if decision.shouldTrackFlow, let flowSession = packet.flowSession() { if decision.shouldTrackFlow, let flowSession = packet.flowSession() {
self.flowSessionManager.updateSession(flowSession) await self.policyService.flowSessionManager.updateSession(flowSession)
//SDLLogger.shared.log("[SDLContext] flow_session: \(flowSession)", level: .debug) //SDLLogger.shared.log("[SDLContext] flow_session: \(flowSession)", level: .debug)
} }

View File

@ -23,20 +23,17 @@ final class SDLHoleDataProcessor {
private let networkAddress: SDLConfiguration.NetworkAddress private let networkAddress: SDLConfiguration.NetworkAddress
private let dataCipher: CCDataCipher? private let dataCipher: CCDataCipher?
private let snapshotPublisher: SnapshotPublisher<IdentitySnapshot> private let policyService: PolicyService
private let flowSessionManager: SDLFlowSessionManager
init(networkAddress: SDLConfiguration.NetworkAddress, init(networkAddress: SDLConfiguration.NetworkAddress,
dataCipher: CCDataCipher?, dataCipher: CCDataCipher?,
snapshotPublisher: SnapshotPublisher<IdentitySnapshot>, policyService: PolicyService) {
flowSessionManager: SDLFlowSessionManager) {
self.networkAddress = networkAddress self.networkAddress = networkAddress
self.dataCipher = dataCipher self.dataCipher = dataCipher
self.snapshotPublisher = snapshotPublisher self.policyService = policyService
self.flowSessionManager = flowSessionManager
} }
func makeProcessingPlan(data: SDLData) throws -> ProcessingPlan? { func makeProcessingPlan(data: SDLData) async throws -> ProcessingPlan? {
guard let dataCipher = self.dataCipher else { guard let dataCipher = self.dataCipher else {
return nil return nil
} }
@ -55,7 +52,7 @@ final class SDLHoleDataProcessor {
case .arp: case .arp:
return self.makeARPPlan(layerData: layerPacket.data, inboundBytes: inboundBytes) return self.makeARPPlan(layerData: layerPacket.data, inboundBytes: inboundBytes)
case .ipv4: case .ipv4:
return self.makeIPv4Plan(layerData: layerPacket.data, identityID: data.identityID, inboundBytes: inboundBytes) return await self.makeIPv4Plan(layerData: layerPacket.data, identityID: data.identityID, inboundBytes: inboundBytes)
default: default:
SDLLogger.log("[SDLContext] get invalid packet", for: .debug) SDLLogger.log("[SDLContext] get invalid packet", for: .debug)
return .init(inboundBytes: inboundBytes, action: .none) return .init(inboundBytes: inboundBytes, action: .none)
@ -89,17 +86,14 @@ final class SDLHoleDataProcessor {
return .init(inboundBytes: inboundBytes, action: .none) return .init(inboundBytes: inboundBytes, action: .none)
} }
private func makeIPv4Plan(layerData: Data, identityID: UInt32, inboundBytes: Int) -> ProcessingPlan { private func makeIPv4Plan(layerData: Data, identityID: UInt32, inboundBytes: Int) async -> ProcessingPlan {
// ip // ip
guard let ipPacket = IPPacket(layerData) else { guard let ipPacket = IPPacket(layerData) else {
return .init(inboundBytes: inboundBytes, action: .none) return .init(inboundBytes: inboundBytes, action: .none)
} }
// //
let identitySnapshot = self.snapshotPublisher.current() if await self.policyService.checkPolicy(srcIdentityID: identityID, ipPacket: ipPacket) {
let ruleMap = identitySnapshot.lookup(identityID)
if true || self.checkPolicy(ipPacket: ipPacket, ruleMap: ruleMap) {
return .init( return .init(
inboundBytes: inboundBytes, inboundBytes: inboundBytes,
action: .writeToTun(packetData: ipPacket.data, identityID: identityID) action: .writeToTun(packetData: ipPacket.data, identityID: identityID)
@ -111,33 +105,4 @@ final class SDLHoleDataProcessor {
action: .requestPolicy(srcIdentityID: identityID) action: .requestPolicy(srcIdentityID: identityID)
) )
} }
private func checkPolicy(ipPacket: IPPacket, ruleMap: IdentityRuleMap?) -> Bool {
//
if let reverseFlowSession = ipPacket.flowSession()?.reverse(),
self.flowSessionManager.hasSession(reverseFlowSession) {
self.flowSessionManager.updateSession(reverseFlowSession)
return true
}
//
let proto = ipPacket.header.proto
// 访
switch ipPacket.transportPacket {
case .tcp(let tcpPacket):
if let ruleMap, ruleMap.isAllow(proto: proto, port: tcpPacket.header.dstPort) {
return true
}
case .udp(let udpPacket):
if let ruleMap, ruleMap.isAllow(proto: proto, port: udpPacket.dstPort) {
return true
}
case .icmp(_):
return true
default:
return false
}
return false
}
} }

View File

@ -0,0 +1,80 @@
//
// PolicyService.swift
// punchnet
//
// Created by on 2026/5/19.
//
import Foundation
actor PolicyService {
//
let identifyStore: IdentityStore
private let snapshotPublisher: SnapshotPublisher<IdentitySnapshot>
// Flow : 180
let flowSessionManager = SDLFlowSessionManager(sessionTimeout: 180)
// identityId
let identityId: UInt32
init(identityId: UInt32) {
self.identityId = identityId
//
let snapshotPublisher = SnapshotPublisher(initial: IdentitySnapshot.empty())
self.identifyStore = IdentityStore(publisher: snapshotPublisher)
self.snapshotPublisher = snapshotPublisher
}
func checkPolicy(srcIdentityID: UInt32, ipPacket: IPPacket) -> Bool {
//
if let reverseFlowSession = ipPacket.flowSession()?.reverse(),
self.flowSessionManager.hasSession(reverseFlowSession) {
self.flowSessionManager.updateSession(reverseFlowSession)
return true
}
//
let identitySnapshot = self.snapshotPublisher.current()
let ruleMap = identitySnapshot.lookup(srcIdentityID)
//
let proto = ipPacket.header.proto
// 访
switch ipPacket.transportPacket {
case .tcp(let tcpPacket):
if let ruleMap, ruleMap.isAllow(proto: proto, port: tcpPacket.header.dstPort) {
return true
}
case .udp(let udpPacket):
if let ruleMap, ruleMap.isAllow(proto: proto, port: udpPacket.dstPort) {
return true
}
case .icmp(_):
return true
default:
return false
}
return false
}
func updatePolicy(superService: SDLSuperService?) async {
guard let superService else {
return
}
let requests = await self.identifyStore.makeBatchPolicyRequests(dstIdentityID: self.identityId)
for request in requests {
await superService.send(type: .policyRequest, data: request)
}
}
func clear() {
self.flowSessionManager.clear()
}
deinit {
SDLLogger.log("[PolicyService] deinit")
}
}