@ -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 ) )
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 := sess . decodeMsg ( msg , & resp ) ; err != nil {
vlogf ( "netmap: decode error: %v" , err )
vlogf ( "netmap: decode error: %v" , err )
return err
return err
}
}
@ -1240,12 +1240,23 @@ func decode(res *http.Response, v any) error {
var jsonEscapedZero = [ ] byte ( ` \u0000 ` )
var jsonEscapedZero = [ ] byte ( ` \u0000 ` )
const justKeepAliveStr = ` { "KeepAlive":true} `
// decodeMsg is responsible for uncompressing msg and unmarshaling into v.
// 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 )
b , err := zstdframe . AppendDecode ( nil , compressedMsg )
if err != nil {
if err != nil {
return err
return err
}
}
sess . ztdDecodesForTest ++
if DevKnob . DumpNetMaps ( ) {
if DevKnob . DumpNetMaps ( ) {
var buf bytes . Buffer
var buf bytes . Buffer
json . Indent ( & buf , b , "" , " " )
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 {
if err := json . Unmarshal ( b , v ) ; err != nil {
return fmt . Errorf ( "response: %v" , err )
return fmt . Errorf ( "response: %v" , err )
}
}
if v . KeepAlive && string ( b ) == justKeepAliveStr {
sess . keepAliveZ = compressedMsg
}
return nil
return nil
}
}