control/controlclient: optimize zstd decode of KeepAlive messages

Maybe it matters? At least globally across all nodes?

Fixes #17343

Change-Id: I3f61758ea37de527e16602ec1a6e453d913b3195
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2025-09-29 15:19:27 -07:00
committed by Brad Fitzpatrick
parent 3ae7a351b4
commit 2cd518a8b6
3 changed files with 57 additions and 2 deletions

View File

@@ -1091,7 +1091,7 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap
vlogf("netmap: read body after %v", time.Since(t0).Round(time.Millisecond))
var resp tailcfg.MapResponse
if err := c.decodeMsg(msg, &resp); err != nil {
if err := sess.decodeMsg(msg, &resp); err != nil {
vlogf("netmap: decode error: %v", err)
return err
}
@@ -1240,12 +1240,23 @@ func decode(res *http.Response, v any) error {
var jsonEscapedZero = []byte(`\u0000`)
const justKeepAliveStr = `{"KeepAlive":true}`
// decodeMsg is responsible for uncompressing msg and unmarshaling into v.
func (c *Direct) decodeMsg(compressedMsg []byte, v any) error {
func (sess *mapSession) decodeMsg(compressedMsg []byte, v *tailcfg.MapResponse) error {
// Fast path for common case of keep-alive message.
// See tailscale/tailscale#17343.
if sess.keepAliveZ != nil && bytes.Equal(compressedMsg, sess.keepAliveZ) {
v.KeepAlive = true
return nil
}
b, err := zstdframe.AppendDecode(nil, compressedMsg)
if err != nil {
return err
}
sess.ztdDecodesForTest++
if DevKnob.DumpNetMaps() {
var buf bytes.Buffer
json.Indent(&buf, b, "", " ")
@@ -1258,6 +1269,9 @@ func (c *Direct) decodeMsg(compressedMsg []byte, v any) error {
if err := json.Unmarshal(b, v); err != nil {
return fmt.Errorf("response: %v", err)
}
if v.KeepAlive && string(b) == justKeepAliveStr {
sess.keepAliveZ = compressedMsg
}
return nil
}