punchnet-macos/Tun/Punchnet/Policy/PolicyService.swift
2026-05-20 21:55:58 +08:00

91 lines
3.0 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// PolicyService.swift
// punchnet
//
// Created by on 2026/5/19.
//
import Foundation
actor PolicyService {
//
let identifyStore: IdentityStore
nonisolated private let snapshotPublisher: SnapshotPublisher<IdentitySnapshot>
// Flow : 180
nonisolated 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
}
nonisolated func policySnapshot() -> PolicySnapshot {
return PolicySnapshot(identitySnapshot: self.snapshotPublisher.current())
}
func updatePolicy(superServiceProxy: SDLSuperServiceProxy) async {
let requests = await self.identifyStore.makeBatchPolicyRequests(dstIdentityID: self.identityId)
for request in requests {
await superServiceProxy.send(type: .policyRequest, data: request)
}
}
func applyPolicyResponse(_ policyResponse: SDLPolicyResponse) async {
guard policyResponse.dstIdentityID == self.identityId else {
SDLLogger.log("[PolicyService] ignore policy response, dstIdentityID mismatch: \(policyResponse.dstIdentityID), expected: \(self.identityId)", for: .debug)
return
}
await self.identifyStore.applyPolicyResponse(policyResponse)
}
func clear() async {
self.flowSessionManager.clear()
await self.identifyStore.clear()
}
deinit {
SDLLogger.log("[PolicyService] deinit")
}
}