fix notice

This commit is contained in:
anlicheng 2026-04-15 11:05:08 +08:00
parent 7e2e744bdb
commit 739acd3938
4 changed files with 24 additions and 232 deletions

View File

@ -1,100 +0,0 @@
//
// SDLNoticeClient.swift
// Tun
//
// Created by on 2024/5/20.
//
import Foundation
//
// SDLanServer.swift
// Tun
//
// Created by on 2024/1/31.
//
import Foundation
import NIOCore
import NIOPosix
// sn-server
final class SDLNoticeClient {
private let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let (writeStream, writeContinuation) = AsyncStream<Data>.makeStream(of: Data.self)
private var task: Task<Void, Never>?
private var channel: Channel
private let noticePort: Int
private var isStopped = false
//
init(noticePort: Int) throws {
self.noticePort = noticePort
let bootstrap = DatagramBootstrap(group: self.group)
.channelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1)
.channelInitializer { channel in
channel.pipeline.addHandler(SDLNoticeClientInboundHandler())
}
self.channel = try bootstrap.bind(host: "0.0.0.0", port: 0).wait()
}
func start() {
let channel = self.channel
self.task = Task.detached {
guard let remoteAddress = try? await SDLAddressResolver.shared.resolve(host: "127.0.0.1", port: self.noticePort) else {
return
}
for await data in self.writeStream {
if Task.isCancelled {
break
}
let buf = channel.allocator.buffer(bytes: data)
let envelope = AddressedEnvelope<ByteBuffer>(remoteAddress: remoteAddress, data: buf)
channel.eventLoop.execute {
channel.writeAndFlush(envelope, promise: nil)
}
}
}
}
//
func send(data: Data) {
self.writeContinuation.yield(data)
}
func waitClose() async throws {
try await self.channel.closeFuture.get()
}
func stop() {
guard !self.isStopped else {
return
}
self.isStopped = true
self.writeContinuation.finish()
self.task?.cancel()
self.task = nil
self.channel.close(promise: nil)
}
deinit {
self.stop()
try? self.group.syncShutdownGracefully()
}
}
extension SDLNoticeClient {
private class SDLNoticeClientInboundHandler: ChannelInboundHandler {
typealias InboundIn = AddressedEnvelope<ByteBuffer>
}
}

View File

@ -1,52 +0,0 @@
//
// NoticeMessage.swift
// sdlan
//
// Created by on 2024/6/3.
//
import Foundation
import NIOCore
struct NoticeMessage {
enum InboundMessage {
case none
case alertMessage(alert: String)
}
static func decodeMessage(buffer: inout ByteBuffer) -> InboundMessage {
guard let type = buffer.readInteger(as: UInt8.self) else {
return .none
}
switch type {
case 0x01:
if let len0 = buffer.readInteger(as: UInt16.self),
let alert = buffer.readString(length: Int(len0)) {
return .alertMessage(alert: alert)
}
default:
return .none
}
return .none
}
static func alert(alert: String) -> Data {
var data = Data()
data.append(contentsOf: [0x01])
data.append(contentsOf: lenBytes(UInt16(alert.count)))
data.append(alert.data(using: .utf8)!)
return data
}
private static func lenBytes(_ value: UInt16) -> [UInt8] {
let byte1 = UInt8((value >> 8) & 0xFF)
let bytes2 = UInt8(value & 0xFF)
return [byte1, bytes2]
}
}

View File

@ -1,60 +0,0 @@
//
// UDPMessageCenterServer.swift
// sdlan
//
// Created by on 2024/5/20.
//
import Foundation
import NIOCore
import NIOPosix
import Combine
final class UDPNoticeCenterServer: ChannelInboundHandler {
public typealias InboundIn = AddressedEnvelope<ByteBuffer>
public typealias OutboundOut = AddressedEnvelope<ByteBuffer>
private var group: MultiThreadedEventLoopGroup?
private var channel: Channel?
var messageFlow = PassthroughSubject<NoticeMessage.InboundMessage, Never>()
public var port: Int = 0
func start() {
self.group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let bootstrap = DatagramBootstrap(group: self.group!)
.channelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1)
.channelInitializer { channel in
channel.pipeline.addHandler(self)
}
self.channel = try! bootstrap.bind(host: "127.0.0.1", port: 0).wait()
self.port = self.channel?.localAddress?.port ?? 0
}
func stop() {
try? self.group?.syncShutdownGracefully()
}
// --MARK: ChannelInboundHandler
public func channelRead(context: ChannelHandlerContext, data: NIOAny) {
let envelope = self.unwrapInboundIn(data)
var buffer = envelope.data
let notice = NoticeMessage.decodeMessage(buffer: &buffer)
self.messageFlow.send(notice)
}
public func channelReadComplete(context: ChannelHandlerContext) {
// As we are not really interested getting notified on success or failure we just pass nil as promise to
// reduce allocations.
context.flush()
}
public func errorCaught(context: ChannelHandlerContext, error: Error) {
// As we are not really interested getting notified on success or failure we just pass nil as promise to
// reduce allocations.
context.close(promise: nil)
}
}

View File

@ -168,24 +168,7 @@ class AppContext {
return nil return nil
} }
} // MARK: TunEvent
//
extension AppContext {
func loadExitNodeIp() -> String? {
if let data = try? KeychainStore.shared.load(account: "exitNodeIp") {
return String(data: data, encoding: .utf8)
}
return nil
}
func saveExitNodeIp(exitNodeIp: String) async throws {
// keychain
if let data = exitNodeIp.data(using: .utf8) {
try KeychainStore.shared.save(data, account: "exitNodeIp")
}
}
func dismissTunnelEvent() { func dismissTunnelEvent() {
self.tunnelEvent = nil self.tunnelEvent = nil
@ -213,3 +196,24 @@ extension AppContext {
} }
} }
//
extension AppContext {
func loadExitNodeIp() -> String? {
if let data = try? KeychainStore.shared.load(account: "exitNodeIp") {
return String(data: data, encoding: .utf8)
}
return nil
}
func saveExitNodeIp(exitNodeIp: String) async throws {
// keychain
if let data = exitNodeIp.data(using: .utf8) {
try KeychainStore.shared.save(data, account: "exitNodeIp")
}
}
}