From 4338db28f7ed04b5f716bc3f37268caea5ecf796 Mon Sep 17 00:00:00 2001 From: Andrew Dunham Date: Tue, 5 Mar 2024 18:53:14 -0500 Subject: [PATCH] wgengine/magicsock: prefer link-local addresses to private ones Since link-local addresses are definitionally more likely to be a direct (lower-latency, more reliable) connection than a non-link-local private address, give those a bit of a boost when selecting endpoints. Updates #8097 Signed-off-by: Andrew Dunham Change-Id: I93fdeb07de55ba39ba5fcee0834b579ca05c2a4e --- wgengine/magicsock/endpoint.go | 8 +++++++- wgengine/magicsock/magicsock_test.go | 13 +++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/wgengine/magicsock/endpoint.go b/wgengine/magicsock/endpoint.go index 16036f638..2f8f1630e 100644 --- a/wgengine/magicsock/endpoint.go +++ b/wgengine/magicsock/endpoint.go @@ -1665,14 +1665,20 @@ func betterAddr(a, b addrQuality) bool { // pay for the bandwidth in a cloud environment. // // Additionally, prefer any loopback address strongly over non-loopback - // addresses. + // addresses, and prefer link-local unicast addresses over other types + // of private IP addresses since it's definitionally more likely that + // they'll be on the same network segment than a general private IP. if a.Addr().IsLoopback() { aPoints += 50 + } else if a.Addr().IsLinkLocalUnicast() { + aPoints += 30 } else if a.Addr().IsPrivate() { aPoints += 20 } if b.Addr().IsLoopback() { bPoints += 50 + } else if b.Addr().IsLinkLocalUnicast() { + bPoints += 30 } else if b.Addr().IsPrivate() { bPoints += 20 } diff --git a/wgengine/magicsock/magicsock_test.go b/wgengine/magicsock/magicsock_test.go index 640728d61..762ac7d57 100644 --- a/wgengine/magicsock/magicsock_test.go +++ b/wgengine/magicsock/magicsock_test.go @@ -1747,6 +1747,19 @@ func TestBetterAddr(t *testing.T) { b: al("192.168.0.1:555", 100*ms), want: false, }, + + // Link-local unicast addresses are preferred over other + // private IPs, but not as much as localhost addresses. + { + a: al("[fe80::ce8:474a:a27e:113b]:555", 101*ms), + b: al("[fd89:1a8a:8888:9999:aaaa:bbbb:cccc:dddd]:555", 100*ms), + want: true, + }, + { + a: al("[fe80::ce8:474a:a27e:113b]:555", 101*ms), + b: al("[::1]:555", 100*ms), + want: false, + }, } for i, tt := range tests { got := betterAddr(tt.a, tt.b)