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 <da@stablebits.net>
reviewable/pr284/r1
Dmitry Adamushko 5 years ago committed by Brad Fitzpatrick
parent 39ae80a2e7
commit f2c2d0de68

@ -205,11 +205,21 @@ func (s *Server) unregisterClient(c *sclient) {
s.curHomeClients.Add(-1) s.curHomeClients.Add(-1)
} }
// Find still-connected peers to notify that we've gone away // Find still-connected peers and either notify that we've gone away
// so they can drop their route entries to us. (issue 150) // 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 { for pubKey, connNum := range c.sentTo {
if peer, ok := s.clients[pubKey]; ok && peer.connNum == connNum { 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() s.mu.Lock()
dst := s.clients[dstKey] 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() s.mu.Unlock()
if dst == nil { if dst == nil {
@ -344,11 +360,6 @@ func (c *sclient) handleFrameSendPacket(ft frameType, fl uint32) error {
return nil 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{ p := pkt{
bs: contents, bs: contents,
} }
@ -527,12 +538,15 @@ type sclient struct {
br *bufio.Reader br *bufio.Reader
connectedAt time.Time connectedAt time.Time
preferred bool 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. // Owned by sender, not thread-safe.
bw *bufio.Writer 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. // pkt is a request to write a data frame to an sclient.

Loading…
Cancel
Save