|
|
@ -37,6 +37,7 @@ import (
|
|
|
|
"tailscale.com/derp"
|
|
|
|
"tailscale.com/derp"
|
|
|
|
"tailscale.com/derp/derphttp"
|
|
|
|
"tailscale.com/derp/derphttp"
|
|
|
|
"tailscale.com/disco"
|
|
|
|
"tailscale.com/disco"
|
|
|
|
|
|
|
|
"tailscale.com/health"
|
|
|
|
"tailscale.com/ipn/ipnstate"
|
|
|
|
"tailscale.com/ipn/ipnstate"
|
|
|
|
"tailscale.com/logtail/backoff"
|
|
|
|
"tailscale.com/logtail/backoff"
|
|
|
|
"tailscale.com/net/dnscache"
|
|
|
|
"tailscale.com/net/dnscache"
|
|
|
@ -973,6 +974,7 @@ func (c *Conn) setNearestDERP(derpNum int) (wantDERP bool) {
|
|
|
|
defer c.mu.Unlock()
|
|
|
|
defer c.mu.Unlock()
|
|
|
|
if !c.wantDerpLocked() {
|
|
|
|
if !c.wantDerpLocked() {
|
|
|
|
c.myDerp = 0
|
|
|
|
c.myDerp = 0
|
|
|
|
|
|
|
|
health.SetMagicSockDERPHome(0)
|
|
|
|
return false
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if derpNum == c.myDerp {
|
|
|
|
if derpNum == c.myDerp {
|
|
|
@ -980,6 +982,7 @@ func (c *Conn) setNearestDERP(derpNum int) (wantDERP bool) {
|
|
|
|
return true
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
c.myDerp = derpNum
|
|
|
|
c.myDerp = derpNum
|
|
|
|
|
|
|
|
health.SetMagicSockDERPHome(derpNum)
|
|
|
|
|
|
|
|
|
|
|
|
if c.privateKey.IsZero() {
|
|
|
|
if c.privateKey.IsZero() {
|
|
|
|
// No private key yet, so DERP connections won't come up anyway.
|
|
|
|
// No private key yet, so DERP connections won't come up anyway.
|
|
|
@ -1438,13 +1441,18 @@ func (c *Conn) runDerpReader(ctx context.Context, derpFakeAddr netaddr.IPPort, d
|
|
|
|
return n
|
|
|
|
return n
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
defer health.SetDERPRegionConnectedState(regionID, false)
|
|
|
|
|
|
|
|
|
|
|
|
// peerPresent is the set of senders we know are present on this
|
|
|
|
// peerPresent is the set of senders we know are present on this
|
|
|
|
// connection, based on messages we've received from the server.
|
|
|
|
// connection, based on messages we've received from the server.
|
|
|
|
peerPresent := map[key.Public]bool{}
|
|
|
|
peerPresent := map[key.Public]bool{}
|
|
|
|
bo := backoff.NewBackoff(fmt.Sprintf("derp-%d", regionID), c.logf, 5*time.Second)
|
|
|
|
bo := backoff.NewBackoff(fmt.Sprintf("derp-%d", regionID), c.logf, 5*time.Second)
|
|
|
|
|
|
|
|
var lastPacketTime time.Time
|
|
|
|
|
|
|
|
|
|
|
|
for {
|
|
|
|
for {
|
|
|
|
msg, connGen, err := dc.RecvDetail()
|
|
|
|
msg, connGen, err := dc.RecvDetail()
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
health.SetDERPRegionConnectedState(regionID, false)
|
|
|
|
// Forget that all these peers have routes.
|
|
|
|
// Forget that all these peers have routes.
|
|
|
|
for peer := range peerPresent {
|
|
|
|
for peer := range peerPresent {
|
|
|
|
delete(peerPresent, peer)
|
|
|
|
delete(peerPresent, peer)
|
|
|
@ -1480,8 +1488,15 @@ func (c *Conn) runDerpReader(ctx context.Context, derpFakeAddr netaddr.IPPort, d
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bo.BackOff(ctx, nil) // reset
|
|
|
|
bo.BackOff(ctx, nil) // reset
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
now := time.Now()
|
|
|
|
|
|
|
|
if lastPacketTime.IsZero() || now.Sub(lastPacketTime) > 5*time.Second {
|
|
|
|
|
|
|
|
health.NoteDERPRegionReceivedFrame(regionID)
|
|
|
|
|
|
|
|
lastPacketTime = now
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch m := msg.(type) {
|
|
|
|
switch m := msg.(type) {
|
|
|
|
case derp.ServerInfoMessage:
|
|
|
|
case derp.ServerInfoMessage:
|
|
|
|
|
|
|
|
health.SetDERPRegionConnectedState(regionID, true)
|
|
|
|
c.logf("magicsock: derp-%d connected; connGen=%v", regionID, connGen)
|
|
|
|
c.logf("magicsock: derp-%d connected; connGen=%v", regionID, connGen)
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
case derp.ReceivedPacket:
|
|
|
|
case derp.ReceivedPacket:
|
|
|
|