From 9ed3a061c303b10666073f91e76a898bf2de08fc Mon Sep 17 00:00:00 2001 From: James Tucker Date: Fri, 5 May 2023 10:53:10 -0700 Subject: [PATCH 01/12] net/netns: fix segv when no tailscale interface is found `interfaces.Tailscale()` returns all zero values when it finds no Tailscale interface and encounters no errors. The netns package was treating no error as a signal that it would receive a non-zero pointer value leading to nil pointer dereference. Observed in: ``` --- FAIL: TestGetInterfaceIndex (0.00s) --- FAIL: TestGetInterfaceIndex/IP_and_port (0.00s) panic: runtime error: invalid memory address or nil pointer dereference [recovered] panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x1029eb7d8] goroutine 7 [running]: testing.tRunner.func1.2({0x102a691e0, 0x102bc05c0}) /Users/raggi/.cache/tailscale-go/src/testing/testing.go:1526 +0x1c8 testing.tRunner.func1() /Users/raggi/.cache/tailscale-go/src/testing/testing.go:1529 +0x384 panic({0x102a691e0, 0x102bc05c0}) /Users/raggi/.cache/tailscale-go/src/runtime/panic.go:884 +0x204 tailscale.com/net/netns.getInterfaceIndex(0x14000073f28, 0x1028d0284?, {0x1029ef3b7, 0xa}) /Users/raggi/src/github.com/tailscale/tailscale/net/netns/netns_darwin.go:114 +0x228 tailscale.com/net/netns.TestGetInterfaceIndex.func2(0x14000138000) /Users/raggi/src/github.com/tailscale/tailscale/net/netns/netns_darwin_test.go:37 +0x54 testing.tRunner(0x14000138000, 0x140000551b0) /Users/raggi/.cache/tailscale-go/src/testing/testing.go:1576 +0x10c created by testing.(*T).Run /Users/raggi/.cache/tailscale-go/src/testing/testing.go:1629 +0x368 FAIL tailscale.com/net/netns 0.824s ``` Fixes #8064 Signed-off-by: James Tucker --- net/netns/netns_darwin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netns/netns_darwin.go b/net/netns/netns_darwin.go index 7315dff40..b32a744b7 100644 --- a/net/netns/netns_darwin.go +++ b/net/netns/netns_darwin.go @@ -111,7 +111,7 @@ func getInterfaceIndex(logf logger.Logf, netMon *netmon.Monitor, address string) // Verify that we didn't just choose the Tailscale interface; // if so, we fall back to binding from the default. _, tsif, err2 := interfaces.Tailscale() - if err2 == nil && tsif.Index == idx { + if err2 == nil && tsif != nil && tsif.Index == idx { logf("[unexpected] netns: interfaceIndexFor returned Tailscale interface") return defaultIdx() } From 8864112a0cf8434b67e993e9252bed7ebaae786e Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Fri, 5 May 2023 12:19:25 -0700 Subject: [PATCH 02/12] ipn/ipnlocal: bound how long cert fetchher checks for existing DNS records It was supposed to be best effort but in some cases (macsys at least, per @marwan-at-work) it hangs and exhausts the whole context.Context deadline so we fail to make the SetDNS call to the server. Updates #8067 Updates #3273 etc Change-Id: Ie1f04abe9689951484748aecdeae312afbafdb0f Signed-off-by: Brad Fitzpatrick --- ipn/ipnlocal/cert.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ipn/ipnlocal/cert.go b/ipn/ipnlocal/cert.go index cabcae1fb..ef19a6571 100644 --- a/ipn/ipnlocal/cert.go +++ b/ipn/ipnlocal/cert.go @@ -31,6 +31,7 @@ import ( "time" "golang.org/x/crypto/acme" + "golang.org/x/exp/slices" "tailscale.com/atomicfile" "tailscale.com/envknob" "tailscale.com/hostinfo" @@ -361,17 +362,16 @@ func (b *LocalBackend) getCertPEM(ctx context.Context, cs certStore, logf logger } key := "_acme-challenge." + domain + // Do a best-effort lookup to see if we've already created this DNS name + // in a previous attempt. Don't burn too much time on it, though. Worst + // case we ask the server to create something that already exists. var resolver net.Resolver - var ok bool - txts, _ := resolver.LookupTXT(ctx, key) - for _, txt := range txts { - if txt == rec { - ok = true - logf("TXT record already existed") - break - } - } - if !ok { + lookupCtx, lookupCancel := context.WithTimeout(ctx, 500*time.Millisecond) + txts, _ := resolver.LookupTXT(lookupCtx, key) + lookupCancel() + if slices.Contains(txts, rec) { + logf("TXT record already existed") + } else { logf("starting SetDNS call...") err = b.SetDNS(ctx, key, rec) if err != nil { From 8d3d48e000f1aea1e349ad3f3f209d29248024d7 Mon Sep 17 00:00:00 2001 From: Charlotte Brandhorst-Satzkorn Date: Thu, 4 May 2023 17:34:44 -0700 Subject: [PATCH 03/12] ipn/ipnlocal: add NodeKey func to return the public node NodeKey This change introduces a NodeKey func on localbackend that returns the public node key. Updates tailscale/corp#9967 Signed-off-by: Charlotte Brandhorst-Satzkorn --- ipn/ipnlocal/local.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 15202b0fd..8c8f342e1 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -3627,6 +3627,19 @@ func (b *LocalBackend) hasNodeKey() bool { return p.Valid() && p.Persist().Valid() && !p.Persist().PrivateNodeKey().IsZero() } +// NodeKey returns the public node key. +func (b *LocalBackend) NodeKey() key.NodePublic { + b.mu.Lock() + defer b.mu.Unlock() + + p := b.pm.CurrentPrefs() + if !p.Valid() || !p.Persist().Valid() || p.Persist().PrivateNodeKey().IsZero() { + return key.NodePublic{} + } + + return p.Persist().PublicNodeKey() +} + // nextState returns the state the backend seems to be in, based on // its internal state. func (b *LocalBackend) nextState() ipn.State { From 280432707439921bc4de56d55a63c4886cdb0cbf Mon Sep 17 00:00:00 2001 From: Charlotte Brandhorst-Satzkorn Date: Thu, 4 May 2023 18:08:11 -0700 Subject: [PATCH 04/12] tailcfg: update rename SSHFailureNotifyRequest and add EventType This change renames SSHFailureNotifyRequest to SSHEventNotifyRequest to better reflect the additional events we could add in the future. This change also adds an EventType used to catagories the events. Updates tailscale/corp#9967 Signed-off-by: Charlotte Brandhorst-Satzkorn --- tailcfg/tailcfg.go | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/tailcfg/tailcfg.go b/tailcfg/tailcfg.go index b77193f2b..6e4b20b38 100644 --- a/tailcfg/tailcfg.go +++ b/tailcfg/tailcfg.go @@ -2075,9 +2075,11 @@ type SSHRecorderFailureAction struct { NotifyURL string `json:",omitempty"` } -// SSHRecordingFailureNotifyRequest is the JSON payload sent to the NotifyURL -// when a recording fails. -type SSHRecordingFailureNotifyRequest struct { +// SSHEventNotifyRequest is the JSON payload sent to the NotifyURL +// for an SSH event. +type SSHEventNotifyRequest struct { + // EventType is the type of notify request being sent. + EventType SSHEventType // CapVersion is the client's current CapabilityVersion. CapVersion CapabilityVersion @@ -2093,10 +2095,19 @@ type SSHRecordingFailureNotifyRequest struct { // LocalUser is the user that was resolved from the SSHUser for the local machine. LocalUser string - // Attempts is the list of recorders that were attempted, in order. - Attempts []SSHRecordingAttempt + // RecordingAttempts is the list of recorders that were attempted, in order. + RecordingAttempts []*SSHRecordingAttempt } +// SSHEventType defines the event type linked to a SSH action or state. +type SSHEventType int + +const ( + UnspecifiedSSHEventType SSHEventType = 0 + SSHSessionRecordingRejected SSHEventType = 1 + SSHSessionRecordingTerminated SSHEventType = 2 +) + // SSHRecordingAttempt is a single attempt to start a recording. type SSHRecordingAttempt struct { // Recorder is the address of the recorder that was attempted. From 68307c1411381809ac28c5677a0ddef90d556480 Mon Sep 17 00:00:00 2001 From: Charlotte Brandhorst-Satzkorn Date: Thu, 4 May 2023 19:49:32 -0700 Subject: [PATCH 05/12] ssh/tailssh: send ssh event notifications on recording failures This change sends an SSHEventNotificationRequest over noise when a SSH session is set to fail closed and the session is unable to start because a recorder is not available or a session is terminated because connection to the recorder is ended. Each of these scenarios have their own event type. Updates tailscale/corp#9967 Signed-off-by: Charlotte Brandhorst-Satzkorn --- ssh/tailssh/tailssh.go | 96 +++++++++++++++++++++++++++++++++---- ssh/tailssh/tailssh_test.go | 5 ++ 2 files changed, 91 insertions(+), 10 deletions(-) diff --git a/ssh/tailssh/tailssh.go b/ssh/tailssh/tailssh.go index 27437901c..623a8695a 100644 --- a/ssh/tailssh/tailssh.go +++ b/ssh/tailssh/tailssh.go @@ -39,6 +39,7 @@ import ( "tailscale.com/net/tsdial" "tailscale.com/tailcfg" "tailscale.com/tempfork/gliderlabs/ssh" + "tailscale.com/types/key" "tailscale.com/types/logger" "tailscale.com/types/netmap" "tailscale.com/util/clientmetric" @@ -68,6 +69,7 @@ type ipnLocalBackend interface { DoNoiseRequest(req *http.Request) (*http.Response, error) Dialer() *tsdial.Dialer TailscaleVarRoot() string + NodeKey() key.NodePublic } type server struct { @@ -105,6 +107,7 @@ func init() { logf: logf, tailscaledPath: tsd, } + return srv, nil }) } @@ -1445,11 +1448,17 @@ func (ss *sshSession) sessionRecordingClient(dialCtx context.Context) (*http.Cli // On success, it returns a WriteCloser that can be used to upload the // recording, and a channel that will be sent an error (or nil) when the upload // fails or completes. -func (ss *sshSession) connectToRecorder(ctx context.Context, recs []netip.AddrPort) (io.WriteCloser, <-chan error, error) { +// +// In both cases, a slice of SSHRecordingAttempts is returned which detail the +// attempted recorder IP and the error message, if the attempt failed. The +// attempts are in order the recorder(s) was attempted. If successful a +// successful connection is made, the last attempt in the slice is the +// attempt for connected recorder. +func (ss *sshSession) connectToRecorder(ctx context.Context, recs []netip.AddrPort) (io.WriteCloser, []*tailcfg.SSHRecordingAttempt, <-chan error, error) { if len(recs) == 0 { - return nil, nil, errors.New("no recorders configured") + return nil, nil, nil, errors.New("no recorders configured") } - + var attempts []*tailcfg.SSHRecordingAttempt // We use a special context for dialing the recorder, so that we can // limit the time we spend dialing to 30 seconds and still have an // unbounded context for the upload. @@ -1457,10 +1466,18 @@ func (ss *sshSession) connectToRecorder(ctx context.Context, recs []netip.AddrPo defer dialCancel() hc, err := ss.sessionRecordingClient(dialCtx) if err != nil { - return nil, nil, err + attempts = append(attempts, &tailcfg.SSHRecordingAttempt{ + FailureMessage: err.Error(), + }) + return nil, attempts, nil, err } var errs []error for _, ap := range recs { + attempt := &tailcfg.SSHRecordingAttempt{ + Recorder: ap, + } + attempts = append(attempts, attempt) + // We dial the recorder and wait for it to send a 100-continue // response before returning from this function. This ensures that // the recorder is ready to accept the recording. @@ -1476,7 +1493,9 @@ func (ss *sshSession) connectToRecorder(ctx context.Context, recs []netip.AddrPo pr, pw := io.Pipe() req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("http://%s:%d/record", ap.Addr(), ap.Port()), pr) if err != nil { - errs = append(errs, fmt.Errorf("recording: error starting recording: %w", err)) + err = fmt.Errorf("recording: error starting recording: %w", err) + attempt.FailureMessage = err.Error() + errs = append(errs, err) continue } // We set the Expect header to 100-continue, so that the recorder @@ -1508,12 +1527,13 @@ func (ss *sshSession) connectToRecorder(ctx context.Context, recs []netip.AddrPo // is unexpected as we haven't sent any data yet. err = errors.New("recording: unexpected EOF") } + attempt.FailureMessage = err.Error() errs = append(errs, err) continue } - return pw, errChan, nil + return pw, attempts, errChan, nil } - return nil, nil, multierr.New(errs...) + return nil, attempts, nil, multierr.New(errs...) } func (ss *sshSession) openFileForRecording(now time.Time) (_ io.WriteCloser, err error) { @@ -1535,6 +1555,15 @@ func (ss *sshSession) openFileForRecording(now time.Time) (_ io.WriteCloser, err // startNewRecording starts a new SSH session recording. // It may return a nil recording if recording is not available. func (ss *sshSession) startNewRecording() (_ *recording, err error) { + // We store the node key as soon as possible when creating + // a new recording incase of FUS. + var nodeKey key.NodePublic + if nk := ss.conn.srv.lb.NodeKey(); nk.IsZero() { + return nil, errors.New("ssh server is unavailable: no node key") + } else { + nodeKey = nk + } + recorders, onFailure := ss.recorders() var localRecording bool if len(recorders) == 0 { @@ -1573,9 +1602,13 @@ func (ss *sshSession) startNewRecording() (_ *recording, err error) { } } else { var errChan <-chan error - rec.out, errChan, err = ss.connectToRecorder(ctx, recorders) + var attempts []*tailcfg.SSHRecordingAttempt + rec.out, attempts, errChan, err = ss.connectToRecorder(ctx, recorders) if err != nil { - // TODO(catzkorn): notify control here. + if onFailure != nil && onFailure.NotifyURL != "" && len(attempts) > 0 { + ss.notifyControl(ctx, nodeKey, tailcfg.SSHSessionRecordingRejected, attempts, onFailure.NotifyURL) + } + if onFailure != nil && onFailure.RejectSessionWithMessage != "" { ss.logf("recording: error starting recording (rejecting session): %v", err) return nil, userVisibleError{ @@ -1592,7 +1625,12 @@ func (ss *sshSession) startNewRecording() (_ *recording, err error) { // Success. return } - // TODO(catzkorn): notify control here. + if onFailure != nil && onFailure.NotifyURL != "" && len(attempts) > 0 { + lastAttempt := attempts[len(attempts)-1] + lastAttempt.FailureMessage = err.Error() + + ss.notifyControl(ctx, nodeKey, tailcfg.SSHSessionRecordingTerminated, attempts, onFailure.NotifyURL) + } if onFailure != nil && onFailure.TerminateSessionWithMessage != "" { ss.logf("recording: error uploading recording (closing session): %v", err) ss.cancelCtx(userVisibleError{ @@ -1650,6 +1688,44 @@ func (ss *sshSession) startNewRecording() (_ *recording, err error) { return rec, nil } +// notifyControl sends a SSHEventNotifyRequest to control over noise. +// A SSHEventNotifyRequest is sent when an action or state reached during +// an SSH session is a defined EventType. +func (ss *sshSession) notifyControl(ctx context.Context, nodeKey key.NodePublic, notifyType tailcfg.SSHEventType, attempts []*tailcfg.SSHRecordingAttempt, url string) { + re := tailcfg.SSHEventNotifyRequest{ + EventType: notifyType, + CapVersion: tailcfg.CurrentCapabilityVersion, + NodeKey: nodeKey, + SrcNode: ss.conn.info.node.ID, + SSHUser: ss.conn.info.sshUser, + LocalUser: ss.conn.localUser.Username, + RecordingAttempts: attempts, + } + + body, err := json.Marshal(re) + if err != nil { + ss.logf("notifyControl: unable to marshal SSHNotifyRequest:", err) + return + } + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body)) + if err != nil { + ss.logf("notifyControl: unable to create request:", err) + return + } + + resp, err := ss.conn.srv.lb.DoNoiseRequest(req) + if err != nil { + ss.logf("notifyControl: unable to send noise request:", err) + return + } + + if resp.StatusCode != http.StatusCreated { + ss.logf("notifyControl: noise request returned status code %v", resp.StatusCode) + return + } +} + // recording is the state for an SSH session recording. type recording struct { ss *sshSession diff --git a/ssh/tailssh/tailssh_test.go b/ssh/tailssh/tailssh_test.go index 607b4eeaa..5eb1a3f62 100644 --- a/ssh/tailssh/tailssh_test.go +++ b/ssh/tailssh/tailssh_test.go @@ -40,6 +40,7 @@ import ( "tailscale.com/tempfork/gliderlabs/ssh" "tailscale.com/tsd" "tailscale.com/tstest" + "tailscale.com/types/key" "tailscale.com/types/logger" "tailscale.com/types/logid" "tailscale.com/types/netmap" @@ -313,6 +314,10 @@ func (ts *localState) TailscaleVarRoot() string { return "" } +func (ts *localState) NodeKey() key.NodePublic { + return key.NewNode().Public() +} + func newSSHRule(action *tailcfg.SSHAction) *tailcfg.SSHRule { return &tailcfg.SSHRule{ SSHUsers: map[string]string{ From 29ded8f9f986645f8add236821c48c0a0479dccf Mon Sep 17 00:00:00 2001 From: Charlotte Brandhorst-Satzkorn Date: Fri, 5 May 2023 11:03:15 -0700 Subject: [PATCH 06/12] ssh/tailssh,tailcfg: add connID to ssheventnotifyrequest and castheader This change adds a ConnectionID field to both SSHEventNotifyRequest and CastHeader that identifies the ID of a connection to the SSH server. Updates tailscale/corp#9967 Signed-off-by: Charlotte Brandhorst-Satzkorn --- ssh/tailssh/tailssh.go | 29 ++++++++++++++++------------- tailcfg/tailcfg.go | 6 ++++++ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/ssh/tailssh/tailssh.go b/ssh/tailssh/tailssh.go index 623a8695a..63e14b86d 100644 --- a/ssh/tailssh/tailssh.go +++ b/ssh/tailssh/tailssh.go @@ -1410,6 +1410,11 @@ type CastHeader struct { // LocalUser is the effective username on the server. LocalUser string `json:"localUser"` + + // ConnectionID uniquely identifies a connection made to the SSH server. + // It may be shared across multiple sessions over the same connection in + // case of SSH multiplexing. + ConnectionID string `json:"connectionID"` } // sessionRecordingClient returns an http.Client that uses srv.lb.Dialer() to @@ -1458,7 +1463,6 @@ func (ss *sshSession) connectToRecorder(ctx context.Context, recs []netip.AddrPo if len(recs) == 0 { return nil, nil, nil, errors.New("no recorders configured") } - var attempts []*tailcfg.SSHRecordingAttempt // We use a special context for dialing the recorder, so that we can // limit the time we spend dialing to 30 seconds and still have an // unbounded context for the upload. @@ -1466,12 +1470,11 @@ func (ss *sshSession) connectToRecorder(ctx context.Context, recs []netip.AddrPo defer dialCancel() hc, err := ss.sessionRecordingClient(dialCtx) if err != nil { - attempts = append(attempts, &tailcfg.SSHRecordingAttempt{ - FailureMessage: err.Error(), - }) - return nil, attempts, nil, err + return nil, nil, nil, err } + var errs []error + var attempts []*tailcfg.SSHRecordingAttempt for _, ap := range recs { attempt := &tailcfg.SSHRecordingAttempt{ Recorder: ap, @@ -1557,11 +1560,9 @@ func (ss *sshSession) openFileForRecording(now time.Time) (_ io.WriteCloser, err func (ss *sshSession) startNewRecording() (_ *recording, err error) { // We store the node key as soon as possible when creating // a new recording incase of FUS. - var nodeKey key.NodePublic - if nk := ss.conn.srv.lb.NodeKey(); nk.IsZero() { + nodeKey := ss.conn.srv.lb.NodeKey() + if nodeKey.IsZero() { return nil, errors.New("ssh server is unavailable: no node key") - } else { - nodeKey = nk } recorders, onFailure := ss.recorders() @@ -1660,10 +1661,11 @@ func (ss *sshSession) startNewRecording() (_ *recording, err error) { // it. Then we can (1) make the cmd, (2) start the // recording, (3) start the process. }, - SSHUser: ss.conn.info.sshUser, - LocalUser: ss.conn.localUser.Username, - SrcNode: strings.TrimSuffix(ss.conn.info.node.Name, "."), - SrcNodeID: ss.conn.info.node.StableID, + SSHUser: ss.conn.info.sshUser, + LocalUser: ss.conn.localUser.Username, + SrcNode: strings.TrimSuffix(ss.conn.info.node.Name, "."), + SrcNodeID: ss.conn.info.node.StableID, + ConnectionID: ss.conn.connID, } if !ss.conn.info.node.IsTagged() { ch.SrcNodeUser = ss.conn.info.uprof.LoginName @@ -1694,6 +1696,7 @@ func (ss *sshSession) startNewRecording() (_ *recording, err error) { func (ss *sshSession) notifyControl(ctx context.Context, nodeKey key.NodePublic, notifyType tailcfg.SSHEventType, attempts []*tailcfg.SSHRecordingAttempt, url string) { re := tailcfg.SSHEventNotifyRequest{ EventType: notifyType, + ConnectionID: ss.conn.connID, CapVersion: tailcfg.CurrentCapabilityVersion, NodeKey: nodeKey, SrcNode: ss.conn.info.node.ID, diff --git a/tailcfg/tailcfg.go b/tailcfg/tailcfg.go index 6e4b20b38..d2df24fc0 100644 --- a/tailcfg/tailcfg.go +++ b/tailcfg/tailcfg.go @@ -2080,6 +2080,12 @@ type SSHRecorderFailureAction struct { type SSHEventNotifyRequest struct { // EventType is the type of notify request being sent. EventType SSHEventType + + // ConnectionID uniquely identifies a connection made to the SSH server. + // It may be shared across multiple sessions over the same connection in + // case a single connection creates multiple sessions. + ConnectionID string + // CapVersion is the client's current CapabilityVersion. CapVersion CapabilityVersion From 024d48d9c1d81e6c4a9225aef1a436be823e5ee9 Mon Sep 17 00:00:00 2001 From: Charlotte Brandhorst-Satzkorn Date: Fri, 5 May 2023 14:06:23 -0700 Subject: [PATCH 07/12] tailcfg: bump capability version This change bumps the capability version to 62, after support for sending SSHEventNotificationRequests to control via noise for failure events was introduced. Updates tailscale/corp#9967 Signed-off-by: Charlotte Brandhorst-Satzkorn --- tailcfg/tailcfg.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tailcfg/tailcfg.go b/tailcfg/tailcfg.go index d2df24fc0..d9a38eda0 100644 --- a/tailcfg/tailcfg.go +++ b/tailcfg/tailcfg.go @@ -98,7 +98,8 @@ type CapabilityVersion int // - 59: 2023-03-16: Client understands Peers[].SelfNodeV4MasqAddrForThisPeer // - 60: 2023-04-06: Client understands IsWireGuardOnly // - 61: 2023-04-18: Client understand SSHAction.SSHRecorderFailureAction -const CurrentCapabilityVersion CapabilityVersion = 61 +// - 62: 2023-05-05: Client can notify control over noise for SSHEventNotificationRequest recording failure events +const CurrentCapabilityVersion CapabilityVersion = 62 type StableID string From 5c38f0979e5f6c599d665b4c0b53e0d09799e81b Mon Sep 17 00:00:00 2001 From: James Tucker Date: Fri, 5 May 2023 11:37:24 -0700 Subject: [PATCH 08/12] tsweb/promvarz: fix repeated expvar definition in test expvar can only be defined once, so running tests with a repeat counter will fail if the variables are defined inside of the test function. Observed failure: ``` --- FAIL: TestHandler (0.00s) panic: Reuse of exported var name: gauge_promvarz_test_expvar [recovered] panic: Reuse of exported var name: gauge_promvarz_test_expvar goroutine 9 [running]: testing.tRunner.func1.2({0x100f267e0, 0x1400026e770}) /usr/local/go/src/testing/testing.go:1526 +0x1c8 testing.tRunner.func1() /usr/local/go/src/testing/testing.go:1529 +0x364 panic({0x100f267e0, 0x1400026e770}) /usr/local/go/src/runtime/panic.go:884 +0x1f4 log.Panicln({0x140000b8e20?, 0x1a?, 0x1400026e750?}) /usr/local/go/src/log/log.go:398 +0x60 expvar.Publish({0x100e2b21d, 0x1a}, {0x100fd7a08?, 0x140000232c0}) /usr/local/go/src/expvar/expvar.go:284 +0xc0 expvar.NewInt(...) /usr/local/go/src/expvar/expvar.go:304 tailscale.com/tsweb/promvarz.TestHandler(0x14000082b60) /Users/charlotte/ts-src/tailscale/tsweb/promvarz/promvarz_test.go:18 +0x5c testing.tRunner(0x14000082b60, 0x100fd5858) /usr/local/go/src/testing/testing.go:1576 +0x104 created by testing.(*T).Run /usr/local/go/src/testing/testing.go:1629 +0x370 FAIL tailscale.com/tsweb/promvarz 0.149s ``` Fixes #8065 Signed-off-by: James Tucker --- tsweb/promvarz/promvarz_test.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tsweb/promvarz/promvarz_test.go b/tsweb/promvarz/promvarz_test.go index 28c906c57..a3f4e66f1 100644 --- a/tsweb/promvarz/promvarz_test.go +++ b/tsweb/promvarz/promvarz_test.go @@ -14,11 +14,14 @@ import ( "github.com/prometheus/client_golang/prometheus/testutil" ) +var ( + testVar1 = expvar.NewInt("gauge_promvarz_test_expvar") + testVar2 = promauto.NewGauge(prometheus.GaugeOpts{Name: "promvarz_test_native"}) +) + func TestHandler(t *testing.T) { - test1 := expvar.NewInt("gauge_promvarz_test_expvar") - test1.Set(42) - test2 := promauto.NewGauge(prometheus.GaugeOpts{Name: "promvarz_test_native"}) - test2.Set(4242) + testVar1.Set(42) + testVar2.Set(4242) svr := httptest.NewServer(http.HandlerFunc(Handler)) defer svr.Close() From b9fb8ac70244f6b391118a9b180699e65533e7b0 Mon Sep 17 00:00:00 2001 From: Chenyang Gao Date: Sat, 6 May 2023 14:04:37 +0800 Subject: [PATCH 09/12] fix sys.Set(router) issue will crash the daemon in some OSs Signed-off-by: Chenyang Gao in commit 6e96744, the tsd system type has been added. Which will cause the daemon will crash on some OSs (Windows, darwin and so on). The root cause is that on those OSs, handleSubnetsInNetstack() will return true and set the conf.Router with a wrapper. Later in NewUserspaceEngine() it will do subsystem set and found that early set router mismatch to current value, then panic. --- cmd/tailscaled/tailscaled.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/tailscaled/tailscaled.go b/cmd/tailscaled/tailscaled.go index 0d46cdb0f..95193f1e7 100644 --- a/cmd/tailscaled/tailscaled.go +++ b/cmd/tailscaled/tailscaled.go @@ -649,7 +649,6 @@ func tryEngine(logf logger.Logf, sys *tsd.System, name string) (onlyNetstack boo dev.Close() return false, fmt.Errorf("creating router: %w", err) } - sys.Set(r) d, err := dns.NewOSConfigurator(logf, devName) if err != nil { @@ -663,6 +662,7 @@ func tryEngine(logf logger.Logf, sys *tsd.System, name string) (onlyNetstack boo conf.Router = netstack.NewSubnetRouterWrapper(conf.Router) netstackSubnetRouter = true } + sys.Set(conf.Router) } e, err := wgengine.NewUserspaceEngine(logf, conf) if err != nil { From 4d730e154c19f54faac23a6f050efd19af06e43b Mon Sep 17 00:00:00 2001 From: License Updater Date: Sat, 6 May 2023 21:42:20 +0000 Subject: [PATCH 10/12] licenses: update android licenses Signed-off-by: License Updater --- licenses/android.md | 82 +++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/licenses/android.md b/licenses/android.md index 87d88b08d..c1cfc84ac 100644 --- a/licenses/android.md +++ b/licenses/android.md @@ -9,22 +9,23 @@ Client][]. See also the dependencies in the [Tailscale CLI][]. - [eliasnaur.com/font/roboto](https://pkg.go.dev/eliasnaur.com/font/roboto) ([BSD-3-Clause](https://git.sr.ht/~eliasnaur/font/tree/832bb8fc08c3/LICENSE)) - - [filippo.io/edwards25519](https://pkg.go.dev/filippo.io/edwards25519) ([BSD-3-Clause](https://github.com/FiloSottile/edwards25519/blob/v1.0.0-rc.1/LICENSE)) + - [filippo.io/edwards25519](https://pkg.go.dev/filippo.io/edwards25519) ([BSD-3-Clause](https://github.com/FiloSottile/edwards25519/blob/v1.0.0/LICENSE)) - [gioui.org](https://pkg.go.dev/gioui.org) ([MIT](https://git.sr.ht/~eliasnaur/gio/tree/32c6a9b10d0b/LICENSE)) - [gioui.org/cpu](https://pkg.go.dev/gioui.org/cpu) ([MIT](https://git.sr.ht/~eliasnaur/gio-cpu/tree/8d6a761490d2/LICENSE)) - [gioui.org/shader](https://pkg.go.dev/gioui.org/shader) ([MIT](https://git.sr.ht/~eliasnaur/gio-shader/tree/v1.0.6/LICENSE)) - - [github.com/aws/aws-sdk-go-v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/v1.17.3/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/config](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/config/v1.11.0/config/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/credentials](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/credentials/v1.6.4/credentials/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/feature/ec2/imds](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/ec2/imds) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/feature/ec2/imds/v1.8.2/feature/ec2/imds/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/internal/configsources](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/configsources) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/internal/configsources/v1.1.27/internal/configsources/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/internal/endpoints/v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/internal/endpoints/v2.4.21/internal/endpoints/v2/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/internal/ini](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/ini) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/internal/ini/v1.3.2/internal/ini/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/internal/sync/singleflight](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight) ([BSD-3-Clause](https://github.com/aws/aws-sdk-go-v2/blob/v1.17.3/internal/sync/singleflight/LICENSE)) - - [github.com/aws/aws-sdk-go-v2/service/internal/presigned-url](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/internal/presigned-url/v1.5.2/service/internal/presigned-url/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/service/ssm](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/ssm) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/ssm/v1.35.0/service/ssm/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/service/sso](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/sso) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/sso/v1.6.2/service/sso/LICENSE.txt)) - - [github.com/aws/aws-sdk-go-v2/service/sts](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/sts) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/sts/v1.11.1/service/sts/LICENSE.txt)) + - [github.com/aws/aws-sdk-go-v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/v1.18.0/LICENSE.txt)) + - [github.com/aws/aws-sdk-go-v2/config](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/config/v1.18.22/config/LICENSE.txt)) + - [github.com/aws/aws-sdk-go-v2/credentials](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/credentials) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/credentials/v1.13.21/credentials/LICENSE.txt)) + - [github.com/aws/aws-sdk-go-v2/feature/ec2/imds](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/feature/ec2/imds) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/feature/ec2/imds/v1.13.3/feature/ec2/imds/LICENSE.txt)) + - [github.com/aws/aws-sdk-go-v2/internal/configsources](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/configsources) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/internal/configsources/v1.1.33/internal/configsources/LICENSE.txt)) + - [github.com/aws/aws-sdk-go-v2/internal/endpoints/v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/internal/endpoints/v2.4.27/internal/endpoints/v2/LICENSE.txt)) + - [github.com/aws/aws-sdk-go-v2/internal/ini](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/ini) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/internal/ini/v1.3.34/internal/ini/LICENSE.txt)) + - [github.com/aws/aws-sdk-go-v2/internal/sync/singleflight](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight) ([BSD-3-Clause](https://github.com/aws/aws-sdk-go-v2/blob/v1.18.0/internal/sync/singleflight/LICENSE)) + - [github.com/aws/aws-sdk-go-v2/service/internal/presigned-url](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/internal/presigned-url/v1.9.27/service/internal/presigned-url/LICENSE.txt)) + - [github.com/aws/aws-sdk-go-v2/service/ssm](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/ssm) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/ssm/v1.36.3/service/ssm/LICENSE.txt)) + - [github.com/aws/aws-sdk-go-v2/service/sso](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/sso) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/sso/v1.12.9/service/sso/LICENSE.txt)) + - [github.com/aws/aws-sdk-go-v2/service/ssooidc](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/ssooidc) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/ssooidc/v1.14.9/service/ssooidc/LICENSE.txt)) + - [github.com/aws/aws-sdk-go-v2/service/sts](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/sts) ([Apache-2.0](https://github.com/aws/aws-sdk-go-v2/blob/service/sts/v1.18.10/service/sts/LICENSE.txt)) - [github.com/aws/smithy-go](https://pkg.go.dev/github.com/aws/smithy-go) ([Apache-2.0](https://github.com/aws/smithy-go/blob/v1.13.5/LICENSE)) - [github.com/aws/smithy-go/internal/sync/singleflight](https://pkg.go.dev/github.com/aws/smithy-go/internal/sync/singleflight) ([BSD-3-Clause](https://github.com/aws/smithy-go/blob/v1.13.5/internal/sync/singleflight/LICENSE)) - [github.com/benoitkugler/textlayout](https://pkg.go.dev/github.com/benoitkugler/textlayout) ([MIT](https://github.com/benoitkugler/textlayout/blob/v0.3.0/LICENSE)) @@ -34,50 +35,51 @@ Client][]. See also the dependencies in the [Tailscale CLI][]. - [github.com/coreos/go-iptables/iptables](https://pkg.go.dev/github.com/coreos/go-iptables/iptables) ([Apache-2.0](https://github.com/coreos/go-iptables/blob/v0.6.0/LICENSE)) - [github.com/fxamacker/cbor/v2](https://pkg.go.dev/github.com/fxamacker/cbor/v2) ([MIT](https://github.com/fxamacker/cbor/blob/v2.4.0/LICENSE)) - [github.com/go-text/typesetting](https://pkg.go.dev/github.com/go-text/typesetting) ([BSD-3-Clause](https://github.com/go-text/typesetting/blob/0399769901d5/LICENSE)) - - [github.com/godbus/dbus/v5](https://pkg.go.dev/github.com/godbus/dbus/v5) ([BSD-2-Clause](https://github.com/godbus/dbus/blob/v5.0.6/LICENSE)) + - [github.com/godbus/dbus/v5](https://pkg.go.dev/github.com/godbus/dbus/v5) ([BSD-2-Clause](https://github.com/godbus/dbus/blob/v5.1.0/LICENSE)) - [github.com/golang/groupcache/lru](https://pkg.go.dev/github.com/golang/groupcache/lru) ([Apache-2.0](https://github.com/golang/groupcache/blob/41bb18bfe9da/LICENSE)) - - [github.com/google/btree](https://pkg.go.dev/github.com/google/btree) ([Apache-2.0](https://github.com/google/btree/blob/v1.0.1/LICENSE)) - - [github.com/hdevalence/ed25519consensus](https://pkg.go.dev/github.com/hdevalence/ed25519consensus) ([BSD-3-Clause](https://github.com/hdevalence/ed25519consensus/blob/c00d1f31bab3/LICENSE)) + - [github.com/google/btree](https://pkg.go.dev/github.com/google/btree) ([Apache-2.0](https://github.com/google/btree/blob/v1.1.2/LICENSE)) + - [github.com/hdevalence/ed25519consensus](https://pkg.go.dev/github.com/hdevalence/ed25519consensus) ([BSD-3-Clause](https://github.com/hdevalence/ed25519consensus/blob/v0.1.0/LICENSE)) - [github.com/illarion/gonotify](https://pkg.go.dev/github.com/illarion/gonotify) ([MIT](https://github.com/illarion/gonotify/blob/v1.0.1/LICENSE)) - - [github.com/insomniacslk/dhcp](https://pkg.go.dev/github.com/insomniacslk/dhcp) ([BSD-3-Clause](https://github.com/insomniacslk/dhcp/blob/de60144f33f8/LICENSE)) + - [github.com/insomniacslk/dhcp](https://pkg.go.dev/github.com/insomniacslk/dhcp) ([BSD-3-Clause](https://github.com/insomniacslk/dhcp/blob/974c6f05fe16/LICENSE)) - [github.com/jmespath/go-jmespath](https://pkg.go.dev/github.com/jmespath/go-jmespath) ([Apache-2.0](https://github.com/jmespath/go-jmespath/blob/v0.4.0/LICENSE)) - [github.com/josharian/native](https://pkg.go.dev/github.com/josharian/native) ([MIT](https://github.com/josharian/native/blob/5c7d0dd6ab86/license)) - - [github.com/jsimonetti/rtnetlink](https://pkg.go.dev/github.com/jsimonetti/rtnetlink) ([MIT](https://github.com/jsimonetti/rtnetlink/blob/d380b505068b/LICENSE.md)) - - [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([Apache-2.0](https://github.com/klauspost/compress/blob/v1.15.4/LICENSE)) - - [github.com/klauspost/compress/internal/snapref](https://pkg.go.dev/github.com/klauspost/compress/internal/snapref) ([BSD-3-Clause](https://github.com/klauspost/compress/blob/v1.15.4/internal/snapref/LICENSE)) - - [github.com/klauspost/compress/zstd/internal/xxhash](https://pkg.go.dev/github.com/klauspost/compress/zstd/internal/xxhash) ([MIT](https://github.com/klauspost/compress/blob/v1.15.4/zstd/internal/xxhash/LICENSE.txt)) + - [github.com/jsimonetti/rtnetlink](https://pkg.go.dev/github.com/jsimonetti/rtnetlink) ([MIT](https://github.com/jsimonetti/rtnetlink/blob/v1.3.2/LICENSE.md)) + - [github.com/klauspost/compress](https://pkg.go.dev/github.com/klauspost/compress) ([Apache-2.0](https://github.com/klauspost/compress/blob/v1.16.5/LICENSE)) + - [github.com/klauspost/compress/internal/snapref](https://pkg.go.dev/github.com/klauspost/compress/internal/snapref) ([BSD-3-Clause](https://github.com/klauspost/compress/blob/v1.16.5/internal/snapref/LICENSE)) + - [github.com/klauspost/compress/zstd/internal/xxhash](https://pkg.go.dev/github.com/klauspost/compress/zstd/internal/xxhash) ([MIT](https://github.com/klauspost/compress/blob/v1.16.5/zstd/internal/xxhash/LICENSE.txt)) - [github.com/kortschak/wol](https://pkg.go.dev/github.com/kortschak/wol) ([BSD-3-Clause](https://github.com/kortschak/wol/blob/da482cc4850a/LICENSE)) - - [github.com/mdlayher/genetlink](https://pkg.go.dev/github.com/mdlayher/genetlink) ([MIT](https://github.com/mdlayher/genetlink/blob/v1.2.0/LICENSE.md)) - - [github.com/mdlayher/netlink](https://pkg.go.dev/github.com/mdlayher/netlink) ([MIT](https://github.com/mdlayher/netlink/blob/v1.7.1/LICENSE.md)) + - [github.com/mdlayher/genetlink](https://pkg.go.dev/github.com/mdlayher/genetlink) ([MIT](https://github.com/mdlayher/genetlink/blob/v1.3.2/LICENSE.md)) + - [github.com/mdlayher/netlink](https://pkg.go.dev/github.com/mdlayher/netlink) ([MIT](https://github.com/mdlayher/netlink/blob/v1.7.2/LICENSE.md)) - [github.com/mdlayher/sdnotify](https://pkg.go.dev/github.com/mdlayher/sdnotify) ([MIT](https://github.com/mdlayher/sdnotify/blob/v1.0.0/LICENSE.md)) - - [github.com/mdlayher/socket](https://pkg.go.dev/github.com/mdlayher/socket) ([MIT](https://github.com/mdlayher/socket/blob/v0.4.0/LICENSE.md)) + - [github.com/mdlayher/socket](https://pkg.go.dev/github.com/mdlayher/socket) ([MIT](https://github.com/mdlayher/socket/blob/v0.4.1/LICENSE.md)) - [github.com/mitchellh/go-ps](https://pkg.go.dev/github.com/mitchellh/go-ps) ([MIT](https://github.com/mitchellh/go-ps/blob/v1.0.0/LICENSE.md)) + - [github.com/pierrec/lz4/v4](https://pkg.go.dev/github.com/pierrec/lz4/v4) ([BSD-3-Clause](https://github.com/pierrec/lz4/blob/v4.1.17/LICENSE)) - [github.com/skip2/go-qrcode](https://pkg.go.dev/github.com/skip2/go-qrcode) ([MIT](https://github.com/skip2/go-qrcode/blob/da1b6568686e/LICENSE)) - - [github.com/tailscale/golang-x-crypto](https://pkg.go.dev/github.com/tailscale/golang-x-crypto) ([BSD-3-Clause](https://github.com/tailscale/golang-x-crypto/blob/bc99ab8c2d17/LICENSE)) + - [github.com/tailscale/golang-x-crypto](https://pkg.go.dev/github.com/tailscale/golang-x-crypto) ([BSD-3-Clause](https://github.com/tailscale/golang-x-crypto/blob/17a3db2c30d2/LICENSE)) - [github.com/tailscale/goupnp](https://pkg.go.dev/github.com/tailscale/goupnp) ([BSD-2-Clause](https://github.com/tailscale/goupnp/blob/c64d0f06ea05/LICENSE)) - [github.com/tailscale/netlink](https://pkg.go.dev/github.com/tailscale/netlink) ([Apache-2.0](https://github.com/tailscale/netlink/blob/cabfb018fe85/LICENSE)) - [github.com/tailscale/tailscale-android](https://pkg.go.dev/github.com/tailscale/tailscale-android) ([BSD-3-Clause](https://github.com/tailscale/tailscale-android/blob/HEAD/LICENSE)) - [github.com/tailscale/wireguard-go](https://pkg.go.dev/github.com/tailscale/wireguard-go) ([MIT](https://github.com/tailscale/wireguard-go/blob/af172621b4dd/LICENSE)) - [github.com/tcnksm/go-httpstat](https://pkg.go.dev/github.com/tcnksm/go-httpstat) ([MIT](https://github.com/tcnksm/go-httpstat/blob/v0.2.0/LICENSE)) - - [github.com/u-root/uio](https://pkg.go.dev/github.com/u-root/uio) ([BSD-3-Clause](https://github.com/u-root/uio/blob/c3537552635f/LICENSE)) - - [github.com/vishvananda/netlink/nl](https://pkg.go.dev/github.com/vishvananda/netlink/nl) ([Apache-2.0](https://github.com/vishvananda/netlink/blob/650dca95af54/LICENSE)) - - [github.com/vishvananda/netns](https://pkg.go.dev/github.com/vishvananda/netns) ([Apache-2.0](https://github.com/vishvananda/netns/blob/50045581ed74/LICENSE)) + - [github.com/u-root/uio](https://pkg.go.dev/github.com/u-root/uio) ([BSD-3-Clause](https://github.com/u-root/uio/blob/3e8cd9d6bf63/LICENSE)) + - [github.com/vishvananda/netlink/nl](https://pkg.go.dev/github.com/vishvananda/netlink/nl) ([Apache-2.0](https://github.com/vishvananda/netlink/blob/v1.2.1-beta.2/LICENSE)) + - [github.com/vishvananda/netns](https://pkg.go.dev/github.com/vishvananda/netns) ([Apache-2.0](https://github.com/vishvananda/netns/blob/v0.0.4/LICENSE)) - [github.com/x448/float16](https://pkg.go.dev/github.com/x448/float16) ([MIT](https://github.com/x448/float16/blob/v0.8.4/LICENSE)) - [go4.org/intern](https://pkg.go.dev/go4.org/intern) ([BSD-3-Clause](https://github.com/go4org/intern/blob/ae77deb06f29/LICENSE)) - - [go4.org/mem](https://pkg.go.dev/go4.org/mem) ([Apache-2.0](https://github.com/go4org/mem/blob/927187094b94/LICENSE)) - - [go4.org/netipx](https://pkg.go.dev/go4.org/netipx) ([BSD-3-Clause](https://github.com/go4org/netipx/blob/7e7bdc8411bf/LICENSE)) + - [go4.org/mem](https://pkg.go.dev/go4.org/mem) ([Apache-2.0](https://github.com/go4org/mem/blob/4f986261bf13/LICENSE)) + - [go4.org/netipx](https://pkg.go.dev/go4.org/netipx) ([BSD-3-Clause](https://github.com/go4org/netipx/blob/f1b76eb4bb35/LICENSE)) - [go4.org/unsafe/assume-no-moving-gc](https://pkg.go.dev/go4.org/unsafe/assume-no-moving-gc) ([BSD-3-Clause](https://github.com/go4org/unsafe-assume-no-moving-gc/blob/ee73d164e760/LICENSE)) - - [golang.org/x/crypto](https://pkg.go.dev/golang.org/x/crypto) ([BSD-3-Clause](https://cs.opensource.google/go/x/crypto/+/v0.6.0:LICENSE)) - - [golang.org/x/exp](https://pkg.go.dev/golang.org/x/exp) ([BSD-3-Clause](https://cs.opensource.google/go/x/exp/+/47842c84:LICENSE)) + - [golang.org/x/crypto](https://pkg.go.dev/golang.org/x/crypto) ([BSD-3-Clause](https://cs.opensource.google/go/x/crypto/+/v0.8.0:LICENSE)) + - [golang.org/x/exp](https://pkg.go.dev/golang.org/x/exp) ([BSD-3-Clause](https://cs.opensource.google/go/x/exp/+/47ecfdc1:LICENSE)) - [golang.org/x/exp/shiny](https://pkg.go.dev/golang.org/x/exp/shiny) ([BSD-3-Clause](https://cs.opensource.google/go/x/exp/+/334a2380:shiny/LICENSE)) - - [golang.org/x/image](https://pkg.go.dev/golang.org/x/image) ([BSD-3-Clause](https://cs.opensource.google/go/x/image/+/v0.5.0:LICENSE)) - - [golang.org/x/net](https://pkg.go.dev/golang.org/x/net) ([BSD-3-Clause](https://cs.opensource.google/go/x/net/+/v0.8.0:LICENSE)) - - [golang.org/x/sync/errgroup](https://pkg.go.dev/golang.org/x/sync/errgroup) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.1.0:LICENSE)) - - [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.6.0:LICENSE)) - - [golang.org/x/term](https://pkg.go.dev/golang.org/x/term) ([BSD-3-Clause](https://cs.opensource.google/go/x/term/+/v0.6.0:LICENSE)) - - [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) ([BSD-3-Clause](https://cs.opensource.google/go/x/text/+/v0.8.0:LICENSE)) - - [golang.org/x/time/rate](https://pkg.go.dev/golang.org/x/time/rate) ([BSD-3-Clause](https://cs.opensource.google/go/x/time/+/579cf78f:LICENSE)) - - [gvisor.dev/gvisor/pkg](https://pkg.go.dev/gvisor.dev/gvisor/pkg) ([Apache-2.0](https://github.com/google/gvisor/blob/162ed5ef888d/LICENSE)) + - [golang.org/x/image](https://pkg.go.dev/golang.org/x/image) ([BSD-3-Clause](https://cs.opensource.google/go/x/image/+/v0.7.0:LICENSE)) + - [golang.org/x/net](https://pkg.go.dev/golang.org/x/net) ([BSD-3-Clause](https://cs.opensource.google/go/x/net/+/v0.9.0:LICENSE)) + - [golang.org/x/sync/errgroup](https://pkg.go.dev/golang.org/x/sync/errgroup) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.2.0:LICENSE)) + - [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.8.0:LICENSE)) + - [golang.org/x/term](https://pkg.go.dev/golang.org/x/term) ([BSD-3-Clause](https://cs.opensource.google/go/x/term/+/v0.7.0:LICENSE)) + - [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) ([BSD-3-Clause](https://cs.opensource.google/go/x/text/+/v0.9.0:LICENSE)) + - [golang.org/x/time/rate](https://pkg.go.dev/golang.org/x/time/rate) ([BSD-3-Clause](https://cs.opensource.google/go/x/time/+/v0.3.0:LICENSE)) + - [gvisor.dev/gvisor/pkg](https://pkg.go.dev/gvisor.dev/gvisor/pkg) ([Apache-2.0](https://github.com/google/gvisor/blob/7b0a1988a28f/LICENSE)) - [inet.af/netaddr](https://pkg.go.dev/inet.af/netaddr) ([BSD-3-Clause](https://github.com/inetaf/netaddr/blob/097006376321/LICENSE)) - [inet.af/peercred](https://pkg.go.dev/inet.af/peercred) ([BSD-3-Clause](https://github.com/inetaf/peercred/blob/0893ea02156a/LICENSE)) - [nhooyr.io/websocket](https://pkg.go.dev/nhooyr.io/websocket) ([MIT](https://github.com/nhooyr/websocket/blob/v1.8.7/LICENSE.txt)) From df8b1b2179302a9e30efb4bc91b77d14737eda46 Mon Sep 17 00:00:00 2001 From: License Updater Date: Thu, 4 May 2023 19:34:48 +0000 Subject: [PATCH 11/12] licenses: update tailscale{,d} licenses Signed-off-by: License Updater --- licenses/tailscale.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/licenses/tailscale.md b/licenses/tailscale.md index e9e939083..1d2eeb7bb 100644 --- a/licenses/tailscale.md +++ b/licenses/tailscale.md @@ -83,18 +83,18 @@ Some packages may only be included on certain architectures or operating systems - [golang.org/x/exp](https://pkg.go.dev/golang.org/x/exp) ([BSD-3-Clause](https://cs.opensource.google/go/x/exp/+/47ecfdc1:LICENSE)) - [golang.org/x/net](https://pkg.go.dev/golang.org/x/net) ([BSD-3-Clause](https://cs.opensource.google/go/x/net/+/v0.9.0:LICENSE)) - [golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2) ([BSD-3-Clause](https://cs.opensource.google/go/x/oauth2/+/v0.7.0:LICENSE)) - - [golang.org/x/sync/errgroup](https://pkg.go.dev/golang.org/x/sync/errgroup) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.1.0:LICENSE)) - - [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.7.0:LICENSE)) + - [golang.org/x/sync/errgroup](https://pkg.go.dev/golang.org/x/sync/errgroup) ([BSD-3-Clause](https://cs.opensource.google/go/x/sync/+/v0.2.0:LICENSE)) + - [golang.org/x/sys](https://pkg.go.dev/golang.org/x/sys) ([BSD-3-Clause](https://cs.opensource.google/go/x/sys/+/v0.8.0:LICENSE)) - [golang.org/x/term](https://pkg.go.dev/golang.org/x/term) ([BSD-3-Clause](https://cs.opensource.google/go/x/term/+/v0.7.0:LICENSE)) - [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) ([BSD-3-Clause](https://cs.opensource.google/go/x/text/+/v0.9.0:LICENSE)) - [golang.org/x/time/rate](https://pkg.go.dev/golang.org/x/time/rate) ([BSD-3-Clause](https://cs.opensource.google/go/x/time/+/v0.3.0:LICENSE)) - [golang.zx2c4.com/wintun](https://pkg.go.dev/golang.zx2c4.com/wintun) ([MIT](https://git.zx2c4.com/wintun-go/tree/LICENSE?id=0fa3db229ce2)) - [golang.zx2c4.com/wireguard/windows/tunnel/winipcfg](https://pkg.go.dev/golang.zx2c4.com/wireguard/windows/tunnel/winipcfg) ([MIT](https://git.zx2c4.com/wireguard-windows/tree/COPYING?h=v0.5.3)) - [gopkg.in/yaml.v2](https://pkg.go.dev/gopkg.in/yaml.v2) ([Apache-2.0](https://github.com/go-yaml/yaml/blob/v2.4.0/LICENSE)) - - [gvisor.dev/gvisor/pkg](https://pkg.go.dev/gvisor.dev/gvisor/pkg) ([Apache-2.0](https://github.com/google/gvisor/blob/162ed5ef888d/LICENSE)) + - [gvisor.dev/gvisor/pkg](https://pkg.go.dev/gvisor.dev/gvisor/pkg) ([Apache-2.0](https://github.com/google/gvisor/blob/7b0a1988a28f/LICENSE)) - [inet.af/peercred](https://pkg.go.dev/inet.af/peercred) ([BSD-3-Clause](https://github.com/inetaf/peercred/blob/0893ea02156a/LICENSE)) - [inet.af/wf](https://pkg.go.dev/inet.af/wf) ([BSD-3-Clause](https://github.com/inetaf/wf/blob/36129f591884/LICENSE)) - - [k8s.io/client-go/util/homedir](https://pkg.go.dev/k8s.io/client-go/util/homedir) ([Apache-2.0](https://github.com/kubernetes/client-go/blob/v0.25.0/LICENSE)) + - [k8s.io/client-go/util/homedir](https://pkg.go.dev/k8s.io/client-go/util/homedir) ([Apache-2.0](https://github.com/kubernetes/client-go/blob/v0.26.1/LICENSE)) - [nhooyr.io/websocket](https://pkg.go.dev/nhooyr.io/websocket) ([MIT](https://github.com/nhooyr/websocket/blob/v1.8.7/LICENSE.txt)) - [sigs.k8s.io/yaml](https://pkg.go.dev/sigs.k8s.io/yaml) ([MIT](https://github.com/kubernetes-sigs/yaml/blob/v1.3.0/LICENSE)) - [software.sslmate.com/src/go-pkcs12](https://pkg.go.dev/software.sslmate.com/src/go-pkcs12) ([BSD-3-Clause](https://github.com/SSLMate/go-pkcs12/blob/v0.2.0/LICENSE)) From e8b06b22323668b28ac4f950b8b8963922d4f8bf Mon Sep 17 00:00:00 2001 From: Chenyang Gao Date: Sun, 7 May 2023 15:20:29 +0800 Subject: [PATCH 12/12] version: properly handle vcs.modified when it's "false" Current code will set the "dirty" field of VersionInfo always "true" if vcs.modified flag is there. No matter whether the flag is "true" or "false". It will make sense to set this field due to vcs.modified value, not only the existence of the key. Signed-off-by: Chenyang Gao --- version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version/version.go b/version/version.go index 98e3892e6..424ac47db 100644 --- a/version/version.go +++ b/version/version.go @@ -131,7 +131,7 @@ var getEmbeddedInfo = lazy.SyncFunc(func() embeddedInfo { ret.commitDate = strings.ReplaceAll(ret.commitDate, "-", "") } case "vcs.modified": - ret.dirty = true + ret.dirty = s.Value == "true" } } if ret.commit == "" || ret.commitDate == "" {