fix sleep and wakeup
This commit is contained in:
parent
7ce880f3dc
commit
337fa37b05
@ -83,11 +83,17 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
|
||||
override func sleep(completionHandler: @escaping () -> Void) {
|
||||
// Add code here to get ready to sleep.
|
||||
completionHandler()
|
||||
Task {
|
||||
await self.contextActor?.sleep()
|
||||
completionHandler()
|
||||
}
|
||||
}
|
||||
|
||||
override func wake() {
|
||||
// Add code here to wake up.
|
||||
Task {
|
||||
await self.contextActor?.wake()
|
||||
}
|
||||
}
|
||||
|
||||
private func handleAppRequest(message: AppRequest) async throws -> Data? {
|
||||
|
||||
@ -67,6 +67,7 @@ actor ArpServer {
|
||||
|
||||
func clear() {
|
||||
self.known_macs = [:]
|
||||
self.coolingDown = [:]
|
||||
}
|
||||
|
||||
func arpRequest(targetIp: UInt32, use quicClient: SDLQUICClient?) throws {
|
||||
|
||||
@ -22,6 +22,14 @@ actor SDLContextActor {
|
||||
case stopped
|
||||
}
|
||||
|
||||
private enum RuntimeState {
|
||||
case idle
|
||||
case running
|
||||
case sleeping
|
||||
case waking
|
||||
case stopped
|
||||
}
|
||||
|
||||
private enum UDPHoleKind: Equatable {
|
||||
case v4
|
||||
case v6
|
||||
@ -35,8 +43,9 @@ actor SDLContextActor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private var readyState: ReadyState = .idle
|
||||
private var runtimeState: RuntimeState = .idle
|
||||
private var readyWaiters: [CheckedContinuation<Void, Error>] = []
|
||||
|
||||
var config: SDLConfiguration
|
||||
@ -139,7 +148,14 @@ actor SDLContextActor {
|
||||
}
|
||||
|
||||
self.readyState = .starting
|
||||
self.prepareTunnelNotifier()
|
||||
self.runtimeState = .running
|
||||
await self.startRuntime(resetNotifier: true)
|
||||
}
|
||||
|
||||
private func startRuntime(resetNotifier: Bool) async {
|
||||
if resetNotifier {
|
||||
self.prepareTunnelNotifier()
|
||||
}
|
||||
self.startMonitor()
|
||||
|
||||
// 启动arp的定时清理任务
|
||||
@ -171,6 +187,38 @@ actor SDLContextActor {
|
||||
// }
|
||||
}
|
||||
|
||||
public func sleep() async {
|
||||
guard self.runtimeState != .stopped else {
|
||||
return
|
||||
}
|
||||
|
||||
SDLLogger.log("[SDLContext] sleep")
|
||||
self.runtimeState = .sleeping
|
||||
await self.stopRuntime(clearCaches: true)
|
||||
}
|
||||
|
||||
public func wake() async {
|
||||
switch self.runtimeState {
|
||||
case .stopped, .waking:
|
||||
return
|
||||
case .running:
|
||||
await self.stopRuntime(clearCaches: true)
|
||||
guard case .running = self.runtimeState else {
|
||||
return
|
||||
}
|
||||
case .idle, .sleeping:
|
||||
break
|
||||
}
|
||||
|
||||
SDLLogger.log("[SDLContext] wake")
|
||||
self.runtimeState = .waking
|
||||
await self.startRuntime(resetNotifier: false)
|
||||
guard case .waking = self.runtimeState else {
|
||||
return
|
||||
}
|
||||
self.runtimeState = .running
|
||||
}
|
||||
|
||||
public func waitForReady() async throws {
|
||||
switch self.readyState {
|
||||
case .ready:
|
||||
@ -201,7 +249,7 @@ actor SDLContextActor {
|
||||
|
||||
try await self.waitForReady()
|
||||
}
|
||||
|
||||
|
||||
// 取消出口节点的时候,ip地址为: 0.0.0.0
|
||||
public func updateExitNode(exitNodeIp: String) async throws {
|
||||
if let ip = SDLUtil.ipv4StrToInt32(exitNodeIp), ip > 0 {
|
||||
@ -391,10 +439,21 @@ actor SDLContextActor {
|
||||
public func stop() async {
|
||||
self.resumeReadyWaiters(.failure(CancellationError()))
|
||||
self.readyState = .stopped
|
||||
self.runtimeState = .stopped
|
||||
await self.stopRuntime(clearCaches: true)
|
||||
}
|
||||
|
||||
private func stopRuntime(clearCaches: Bool) async {
|
||||
self.superRegistrationStateMachine.reset()
|
||||
|
||||
|
||||
await self.supervisor.stop()
|
||||
await self.puncherActor.stop()
|
||||
await self.arpServer.clear()
|
||||
await self.sessionManager.clear()
|
||||
|
||||
if clearCaches {
|
||||
self.flowSessionManager.clear()
|
||||
}
|
||||
|
||||
self.udpHoleWorkers?.forEach { $0.cancel() }
|
||||
self.udpHoleWorkers = nil
|
||||
@ -442,6 +501,7 @@ actor SDLContextActor {
|
||||
|
||||
self.sessionToken = nil
|
||||
self.dataCipher = nil
|
||||
self.natType = .blocked
|
||||
|
||||
await self.ipv6AssistClient?.stop()
|
||||
self.ipv6AssistClient = nil
|
||||
|
||||
@ -29,7 +29,7 @@ struct FlowSession: Hashable {
|
||||
lhs.dstPort == rhs.dstPort &&
|
||||
lhs.proto == rhs.proto
|
||||
}
|
||||
|
||||
|
||||
func reverse() -> FlowSession {
|
||||
return FlowSession(
|
||||
srcIP: dstIP,
|
||||
@ -39,7 +39,7 @@ struct FlowSession: Hashable {
|
||||
proto: proto
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// MARK: - 会话管理器
|
||||
@ -68,14 +68,14 @@ final class SDLFlowSessionManager {
|
||||
defer {
|
||||
lock.unlock()
|
||||
}
|
||||
|
||||
|
||||
if let expireTs = sessions[key] {
|
||||
if expireTs >= Date().timeIntervalSince1970 {
|
||||
return true
|
||||
}
|
||||
self.sessions.removeValue(forKey: key)
|
||||
}
|
||||
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@ -89,6 +89,15 @@ final class SDLFlowSessionManager {
|
||||
sessions.removeValue(forKey: key)
|
||||
}
|
||||
|
||||
func clear() {
|
||||
lock.lock()
|
||||
defer {
|
||||
lock.unlock()
|
||||
}
|
||||
|
||||
sessions.removeAll()
|
||||
}
|
||||
|
||||
// 清理过期会话
|
||||
func cleanupExpiredSessions() {
|
||||
lock.lock()
|
||||
|
||||
@ -13,7 +13,7 @@ struct Session {
|
||||
case v4
|
||||
case v6
|
||||
}
|
||||
|
||||
|
||||
// 在内部的通讯的ip地址, 整数格式
|
||||
let dstMac: Data
|
||||
// 对端的主机在nat上映射的端口信息
|
||||
@ -30,7 +30,7 @@ struct Session {
|
||||
self.addressType = addressType
|
||||
self.lastTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
}
|
||||
|
||||
|
||||
mutating func updateLastTimestamp(_ lastTimestamp: Int32) {
|
||||
self.lastTimestamp = lastTimestamp
|
||||
}
|
||||
@ -67,7 +67,7 @@ actor SessionManager {
|
||||
|
||||
return session
|
||||
}
|
||||
|
||||
|
||||
func addSession(session: Session) {
|
||||
let timestamp = Int32(Date().timeIntervalSince1970)
|
||||
|
||||
@ -84,6 +84,10 @@ actor SessionManager {
|
||||
self.sessions.removeValue(forKey: dstMac)
|
||||
}
|
||||
|
||||
func clear() {
|
||||
self.sessions.removeAll()
|
||||
}
|
||||
|
||||
private func selectSession(in sessions: [Session.AddressType: Session]) -> Session? {
|
||||
return sessions.values.max(by: { $0.lastTimestamp < $1.lastTimestamp })
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user