From b462954c20edfd15fc8a923ab2e3313178f13c57 Mon Sep 17 00:00:00 2001 From: David Crawshaw Date: Thu, 16 Jun 2022 16:40:37 +1000 Subject: [PATCH] controlclient: preserve NetInfo on Hostinfo update We have two separate functions, SetHostinfo and SetNetInfo, called by different systems at different times. But we store the NetInfo object inside the Hostinfo object. Usually this is fine if we: 1. SetHostinfo 2. SetNetInfo But it is possible to: 1. SetNetInfo -- controlclient now knows about our home DERP 2. SetHostinfo -- NetInfo is now nil The result is controlclient loses track of our PreferredDERP. In our end-to-end test, this appears as the client being connected to a test DERP server, but the server never receiving the information. This is visible in the logs of the end-to-end test by searching for the string "[v1] HostInfo" and seeing that even though a DERP home is well established before the log line, there is no NetInfo to speak of. Signed-off-by: David Crawshaw --- control/controlclient/direct.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/control/controlclient/direct.go b/control/controlclient/direct.go index bff285865..b89925260 100644 --- a/control/controlclient/direct.go +++ b/control/controlclient/direct.go @@ -242,7 +242,11 @@ func (c *Direct) SetHostinfo(hi *tailcfg.Hostinfo) bool { if hi.Equal(c.hostinfo) { return false } - c.hostinfo = hi.Clone() + hi = hi.Clone() + if c.hostinfo != nil && c.hostinfo.NetInfo != nil && hi.NetInfo == nil { + hi.NetInfo = c.hostinfo.NetInfo + } + c.hostinfo = hi j, _ := json.Marshal(c.hostinfo) c.logf("[v1] HostInfo: %s", j) return true