Skip to content

Commit

Permalink
Remove WireGuard from BSK (#958)
Browse files Browse the repository at this point in the history
Required:

Task/Issue URL: https://app.asana.com/0/414709148257752/1207874749913488/f
iOS PR: duckduckgo/iOS#3273
macOS PR: duckduckgo/macos-browser#3144
What kind of version bump will this require?: Major

Description:

This PR removes wireguard-apple as a direct dependency of BSK, and shifts that dependency to the clients.
  • Loading branch information
samsymons authored Aug 28, 2024
1 parent 606ccf9 commit db0a7b4
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 46 deletions.
9 changes: 0 additions & 9 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,6 @@
"revision" : "1403e17eeeb8493b92fb9d11eb8c846bb9776581",
"version" : "2.1.2"
}
},
{
"identity" : "wireguard-apple",
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/wireguard-apple",
"state" : {
"revision" : "13fd026384b1af11048451061cc1b21434990668",
"version" : "1.1.3"
}
}
],
"version" : 2
Expand Down
2 changes: 0 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ let package = Package(
.package(url: "https://github.com/duckduckgo/privacy-dashboard", exact: "5.1.1"),
.package(url: "https://github.com/httpswift/swifter.git", exact: "1.5.0"),
.package(url: "https://github.com/duckduckgo/bloom_cpp.git", exact: "3.0.0"),
.package(url: "https://github.com/duckduckgo/wireguard-apple", exact: "1.1.3"),
.package(url: "https://github.com/1024jp/GzipSwift.git", exact: "6.0.1")
],
targets: [
Expand Down Expand Up @@ -321,7 +320,6 @@ let package = Package(
name: "NetworkProtection",
dependencies: [
.target(name: "WireGuardC"),
.product(name: "WireGuard", package: "wireguard-apple"),
"Common",
],
swiftSettings: [
Expand Down
5 changes: 4 additions & 1 deletion Sources/NetworkProtection/PacketTunnelProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ open class PacketTunnelProvider: NEPacketTunnelProvider {
// MARK: - WireGuard

private lazy var adapter: WireGuardAdapter = {
WireGuardAdapter(with: self) { logLevel, message in
WireGuardAdapter(with: self, wireGuardInterface: self.wireGuardInterface) { logLevel, message in
if logLevel == .error {
os_log("🔴 Received error from adapter: %{public}@", log: .networkProtection, type: .error, message)
} else {
Expand Down Expand Up @@ -416,6 +416,7 @@ open class PacketTunnelProvider: NEPacketTunnelProvider {
private let controllerErrorStore: NetworkProtectionTunnelErrorStore
private let knownFailureStore: NetworkProtectionKnownFailureStore
private let snoozeTimingStore: NetworkProtectionSnoozeTimingStore
private let wireGuardInterface: WireGuardInterface

// MARK: - Cancellables

Expand All @@ -435,6 +436,7 @@ open class PacketTunnelProvider: NEPacketTunnelProvider {
controllerErrorStore: NetworkProtectionTunnelErrorStore,
knownFailureStore: NetworkProtectionKnownFailureStore = NetworkProtectionKnownFailureStore(),
snoozeTimingStore: NetworkProtectionSnoozeTimingStore,
wireGuardInterface: WireGuardInterface,
keychainType: KeychainType,
tokenStore: NetworkProtectionTokenStore,
debugEvents: EventMapping<NetworkProtectionError>?,
Expand All @@ -454,6 +456,7 @@ open class PacketTunnelProvider: NEPacketTunnelProvider {
self.controllerErrorStore = controllerErrorStore
self.knownFailureStore = knownFailureStore
self.snoozeTimingStore = snoozeTimingStore
self.wireGuardInterface = wireGuardInterface
self.settings = settings
self.defaults = defaults
self.isSubscriptionEnabled = isSubscriptionEnabled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ import Network
import NetworkExtension
import Common

#if SWIFT_PACKAGE
import WireGuard
#endif

/// A type alias for `Result` type that holds a tuple with source and resolved endpoint.
typealias EndpointResolutionResult = Result<(Endpoint, Endpoint), DNSResolutionError>

Expand Down
71 changes: 41 additions & 30 deletions Sources/NetworkProtection/WireGuardKit/WireGuardAdapter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,24 @@
import Foundation
import NetworkExtension
@_implementationOnly import WireGuardC
import WireGuard
import Common

// MARK: - WireGuard Interface

/// This protocol abstracts the WireGuard Go library.
/// The Go library is only included in VPN packet tunnel provider targets that need it, to avoid being embedded in other targets such as apps and login items that don't use it.
public protocol WireGuardInterface {
func turnOn(settings: UnsafePointer<CChar>, handle: Int32) -> Int32
func turnOff(handle: Int32)
func getConfig(handle: Int32) -> UnsafeMutablePointer<CChar>?
func setConfig(handle: Int32, config: String) -> Int64
func bumpSockets(handle: Int32)
func disableSomeRoamingForBrokenMobileSemantics(handle: Int32)
func setLogger(context: UnsafeMutableRawPointer?, logFunction: (@convention(c) (UnsafeMutableRawPointer?, Int32, UnsafePointer<CChar>?) -> Void)?)
}

// MARK: - WireGuard Adapter

public enum WireGuardAdapterErrorInvalidStateReason: String {
case alreadyStarted
case alreadyStopped
Expand Down Expand Up @@ -125,6 +140,8 @@ public class WireGuardAdapter {
/// Adapter state.
private var state: State = .stopped

private let wireGuardInterface: WireGuardInterface

/// Tunnel device file descriptor.
private var tunnelFileDescriptor: Int32? {
var ctlInfo = ctl_info()
Expand Down Expand Up @@ -163,14 +180,6 @@ public class WireGuardAdapter {
return nil
}

/// Returns a WireGuard version.
public class var backendVersion: String {
guard let ver = wgVersion() else { return "unknown" }
let str = String(cString: ver)
free(UnsafeMutableRawPointer(mutating: ver))
return str
}

/// Returns the tunnel device interface name, or nil on error.
/// - Returns: String.
public var interfaceName: String? {
Expand Down Expand Up @@ -203,10 +212,11 @@ public class WireGuardAdapter {
/// - Parameter packetTunnelProvider: an instance of `NEPacketTunnelProvider`. Internally stored
/// as a weak reference.
/// - Parameter logHandler: a log handler closure.
public init(with packetTunnelProvider: NEPacketTunnelProvider, logHandler: @escaping LogHandler) {
public init(with packetTunnelProvider: NEPacketTunnelProvider, wireGuardInterface: WireGuardInterface, logHandler: @escaping LogHandler) {
os_log("[+] WireGuardAdapter", log: .networkProtectionMemoryLog, type: .debug)

self.packetTunnelProvider = packetTunnelProvider
self.wireGuardInterface = wireGuardInterface
self.logHandler = logHandler

setupLogHandler()
Expand All @@ -217,14 +227,14 @@ public class WireGuardAdapter {

// Force remove logger to make sure that no further calls to the instance of this class
// can happen after deallocation.
wgSetLogger(nil, nil)
wireGuardInterface.setLogger(context: nil, logFunction: nil)

// Cancel network monitor
networkMonitor?.cancel()

// Shutdown the tunnel
if case .started(let handle, _) = self.state {
wgTurnOff(handle)
wireGuardInterface.turnOff(handle: handle)
}
}

Expand Down Expand Up @@ -299,7 +309,7 @@ public class WireGuardAdapter {
return
}

if let settings = wgGetConfig(handle) {
if let settings = self.wireGuardInterface.getConfig(handle: handle) {
completionHandler(String(cString: settings))
free(settings)
} else {
Expand Down Expand Up @@ -353,7 +363,7 @@ public class WireGuardAdapter {
workQueue.async {
switch self.state {
case .started(let handle, _):
wgTurnOff(handle)
self.wireGuardInterface.turnOff(handle: handle)

case .temporaryShutdown, .snoozing:
break
Expand All @@ -376,7 +386,7 @@ public class WireGuardAdapter {
workQueue.async {
switch self.state {
case .started(let handle, _):
wgTurnOff(handle)
self.wireGuardInterface.turnOff(handle: handle)

case .temporaryShutdown, .snoozing:
break
Expand Down Expand Up @@ -430,16 +440,15 @@ public class WireGuardAdapter {
let (wgConfig, resolutionResults) = settingsGenerator.uapiConfiguration()
self.logEndpointResolutionResults(resolutionResults)

let result = wgSetConfig(handle, wgConfig)
let result = self.wireGuardInterface.setConfig(handle: handle, config: wgConfig)

if result < 0 {
let error = NSError(domain: WireGuardAdapterError.wireguardAdapterDomain,
code: Int(result))
let error = NSError(domain: WireGuardAdapterError.wireguardAdapterDomain, code: Int(result))
throw WireGuardAdapterError.setWireguardConfig(error)
}

#if os(iOS)
wgDisableSomeRoamingForBrokenMobileSemantics(handle)
self.wireGuardInterface.disableSomeRoamingForBrokenMobileSemantics(handle: handle)
#endif

self.state = .started(handle, settingsGenerator)
Expand Down Expand Up @@ -467,18 +476,20 @@ public class WireGuardAdapter {

/// Setup WireGuard log handler.
private func setupLogHandler() {
let context = Unmanaged.passUnretained(self).toOpaque()
wgSetLogger(context) { context, logLevel, message in
guard let context = context, let message = message else { return }
let loggerFunction: @convention(c) (UnsafeMutableRawPointer?, Int32, UnsafePointer<CChar>?) -> Void = { adapter, logLevel, message in
guard let adapter = adapter, let message = message else { return }

let unretainedSelf = Unmanaged<WireGuardAdapter>.fromOpaque(context)
let unretainedSelf = Unmanaged<WireGuardAdapter>.fromOpaque(adapter)
.takeUnretainedValue()

let swiftString = String(cString: message).trimmingCharacters(in: .newlines)
let tunnelLogLevel = WireGuardLogLevel(rawValue: logLevel) ?? .verbose

unretainedSelf.logHandler(tunnelLogLevel, swiftString)
}

let context = Unmanaged.passUnretained(self).toOpaque()
wireGuardInterface.setLogger(context: context, logFunction: loggerFunction)
}

/// Set network tunnel configuration.
Expand Down Expand Up @@ -551,14 +562,14 @@ public class WireGuardAdapter {
throw WireGuardAdapterError.cannotLocateTunnelFileDescriptor
}

let handle = wgTurnOn(wgConfig, tunnelFileDescriptor)
let handle = wireGuardInterface.turnOn(settings: wgConfig, handle: tunnelFileDescriptor)
if handle < 0 {
let error = NSError(domain: WireGuardAdapterError.wireguardAdapterDomain,
code: Int(handle))
throw WireGuardAdapterError.startWireGuardBackend(error)
}
#if os(iOS)
wgDisableSomeRoamingForBrokenMobileSemantics(handle)
wireGuardInterface.disableSomeRoamingForBrokenMobileSemantics(handle: handle)
#endif
return handle
}
Expand Down Expand Up @@ -598,7 +609,7 @@ public class WireGuardAdapter {

#if os(macOS)
if case .started(let handle, _) = self.state {
wgBumpSockets(handle)
wireGuardInterface.bumpSockets(handle: handle)
}
#elseif os(iOS)
switch self.state {
Expand All @@ -607,14 +618,14 @@ public class WireGuardAdapter {
let (wgConfig, resolutionResults) = settingsGenerator.endpointUapiConfiguration()
self.logEndpointResolutionResults(resolutionResults)

wgSetConfig(handle, wgConfig)
wgDisableSomeRoamingForBrokenMobileSemantics(handle)
wgBumpSockets(handle)
_ = self.wireGuardInterface.setConfig(handle: handle, config: wgConfig)
self.wireGuardInterface.disableSomeRoamingForBrokenMobileSemantics(handle: handle)
self.wireGuardInterface.bumpSockets(handle: handle)
} else {
self.logHandler(.verbose, "Connectivity offline, pausing backend.")

self.state = .temporaryShutdown(settingsGenerator)
wgTurnOff(handle)
self.wireGuardInterface.turnOff(handle: handle)
}

case .temporaryShutdown(let settingsGenerator):
Expand Down

0 comments on commit db0a7b4

Please sign in to comment.