@ -62,6 +62,7 @@ type LocalBackend struct {
ctxCancel context . CancelFunc // cancels ctx
ctxCancel context . CancelFunc // cancels ctx
logf logger . Logf // general logging
logf logger . Logf // general logging
keyLogf logger . Logf // for printing list of peers on change
keyLogf logger . Logf // for printing list of peers on change
statsLogf logger . Logf // for printing peers stats on change
e wgengine . Engine
e wgengine . Engine
store StateStore
store StateStore
backendLogID string
backendLogID string
@ -121,6 +122,7 @@ func NewLocalBackend(logf logger.Logf, logid string, store StateStore, e wgengin
ctxCancel : cancel ,
ctxCancel : cancel ,
logf : logf ,
logf : logf ,
keyLogf : logger . LogOnChange ( logf , 5 * time . Minute , time . Now ) ,
keyLogf : logger . LogOnChange ( logf , 5 * time . Minute , time . Now ) ,
statsLogf : logger . LogOnChange ( logf , 5 * time . Minute , time . Now ) ,
e : e ,
e : e ,
store : store ,
store : store ,
backendLogID : logid ,
backendLogID : logid ,
@ -343,9 +345,8 @@ func (b *LocalBackend) setWgengineStatus(s *wgengine.Status, err error) {
return
return
}
}
es := b . parseWgStatus ( s )
b . mu . Lock ( )
b . mu . Lock ( )
es := b . parseWgStatusLocked ( s )
c := b . c
c := b . c
b . engineStatus = es
b . engineStatus = es
b . endpoints = append ( [ ] string { } , s . LocalAddrs ... )
b . endpoints = append ( [ ] string { } , s . LocalAddrs ... )
@ -922,30 +923,33 @@ func (b *LocalBackend) Ping(ipStr string) {
} )
} )
}
}
func ( b * LocalBackend ) parseWgStatus ( s * wgengine . Status ) ( ret EngineStatus ) {
// parseWgStatusLocked returns an EngineStatus based on s.
var (
//
peerStats [ ] string
// b.mu must be held; mostly because the caller is about to anyway, and doing so
peerKeys [ ] string
// gives us slightly better guarantees about the two peers stats lines not
)
// being intermixed if there are concurrent calls to our caller.
func ( b * LocalBackend ) parseWgStatusLocked ( s * wgengine . Status ) ( ret EngineStatus ) {
var peerStats , peerKeys strings . Builder
ret . LiveDERPs = s . DERPs
ret . LiveDERPs = s . DERPs
ret . LivePeers = map [ tailcfg . NodeKey ] wgengine . PeerStatus { }
ret . LivePeers = map [ tailcfg . NodeKey ] wgengine . PeerStatus { }
for _ , p := range s . Peers {
for _ , p := range s . Peers {
if ! p . LastHandshake . IsZero ( ) {
if ! p . LastHandshake . IsZero ( ) {
peerStats = append ( peerStats , fmt . Sprintf ( "%d/%d" , p . RxBytes , p . TxBytes ) )
fmt . Fprintf ( & peerStats , "%d/%d " , p . RxBytes , p . TxBytes )
fmt . Fprintf ( & peerKeys , "%s " , p . NodeKey . ShortString ( ) )
ret . NumLive ++
ret . NumLive ++
ret . LivePeers [ p . NodeKey ] = p
ret . LivePeers [ p . NodeKey ] = p
peerKeys = append ( peerKeys , p . NodeKey . ShortString ( ) )
}
}
ret . RBytes += p . RxBytes
ret . RBytes += p . RxBytes
ret . WBytes += p . TxBytes
ret . WBytes += p . TxBytes
}
}
if len ( peerStats ) > 0 {
// [GRINDER STATS LINE ] - please don't remove (used for log parsing)
// [GRINDER STATS LINE S ] - please don't remove (used for log parsing)
b . keyLogf ( "peer keys: %s" , strings . Join ( peerKeys , " " ) )
if peerStats . Len ( ) > 0 {
// [GRINDER STATS LINE] - please don't remove (used for log parsing)
b . keyLogf ( "peer keys: %s" , strings . TrimSpace ( peerKeys . String ( ) ) )
b . l ogf( "v%v peers: %v" , version . Long , strings . Join( peerStats , " " ) )
b . statsL ogf( "v%v peers: %v" , version . Long , strings . TrimSpace( peerStats . String ( ) ) )
}
}
return ret
return ret
}
}