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:
parent
97c569fb35
commit
d1638726ca
46 changed files with 15079 additions and 456 deletions
|
|
@ -9,3 +9,5 @@ CODE_SIGN_ENTITLEMENTS = NetworkExtension/NetworkExtension-iOS.entitlements
|
|||
CODE_SIGN_ENTITLEMENTS[sdk=macosx*] = NetworkExtension/NetworkExtension-macOS.entitlements
|
||||
|
||||
SWIFT_INCLUDE_PATHS = $(inherited) $(PROJECT_DIR)/NetworkExtension
|
||||
|
||||
OTHER_LDFLAGS = $(inherited) -framework SystemConfiguration
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# This is a build script. It is run by Xcode as a build step.
|
||||
# The type of build is described in various environment variables set by Xcode.
|
||||
|
||||
export PATH="${PATH}:${HOME}/.cargo/bin:/opt/homebrew/bin:/usr/local/bin:/etc/profiles/per-user/${USER}/bin"
|
||||
export PATH="${PATH}:${HOME}/.cargo/bin:${HOME}/.nix-profile/bin:/opt/homebrew/bin:/usr/local/bin:/etc/profiles/per-user/${USER}/bin:/run/current-system/sw/bin:/nix/var/nix/profiles/default/bin"
|
||||
|
||||
if ! [[ -x "$(command -v cargo)" ]]; then
|
||||
echo 'error: Unable to find cargo'
|
||||
|
|
@ -63,13 +63,13 @@ else
|
|||
fi
|
||||
|
||||
if [[ -x "$(command -v rustup)" ]]; then
|
||||
CARGO_PATH="$(dirname $(rustup which cargo)):/usr/bin"
|
||||
CARGO_PATH="$(dirname "$(rustup which cargo)"):/usr/bin"
|
||||
else
|
||||
CARGO_PATH="$(dirname $(readlink -f $(which cargo))):/usr/bin"
|
||||
CARGO_PATH="$(dirname "$(readlink -f "$(command -v cargo)")"):/usr/bin"
|
||||
fi
|
||||
|
||||
PROTOC=$(readlink -f $(which protoc))
|
||||
CARGO_PATH="$(dirname $PROTOC):$CARGO_PATH"
|
||||
PROTOC="$(readlink -f "$(command -v protoc)")"
|
||||
CARGO_PATH="$(dirname "$PROTOC"):$CARGO_PATH"
|
||||
|
||||
# Run cargo without the various environment variables set by Xcode.
|
||||
# Those variables can confuse cargo and the build scripts it runs.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue