Tun Network设置抽象

This commit is contained in:
anlicheng 2026-05-20 23:24:49 +08:00
parent 5f36c28040
commit 351695aa52
2 changed files with 101 additions and 65 deletions

View File

@ -68,6 +68,7 @@ actor SDLContextActor {
private let udpHoleServiceProxy: SDLUDPHoleServiceProxy
private let packetOutboundActor: PacketOutboundActor
private let packetInboundActor: PacketInboundActor
private let tunNetworkManager: SDLTunNetworkManager
private let publicDnsServers = ["223.5.5.5", "119.29.29.29"]
@ -105,6 +106,7 @@ actor SDLContextActor {
let policyService = PolicyService(identityId: config.identityId)
let superServiceProxy = SDLSuperServiceProxy()
let udpHoleServiceProxy = SDLUDPHoleServiceProxy()
let tunNetworkManager = SDLTunNetworkManager(provider: provider)
let packetOutboundActor = PacketOutboundActor(
provider: provider,
config: config,
@ -145,6 +147,7 @@ actor SDLContextActor {
self.udpHoleServiceProxy = udpHoleServiceProxy
self.packetOutboundActor = packetOutboundActor
self.packetInboundActor = packetInboundActor
self.tunNetworkManager = tunNetworkManager
}
public func start() async {
@ -336,7 +339,7 @@ extension SDLContextActor {
SDLLogger.log("[SDLContext] registerSuperAck, use algorithm \(algorithm), key len: \(key.count)")
// tun
do {
try await self.setNetworkSettings(config: self.config, dnsServer: DNSHelper.dnsServer)
try await self.tunNetworkManager.apply(settings: .init(config: self.config), dnsServer: DNSHelper.dnsServer)
SDLLogger.log("[SDLContext] setNetworkSettings successed")
await self.packetOutboundActor.startPacketReader()
//
@ -590,71 +593,8 @@ extension SDLContextActor {
}
await self.packetOutboundActor.updateRuntime(config: self.config, dataCipher: self.dataCipher)
await self.packetInboundActor.updateRuntime(config: self.config, dataCipher: self.dataCipher)
try await self.setNetworkSettings(config: self.config, dnsServer: DNSHelper.dnsServer)
}
// MARK:
private func setNetworkSettings(config: SDLConfiguration, dnsServer: String) async throws {
let networkAddress = config.networkAddress
//
var routes: [NEIPv4Route] = [
NEIPv4Route(destinationAddress: networkAddress.netAddress, subnetMask: networkAddress.maskAddress),
NEIPv4Route(destinationAddress: dnsServer, subnetMask: "255.255.255.255"),
]
//
if config.exitNode != nil {
routes.append(.default())
}
// Add code here to start the process of connecting the tunnel.
let networkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "8.8.8.8")
networkSettings.mtu = 1250
// DNS
let networkDomain = networkAddress.networkDomain
let dnsSettings = NEDNSSettings(servers: [dnsServer])
dnsSettings.searchDomains = [networkDomain]
dnsSettings.matchDomains = [networkDomain, ""]
// false Search Domain
dnsSettings.matchDomainsNoSearch = false
networkSettings.dnsSettings = dnsSettings
let ipv4Settings = NEIPv4Settings(addresses: [networkAddress.ipAddress], subnetMasks: [networkAddress.maskAddress])
//
ipv4Settings.includedRoutes = routes
//
ipv4Settings.excludedRoutes = self.getIpv4ExcludeRoutes()
networkSettings.ipv4Settings = ipv4Settings
//
try await self.provider.setTunnelNetworkSettings(networkSettings)
}
private func getIpv4ExcludeRoutes() -> [NEIPv4Route] {
//
let dnsServers = SDLUtil.getMacOSSystemDnsServers()
var ipv4DnsServers = dnsServers.filter {!$0.contains(":")}
// dns
let commonDnsServers = [
"8.8.8.8",
"8.8.4.4",
"223.5.5.5",
"223.6.6.6",
"114.114.114.114"
]
for ip in commonDnsServers {
if !ipv4DnsServers.contains(ip) {
ipv4DnsServers.append(ip)
}
}
return ipv4DnsServers.map { NEIPv4Route(destinationAddress: $0, subnetMask: "255.255.255.255") }
try await self.tunNetworkManager.apply(settings: .init(config: self.config), dnsServer: DNSHelper.dnsServer)
}
}

View File

@ -0,0 +1,96 @@
//
// SDLTunNetworkManager.swift
// Tun
//
// Created by Codex on 2026/5/20.
//
import Foundation
import NetworkExtension
final class SDLTunNetworkManager: @unchecked Sendable {
struct Settings: Sendable {
let ipAddress: String
let maskAddress: String
let netAddress: String
let networkDomain: String
let shouldRouteDefault: Bool
init(config: SDLConfiguration) {
let networkAddress = config.networkAddress
self.ipAddress = networkAddress.ipAddress
self.maskAddress = networkAddress.maskAddress
self.netAddress = networkAddress.netAddress
self.networkDomain = networkAddress.networkDomain
self.shouldRouteDefault = config.exitNode != nil
}
}
private let provider: NEPacketTunnelProvider
init(provider: NEPacketTunnelProvider) {
self.provider = provider
}
func apply(settings: Settings, dnsServer: String) async throws {
let networkSettings = self.makeNetworkSettings(settings: settings, dnsServer: dnsServer)
try await self.provider.setTunnelNetworkSettings(networkSettings)
}
private func makeNetworkSettings(settings: Settings, dnsServer: String) -> NEPacketTunnelNetworkSettings {
let networkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "8.8.8.8")
networkSettings.mtu = 1250
networkSettings.dnsSettings = self.makeDNSSettings(settings: settings, dnsServer: dnsServer)
networkSettings.ipv4Settings = self.makeIPv4Settings(settings: settings, dnsServer: dnsServer)
return networkSettings
}
private func makeDNSSettings(settings: Settings, dnsServer: String) -> NEDNSSettings {
let dnsSettings = NEDNSSettings(servers: [dnsServer])
dnsSettings.searchDomains = [settings.networkDomain]
dnsSettings.matchDomains = [settings.networkDomain, ""]
// false Search Domain
dnsSettings.matchDomainsNoSearch = false
return dnsSettings
}
private func makeIPv4Settings(settings: Settings, dnsServer: String) -> NEIPv4Settings {
let ipv4Settings = NEIPv4Settings(addresses: [settings.ipAddress], subnetMasks: [settings.maskAddress])
ipv4Settings.includedRoutes = self.makeIPv4IncludedRoutes(settings: settings, dnsServer: dnsServer)
ipv4Settings.excludedRoutes = self.makeIPv4ExcludedRoutes()
return ipv4Settings
}
private func makeIPv4IncludedRoutes(settings: Settings, dnsServer: String) -> [NEIPv4Route] {
var routes: [NEIPv4Route] = [
NEIPv4Route(destinationAddress: settings.netAddress, subnetMask: settings.maskAddress),
NEIPv4Route(destinationAddress: dnsServer, subnetMask: "255.255.255.255"),
]
if settings.shouldRouteDefault {
routes.append(.default())
}
return routes
}
private func makeIPv4ExcludedRoutes() -> [NEIPv4Route] {
let dnsServers = SDLUtil.getMacOSSystemDnsServers()
var ipv4DnsServers = dnsServers.filter { !$0.contains(":") }
let commonDnsServers = [
"8.8.8.8",
"8.8.4.4",
"223.5.5.5",
"223.6.6.6",
"114.114.114.114"
]
for ip in commonDnsServers where !ipv4DnsServers.contains(ip) {
ipv4DnsServers.append(ip)
}
return ipv4DnsServers.map {
NEIPv4Route(destinationAddress: $0, subnetMask: "255.255.255.255")
}
}
}