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

View File

@ -23,20 +23,17 @@ final class SDLHoleDataProcessor {
private let networkAddress: SDLConfiguration.NetworkAddress
private let dataCipher: CCDataCipher?
private let snapshotPublisher: SnapshotPublisher<IdentitySnapshot>
private let flowSessionManager: SDLFlowSessionManager
private let policyService: PolicyService
init(networkAddress: SDLConfiguration.NetworkAddress,
dataCipher: CCDataCipher?,
snapshotPublisher: SnapshotPublisher<IdentitySnapshot>,
flowSessionManager: SDLFlowSessionManager) {
policyService: PolicyService) {
self.networkAddress = networkAddress
self.dataCipher = dataCipher
self.snapshotPublisher = snapshotPublisher
self.flowSessionManager = flowSessionManager
self.policyService = policyService
}
func makeProcessingPlan(data: SDLData) throws -> ProcessingPlan? {
func makeProcessingPlan(data: SDLData) async throws -> ProcessingPlan? {
guard let dataCipher = self.dataCipher else {
return nil
}
@ -55,7 +52,7 @@ final class SDLHoleDataProcessor {
case .arp:
return self.makeARPPlan(layerData: layerPacket.data, inboundBytes: inboundBytes)
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:
SDLLogger.log("[SDLContext] get invalid packet", for: .debug)
return .init(inboundBytes: inboundBytes, action: .none)
@ -89,17 +86,14 @@ final class SDLHoleDataProcessor {
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
guard let ipPacket = IPPacket(layerData) else {
return .init(inboundBytes: inboundBytes, action: .none)
}
//
let identitySnapshot = self.snapshotPublisher.current()
let ruleMap = identitySnapshot.lookup(identityID)
if true || self.checkPolicy(ipPacket: ipPacket, ruleMap: ruleMap) {
if await self.policyService.checkPolicy(srcIdentityID: identityID, ipPacket: ipPacket) {
return .init(
inboundBytes: inboundBytes,
action: .writeToTun(packetData: ipPacket.data, identityID: identityID)
@ -111,33 +105,4 @@ final class SDLHoleDataProcessor {
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")
}
}