Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wgengine/router: avoid unncessary routing configuration changes #4965

Merged
merged 1 commit into from
Jun 28, 2022

Conversation

mihaip
Copy link
Contributor

@mihaip mihaip commented Jun 28, 2022

The iOS and macOS networking extension API only exposes a single setter
for the entire routing and DNS configuration, and does not appear to
do any kind of diffing or deltas when applying changes. This results
in spurious "network changed" errors in Chrome, even when the
OneCGNATRoute flag from df9ce97 is
used (because we're setting the same configuration repeatedly).

Since we already keep track of the current routing and DNS configuration
in CallbackRouter, use that to detect if they're actually changing, and
only invoke the platform setter if it's actually necessary.

Updates #3102

Signed-off-by: Mihai Parparita mihai@tailscale.com

@mihaip mihaip requested a review from bradfitz June 28, 2022 22:37
}

for i := range a.LocalAddrs {
if a.LocalAddrs[i] != b.LocalAddrs[i] {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wasn't sure if the "can compare with ==" comment in netaddr is only true for IP, or if we can also use it for IPPrefix

Copy link
Member

Choose a reason for hiding this comment

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

also IPPrefix and IPPort and IPRange. I guess docs could be more clear.

@@ -72,6 +72,49 @@ type Config struct {
NetfilterMode preftype.NetfilterMode // how much to manage netfilter rules
}

func (a *Config) Equal(b *Config) bool {
Copy link
Member

@bradfitz bradfitz Jun 28, 2022

Choose a reason for hiding this comment

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

it's probably worth adding a test like tailcfg's TestHostinfoEqual here, so a test fails if somebody adds a new field to Config and forgets to update this method.

At least just this part of the test:

func TestHostinfoEqual(t *testing.T) {
	hiHandles := []string{
		"IPNVersion", "FrontendLogID", "BackendLogID",
		"OS", "OSVersion", "Desktop", "Package", "DeviceModel", "Hostname",
		"ShieldsUp", "ShareeNode",
		"GoArch",
		"RoutableIPs", "RequestTags",
		"Services", "NetInfo", "SSH_HostKeys",
	}
	if have := fieldsOf(reflect.TypeOf(Hostinfo{})); !reflect.DeepEqual(have, hiHandles) {
		t.Errorf("Hostinfo.Equal check might be out of sync\nfields: %q\nhandled: %q\n",
			have, hiHandles)
	}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would it also make sense to use reflect.DeepEqual in the implementation of Equal for Config (that's what Hostinfo does)?

Copy link
Member

Choose a reason for hiding this comment

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

it's not as fast and can allocate and nil vs empty slices are different. So if those don't matter then that's fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is not a hotspot as far as I can tell, so I switched to it. Added tests too.

The iOS and macOS networking extension API only exposes a single setter
for the entire routing and DNS configuration, and does not appear to
do any kind of diffing or deltas when applying changes. This results
in spurious "network changed" errors in Chrome, even when the
`OneCGNATRoute` flag from df9ce97 is
used (because we're setting the same configuration repeatedly).

Since we already keep track of the current routing and DNS configuration
in CallbackRouter, use that to detect if they're actually changing, and
only invoke the platform setter if it's actually necessary.

Updates #3102

Signed-off-by: Mihai Parparita <mihai@tailscale.com>
@mihaip mihaip force-pushed the mihaip/chrome-network-error-changed branch from a8c488a to cee69a3 Compare June 28, 2022 23:46
@mihaip mihaip merged commit 06aa141 into main Jun 28, 2022
@mihaip mihaip deleted the mihaip/chrome-network-error-changed branch June 28, 2022 23:59
DentonGentry added a commit to tailscale/tailscale-android that referenced this pull request Jun 29, 2022
Especially want to get tailscale/tailscale#4965
into an Open Testing release.

Signed-off-by: Denton Gentry <dgentry@tailscale.com>
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.

None yet

2 participants