From 6a934639524bf1e54686d038f526bc2d0d40a71b Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Fri, 6 Aug 2021 15:30:59 -0700 Subject: [PATCH] move code around, add benchmark note that this splits a mutex access in two --- wgengine/userspace.go | 38 +++++++++++++-------- wgengine/userspace_test.go | 67 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 14 deletions(-) diff --git a/wgengine/userspace.go b/wgengine/userspace.go index 4a22c888a..5e237807f 100644 --- a/wgengine/userspace.go +++ b/wgengine/userspace.go @@ -921,11 +921,6 @@ func (e *userspaceEngine) getStatus() (*Status, error) { errc <- err }() - pp := make(map[wgkey.Key]*ipnstate.PeerStatusLite) - p := &ipnstate.PeerStatusLite{} - - var hst1, hst2, n int64 - br := e.statusBufioReader if br != nil { br.Reset(pr) @@ -933,6 +928,29 @@ func (e *userspaceEngine) getStatus() (*Status, error) { br = bufio.NewReaderSize(pr, 1<<10) e.statusBufioReader = br } + + peers, err := e.getPeerStatusLite(br) + if err != nil { + return nil, err + } + if err := <-errc; err != nil { + return nil, fmt.Errorf("IpcGetOperation: %v", err) + } + e.mu.Lock() + defer e.mu.Unlock() + return &Status{ + LocalAddrs: append([]tailcfg.Endpoint(nil), e.endpoints...), + Peers: peers, + DERPs: derpConns, + }, nil +} + +func (e *userspaceEngine) getPeerStatusLite(br *bufio.Reader) ([]ipnstate.PeerStatusLite, error) { + pp := make(map[wgkey.Key]*ipnstate.PeerStatusLite) + p := &ipnstate.PeerStatusLite{} + + var hst1, hst2, n int64 + for { line, err := br.ReadSlice('\n') if err == io.EOF { @@ -986,9 +1004,6 @@ func (e *userspaceEngine) getStatus() (*Status, error) { } // else leave at time.IsZero() } } - if err := <-errc; err != nil { - return nil, fmt.Errorf("IpcGetOperation: %v", err) - } e.mu.Lock() defer e.mu.Unlock() @@ -999,12 +1014,7 @@ func (e *userspaceEngine) getStatus() (*Status, error) { peers = append(peers, *p) } } - - return &Status{ - LocalAddrs: append([]tailcfg.Endpoint(nil), e.endpoints...), - Peers: peers, - DERPs: derpConns, - }, nil + return peers, nil } func (e *userspaceEngine) RequestStatus() { diff --git a/wgengine/userspace_test.go b/wgengine/userspace_test.go index 39fcd9f5b..3d32c4b8a 100644 --- a/wgengine/userspace_test.go +++ b/wgengine/userspace_test.go @@ -5,9 +5,11 @@ package wgengine import ( + "bufio" "bytes" "fmt" "reflect" + "strings" "testing" "go4.org/mem" @@ -17,6 +19,7 @@ import ( "tailscale.com/tailcfg" "tailscale.com/tstime/mono" "tailscale.com/types/key" + "tailscale.com/types/wgkey" "tailscale.com/wgengine/router" "tailscale.com/wgengine/wgcfg" ) @@ -252,3 +255,67 @@ func BenchmarkGenLocalAddrFunc(b *testing.B) { }) b.Logf("x = %v", x) } + +func BenchmarkGetPeerStatusLite(b *testing.B) { + e := new(userspaceEngine) + br := bufio.NewReaderSize(nil, 1<<10) + parseKey := func(s string) wgkey.Key { + k, err := wgkey.ParseHex(s) + if err != nil { + b.Fatal(err) + } + return k + } + e.peerSequence = []wgkey.Key{ + parseKey("0000000000000000000000000000000000000000000000000000000000000002"), + parseKey("0000000000000000000000000000000000000000000000000000000000000003"), + parseKey("0000000000000000000000000000000000000000000000000000000000000004"), + } + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + br.Reset(strings.NewReader(sampleStatus)) + _, err := e.getPeerStatusLite(br) + if err != nil { + b.Fatal(err) + } + } +} + +const sampleStatus = ` +private_key=0000000000000000000000000000000000000000000000000000000000000001 +listen_port=50818 +public_key=0000000000000000000000000000000000000000000000000000000000000002 +preshared_key=0000000000000000000000000000000000000000000000000000000000000000 +protocol_version=1 +endpoint={"pk":"0000000000000000000000000000000000000000000000000000000000000002","dk":"discokey:0000000000000000000000000000000000000000000000000000000000000000","ipp":["139.162.81.125:41641"]} +last_handshake_time_sec=1628288511 +last_handshake_time_nsec=993469000 +tx_bytes=272 +rx_bytes=272 +persistent_keepalive_interval=25 +allowed_ip=100.100.100.101/32 +allowed_ip=::2/128 +public_key=0000000000000000000000000000000000000000000000000000000000000003 +preshared_key=0000000000000000000000000000000000000000000000000000000000000000 +protocol_version=1 +endpoint={"pk":"0000000000000000000000000000000000000000000000000000000000000003","dk":"discokey:c6c0a1488ac6cb9e0103d056ca51387e33513d577b985e77c6ea075f76b27d35","ipp":null} +last_handshake_time_sec=1628288511 +last_handshake_time_nsec=615842000 +tx_bytes=1300 +rx_bytes=92 +persistent_keepalive_interval=0 +allowed_ip=100.100.100.102/32 +allowed_ip=::3/128 +public_key=0000000000000000000000000000000000000000000000000000000000000004 +preshared_key=0000000000000000000000000000000000000000000000000000000000000000 +protocol_version=1 +endpoint={"pk":"0000000000000000000000000000000000000000000000000000000000000004","dk":"discokey:c6c0a1488ac6cb9e0103d056ca51387e33513d577b985e77c6ea075f76b27d35","ipp":null} +last_handshake_time_sec=1628288511 +last_handshake_time_nsec=615842000 +tx_bytes=1300 +rx_bytes=92 +persistent_keepalive_interval=0 +allowed_ip=100.100.100.103/32 +allowed_ip=::4/128 +`