control/controlclient: add opt-in netmap verbose debugging env var

This commit is contained in:
Brad Fitzpatrick 2020-04-11 09:22:33 -07:00
parent 45f2b53aca
commit 347a926ac4
1 changed files with 21 additions and 0 deletions

View File

@ -426,6 +426,8 @@ func (c *Direct) SetEndpoints(localPort uint16, endpoints []string) (changed boo
return c.newEndpoints(localPort, endpoints) return c.newEndpoints(localPort, endpoints)
} }
var debugNetmap, _ = strconv.ParseBool(os.Getenv("TS_DEBUG_NETMAP"))
func (c *Direct) PollNetMap(ctx context.Context, maxPolls int, cb func(*NetworkMap)) error { func (c *Direct) PollNetMap(ctx context.Context, maxPolls int, cb func(*NetworkMap)) error {
c.mu.Lock() c.mu.Lock()
persist := c.persist persist := c.persist
@ -443,6 +445,11 @@ func (c *Direct) PollNetMap(ctx context.Context, maxPolls int, cb func(*NetworkM
allowStream := maxPolls != 1 allowStream := maxPolls != 1
c.logf("PollNetMap: stream=%v :%v %v", maxPolls, localPort, ep) c.logf("PollNetMap: stream=%v :%v %v", maxPolls, localPort, ep)
vlogf := logger.Discard
if debugNetmap {
vlogf = c.logf
}
request := tailcfg.MapRequest{ request := tailcfg.MapRequest{
Version: 4, Version: 4,
IncludeIPv6: includeIPv6(), IncludeIPv6: includeIPv6(),
@ -458,9 +465,11 @@ func (c *Direct) PollNetMap(ctx context.Context, maxPolls int, cb func(*NetworkM
bodyData, err := encode(request, &serverKey, &persist.PrivateMachineKey) bodyData, err := encode(request, &serverKey, &persist.PrivateMachineKey)
if err != nil { if err != nil {
vlogf("netmap: encode: %v", err)
return err return err
} }
t0 := time.Now()
u := fmt.Sprintf("%s/machine/%s/map", serverURL, persist.PrivateMachineKey.Public().HexString()) u := fmt.Sprintf("%s/machine/%s/map", serverURL, persist.PrivateMachineKey.Public().HexString())
req, err := http.NewRequest("POST", u, bytes.NewReader(bodyData)) req, err := http.NewRequest("POST", u, bytes.NewReader(bodyData))
if err != nil { if err != nil {
@ -472,8 +481,10 @@ func (c *Direct) PollNetMap(ctx context.Context, maxPolls int, cb func(*NetworkM
res, err := c.httpc.Do(req) res, err := c.httpc.Do(req)
if err != nil { if err != nil {
vlogf("netmap: Do: %v", err)
return err return err
} }
vlogf("netmap: Do = %v after %v", res.StatusCode, time.Since(t0).Round(time.Millisecond))
if res.StatusCode != 200 { if res.StatusCode != 200 {
msg, _ := ioutil.ReadAll(res.Body) msg, _ := ioutil.ReadAll(res.Body)
res.Body.Close() res.Body.Close()
@ -498,11 +509,13 @@ func (c *Direct) PollNetMap(ctx context.Context, maxPolls int, cb func(*NetworkM
return return
case _, ok := <-timeoutReset: case _, ok := <-timeoutReset:
if !ok { if !ok {
vlogf("netmap: ending timeout goroutine")
return // channel closed, shut down goroutine return // channel closed, shut down goroutine
} }
if !timeout.Stop() { if !timeout.Stop() {
<-timeout.C <-timeout.C
} }
vlogf("netmap: reset timeout timer")
timeout.Reset(pollTimeout) timeout.Reset(pollTimeout)
} }
} }
@ -516,24 +529,32 @@ func (c *Direct) PollNetMap(ctx context.Context, maxPolls int, cb func(*NetworkM
// We can use this same read loop either way. // We can use this same read loop either way.
var msg []byte var msg []byte
for i := 0; i < maxPolls || maxPolls < 0; i++ { for i := 0; i < maxPolls || maxPolls < 0; i++ {
vlogf("netmap: starting size read after %v (poll %v)", time.Since(t0).Round(time.Millisecond), i)
var siz [4]byte var siz [4]byte
if _, err := io.ReadFull(res.Body, siz[:]); err != nil { if _, err := io.ReadFull(res.Body, siz[:]); err != nil {
vlogf("netmap: size read error after %v: %v", time.Since(t0).Round(time.Millisecond), err)
return err return err
} }
size := binary.LittleEndian.Uint32(siz[:]) size := binary.LittleEndian.Uint32(siz[:])
vlogf("netmap: read size %v after %v", size, time.Since(t0).Round(time.Millisecond))
msg = append(msg[:0], make([]byte, size)...) msg = append(msg[:0], make([]byte, size)...)
if _, err := io.ReadFull(res.Body, msg); err != nil { if _, err := io.ReadFull(res.Body, msg); err != nil {
vlogf("netmap: body read error: %v", err)
return err return err
} }
vlogf("netmap: read body after %v", time.Since(t0).Round(time.Millisecond))
var resp tailcfg.MapResponse var resp tailcfg.MapResponse
if err := c.decodeMsg(msg, &resp); err != nil { if err := c.decodeMsg(msg, &resp); err != nil {
vlogf("netmap: decode error: %v")
return err return err
} }
if resp.KeepAlive { if resp.KeepAlive {
vlogf("netmap: got keep-alive")
timeoutReset <- struct{}{} timeoutReset <- struct{}{}
continue continue
} }
vlogf("netmap: got new map")
nm := &NetworkMap{ nm := &NetworkMap{
NodeKey: tailcfg.NodeKey(persist.PrivateNodeKey.Public()), NodeKey: tailcfg.NodeKey(persist.PrivateNodeKey.Public()),