|
|
|
@ -20,6 +20,7 @@ import (
|
|
|
|
|
"os"
|
|
|
|
|
"runtime"
|
|
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
|
|
|
|
"sync"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
@ -72,6 +73,7 @@ type Server struct {
|
|
|
|
|
homeMovesOut expvar.Int // established clients announce home server moves out
|
|
|
|
|
multiForwarderCreated expvar.Int
|
|
|
|
|
multiForwarderDeleted expvar.Int
|
|
|
|
|
removePktForwardOther expvar.Int
|
|
|
|
|
|
|
|
|
|
mu sync.Mutex
|
|
|
|
|
closed bool
|
|
|
|
@ -81,8 +83,9 @@ type Server struct {
|
|
|
|
|
watchers map[*sclient]bool // mesh peer -> true
|
|
|
|
|
// clientsMesh tracks all clients in the cluster, both locally
|
|
|
|
|
// and to mesh peers. If the value is nil, that means the
|
|
|
|
|
// peer is only remote (and thus in the clients Map). If the
|
|
|
|
|
// value is non-nil, it's only remote.
|
|
|
|
|
// peer is only local (and thus in the clients Map, but not
|
|
|
|
|
// remote). If the value is non-nil, it's remote (+ maybe also
|
|
|
|
|
// local).
|
|
|
|
|
clientsMesh map[key.Public]PacketForwarder
|
|
|
|
|
// sentTo tracks which peers have sent to which other peers,
|
|
|
|
|
// and at which connection number. This isn't on sclient
|
|
|
|
@ -1067,6 +1070,7 @@ func (s *Server) RemovePacketForwarder(dst key.Public, fwd PacketForwarder) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if v != fwd {
|
|
|
|
|
s.removePktForwardOther.Add(1)
|
|
|
|
|
// Delete of an entry that wasn't in the
|
|
|
|
|
// map. Harmless, so ignore.
|
|
|
|
|
// (This might happen if a user is moving around
|
|
|
|
@ -1131,6 +1135,7 @@ func (s *Server) ExpVar() expvar.Var {
|
|
|
|
|
m.Set("gauge_current_connnections", &s.curClients)
|
|
|
|
|
m.Set("gauge_current_home_connnections", &s.curHomeClients)
|
|
|
|
|
m.Set("gauge_clients_total", expvar.Func(func() interface{} { return len(s.clientsMesh) }))
|
|
|
|
|
m.Set("gauge_clients_local", expvar.Func(func() interface{} { return len(s.clients) }))
|
|
|
|
|
m.Set("gauge_clients_remote", expvar.Func(func() interface{} { return len(s.clientsMesh) - len(s.clients) }))
|
|
|
|
|
m.Set("accepts", &s.accepts)
|
|
|
|
|
m.Set("clients_replaced", &s.clientsReplaced)
|
|
|
|
@ -1148,5 +1153,45 @@ func (s *Server) ExpVar() expvar.Var {
|
|
|
|
|
m.Set("packets_forwarded_in", &s.packetsForwardedIn)
|
|
|
|
|
m.Set("multiforwarder_created", &s.multiForwarderCreated)
|
|
|
|
|
m.Set("multiforwarder_deleted", &s.multiForwarderDeleted)
|
|
|
|
|
m.Set("packet_forwarder_delete_other_value", &s.removePktForwardOther)
|
|
|
|
|
return m
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Server) ConsistencyCheck() error {
|
|
|
|
|
s.mu.Lock()
|
|
|
|
|
defer s.mu.Unlock()
|
|
|
|
|
|
|
|
|
|
var errs []string
|
|
|
|
|
|
|
|
|
|
var nilMeshNotInClient int
|
|
|
|
|
for k, f := range s.clientsMesh {
|
|
|
|
|
if f == nil {
|
|
|
|
|
if _, ok := s.clients[k]; !ok {
|
|
|
|
|
nilMeshNotInClient++
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if nilMeshNotInClient != 0 {
|
|
|
|
|
errs = append(errs, fmt.Sprintf("%d s.clientsMesh keys not in s.clients", nilMeshNotInClient))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var clientNotInMesh int
|
|
|
|
|
for k := range s.clients {
|
|
|
|
|
if _, ok := s.clientsMesh[k]; !ok {
|
|
|
|
|
clientNotInMesh++
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if clientNotInMesh != 0 {
|
|
|
|
|
errs = append(errs, fmt.Sprintf("%d s.clients keys not in s.clientsMesh", clientNotInMesh))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if s.curClients.Value() != int64(len(s.clients)) {
|
|
|
|
|
errs = append(errs, fmt.Sprintf("expvar connections = %d != clients map says of %d",
|
|
|
|
|
s.curClients.Value(),
|
|
|
|
|
len(s.clients)))
|
|
|
|
|
}
|
|
|
|
|
if len(errs) == 0 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return errors.New(strings.Join(errs, ", "))
|
|
|
|
|
}
|
|
|
|
|