tailcfg: pointerify RegisterRequest.Auth, omitemptify RegisterResponseAuth

We were storing server-side lots of:

    "Auth":{"Provider":"","LoginName":"","Oauth2Token":null,"AuthKey":""},

That was about 7% of our total storage of pending RegisterRequest
bodies.

Updates tailscale/corp#19327

Change-Id: Ib73842759a2b303ff5fe4c052a76baea0d68ae7d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2024-04-20 10:04:04 -07:00 committed by Brad Fitzpatrick
parent 375617c5c8
commit 05bfa022f2
5 changed files with 20 additions and 12 deletions

View File

@ -6,6 +6,7 @@
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"cmp"
"context" "context"
"crypto/ed25519" "crypto/ed25519"
"encoding/base64" "encoding/base64"
@ -586,10 +587,14 @@ func (c *Direct) doLogin(ctx context.Context, opt loginOpt) (mustRegen bool, new
c.logf("RegisterReq: onode=%v node=%v fup=%v nks=%v", c.logf("RegisterReq: onode=%v node=%v fup=%v nks=%v",
request.OldNodeKey.ShortString(), request.OldNodeKey.ShortString(),
request.NodeKey.ShortString(), opt.URL != "", len(nodeKeySignature) > 0) request.NodeKey.ShortString(), opt.URL != "", len(nodeKeySignature) > 0)
request.Auth.Oauth2Token = opt.Token if opt.Token != nil || cmp.Or(persist.Provider, persist.UserProfile.LoginName, authKey) != "" {
request.Auth.Provider = persist.Provider request.Auth = &tailcfg.RegisterResponseAuth{
request.Auth.LoginName = persist.UserProfile.LoginName Oauth2Token: opt.Token,
request.Auth.AuthKey = authKey Provider: persist.Provider,
LoginName: persist.UserProfile.LoginName,
AuthKey: authKey,
}
}
err = signRegisterRequest(&request, c.serverURL, c.serverLegacyKey, machinePrivKey.Public()) err = signRegisterRequest(&request, c.serverURL, c.serverLegacyKey, machinePrivKey.Public())
if err != nil { if err != nil {
// If signing failed, clear all related fields // If signing failed, clear all related fields

View File

@ -1069,10 +1069,13 @@ func (st SignatureType) String() string {
// in response to a RegisterRequest. // in response to a RegisterRequest.
type RegisterResponseAuth struct { type RegisterResponseAuth struct {
_ structs.Incomparable _ structs.Incomparable
// One of Provider/LoginName, Oauth2Token, or AuthKey is set. // One of Provider/LoginName, Oauth2Token, or AuthKey is set.
Provider, LoginName string
Oauth2Token *Oauth2Token Provider string `json:",omitempty"`
AuthKey string LoginName string `json:",omitempty"`
Oauth2Token *Oauth2Token `json:",omitempty"`
AuthKey string `json:",omitempty"`
} }
// RegisterRequest is sent by a client to register the key for a node. // RegisterRequest is sent by a client to register the key for a node.
@ -1093,7 +1096,7 @@ type RegisterRequest struct {
NodeKey key.NodePublic NodeKey key.NodePublic
OldNodeKey key.NodePublic OldNodeKey key.NodePublic
NLKey key.NLPublic NLKey key.NLPublic
Auth RegisterResponseAuth Auth *RegisterResponseAuth `json:",omitempty"`
// Expiry optionally specifies the requested key expiry. // Expiry optionally specifies the requested key expiry.
// The server policy may override. // The server policy may override.
// As a special case, if Expiry is in the past and NodeKey is // As a special case, if Expiry is in the past and NodeKey is

View File

@ -335,7 +335,7 @@ func (src *RegisterRequest) Clone() *RegisterRequest {
} }
dst := new(RegisterRequest) dst := new(RegisterRequest)
*dst = *src *dst = *src
dst.Auth = *src.Auth.Clone() dst.Auth = src.Auth.Clone()
dst.Hostinfo = src.Hostinfo.Clone() dst.Hostinfo = src.Hostinfo.Clone()
dst.NodeKeySignature = append(src.NodeKeySignature[:0:0], src.NodeKeySignature...) dst.NodeKeySignature = append(src.NodeKeySignature[:0:0], src.NodeKeySignature...)
if dst.Timestamp != nil { if dst.Timestamp != nil {
@ -353,7 +353,7 @@ func (src *RegisterRequest) Clone() *RegisterRequest {
NodeKey key.NodePublic NodeKey key.NodePublic
OldNodeKey key.NodePublic OldNodeKey key.NodePublic
NLKey key.NLPublic NLKey key.NLPublic
Auth RegisterResponseAuth Auth *RegisterResponseAuth
Expiry time.Time Expiry time.Time
Followup string Followup string
Hostinfo *Hostinfo Hostinfo *Hostinfo

View File

@ -803,7 +803,7 @@ func (v RegisterRequestView) Tailnet() string { return v.ж.Tailnet }
NodeKey key.NodePublic NodeKey key.NodePublic
OldNodeKey key.NodePublic OldNodeKey key.NodePublic
NLKey key.NLPublic NLKey key.NLPublic
Auth RegisterResponseAuth Auth *RegisterResponseAuth
Expiry time.Time Expiry time.Time
Followup string Followup string
Hostinfo *Hostinfo Hostinfo *Hostinfo

View File

@ -585,7 +585,7 @@ func (s *Server) serveRegister(w http.ResponseWriter, r *http.Request, mkey key.
j, _ := json.MarshalIndent(req, "", "\t") j, _ := json.MarshalIndent(req, "", "\t")
log.Printf("Got %T: %s", req, j) log.Printf("Got %T: %s", req, j)
} }
if s.RequireAuthKey != "" && req.Auth.AuthKey != s.RequireAuthKey { if s.RequireAuthKey != "" && (req.Auth == nil || req.Auth.AuthKey != s.RequireAuthKey) {
res := must.Get(s.encode(false, tailcfg.RegisterResponse{ res := must.Get(s.encode(false, tailcfg.RegisterResponse{
Error: "invalid authkey", Error: "invalid authkey",
})) }))