mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 10:18:54 +00:00
Temporarily set matchDomains when tunnel is reasserting (#3012)
I realized we had the right approach in the comments on PR #2967, but had a bug in the implementation. This implements that approach. Tested to work under the following scenarios: - macOS with Ethernet and WiFi connected - Disable Ethernet adapter -> ✅ - Disable WiFi (no internet) -> Enable WiFi -> ✅ - Enable Ethernet adapter -> Disable WiFi -> ✅ - Disable both Ethernet and WiFi -> Enable WiFi -> ✅ - Switching WiFi networks -> ✅ - iOS with WiFi and cellular connected - Disable WiFi -> ✅ - Disable cellular -> ✅ - Disable both WiFi and cellular -> Enable WiFi -> ✅ - Switching WiFi networks -> ✅ Under all of the tests above, Split DNS with connlib worked reliably after the `onTunnelReady` callback completed.
This commit is contained in:
@@ -35,8 +35,6 @@
|
||||
8D2F64EF2A973F7000B6176A /* PrimaryMacAddress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D2F64EC2A97336C00B6176A /* PrimaryMacAddress.swift */; };
|
||||
8DC08BCB2B296C4500675F46 /* libresolv.9.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC08BCA2B296C4500675F46 /* libresolv.9.tbd */; };
|
||||
8DC08BCD2B296C5900675F46 /* libresolv.9.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC08BCC2B296C5900675F46 /* libresolv.9.tbd */; };
|
||||
8DC08BCF2B29791E00675F46 /* DNSResolvers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DC08BCE2B29791E00675F46 /* DNSResolvers.swift */; };
|
||||
8DC08BD02B29791E00675F46 /* DNSResolvers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DC08BCE2B29791E00675F46 /* DNSResolvers.swift */; };
|
||||
8DC08BD22B297B7B00675F46 /* libresolv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC08BD12B297B7B00675F46 /* libresolv.tbd */; };
|
||||
8DC08BD42B297B8200675F46 /* libresolv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC08BD32B297B8200675F46 /* libresolv.tbd */; };
|
||||
8DC08BD62B297DA400675F46 /* FirezoneNetworkExtension-Bridging-Header.h in Sources */ = {isa = PBXBuildFile; fileRef = 6FE455112A5D13A2006549B1 /* FirezoneNetworkExtension-Bridging-Header.h */; };
|
||||
@@ -123,7 +121,6 @@
|
||||
8D2F64EC2A97336C00B6176A /* PrimaryMacAddress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimaryMacAddress.swift; sourceTree = "<group>"; };
|
||||
8DC08BCA2B296C4500675F46 /* libresolv.9.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.9.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS17.2.sdk/usr/lib/libresolv.9.tbd; sourceTree = DEVELOPER_DIR; };
|
||||
8DC08BCC2B296C5900675F46 /* libresolv.9.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.9.tbd; path = usr/lib/libresolv.9.tbd; sourceTree = SDKROOT; };
|
||||
8DC08BCE2B29791E00675F46 /* DNSResolvers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DNSResolvers.swift; sourceTree = "<group>"; };
|
||||
8DC08BD12B297B7B00675F46 /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = usr/lib/libresolv.tbd; sourceTree = SDKROOT; };
|
||||
8DC08BD32B297B8200675F46 /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS17.2.sdk/usr/lib/libresolv.tbd; sourceTree = DEVELOPER_DIR; };
|
||||
8DCC021928D512AC007E12D2 /* Firezone.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Firezone.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@@ -193,7 +190,6 @@
|
||||
6FE4550E2A5D112C006549B1 /* connlib-client-apple.swift */,
|
||||
8D2F64EC2A97336C00B6176A /* PrimaryMacAddress.swift */,
|
||||
6FE455112A5D13A2006549B1 /* FirezoneNetworkExtension-Bridging-Header.h */,
|
||||
8DC08BCE2B29791E00675F46 /* DNSResolvers.swift */,
|
||||
8D28EB982B35FBD70083621C /* Resolv.swift */,
|
||||
);
|
||||
path = FirezoneNetworkExtension;
|
||||
@@ -512,7 +508,6 @@
|
||||
6FA39A042A6A7248000F0157 /* NetworkResource.swift in Sources */,
|
||||
6FE4550C2A5D111E006549B1 /* SwiftBridgeCore.swift in Sources */,
|
||||
6FE93AFB2A738D7E002D278A /* NetworkSettings.swift in Sources */,
|
||||
8DC08BCF2B29791E00675F46 /* DNSResolvers.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -521,7 +516,6 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8DC08BD62B297DA400675F46 /* FirezoneNetworkExtension-Bridging-Header.h in Sources */,
|
||||
8DC08BD02B29791E00675F46 /* DNSResolvers.swift in Sources */,
|
||||
8D2F64EF2A973F7000B6176A /* PrimaryMacAddress.swift in Sources */,
|
||||
6FE4550A2A5D110D006549B1 /* CallbackHandler.swift in Sources */,
|
||||
8D28EB9A2B35FBD70083621C /* Resolv.swift in Sources */,
|
||||
|
||||
@@ -250,6 +250,18 @@ extension Adapter {
|
||||
// MARK: Responding to path updates
|
||||
|
||||
extension Adapter {
|
||||
private func resetToSystemDNS() {
|
||||
// Setting this to anything but an empty string will populate /etc/resolv.conf with
|
||||
// the default interface's DNS servers, which we read later from connlib
|
||||
// during tunnel setup.
|
||||
self.networkSettings?.setMatchDomains(["firezone-fd0020211111"])
|
||||
self.networkSettings?.apply(
|
||||
on: self.packetTunnelProvider,
|
||||
logger: self.logger,
|
||||
completionHandler: nil
|
||||
)
|
||||
}
|
||||
|
||||
private func beginPathMonitoring() {
|
||||
self.logger.log("Beginning path monitoring")
|
||||
let networkMonitor = NWPathMonitor()
|
||||
@@ -267,6 +279,7 @@ extension Adapter {
|
||||
if path.status != .satisfied {
|
||||
self.logger.log("Adapter.didReceivePathUpdate: Offline. Shutting down connlib.")
|
||||
onStarted?(nil)
|
||||
resetToSystemDNS()
|
||||
self.packetTunnelProvider?.reasserting = true
|
||||
self.state = .stoppingTunnelTemporarily(session: session, onStopped: nil)
|
||||
session.disconnect()
|
||||
@@ -275,6 +288,7 @@ extension Adapter {
|
||||
case .tunnelReady(let session):
|
||||
if path.status != .satisfied {
|
||||
self.logger.log("Adapter.didReceivePathUpdate: Offline. Shutting down connlib.")
|
||||
resetToSystemDNS()
|
||||
self.packetTunnelProvider?.reasserting = true
|
||||
self.state = .stoppingTunnelTemporarily(session: session, onStopped: nil)
|
||||
session.disconnect()
|
||||
@@ -367,6 +381,8 @@ extension Adapter: CallbackHandlerDelegate {
|
||||
self.logger.error("Adapter.onTunnelReady: No packet tunnel provider")
|
||||
return
|
||||
}
|
||||
// Connlib's up, set it as the default DNS
|
||||
networkSettings.setMatchDomains([""])
|
||||
networkSettings.apply(on: packetTunnelProvider, logger: self.logger) { error in
|
||||
if let error = error {
|
||||
packetTunnelProvider.handleTunnelShutdown(
|
||||
@@ -503,7 +519,7 @@ extension Adapter: CallbackHandlerDelegate {
|
||||
}
|
||||
|
||||
public func getSystemDefaultResolvers() -> [String] {
|
||||
let resolvers = DNSResolvers.getDNSResolvers()
|
||||
let resolvers = Resolv().getservers().map(Resolv.getnameinfo)
|
||||
self.logger.info("getSystemDefaultResolvers: \(resolvers)")
|
||||
return resolvers
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
//
|
||||
// DNSResolvers.swift
|
||||
// Firezone
|
||||
//
|
||||
// Created by Jamil Bou Kheir on 12/12/23.
|
||||
//
|
||||
// Returns the system's DNS Resolvers on macOS
|
||||
|
||||
import Foundation
|
||||
|
||||
public class DNSResolvers {
|
||||
// FIXME: We need to find a method of finding the system's default resolvers that
|
||||
// works on both macOS and iOS. See https://github.com/firezone/firezone/issues/2939
|
||||
private static let resolvers = ["1.1.1.1", "1.0.0.1"]
|
||||
|
||||
public static func getDNSResolvers() -> [String] {
|
||||
return resolvers
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ class NetworkSettings {
|
||||
// Modifiable values
|
||||
private(set) var routes: [String] = []
|
||||
private(set) var resourceDomains: [String] = []
|
||||
private(set) var matchDomains: [String] = [""]
|
||||
|
||||
// To keep track of modifications
|
||||
private(set) var hasUnappliedChanges: Bool
|
||||
@@ -57,10 +58,17 @@ class NetworkSettings {
|
||||
self.hasUnappliedChanges = true
|
||||
}
|
||||
|
||||
func setMatchDomains(_ matchDomains: [String]) {
|
||||
self.matchDomains = matchDomains
|
||||
self.hasUnappliedChanges = true
|
||||
}
|
||||
|
||||
func apply(
|
||||
on packetTunnelProvider: NEPacketTunnelProvider, logger: Logger,
|
||||
on packetTunnelProvider: NEPacketTunnelProvider?,
|
||||
logger: Logger,
|
||||
completionHandler: ((Error?) -> Void)?
|
||||
) {
|
||||
guard let packetTunnelProvider = packetTunnelProvider else { return }
|
||||
|
||||
guard self.hasUnappliedChanges else {
|
||||
logger.error("NetworkSettings.apply: No changes to apply")
|
||||
@@ -141,7 +149,8 @@ class NetworkSettings {
|
||||
|
||||
let dnsSettings = NEDNSSettings(servers: [dnsAddress])
|
||||
// Intercept all DNS queries; SplitDNS will be handled by connlib
|
||||
dnsSettings.matchDomains = [""]
|
||||
dnsSettings.matchDomains = matchDomains
|
||||
dnsSettings.matchDomainsNoSearch = true
|
||||
tunnelNetworkSettings.dnsSettings = dnsSettings
|
||||
tunnelNetworkSettings.mtu = mtu
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
//
|
||||
// Created by Jamil Bou Kheir on 12/22/23.
|
||||
//
|
||||
// Reads system resolvers from libresolv, similar to reading /etc/resolv.conf but this also works on iOS
|
||||
|
||||
public class Resolv {
|
||||
var state = __res_9_state()
|
||||
|
||||
Reference in New Issue
Block a user