87 lines
2.8 KiB
Swift
87 lines
2.8 KiB
Swift
//
|
||
// 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(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")
|
||
}
|
||
|
||
}
|