Skip to content

fix(apple): save networkSettings var - #10022

Merged
jamilbk merged 3 commits into
mainfrom
fix/ios-system-resolvers
Jul 27, 2025
Merged

fix(apple): save networkSettings var#10022
jamilbk merged 3 commits into
mainfrom
fix/ios-system-resolvers

Conversation

@jamilbk

@jamilbk jamilbk commented Jul 27, 2025

Copy link
Copy Markdown
Member

In 45466e3, the networkSettings variable was no longer saved on the adapter instance, causing all calls of the iOS-specific version of getting system resolvers to return the connlib sentinels after the tunnel first came up.

This PR fixes that logic bug and also cleans this area of the codebase up just a tiny bit so it's easier to follow.

Lastly, we also fix a bug where if the tunnel came up while Firezone was already running, networkSettings would be nil, and we would read the default system resolvers, which were the connlib sentinels.

Fixes #10017

@vercel

vercel Bot commented Jul 27, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
firezone ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 27, 2025 10:37pm

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes a critical bug where the networkSettings variable was not being saved to the adapter instance, causing iOS-specific system resolver calls to return connlib sentinels instead of actual system DNS resolvers. The fix ensures proper DNS resolution functionality on iOS devices.

Key changes:

  • Save networkSettings to the adapter instance after configuration
  • Move path monitoring initialization to occur after network settings are applied
  • Consolidate DNS resolver fetching logic into a single method that handles the complete flow

if lastRelevantPath?.connectivityDifferentFrom(path: path) != false {
lastRelevantPath = path

if lastPath?.connectivityDifferentFrom(path: path) != false {

Copilot AI Jul 27, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The double negative logic != false is unclear and harder to read. Consider using == true or restructuring the condition for better readability.

Suggested change
if lastPath?.connectivityDifferentFrom(path: path) != false {
if lastPath?.connectivityDifferentFrom(path: path) == true {

Copilot uses AI. Check for mistakes.
let networkSettings =
self.networkSettings
?? NetworkSettings(packetTunnelProvider: packetTunnelProvider)
networkSettings ?? NetworkSettings(packetTunnelProvider: packetTunnelProvider)

Copilot AI Jul 27, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The variable networkSettings is being accessed without self. prefix, which could be confusing since there's also a local variable assignment on line 355. Consider using self.networkSettings for clarity.

Suggested change
networkSettings ?? NetworkSettings(packetTunnelProvider: packetTunnelProvider)
self.networkSettings ?? NetworkSettings(packetTunnelProvider: packetTunnelProvider)

Copilot uses AI. Check for mistakes.

@thomaseizinger thomaseizinger left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch. It may be useful to add a few debug log lines here. For one, I find natural language in those easier to read along as they are often a good replacement for comments. Two, looking at those logs will then make it easier to debug in case we ever want to know what is happening.

@jamilbk

jamilbk commented Jul 27, 2025

Copy link
Copy Markdown
Member Author

Yeah let me do one more quick pass over it to add more logging, comments, and some testing.

@jamilbk
jamilbk added this pull request to the merge queue Jul 27, 2025
Merged via the queue into main with commit 42de3ad Jul 27, 2025
27 checks passed
for stringAddress in resolvers {
if let ipv4Address = IPv4Address(stringAddress) {
parsedResolvers.append("\(ipv4Address)")
if ipv4Address.isWithinSentinelRange() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Connlib filters these out for you already so you wouldn't need to do that :)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you saying I should move the warning log to connlib instead?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be helpful to know that we are (mistakenly) trying to set the sentinels as resolvers. Note this is really only a problem on iOS AFAIK.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't see that there is a warning log, yeah I guess that makes sense then.

We can add a debug log to connlib that we are filtering a sentinel DNS and we already have one that we don't have any DNS servers.

What we could react to instead is receiving an empty list of DNS resolvers to set from connlib? Really that should never happen.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to add the warning log to connlib because we may have intermitten states where we don't have a resolver so there would be false-positives.

All of this is going to get a lot easier once we do #8263 because then there will only be one resolver IP and that is simply always set. Then, connlib definitely knows if it is in a state where it doesn't have any servers to forward the queries to.

if lastRelevantPath?.connectivityDifferentFrom(path: path) != false {
lastRelevantPath = path

if lastPath?.connectivityDifferentFrom(path: path) != false {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about it now, does it make sense to update the path but not react to it? Wouldn't it better to store the last path we performed a reset on and always compare connectivity to that?

@jamilbk jamilbk Jul 27, 2025

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's logically the same either way. This way there's one less thing to update inside the conditional and it's a bit less cognitive overhead IMO.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Issues applying system default resolvers on iOS

3 participants