Add proxy subscription runtime support

Add daemon RPCs, Apple and GTK import flows, packet proxy runtime support, diagnostics, and BEPs for proxy subscription handling.

Redact subscription URL secrets from fetch errors before they reach logs or UI surfaces.
This commit is contained in:
JettChenT 2026-06-01 15:23:17 +08:00
parent 97c569fb35
commit d1638726ca
46 changed files with 15079 additions and 456 deletions

View file

@ -28,13 +28,13 @@ final class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
get throws { try _client.get() }
}
private let _client: Result<TunnelClient, Swift.Error> = Result {
try TunnelClient.unix(socketURL: Constants.socketURL)
try TunnelClient.unix(socketURL: Constants.packetTunnelSocketURL)
}
override init() {
do {
libburrow.spawnInProcess(
socketPath: try Constants.socketURL.path(percentEncoded: false),
socketPath: try Constants.packetTunnelSocketURL.path(percentEncoded: false),
databasePath: try Constants.databaseURL.path(percentEncoded: false)
)
} catch {
@ -54,6 +54,11 @@ final class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
guard let settings = configuration?.settings else {
throw Error.missingTunnelConfiguration
}
if let configuration {
logger.log(
"Applying tunnel configuration addresses=\(configuration.addresses.joined(separator: ","), privacy: .public) routes=\(configuration.routes.joined(separator: ","), privacy: .public) excludedRoutes=\(configuration.excludedRoutes.joined(separator: ","), privacy: .public) dns=\(configuration.dnsServers.joined(separator: ","), privacy: .public) includeDefaultRoute=\(configuration.includeDefaultRoute, privacy: .public)"
)
}
try await setTunnelNetworkSettings(settings)
try startPacketBridge()
logger.log("Started tunnel with network settings: \(settings)")
@ -88,15 +93,22 @@ extension PacketTunnelProvider {
private func startPacketBridge() throws {
stopPacketBridge()
let packetClient = TunnelPacketClient.unix(socketURL: try Constants.socketURL)
let packetClient = TunnelPacketClient.unix(socketURL: try Constants.packetTunnelSocketURL)
let call = packetClient.makeTunnelPacketsCall()
self.packetCall = call
inboundPacketTask = Task { [weak self] in
guard let self else { return }
var packetCount = 0
var byteCount = 0
do {
for try await packet in call.responseStream {
let payload = packet.payload
packetCount += 1
byteCount += payload.count
if packetCount == 1 || packetCount % 1024 == 0 {
self.logger.log("Tunnel packet receive progress packets=\(packetCount, privacy: .public) bytes=\(byteCount, privacy: .public) lastBytes=\(payload.count, privacy: .public)")
}
self.packetFlow.writePackets(
[payload],
withProtocols: [Self.protocolNumber(for: payload)]
@ -111,10 +123,17 @@ extension PacketTunnelProvider {
outboundPacketTask = Task { [weak self] in
guard let self else { return }
defer { call.requestStream.finish() }
var packetCount = 0
var byteCount = 0
do {
while !Task.isCancelled {
let packets = await self.readPacketsBatch()
for (payload, _) in packets {
packetCount += 1
byteCount += payload.count
if packetCount == 1 || packetCount % 1024 == 0 {
self.logger.log("Tunnel packet send progress packets=\(packetCount, privacy: .public) bytes=\(byteCount, privacy: .public) lastBytes=\(payload.count, privacy: .public)")
}
var packet = Burrow_TunnelPacket()
packet.payload = payload
try await call.requestStream.send(packet)
@ -128,6 +147,7 @@ extension PacketTunnelProvider {
}
private func stopPacketBridge() {
logger.log("Stopping tunnel packet bridge")
inboundPacketTask?.cancel()
inboundPacketTask = nil
outboundPacketTask?.cancel()
@ -165,6 +185,9 @@ extension Burrow_TunnelConfigurationResponse {
let parsedRoutes = routes.compactMap(ParsedTunnelRoute.init(rawValue:))
var ipv4Routes = parsedRoutes.compactMap(\.ipv4Route)
var ipv6Routes = parsedRoutes.compactMap(\.ipv6Route)
let parsedExcludedRoutes = excludedRoutes.compactMap(ParsedTunnelRoute.init(rawValue:))
let excludedIPv4Routes = parsedExcludedRoutes.compactMap(\.ipv4Route)
let excludedIPv6Routes = parsedExcludedRoutes.compactMap(\.ipv6Route)
if includeDefaultRoute {
ipv4Routes.append(.default())
ipv6Routes.append(.default())
@ -180,6 +203,9 @@ extension Burrow_TunnelConfigurationResponse {
if !ipv4Routes.isEmpty {
ipv4Settings.includedRoutes = ipv4Routes
}
if !excludedIPv4Routes.isEmpty {
ipv4Settings.excludedRoutes = excludedIPv4Routes
}
settings.ipv4Settings = ipv4Settings
}
if !ipv6Addresses.isEmpty {
@ -190,6 +216,9 @@ extension Burrow_TunnelConfigurationResponse {
if !ipv6Routes.isEmpty {
ipv6Settings.includedRoutes = ipv6Routes
}
if !excludedIPv6Routes.isEmpty {
ipv6Settings.excludedRoutes = excludedIPv6Routes
}
settings.ipv6Settings = ipv6Settings
}
if !dnsServers.isEmpty {