diff --git a/client/tailscale/localclient.go b/client/tailscale/localclient.go index 93a9d1641..c25ee4653 100644 --- a/client/tailscale/localclient.go +++ b/client/tailscale/localclient.go @@ -862,7 +862,7 @@ func (lc *LocalClient) NetworkLockSign(ctx context.Context, nodeKey key.NodePubl // SetServeConfig sets or replaces the serving settings. // If config is nil, settings are cleared and serving is disabled. func (lc *LocalClient) SetServeConfig(ctx context.Context, config *ipn.ServeConfig) error { - b, err := json.Marshal(&config) + b, err := json.Marshal(config) if err != nil { return fmt.Errorf("encoding config: %w", err) } @@ -874,13 +874,18 @@ func (lc *LocalClient) SetServeConfig(ctx context.Context, config *ipn.ServeConf } // GetServeConfig return the current serve config. +// +// If the serve config is empty, it returns (nil, nil). func (lc *LocalClient) GetServeConfig(ctx context.Context) (*ipn.ServeConfig, error) { body, err := lc.send(ctx, "GET", "/localapi/v0/serve-config", 200, nil) if err != nil { return nil, fmt.Errorf("getting serve config: %w", err) } - sc := new(ipn.ServeConfig) - if err := json.Unmarshal(body, sc); err != nil { + return getServeConfigFromJSON(body) +} + +func getServeConfigFromJSON(body []byte) (sc *ipn.ServeConfig, err error) { + if err := json.Unmarshal(body, &sc); err != nil { return nil, err } return sc, nil diff --git a/client/tailscale/localclient_test.go b/client/tailscale/localclient_test.go new file mode 100644 index 000000000..9121b1acf --- /dev/null +++ b/client/tailscale/localclient_test.go @@ -0,0 +1,28 @@ +// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.19 + +package tailscale + +import "testing" + +func TestGetServeConfigFromJSON(t *testing.T) { + sc, err := getServeConfigFromJSON([]byte("null")) + if sc != nil { + t.Errorf("want nil for null") + } + if err != nil { + t.Errorf("reading null: %v", err) + } + + sc, err = getServeConfigFromJSON([]byte(`{"TCP":{}}`)) + if err != nil { + t.Errorf("reading object: %v", err) + } else if sc == nil { + t.Errorf("want non-nil for object") + } else if sc.TCP == nil { + t.Errorf("want non-nil TCP for object") + } +}