From 614261d00dbf74f8329fc0946f05fbf1fc7db93e Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Thu, 9 Apr 2020 22:25:31 -0700 Subject: [PATCH] wgengine/magicsock: reset AddrSet states on Rebind Signed-off-by: Brad Fitzpatrick --- wgengine/magicsock/magicsock.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/wgengine/magicsock/magicsock.go b/wgengine/magicsock/magicsock.go index 92bb3c5f6..2264b69fa 100644 --- a/wgengine/magicsock/magicsock.go +++ b/wgengine/magicsock/magicsock.go @@ -584,6 +584,8 @@ func shouldSprayPacket(b []byte) bool { var logPacketDests, _ = strconv.ParseBool(os.Getenv("DEBUG_LOG_PACKET_DESTS")) +const sprayPeriod = 3 * time.Second + // appendDests appends to dsts the destinations that b should be // written to in order to reach as. Some of the returned UDPAddrs may // be fake addrs representing DERP servers. @@ -606,7 +608,6 @@ func (as *AddrSet) appendDests(dsts []*net.UDPAddr, b []byte) (_ []*net.UDPAddr, // Multiple packets are necessary because we have to both establish the // NAT mappings between two peers *and use* the mappings to switch away // from DERP to a higher-priority UDP endpoint. - const sprayPeriod = 3 * time.Second const sprayFreq = 250 * time.Millisecond if spray { as.lastSpray = now @@ -1477,6 +1478,20 @@ func (c *Conn) Rebind() { return } c.pconn4.Reset(packetConn.(*net.UDPConn)) + c.resetAddrSetStates() +} + +// resetAddrSetStates resets the preferred address for all peers and +// re-enables spraying. +// This is called when connectivity changes enough that we no longer +// trust the old routes. +func (c *Conn) resetAddrSetStates() { + c.mu.Lock() + defer c.mu.Unlock() + for _, as := range c.addrsByKey { + as.curAddr = -1 + as.stopSpray = as.timeNow().Add(sprayPeriod) + } } // AddrSet is a set of UDP addresses that implements wireguard/conn.Endpoint.