From f2c2d0de68267ab102c382ba6fd9675986430bfa Mon Sep 17 00:00:00 2001 From: Dmitry Adamushko Date: Mon, 6 Apr 2020 09:18:37 +0200 Subject: [PATCH] derp/derp_server: unregisterClient() for replaced client connections. When unregistering a replaced client connection, move the still-connected peers to the current client connecition. Inform the peers that we've gone only when unregistering the active client connection. Signed-off-by: Dmitry Adamushko --- derp/derp_server.go | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/derp/derp_server.go b/derp/derp_server.go index 1f866ad66..530f87eb4 100644 --- a/derp/derp_server.go +++ b/derp/derp_server.go @@ -205,11 +205,21 @@ func (s *Server) unregisterClient(c *sclient) { s.curHomeClients.Add(-1) } - // Find still-connected peers to notify that we've gone away - // so they can drop their route entries to us. (issue 150) + // Find still-connected peers and either notify that we've gone away + // so they can drop their route entries to us (issue 150) + // or move them over to the active client (in case a replaced client + // connection is being unregistered). for pubKey, connNum := range c.sentTo { if peer, ok := s.clients[pubKey]; ok && peer.connNum == connNum { - go peer.requestPeerGoneWrite(c.key) + if cur == c { + go peer.requestPeerGoneWrite(c.key) + } else { + // Only if the current client has not already accepted a newer + // connection from the peer. + if _, ok := cur.sentTo[pubKey]; !ok { + cur.sentTo[pubKey] = connNum + } + } } } } @@ -333,6 +343,12 @@ func (c *sclient) handleFrameSendPacket(ft frameType, fl uint32) error { s.mu.Lock() dst := s.clients[dstKey] + if dst != nil { + // Track that we've sent to this peer, so if/when we + // disconnect first, the server can inform all our old + // recipients that we're gone. (Issue 150 optimization) + c.sentTo[dstKey] = dst.connNum + } s.mu.Unlock() if dst == nil { @@ -344,11 +360,6 @@ func (c *sclient) handleFrameSendPacket(ft frameType, fl uint32) error { return nil } - // Track that we've sent to this peer, so if/when we - // disconnect first, the server can inform all our old - // recipients that we're gone. (Issue 150 optimization) - c.sentTo[dstKey] = dst.connNum - p := pkt{ bs: contents, } @@ -527,12 +538,15 @@ type sclient struct { br *bufio.Reader connectedAt time.Time preferred bool - // sentTo tracks all the peers this client has ever sent a packet to, and at which - // connection number. - sentTo map[key.Public]int64 // recipient => rcpt's latest sclient.connNum // Owned by sender, not thread-safe. bw *bufio.Writer + + // Guarded by s.mu. + // + // sentTo tracks all the peers this client has ever sent a packet to, and at which + // connection number. + sentTo map[key.Public]int64 // recipient => rcpt's latest sclient.connNum } // pkt is a request to write a data frame to an sclient.