Skip to content

Commit

Permalink
And get things working for iOS too
Browse files Browse the repository at this point in the history
  • Loading branch information
jamilbk committed Mar 17, 2024
1 parent ac061a6 commit c559e97
Showing 1 changed file with 38 additions and 39 deletions.
77 changes: 38 additions & 39 deletions swift/apple/FirezoneNetworkExtension/Adapter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ class Adapter {
/// Network routes monitor.
private var networkMonitor: NWPathMonitor?

/// Used to avoid path update callback cycles on iOS
#if os(iOS)
private var gateways: [Network.NWEndpoint] = []
#endif

/// Private queue used to synchronize access to `WireGuardAdapter` members.
private let workQueue = DispatchQueue(label: "FirezoneAdapterWorkQueue")

Expand Down Expand Up @@ -254,17 +259,6 @@ extension Adapter {
if case .tunnelReady(let session) = state {
// Only respond to path updates if the tunnel is up and functioning

logger.log("\(#function): path.availableInterfaces: \(path.availableInterfaces)")
logger.log("\(#function): path.gateways: \(path.gateways)")
logger.log("\(#function): path.isConstrained: \(path.isConstrained)")
logger.log("\(#function): path.isExpensive: \(path.isExpensive)")
logger.log("\(#function): path.localEndpoint: \(path.localEndpoint)")
logger.log("\(#function): path.remoteEndpoint: \(path.remoteEndpoint)")
logger.log("\(#function): path.supportsDNS: \(path.supportsDNS)")
logger.log("\(#function): path.supportsIPv4: \(path.supportsIPv4)")
logger.log("\(#function): path.supportsIPv6: \(path.supportsIPv6)")
logger.log("\(#function): path.unsatisfiedReason: \(path.unsatisfiedReason)")

if path.status == .unsatisfied {
logger.log("\(#function): Detected network change: Offline.")

Expand All @@ -282,14 +276,31 @@ extension Adapter {
session.reconnect()

// Set potentially new DNS servers
session.setDns(getSystemDefaultResolvers().intoRustString())
if shouldUpdateDns(path: path) {
session.setDns(getSystemDefaultResolvers().intoRustString())
}

if packetTunnelProvider?.reasserting == true {
packetTunnelProvider?.reasserting = false
}
}
}
}

#if os(iOS)
private func shouldUpdateDns(path: Network.NWPath) -> Bool {
if !path.gateways.elementsEqual(gateways) {
gateways = path.gateways
return true
}

return false
}
#else
private func shouldUpdateDns(path _: Network.NWPath) -> Bool {
return true
}
#endif
}

// MARK: Implementing CallbackHandlerDelegate
Expand Down Expand Up @@ -376,7 +387,7 @@ extension Adapter: CallbackHandlerDelegate {

public func getSystemDefaultResolvers() -> String {
#if os(macOS)
let resolvers = SystemConfigurationResolvers(logger: self.logger).getDefaultDNSServers()
let resolvers = SystemConfigurationResolvers(logger: logger).getDefaultDNSServers()
#elseif os(iOS)
let resolvers = resetToSystemDNSGettingBindResolvers()
#endif
Expand All @@ -398,36 +409,24 @@ extension Adapter: CallbackHandlerDelegate {
// If matchDomains is an empty string, /etc/resolv.conf will contain connlib's
// sentinel, which isn't helpful to us.
private func resetToSystemDNSGettingBindResolvers() -> [String] {
logger.log("\(#function): Getting system default resolvers from Bind")
var resolvers: [String] = []
let semaphore = DispatchSemaphore(value: 0)

switch self.state {
case .startingTunnel:
return BindResolvers().getservers().map(BindResolvers.getnameinfo)
case .tunnelReady:
var resolvers: [String] = []
// Set tunnel's matchDomains to a dummy string that will never match any name
networkSettings.matchDomains = ["firezone-fd0020211111"]

// async / await can't be used here because this is an FFI callback
let semaphore = DispatchSemaphore(value: 0)
// Call apply to populate /etc/resolv.conf with the system's default resolvers
networkSettings.apply {
// Only now can we get the system resolvers
resolvers = BindResolvers().getservers().map(BindResolvers.getnameinfo)

// Set tunnel's matchDomains to a dummy string that will never match any name
networkSettings.matchDomains = ["firezone-fd0020211111"]

// Call apply to populate /etc/resolv.conf with the system's default resolvers
networkSettings.apply {
// Only now can we get the system resolvers
resolvers = BindResolvers().getservers().map(BindResolvers.getnameinfo)

// Restore connlib's DNS resolvers
self.networkSettings.matchDomains = [""]
self.networkSettings.apply { semaphore.signal() }
semaphore.wait()
}

return resolvers
case .stoppedTunnel:
logger.error("\(#function): Unexpected state")
return []
// Restore connlib's DNS resolvers
self.networkSettings.matchDomains = [""]
self.networkSettings.apply { semaphore.signal() }
}

semaphore.wait()
return resolvers
}
}
#endif

0 comments on commit c559e97

Please sign in to comment.