diff --git a/appc/appconnector.go b/appc/appconnector.go
index ee495bd10f100..5be7f8021a3ce 100644
--- a/appc/appconnector.go
+++ b/appc/appconnector.go
@@ -12,21 +12,21 @@ package appc
import (
"context"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
"strings"
"time"
- "tailscale.com/syncs"
- "tailscale.com/types/appctype"
- "tailscale.com/types/logger"
- "tailscale.com/types/views"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/execqueue"
- "tailscale.com/util/slicesx"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/appctype"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/execqueue"
+ "github.com/metacubex/tailscale/util/slicesx"
)
// rateLogger responds to calls to update by adding a count for the current period and
diff --git a/appc/appconnector_test.go b/appc/appconnector_test.go
index c58aa80410869..2fc890597072b 100644
--- a/appc/appconnector_test.go
+++ b/appc/appconnector_test.go
@@ -1,29 +1,31 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package appc
import (
- stdcmp "cmp"
"fmt"
+ stdcmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"reflect"
- "slices"
"sync/atomic"
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
+ "github.com/metacubex/tailscale/appc/appctest"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/appctype"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/slicesx"
"golang.org/x/net/dns/dnsmessage"
- "tailscale.com/appc/appctest"
- "tailscale.com/tstest"
- "tailscale.com/types/appctype"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/mak"
- "tailscale.com/util/must"
- "tailscale.com/util/slicesx"
)
func TestUpdateDomains(t *testing.T) {
diff --git a/appc/appctest/appctest.go b/appc/appctest/appctest.go
index c5eabf6761ec3..ce4c85db1a61c 100644
--- a/appc/appctest/appctest.go
+++ b/appc/appctest/appctest.go
@@ -5,8 +5,8 @@
package appctest
import (
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
)
// RouteCollector is a test helper that collects the list of routes advertised
diff --git a/appc/conn25.go b/appc/conn25.go
index 62cb70017824a..e7e5e3c10b607 100644
--- a/appc/conn25.go
+++ b/appc/conn25.go
@@ -4,18 +4,18 @@
package appc
import (
- "cmp"
- "slices"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
- "tailscale.com/ipn/ipnext"
- "tailscale.com/tailcfg"
- "tailscale.com/types/appctype"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/ipn/ipnext"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/appctype"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
)
-const AppConnectorsExperimentalAttrName = "tailscale.com/app-connectors-experimental"
+const AppConnectorsExperimentalAttrName = "github.com/metacubex/tailscale/app-connectors-experimental"
func isPeerEligibleConnector(peer tailcfg.NodeView) bool {
if !peer.Valid() || !peer.Hostinfo().Valid() {
@@ -43,12 +43,15 @@ func PickConnector(nb ipnext.NodeBackend, app appctype.Conn25Attr) []tailcfg.Nod
if !isPeerEligibleConnector(n) {
return false
}
- for _, t := range n.Tags().All() {
+ matched := false
+ n.Tags().All()(func(_ int, t string) bool {
if appTagsSet.Contains(t) {
- return true
+ matched = true
+ return false
}
- }
- return false
+ return true
+ })
+ return matched
})
sortByPreference(matches)
return matches
@@ -96,7 +99,7 @@ func PickSplitDNSPeers(hasCap func(c tailcfg.NodeCapability) bool, self tailcfg.
if !isPeerEligibleConnector(peer) {
continue
}
- for _, t := range peer.Tags().All() {
+ peer.Tags().All()(func(_ int, t string) bool {
domains := tagToDomain[t]
for domain := range domains {
if selfRoutedDomains.Contains(domain) {
@@ -107,7 +110,8 @@ func PickSplitDNSPeers(hasCap func(c tailcfg.NodeCapability) bool, self tailcfg.
}
work[domain].Add(peer.ID())
}
- }
+ return true
+ })
}
// Populate m. Make a []tailcfg.NodeView from []tailcfg.NodeID using the peers map.
diff --git a/appc/conn25_test.go b/appc/conn25_test.go
index dd98312ca638d..a25d97b237613 100644
--- a/appc/conn25_test.go
+++ b/appc/conn25_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,10 +11,10 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
- "tailscale.com/ipn/ipnext"
- "tailscale.com/tailcfg"
- "tailscale.com/types/appctype"
- "tailscale.com/types/opt"
+ "github.com/metacubex/tailscale/ipn/ipnext"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/appctype"
+ "github.com/metacubex/tailscale/types/opt"
)
func TestPickSplitDNSPeers(t *testing.T) {
diff --git a/appc/observe.go b/appc/observe.go
index 3cb2db662b564..693c2ccbeeb19 100644
--- a/appc/observe.go
+++ b/appc/observe.go
@@ -9,8 +9,8 @@ import (
"net/netip"
"strings"
+ "github.com/metacubex/tailscale/util/mak"
"golang.org/x/net/dns/dnsmessage"
- "tailscale.com/util/mak"
)
// ObserveDNSResponse is a callback invoked by the DNS resolver when a DNS
diff --git a/atomicfile/atomicfile.go b/atomicfile/atomicfile.go
index 1fa4c0641f74e..3520fa80d2ae7 100644
--- a/atomicfile/atomicfile.go
+++ b/atomicfile/atomicfile.go
@@ -5,7 +5,7 @@
// atomically.
//
// This package should be considered internal; its API is not stable.
-package atomicfile // import "tailscale.com/atomicfile"
+package atomicfile // import "github.com/metacubex/tailscale/atomicfile"
import (
"fmt"
diff --git a/atomicfile/atomicfile_test.go b/atomicfile/atomicfile_test.go
index 6dbf4eb430372..2ad6ac253e3a7 100644
--- a/atomicfile/atomicfile_test.go
+++ b/atomicfile/atomicfile_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !js && !windows
-
package atomicfile
import (
diff --git a/atomicfile/atomicfile_windows_test.go b/atomicfile/atomicfile_windows_test.go
index 8748fc324f61a..50a9376637919 100644
--- a/atomicfile/atomicfile_windows_test.go
+++ b/atomicfile/atomicfile_windows_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/cache_key_test.go b/cache_key_test.go
index 8600bcd719f04..7dfe90d765402 100644
--- a/cache_key_test.go
+++ b/cache_key_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,7 +11,7 @@ import (
"strings"
"testing"
- "tailscale.com/util/cibuild"
+ "github.com/metacubex/tailscale/util/cibuild"
)
// TestTsgoRevInCacheKey verifies that the Tailscale Go toolchain's git
diff --git a/chirp/chirp_test.go b/chirp/chirp_test.go
index eedc17f48afa9..83983f7bd940f 100644
--- a/chirp/chirp_test.go
+++ b/chirp/chirp_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/client/freedesktop/freedesktop_test.go b/client/freedesktop/freedesktop_test.go
index d02d1f67c286a..2352984f18d1d 100644
--- a/client/freedesktop/freedesktop_test.go
+++ b/client/freedesktop/freedesktop_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/client/local/debugportmapper.go b/client/local/debugportmapper.go
index 1cbb3ee0a303e..7b6429ea07290 100644
--- a/client/local/debugportmapper.go
+++ b/client/local/debugportmapper.go
@@ -6,9 +6,9 @@
package local
import (
- "cmp"
"context"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"io"
"net/http"
"net/netip"
@@ -16,7 +16,7 @@ import (
"strconv"
"time"
- "tailscale.com/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
)
// DebugPortmapOpts contains options for the [Client.DebugPortmap] command.
diff --git a/client/local/local.go b/client/local/local.go
index 1a2d7342b06b4..a9d61aad57d62 100644
--- a/client/local/local.go
+++ b/client/local/local.go
@@ -7,14 +7,14 @@ package local
import (
"bufio"
"bytes"
- "cmp"
"context"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
"io"
- "iter"
"net"
"net/http"
"net/http/httptrace"
@@ -27,24 +27,24 @@ import (
"sync"
"time"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/drive"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/net/netutil"
- "tailscale.com/net/udprelay/status"
- "tailscale.com/paths"
- "tailscale.com/safesocket"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/types/appctype"
- "tailscale.com/types/dnstype"
- "tailscale.com/types/key"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/eventbus"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/net/netutil"
+ "github.com/metacubex/tailscale/net/udprelay/status"
+ "github.com/metacubex/tailscale/paths"
+ "github.com/metacubex/tailscale/safesocket"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/appctype"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/eventbus"
)
// defaultClient is the default Client when using the legacy
@@ -192,7 +192,8 @@ func (e *AccessDeniedError) Unwrap() error { return e.err }
// IsAccessDeniedError reports whether err is or wraps an AccessDeniedError.
func IsAccessDeniedError(err error) bool {
- _, ok := errors.AsType[*AccessDeniedError](err)
+ var accessDeniedErr *AccessDeniedError
+ ok := errors.As(err, &accessDeniedErr)
return ok
}
@@ -210,7 +211,8 @@ func (e *PreconditionsFailedError) Unwrap() error { return e.err }
// IsPreconditionsFailedError reports whether err is or wraps an PreconditionsFailedError.
func IsPreconditionsFailedError(err error) bool {
- _, ok := errors.AsType[*PreconditionsFailedError](err)
+ var preconditionsFailedErr *PreconditionsFailedError
+ ok := errors.As(err, &preconditionsFailedErr)
return ok
}
@@ -868,7 +870,7 @@ func (lc *Client) CheckUDPGROForwarding(ctx context.Context) error {
// SetUDPGROForwarding enables UDP GRO forwarding for the main interface of this
// node. This can be done to improve performance of tailnet nodes acting as exit
// nodes or subnet routers.
-// See https://tailscale.com/kb/1320/performance-best-practices#linux-optimizations-for-subnet-routers-and-exit-nodes
+// See https://github.com/metacubex/tailscale/kb/1320/performance-best-practices#linux-optimizations-for-subnet-routers-and-exit-nodes
func (lc *Client) SetUDPGROForwarding(ctx context.Context) error {
body, err := lc.get200(ctx, "/localapi/v0/set-udp-gro-forwarding")
if err != nil {
@@ -1169,7 +1171,7 @@ func tailscaledConnectHint() string {
// ActiveState=inactive
// SubState=dead
st := map[string]string{}
- for line := range strings.SplitSeq(string(out), "\n") {
+ for _, line := range strings.Split(string(out), "\n") {
if k, v, ok := strings.Cut(line, "="); ok {
st[k] = strings.TrimSpace(v)
}
diff --git a/client/local/local_test.go b/client/local/local_test.go
index 58a87b224564b..8ba79fd398926 100644
--- a/client/local/local_test.go
+++ b/client/local/local_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build go1.19
-
package local
import (
@@ -11,9 +11,9 @@ import (
"net/http"
"testing"
- "tailscale.com/tstest/deptest"
- "tailscale.com/tstest/nettest"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/tstest/deptest"
+ "github.com/metacubex/tailscale/tstest/nettest"
+ "github.com/metacubex/tailscale/types/key"
)
func TestGetServeConfigFromJSON(t *testing.T) {
@@ -117,9 +117,9 @@ func TestDeps(t *testing.T) {
BadDeps: map[string]string{
// Make sure we don't again accidentally bring in a dependency on
// drive or its transitive dependencies
- "testing": "do not use testing package in production code",
- "tailscale.com/drive/driveimpl": "https://github.com/tailscale/tailscale/pull/10631",
- "github.com/studio-b12/gowebdav": "https://github.com/tailscale/tailscale/pull/10631",
+ "testing": "do not use testing package in production code",
+ "github.com/metacubex/tailscale/drive/driveimpl": "https://github.com/tailscale/tailscale/pull/10631",
+ "github.com/studio-b12/gowebdav": "https://github.com/tailscale/tailscale/pull/10631",
},
}.Check(t)
}
diff --git a/client/local/serve.go b/client/local/serve.go
index 7f9a16a03f825..30c83f9c16eaf 100644
--- a/client/local/serve.go
+++ b/client/local/serve.go
@@ -11,7 +11,7 @@ import (
"fmt"
"net/http"
- "tailscale.com/ipn"
+ "github.com/metacubex/tailscale/ipn"
)
// GetServeConfig return the current serve config.
diff --git a/client/local/syspolicy.go b/client/local/syspolicy.go
index 49708fa154d9a..5767ee3403cde 100644
--- a/client/local/syspolicy.go
+++ b/client/local/syspolicy.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_syspolicy
+//go:build ts_enable_syspolicy
package local
@@ -9,7 +9,7 @@ import (
"context"
"net/http"
- "tailscale.com/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
)
// GetEffectivePolicy returns the effective policy for the specified scope.
diff --git a/client/local/tailnetlock.go b/client/local/tailnetlock.go
index 5af90eb165102..50d966ba9caf9 100644
--- a/client/local/tailnetlock.go
+++ b/client/local/tailnetlock.go
@@ -12,10 +12,10 @@ import (
"fmt"
"net/url"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tka"
- "tailscale.com/types/key"
- "tailscale.com/types/tkatype"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/tkatype"
)
// NetworkLockStatus fetches information about the tailnet key authority, if one is configured.
diff --git a/client/systray/startup-creator.go b/client/systray/startup-creator.go
index 02a01809945e1..03dc09a2eb38d 100644
--- a/client/systray/startup-creator.go
+++ b/client/systray/startup-creator.go
@@ -16,7 +16,7 @@ import (
"path/filepath"
"strings"
- "tailscale.com/client/freedesktop"
+ "github.com/metacubex/tailscale/client/freedesktop"
)
//go:embed tailscale-systray.service
diff --git a/client/systray/systray.go b/client/systray/systray.go
index d0287e6470b06..9f1f908f3338c 100644
--- a/client/systray/systray.go
+++ b/client/systray/systray.go
@@ -11,6 +11,7 @@ import (
"context"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"image"
"io"
"log"
@@ -18,7 +19,6 @@ import (
"os"
"os/signal"
"runtime"
- "slices"
"strings"
"sync"
"syscall"
@@ -28,13 +28,13 @@ import (
ico "github.com/Kodeworks/golang-image-ico"
"github.com/atotto/clipboard"
dbus "github.com/godbus/dbus/v5"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/util/stringsx"
"github.com/toqueteos/webbrowser"
- "tailscale.com/client/local"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/util/slicesx"
- "tailscale.com/util/stringsx"
)
var (
@@ -168,7 +168,7 @@ This usually means that you should run the application like:
tailscale systray
-See https://tailscale.com/kb/1597/linux-systray for more information.`)
+See https://github.com/metacubex/tailscale/kb/1597/linux-systray for more information.`)
}
setAppIcon(disconnected)
@@ -185,7 +185,7 @@ No permission to manage Tailscale. Set operator by running:
sudo tailscale set --operator=$USER
-See https://tailscale.com/s/cli-operator for more information.`)
+See https://github.com/metacubex/tailscale/s/cli-operator for more information.`)
}
menu.mu.Unlock()
}
@@ -231,10 +231,10 @@ func (menu *Menu) rebuild() {
systray.ResetMenu()
if menu.readonly {
- const readonlyMsg = "No permission to manage Tailscale.\nSee tailscale.com/s/cli-operator"
+ const readonlyMsg = "No permission to manage Tailscale.\nSee github.com/metacubex/tailscale/s/cli-operator"
m := systray.AddMenuItem(readonlyMsg, "")
onClick(ctx, m, func(_ context.Context) {
- webbrowser.Open("https://tailscale.com/s/cli-operator")
+ webbrowser.Open("https://github.com/metacubex/tailscale/s/cli-operator")
})
systray.AddSeparator()
}
diff --git a/client/systray/systray_test.go b/client/systray/systray_test.go
index 6b8ce8b95e540..f9afe7630f8b4 100644
--- a/client/systray/systray_test.go
+++ b/client/systray/systray_test.go
@@ -1,16 +1,16 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build cgo || !darwin
-
package systray
import (
"testing"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
)
func TestRecommendedIsActive(t *testing.T) {
diff --git a/client/tailscale/acl.go b/client/tailscale/acl.go
index e69d45a2bff5d..5c1e83f49a11d 100644
--- a/client/tailscale/acl.go
+++ b/client/tailscale/acl.go
@@ -117,7 +117,7 @@ func (c *Client) ACL(ctx context.Context) (acl *ACL, err error) {
// it as a string.
// HuJSON is JSON with a few modifications to make it more human-friendly. The primary
// changes are allowing comments and trailing comments. See the following links for more info:
-// https://tailscale.com/s/acl-format
+// https://github.com/metacubex/tailscale/s/acl-format
// https://github.com/tailscale/hujson
func (c *Client) ACLHuJSON(ctx context.Context) (acl *ACLHuJSON, err error) {
// Format return errors to be descriptive.
@@ -290,7 +290,7 @@ type UserRuleMatch struct {
Ports []string `json:"ports"`
LineNumber int `json:"lineNumber"`
// Via is the list of targets through which Users can access Ports.
- // See https://tailscale.com/kb/1378/via for more information.
+ // See https://github.com/metacubex/tailscale/kb/1378/via for more information.
Via []string `json:"via,omitempty"`
// Postures is a list of posture policies that are
@@ -298,7 +298,7 @@ type UserRuleMatch struct {
// up in the ACLPreviewResponse parent struct.
// The source of the list is from srcPosture on
// an ACL or Grant rule:
- // https://tailscale.com/kb/1288/device-posture#posture-conditions
+ // https://github.com/metacubex/tailscale/kb/1288/device-posture#posture-conditions
Postures []string `json:"postures"`
}
@@ -311,7 +311,7 @@ type ACLPreviewResponse struct {
// Postures is a map of postures and associated rules that apply
// to this preview.
// For more details about the posture mapping, see:
- // https://tailscale.com/kb/1288/device-posture#postures
+ // https://github.com/metacubex/tailscale/kb/1288/device-posture#postures
Postures map[string][]string `json:"postures,omitempty"`
}
@@ -324,7 +324,7 @@ type ACLPreview struct {
// Postures is a map of postures and associated rules that apply
// to this preview.
// For more details about the posture mapping, see:
- // https://tailscale.com/kb/1288/device-posture#postures
+ // https://github.com/metacubex/tailscale/kb/1288/device-posture#postures
Postures map[string][]string `json:"postures,omitempty"`
}
diff --git a/client/tailscale/apitype/apitype.go b/client/tailscale/apitype/apitype.go
index d7d1440be9f8a..39d0e4c873692 100644
--- a/client/tailscale/apitype/apitype.go
+++ b/client/tailscale/apitype/apitype.go
@@ -5,9 +5,9 @@
package apitype
import (
- "tailscale.com/tailcfg"
- "tailscale.com/types/dnstype"
- "tailscale.com/util/ctxkey"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/util/ctxkey"
)
// LocalAPIHost is the Host header value used by the LocalAPI.
diff --git a/client/tailscale/cert.go b/client/tailscale/cert.go
index 797c5535d17f5..7d9f936f4f394 100644
--- a/client/tailscale/cert.go
+++ b/client/tailscale/cert.go
@@ -9,26 +9,26 @@ import (
"context"
"crypto/tls"
- "tailscale.com/client/local"
+ "github.com/metacubex/tailscale/client/local"
)
-// GetCertificate is an alias for [tailscale.com/client/local.GetCertificate].
+// GetCertificate is an alias for [github.com/metacubex/tailscale/client/local.GetCertificate].
//
-// Deprecated: import [tailscale.com/client/local] instead and use [local.Client.GetCertificate].
+// Deprecated: import [github.com/metacubex/tailscale/client/local] instead and use [local.Client.GetCertificate].
func GetCertificate(hi *tls.ClientHelloInfo) (*tls.Certificate, error) {
return local.GetCertificate(hi)
}
-// CertPair is an alias for [tailscale.com/client/local.CertPair].
+// CertPair is an alias for [github.com/metacubex/tailscale/client/local.CertPair].
//
-// Deprecated: import [tailscale.com/client/local] instead and use [local.Client.CertPair].
+// Deprecated: import [github.com/metacubex/tailscale/client/local] instead and use [local.Client.CertPair].
func CertPair(ctx context.Context, domain string) (certPEM, keyPEM []byte, err error) {
return local.CertPair(ctx, domain)
}
-// ExpandSNIName is an alias for [tailscale.com/client/local.ExpandSNIName].
+// ExpandSNIName is an alias for [github.com/metacubex/tailscale/client/local.ExpandSNIName].
//
-// Deprecated: import [tailscale.com/client/local] instead and use [local.Client.ExpandSNIName].
+// Deprecated: import [github.com/metacubex/tailscale/client/local] instead and use [local.Client.ExpandSNIName].
func ExpandSNIName(ctx context.Context, name string) (fqdn string, ok bool) {
return local.ExpandSNIName(ctx, name)
}
diff --git a/client/tailscale/devices.go b/client/tailscale/devices.go
index 2b2cf7a0cd049..9936d7731bd45 100644
--- a/client/tailscale/devices.go
+++ b/client/tailscale/devices.go
@@ -14,7 +14,7 @@ import (
"net/http"
"net/url"
- "tailscale.com/types/opt"
+ "github.com/metacubex/tailscale/types/opt"
)
type GetDevicesResponse struct {
diff --git a/client/tailscale/dns.go b/client/tailscale/dns.go
index 427caea0fc593..49878ac15291b 100644
--- a/client/tailscale/dns.go
+++ b/client/tailscale/dns.go
@@ -12,7 +12,7 @@ import (
"fmt"
"net/http"
- "tailscale.com/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
)
// DNSNameServers is returned when retrieving the list of nameservers.
diff --git a/client/tailscale/example/servetls/servetls.go b/client/tailscale/example/servetls/servetls.go
index 864dafd07b242..916ed659646f0 100644
--- a/client/tailscale/example/servetls/servetls.go
+++ b/client/tailscale/example/servetls/servetls.go
@@ -11,7 +11,7 @@ import (
"log"
"net/http"
- "tailscale.com/client/local"
+ "github.com/metacubex/tailscale/client/local"
)
func main() {
diff --git a/client/tailscale/localclient_aliases.go b/client/tailscale/localclient_aliases.go
index 98a72068a5eba..998d3124d0e7c 100644
--- a/client/tailscale/localclient_aliases.go
+++ b/client/tailscale/localclient_aliases.go
@@ -6,74 +6,74 @@ package tailscale
import (
"context"
- "tailscale.com/client/local"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/ipn/ipnstate"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
)
-// ErrPeerNotFound is an alias for [tailscale.com/client/local.ErrPeerNotFound].
+// ErrPeerNotFound is an alias for [github.com/metacubex/tailscale/client/local.ErrPeerNotFound].
//
-// Deprecated: import [tailscale.com/client/local] instead.
+// Deprecated: import [github.com/metacubex/tailscale/client/local] instead.
var ErrPeerNotFound = local.ErrPeerNotFound
-// LocalClient is an alias for [tailscale.com/client/local.Client].
+// LocalClient is an alias for [github.com/metacubex/tailscale/client/local.Client].
//
-// Deprecated: import [tailscale.com/client/local] instead.
+// Deprecated: import [github.com/metacubex/tailscale/client/local] instead.
type LocalClient = local.Client
-// IPNBusWatcher is an alias for [tailscale.com/client/local.IPNBusWatcher].
+// IPNBusWatcher is an alias for [github.com/metacubex/tailscale/client/local.IPNBusWatcher].
//
-// Deprecated: import [tailscale.com/client/local] instead.
+// Deprecated: import [github.com/metacubex/tailscale/client/local] instead.
type IPNBusWatcher = local.IPNBusWatcher
-// BugReportOpts is an alias for [tailscale.com/client/local.BugReportOpts].
+// BugReportOpts is an alias for [github.com/metacubex/tailscale/client/local.BugReportOpts].
//
-// Deprecated: import [tailscale.com/client/local] instead.
+// Deprecated: import [github.com/metacubex/tailscale/client/local] instead.
type BugReportOpts = local.BugReportOpts
-// PingOpts is an alias for [tailscale.com/client/local.PingOpts].
+// PingOpts is an alias for [github.com/metacubex/tailscale/client/local.PingOpts].
//
-// Deprecated: import [tailscale.com/client/local] instead.
+// Deprecated: import [github.com/metacubex/tailscale/client/local] instead.
type PingOpts = local.PingOpts
-// SetVersionMismatchHandler is an alias for [tailscale.com/client/local.SetVersionMismatchHandler].
+// SetVersionMismatchHandler is an alias for [github.com/metacubex/tailscale/client/local.SetVersionMismatchHandler].
//
-// Deprecated: import [tailscale.com/client/local] instead.
+// Deprecated: import [github.com/metacubex/tailscale/client/local] instead.
func SetVersionMismatchHandler(f func(clientVer, serverVer string)) {
local.SetVersionMismatchHandler(f)
}
-// IsAccessDeniedError is an alias for [tailscale.com/client/local.IsAccessDeniedError].
+// IsAccessDeniedError is an alias for [github.com/metacubex/tailscale/client/local.IsAccessDeniedError].
//
-// Deprecated: import [tailscale.com/client/local] instead.
+// Deprecated: import [github.com/metacubex/tailscale/client/local] instead.
func IsAccessDeniedError(err error) bool {
return local.IsAccessDeniedError(err)
}
-// IsPreconditionsFailedError is an alias for [tailscale.com/client/local.IsPreconditionsFailedError].
+// IsPreconditionsFailedError is an alias for [github.com/metacubex/tailscale/client/local.IsPreconditionsFailedError].
//
-// Deprecated: import [tailscale.com/client/local] instead.
+// Deprecated: import [github.com/metacubex/tailscale/client/local] instead.
func IsPreconditionsFailedError(err error) bool {
return local.IsPreconditionsFailedError(err)
}
-// WhoIs is an alias for [tailscale.com/client/local.WhoIs].
+// WhoIs is an alias for [github.com/metacubex/tailscale/client/local.WhoIs].
//
-// Deprecated: import [tailscale.com/client/local] instead and use [local.Client.WhoIs].
+// Deprecated: import [github.com/metacubex/tailscale/client/local] instead and use [local.Client.WhoIs].
func WhoIs(ctx context.Context, remoteAddr string) (*apitype.WhoIsResponse, error) {
return local.WhoIs(ctx, remoteAddr)
}
-// Status is an alias for [tailscale.com/client/local.Status].
+// Status is an alias for [github.com/metacubex/tailscale/client/local.Status].
//
-// Deprecated: import [tailscale.com/client/local] instead.
+// Deprecated: import [github.com/metacubex/tailscale/client/local] instead.
func Status(ctx context.Context) (*ipnstate.Status, error) {
return local.Status(ctx)
}
-// StatusWithoutPeers is an alias for [tailscale.com/client/local.StatusWithoutPeers].
+// StatusWithoutPeers is an alias for [github.com/metacubex/tailscale/client/local.StatusWithoutPeers].
//
-// Deprecated: import [tailscale.com/client/local] instead.
+// Deprecated: import [github.com/metacubex/tailscale/client/local] instead.
func StatusWithoutPeers(ctx context.Context) (*ipnstate.Status, error) {
return local.StatusWithoutPeers(ctx)
}
diff --git a/client/tailscale/required_version.go b/client/tailscale/required_version.go
index fb994e55fb604..e54e056ae6493 100644
--- a/client/tailscale/required_version.go
+++ b/client/tailscale/required_version.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !go1.23
+//go:build !go1.20
package tailscale
diff --git a/client/tailscale/tailnet.go b/client/tailscale/tailnet.go
index 75ca7dfd60a33..dfac61cc1e24d 100644
--- a/client/tailscale/tailnet.go
+++ b/client/tailscale/tailnet.go
@@ -10,7 +10,7 @@ import (
"fmt"
"net/http"
- "tailscale.com/util/httpm"
+ "github.com/metacubex/tailscale/util/httpm"
)
// TailnetDeleteRequest handles sending a DELETE request for a tailnet to control.
diff --git a/client/tailscale/tailscale.go b/client/tailscale/tailscale.go
index d5585a052bb99..3dd9b549a7453 100644
--- a/client/tailscale/tailscale.go
+++ b/client/tailscale/tailscale.go
@@ -71,7 +71,7 @@ func (c *Client) httpClient() *http.Client {
// be of type url.Values to add a query string to the URL.
//
// For example, BuildURL(devices, 5) with the default server URL would result in
-// https://api.tailscale.com/api/v2/devices/5.
+// https://api.github.com/metacubex/tailscale/api/v2/devices/5.
func (c *Client) BuildURL(pathElements ...any) string {
elem := make([]string, 1, len(pathElements)+1)
elem[0] = "/api/v2"
@@ -96,7 +96,7 @@ func (c *Client) BuildURL(pathElements ...any) string {
// be of type url.Values to add a query string to the URL.
//
// For example, BuildTailnetURL(policy, validate) with the default server URL and a tailnet of "example.com"
-// would result in https://api.tailscale.com/api/v2/tailnet/example.com/policy/validate.
+// would result in https://api.github.com/metacubex/tailscale/api/v2/tailnet/example.com/policy/validate.
func (c *Client) BuildTailnetURL(pathElements ...any) string {
allElements := make([]any, 2, len(pathElements)+2)
allElements[0] = "tailnet"
diff --git a/client/tailscale/tailscale_test.go b/client/tailscale/tailscale_test.go
index 342a2d7872026..a9c1c4425c800 100644
--- a/client/tailscale/tailscale_test.go
+++ b/client/tailscale/tailscale_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/client/web/assets.go b/client/web/assets.go
index b9e4226299dd1..4f8b5165dce32 100644
--- a/client/web/assets.go
+++ b/client/web/assets.go
@@ -4,6 +4,7 @@
package web
import (
+ "embed"
"io"
"io/fs"
"log"
@@ -15,12 +16,13 @@ import (
"path/filepath"
"strings"
"time"
-
- prebuilt "github.com/tailscale/web-client-prebuilt"
)
var start = time.Now()
+//go:embed static/index.html
+var embeddedAssets embed.FS
+
func assetsHandler(devMode bool) (_ http.Handler, cleanup func()) {
if devMode {
// When in dev mode, proxy asset requests to the Vite dev server.
@@ -28,7 +30,12 @@ func assetsHandler(devMode bool) (_ http.Handler, cleanup func()) {
return devServerProxy(), cleanup
}
- fsys := prebuilt.FS()
+ fsys, err := fs.Sub(embeddedAssets, "static")
+ if err != nil {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ }), nil
+ }
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
path := strings.TrimPrefix(r.URL.Path, "/")
f, err := openPrecompressedFile(w, r, path, fsys)
diff --git a/client/web/auth.go b/client/web/auth.go
index 916f24782d55a..74571adb4c8f5 100644
--- a/client/web/auth.go
+++ b/client/web/auth.go
@@ -9,15 +9,15 @@ import (
"encoding/base64"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/http"
"net/url"
- "slices"
"strings"
"time"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
)
const (
@@ -234,7 +234,7 @@ func (s *Server) awaitUserAuth(ctx context.Context, session *browserSession) err
func (s *Server) newSessionID() (string, error) {
raw := make([]byte, 16)
- for range 5 {
+ for i := 0; i < 5; i++ {
if _, err := rand.Read(raw); err != nil {
return "", err
}
diff --git a/client/web/static/index.html b/client/web/static/index.html
new file mode 100644
index 0000000000000..e2694e7ac8f10
--- /dev/null
+++ b/client/web/static/index.html
@@ -0,0 +1,6 @@
+
+
+
Tailscale Web Client
+
+Tailscale web client assets are not bundled in this build.
+
diff --git a/client/web/synology.go b/client/web/synology.go
index e39cbc9c5c82e..5ec3c3b801f4a 100644
--- a/client/web/synology.go
+++ b/client/web/synology.go
@@ -13,7 +13,7 @@ import (
"os/exec"
"strings"
- "tailscale.com/util/groupmember"
+ "github.com/metacubex/tailscale/util/groupmember"
)
// authorizeSynology authenticates the logged-in Synology user and verifies
diff --git a/client/web/web.go b/client/web/web.go
index 95259ef1a9039..047466fb92b43 100644
--- a/client/web/web.go
+++ b/client/web/web.go
@@ -5,11 +5,12 @@
package web
import (
- "cmp"
"context"
"encoding/json"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
"net/http"
@@ -17,32 +18,31 @@ import (
"net/url"
"os"
"path"
- "slices"
"strings"
"sync"
"time"
- "tailscale.com/client/local"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/envknob"
- "tailscale.com/envknob/featureknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/licenses"
- "tailscale.com/net/netutil"
- "tailscale.com/net/tsaddr"
- "tailscale.com/tailcfg"
- "tailscale.com/tsweb"
- "tailscale.com/types/logger"
- "tailscale.com/types/views"
- "tailscale.com/util/ctxkey"
- "tailscale.com/util/httpm"
- "tailscale.com/util/syspolicy/policyclient"
- "tailscale.com/version"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/envknob/featureknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/licenses"
+ "github.com/metacubex/tailscale/net/netutil"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsweb"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/ctxkey"
+ "github.com/metacubex/tailscale/util/httpm"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/version"
+ "github.com/metacubex/tailscale/version/distro"
)
// ListenPort is the static port used for the web client when run inside tailscaled.
@@ -540,7 +540,8 @@ func handleJSON[data any](h func(ctx context.Context, data data) error) http.Han
return
}
if err := h(r.Context(), body); err != nil {
- if httpErr, ok := errors.AsType[tsweb.HTTPError](err); ok {
+ var httpErr tsweb.HTTPError
+ if ok := errors.As(err, &httpErr); ok {
tsweb.WriteHTTPError(w, r, httpErr)
} else {
http.Error(w, err.Error(), http.StatusInternalServerError)
@@ -1214,7 +1215,7 @@ func (s *Server) tailscaleUp(ctx context.Context, st *ipnstate.Status, opt tails
type tailscaleUpOptions struct {
// If true, force reauthentication of the client.
- // Otherwise simply reconnect, the same as running `tailscale up`.
+ // Otherwise simply reconnect, the same as running ailscale up`.
Reauthenticate bool
ControlURL string
diff --git a/client/web/web_test.go b/client/web/web_test.go
index 51b6a8ac58781..ded9b23a7d332 100644
--- a/client/web/web_test.go
+++ b/client/web/web_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,26 +11,26 @@ import (
"encoding/json"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net/http"
"net/http/httptest"
"net/netip"
"net/url"
- "slices"
"strings"
"testing"
"time"
"github.com/google/go-cmp/cmp"
- "tailscale.com/client/local"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/net/memnet"
- "tailscale.com/tailcfg"
- "tailscale.com/types/views"
- "tailscale.com/util/httpm"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/net/memnet"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/httpm"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
func TestQnapAuthnURL(t *testing.T) {
diff --git a/clientupdate/clientupdate.go b/clientupdate/clientupdate.go
index 6d034b342d1cf..a61fdd22492aa 100644
--- a/clientupdate/clientupdate.go
+++ b/clientupdate/clientupdate.go
@@ -14,9 +14,9 @@ import (
"encoding/json"
"errors"
"fmt"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"io"
"io/fs"
- "maps"
"net/http"
"os"
"os/exec"
@@ -27,14 +27,14 @@ import (
"strconv"
"strings"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/hostinfo"
- "tailscale.com/types/lazy"
- "tailscale.com/types/logger"
- "tailscale.com/util/cmpver"
- "tailscale.com/version"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/cmpver"
+ "github.com/metacubex/tailscale/version"
+ "github.com/metacubex/tailscale/version/distro"
)
const (
@@ -519,7 +519,7 @@ func updateDebianAptSourcesList(dstTrack string) (rewrote bool, err error) {
}
func updateDebianAptSourcesListBytes(was []byte, dstTrack string) (newContent []byte, err error) {
- trackURLPrefix := []byte("https://pkgs.tailscale.com/" + dstTrack + "/")
+ trackURLPrefix := []byte("https://pkgs.github.com/metacubex/tailscale/" + dstTrack + "/")
var buf bytes.Buffer
var changes int
bs := bufio.NewScanner(bytes.NewReader(was))
@@ -627,7 +627,7 @@ func updateYUMRepoTrack(repoFile, dstTrack string) (rewrote bool, err error) {
}
urlRe := regexp.MustCompile(`^(baseurl|gpgkey)=https://pkgs\.tailscale\.com/(stable|unstable|release-candidate)`)
- urlReplacement := fmt.Sprintf("$1=https://pkgs.tailscale.com/%s", dstTrack)
+ urlReplacement := fmt.Sprintf("$1=https://pkgs.github.com/metacubex/tailscale/%s", dstTrack)
s := bufio.NewScanner(bytes.NewReader(was))
newContent := bytes.NewBuffer(make([]byte, 0, len(was)))
diff --git a/clientupdate/clientupdate_downloads.go b/clientupdate/clientupdate_downloads.go
index 9458f88fe8a18..bc317cb1e75d6 100644
--- a/clientupdate/clientupdate_downloads.go
+++ b/clientupdate/clientupdate_downloads.go
@@ -8,7 +8,7 @@ package clientupdate
import (
"context"
- "tailscale.com/clientupdate/distsign"
+ "github.com/metacubex/tailscale/clientupdate/distsign"
)
func (up *Updater) downloadURLToFile(pathSrc, fileDst string) (ret error) {
diff --git a/clientupdate/clientupdate_test.go b/clientupdate/clientupdate_test.go
index 8095151c8169c..5b60c9a96dda7 100644
--- a/clientupdate/clientupdate_test.go
+++ b/clientupdate/clientupdate_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,13 +10,13 @@ import (
"compress/gzip"
"encoding/json"
"fmt"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io/fs"
- "maps"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
- "slices"
"sort"
"strings"
"testing"
@@ -31,38 +33,38 @@ func TestUpdateDebianAptSourcesListBytes(t *testing.T) {
{
name: "stable-to-unstable",
toTrack: UnstableTrack,
- in: "# Tailscale packages for debian buster\ndeb https://pkgs.tailscale.com/stable/debian bullseye main\n",
- want: "# Tailscale packages for debian buster\ndeb https://pkgs.tailscale.com/unstable/debian bullseye main\n",
+ in: "# Tailscale packages for debian buster\ndeb https://pkgs.github.com/metacubex/tailscale/stable/debian bullseye main\n",
+ want: "# Tailscale packages for debian buster\ndeb https://pkgs.github.com/metacubex/tailscale/unstable/debian bullseye main\n",
},
{
name: "stable-unchanged",
toTrack: StableTrack,
- in: "# Tailscale packages for debian buster\ndeb https://pkgs.tailscale.com/stable/debian bullseye main\n",
+ in: "# Tailscale packages for debian buster\ndeb https://pkgs.github.com/metacubex/tailscale/stable/debian bullseye main\n",
},
{
name: "if-both-stable-and-unstable-dont-change",
toTrack: StableTrack,
in: "# Tailscale packages for debian buster\n" +
- "deb https://pkgs.tailscale.com/stable/debian bullseye main\n" +
- "deb https://pkgs.tailscale.com/unstable/debian bullseye main\n",
+ "deb https://pkgs.github.com/metacubex/tailscale/stable/debian bullseye main\n" +
+ "deb https://pkgs.github.com/metacubex/tailscale/unstable/debian bullseye main\n",
},
{
name: "if-both-stable-and-unstable-dont-change-unstable",
toTrack: UnstableTrack,
in: "# Tailscale packages for debian buster\n" +
- "deb https://pkgs.tailscale.com/stable/debian bullseye main\n" +
- "deb https://pkgs.tailscale.com/unstable/debian bullseye main\n",
+ "deb https://pkgs.github.com/metacubex/tailscale/stable/debian bullseye main\n" +
+ "deb https://pkgs.github.com/metacubex/tailscale/unstable/debian bullseye main\n",
},
{
name: "signed-by-form",
toTrack: UnstableTrack,
- in: "# Tailscale packages for ubuntu jammy\ndeb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/ubuntu jammy main\n",
- want: "# Tailscale packages for ubuntu jammy\ndeb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/unstable/ubuntu jammy main\n",
+ in: "# Tailscale packages for ubuntu jammy\ndeb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.github.com/metacubex/tailscale/stable/ubuntu jammy main\n",
+ want: "# Tailscale packages for ubuntu jammy\ndeb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.github.com/metacubex/tailscale/unstable/ubuntu jammy main\n",
},
{
name: "unsupported-lines",
toTrack: UnstableTrack,
- in: "# Tailscale packages for ubuntu jammy\ndeb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/foobar/ubuntu jammy main\n",
+ in: "# Tailscale packages for ubuntu jammy\ndeb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.github.com/metacubex/tailscale/foobar/ubuntu jammy main\n",
wantErr: "unexpected/unsupported /etc/apt/sources.list.d/tailscale.list contents",
},
}
@@ -93,34 +95,34 @@ var YUMRepos = map[string]string{
StableTrack: `
[tailscale-stable]
name=Tailscale stable
-baseurl=https://pkgs.tailscale.com/stable/fedora/$basearch
+baseurl=https://pkgs.github.com/metacubex/tailscale/stable/fedora/$basearch
enabled=1
type=rpm
repo_gpgcheck=1
gpgcheck=0
-gpgkey=https://pkgs.tailscale.com/stable/fedora/repo.gpg
+gpgkey=https://pkgs.github.com/metacubex/tailscale/stable/fedora/repo.gpg
`,
UnstableTrack: `
[tailscale-unstable]
name=Tailscale unstable
-baseurl=https://pkgs.tailscale.com/unstable/fedora/$basearch
+baseurl=https://pkgs.github.com/metacubex/tailscale/unstable/fedora/$basearch
enabled=1
type=rpm
repo_gpgcheck=1
gpgcheck=0
-gpgkey=https://pkgs.tailscale.com/unstable/fedora/repo.gpg
+gpgkey=https://pkgs.github.com/metacubex/tailscale/unstable/fedora/repo.gpg
`,
ReleaseCandidateTrack: `
[tailscale-release-candidate]
name=Tailscale release-candidate
-baseurl=https://pkgs.tailscale.com/release-candidate/fedora/$basearch
+baseurl=https://pkgs.github.com/metacubex/tailscale/release-candidate/fedora/$basearch
enabled=1
type=rpm
repo_gpgcheck=1
gpgcheck=0
-gpgkey=https://pkgs.tailscale.com/release-candidate/fedora/repo.gpg
+gpgkey=https://pkgs.github.com/metacubex/tailscale/release-candidate/fedora/repo.gpg
`,
"FakeRepo": `
@@ -221,7 +223,7 @@ tailscale-1.44.2-r0 description:
The easiest, most secure way to use WireGuard and 2FA
tailscale-1.44.2-r0 webpage:
-https://tailscale.com/
+https://github.com/metacubex/tailscale/
tailscale-1.44.2-r0 installed size:
32 MiB
@@ -249,7 +251,7 @@ tailscale description:
The easiest, most secure way to use WireGuard and 2FA
tailscale webpage:
-https://tailscale.com/
+https://github.com/metacubex/tailscale/
tailscale installed size:
32 MiB
@@ -268,7 +270,7 @@ tailscale-1.54.1-r0 description:
The easiest, most secure way to use WireGuard and 2FA
tailscale-1.54.1-r0 webpage:
-https://tailscale.com/
+https://github.com/metacubex/tailscale/
tailscale-1.54.1-r0 installed size:
34 MiB
@@ -277,7 +279,7 @@ tailscale-1.58.2-r0 description:
The easiest, most secure way to use WireGuard and 2FA
tailscale-1.58.2-r0 webpage:
-https://tailscale.com/
+https://github.com/metacubex/tailscale/
tailscale-1.58.2-r0 installed size:
35 MiB
diff --git a/clientupdate/clientupdate_windows.go b/clientupdate/clientupdate_windows.go
index 50b77c38b4e5a..7d21221fbe35f 100644
--- a/clientupdate/clientupdate_windows.go
+++ b/clientupdate/clientupdate_windows.go
@@ -19,9 +19,9 @@ import (
"time"
"github.com/google/uuid"
+ "github.com/metacubex/tailscale/util/winutil"
+ "github.com/metacubex/tailscale/util/winutil/authenticode"
"golang.org/x/sys/windows"
- "tailscale.com/util/winutil"
- "tailscale.com/util/winutil/authenticode"
)
const (
@@ -275,7 +275,7 @@ func msiUUIDForVersion(ver string) string {
if err != nil {
track = UnstableTrack
}
- msiURL := fmt.Sprintf("https://pkgs.tailscale.com/%s/tailscale-setup-%s-%s.msi", track, ver, arch)
+ msiURL := fmt.Sprintf("https://pkgs.github.com/metacubex/tailscale/%s/tailscale-setup-%s-%s.msi", track, ver, arch)
return "{" + strings.ToUpper(uuid.NewSHA1(uuid.NameSpaceURL, []byte(msiURL)).String()) + "}"
}
diff --git a/clientupdate/distsign/distsign.go b/clientupdate/distsign/distsign.go
index c804b855cfc1d..813969eb73cba 100644
--- a/clientupdate/distsign/distsign.go
+++ b/clientupdate/distsign/distsign.go
@@ -53,12 +53,12 @@ import (
"os"
"time"
- "github.com/hdevalence/ed25519consensus"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/ed25519consensus"
+ "github.com/metacubex/tailscale/util/httpm"
+ "github.com/metacubex/tailscale/util/must"
"golang.org/x/crypto/blake2s"
- "tailscale.com/feature"
- "tailscale.com/types/logger"
- "tailscale.com/util/httpm"
- "tailscale.com/util/must"
)
const (
@@ -329,7 +329,13 @@ func fetch(url string, limit int64) ([]byte, error) {
// download writes the response body of url into a local file at dst, up to
// limit bytes. On success, the returned value is a BLAKE2s hash of the file.
func (c *Client) download(ctx context.Context, url, dst string, limit int64) ([]byte, int64, error) {
- tr := http.DefaultTransport.(*http.Transport).Clone()
+ tr := (&http.Transport{
+ ForceAttemptHTTP2: true,
+ MaxIdleConns: 100,
+ IdleConnTimeout: 90 * time.Second,
+ TLSHandshakeTimeout: 10 * time.Second,
+ ExpectContinueTimeout: 1 * time.Second,
+ }).Clone()
tr.Proxy = feature.HookProxyFromEnvironment.GetOrNil()
defer tr.CloseIdleConnections()
hc := &http.Client{
diff --git a/clientupdate/distsign/distsign_test.go b/clientupdate/distsign/distsign_test.go
index 1380078859f3a..6e89a42ba9cca 100644
--- a/clientupdate/distsign/distsign_test.go
+++ b/clientupdate/distsign/distsign_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/clientupdate/distsign/roots_test.go b/clientupdate/distsign/roots_test.go
index 562b06c1c29c1..aea17dd09e51d 100644
--- a/clientupdate/distsign/roots_test.go
+++ b/clientupdate/distsign/roots_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/cmd/build-webclient/build-webclient.go b/cmd/build-webclient/build-webclient.go
index 949d9ef349ef1..69494542d81f3 100644
--- a/cmd/build-webclient/build-webclient.go
+++ b/cmd/build-webclient/build-webclient.go
@@ -19,7 +19,7 @@ import (
"os/exec"
"path/filepath"
- "tailscale.com/util/precompress"
+ "github.com/metacubex/tailscale/util/precompress"
)
var (
diff --git a/cmd/checkmetrics/checkmetrics.go b/cmd/checkmetrics/checkmetrics.go
index 5612ffbf512f9..1d90f8f715d57 100644
--- a/cmd/checkmetrics/checkmetrics.go
+++ b/cmd/checkmetrics/checkmetrics.go
@@ -17,10 +17,10 @@ import (
"strings"
"time"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/tsnet"
- "tailscale.com/tstest/integration/testcontrol"
- "tailscale.com/util/httpm"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/tstest/integration/testcontrol"
+ "github.com/metacubex/tailscale/util/httpm"
)
var (
diff --git a/cmd/cloner/cloner.go b/cmd/cloner/cloner.go
index 576edd2b1f6e0..7ee007239e38f 100644
--- a/cmd/cloner/cloner.go
+++ b/cmd/cloner/cloner.go
@@ -21,7 +21,7 @@ import (
"os"
"strings"
- "tailscale.com/util/codegen"
+ "github.com/metacubex/tailscale/util/codegen"
)
var (
@@ -83,7 +83,7 @@ func main() {
cloneOutput += "_test"
}
cloneOutput += ".go"
- if err := codegen.WritePackageFile("tailscale.com/cmd/cloner", pkg, cloneOutput, it, buf); err != nil {
+ if err := codegen.WritePackageFile("github.com/metacubex/tailscale/cmd/cloner", pkg, cloneOutput, it, buf); err != nil {
log.Fatal(err)
}
}
diff --git a/cmd/cloner/cloner_test.go b/cmd/cloner/cloner_test.go
index 834d1be7bd31d..c15ddbeb8a86c 100644
--- a/cmd/cloner/cloner_test.go
+++ b/cmd/cloner/cloner_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,7 +9,7 @@ import (
"reflect"
"testing"
- "tailscale.com/cmd/cloner/clonerex"
+ "github.com/metacubex/tailscale/cmd/cloner/clonerex"
)
func TestSliceContainer(t *testing.T) {
diff --git a/cmd/cloner/clonerex/clonerex.go b/cmd/cloner/clonerex/clonerex.go
index 41626d3ae8b45..769053077ed4e 100644
--- a/cmd/cloner/clonerex/clonerex.go
+++ b/cmd/cloner/clonerex/clonerex.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:generate go run tailscale.com/cmd/cloner -clonefunc=true -type SliceContainer,InterfaceContainer,MapWithPointers,DeeplyNestedMap,NamedMapContainer,MapSlicePointerContainer
+//go:generate go run github.com/metacubex/tailscale/cmd/cloner -clonefunc=true -type SliceContainer,InterfaceContainer,MapWithPointers,DeeplyNestedMap,NamedMapContainer,MapSlicePointerContainer
// Package clonerex is an example package for the cloner tool.
package clonerex
diff --git a/cmd/cloner/clonerex/clonerex_clone.go b/cmd/cloner/clonerex/clonerex_clone.go
index 9e21ff9d03f0d..397ba07d5578e 100644
--- a/cmd/cloner/clonerex/clonerex_clone.go
+++ b/cmd/cloner/clonerex/clonerex_clone.go
@@ -1,12 +1,12 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-// Code generated by tailscale.com/cmd/cloner; DO NOT EDIT.
+// Code generated by github.com/metacubex/tailscale/cmd/cloner; DO NOT EDIT.
package clonerex
import (
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
)
// Clone makes a deep copy of SliceContainer.
diff --git a/cmd/connector-gen/github.go b/cmd/connector-gen/github.go
index a0162aa06cae3..a2db981467688 100644
--- a/cmd/connector-gen/github.go
+++ b/cmd/connector-gen/github.go
@@ -6,10 +6,10 @@ package main
import (
"encoding/json"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
"net/http"
"net/netip"
- "slices"
"strings"
"go4.org/netipx"
diff --git a/cmd/containerboot/egressservices.go b/cmd/containerboot/egressservices.go
index abde125237a75..2fea4db1973b7 100644
--- a/cmd/containerboot/egressservices.go
+++ b/cmd/containerboot/egressservices.go
@@ -23,14 +23,14 @@ import (
"github.com/fsnotify/fsnotify"
- "tailscale.com/client/local"
- "tailscale.com/kube/egressservices"
- "tailscale.com/kube/kubeclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/types/netmap"
- "tailscale.com/util/httpm"
- "tailscale.com/util/linuxfw"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/kube/egressservices"
+ "github.com/metacubex/tailscale/kube/kubeclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/httpm"
+ "github.com/metacubex/tailscale/util/linuxfw"
+ "github.com/metacubex/tailscale/util/mak"
)
const tailscaleTunInterface = "tailscale0"
diff --git a/cmd/containerboot/egressservices_test.go b/cmd/containerboot/egressservices_test.go
index b30765f19425a..49e6f0dee6a51 100644
--- a/cmd/containerboot/egressservices_test.go
+++ b/cmd/containerboot/egressservices_test.go
@@ -1,7 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux
package main
@@ -16,8 +17,8 @@ import (
"sync"
"testing"
- "tailscale.com/kube/egressservices"
- "tailscale.com/kube/kubetypes"
+ "github.com/metacubex/tailscale/kube/egressservices"
+ "github.com/metacubex/tailscale/kube/kubetypes"
)
func Test_updatesForSvc(t *testing.T) {
diff --git a/cmd/containerboot/forwarding.go b/cmd/containerboot/forwarding.go
index 6d90fbaaa9723..04a5aec2ed9c5 100644
--- a/cmd/containerboot/forwarding.go
+++ b/cmd/containerboot/forwarding.go
@@ -15,7 +15,7 @@ import (
"path/filepath"
"strings"
- "tailscale.com/util/linuxfw"
+ "github.com/metacubex/tailscale/util/linuxfw"
)
// ensureIPForwarding enables IPv4/IPv6 forwarding for the container.
diff --git a/cmd/containerboot/ingressservices.go b/cmd/containerboot/ingressservices.go
index d76bf86e0b8ec..1b1505c71d47f 100644
--- a/cmd/containerboot/ingressservices.go
+++ b/cmd/containerboot/ingressservices.go
@@ -16,11 +16,11 @@ import (
"reflect"
"time"
+ "github.com/metacubex/tailscale/kube/ingressservices"
+ "github.com/metacubex/tailscale/kube/kubeclient"
+ "github.com/metacubex/tailscale/util/linuxfw"
+ "github.com/metacubex/tailscale/util/mak"
"github.com/fsnotify/fsnotify"
- "tailscale.com/kube/ingressservices"
- "tailscale.com/kube/kubeclient"
- "tailscale.com/util/linuxfw"
- "tailscale.com/util/mak"
)
// ingressProxy corresponds to a Kubernetes Operator's network layer ingress
diff --git a/cmd/containerboot/ingressservices_test.go b/cmd/containerboot/ingressservices_test.go
index 46330103e343b..9ef15583580d2 100644
--- a/cmd/containerboot/ingressservices_test.go
+++ b/cmd/containerboot/ingressservices_test.go
@@ -1,7 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux
package main
@@ -9,8 +10,8 @@ import (
"net/netip"
"testing"
- "tailscale.com/kube/ingressservices"
- "tailscale.com/util/linuxfw"
+ "github.com/metacubex/tailscale/kube/ingressservices"
+ "github.com/metacubex/tailscale/util/linuxfw"
)
func TestSyncIngressConfigs(t *testing.T) {
diff --git a/cmd/containerboot/kube.go b/cmd/containerboot/kube.go
index 3e97710da6c92..3dfa6f691e662 100644
--- a/cmd/containerboot/kube.go
+++ b/cmd/containerboot/kube.go
@@ -18,18 +18,18 @@ import (
"strings"
"time"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/kube/authkey"
+ "github.com/metacubex/tailscale/kube/egressservices"
+ "github.com/metacubex/tailscale/kube/ingressservices"
+ "github.com/metacubex/tailscale/kube/kubeapi"
+ "github.com/metacubex/tailscale/kube/kubeclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/backoff"
"github.com/fsnotify/fsnotify"
- "tailscale.com/client/local"
- "tailscale.com/ipn"
- "tailscale.com/kube/authkey"
- "tailscale.com/kube/egressservices"
- "tailscale.com/kube/ingressservices"
- "tailscale.com/kube/kubeapi"
- "tailscale.com/kube/kubeclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
- "tailscale.com/util/backoff"
)
const fieldManager = "tailscale-container"
diff --git a/cmd/containerboot/kube_test.go b/cmd/containerboot/kube_test.go
index fec0b74f7d8f1..5ad3c8290cacf 100644
--- a/cmd/containerboot/kube_test.go
+++ b/cmd/containerboot/kube_test.go
@@ -1,7 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux
package main
@@ -12,14 +13,14 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/kube/egressservices"
+ "github.com/metacubex/tailscale/kube/ingressservices"
+ "github.com/metacubex/tailscale/kube/kubeapi"
+ "github.com/metacubex/tailscale/kube/kubeclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tailcfg"
"github.com/google/go-cmp/cmp"
- "tailscale.com/ipn"
- "tailscale.com/kube/egressservices"
- "tailscale.com/kube/ingressservices"
- "tailscale.com/kube/kubeapi"
- "tailscale.com/kube/kubeclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tailcfg"
)
func TestSetupKube(t *testing.T) {
diff --git a/cmd/containerboot/main.go b/cmd/containerboot/main.go
index 1a11c3150cdd2..797a5d9ff4d36 100644
--- a/cmd/containerboot/main.go
+++ b/cmd/containerboot/main.go
@@ -72,7 +72,7 @@
// check endpoints if enabled via TS_ENABLE_METRICS and/or TS_ENABLE_HEALTH_CHECK.
// Defaults to [::]:9002, serving on all available interfaces.
// - TS_ENABLE_METRICS: if true, a metrics endpoint will be served at /metrics on
-// the address specified by TS_LOCAL_ADDR_PORT. See https://tailscale.com/kb/1482/client-metrics
+// the address specified by TS_LOCAL_ADDR_PORT. See https://github.com/metacubex/tailscale/kb/1482/client-metrics
// for more information on the metrics exposed.
// - TS_ENABLE_HEALTH_CHECK: if true, a health check endpoint will be served at /healthz on
// the address specified by TS_LOCAL_ADDR_PORT. The health endpoint will return 200
@@ -90,7 +90,7 @@
// TS_EXPERIMENTAL_ENABLE_FORWARDING_OPTIMIZATIONS: set to true to
// autoconfigure the default network interface for optimal performance for
// Tailscale subnet router/exit node.
-// https://tailscale.com/kb/1320/performance-best-practices#linux-optimizations-for-subnet-routers-and-exit-nodes
+// https://github.com/metacubex/tailscale/kb/1320/performance-best-practices#linux-optimizations-for-subnet-routers-and-exit-nodes
// NB: This env var is currently experimental and the logic will likely change!
// - EXPERIMENTAL_ALLOW_PROXYING_CLUSTER_TRAFFIC_VIA_INGRESS: if set to true
// and if this containerboot instance is an L7 ingress proxy (created by
@@ -119,6 +119,7 @@ import (
"context"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io/fs"
"log"
"math"
@@ -128,7 +129,6 @@ import (
"os"
"os/signal"
"path/filepath"
- "slices"
"strings"
"sync"
"sync/atomic"
@@ -137,22 +137,22 @@ import (
"golang.org/x/sys/unix"
- "tailscale.com/client/local"
- "tailscale.com/health"
- "tailscale.com/ipn"
- kubeutils "tailscale.com/k8s-operator"
- "tailscale.com/kube/authkey"
- healthz "tailscale.com/kube/health"
- "tailscale.com/kube/kubetypes"
- klc "tailscale.com/kube/localclient"
- "tailscale.com/kube/metrics"
- "tailscale.com/kube/services"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/util/deephash"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/linuxfw"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn"
+ kubeutils "github.com/metacubex/tailscale/k8s-operator"
+ "github.com/metacubex/tailscale/kube/authkey"
+ healthz "github.com/metacubex/tailscale/kube/health"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ klc "github.com/metacubex/tailscale/kube/localclient"
+ "github.com/metacubex/tailscale/kube/metrics"
+ "github.com/metacubex/tailscale/kube/services"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/deephash"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/linuxfw"
)
func newNetfilterRunner(logf logger.Logf) (linuxfw.NetfilterRunner, error) {
diff --git a/cmd/containerboot/main_test.go b/cmd/containerboot/main_test.go
index 40f575250cb1c..0b9f8a45c361e 100644
--- a/cmd/containerboot/main_test.go
+++ b/cmd/containerboot/main_test.go
@@ -1,7 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux
package main
@@ -13,9 +14,9 @@ import (
"encoding/pem"
"errors"
"fmt"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"io"
"io/fs"
- "maps"
"net"
"net/http"
"net/http/httptest"
@@ -30,17 +31,17 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/cmd/testwrapper/flakytest"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/kube/egressservices"
+ "github.com/metacubex/tailscale/kube/kubeclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/netmap"
"github.com/google/go-cmp/cmp"
"golang.org/x/sys/unix"
- "tailscale.com/cmd/testwrapper/flakytest"
- "tailscale.com/health"
- "tailscale.com/ipn"
- "tailscale.com/kube/egressservices"
- "tailscale.com/kube/kubeclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/types/netmap"
)
const configFileAuthKey = "some-auth-key"
@@ -48,7 +49,7 @@ const configFileAuthKey = "some-auth-key"
func TestContainerBoot(t *testing.T) {
flakytest.Mark(t, "https://github.com/tailscale/tailscale/issues/19380")
boot := filepath.Join(t.TempDir(), "containerboot")
- if err := exec.Command("go", "build", "-ldflags", "-X main.testSleepDuration=1ms", "-o", boot, "tailscale.com/cmd/containerboot").Run(); err != nil {
+ if err := exec.Command("go", "build", "-ldflags", "-X main.testSleepDuration=1ms", "-o", boot, "github.com/metacubex/tailscale/cmd/containerboot").Run(); err != nil {
t.Fatalf("Building containerboot: %v", err)
}
egressStatus := egressSvcStatus("foo", "foo.tailnetxyz.ts.net", "100.64.0.2")
diff --git a/cmd/containerboot/serve.go b/cmd/containerboot/serve.go
index f64d2d24f681f..1eb8b753cd247 100644
--- a/cmd/containerboot/serve.go
+++ b/cmd/containerboot/serve.go
@@ -17,14 +17,14 @@ import (
"sync/atomic"
"time"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/kube/certs"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ klc "github.com/metacubex/tailscale/kube/localclient"
+ "github.com/metacubex/tailscale/kube/services"
+ "github.com/metacubex/tailscale/types/netmap"
"github.com/fsnotify/fsnotify"
- "tailscale.com/client/local"
- "tailscale.com/ipn"
- "tailscale.com/kube/certs"
- "tailscale.com/kube/kubetypes"
- klc "tailscale.com/kube/localclient"
- "tailscale.com/kube/services"
- "tailscale.com/types/netmap"
)
// watchServeConfigChanges watches path for changes, and when it sees one, reads
@@ -162,7 +162,7 @@ func isValidHTTPSConfig(certDomain string, sc *ipn.ServeConfig) bool {
log.Printf(
`serve proxy: this node is configured as a proxy that exposes an HTTPS endpoint to tailnet,
(perhaps a Kubernetes operator Ingress proxy) but it is not able to issue TLS certs, so this will likely not work.
- To make it work, ensure that HTTPS is enabled for your tailnet, see https://tailscale.com/kb/1153/enabling-https for more details.`)
+ To make it work, ensure that HTTPS is enabled for your tailnet, see https://github.com/metacubex/tailscale/kb/1153/enabling-https for more details.`)
return false
}
return true
diff --git a/cmd/containerboot/serve_test.go b/cmd/containerboot/serve_test.go
index 5da5ef5f737c3..ccbb3de7bc221 100644
--- a/cmd/containerboot/serve_test.go
+++ b/cmd/containerboot/serve_test.go
@@ -1,7 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux
package main
@@ -11,11 +12,11 @@ import (
"path/filepath"
"testing"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/kube/localclient"
+ "github.com/metacubex/tailscale/tailcfg"
"github.com/google/go-cmp/cmp"
- "tailscale.com/ipn"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/kube/localclient"
- "tailscale.com/tailcfg"
)
func TestUpdateServeConfig(t *testing.T) {
diff --git a/cmd/containerboot/settings.go b/cmd/containerboot/settings.go
index f695f2e5db5f4..dbb91fed89beb 100644
--- a/cmd/containerboot/settings.go
+++ b/cmd/containerboot/settings.go
@@ -16,8 +16,8 @@ import (
"strconv"
"strings"
- "tailscale.com/ipn/conffile"
- "tailscale.com/kube/kubeclient"
+ "github.com/metacubex/tailscale/ipn/conffile"
+ "github.com/metacubex/tailscale/kube/kubeclient"
)
// settings is all the configuration for containerboot.
diff --git a/cmd/containerboot/settings_test.go b/cmd/containerboot/settings_test.go
index eca50101b6c70..00f8d0029e890 100644
--- a/cmd/containerboot/settings_test.go
+++ b/cmd/containerboot/settings_test.go
@@ -1,7 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux
package main
diff --git a/cmd/containerboot/tailscaled.go b/cmd/containerboot/tailscaled.go
index 6f4ed77e76d72..743672660e52b 100644
--- a/cmd/containerboot/tailscaled.go
+++ b/cmd/containerboot/tailscaled.go
@@ -19,8 +19,8 @@ import (
"syscall"
"time"
+ "github.com/metacubex/tailscale/client/local"
"github.com/fsnotify/fsnotify"
- "tailscale.com/client/local"
)
func startTailscaled(ctx context.Context, cfg *settings) (*local.Client, *os.Process, error) {
diff --git a/cmd/derper/ace.go b/cmd/derper/ace.go
index ae2d0cbebb413..d01c323382b7c 100644
--- a/cmd/derper/ace.go
+++ b/cmd/derper/ace.go
@@ -12,8 +12,8 @@ import (
"net/http"
"strings"
- "tailscale.com/derp/derpserver"
- "tailscale.com/net/connectproxy"
+ "github.com/metacubex/tailscale/derp/derpserver"
+ "github.com/metacubex/tailscale/net/connectproxy"
)
// serveConnect handles a CONNECT request for ACE support.
@@ -56,8 +56,8 @@ func serveConnect(s *derpserver.Server, w http.ResponseWriter, r *http.Request)
// encryption, varying by the request type:
//
// 1. TLS from client to ACE proxy (CONNECT)
- // 2a. TLS from ACE proxy to https://controlplane.tailscale.com/key (port 443)
- // 2b. ts2021 Noise from ACE proxy to http://controlplane.tailscale.com/ts2021 (port 80)
+ // 2a. TLS from ACE proxy to https://controlplane.github.com/metacubex/tailscale/key (port 443)
+ // 2b. ts2021 Noise from ACE proxy to http://controlplane.github.com/metacubex/tailscale/ts2021 (port 80)
//
// But nothing's stopping the client from doing its ts2021
// upgrade over https anyway and having three layers of
diff --git a/cmd/derper/bootstrap_dns.go b/cmd/derper/bootstrap_dns.go
index 9abc95df56878..1b34db6872d92 100644
--- a/cmd/derper/bootstrap_dns.go
+++ b/cmd/derper/bootstrap_dns.go
@@ -8,8 +8,8 @@ import (
"encoding/binary"
"encoding/json"
"expvar"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"log"
- "math/rand/v2"
"net"
"net/http"
"net/netip"
@@ -18,9 +18,9 @@ import (
"sync/atomic"
"time"
- "tailscale.com/syncs"
- "tailscale.com/util/mak"
- "tailscale.com/util/slicesx"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/slicesx"
)
const refreshTimeout = time.Minute
diff --git a/cmd/derper/bootstrap_dns_test.go b/cmd/derper/bootstrap_dns_test.go
index 2055b97511940..354766a47e27b 100644
--- a/cmd/derper/bootstrap_dns_test.go
+++ b/cmd/derper/bootstrap_dns_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -15,8 +17,8 @@ import (
"reflect"
"testing"
- "tailscale.com/tstest"
- "tailscale.com/tstest/nettest"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstest/nettest"
)
func BenchmarkHandleBootstrapDNS(b *testing.B) {
diff --git a/cmd/derper/cert.go b/cmd/derper/cert.go
index 979c0d671517f..f8c5d8eb61a53 100644
--- a/cmd/derper/cert.go
+++ b/cmd/derper/cert.go
@@ -25,9 +25,9 @@ import (
"regexp"
"time"
+ "github.com/metacubex/tailscale/tailcfg"
"golang.org/x/crypto/acme"
"golang.org/x/crypto/acme/autocert"
- "tailscale.com/tailcfg"
)
var unsafeHostnameCharacters = regexp.MustCompile(`[^a-zA-Z0-9-\.]`)
@@ -133,7 +133,7 @@ func NewManualCertManager(certdir, hostname string) (certProvider, error) {
CertName: fmt.Sprintf("sha256-raw:%-02x", sha256.Sum256(x509Cert.Raw)),
}
dnJSON, _ := json.Marshal(dn)
- log.Printf("Using self-signed certificate for IP address %q. Configure it in DERPMap using: (https://tailscale.com/s/custom-derp)\n %s", hostname, dnJSON)
+ log.Printf("Using self-signed certificate for IP address %q. Configure it in DERPMap using: (https://github.com/metacubex/tailscale/s/custom-derp)\n %s", hostname, dnJSON)
}
return &manualCertManager{
cert: &cert,
diff --git a/cmd/derper/cert_test.go b/cmd/derper/cert_test.go
index e111ed76b7a97..da4fb47779371 100644
--- a/cmd/derper/cert_test.go
+++ b/cmd/derper/cert_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -22,11 +24,11 @@ import (
"testing"
"time"
- "tailscale.com/derp/derphttp"
- "tailscale.com/derp/derpserver"
- "tailscale.com/net/netmon"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/derp/derphttp"
+ "github.com/metacubex/tailscale/derp/derpserver"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
)
// Verify that in --certmode=manual mode, we can use a bare IP address
diff --git a/cmd/derper/depaware.txt b/cmd/derper/depaware.txt
index c927335e47a37..151419ab15ed4 100644
--- a/cmd/derper/depaware.txt
+++ b/cmd/derper/depaware.txt
@@ -14,12 +14,12 @@ tailscale.com/cmd/derper dependencies: (generated by github.com/tailscale/depawa
W 💣 github.com/dblohm7/wingoes from tailscale.com/util/winutil
github.com/dgryski/go-metro from github.com/axiomhq/hyperloglog
github.com/fxamacker/cbor/v2 from tailscale.com/tka
- github.com/go-json-experiment/json from tailscale.com/types/opt+
- github.com/go-json-experiment/json/internal from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonflags from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonopts from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonwire from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/jsontext from github.com/go-json-experiment/json+
+ github.com/metacubex/jsonv2 from tailscale.com/types/opt+
+ github.com/metacubex/jsonv2/internal from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonflags from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonopts from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonwire from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/jsontext from github.com/metacubex/jsonv2+
💣 github.com/go4org/hashtriemap from tailscale.com/derp/derpserver
github.com/golang/groupcache/lru from tailscale.com/net/dnscache
github.com/hdevalence/ed25519consensus from tailscale.com/tka
diff --git a/cmd/derper/derper.go b/cmd/derper/derper.go
index 745d887f8bc06..90da3d2c3376d 100644
--- a/cmd/derper/derper.go
+++ b/cmd/derper/derper.go
@@ -5,13 +5,12 @@
//
// For more information, see:
//
-// - About: https://tailscale.com/kb/1232/derp-servers
-// - Protocol & Go docs: https://pkg.go.dev/tailscale.com/derp
+// - About: https://github.com/metacubex/tailscale/kb/1232/derp-servers
+// - Protocol & Go docs: https://pkg.go.dev/github.com/metacubex/tailscale/derp
// - Running a DERP server: https://github.com/tailscale/tailscale/tree/main/cmd/derper#derp
-package main // import "tailscale.com/cmd/derper"
+package main // import "github.com/metacubex/tailscale/cmd/derper"
import (
- "cmp"
"context"
"crypto/tls"
"encoding/json"
@@ -19,6 +18,7 @@ import (
"expvar"
"flag"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"html/template"
"io"
"log"
@@ -37,20 +37,20 @@ import (
"syscall"
"time"
+ "github.com/metacubex/tailscale/atomicfile"
+ "github.com/metacubex/tailscale/derp/derpserver"
+ "github.com/metacubex/tailscale/metrics"
+ "github.com/metacubex/tailscale/net/ktimeout"
+ "github.com/metacubex/tailscale/net/stunserver"
+ "github.com/metacubex/tailscale/tsweb"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/version"
"github.com/tailscale/setec/client/setec"
"golang.org/x/time/rate"
- "tailscale.com/atomicfile"
- "tailscale.com/derp/derpserver"
- "tailscale.com/metrics"
- "tailscale.com/net/ktimeout"
- "tailscale.com/net/stunserver"
- "tailscale.com/tsweb"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/version"
// Support for prometheus varz in tsweb
- _ "tailscale.com/tsweb/promvarz"
+ _ "github.com/metacubex/tailscale/tsweb/promvarz"
)
var (
@@ -560,7 +560,7 @@ type templateData struct {
var homePageTemplate = template.Must(template.New("home").Parse(`
DERP
- This is a Tailscale DERP server.
+ This is a Tailscale DERP server.
@@ -580,11 +580,11 @@ var homePageTemplate = template.Must(template.New("home").Parse(`
diff --git a/cmd/derper/derper_test.go b/cmd/derper/derper_test.go
index fc1ebd6930dd6..2f26826702ccf 100644
--- a/cmd/derper/derper_test.go
+++ b/cmd/derper/derper_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,8 +13,8 @@ import (
"strings"
"testing"
- "tailscale.com/derp/derpserver"
- "tailscale.com/tstest/deptest"
+ "github.com/metacubex/tailscale/derp/derpserver"
+ "github.com/metacubex/tailscale/tstest/deptest"
)
func TestProdAutocertHostPolicy(t *testing.T) {
@@ -101,14 +103,14 @@ func TestNoContent(t *testing.T) {
func TestDeps(t *testing.T) {
deptest.DepChecker{
BadDeps: map[string]string{
- "testing": "do not use testing package in production code",
- "gvisor.dev/gvisor/pkg/buffer": "https://github.com/tailscale/tailscale/issues/9756",
- "gvisor.dev/gvisor/pkg/cpuid": "https://github.com/tailscale/tailscale/issues/9756",
- "gvisor.dev/gvisor/pkg/tcpip": "https://github.com/tailscale/tailscale/issues/9756",
- "gvisor.dev/gvisor/pkg/tcpip/header": "https://github.com/tailscale/tailscale/issues/9756",
- "tailscale.com/net/packet": "not needed in derper",
- "github.com/gaissmai/bart": "not needed in derper",
- "database/sql/driver": "not needed in derper", // previously came in via github.com/google/uuid
+ "testing": "do not use testing package in production code",
+ "github.com/metacubex/gvisor/pkg/buffer": "https://github.com/tailscale/tailscale/issues/9756",
+ "github.com/metacubex/gvisor/pkg/cpuid": "https://github.com/tailscale/tailscale/issues/9756",
+ "github.com/metacubex/gvisor/pkg/tcpip": "https://github.com/tailscale/tailscale/issues/9756",
+ "github.com/metacubex/gvisor/pkg/tcpip/header": "https://github.com/tailscale/tailscale/issues/9756",
+ "github.com/metacubex/tailscale/net/packet": "not needed in derper",
+ "github.com/metacubex/bart": "not needed in derper",
+ "database/sql/driver": "not needed in derper", // previously came in via github.com/google/uuid
},
}.Check(t)
}
diff --git a/cmd/derper/mesh.go b/cmd/derper/mesh.go
index c07cfe969d9e3..df89e4f204e5b 100644
--- a/cmd/derper/mesh.go
+++ b/cmd/derper/mesh.go
@@ -11,11 +11,11 @@ import (
"net"
"strings"
- "tailscale.com/derp"
- "tailscale.com/derp/derphttp"
- "tailscale.com/derp/derpserver"
- "tailscale.com/net/netmon"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/derp"
+ "github.com/metacubex/tailscale/derp/derphttp"
+ "github.com/metacubex/tailscale/derp/derpserver"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/types/logger"
)
func startMesh(s *derpserver.Server) error {
diff --git a/cmd/derper/websocket.go b/cmd/derper/websocket.go
index 1929f16906659..17ce2c916cf2c 100644
--- a/cmd/derper/websocket.go
+++ b/cmd/derper/websocket.go
@@ -11,8 +11,8 @@ import (
"strings"
"github.com/coder/websocket"
- "tailscale.com/derp/derpserver"
- "tailscale.com/net/wsconn"
+ "github.com/metacubex/tailscale/derp/derpserver"
+ "github.com/metacubex/tailscale/net/wsconn"
)
var counterWebSocketAccepts = expvar.NewInt("derp_websocket_accepts")
diff --git a/cmd/derpprobe/derpprobe.go b/cmd/derpprobe/derpprobe.go
index 549364e5e8f6a..718bae763ffe5 100644
--- a/cmd/derpprobe/derpprobe.go
+++ b/cmd/derpprobe/derpprobe.go
@@ -16,14 +16,14 @@ import (
"sort"
"time"
+ "github.com/metacubex/tailscale/prober"
+ "github.com/metacubex/tailscale/tsweb"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/version"
"github.com/tailscale/setec/client/setec"
- "tailscale.com/prober"
- "tailscale.com/tsweb"
- "tailscale.com/types/key"
- "tailscale.com/version"
// Support for prometheus varz in tsweb
- _ "tailscale.com/tsweb/promvarz"
+ _ "github.com/metacubex/tailscale/tsweb/promvarz"
)
const meshKeyEnvVar = "TAILSCALE_DERPER_MESH_KEY"
@@ -35,7 +35,7 @@ func defaultSetecCacheDir() string {
var (
dev = flag.Bool("dev", false, "run in localhost development mode")
- derpMapURL = flag.String("derp-map", "https://login.tailscale.com/derpmap/default", "URL to DERP map (https:// or file://) or 'local' to use the local tailscaled's DERP map")
+ derpMapURL = flag.String("derp-map", "https://login.github.com/metacubex/tailscale/derpmap/default", "URL to DERP map (https:// or file://) or 'local' to use the local tailscaled's DERP map")
versionFlag = flag.Bool("version", false, "print version and exit")
listen = flag.String("listen", ":8030", "HTTP listen address")
probeOnce = flag.Bool("once", false, "probe once and print results, then exit; ignores the listen flag")
diff --git a/cmd/dist/dist.go b/cmd/dist/dist.go
index 88b9e6fba9133..2329d9a46adb3 100644
--- a/cmd/dist/dist.go
+++ b/cmd/dist/dist.go
@@ -5,19 +5,19 @@
package main
import (
- "cmp"
"context"
"errors"
"flag"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
"os"
- "slices"
- "tailscale.com/release/dist"
- "tailscale.com/release/dist/cli"
- "tailscale.com/release/dist/qnap"
- "tailscale.com/release/dist/synology"
- "tailscale.com/release/dist/unixpkgs"
+ "github.com/metacubex/tailscale/release/dist"
+ "github.com/metacubex/tailscale/release/dist/cli"
+ "github.com/metacubex/tailscale/release/dist/qnap"
+ "github.com/metacubex/tailscale/release/dist/synology"
+ "github.com/metacubex/tailscale/release/dist/unixpkgs"
)
var (
diff --git a/cmd/distsign/distsign.go b/cmd/distsign/distsign.go
index e0dba27206be9..a9aca4c7047df 100644
--- a/cmd/distsign/distsign.go
+++ b/cmd/distsign/distsign.go
@@ -12,11 +12,11 @@ import (
"os"
"path/filepath"
- "tailscale.com/clientupdate/distsign"
+ "github.com/metacubex/tailscale/clientupdate/distsign"
)
var (
- pkgsURL = flag.String("pkgs-url", "https://pkgs.tailscale.com/", "URL of the packages server")
+ pkgsURL = flag.String("pkgs-url", "https://pkgs.github.com/metacubex/tailscale/", "URL of the packages server")
pkgName = flag.String("pkg-name", "", "name of the package on the packages server, including the stable/unstable track prefix")
)
diff --git a/cmd/featuretags/featuretags.go b/cmd/featuretags/featuretags.go
index f3aae68cc8b17..c3b5b53f0174b 100644
--- a/cmd/featuretags/featuretags.go
+++ b/cmd/featuretags/featuretags.go
@@ -8,13 +8,13 @@ package main
import (
"flag"
"fmt"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
- "maps"
- "slices"
"strings"
- "tailscale.com/feature/featuretags"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/feature/featuretags"
+ "github.com/metacubex/tailscale/util/set"
)
var (
diff --git a/cmd/get-authkey/main.go b/cmd/get-authkey/main.go
index da98decda6ae5..83fb64e712b53 100644
--- a/cmd/get-authkey/main.go
+++ b/cmd/get-authkey/main.go
@@ -2,21 +2,21 @@
// SPDX-License-Identifier: BSD-3-Clause
// get-authkey allocates an authkey using an OAuth API client
-// https://tailscale.com/s/oauth-clients and prints it
+// https://github.com/metacubex/tailscale/s/oauth-clients and prints it
// to stdout for scripts to capture and use.
package main
import (
- "cmp"
"context"
"flag"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"log"
"os"
"strings"
+ "github.com/metacubex/tailscale/internal/client/tailscale"
"golang.org/x/oauth2/clientcredentials"
- "tailscale.com/internal/client/tailscale"
)
func main() {
diff --git a/cmd/gitops-pusher/gitops-pusher.go b/cmd/gitops-pusher/gitops-pusher.go
index 9ea115a1585e7..9ca0b36c409ad 100644
--- a/cmd/gitops-pusher/gitops-pusher.go
+++ b/cmd/gitops-pusher/gitops-pusher.go
@@ -22,13 +22,13 @@ import (
"sync"
"time"
+ tsclient "github.com/metacubex/tailscale/client/tailscale"
+ _ "github.com/metacubex/tailscale/feature/identityfederation"
+ "github.com/metacubex/tailscale/internal/client/tailscale"
+ "github.com/metacubex/tailscale/util/httpm"
"github.com/peterbourgon/ff/v3/ffcli"
"github.com/tailscale/hujson"
"golang.org/x/oauth2/clientcredentials"
- tsclient "tailscale.com/client/tailscale"
- _ "tailscale.com/feature/identityfederation"
- "tailscale.com/internal/client/tailscale"
- "tailscale.com/util/httpm"
)
var (
diff --git a/cmd/gitops-pusher/gitops-pusher_test.go b/cmd/gitops-pusher/gitops-pusher_test.go
index 8d785e8cf793a..802ac20533e76 100644
--- a/cmd/gitops-pusher/gitops-pusher_test.go
+++ b/cmd/gitops-pusher/gitops-pusher_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,7 +10,7 @@ import (
"strings"
"testing"
- "tailscale.com/client/tailscale"
+ "github.com/metacubex/tailscale/client/tailscale"
)
func TestEmbeddedTypeUnmarshal(t *testing.T) {
diff --git a/cmd/hello/hello.go b/cmd/hello/hello.go
index 45eb7751c3790..f5e35b176414a 100644
--- a/cmd/hello/hello.go
+++ b/cmd/hello/hello.go
@@ -2,12 +2,12 @@
// SPDX-License-Identifier: BSD-3-Clause
// The hello binary runs hello.ts.net.
-package main // import "tailscale.com/cmd/hello"
+package main // import "github.com/metacubex/tailscale/cmd/hello"
import (
"log"
- "tailscale.com/cmd/hello/helloserver"
+ "github.com/metacubex/tailscale/cmd/hello/helloserver"
)
func main() {
diff --git a/cmd/hello/helloserver/helloserver.go b/cmd/hello/helloserver/helloserver.go
index 8d5972b83c8c5..e237b368c905f 100644
--- a/cmd/hello/helloserver/helloserver.go
+++ b/cmd/hello/helloserver/helloserver.go
@@ -13,9 +13,9 @@ import (
"strings"
"time"
- "tailscale.com/client/local"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/tailcfg"
)
//go:embed hello.tmpl.html
diff --git a/cmd/jsonimports/format.go b/cmd/jsonimports/format.go
index e990d0e6745c3..bbcd192246687 100644
--- a/cmd/jsonimports/format.go
+++ b/cmd/jsonimports/format.go
@@ -5,27 +5,27 @@ package main
import (
"bytes"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"go/ast"
"go/format"
"go/parser"
"go/token"
"go/types"
"path"
- "slices"
"strconv"
"strings"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/util/must"
)
// mustFormatFile formats a Go source file and adjust "json" imports.
// It panics if there are any parsing errors.
//
// - "encoding/json" is imported under the name "jsonv1" or "jsonv1std"
-// - "encoding/json/v2" is rewritten to import "github.com/go-json-experiment/json" instead
-// - "encoding/json/jsontext" is rewritten to import "github.com/go-json-experiment/json/jsontext" instead
-// - "github.com/go-json-experiment/json" is imported under the name "jsonv2"
-// - "github.com/go-json-experiment/json/v1" is imported under the name "jsonv1"
+// - "encoding/json/v2" is rewritten to import "github.com/metacubex/jsonv2" instead
+// - "encoding/json/jsontext" is rewritten to import "github.com/metacubex/jsonv2/jsontext" instead
+// - "github.com/metacubex/jsonv2" is imported under the name "jsonv2"
+// - "github.com/metacubex/jsonv2/v1" is imported under the name "jsonv1"
//
// If no changes to the file is made, it returns input.
func mustFormatFile(in []byte) (out []byte) {
@@ -40,9 +40,9 @@ func mustFormatFile(in []byte) (out []byte) {
"encoding/json",
"encoding/json/v2",
"encoding/json/jsontext",
- "github.com/go-json-experiment/json",
- "github.com/go-json-experiment/json/v1",
- "github.com/go-json-experiment/json/jsontext":
+ "github.com/metacubex/jsonv2",
+ "github.com/metacubex/jsonv2/v1",
+ "github.com/metacubex/jsonv2/jsontext":
jsonImports[pkgPath] = append(jsonImports[pkgPath], imp)
}
}
@@ -57,15 +57,15 @@ func mustFormatFile(in []byte) (out []byte) {
Error: func(err error) {},
}).Check("", fset, []*ast.File{f}, typeInfo)
- // Rewrite imports to instead use "github.com/go-json-experiment/json".
+ // Rewrite imports to instead use "github.com/metacubex/jsonv2".
// This ensures that code continues to build even if
// goexperiment.jsonv2 is *not* specified.
- // As of https://github.com/go-json-experiment/json/pull/186,
- // imports to "github.com/go-json-experiment/json" are identical
+ // As of https://github.com/metacubex/jsonv2/pull/186,
+ // imports to "github.com/metacubex/jsonv2" are identical
// to the standard library if built with goexperiment.jsonv2.
for fromPath, toPath := range map[string]string{
- "encoding/json/v2": "github.com/go-json-experiment/json",
- "encoding/json/jsontext": "github.com/go-json-experiment/json/jsontext",
+ "encoding/json/v2": "github.com/metacubex/jsonv2",
+ "encoding/json/jsontext": "github.com/metacubex/jsonv2/jsontext",
} {
for _, imp := range jsonImports[fromPath] {
imp.Path.Value = strconv.Quote(toPath)
@@ -85,14 +85,14 @@ func mustFormatFile(in []byte) (out []byte) {
switch pkgPath {
case "encoding/json":
newName = "jsonv1"
- // If "github.com/go-json-experiment/json/v1" is also imported,
+ // If "github.com/metacubex/jsonv2/v1" is also imported,
// then use jsonv1std for "encoding/json" to avoid a conflict.
- if len(jsonImports["github.com/go-json-experiment/json/v1"]) > 0 {
+ if len(jsonImports["github.com/metacubex/jsonv2/v1"]) > 0 {
newName += "std"
}
- case "github.com/go-json-experiment/json":
+ case "github.com/metacubex/jsonv2":
newName = "jsonv2"
- case "github.com/go-json-experiment/json/v1":
+ case "github.com/metacubex/jsonv2/v1":
newName = "jsonv1"
}
diff --git a/cmd/jsonimports/format_test.go b/cmd/jsonimports/format_test.go
index fb3d6fa09698d..d37222700c8ab 100644
--- a/cmd/jsonimports/format_test.go
+++ b/cmd/jsonimports/format_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,8 +9,8 @@ import (
"go/format"
"testing"
- "tailscale.com/util/must"
- "tailscale.com/util/safediff"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/safediff"
)
func TestFormatFile(t *testing.T) {
@@ -17,7 +19,7 @@ func TestFormatFile(t *testing.T) {
import (
"encoding/json"
- jsonv2exp "github.com/go-json-experiment/json"
+ jsonv2exp "github.com/metacubex/jsonv2"
)
func main() {
@@ -33,7 +35,7 @@ func TestFormatFile(t *testing.T) {
import (
jsonv1 "encoding/json"
- jsonv2 "github.com/go-json-experiment/json"
+ jsonv2 "github.com/metacubex/jsonv2"
)
func main() {
@@ -49,8 +51,8 @@ func TestFormatFile(t *testing.T) {
in: `package foobar
import (
- "github.com/go-json-experiment/json"
- jsonv2exp "github.com/go-json-experiment/json"
+ "github.com/metacubex/jsonv2"
+ jsonv2exp "github.com/metacubex/jsonv2"
)
func main() {
@@ -60,7 +62,7 @@ func TestFormatFile(t *testing.T) {
`,
want: `package foobar
import (
- jsonv2 "github.com/go-json-experiment/json"
+ jsonv2 "github.com/metacubex/jsonv2"
)
func main() {
jsonv2.Marshal()
@@ -69,13 +71,13 @@ func TestFormatFile(t *testing.T) {
`,
}, {
in: `package foobar
- import "github.com/go-json-experiment/json/v1"
+ import "github.com/metacubex/jsonv2/v1"
func main() {
json.Marshal()
}
`,
want: `package foobar
- import jsonv1 "github.com/go-json-experiment/json/v1"
+ import jsonv1 "github.com/metacubex/jsonv2/v1"
func main() {
jsonv1.Marshal()
}
@@ -84,7 +86,7 @@ func TestFormatFile(t *testing.T) {
in: `package foobar
import (
"encoding/json"
- jsonv1in2 "github.com/go-json-experiment/json/v1"
+ jsonv1in2 "github.com/metacubex/jsonv2/v1"
)
func main() {
json.Marshal()
@@ -94,7 +96,7 @@ func TestFormatFile(t *testing.T) {
want: `package foobar
import (
jsonv1std "encoding/json"
- jsonv1 "github.com/go-json-experiment/json/v1"
+ jsonv1 "github.com/metacubex/jsonv2/v1"
)
func main() {
jsonv1std.Marshal()
@@ -105,7 +107,7 @@ func TestFormatFile(t *testing.T) {
in: `package foobar
import (
"encoding/json"
- jsonv1in2 "github.com/go-json-experiment/json/v1"
+ jsonv1in2 "github.com/metacubex/jsonv2/v1"
)
func main() {
json.Marshal()
@@ -115,7 +117,7 @@ func TestFormatFile(t *testing.T) {
want: `package foobar
import (
jsonv1std "encoding/json"
- jsonv1 "github.com/go-json-experiment/json/v1"
+ jsonv1 "github.com/metacubex/jsonv2/v1"
)
func main() {
jsonv1std.Marshal()
@@ -138,8 +140,8 @@ func TestFormatFile(t *testing.T) {
want: `package foobar
import (
jsonv1 "encoding/json"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
)
func main() {
jsonv1.Marshal()
diff --git a/cmd/jsonimports/jsonimports.go b/cmd/jsonimports/jsonimports.go
index 6903844e121ca..963687de9b8e2 100644
--- a/cmd/jsonimports/jsonimports.go
+++ b/cmd/jsonimports/jsonimports.go
@@ -11,9 +11,9 @@
// - "encoding/json"
// - "encoding/json/v2"
// - "encoding/json/jsontext"
-// - "github.com/go-json-experiment/json/v1"
-// - "github.com/go-json-experiment/json"
-// - "github.com/go-json-experiment/json/jsontext"
+// - "github.com/metacubex/jsonv2/v1"
+// - "github.com/metacubex/jsonv2"
+// - "github.com/metacubex/jsonv2/jsontext"
//
// In order to enforce consistent usage, we apply the following rules:
//
@@ -21,17 +21,17 @@
// and "encoding/json/jsontext" into the standard library
// (i.e., they are no longer considered experimental),
// we forbid any code from directly importing those packages.
-// Go code should instead import "github.com/go-json-experiment/json"
-// and "github.com/go-json-experiment/json/jsontext".
+// Go code should instead import "github.com/metacubex/jsonv2"
+// and "github.com/metacubex/jsonv2/jsontext".
// The latter packages contain aliases to the standard library
// if built on Go 1.25 with the goexperiment.jsonv2 tag specified.
//
-// - Imports of "encoding/json" or "github.com/go-json-experiment/json/v1"
+// - Imports of "encoding/json" or "github.com/metacubex/jsonv2/v1"
// must be explicitly imported under the package name "jsonv1".
// If both packages need to be imported, then the former should
// be imported under the package name "jsonv1std".
//
-// - Imports of "github.com/go-json-experiment/json"
+// - Imports of "github.com/metacubex/jsonv2"
// must be explicitly imported under the package name "jsonv2".
//
// The latter two rules exist to provide clarity when reading code.
@@ -55,9 +55,9 @@ import (
"strings"
"sync"
- "tailscale.com/syncs"
- "tailscale.com/util/must"
- "tailscale.com/util/safediff"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/safediff"
)
func main() {
@@ -118,7 +118,7 @@ func main() {
if numDiffs > 0 && !*update {
fmt.Printf(`%d files with "json" imports that need formatting`+"\n", numDiffs)
fmt.Println("Please run:")
- fmt.Println("\t./tool/go run tailscale.com/cmd/jsonimports -update")
+ fmt.Println("\t./tool/go run github.com/metacubex/tailscale/cmd/jsonimports -update")
os.Exit(1)
}
}
diff --git a/cmd/k8s-nameserver/main.go b/cmd/k8s-nameserver/main.go
index 1b219fb1ab924..1d0adad4dac49 100644
--- a/cmd/k8s-nameserver/main.go
+++ b/cmd/k8s-nameserver/main.go
@@ -21,9 +21,9 @@ import (
"syscall"
"github.com/fsnotify/fsnotify"
+ operatorutils "github.com/metacubex/tailscale/k8s-operator"
+ "github.com/metacubex/tailscale/util/dnsname"
"github.com/miekg/dns"
- operatorutils "tailscale.com/k8s-operator"
- "tailscale.com/util/dnsname"
)
const (
diff --git a/cmd/k8s-nameserver/main_test.go b/cmd/k8s-nameserver/main_test.go
index b5cd8c907d522..5b2cae1d0dd38 100644
--- a/cmd/k8s-nameserver/main_test.go
+++ b/cmd/k8s-nameserver/main_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
@@ -10,8 +10,8 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
+ "github.com/metacubex/tailscale/util/dnsname"
"github.com/miekg/dns"
- "tailscale.com/util/dnsname"
)
func TestNameserver(t *testing.T) {
diff --git a/cmd/k8s-operator/api-server-proxy-pg.go b/cmd/k8s-operator/api-server-proxy-pg.go
index ac2f7357768fc..fdc80f601ac4c 100644
--- a/cmd/k8s-operator/api-server-proxy-pg.go
+++ b/cmd/k8s-operator/api-server-proxy-pg.go
@@ -10,8 +10,8 @@ import (
"encoding/json"
"errors"
"fmt"
- "maps"
- "slices"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
"go.uber.org/zap"
@@ -25,17 +25,17 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"tailscale.com/client/tailscale/v2"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/kube/k8s-proxy/conf"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/kube/k8s-proxy/conf"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
)
const (
- proxyPGFinalizerName = "tailscale.com/kube-apiserver-finalizer"
+ proxyPGFinalizerName = "github.com/metacubex/tailscale/kube-apiserver-finalizer"
// Reasons for KubeAPIServerProxyValid condition.
reasonKubeAPIServerProxyInvalid = "KubeAPIServerProxyInvalid"
diff --git a/cmd/k8s-operator/api-server-proxy-pg_test.go b/cmd/k8s-operator/api-server-proxy-pg_test.go
index 889ef064b05d9..216460ab85010 100644
--- a/cmd/k8s-operator/api-server-proxy-pg_test.go
+++ b/cmd/k8s-operator/api-server-proxy-pg_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -18,14 +20,14 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"tailscale.com/client/tailscale/v2"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/kube/k8s-proxy/conf"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/types/opt"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/kube/k8s-proxy/conf"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/opt"
)
func TestAPIServerProxyReconciler(t *testing.T) {
diff --git a/cmd/k8s-operator/api-server-proxy.go b/cmd/k8s-operator/api-server-proxy.go
index b8d87cf0aa38a..f31f7bf333c15 100644
--- a/cmd/k8s-operator/api-server-proxy.go
+++ b/cmd/k8s-operator/api-server-proxy.go
@@ -10,7 +10,7 @@ import (
"log"
"os"
- "tailscale.com/kube/kubetypes"
+ "github.com/metacubex/tailscale/kube/kubetypes"
)
func parseAPIProxyMode() *kubetypes.APIServerProxyMode {
diff --git a/cmd/k8s-operator/connector.go b/cmd/k8s-operator/connector.go
index 0c2d32482e78b..b43cc7f307442 100644
--- a/cmd/k8s-operator/connector.go
+++ b/cmd/k8s-operator/connector.go
@@ -9,8 +9,8 @@ import (
"context"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
"strings"
"sync"
"time"
@@ -26,12 +26,12 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tstime"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/set"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/set"
)
const (
diff --git a/cmd/k8s-operator/connector_test.go b/cmd/k8s-operator/connector_test.go
index 69e8e287d07d1..dd3de9157f53c 100644
--- a/cmd/k8s-operator/connector_test.go
+++ b/cmd/k8s-operator/connector_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
@@ -20,11 +20,11 @@ import (
"k8s.io/client-go/tools/record"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tstest"
- "tailscale.com/util/mak"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/util/mak"
)
func TestConnector(t *testing.T) {
@@ -37,7 +37,7 @@ func TestConnector(t *testing.T) {
},
TypeMeta: metav1.TypeMeta{
Kind: tsapi.ConnectorKind,
- APIVersion: "tailscale.com/v1alpha1",
+ APIVersion: "github.com/metacubex/tailscale/v1alpha1",
},
Spec: tsapi.ConnectorSpec{
Replicas: new(int32(1)),
@@ -97,7 +97,7 @@ func TestConnector(t *testing.T) {
mak.Set(&secret.Data, "device_ips", []byte(`["127.0.0.1", "::1"]`))
})
expectReconciled(t, cr, "", "test")
- cn.Finalizers = append(cn.Finalizers, "tailscale.com/finalizer")
+ cn.Finalizers = append(cn.Finalizers, "github.com/metacubex/tailscale/finalizer")
cn.Status.IsExitNode = cn.Spec.ExitNode
cn.Status.SubnetRoutes = cn.Spec.SubnetRouter.AdvertiseRoutes.Stringify()
cn.Status.Hostname = hostname
@@ -373,7 +373,7 @@ func TestConnectorWithAppConnector(t *testing.T) {
expectEqual(t, fc, expectedSTS(t, fc, opts), removeResourceReqs)
// Connector's ready condition should be set to true
- cn.ObjectMeta.Finalizers = append(cn.ObjectMeta.Finalizers, "tailscale.com/finalizer")
+ cn.ObjectMeta.Finalizers = append(cn.ObjectMeta.Finalizers, "github.com/metacubex/tailscale/finalizer")
cn.Status.IsAppConnector = true
cn.Status.Devices = []tsapi.ConnectorDevice{}
cn.Status.Conditions = []metav1.Condition{{
diff --git a/cmd/k8s-operator/depaware.txt b/cmd/k8s-operator/depaware.txt
index 12073da0be581..1a15b2e2b4d90 100644
--- a/cmd/k8s-operator/depaware.txt
+++ b/cmd/k8s-operator/depaware.txt
@@ -36,12 +36,12 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
github.com/gaissmai/bart/internal/nodes from github.com/gaissmai/bart
github.com/gaissmai/bart/internal/sparse from github.com/gaissmai/bart/internal/nodes
github.com/gaissmai/bart/internal/value from github.com/gaissmai/bart+
- github.com/go-json-experiment/json from tailscale.com/types/opt+
- github.com/go-json-experiment/json/internal from github.com/go-json-experiment/json/internal/jsonflags+
- github.com/go-json-experiment/json/internal/jsonflags from github.com/go-json-experiment/json/internal/jsonopts+
- github.com/go-json-experiment/json/internal/jsonopts from github.com/go-json-experiment/json/jsontext+
- github.com/go-json-experiment/json/internal/jsonwire from github.com/go-json-experiment/json/jsontext+
- github.com/go-json-experiment/json/jsontext from tailscale.com/logtail+
+ github.com/metacubex/jsonv2 from tailscale.com/types/opt+
+ github.com/metacubex/jsonv2/internal from github.com/metacubex/jsonv2/internal/jsonflags+
+ github.com/metacubex/jsonv2/internal/jsonflags from github.com/metacubex/jsonv2/internal/jsonopts+
+ github.com/metacubex/jsonv2/internal/jsonopts from github.com/metacubex/jsonv2/jsontext+
+ github.com/metacubex/jsonv2/internal/jsonwire from github.com/metacubex/jsonv2/jsontext+
+ github.com/metacubex/jsonv2/jsontext from tailscale.com/logtail+
github.com/go-logr/logr from github.com/go-logr/logr/slogr+
github.com/go-logr/logr/slogr from github.com/go-logr/zapr
github.com/go-logr/zapr from sigs.k8s.io/controller-runtime/pkg/log/zap+
diff --git a/cmd/k8s-operator/dnsrecords.go b/cmd/k8s-operator/dnsrecords.go
index e75bcd4c2e1da..eb11c8239a76d 100644
--- a/cmd/k8s-operator/dnsrecords.go
+++ b/cmd/k8s-operator/dnsrecords.go
@@ -9,9 +9,13 @@ import (
"context"
"encoding/json"
"fmt"
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
+ operatorutils "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
"go.uber.org/zap"
corev1 "k8s.io/api/core/v1"
discoveryv1 "k8s.io/api/discovery/v1"
@@ -22,15 +26,11 @@ import (
"k8s.io/utils/net"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
- operatorutils "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
)
const (
- dnsRecordsRecocilerFinalizer = "tailscale.com/dns-records-reconciler"
- annotationTSMagicDNSName = "tailscale.com/magic-dnsname"
+ dnsRecordsRecocilerFinalizer = "github.com/metacubex/tailscale/dns-records-reconciler"
+ annotationTSMagicDNSName = "github.com/metacubex/tailscale/magic-dnsname"
// Service types for consistent string usage
serviceTypeIngress = "ingress"
@@ -42,11 +42,11 @@ const (
// The records that it creates are:
// - For tailscale Ingress, a mapping of the Ingress's MagicDNSName to the IP addresses
// (both IPv4 and IPv6) of the ingress proxy Pod.
-// - For egress proxies configured via tailscale.com/tailnet-fqdn annotation, a
+// - For egress proxies configured via github.com/metacubex/tailscale/tailnet-fqdn annotation, a
// mapping of the tailnet FQDN to the IP addresses (both IPv4 and IPv6) of the egress proxy Pod.
//
// Records will only be created if there is exactly one ready
-// tailscale.com/v1alpha1.DNSConfig instance in the cluster (so that we know
+// github.com/metacubex/tailscale/v1alpha1.DNSConfig instance in the cluster (so that we know
// that there is a ts.net nameserver deployed in the cluster).
type dnsRecordsReconciler struct {
client.Client
@@ -83,7 +83,7 @@ func (dnsRR *dnsRecordsReconciler) Reconcile(ctx context.Context, req reconcile.
}
// Check that there is a ts.net nameserver deployed to the cluster by
- // checking that there is tailscale.com/v1alpha1.DNSConfig resource in a
+ // checking that there is github.com/metacubex/tailscale/v1alpha1.DNSConfig resource in a
// Ready state.
dnsCfgLst := new(tsapi.DNSConfigList)
if err = dnsRR.List(ctx, dnsCfgLst); err != nil {
@@ -117,24 +117,24 @@ func (dnsRR *dnsRecordsReconciler) Reconcile(ctx context.Context, req reconcile.
// maybeProvision ensures that dnsrecords ConfigMap contains a record for the
// proxy associated with the Service.
// The record is only provisioned if the proxy is for a tailscale Ingress or
-// egress configured via tailscale.com/tailnet-fqdn annotation.
+// egress configured via github.com/metacubex/tailscale/tailnet-fqdn annotation.
//
// For Ingress, the record is a mapping between the MagicDNSName of the Ingress, retrieved from
// ingress.status.loadBalancer.ingress.hostname field and the proxy Pod IP addresses
// retrieved from the EndpointSlice associated with this Service, i.e
// Records{IP4: {: <[IPv4 addresses]>}, IP6: {: <[IPv6 addresses]>}}
//
-// For egress, the record is a mapping between tailscale.com/tailnet-fqdn
+// For egress, the record is a mapping between github.com/metacubex/tailscale/tailnet-fqdn
// annotation and the proxy Pod IP addresses, retrieved from the EndpointSlice
// associated with this Service, i.e
// Records{IP4: {: <[IPv4 addresses]>}, IP6: {: <[IPv6 addresses]>}}
//
-// For ProxyGroup egress, the record is a mapping between tailscale.com/magic-dnsname
+// For ProxyGroup egress, the record is a mapping between github.com/metacubex/tailscale/magic-dnsname
// annotation and the ClusterIP Service IPs (which provides portmapping), i.e
// Records{IP4: {: <[IPv4 ClusterIPs]>}, IP6: {: <[IPv6 ClusterIPs]>}}
//
// If records need to be created for this proxy, maybeProvision will also:
-// - update the Service with a tailscale.com/magic-dnsname annotation
+// - update the Service with a github.com/metacubex/tailscale/magic-dnsname annotation
// - update the Service with a finalizer
func (dnsRR *dnsRecordsReconciler) maybeProvision(ctx context.Context, proxySvc *corev1.Service, logger *zap.SugaredLogger) error {
if !dnsRR.isInterestingService(ctx, proxySvc) {
@@ -160,7 +160,7 @@ func (dnsRR *dnsRecordsReconciler) maybeProvision(ctx context.Context, proxySvc
// name to help with records cleanup when proxy resources are deleted or
// MagicDNS name changes.
oldFqdn := proxySvc.Annotations[annotationTSMagicDNSName]
- if oldFqdn != "" && oldFqdn != fqdn { // i.e user has changed the value of tailscale.com/tailnet-fqdn annotation
+ if oldFqdn != "" && oldFqdn != fqdn { // i.e user has changed the value of github.com/metacubex/tailscale/tailnet-fqdn annotation
logger.Debugf("MagicDNS name has changed, removing record for %s", oldFqdn)
updateFunc := func(rec *operatorutils.Records) {
delete(rec.IP4, oldFqdn)
@@ -213,10 +213,10 @@ func epIsReady(ep *discoveryv1.Endpoint) bool {
}
// maybeCleanup ensures that the DNS record for the proxy has been removed from
-// dnsrecords ConfigMap and the tailscale.com/dns-records-reconciler finalizer
+// dnsrecords ConfigMap and the github.com/metacubex/tailscale/dns-records-reconciler finalizer
// has been removed from the Service. If the record is not found in the
// ConfigMap, the ConfigMap does not exist, or the Service does not have
-// tailscale.com/magic-dnsname annotation, just remove the finalizer.
+// github.com/metacubex/tailscale/magic-dnsname annotation, just remove the finalizer.
func (dnsRR *dnsRecordsReconciler) maybeCleanup(ctx context.Context, proxySvc *corev1.Service, logger *zap.SugaredLogger) error {
ix := slices.Index(proxySvc.Finalizers, dnsRecordsRecocilerFinalizer)
if ix == -1 {
@@ -269,7 +269,7 @@ func (dnsRR *dnsRecordsReconciler) removeProxySvcFinalizer(ctx context.Context,
// fqdnForDNSRecord returns MagicDNS name associated with a given proxy Service.
// If the proxy Service is for a tailscale Ingress proxy, returns ingress.status.loadBalancer.ingress.hostname.
-// If the proxy Service is for an tailscale egress proxy configured via tailscale.com/tailnet-fqdn annotation, returns the annotation value.
+// If the proxy Service is for an tailscale egress proxy configured via github.com/metacubex/tailscale/tailnet-fqdn annotation, returns the annotation value.
// For ProxyGroup egress Services, returns the tailnet-fqdn annotation from the parent Service.
// This function is not expected to be called with proxy Services for other
// proxy types, or any other Services, but it just returns an empty string if
@@ -329,7 +329,7 @@ func (dnsRR *dnsRecordsReconciler) updateDNSConfig(ctx context.Context, update f
// isSvcForFQDNEgressProxy returns true if the Service is a headless Service
// created for a proxy for a tailscale egress Service configured via
-// tailscale.com/tailnet-fqdn annotation.
+// github.com/metacubex/tailscale/tailnet-fqdn annotation.
func (dnsRR *dnsRecordsReconciler) isSvcForFQDNEgressProxy(ctx context.Context, svc *corev1.Service) (bool, error) {
if !isManagedByType(svc, "svc") {
return false, nil
diff --git a/cmd/k8s-operator/dnsrecords_test.go b/cmd/k8s-operator/dnsrecords_test.go
index c6c5ee0296ca3..1270630f72326 100644
--- a/cmd/k8s-operator/dnsrecords_test.go
+++ b/cmd/k8s-operator/dnsrecords_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
@@ -12,6 +12,10 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
+ operatorutils "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tstest"
"go.uber.org/zap"
corev1 "k8s.io/api/core/v1"
discoveryv1 "k8s.io/api/discovery/v1"
@@ -21,10 +25,6 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
- operatorutils "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tstest"
)
func TestDNSRecordsReconciler(t *testing.T) {
@@ -76,12 +76,12 @@ func TestDNSRecordsReconciler(t *testing.T) {
}
// 1. DNS record is created for an egress proxy configured via
- // tailscale.com/tailnet-fqdn annotation
+ // github.com/metacubex/tailscale/tailnet-fqdn annotation
egressSvcFQDN := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "egress-fqdn",
Namespace: "test",
- Annotations: map[string]string{"tailscale.com/tailnet-fqdn": "foo.bar.ts.net"},
+ Annotations: map[string]string{"github.com/metacubex/tailscale/tailnet-fqdn": "foo.bar.ts.net"},
},
Spec: corev1.ServiceSpec{
ExternalName: "unused",
@@ -102,10 +102,10 @@ func TestDNSRecordsReconciler(t *testing.T) {
wantHostsIPv6 := map[string][]string{"foo.bar.ts.net": {"2600:1900:4011:161:0:d:0:d"}}
expectHostsRecordsWithIPv6(t, fc, wantHosts, wantHostsIPv6)
- // 2. DNS record is updated if tailscale.com/tailnet-fqdn annotation's
+ // 2. DNS record is updated if github.com/metacubex/tailscale/tailnet-fqdn annotation's
// value changes
mustUpdate(t, fc, "test", "egress-fqdn", func(svc *corev1.Service) {
- svc.Annotations["tailscale.com/tailnet-fqdn"] = "baz.bar.ts.net"
+ svc.Annotations["github.com/metacubex/tailscale/tailnet-fqdn"] = "baz.bar.ts.net"
})
expectReconciled(t, dnsRR, "tailscale", "egress-fqdn") // dns-records-reconciler reconcile the headless Service
wantHosts = map[string][]string{"baz.bar.ts.net": {"10.9.8.7"}}
diff --git a/cmd/k8s-operator/e2e/helpers.go b/cmd/k8s-operator/e2e/helpers.go
index e01821c2367e3..bf37a9fd78688 100644
--- a/cmd/k8s-operator/e2e/helpers.go
+++ b/cmd/k8s-operator/e2e/helpers.go
@@ -11,7 +11,7 @@ import (
"strings"
"time"
- "tailscale.com/tsnet"
+ "github.com/metacubex/tailscale/tsnet"
)
func generateName(prefix string) string {
diff --git a/cmd/k8s-operator/e2e/ingress_test.go b/cmd/k8s-operator/e2e/ingress_test.go
index bef24ca5a0a3b..94db492e016a0 100644
--- a/cmd/k8s-operator/e2e/ingress_test.go
+++ b/cmd/k8s-operator/e2e/ingress_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -17,13 +19,13 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
+ kube "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/util/httpm"
"tailscale.com/client/tailscale/v2"
- kube "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tsnet"
- "tailscale.com/tstest"
- "tailscale.com/util/httpm"
)
// See [TestMain] for test requirements.
@@ -41,7 +43,7 @@ func TestL3Ingress(t *testing.T) {
Name: generateName("test-ingress"),
Namespace: ns,
Annotations: map[string]string{
- "tailscale.com/expose": "true",
+ "github.com/metacubex/tailscale/expose": "true",
},
},
Spec: corev1.ServiceSpec{
@@ -81,8 +83,8 @@ func TestL3Ingress(t *testing.T) {
if err := kubeClient.List(t.Context(), &secrets,
client.InNamespace("tailscale"),
client.MatchingLabels{
- "tailscale.com/parent-resource": svc.Name,
- "tailscale.com/parent-resource-ns": ns,
+ "github.com/metacubex/tailscale/parent-resource": svc.Name,
+ "github.com/metacubex/tailscale/parent-resource-ns": ns,
},
); err != nil {
return err
@@ -131,7 +133,7 @@ func TestL3HAIngress(t *testing.T) {
Name: generateName("test-ingress"),
Namespace: ns,
Annotations: map[string]string{
- "tailscale.com/proxy-group": pg.Name,
+ "github.com/metacubex/tailscale/proxy-group": pg.Name,
},
},
Spec: corev1.ServiceSpec{
@@ -263,7 +265,7 @@ func TestL7HAIngress(t *testing.T) {
createAndCleanup(t, kubeClient, pg)
// Apply Ingress to expose nginx.
- ingress := l7Ingress(ns, nginx.Name, map[string]string{"tailscale.com/proxy-group": pg.Name})
+ ingress := l7Ingress(ns, nginx.Name, map[string]string{"github.com/metacubex/tailscale/proxy-group": pg.Name})
createAndCleanup(t, kubeClient, ingress)
t.Log("Waiting for the Ingress to be ready...")
@@ -334,7 +336,7 @@ func TestL7HAIngressMultiTailnet(t *testing.T) {
// Apply Ingress to expose nginx.
ingress := l7Ingress(ns, nginx.Name, map[string]string{
- "tailscale.com/proxy-group": secondTailnetPG.Name,
+ "github.com/metacubex/tailscale/proxy-group": secondTailnetPG.Name,
})
createAndCleanup(t, kubeClient, ingress)
@@ -457,7 +459,7 @@ func triggerReconcile(t testing.TB, key client.ObjectKey, obj client.Object, aft
if ann == nil {
ann = map[string]string{}
}
- ann["tailscale.com/trigger-reconcile"] = "true"
+ ann["github.com/metacubex/tailscale/trigger-reconcile"] = "true"
obj.SetAnnotations(ann)
if err := kubeClient.Update(t.Context(), obj); err != nil {
t.Logf("failed to update %s: %v", key, err)
@@ -517,9 +519,9 @@ func verifyProxyGroupTailnet(t *testing.T, pg *tsapi.ProxyGroup, cl *tsnet.Serve
if err := kubeClient.List(t.Context(), &secrets,
client.InNamespace("tailscale"),
client.MatchingLabels{
- kubetypes.LabelSecretType: kubetypes.LabelSecretTypeState,
- "tailscale.com/parent-resource-type": "proxygroup",
- "tailscale.com/parent-resource": pg.Name,
+ kubetypes.LabelSecretType: kubetypes.LabelSecretTypeState,
+ "github.com/metacubex/tailscale/parent-resource-type": "proxygroup",
+ "github.com/metacubex/tailscale/parent-resource": pg.Name,
},
); err != nil {
return err
diff --git a/cmd/k8s-operator/e2e/main_test.go b/cmd/k8s-operator/e2e/main_test.go
index 9eab9e30157aa..a360aeb1d3fe0 100644
--- a/cmd/k8s-operator/e2e/main_test.go
+++ b/cmd/k8s-operator/e2e/main_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/cmd/k8s-operator/e2e/proxy_test.go b/cmd/k8s-operator/e2e/proxy_test.go
index 3caf1c91d8bc9..c59fa298e889a 100644
--- a/cmd/k8s-operator/e2e/proxy_test.go
+++ b/cmd/k8s-operator/e2e/proxy_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -15,8 +17,8 @@ import (
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
- "tailscale.com/ipn"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tstest"
)
// See [TestMain] for test requirements.
diff --git a/cmd/k8s-operator/e2e/proxygrouppolicy_test.go b/cmd/k8s-operator/e2e/proxygrouppolicy_test.go
index 0e73394d539da..3a1d42758647a 100644
--- a/cmd/k8s-operator/e2e/proxygrouppolicy_test.go
+++ b/cmd/k8s-operator/e2e/proxygrouppolicy_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,7 +14,7 @@ import (
networkingv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
)
// See [TestMain] for test requirements.
@@ -43,8 +45,8 @@ func TestProxyGroupPolicy(t *testing.T) {
Name: "egress-to-proxy-group",
Namespace: metav1.NamespaceDefault,
Annotations: map[string]string{
- "tailscale.com/tailnet-fqdn": "test.something.ts.net",
- "tailscale.com/proxy-group": "test",
+ "github.com/metacubex/tailscale/tailnet-fqdn": "test.something.ts.net",
+ "github.com/metacubex/tailscale/proxy-group": "test",
},
},
Spec: corev1.ServiceSpec{
@@ -76,7 +78,7 @@ func TestProxyGroupPolicy(t *testing.T) {
Name: "ingress-to-proxy-group",
Namespace: metav1.NamespaceDefault,
Annotations: map[string]string{
- "tailscale.com/proxy-group": "test",
+ "github.com/metacubex/tailscale/proxy-group": "test",
},
},
Spec: corev1.ServiceSpec{
@@ -107,7 +109,7 @@ func TestProxyGroupPolicy(t *testing.T) {
Name: "ingress-to-proxy-group",
Namespace: metav1.NamespaceDefault,
Annotations: map[string]string{
- "tailscale.com/proxy-group": "test",
+ "github.com/metacubex/tailscale/proxy-group": "test",
},
},
Spec: networkingv1.IngressSpec{
diff --git a/cmd/k8s-operator/e2e/setup.go b/cmd/k8s-operator/e2e/setup.go
index 0d4ca80ad68f9..2cccf5f5bb70f 100644
--- a/cmd/k8s-operator/e2e/setup.go
+++ b/cmd/k8s-operator/e2e/setup.go
@@ -13,6 +13,7 @@ import (
"encoding/json"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net/http"
"net/url"
@@ -20,7 +21,6 @@ import (
"os/exec"
"os/signal"
"path/filepath"
- "slices"
"strings"
"sync"
"syscall"
@@ -54,13 +54,13 @@ import (
"sigs.k8s.io/kind/pkg/cluster/nodeutils"
"sigs.k8s.io/kind/pkg/cmd"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/util/must"
"tailscale.com/client/tailscale/v2"
- "tailscale.com/ipn"
- "tailscale.com/ipn/store/mem"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/tsnet"
- "tailscale.com/util/must"
)
const (
@@ -419,7 +419,7 @@ func runTests(m *testing.M) (int, error) {
}
// Generate CRDs for the helm chart.
- cmd := exec.CommandContext(ctx, "go", "run", "tailscale.com/cmd/k8s-operator/generate", "helmcrd")
+ cmd := exec.CommandContext(ctx, "go", "run", "github.com/metacubex/tailscale/cmd/k8s-operator/generate", "helmcrd")
cmd.Dir = ossDir
out, err := cmd.CombinedOutput()
if err != nil {
diff --git a/cmd/k8s-operator/e2e/ssh.go b/cmd/k8s-operator/e2e/ssh.go
index 9adcce6e3eee0..d1ec6dacd1175 100644
--- a/cmd/k8s-operator/e2e/ssh.go
+++ b/cmd/k8s-operator/e2e/ssh.go
@@ -25,7 +25,7 @@ import (
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
- tailscaleroot "tailscale.com"
+ tailscaleroot "github.com/metacubex/tailscale"
)
const (
diff --git a/cmd/k8s-operator/egress-eps.go b/cmd/k8s-operator/egress-eps.go
index 9f8510165bea9..41936d4c912e2 100644
--- a/cmd/k8s-operator/egress-eps.go
+++ b/cmd/k8s-operator/egress-eps.go
@@ -21,7 +21,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
- "tailscale.com/kube/egressservices"
+ "github.com/metacubex/tailscale/kube/egressservices"
)
// egressEpsReconciler reconciles EndpointSlices for tailnet services exposed to cluster via egress ProxyGroup proxies.
diff --git a/cmd/k8s-operator/egress-eps_test.go b/cmd/k8s-operator/egress-eps_test.go
index 6335b4eb8454b..0bcdcc522981f 100644
--- a/cmd/k8s-operator/egress-eps_test.go
+++ b/cmd/k8s-operator/egress-eps_test.go
@@ -1,27 +1,27 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
"encoding/json"
"fmt"
- "math/rand/v2"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"testing"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/kube/egressservices"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/util/mak"
"go.uber.org/zap"
corev1 "k8s.io/api/core/v1"
discoveryv1 "k8s.io/api/discovery/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/kube/egressservices"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tstest"
- "tailscale.com/util/mak"
)
func TestTailscaleEgressEndpointSlices(t *testing.T) {
diff --git a/cmd/k8s-operator/egress-pod-readiness.go b/cmd/k8s-operator/egress-pod-readiness.go
index a8f306353d880..9405de991f722 100644
--- a/cmd/k8s-operator/egress-pod-readiness.go
+++ b/cmd/k8s-operator/egress-pod-readiness.go
@@ -9,12 +9,17 @@ import (
"context"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/http"
- "slices"
"strings"
"sync/atomic"
"time"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/backoff"
+ "github.com/metacubex/tailscale/util/httpm"
"go.uber.org/zap"
xslices "golang.org/x/exp/slices"
corev1 "k8s.io/api/core/v1"
@@ -23,16 +28,11 @@ import (
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tstime"
- "tailscale.com/util/backoff"
- "tailscale.com/util/httpm"
)
-const tsEgressReadinessGate = "tailscale.com/egress-services"
+const tsEgressReadinessGate = "github.com/metacubex/tailscale/egress-services"
-// egressPodsReconciler is responsible for setting tailscale.com/egress-services condition on egress ProxyGroup Pods.
+// egressPodsReconciler is responsible for setting github.com/metacubex/tailscale/egress-services condition on egress ProxyGroup Pods.
// The condition is used as a readiness gate for the Pod, meaning that kubelet will not mark the Pod as ready before the
// condition is set. The ProxyGroup StatefulSet updates are rolled out in such a way that no Pod is restarted, before
// the previous Pod is marked as ready, so ensuring that the Pod does not get marked as ready when it is not yet able to
@@ -50,7 +50,7 @@ type egressPodsReconciler struct {
// Reconcile reconciles an egress ProxyGroup Pods on changes to those Pods and ProxyGroup EndpointSlices. It ensures
// that for each Pod who is ready to route traffic to all egress services for the ProxyGroup, the Pod has a
-// tailscale.com/egress-services condition to set, so that kubelet will mark the Pod as ready.
+// github.com/metacubex/tailscale/egress-services condition to set, so that kubelet will mark the Pod as ready.
//
// For the Pod to be ready
// to route traffic to the egress service, the kube proxy needs to have set up the Pod's IP as an endpoint for the
diff --git a/cmd/k8s-operator/egress-pod-readiness_test.go b/cmd/k8s-operator/egress-pod-readiness_test.go
index 0cf9108f5cd20..422e288e22bce 100644
--- a/cmd/k8s-operator/egress-pod-readiness_test.go
+++ b/cmd/k8s-operator/egress-pod-readiness_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
@@ -16,14 +16,14 @@ import (
"testing"
"time"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tstest"
"go.uber.org/zap"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tstest"
)
func TestEgressPodReadiness(t *testing.T) {
diff --git a/cmd/k8s-operator/egress-services-readiness.go b/cmd/k8s-operator/egress-services-readiness.go
index 965dc08f87f1d..184f4ac92e4e0 100644
--- a/cmd/k8s-operator/egress-services-readiness.go
+++ b/cmd/k8s-operator/egress-services-readiness.go
@@ -11,6 +11,9 @@ import (
"fmt"
"strings"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/tstime"
"go.uber.org/zap"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
@@ -20,9 +23,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/tstime"
)
const (
diff --git a/cmd/k8s-operator/egress-services-readiness_test.go b/cmd/k8s-operator/egress-services-readiness_test.go
index 96d76cc4e7252..df177c478f83e 100644
--- a/cmd/k8s-operator/egress-services-readiness_test.go
+++ b/cmd/k8s-operator/egress-services-readiness_test.go
@@ -1,24 +1,24 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
"fmt"
"testing"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstime"
"go.uber.org/zap"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
discoveryv1 "k8s.io/api/discovery/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/tstest"
- "tailscale.com/tstime"
)
func TestEgressServiceReadiness(t *testing.T) {
diff --git a/cmd/k8s-operator/egress-services.go b/cmd/k8s-operator/egress-services.go
index b9a3f8eaba799..6cb674fc9c533 100644
--- a/cmd/k8s-operator/egress-services.go
+++ b/cmd/k8s-operator/egress-services.go
@@ -11,9 +11,9 @@ import (
"encoding/json"
"errors"
"fmt"
- "math/rand/v2"
+ "github.com/metacubex/tailscale/util/go120/randv2"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"reflect"
- "slices"
"strings"
"sync"
@@ -31,14 +31,14 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/kube/egressservices"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tstime"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/kube/egressservices"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
)
const (
@@ -47,9 +47,9 @@ const (
reasonEgressSvcCreationFailed = "EgressSvcCreationFailed"
reasonProxyGroupNotReady = "ProxyGroupNotReady"
- labelProxyGroup = "tailscale.com/proxy-group"
+ labelProxyGroup = "github.com/metacubex/tailscale/proxy-group"
- labelSvcType = "tailscale.com/svc-type" // ingress or egress
+ labelSvcType = "github.com/metacubex/tailscale/svc-type" // ingress or egress
typeEgress = "egress"
// maxPorts is the maximum number of ports that can be exposed on a
// container. In practice this will be ports in range [10000 - 11000). The
@@ -617,8 +617,8 @@ func unusedPort(usedPorts sets.Set[int32]) int32 {
}
// tailnetTargetFromSvc returns a tailnet target for the given egress Service.
-// Service must contain exactly one of tailscale.com/tailnet-ip,
-// tailscale.com/tailnet-fqdn annotations.
+// Service must contain exactly one of github.com/metacubex/tailscale/tailnet-ip,
+// github.com/metacubex/tailscale/tailnet-fqdn annotations.
func tailnetTargetFromSvc(svc *corev1.Service) egressservices.TailnetTarget {
if fqdn := svc.Annotations[AnnotationTailnetTargetFQDN]; fqdn != "" {
return egressservices.TailnetTarget{
diff --git a/cmd/k8s-operator/egress-services_test.go b/cmd/k8s-operator/egress-services_test.go
index a7dd79f7f1f84..cbc4c46352d3d 100644
--- a/cmd/k8s-operator/egress-services_test.go
+++ b/cmd/k8s-operator/egress-services_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
@@ -22,15 +22,15 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/kube/egressservices"
- "tailscale.com/tstest"
- "tailscale.com/tstime"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/kube/egressservices"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstime"
)
func TestTailscaleEgressServices(t *testing.T) {
pg := &tsapi.ProxyGroup{
- TypeMeta: metav1.TypeMeta{Kind: "ProxyGroup", APIVersion: "tailscale.com/v1alpha1"},
+ TypeMeta: metav1.TypeMeta{Kind: "ProxyGroup", APIVersion: "github.com/metacubex/tailscale/v1alpha1"},
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
UID: types.UID("1234-UID"),
@@ -148,7 +148,7 @@ func validateReadyService(t *testing.T, fc client.WithWatch, esr *egressSvcsReco
condition(tsapi.EgressSvcValid, metav1.ConditionTrue, "EgressSvcValid", "EgressSvcValid", clock),
condition(tsapi.EgressSvcConfigured, metav1.ConditionTrue, r, r, clock),
}
- svc.ObjectMeta.Finalizers = []string{"tailscale.com/finalizer"}
+ svc.ObjectMeta.Finalizers = []string{"github.com/metacubex/tailscale/finalizer"}
svc.Spec.ExternalName = fmt.Sprintf("%s.operator-ns.svc.cluster.local", name)
expectEqual(t, fc, svc)
diff --git a/cmd/k8s-operator/generate/main_test.go b/cmd/k8s-operator/generate/main_test.go
index 775d16ba1e827..cbaab9ff56675 100644
--- a/cmd/k8s-operator/generate/main_test.go
+++ b/cmd/k8s-operator/generate/main_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9 && !windows
-
package main
import (
@@ -16,8 +16,8 @@ import (
"testing"
"time"
- "tailscale.com/tstest/nettest"
- "tailscale.com/util/cibuild"
+ "github.com/metacubex/tailscale/tstest/nettest"
+ "github.com/metacubex/tailscale/util/cibuild"
)
func Test_generate(t *testing.T) {
diff --git a/cmd/k8s-operator/ingress-for-pg.go b/cmd/k8s-operator/ingress-for-pg.go
index d6872f6809177..3f558c032b413 100644
--- a/cmd/k8s-operator/ingress-for-pg.go
+++ b/cmd/k8s-operator/ingress-for-pg.go
@@ -10,10 +10,10 @@ import (
"encoding/json"
"errors"
"fmt"
- "maps"
- "math/rand/v2"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ "github.com/metacubex/tailscale/util/go120/randv2"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"reflect"
- "slices"
"strings"
"sync"
"time"
@@ -31,27 +31,27 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"tailscale.com/client/tailscale/v2"
- "tailscale.com/ipn"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tailcfg"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/ipn"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
)
const (
serveConfigKey = "serve-config.json"
// FinalizerNamePG is the finalizer used by the IngressPGReconciler
- FinalizerNamePG = "tailscale.com/ingress-pg-finalizer"
+ FinalizerNamePG = "github.com/metacubex/tailscale/ingress-pg-finalizer"
indexIngressProxyGroup = ".metadata.annotations.ingress-proxy-group"
// annotationHTTPEndpoint can be used to configure the Ingress to expose an HTTP endpoint to tailnet (as
// well as the default HTTPS endpoint).
- annotationHTTPEndpoint = "tailscale.com/http-endpoint"
- labelDomain = "tailscale.com/domain"
+ annotationHTTPEndpoint = "github.com/metacubex/tailscale/http-endpoint"
+ labelDomain = "github.com/metacubex/tailscale/domain"
managedTSServiceComment = "This Tailscale Service is managed by the Tailscale Kubernetes Operator, do not modify"
)
@@ -79,7 +79,7 @@ type HAIngressReconciler struct {
// Reconcile reconciles Ingresses that should be exposed over Tailscale in HA
// mode (on a ProxyGroup). It looks at all Ingresses with
-// tailscale.com/proxy-group annotation. For each such Ingress, it ensures that
+// github.com/metacubex/tailscale/proxy-group annotation. For each such Ingress, it ensures that
// a TailscaleService named after the hostname of the Ingress exists and is up to
// date. It also ensures that the serve config for the ingress ProxyGroup is
// updated to route traffic for the Tailscale Service to the Ingress's backend
@@ -647,7 +647,7 @@ func (r *HAIngressReconciler) shouldExpose(ing *networkingv1.Ingress) bool {
// validateIngress validates that the Ingress is properly configured.
// Currently validates:
-// - Any tags provided via tailscale.com/tags annotation are valid Tailscale ACL tags
+// - Any tags provided via github.com/metacubex/tailscale/tags annotation are valid Tailscale ACL tags
// - The derived hostname is a valid DNS label
// - The referenced ProxyGroup exists and is of type 'ingress'
// - Ingress' TLS block is invalid
@@ -842,7 +842,7 @@ func numberPodsAdvertising(ctx context.Context, cl client.Client, tsNamespace, p
return count, nil
}
-const ownerAnnotation = "tailscale.com/owner-references"
+const ownerAnnotation = "github.com/metacubex/tailscale/owner-references"
// ownerAnnotationValue is the content of the TailscaleService.Annotation[ownerAnnotation] field.
type ownerAnnotationValue struct {
diff --git a/cmd/k8s-operator/ingress-for-pg_test.go b/cmd/k8s-operator/ingress-for-pg_test.go
index 8312dc5f70520..71a533cb3bdd0 100644
--- a/cmd/k8s-operator/ingress-for-pg_test.go
+++ b/cmd/k8s-operator/ingress-for-pg_test.go
@@ -1,17 +1,17 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
"context"
"encoding/json"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"reflect"
- "slices"
"strings"
"testing"
@@ -27,12 +27,12 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"tailscale.com/client/tailscale/v2"
- "tailscale.com/ipn"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/ipn"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tailcfg"
)
func TestIngressPGReconciler(t *testing.T) {
@@ -45,7 +45,7 @@ func TestIngressPGReconciler(t *testing.T) {
Namespace: "default",
UID: types.UID("1234-UID"),
Annotations: map[string]string{
- "tailscale.com/proxy-group": "test-pg",
+ "github.com/metacubex/tailscale/proxy-group": "test-pg",
},
},
Spec: networkingv1.IngressSpec{
@@ -84,7 +84,7 @@ func TestIngressPGReconciler(t *testing.T) {
expectEqual(t, fc, certSecretRoleBinding(pg, "operator-ns", "my-svc.ts.net"))
mustUpdate(t, fc, "default", "test-ingress", func(ing *networkingv1.Ingress) {
- ing.Annotations["tailscale.com/tags"] = "tag:custom,tag:test"
+ ing.Annotations["github.com/metacubex/tailscale/tags"] = "tag:custom,tag:test"
})
expectReconciled(t, ingPGR, "default", "test-ingress")
@@ -112,7 +112,7 @@ func TestIngressPGReconciler(t *testing.T) {
Namespace: "default",
UID: types.UID("5678-UID"),
Annotations: map[string]string{
- "tailscale.com/proxy-group": "test-pg",
+ "github.com/metacubex/tailscale/proxy-group": "test-pg",
},
},
Spec: networkingv1.IngressSpec{
@@ -187,7 +187,7 @@ func TestIngressPGReconciler(t *testing.T) {
// Test Ingress ProxyGroup change
createPGResources(t, fc, "test-pg-second")
mustUpdate(t, fc, "default", "test-ingress", func(ing *networkingv1.Ingress) {
- ing.Annotations["tailscale.com/proxy-group"] = "test-pg-second"
+ ing.Annotations["github.com/metacubex/tailscale/proxy-group"] = "test-pg-second"
})
expectReconciled(t, ingPGR, "default", "test-ingress")
expectEqual(t, fc, certSecretRole("test-pg-second", "operator-ns", "my-svc.ts.net"))
@@ -237,7 +237,7 @@ func TestIngressPGReconciler(t *testing.T) {
Namespace: "default",
UID: types.UID("5678-UID"),
Annotations: map[string]string{
- "tailscale.com/proxy-group": "test-pg",
+ "github.com/metacubex/tailscale/proxy-group": "test-pg",
},
},
Spec: networkingv1.IngressSpec{
@@ -281,7 +281,7 @@ func TestIngressPGReconciler_UpdateIngressHostname(t *testing.T) {
Namespace: "default",
UID: types.UID("1234-UID"),
Annotations: map[string]string{
- "tailscale.com/proxy-group": "test-pg",
+ "github.com/metacubex/tailscale/proxy-group": "test-pg",
},
},
Spec: networkingv1.IngressSpec{
@@ -516,8 +516,8 @@ func TestIngressPGReconciler_HTTPEndpoint(t *testing.T) {
Namespace: "default",
UID: types.UID("1234-UID"),
Annotations: map[string]string{
- "tailscale.com/proxy-group": "test-pg",
- "tailscale.com/http-endpoint": "enabled",
+ "github.com/metacubex/tailscale/proxy-group": "test-pg",
+ "github.com/metacubex/tailscale/http-endpoint": "enabled",
},
},
Spec: networkingv1.IngressSpec{
@@ -593,7 +593,7 @@ func TestIngressPGReconciler_HTTPEndpoint(t *testing.T) {
// Remove HTTP endpoint annotation
mustUpdate(t, fc, "default", "test-ingress", func(ing *networkingv1.Ingress) {
- delete(ing.Annotations, "tailscale.com/http-endpoint")
+ delete(ing.Annotations, "github.com/metacubex/tailscale/http-endpoint")
})
// Verify reconciliation after removing HTTP
@@ -647,8 +647,8 @@ func TestIngressPGReconciler_HTTPRedirect(t *testing.T) {
Namespace: "default",
UID: types.UID("1234-UID"),
Annotations: map[string]string{
- "tailscale.com/proxy-group": "test-pg",
- "tailscale.com/http-redirect": "true",
+ "github.com/metacubex/tailscale/proxy-group": "test-pg",
+ "github.com/metacubex/tailscale/http-redirect": "true",
},
},
Spec: networkingv1.IngressSpec{
@@ -719,7 +719,7 @@ func TestIngressPGReconciler_HTTPRedirect(t *testing.T) {
// Remove HTTP redirect annotation
mustUpdate(t, fc, "default", "test-ingress", func(ing *networkingv1.Ingress) {
- delete(ing.Annotations, "tailscale.com/http-redirect")
+ delete(ing.Annotations, "github.com/metacubex/tailscale/http-redirect")
})
// Verify reconciliation after removing HTTP redirect
@@ -772,9 +772,9 @@ func TestIngressPGReconciler_HTTPEndpointAndRedirectConflict(t *testing.T) {
Namespace: "default",
UID: types.UID("1234-UID"),
Annotations: map[string]string{
- "tailscale.com/proxy-group": "test-pg",
- "tailscale.com/http-endpoint": "enabled",
- "tailscale.com/http-redirect": "true",
+ "github.com/metacubex/tailscale/proxy-group": "test-pg",
+ "github.com/metacubex/tailscale/http-endpoint": "enabled",
+ "github.com/metacubex/tailscale/http-redirect": "true",
},
},
Spec: networkingv1.IngressSpec{
@@ -865,7 +865,7 @@ func TestIngressPGReconciler_MultiCluster(t *testing.T) {
Namespace: "default",
UID: types.UID("1234-UID"),
Annotations: map[string]string{
- "tailscale.com/proxy-group": "test-pg",
+ "github.com/metacubex/tailscale/proxy-group": "test-pg",
},
},
Spec: networkingv1.IngressSpec{
@@ -1189,7 +1189,7 @@ func createPGResources(t *testing.T, fc client.Client, pgName string) {
func setupIngressTest(t *testing.T) (*HAIngressReconciler, client.Client, *fakeTSClient) {
tsIngressClass := &networkingv1.IngressClass{
ObjectMeta: metav1.ObjectMeta{Name: "tailscale"},
- Spec: networkingv1.IngressClassSpec{Controller: "tailscale.com/ts-ingress"},
+ Spec: networkingv1.IngressClassSpec{Controller: "github.com/metacubex/tailscale/ts-ingress"},
}
fc := fake.NewClientBuilder().
diff --git a/cmd/k8s-operator/ingress.go b/cmd/k8s-operator/ingress.go
index 4952e789f6a02..bb3fb375439be 100644
--- a/cmd/k8s-operator/ingress.go
+++ b/cmd/k8s-operator/ingress.go
@@ -8,7 +8,7 @@ package main
import (
"context"
"fmt"
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
"sync"
@@ -23,16 +23,16 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
- "tailscale.com/ipn"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/types/opt"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
)
const (
- tailscaleIngressControllerName = "tailscale.com/ts-ingress" // ingressClass.spec.controllerName for tailscale IngressClass resource
+ tailscaleIngressControllerName = "github.com/metacubex/tailscale/ts-ingress" // ingressClass.spec.controllerName for tailscale IngressClass resource
ingressClassDefaultAnnotation = "ingressclass.kubernetes.io/is-default-class" // we do not support this https://kubernetes.io/docs/concepts/services-networking/ingress/#default-ingress-class
indexIngressProxyClass = ".metadata.annotations.ingress-proxy-class"
)
@@ -392,7 +392,7 @@ func handlersForIngress(ctx context.Context, ing *networkingv1.Ingress, cl clien
}
// isHTTPRedirectEnabled returns true if HTTP redirect is enabled for the Ingress.
-// The annotation is tailscale.com/http-redirect and it should be set to "true".
+// The annotation is github.com/metacubex/tailscale/http-redirect and it should be set to "true".
func isHTTPRedirectEnabled(ing *networkingv1.Ingress) bool {
return ing.Annotations != nil && opt.Bool(ing.Annotations[AnnotationHTTPRedirect]).EqualBool(true)
}
diff --git a/cmd/k8s-operator/ingress_test.go b/cmd/k8s-operator/ingress_test.go
index c2a1198cce539..22fce785d647f 100644
--- a/cmd/k8s-operator/ingress_test.go
+++ b/cmd/k8s-operator/ingress_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
@@ -23,12 +23,12 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"tailscale.com/client/tailscale/v2"
- "tailscale.com/ipn"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tstest"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/ipn"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/util/mak"
)
func TestTailscaleIngress(t *testing.T) {
@@ -94,7 +94,7 @@ func TestTailscaleIngress(t *testing.T) {
// Get the ingress and update it with expected changes
ing := ingress()
- ing.Finalizers = append(ing.Finalizers, "tailscale.com/finalizer")
+ ing.Finalizers = append(ing.Finalizers, "github.com/metacubex/tailscale/finalizer")
ing.Status.LoadBalancer = networkingv1.IngressLoadBalancerStatus{
Ingress: []networkingv1.IngressLoadBalancerIngress{
{Hostname: "foo.tailnetxyz.ts.net", Ports: []networkingv1.IngressPortStatus{{Port: 443, Protocol: "TCP"}}},
@@ -190,7 +190,7 @@ func TestTailscaleIngressHostname(t *testing.T) {
// Get the ingress and update it with expected changes
ing := ingress()
- ing.Finalizers = append(ing.Finalizers, "tailscale.com/finalizer")
+ ing.Finalizers = append(ing.Finalizers, "github.com/metacubex/tailscale/finalizer")
expectEqual(t, fc, ing)
// 3. Ingress proxy with capability version >= 110 advertises HTTPS endpoint
@@ -336,7 +336,7 @@ func TestTailscaleIngressWithProxyClass(t *testing.T) {
opts.proxyClass = pc.Name
expectEqual(t, fc, expectedSTSUserspace(t, fc, opts))
- // 4. tailscale.com/proxy-class label is removed from the Ingress, the
+ // 4. github.com/metacubex/tailscale/proxy-class label is removed from the Ingress, the
// Ingress gets reconciled and the custom ProxyClass configuration is
// removed from the proxy resources.
mustUpdate(t, fc, "default", "test", func(ing *networkingv1.Ingress) {
@@ -767,7 +767,7 @@ func TestEmptyPath(t *testing.T) {
func ingressClass() *networkingv1.IngressClass {
return &networkingv1.IngressClass{
ObjectMeta: metav1.ObjectMeta{Name: "tailscale"},
- Spec: networkingv1.IngressClassSpec{Controller: "tailscale.com/ts-ingress"},
+ Spec: networkingv1.IngressClassSpec{Controller: "github.com/metacubex/tailscale/ts-ingress"},
}
}
diff --git a/cmd/k8s-operator/metrics_resources.go b/cmd/k8s-operator/metrics_resources.go
index 4384f4cba40bd..f80068aabf75b 100644
--- a/cmd/k8s-operator/metrics_resources.go
+++ b/cmd/k8s-operator/metrics_resources.go
@@ -8,9 +8,12 @@ package main
import (
"context"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"reflect"
+ kube "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/kube/kubetypes"
"go.uber.org/zap"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
@@ -19,13 +22,10 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
- kube "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/kube/kubetypes"
)
const (
- labelMetricsTarget = "tailscale.com/metrics-target"
+ labelMetricsTarget = "github.com/metacubex/tailscale/metrics-target"
// These labels get transferred from the metrics Service to the ingested Prometheus metrics.
labelPromProxyType = "ts_proxy_type"
diff --git a/cmd/k8s-operator/nameserver.go b/cmd/k8s-operator/nameserver.go
index f5565e5d30cee..d9dc48f7b8220 100644
--- a/cmd/k8s-operator/nameserver.go
+++ b/cmd/k8s-operator/nameserver.go
@@ -10,7 +10,7 @@ import (
_ "embed"
"errors"
"fmt"
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
"sync"
@@ -27,12 +27,12 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/yaml"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tstime"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/set"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/set"
)
const (
@@ -113,7 +113,7 @@ func (a *NameserverReconciler) Reconcile(ctx context.Context, req reconcile.Requ
return res, fmt.Errorf("error listing DNSConfigs: %w", err)
}
if len(dnsCfgs.Items) > 1 { // enforce DNSConfig to be a singleton
- msg := "invalid cluster configuration: more than one tailscale.com/dnsconfigs found. Please ensure that no more than one is created."
+ msg := "invalid cluster configuration: more than one github.com/metacubex/tailscale/dnsconfigs found. Please ensure that no more than one is created."
logger.Error(msg)
a.recorder.Event(&dnsCfg, corev1.EventTypeWarning, reasonMultipleDNSConfigsPresent, messageMultipleDNSConfigsPresent)
setStatus(&dnsCfg, metav1.ConditionFalse, reasonMultipleDNSConfigsPresent, messageMultipleDNSConfigsPresent)
diff --git a/cmd/k8s-operator/nameserver_test.go b/cmd/k8s-operator/nameserver_test.go
index 3ec00d5ed8859..79ba231e5b622 100644
--- a/cmd/k8s-operator/nameserver_test.go
+++ b/cmd/k8s-operator/nameserver_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
// tailscale-operator provides a way to expose services running in a Kubernetes
// cluster to your Tailnet and to make Tailscale nodes available to cluster
// workloads
@@ -20,15 +20,15 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/yaml"
- operatorutils "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/tstest"
- "tailscale.com/util/mak"
+ operatorutils "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/util/mak"
)
func TestNameserverReconciler(t *testing.T) {
dnsConfig := &tsapi.DNSConfig{
- TypeMeta: metav1.TypeMeta{Kind: "DNSConfig", APIVersion: "tailscale.com/v1alpha1"},
+ TypeMeta: metav1.TypeMeta{Kind: "DNSConfig", APIVersion: "github.com/metacubex/tailscale/v1alpha1"},
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
diff --git a/cmd/k8s-operator/nodeport-service-ports.go b/cmd/k8s-operator/nodeport-service-ports.go
index f8d28860bf84e..70b6b510800f8 100644
--- a/cmd/k8s-operator/nodeport-service-ports.go
+++ b/cmd/k8s-operator/nodeport-service-ports.go
@@ -6,20 +6,20 @@ package main
import (
"context"
"fmt"
- "math/rand/v2"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"regexp"
"sort"
"strconv"
"strings"
+ k8soperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/kube/kubetypes"
"go.uber.org/zap"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"sigs.k8s.io/controller-runtime/pkg/client"
- k8soperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/kube/kubetypes"
)
const (
diff --git a/cmd/k8s-operator/nodeport-services-ports_test.go b/cmd/k8s-operator/nodeport-services-ports_test.go
index 9c147f79aecbd..12088c4b611c5 100644
--- a/cmd/k8s-operator/nodeport-services-ports_test.go
+++ b/cmd/k8s-operator/nodeport-services-ports_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
@@ -10,10 +10,10 @@ import (
"testing"
"time"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/tstest"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/tstest"
)
func TestGetServicesNodePortRangeFromErr(t *testing.T) {
diff --git a/cmd/k8s-operator/operator.go b/cmd/k8s-operator/operator.go
index 9f9c719973895..3564b31ac88ee 100644
--- a/cmd/k8s-operator/operator.go
+++ b/cmd/k8s-operator/operator.go
@@ -48,32 +48,32 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"tailscale.com/client/tailscale/v2"
- "tailscale.com/client/local"
- "tailscale.com/envknob"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn"
- "tailscale.com/ipn/store/kubestore"
- apiproxy "tailscale.com/k8s-operator/api-proxy"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/reconciler/proxygrouppolicy"
- "tailscale.com/k8s-operator/reconciler/tailnet"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tsnet"
- "tailscale.com/tstime"
- "tailscale.com/types/logger"
- "tailscale.com/util/set"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/store/kubestore"
+ apiproxy "github.com/metacubex/tailscale/k8s-operator/api-proxy"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/reconciler/proxygrouppolicy"
+ "github.com/metacubex/tailscale/k8s-operator/reconciler/tailnet"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/version"
)
// Generate Connector and ProxyClass CustomResourceDefinition yamls from their Go types.
//go:generate go run sigs.k8s.io/controller-tools/cmd/controller-gen crd schemapatch:manifests=./deploy/crds output:dir=./deploy/crds paths=../../k8s-operator/apis/...
// Generate static manifests for deploying Tailscale operator on Kubernetes from the operator's Helm chart.
-//go:generate go run tailscale.com/cmd/k8s-operator/generate staticmanifests
+//go:generate go run github.com/metacubex/tailscale/cmd/k8s-operator/generate staticmanifests
// Generate the helm chart's CRDs (which are ignored from git).
-//go:generate go run tailscale.com/cmd/k8s-operator/generate helmcrd
+//go:generate go run github.com/metacubex/tailscale/cmd/k8s-operator/generate helmcrd
// Generate CRD API docs.
//go:generate go run github.com/elastic/crd-ref-docs --renderer=markdown --source-path=../../k8s-operator/apis/ --config=../../k8s-operator/api-docs-config.yaml --output-path=../../k8s-operator/api.md
@@ -122,7 +122,7 @@ func main() {
// The operator can run either as a plain operator or it can
// additionally act as api-server proxy
- // https://tailscale.com/kb/1236/kubernetes-operator/?q=kubernetes#accessing-the-kubernetes-control-plane-using-an-api-server-proxy.
+ // https://github.com/metacubex/tailscale/kb/1236/kubernetes-operator/?q=kubernetes#accessing-the-kubernetes-control-plane-using-an-api-server-proxy.
mode := parseAPIProxyMode()
if mode == nil {
hostinfo.SetApp(kubetypes.AppOperator)
@@ -416,7 +416,7 @@ func runReconcilers(opts reconcilerOpts) {
if opts.defaultProxyClass != "" {
// If a default ProxyClass is specified, we'll need to list all objects
// that could be affected. For L3 ingress, this is Services with the
- // "tailscale.com/expose" annotation and LoadBalancer services (either
+ // "github.com/metacubex/tailscale/expose" annotation and LoadBalancer services (either
// with the loadBalancerClass "tailscale", or unset if we're the default).
if err := mgr.GetFieldIndexer().IndexField(context.Background(), new(corev1.Service), indexServiceExposed, indexExposed); err != nil {
startlog.Fatalf("failed setting up exposed indexer for Services: %v", err)
@@ -790,7 +790,7 @@ type reconcilerOpts struct {
// proxyTags are ACL tags to tag proxy auth keys. Multiple tags should
// be provided as a string with comma-separated tag values. Proxy tags
// default to tag:k8s.
- // https://tailscale.com/kb/1085/auth-keys
+ // https://github.com/metacubex/tailscale/kb/1085/auth-keys
proxyTags string
// proxyActAsDefaultLoadBalancer determines whether this operator
// instance should act as the default ingress controller when looking at
@@ -966,7 +966,7 @@ func indexType(o client.Object) []string {
// proxyClassHandlerForSvc returns a handler that, for a given ProxyClass,
// returns a list of reconcile requests for all Services labeled with
-// tailscale.com/proxy-class: .
+// github.com/metacubex/tailscale/proxy-class: .
func proxyClassHandlerForSvc(cl client.Client, logger *zap.SugaredLogger, defaultProxyClass string, isDefaultLoadBalancer bool) handler.MapFunc {
return func(ctx context.Context, o client.Object) []reconcile.Request {
svcList := new(corev1.ServiceList)
@@ -1037,7 +1037,7 @@ func proxyClassHandlerForSvc(cl client.Client, logger *zap.SugaredLogger, defaul
// proxyClassHandlerForIngress returns a handler that, for a given ProxyClass,
// returns a list of reconcile requests for all Ingresses labeled with
-// tailscale.com/proxy-class: .
+// github.com/metacubex/tailscale/proxy-class: .
func proxyClassHandlerForIngress(cl client.Client, logger *zap.SugaredLogger) handler.MapFunc {
return func(ctx context.Context, o client.Object) []reconcile.Request {
ingList := new(networkingv1.IngressList)
diff --git a/cmd/k8s-operator/operator_test.go b/cmd/k8s-operator/operator_test.go
index b775a36fb5d11..6b47e9ecc903a 100644
--- a/cmd/k8s-operator/operator_test.go
+++ b/cmd/k8s-operator/operator_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
@@ -25,15 +25,15 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
- "tailscale.com/k8s-operator/apis/v1alpha1"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/net/dns/resolvconffile"
- "tailscale.com/tstest"
- "tailscale.com/tstime"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/net/dns/resolvconffile"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/mak"
)
func TestLoadBalancerClass(t *testing.T) {
@@ -103,7 +103,7 @@ func TestLoadBalancerClass(t *testing.T) {
Status: metav1.ConditionFalse,
LastTransitionTime: t0,
Reason: reasonProxyInvalid,
- Message: `unable to provision proxy resources: invalid Service: invalid value of annotation tailscale.com/tailnet-fqdn: "invalid.example.com" does not appear to be a valid MagicDNS name`,
+ Message: `unable to provision proxy resources: invalid Service: invalid value of annotation github.com/metacubex/tailscale/tailnet-fqdn: "invalid.example.com" does not appear to be a valid MagicDNS name`,
}},
},
}
@@ -135,7 +135,7 @@ func TestLoadBalancerClass(t *testing.T) {
expectEqual(t, fc, expectedSTS(t, fc, opts), removeResourceReqs)
want.Annotations = nil
- want.ObjectMeta.Finalizers = []string{"tailscale.com/finalizer"}
+ want.ObjectMeta.Finalizers = []string{"github.com/metacubex/tailscale/finalizer"}
want.Status = corev1.ServiceStatus{
Conditions: []metav1.Condition{{
Type: string(tsapi.ProxyReady),
@@ -277,7 +277,7 @@ func TestTailnetTargetFQDNAnnotation(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "default",
- Finalizers: []string{"tailscale.com/finalizer"},
+ Finalizers: []string{"github.com/metacubex/tailscale/finalizer"},
UID: types.UID("1234-UID"),
Annotations: map[string]string{
AnnotationTailnetTargetFQDN: tailnetTargetFQDN,
@@ -387,7 +387,7 @@ func TestTailnetTargetIPAnnotation(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "default",
- Finalizers: []string{"tailscale.com/finalizer"},
+ Finalizers: []string{"github.com/metacubex/tailscale/finalizer"},
UID: types.UID("1234-UID"),
Annotations: map[string]string{
AnnotationTailnetTargetIP: tailnetTargetIP,
@@ -495,7 +495,7 @@ func TestTailnetTargetIPAnnotation_IPCouldNotBeParsed(t *testing.T) {
Status: metav1.ConditionFalse,
LastTransitionTime: t0,
Reason: reasonProxyInvalid,
- Message: `unable to provision proxy resources: invalid Service: invalid value of annotation tailscale.com/tailnet-ip: "invalid-ip" could not be parsed as a valid IP Address, error: ParseAddr("invalid-ip"): unable to parse IP`,
+ Message: `unable to provision proxy resources: invalid Service: invalid value of annotation github.com/metacubex/tailscale/tailnet-ip: "invalid-ip" could not be parsed as a valid IP Address, error: ParseAddr("invalid-ip"): unable to parse IP`,
}},
},
}
@@ -563,7 +563,7 @@ func TestTailnetTargetIPAnnotation_InvalidIP(t *testing.T) {
Status: metav1.ConditionFalse,
LastTransitionTime: t0,
Reason: reasonProxyInvalid,
- Message: `unable to provision proxy resources: invalid Service: invalid value of annotation tailscale.com/tailnet-ip: "999.999.999.999" could not be parsed as a valid IP Address, error: ParseAddr("999.999.999.999"): IPv4 field has value >255`,
+ Message: `unable to provision proxy resources: invalid Service: invalid value of annotation github.com/metacubex/tailscale/tailnet-ip: "999.999.999.999" could not be parsed as a valid IP Address, error: ParseAddr("999.999.999.999"): IPv4 field has value >255`,
}},
},
}
@@ -600,7 +600,7 @@ func TestAnnotations(t *testing.T) {
// on it being set.
UID: "1234-UID",
Annotations: map[string]string{
- "tailscale.com/expose": "true",
+ "github.com/metacubex/tailscale/expose": "true",
},
},
Spec: corev1.ServiceSpec{
@@ -630,10 +630,10 @@ func TestAnnotations(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "default",
- Finalizers: []string{"tailscale.com/finalizer"},
+ Finalizers: []string{"github.com/metacubex/tailscale/finalizer"},
UID: types.UID("1234-UID"),
Annotations: map[string]string{
- "tailscale.com/expose": "true",
+ "github.com/metacubex/tailscale/expose": "true",
},
},
Spec: corev1.ServiceSpec{
@@ -649,7 +649,7 @@ func TestAnnotations(t *testing.T) {
// Turn the service back into a ClusterIP service, which should make the
// operator clean up.
mustUpdate(t, fc, "default", "test", func(s *corev1.Service) {
- delete(s.ObjectMeta.Annotations, "tailscale.com/expose")
+ delete(s.ObjectMeta.Annotations, "github.com/metacubex/tailscale/expose")
})
// synchronous StatefulSet deletion triggers a requeue. But, the StatefulSet
// didn't create any child resources since this is all faked, so the
@@ -704,7 +704,7 @@ func TestAnnotationIntoLB(t *testing.T) {
// on it being set.
UID: "1234-UID",
Annotations: map[string]string{
- "tailscale.com/expose": "true",
+ "github.com/metacubex/tailscale/expose": "true",
},
},
Spec: corev1.ServiceSpec{
@@ -747,10 +747,10 @@ func TestAnnotationIntoLB(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "default",
- Finalizers: []string{"tailscale.com/finalizer"},
+ Finalizers: []string{"github.com/metacubex/tailscale/finalizer"},
UID: types.UID("1234-UID"),
Annotations: map[string]string{
- "tailscale.com/expose": "true",
+ "github.com/metacubex/tailscale/expose": "true",
},
},
Spec: corev1.ServiceSpec{
@@ -766,7 +766,7 @@ func TestAnnotationIntoLB(t *testing.T) {
// Remove Tailscale's annotation, and at the same time convert the service
// into a tailscale LoadBalancer.
mustUpdate(t, fc, "default", "test", func(s *corev1.Service) {
- delete(s.ObjectMeta.Annotations, "tailscale.com/expose")
+ delete(s.ObjectMeta.Annotations, "github.com/metacubex/tailscale/expose")
s.Spec.Type = corev1.ServiceTypeLoadBalancer
s.Spec.LoadBalancerClass = new("tailscale")
})
@@ -780,7 +780,7 @@ func TestAnnotationIntoLB(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "default",
- Finalizers: []string{"tailscale.com/finalizer"},
+ Finalizers: []string{"github.com/metacubex/tailscale/finalizer"},
UID: "1234-UID",
},
Spec: corev1.ServiceSpec{
@@ -875,7 +875,7 @@ func TestLBIntoAnnotation(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "default",
- Finalizers: []string{"tailscale.com/finalizer"},
+ Finalizers: []string{"github.com/metacubex/tailscale/finalizer"},
UID: types.UID("1234-UID"),
},
Spec: corev1.ServiceSpec{
@@ -903,7 +903,7 @@ func TestLBIntoAnnotation(t *testing.T) {
// tailscale annotation.
mustUpdate(t, fc, "default", "test", func(s *corev1.Service) {
s.ObjectMeta.Annotations = map[string]string{
- "tailscale.com/expose": "true",
+ "github.com/metacubex/tailscale/expose": "true",
}
s.Spec.Type = corev1.ServiceTypeClusterIP
s.Spec.LoadBalancerClass = nil
@@ -923,9 +923,9 @@ func TestLBIntoAnnotation(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "default",
- Finalizers: []string{"tailscale.com/finalizer"},
+ Finalizers: []string{"github.com/metacubex/tailscale/finalizer"},
Annotations: map[string]string{
- "tailscale.com/expose": "true",
+ "github.com/metacubex/tailscale/expose": "true",
},
UID: "1234-UID",
},
@@ -969,8 +969,8 @@ func TestCustomHostname(t *testing.T) {
// on it being set.
UID: "1234-UID",
Annotations: map[string]string{
- "tailscale.com/expose": "true",
- "tailscale.com/hostname": "reindeer-flotilla",
+ "github.com/metacubex/tailscale/expose": "true",
+ "github.com/metacubex/tailscale/hostname": "reindeer-flotilla",
},
},
Spec: corev1.ServiceSpec{
@@ -1000,11 +1000,11 @@ func TestCustomHostname(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "default",
- Finalizers: []string{"tailscale.com/finalizer"},
+ Finalizers: []string{"github.com/metacubex/tailscale/finalizer"},
UID: types.UID("1234-UID"),
Annotations: map[string]string{
- "tailscale.com/expose": "true",
- "tailscale.com/hostname": "reindeer-flotilla",
+ "github.com/metacubex/tailscale/expose": "true",
+ "github.com/metacubex/tailscale/hostname": "reindeer-flotilla",
},
},
Spec: corev1.ServiceSpec{
@@ -1020,7 +1020,7 @@ func TestCustomHostname(t *testing.T) {
// Turn the service back into a ClusterIP service, which should make the
// operator clean up.
mustUpdate(t, fc, "default", "test", func(s *corev1.Service) {
- delete(s.ObjectMeta.Annotations, "tailscale.com/expose")
+ delete(s.ObjectMeta.Annotations, "github.com/metacubex/tailscale/expose")
})
// synchronous StatefulSet deletion triggers a requeue. But, the StatefulSet
// didn't create any child resources since this is all faked, so the
@@ -1038,7 +1038,7 @@ func TestCustomHostname(t *testing.T) {
Namespace: "default",
UID: "1234-UID",
Annotations: map[string]string{
- "tailscale.com/hostname": "reindeer-flotilla",
+ "github.com/metacubex/tailscale/hostname": "reindeer-flotilla",
},
},
Spec: corev1.ServiceSpec{
@@ -1079,8 +1079,8 @@ func TestCustomPriorityClassName(t *testing.T) {
// on it being set.
UID: "1234-UID",
Annotations: map[string]string{
- "tailscale.com/expose": "true",
- "tailscale.com/hostname": "tailscale-critical",
+ "github.com/metacubex/tailscale/expose": "true",
+ "github.com/metacubex/tailscale/hostname": "tailscale-critical",
},
},
Spec: corev1.ServiceSpec{
@@ -1352,7 +1352,7 @@ func TestProxyClassForService(t *testing.T) {
expectEqual(t, fc, expectedHeadlessService(shortName, "svc"))
expectEqual(t, fc, expectedSTS(t, fc, opts), removeResourceReqs)
- // 2. The Service gets updated with tailscale.com/proxy-class label
+ // 2. The Service gets updated with github.com/metacubex/tailscale/proxy-class label
// pointing at the 'custom-metadata' ProxyClass. The ProxyClass is not
// yet ready, so no changes are actually applied to the proxy resources.
mustUpdate(t, fc, "default", "test", func(svc *corev1.Service) {
@@ -1379,7 +1379,7 @@ func TestProxyClassForService(t *testing.T) {
expectEqual(t, fc, expectedSTS(t, fc, opts), removeResourceReqs)
expectEqual(t, fc, expectedSecret(t, fc, opts), removeAuthKeyIfExistsModifier(t))
- // 4. tailscale.com/proxy-class label is removed from the Service, the
+ // 4. github.com/metacubex/tailscale/proxy-class label is removed from the Service, the
// configuration from the ProxyClass is removed from the cluster
// resources.
mustUpdate(t, fc, "default", "test", func(svc *corev1.Service) {
@@ -2081,7 +2081,7 @@ func TestIgnorePGService(t *testing.T) {
// on it being set.
UID: "1234-UID",
Annotations: map[string]string{
- "tailscale.com/proxygroup": "test-pg",
+ "github.com/metacubex/tailscale/proxygroup": "test-pg",
},
},
Spec: corev1.ServiceSpec{
diff --git a/cmd/k8s-operator/proxyclass.go b/cmd/k8s-operator/proxyclass.go
index c0ea46116373b..97decb36d2008 100644
--- a/cmd/k8s-operator/proxyclass.go
+++ b/cmd/k8s-operator/proxyclass.go
@@ -8,11 +8,16 @@ package main
import (
"context"
"fmt"
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
"sync"
dockerref "github.com/distribution/reference"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/set"
"go.uber.org/zap"
corev1 "k8s.io/api/core/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
@@ -26,11 +31,6 @@ import (
"k8s.io/client-go/tools/record"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/tstime"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/set"
)
const (
diff --git a/cmd/k8s-operator/proxyclass_test.go b/cmd/k8s-operator/proxyclass_test.go
index 171cfc5904cd3..8a102cd154655 100644
--- a/cmd/k8s-operator/proxyclass_test.go
+++ b/cmd/k8s-operator/proxyclass_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
// tailscale-operator provides a way to expose services running in a Kubernetes
// cluster to your Tailnet.
package main
@@ -12,27 +12,27 @@ import (
"testing"
"time"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/tstest"
"go.uber.org/zap"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/record"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/tstest"
)
func TestProxyClass(t *testing.T) {
pc := &tsapi.ProxyClass{
- TypeMeta: metav1.TypeMeta{Kind: "ProxyClass", APIVersion: "tailscale.com/v1alpha1"},
+ TypeMeta: metav1.TypeMeta{Kind: "ProxyClass", APIVersion: "github.com/metacubex/tailscale/v1alpha1"},
ObjectMeta: metav1.ObjectMeta{
Name: "test",
// The apiserver is supposed to set the UID, but the fake client
// doesn't. So, set it explicitly because other code later depends
// on it being set.
UID: types.UID("1234-UID"),
- Finalizers: []string{"tailscale.com/finalizer"},
+ Finalizers: []string{"github.com/metacubex/tailscale/finalizer"},
},
Spec: tsapi.ProxyClassSpec{
StatefulSet: &tsapi.StatefulSet{
diff --git a/cmd/k8s-operator/proxygroup.go b/cmd/k8s-operator/proxygroup.go
index 9df8460b7c92b..de9f32561ac94 100644
--- a/cmd/k8s-operator/proxygroup.go
+++ b/cmd/k8s-operator/proxygroup.go
@@ -10,8 +10,8 @@ import (
"encoding/json"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
"sort"
"strings"
"sync"
@@ -34,19 +34,19 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"tailscale.com/client/tailscale/v2"
- "tailscale.com/ipn"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/kube/egressservices"
- "tailscale.com/kube/k8s-proxy/conf"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/types/opt"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/ipn"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/kube/egressservices"
+ "github.com/metacubex/tailscale/kube/k8s-proxy/conf"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
)
const (
@@ -66,7 +66,7 @@ const (
// If the controller needs to depend on newer client behaviour, it should
// maintain backwards compatible logic for older capability versions for 3
// stable releases, as per documentation on supported version drift:
- // https://tailscale.com/kb/1236/kubernetes-operator#supported-versions
+ // https://github.com/metacubex/tailscale/kb/1236/kubernetes-operator#supported-versions
//
// tailcfg.CurrentCapabilityVersion was 106 when the ProxyGroup controller was
// first introduced.
diff --git a/cmd/k8s-operator/proxygroup_specs.go b/cmd/k8s-operator/proxygroup_specs.go
index 60b4bddd5613c..262cb9e2df3f0 100644
--- a/cmd/k8s-operator/proxygroup_specs.go
+++ b/cmd/k8s-operator/proxygroup_specs.go
@@ -7,11 +7,15 @@ package main
import (
"fmt"
- "maps"
- "slices"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strconv"
"strings"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/kube/egressservices"
+ "github.com/metacubex/tailscale/kube/ingressservices"
+ "github.com/metacubex/tailscale/kube/kubetypes"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
@@ -19,10 +23,6 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
"sigs.k8s.io/yaml"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/kube/egressservices"
- "tailscale.com/kube/ingressservices"
- "tailscale.com/kube/kubetypes"
)
const (
diff --git a/cmd/k8s-operator/proxygroup_test.go b/cmd/k8s-operator/proxygroup_test.go
index 95eb7bd5f4723..2e24cdeea3c7d 100644
--- a/cmd/k8s-operator/proxygroup_test.go
+++ b/cmd/k8s-operator/proxygroup_test.go
@@ -1,17 +1,17 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
"context"
"encoding/json"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"reflect"
- "slices"
"strings"
"testing"
"time"
@@ -32,15 +32,15 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"tailscale.com/client/tailscale/v2"
- "tailscale.com/ipn"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/kube/k8s-proxy/conf"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/types/opt"
+ "github.com/metacubex/tailscale/ipn"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/kube/k8s-proxy/conf"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/opt"
)
const (
@@ -620,7 +620,7 @@ func TestProxyGroupWithStaticEndpoints(t *testing.T) {
pg := &tsapi.ProxyGroup{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
- Finalizers: []string{"tailscale.com/finalizer"},
+ Finalizers: []string{"github.com/metacubex/tailscale/finalizer"},
},
Spec: tsapi.ProxyGroupSpec{
Type: tsapi.ProxyGroupTypeEgress,
@@ -825,7 +825,7 @@ func TestProxyGroup(t *testing.T) {
pg := &tsapi.ProxyGroup{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
- Finalizers: []string{"tailscale.com/finalizer"},
+ Finalizers: []string{"github.com/metacubex/tailscale/finalizer"},
Generation: 1,
},
Spec: tsapi.ProxyGroupSpec{
@@ -1672,7 +1672,7 @@ func TestProxyGroupGetAuthKey(t *testing.T) {
pg := &tsapi.ProxyGroup{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
- Finalizers: []string{"tailscale.com/finalizer"},
+ Finalizers: []string{"github.com/metacubex/tailscale/finalizer"},
},
Spec: tsapi.ProxyGroupSpec{
Type: tsapi.ProxyGroupTypeEgress,
diff --git a/cmd/k8s-operator/sts.go b/cmd/k8s-operator/sts.go
index 66c2e917f376a..4695b15496cc5 100644
--- a/cmd/k8s-operator/sts.go
+++ b/cmd/k8s-operator/sts.go
@@ -11,10 +11,10 @@ import (
"encoding/json"
"errors"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"os"
"path"
- "slices"
"strconv"
"strings"
@@ -31,46 +31,46 @@ import (
"sigs.k8s.io/yaml"
"tailscale.com/client/tailscale/v2"
- "tailscale.com/ipn"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/net/netutil"
- "tailscale.com/tailcfg"
- "tailscale.com/types/opt"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/ipn"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/net/netutil"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/util/mak"
)
const (
// Labels that the operator sets on StatefulSets and Pods. If you add a
// new label here, do also add it to tailscaleManagedLabels var to
// ensure that it does not get overwritten by ProxyClass configuration.
- LabelParentType = "tailscale.com/parent-resource-type"
- LabelParentName = "tailscale.com/parent-resource"
- LabelParentNamespace = "tailscale.com/parent-resource-ns"
+ LabelParentType = "github.com/metacubex/tailscale/parent-resource-type"
+ LabelParentName = "github.com/metacubex/tailscale/parent-resource"
+ LabelParentNamespace = "github.com/metacubex/tailscale/parent-resource-ns"
// LabelProxyClass can be set by users on tailscale Ingresses and Services that define cluster ingress or
// cluster egress, to specify that configuration in this ProxyClass should be applied to resources created for
// the Ingress or Service.
- LabelAnnotationProxyClass = "tailscale.com/proxy-class"
+ LabelAnnotationProxyClass = "github.com/metacubex/tailscale/proxy-class"
- FinalizerName = "tailscale.com/finalizer"
+ FinalizerName = "github.com/metacubex/tailscale/finalizer"
// Annotations settable by users on services.
- AnnotationExpose = "tailscale.com/expose"
- AnnotationTags = "tailscale.com/tags"
- AnnotationHostname = "tailscale.com/hostname"
- annotationTailnetTargetIPOld = "tailscale.com/ts-tailnet-target-ip"
- AnnotationTailnetTargetIP = "tailscale.com/tailnet-ip"
+ AnnotationExpose = "github.com/metacubex/tailscale/expose"
+ AnnotationTags = "github.com/metacubex/tailscale/tags"
+ AnnotationHostname = "github.com/metacubex/tailscale/hostname"
+ annotationTailnetTargetIPOld = "github.com/metacubex/tailscale/ts-tailnet-target-ip"
+ AnnotationTailnetTargetIP = "github.com/metacubex/tailscale/tailnet-ip"
// MagicDNS name of tailnet node.
- AnnotationTailnetTargetFQDN = "tailscale.com/tailnet-fqdn"
+ AnnotationTailnetTargetFQDN = "github.com/metacubex/tailscale/tailnet-fqdn"
- AnnotationProxyGroup = "tailscale.com/proxy-group"
+ AnnotationProxyGroup = "github.com/metacubex/tailscale/proxy-group"
// Annotations settable by users on ingresses.
- AnnotationFunnel = "tailscale.com/funnel"
- AnnotationHTTPRedirect = "tailscale.com/http-redirect"
+ AnnotationFunnel = "github.com/metacubex/tailscale/funnel"
+ AnnotationHTTPRedirect = "github.com/metacubex/tailscale/http-redirect"
// If set to true, set up iptables/nftables rules in the proxy forward
// cluster traffic to the tailnet IP of that proxy. This can only be set
@@ -83,17 +83,17 @@ const (
// container and will also run a privileged init container that enables
// forwarding.
// Eventually this behaviour might become the default.
- AnnotationExperimentalForwardClusterTrafficViaL7IngresProxy = "tailscale.com/experimental-forward-cluster-traffic-via-ingress"
+ AnnotationExperimentalForwardClusterTrafficViaL7IngresProxy = "github.com/metacubex/tailscale/experimental-forward-cluster-traffic-via-ingress"
// Annotations set by the operator on pods to trigger restarts when the
// hostname, IP, FQDN or tailscaled config changes. If you add a new
// annotation here, also add it to tailscaleManagedAnnotations var to
// ensure that it does not get removed when a ProxyClass configuration
// is applied.
- podAnnotationLastSetClusterIP = "tailscale.com/operator-last-set-cluster-ip"
- podAnnotationLastSetClusterDNSName = "tailscale.com/operator-last-set-cluster-dns-name"
- podAnnotationLastSetTailnetTargetIP = "tailscale.com/operator-last-set-ts-tailnet-target-ip"
- podAnnotationLastSetTailnetTargetFQDN = "tailscale.com/operator-last-set-ts-tailnet-target-fqdn"
+ podAnnotationLastSetClusterIP = "github.com/metacubex/tailscale/operator-last-set-cluster-ip"
+ podAnnotationLastSetClusterDNSName = "github.com/metacubex/tailscale/operator-last-set-cluster-dns-name"
+ podAnnotationLastSetTailnetTargetIP = "github.com/metacubex/tailscale/operator-last-set-ts-tailnet-target-ip"
+ podAnnotationLastSetTailnetTargetFQDN = "github.com/metacubex/tailscale/operator-last-set-ts-tailnet-target-fqdn"
proxyTypeEgress = "egress_service"
proxyTypeIngressService = "ingress_service"
@@ -866,7 +866,7 @@ func applyProxyClassToStatefulSet(pc *tsapi.ProxyClass, ss *appsv1.StatefulSet,
if isEgress {
// TODO (irbekrm): fix this
// For Ingress proxies that have been configured with
- // tailscale.com/experimental-forward-cluster-traffic-via-ingress
+ // github.com/metacubex/tailscale/experimental-forward-cluster-traffic-via-ingress
// annotation, all cluster traffic is forwarded to the
// Ingress backend(s).
logger.Info("ProxyClass specifies that metrics should be enabled, but this is currently not supported for egress proxies.")
diff --git a/cmd/k8s-operator/sts_test.go b/cmd/k8s-operator/sts_test.go
index f55f582a6de42..58302106f544d 100644
--- a/cmd/k8s-operator/sts_test.go
+++ b/cmd/k8s-operator/sts_test.go
@@ -1,28 +1,28 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
_ "embed"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"reflect"
"regexp"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/kube/kubetypes"
"go.uber.org/zap"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/yaml"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/kube/kubetypes"
)
// Test_statefulSetNameBase tests that parent name portion in a StatefulSet name
diff --git a/cmd/k8s-operator/svc-for-pg.go b/cmd/k8s-operator/svc-for-pg.go
index 29d1a1ebd23c9..3558fcf602ed7 100644
--- a/cmd/k8s-operator/svc-for-pg.go
+++ b/cmd/k8s-operator/svc-for-pg.go
@@ -10,9 +10,9 @@ import (
"encoding/json"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"reflect"
- "slices"
"strings"
"sync"
@@ -28,21 +28,21 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"tailscale.com/client/tailscale/v2"
- "tailscale.com/ipn"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/kube/ingressservices"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/ipn"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/kube/ingressservices"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
)
const (
- svcPGFinalizerName = "tailscale.com/service-pg-finalizer"
+ svcPGFinalizerName = "github.com/metacubex/tailscale/service-pg-finalizer"
reasonIngressSvcInvalid = "IngressSvcInvalid"
reasonIngressSvcConfigured = "IngressSvcConfigured"
reasonIngressSvcNoBackendsConfigured = "IngressSvcNoBackendsConfigured"
@@ -72,7 +72,7 @@ type HAServiceReconciler struct {
// Reconcile reconciles Services that should be exposed over Tailscale in HA
// mode (on a ProxyGroup). It looks at all Services with
-// tailscale.com/proxy-group annotation. For each such Service, it ensures that
+// github.com/metacubex/tailscale/proxy-group annotation. For each such Service, it ensures that
// a Tailscale Service named after the hostname of the Service exists and is up to
// date.
// HA Servicees support multi-cluster Service setup.
diff --git a/cmd/k8s-operator/svc-for-pg_test.go b/cmd/k8s-operator/svc-for-pg_test.go
index 455d3363cb956..85e0ba9a2a727 100644
--- a/cmd/k8s-operator/svc-for-pg_test.go
+++ b/cmd/k8s-operator/svc-for-pg_test.go
@@ -1,15 +1,15 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
"context"
"encoding/json"
"fmt"
- "math/rand/v2"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"net/netip"
"testing"
"time"
@@ -24,13 +24,13 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"tailscale.com/client/tailscale/v2"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/kube/ingressservices"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tstest"
- "tailscale.com/util/mak"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/kube/ingressservices"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/util/mak"
)
func TestServicePGReconciler(t *testing.T) {
@@ -220,8 +220,8 @@ func TestValidateService(t *testing.T) {
Namespace: "ns-1",
UID: types.UID("1234-UID"),
Annotations: map[string]string{
- "tailscale.com/proxy-group": "test-pg",
- "tailscale.com/hostname": "my-app",
+ "github.com/metacubex/tailscale/proxy-group": "test-pg",
+ "github.com/metacubex/tailscale/hostname": "my-app",
},
},
Spec: corev1.ServiceSpec{
@@ -237,8 +237,8 @@ func TestValidateService(t *testing.T) {
Namespace: "ns-2",
UID: types.UID("1235-UID"),
Annotations: map[string]string{
- "tailscale.com/proxy-group": "test-pg",
- "tailscale.com/hostname": "my-app",
+ "github.com/metacubex/tailscale/proxy-group": "test-pg",
+ "github.com/metacubex/tailscale/hostname": "my-app",
},
},
Spec: corev1.ServiceSpec{
@@ -310,7 +310,7 @@ func TestIgnoreRegularService(t *testing.T) {
// on it being set.
UID: types.UID("1234-UID"),
Annotations: map[string]string{
- "tailscale.com/expose": "true",
+ "github.com/metacubex/tailscale/expose": "true",
},
},
Spec: corev1.ServiceSpec{
@@ -376,7 +376,7 @@ func setupTestService(t *testing.T, svcName string, hostname string, clusterIP s
Namespace: "default",
UID: types.UID(fmt.Sprintf("%d-UID", uid)),
Annotations: map[string]string{
- "tailscale.com/proxy-group": "test-pg",
+ "github.com/metacubex/tailscale/proxy-group": "test-pg",
},
},
Spec: corev1.ServiceSpec{
diff --git a/cmd/k8s-operator/svc.go b/cmd/k8s-operator/svc.go
index 6f12148c85807..39ebc97723dc0 100644
--- a/cmd/k8s-operator/svc.go
+++ b/cmd/k8s-operator/svc.go
@@ -9,8 +9,8 @@ import (
"context"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
"strings"
"sync"
@@ -24,14 +24,14 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/net/dns/resolvconffile"
- "tailscale.com/tstime"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/set"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/net/dns/resolvconffile"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/set"
)
const (
@@ -430,14 +430,14 @@ func isTailscaleLoadBalancerService(svc *corev1.Service, isDefaultLoadBalancer b
svc.Spec.LoadBalancerClass == nil && isDefaultLoadBalancer)
}
-// hasExposeAnnotation reports whether Service has the tailscale.com/expose
+// hasExposeAnnotation reports whether Service has the github.com/metacubex/tailscale/expose
// annotation set
func hasExposeAnnotation(svc *corev1.Service) bool {
return svc != nil && svc.Annotations[AnnotationExpose] == "true"
}
-// tailnetTargetAnnotation returns the value of tailscale.com/tailnet-ip
-// annotation or of the deprecated tailscale.com/ts-tailnet-target-ip
+// tailnetTargetAnnotation returns the value of github.com/metacubex/tailscale/tailnet-ip
+// annotation or of the deprecated github.com/metacubex/tailscale/ts-tailnet-target-ip
// annotation. If neither is set, it returns an empty string. If both are set,
// it returns the value of the new annotation.
func tailnetTargetAnnotation(svc *corev1.Service) string {
diff --git a/cmd/k8s-operator/svc_test.go b/cmd/k8s-operator/svc_test.go
index 677e9db10d40d..e03c2dad12cd3 100644
--- a/cmd/k8s-operator/svc_test.go
+++ b/cmd/k8s-operator/svc_test.go
@@ -1,13 +1,13 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
"context"
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"testing"
"go.uber.org/zap"
@@ -17,10 +17,10 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tstest"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tstest"
)
func TestService_DefaultProxyClassInitiallyNotReady(t *testing.T) {
diff --git a/cmd/k8s-operator/testutils_test.go b/cmd/k8s-operator/testutils_test.go
index 074d920940cf4..f415956183944 100644
--- a/cmd/k8s-operator/testutils_test.go
+++ b/cmd/k8s-operator/testutils_test.go
@@ -1,20 +1,20 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
"context"
"encoding/json"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/http"
"net/netip"
"path"
"reflect"
- "slices"
"strings"
"sync"
"testing"
@@ -34,11 +34,11 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"tailscale.com/client/tailscale/v2"
- "tailscale.com/ipn"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/ipn"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/util/mak"
)
const (
@@ -137,13 +137,13 @@ func expectedSTS(t *testing.T, cl client.Client, opts configOpts) *appsv1.Statef
})
}
if opts.tailnetTargetIP != "" {
- mak.Set(&annots, "tailscale.com/operator-last-set-ts-tailnet-target-ip", opts.tailnetTargetIP)
+ mak.Set(&annots, "github.com/metacubex/tailscale/operator-last-set-ts-tailnet-target-ip", opts.tailnetTargetIP)
tsContainer.Env = append(tsContainer.Env, corev1.EnvVar{
Name: "TS_TAILNET_TARGET_IP",
Value: opts.tailnetTargetIP,
})
} else if opts.tailnetTargetFQDN != "" {
- mak.Set(&annots, "tailscale.com/operator-last-set-ts-tailnet-target-fqdn", opts.tailnetTargetFQDN)
+ mak.Set(&annots, "github.com/metacubex/tailscale/operator-last-set-ts-tailnet-target-fqdn", opts.tailnetTargetFQDN)
tsContainer.Env = append(tsContainer.Env, corev1.EnvVar{
Name: "TS_TAILNET_TARGET_FQDN",
Value: opts.tailnetTargetFQDN,
@@ -154,13 +154,13 @@ func expectedSTS(t *testing.T, cl client.Client, opts configOpts) *appsv1.Statef
Name: "TS_DEST_IP",
Value: opts.clusterTargetIP,
})
- mak.Set(&annots, "tailscale.com/operator-last-set-cluster-ip", opts.clusterTargetIP)
+ mak.Set(&annots, "github.com/metacubex/tailscale/operator-last-set-cluster-ip", opts.clusterTargetIP)
} else if opts.clusterTargetDNS != "" {
tsContainer.Env = append(tsContainer.Env, corev1.EnvVar{
Name: "TS_EXPERIMENTAL_DEST_DNS_NAME",
Value: opts.clusterTargetDNS,
})
- mak.Set(&annots, "tailscale.com/operator-last-set-cluster-dns-name", opts.clusterTargetDNS)
+ mak.Set(&annots, "github.com/metacubex/tailscale/operator-last-set-cluster-dns-name", opts.clusterTargetDNS)
}
if opts.serveConfig != nil {
tsContainer.Env = append(tsContainer.Env, corev1.EnvVar{
@@ -217,10 +217,10 @@ func expectedSTS(t *testing.T, cl client.Client, opts configOpts) *appsv1.Statef
Name: opts.stsName,
Namespace: "operator-ns",
Labels: map[string]string{
- "tailscale.com/managed": "true",
- "tailscale.com/parent-resource": "test",
- "tailscale.com/parent-resource-ns": opts.namespace,
- "tailscale.com/parent-resource-type": opts.parentType,
+ "github.com/metacubex/tailscale/managed": "true",
+ "github.com/metacubex/tailscale/parent-resource": "test",
+ "github.com/metacubex/tailscale/parent-resource-ns": opts.namespace,
+ "github.com/metacubex/tailscale/parent-resource-type": opts.parentType,
},
},
Spec: appsv1.StatefulSetSpec{
@@ -234,11 +234,11 @@ func expectedSTS(t *testing.T, cl client.Client, opts configOpts) *appsv1.Statef
Annotations: annots,
DeletionGracePeriodSeconds: new(int64(10)),
Labels: map[string]string{
- "tailscale.com/managed": "true",
- "tailscale.com/parent-resource": "test",
- "tailscale.com/parent-resource-ns": opts.namespace,
- "tailscale.com/parent-resource-type": opts.parentType,
- "app": "1234-UID",
+ "github.com/metacubex/tailscale/managed": "true",
+ "github.com/metacubex/tailscale/parent-resource": "test",
+ "github.com/metacubex/tailscale/parent-resource-ns": opts.namespace,
+ "github.com/metacubex/tailscale/parent-resource-type": opts.parentType,
+ "app": "1234-UID",
},
},
Spec: corev1.PodSpec{
@@ -358,10 +358,10 @@ func expectedSTSUserspace(t *testing.T, cl client.Client, opts configOpts) *apps
Name: opts.stsName,
Namespace: "operator-ns",
Labels: map[string]string{
- "tailscale.com/managed": "true",
- "tailscale.com/parent-resource": "test",
- "tailscale.com/parent-resource-ns": opts.namespace,
- "tailscale.com/parent-resource-type": opts.parentType,
+ "github.com/metacubex/tailscale/managed": "true",
+ "github.com/metacubex/tailscale/parent-resource": "test",
+ "github.com/metacubex/tailscale/parent-resource-ns": opts.namespace,
+ "github.com/metacubex/tailscale/parent-resource-type": opts.parentType,
},
},
Spec: appsv1.StatefulSetSpec{
@@ -374,11 +374,11 @@ func expectedSTSUserspace(t *testing.T, cl client.Client, opts configOpts) *apps
ObjectMeta: metav1.ObjectMeta{
DeletionGracePeriodSeconds: new(int64(10)),
Labels: map[string]string{
- "tailscale.com/managed": "true",
- "tailscale.com/parent-resource": "test",
- "tailscale.com/parent-resource-ns": opts.namespace,
- "tailscale.com/parent-resource-type": opts.parentType,
- "app": "1234-UID",
+ "github.com/metacubex/tailscale/managed": "true",
+ "github.com/metacubex/tailscale/parent-resource": "test",
+ "github.com/metacubex/tailscale/parent-resource-ns": opts.namespace,
+ "github.com/metacubex/tailscale/parent-resource-type": opts.parentType,
+ "app": "1234-UID",
},
},
Spec: corev1.PodSpec{
@@ -410,10 +410,10 @@ func expectedHeadlessService(name string, parentType string) *corev1.Service {
GenerateName: "ts-test-",
Namespace: "operator-ns",
Labels: map[string]string{
- "tailscale.com/managed": "true",
- "tailscale.com/parent-resource": "test",
- "tailscale.com/parent-resource-ns": "default",
- "tailscale.com/parent-resource-type": parentType,
+ "github.com/metacubex/tailscale/managed": "true",
+ "github.com/metacubex/tailscale/parent-resource": "test",
+ "github.com/metacubex/tailscale/parent-resource-ns": "default",
+ "github.com/metacubex/tailscale/parent-resource-type": parentType,
},
},
Spec: corev1.ServiceSpec{
@@ -429,12 +429,12 @@ func expectedHeadlessService(name string, parentType string) *corev1.Service {
func expectedMetricsService(opts configOpts) *corev1.Service {
labels := metricsLabels(opts)
selector := map[string]string{
- "tailscale.com/managed": "true",
- "tailscale.com/parent-resource": "test",
- "tailscale.com/parent-resource-type": opts.parentType,
+ "github.com/metacubex/tailscale/managed": "true",
+ "github.com/metacubex/tailscale/parent-resource": "test",
+ "github.com/metacubex/tailscale/parent-resource-type": opts.parentType,
}
if opts.namespaced {
- selector["tailscale.com/parent-resource-ns"] = opts.namespace
+ selector["github.com/metacubex/tailscale/parent-resource-ns"] = opts.namespace
}
return &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
@@ -456,11 +456,11 @@ func metricsLabels(opts configOpts) map[string]string {
promJob = fmt.Sprintf("ts_%s_test", opts.proxyType)
}
labels := map[string]string{
- "tailscale.com/managed": "true",
- "tailscale.com/metrics-target": opts.stsName,
- "ts_prom_job": promJob,
- "ts_proxy_type": opts.proxyType,
- "ts_proxy_parent_name": "test",
+ "github.com/metacubex/tailscale/managed": "true",
+ "github.com/metacubex/tailscale/metrics-target": opts.stsName,
+ "ts_prom_job": promJob,
+ "ts_proxy_type": opts.proxyType,
+ "ts_proxy_parent_name": "test",
}
if opts.namespaced {
labels["ts_proxy_parent_namespace"] = "default"
@@ -578,13 +578,13 @@ func expectedSecret(t *testing.T, cl client.Client, opts configOpts) *corev1.Sec
mak.Set(&s.StringData, "cap-95.hujson", string(bn))
mak.Set(&s.StringData, "cap-107.hujson", string(bnn))
labels := map[string]string{
- "tailscale.com/managed": "true",
- "tailscale.com/parent-resource": "test",
- "tailscale.com/parent-resource-ns": "default",
- "tailscale.com/parent-resource-type": opts.parentType,
+ "github.com/metacubex/tailscale/managed": "true",
+ "github.com/metacubex/tailscale/parent-resource": "test",
+ "github.com/metacubex/tailscale/parent-resource-ns": "default",
+ "github.com/metacubex/tailscale/parent-resource-type": opts.parentType,
}
if opts.parentType == "connector" {
- labels["tailscale.com/parent-resource-ns"] = "" // Connector is cluster scoped
+ labels["github.com/metacubex/tailscale/parent-resource-ns"] = "" // Connector is cluster scoped
}
s.Labels = labels
for key, val := range opts.secretExtraData {
diff --git a/cmd/k8s-operator/tsclient.go b/cmd/k8s-operator/tsclient.go
index 702f4cc537240..4d3edea512598 100644
--- a/cmd/k8s-operator/tsclient.go
+++ b/cmd/k8s-operator/tsclient.go
@@ -18,7 +18,7 @@ import (
"golang.org/x/oauth2/clientcredentials"
"tailscale.com/client/tailscale/v2"
- "tailscale.com/ipn"
+ "github.com/metacubex/tailscale/ipn"
)
const (
diff --git a/cmd/k8s-operator/tsrecorder.go b/cmd/k8s-operator/tsrecorder.go
index 86669d212e738..3d7e922c80057 100644
--- a/cmd/k8s-operator/tsrecorder.go
+++ b/cmd/k8s-operator/tsrecorder.go
@@ -10,7 +10,7 @@ import (
"encoding/json"
"errors"
"fmt"
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strconv"
"strings"
"sync"
@@ -33,14 +33,14 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"tailscale.com/client/tailscale/v2"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/set"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/set"
)
const (
diff --git a/cmd/k8s-operator/tsrecorder_specs.go b/cmd/k8s-operator/tsrecorder_specs.go
index 5a93bc22b546c..34d2a063da95d 100644
--- a/cmd/k8s-operator/tsrecorder_specs.go
+++ b/cmd/k8s-operator/tsrecorder_specs.go
@@ -7,15 +7,15 @@ package main
import (
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/version"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/version"
)
func tsrStatefulSet(tsr *tsapi.Recorder, namespace string, loginServer string) *appsv1.StatefulSet {
diff --git a/cmd/k8s-operator/tsrecorder_specs_test.go b/cmd/k8s-operator/tsrecorder_specs_test.go
index 13da8a3c8781f..faa6888331704 100644
--- a/cmd/k8s-operator/tsrecorder_specs_test.go
+++ b/cmd/k8s-operator/tsrecorder_specs_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
@@ -13,7 +13,7 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
)
func TestRecorderSpecs(t *testing.T) {
diff --git a/cmd/k8s-operator/tsrecorder_test.go b/cmd/k8s-operator/tsrecorder_test.go
index 8f189728c0207..6eb1641d32f19 100644
--- a/cmd/k8s-operator/tsrecorder_test.go
+++ b/cmd/k8s-operator/tsrecorder_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
@@ -24,10 +24,10 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"tailscale.com/client/tailscale/v2"
- tsoperator "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/tstest"
+ tsoperator "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/tstest"
)
const (
@@ -39,7 +39,7 @@ func TestRecorder(t *testing.T) {
tsr := &tsapi.Recorder{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
- Finalizers: []string{"tailscale.com/finalizer"},
+ Finalizers: []string{"github.com/metacubex/tailscale/finalizer"},
},
Spec: tsapi.RecorderSpec{
Replicas: new(int32(3)),
diff --git a/cmd/k8s-proxy/internal/config/config.go b/cmd/k8s-proxy/internal/config/config.go
index c12383d45c470..ca9b3cd2ad0db 100644
--- a/cmd/k8s-proxy/internal/config/config.go
+++ b/cmd/k8s-proxy/internal/config/config.go
@@ -19,15 +19,15 @@ import (
"time"
"github.com/fsnotify/fsnotify"
+ "github.com/metacubex/tailscale/kube/k8s-proxy/conf"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/util/testenv"
"go.uber.org/zap"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/watch"
clientcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
- "tailscale.com/kube/k8s-proxy/conf"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/util/testenv"
)
type configLoader struct {
diff --git a/cmd/k8s-proxy/internal/config/config_test.go b/cmd/k8s-proxy/internal/config/config_test.go
index aedd29d4e1877..0562b00e89087 100644
--- a/cmd/k8s-proxy/internal/config/config_test.go
+++ b/cmd/k8s-proxy/internal/config/config_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,14 +14,14 @@ import (
"time"
"github.com/google/go-cmp/cmp"
+ "github.com/metacubex/tailscale/kube/k8s-proxy/conf"
+ "github.com/metacubex/tailscale/kube/kubetypes"
"go.uber.org/zap"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/kubernetes/fake"
ktesting "k8s.io/client-go/testing"
- "tailscale.com/kube/k8s-proxy/conf"
- "tailscale.com/kube/kubetypes"
)
func TestWatchConfig(t *testing.T) {
diff --git a/cmd/k8s-proxy/k8s-proxy.go b/cmd/k8s-proxy/k8s-proxy.go
index 673493f58cecd..63c0aa35de96e 100644
--- a/cmd/k8s-proxy/k8s-proxy.go
+++ b/cmd/k8s-proxy/k8s-proxy.go
@@ -22,6 +22,12 @@ import (
"syscall"
"time"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/cmd/k8s-proxy/internal/config"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/store"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"golang.org/x/sync/errgroup"
@@ -29,27 +35,21 @@ import (
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/utils/strings/slices"
- "tailscale.com/client/local"
- "tailscale.com/cmd/k8s-proxy/internal/config"
- "tailscale.com/health"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn"
- "tailscale.com/ipn/store"
// we need to import this package so that the `kube:` ipn store gets registered
- _ "tailscale.com/ipn/store/kubestore"
- apiproxy "tailscale.com/k8s-operator/api-proxy"
- "tailscale.com/kube/certs"
- healthz "tailscale.com/kube/health"
- "tailscale.com/kube/k8s-proxy/conf"
- "tailscale.com/kube/kubeclient"
- "tailscale.com/kube/kubetypes"
- klc "tailscale.com/kube/localclient"
- "tailscale.com/kube/metrics"
- "tailscale.com/kube/services"
- "tailscale.com/kube/state"
- "tailscale.com/tailcfg"
- "tailscale.com/tsnet"
+ _ "github.com/metacubex/tailscale/ipn/store/kubestore"
+ apiproxy "github.com/metacubex/tailscale/k8s-operator/api-proxy"
+ "github.com/metacubex/tailscale/kube/certs"
+ healthz "github.com/metacubex/tailscale/kube/health"
+ "github.com/metacubex/tailscale/kube/k8s-proxy/conf"
+ "github.com/metacubex/tailscale/kube/kubeclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ klc "github.com/metacubex/tailscale/kube/localclient"
+ "github.com/metacubex/tailscale/kube/metrics"
+ "github.com/metacubex/tailscale/kube/services"
+ "github.com/metacubex/tailscale/kube/state"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsnet"
)
const (
diff --git a/cmd/k8s-proxy/kube.go b/cmd/k8s-proxy/kube.go
index 1d9348f1a3bea..67f7eb3b65b2c 100644
--- a/cmd/k8s-proxy/kube.go
+++ b/cmd/k8s-proxy/kube.go
@@ -12,16 +12,16 @@ import (
"sync"
"time"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/kube/authkey"
+ "github.com/metacubex/tailscale/kube/k8s-proxy/conf"
+ "github.com/metacubex/tailscale/kube/kubeapi"
+ "github.com/metacubex/tailscale/kube/kubeclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tailcfg"
"go.uber.org/zap"
- "tailscale.com/client/local"
- "tailscale.com/health"
- "tailscale.com/ipn"
- "tailscale.com/kube/authkey"
- "tailscale.com/kube/k8s-proxy/conf"
- "tailscale.com/kube/kubeapi"
- "tailscale.com/kube/kubeclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tailcfg"
)
const k8sProxyFieldManager = "tailscale-k8s-proxy"
diff --git a/cmd/k8s-proxy/kube_test.go b/cmd/k8s-proxy/kube_test.go
index c7e0f33d02b9e..8c399289d372a 100644
--- a/cmd/k8s-proxy/kube_test.go
+++ b/cmd/k8s-proxy/kube_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package main
import (
@@ -11,11 +11,11 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
- "tailscale.com/health"
- "tailscale.com/kube/kubeapi"
- "tailscale.com/kube/kubeclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/kube/kubeapi"
+ "github.com/metacubex/tailscale/kube/kubeclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tailcfg"
)
func TestResetState(t *testing.T) {
diff --git a/cmd/mkversion/mkversion.go b/cmd/mkversion/mkversion.go
index ec9b0bb85ace4..e7d41966a1ef9 100644
--- a/cmd/mkversion/mkversion.go
+++ b/cmd/mkversion/mkversion.go
@@ -14,8 +14,8 @@ import (
"os"
"time"
- "tailscale.com/tailcfg"
- "tailscale.com/version/mkversion"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/version/mkversion"
)
func main() {
diff --git a/cmd/nardump/nardump.go b/cmd/nardump/nardump.go
index 38a2a67319595..454984708ac76 100644
--- a/cmd/nardump/nardump.go
+++ b/cmd/nardump/nardump.go
@@ -15,7 +15,7 @@ import (
"log"
"os"
- "tailscale.com/cmd/nardump/nardump"
+ "github.com/metacubex/tailscale/cmd/nardump/nardump"
)
var sri = flag.Bool("sri", false, "print SRI")
diff --git a/cmd/nardump/nardump/nardump_test.go b/cmd/nardump/nardump/nardump_test.go
index 16b690ee257f0..2e4470fbd46c0 100644
--- a/cmd/nardump/nardump/nardump_test.go
+++ b/cmd/nardump/nardump/nardump_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/cmd/natc/ippool/consensusippool.go b/cmd/natc/ippool/consensusippool.go
index d595d3e7ddc7a..5627798ea97cc 100644
--- a/cmd/natc/ippool/consensusippool.go
+++ b/cmd/natc/ippool/consensusippool.go
@@ -13,12 +13,12 @@ import (
"time"
"github.com/hashicorp/raft"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsconsensus"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/util/mak"
"go4.org/netipx"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tsconsensus"
- "tailscale.com/tsnet"
- "tailscale.com/util/mak"
)
// ConsensusIPPool implements an [IPPool] that is distributed among members of a cluster for high availability.
diff --git a/cmd/natc/ippool/consensusippool_test.go b/cmd/natc/ippool/consensusippool_test.go
index fe42b2b223a8b..39db0f4c765eb 100644
--- a/cmd/natc/ippool/consensusippool_test.go
+++ b/cmd/natc/ippool/consensusippool_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -13,10 +15,10 @@ import (
"time"
"github.com/hashicorp/raft"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsconsensus"
+ "github.com/metacubex/tailscale/util/must"
"go4.org/netipx"
- "tailscale.com/tailcfg"
- "tailscale.com/tsconsensus"
- "tailscale.com/util/must"
)
func makeSetFromPrefix(pfx netip.Prefix) *netipx.IPSet {
diff --git a/cmd/natc/ippool/consensusippoolserialize.go b/cmd/natc/ippool/consensusippoolserialize.go
index be3312d300bad..62a1b4a6fff83 100644
--- a/cmd/natc/ippool/consensusippoolserialize.go
+++ b/cmd/natc/ippool/consensusippoolserialize.go
@@ -5,15 +5,15 @@ package ippool
import (
"encoding/json"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"io"
"log"
- "maps"
"net/netip"
"github.com/hashicorp/raft"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
"go4.org/netipx"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
)
// Snapshot and Restore enable the raft lib to do log compaction.
diff --git a/cmd/natc/ippool/ippool.go b/cmd/natc/ippool/ippool.go
index 641702f5d31e8..e089878354dfd 100644
--- a/cmd/natc/ippool/ippool.go
+++ b/cmd/natc/ippool/ippool.go
@@ -12,12 +12,12 @@ import (
"sync"
"time"
- "github.com/gaissmai/bart"
+ "github.com/metacubex/bart"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/mak"
"go4.org/netipx"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/mak"
)
var ErrNoIPsAvailable = errors.New("no IPs available")
diff --git a/cmd/natc/ippool/ippool_test.go b/cmd/natc/ippool/ippool_test.go
index af0053c2f54d8..5419d1b0a1021 100644
--- a/cmd/natc/ippool/ippool_test.go
+++ b/cmd/natc/ippool/ippool_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,9 +12,9 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/must"
"go4.org/netipx"
- "tailscale.com/tailcfg"
- "tailscale.com/util/must"
)
func TestIPPoolExhaustion(t *testing.T) {
diff --git a/cmd/natc/ippool/ipx.go b/cmd/natc/ippool/ipx.go
index 4f52d6ede049a..ea4b1e2da16a7 100644
--- a/cmd/natc/ippool/ipx.go
+++ b/cmd/natc/ippool/ipx.go
@@ -4,9 +4,9 @@
package ippool
import (
+ "github.com/metacubex/tailscale/util/go120/randv2"
"math/big"
"math/bits"
- "math/rand/v2"
"net/netip"
"go4.org/netipx"
diff --git a/cmd/natc/ippool/ipx_test.go b/cmd/natc/ippool/ipx_test.go
index cb6889b683978..df2bbc508c9a1 100644
--- a/cmd/natc/ippool/ipx_test.go
+++ b/cmd/natc/ippool/ipx_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,8 +11,8 @@ import (
"net/netip"
"testing"
+ "github.com/metacubex/tailscale/util/must"
"go4.org/netipx"
- "tailscale.com/util/must"
)
func TestV4ToNum(t *testing.T) {
diff --git a/cmd/natc/natc.go b/cmd/natc/natc.go
index 877f16cc02689..135adcc44cbcb 100644
--- a/cmd/natc/natc.go
+++ b/cmd/natc/natc.go
@@ -13,8 +13,8 @@ import (
"expvar"
"flag"
"fmt"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"log"
- "math/rand/v2"
"net"
"net/http"
"net/netip"
@@ -23,24 +23,24 @@ import (
"strings"
"time"
- "github.com/gaissmai/bart"
"github.com/hashicorp/raft"
"github.com/inetaf/tcpproxy"
+ "github.com/metacubex/bart"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/cmd/natc/ippool"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/net/netutil"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/tsweb"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/wgengine/netstack"
"github.com/peterbourgon/ff/v3"
"go4.org/netipx"
"golang.org/x/net/dns/dnsmessage"
- "tailscale.com/client/local"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/cmd/natc/ippool"
- "tailscale.com/envknob"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn"
- "tailscale.com/net/netutil"
- "tailscale.com/tsnet"
- "tailscale.com/tsweb"
- "tailscale.com/util/mak"
- "tailscale.com/util/must"
- "tailscale.com/wgengine/netstack"
)
func main() {
diff --git a/cmd/natc/natc_test.go b/cmd/natc/natc_test.go
index 00c94868ec8a2..ad42d37ff2f9d 100644
--- a/cmd/natc/natc_test.go
+++ b/cmd/natc/natc_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -13,12 +15,12 @@ import (
"testing"
"time"
- "github.com/gaissmai/bart"
+ "github.com/metacubex/bart"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/cmd/natc/ippool"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/must"
"golang.org/x/net/dns/dnsmessage"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/cmd/natc/ippool"
- "tailscale.com/tailcfg"
- "tailscale.com/util/must"
)
func prefixEqual(a, b netip.Prefix) bool {
diff --git a/cmd/netlogfmt/main.go b/cmd/netlogfmt/main.go
index 212b36fb6b0ae..f70a2c29641cb 100644
--- a/cmd/netlogfmt/main.go
+++ b/cmd/netlogfmt/main.go
@@ -2,13 +2,13 @@
// SPDX-License-Identifier: BSD-3-Clause
// netlogfmt parses a stream of JSON log messages from stdin and
-// formats the network traffic logs produced by "tailscale.com/wgengine/netlog"
-// according to the schema in "tailscale.com/types/netlogtype.Message"
+// formats the network traffic logs produced by "github.com/metacubex/tailscale/wgengine/netlog"
+// according to the schema in "github.com/metacubex/tailscale/types/netlogtype.Message"
// in a more humanly readable format.
//
// Example usage:
//
-// $ cat netlog.json | go run tailscale.com/cmd/netlogfmt
+// $ cat netlog.json | go run github.com/metacubex/tailscale/cmd/netlogfmt
// =========================================================================================
// NodeID: n123456CNTRL
// Logged: 2022-10-13T20:23:10.165Z
@@ -25,30 +25,30 @@
package main
import (
- "cmp"
"encoding/base64"
"encoding/json"
"flag"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
"math"
"net/http"
"net/netip"
"os"
- "slices"
"strconv"
"strings"
"time"
"github.com/dsnet/try"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/tailcfg"
- "tailscale.com/types/bools"
- "tailscale.com/types/logid"
- "tailscale.com/types/netlogtype"
- "tailscale.com/util/must"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/bools"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/types/netlogtype"
+ "github.com/metacubex/tailscale/util/must"
)
var (
@@ -57,8 +57,8 @@ var (
"If network flow logs do not support embedded node information,\n"+
"then --api-key and --tailnet-name must also be provided.\n"+
"Valid values include \"nodeId\", \"name\", or \"user\".")
- apiKey = flag.String("api-key", "", "The API key to query the Tailscale API with.\nSee https://login.tailscale.com/admin/settings/keys")
- tailnetName = flag.String("tailnet-name", "", "The Tailnet name to lookup nodes within.\nSee https://login.tailscale.com/admin/settings/general")
+ apiKey = flag.String("api-key", "", "The API key to query the Tailscale API with.\nSee https://login.github.com/metacubex/tailscale/admin/settings/keys")
+ tailnetName = flag.String("tailnet-name", "", "The Tailnet name to lookup nodes within.\nSee https://login.github.com/metacubex/tailscale/admin/settings/general")
)
var (
@@ -352,7 +352,7 @@ func mustLoadTailnetNodes() {
}
// Query the Tailscale API for a list of devices in the tailnet.
- const apiURL = "https://api.tailscale.com/api/v2"
+ const apiURL = "https://api.github.com/metacubex/tailscale/api/v2"
req := must.Get(http.NewRequest("GET", apiURL+"/tailnet/"+*tailnetName+"/devices", nil))
req.Header.Add("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(*apiKey+":")))
resp := must.Get(http.DefaultClient.Do(req))
diff --git a/cmd/nginx-auth/nginx-auth.go b/cmd/nginx-auth/nginx-auth.go
index 6b791eb6c35fa..71949b2c46685 100644
--- a/cmd/nginx-auth/nginx-auth.go
+++ b/cmd/nginx-auth/nginx-auth.go
@@ -20,8 +20,8 @@ import (
"os"
"strings"
+ "github.com/metacubex/tailscale/client/tailscale"
"github.com/coreos/go-systemd/activation"
- "tailscale.com/client/tailscale"
)
var (
diff --git a/cmd/omitsize/omitsize.go b/cmd/omitsize/omitsize.go
index 84863865991bc..71155e1732b33 100644
--- a/cmd/omitsize/omitsize.go
+++ b/cmd/omitsize/omitsize.go
@@ -9,18 +9,18 @@ import (
"crypto/sha256"
"flag"
"fmt"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
- "maps"
"os"
"os/exec"
"path/filepath"
- "slices"
"strconv"
"strings"
"sync"
- "tailscale.com/feature/featuretags"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/feature/featuretags"
+ "github.com/metacubex/tailscale/util/set"
)
var (
diff --git a/cmd/pgproxy/pgproxy.go b/cmd/pgproxy/pgproxy.go
index a138eacdce4fc..30e182e1eaf41 100644
--- a/cmd/pgproxy/pgproxy.go
+++ b/cmd/pgproxy/pgproxy.go
@@ -24,10 +24,10 @@ import (
"strings"
"time"
- "tailscale.com/client/local"
- "tailscale.com/metrics"
- "tailscale.com/tsnet"
- "tailscale.com/tsweb"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/metrics"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/tsweb"
)
var (
diff --git a/cmd/printdep/printdep.go b/cmd/printdep/printdep.go
index f5aeab7a561b6..48963481a33cd 100644
--- a/cmd/printdep/printdep.go
+++ b/cmd/printdep/printdep.go
@@ -12,7 +12,7 @@ import (
"runtime"
"strings"
- ts "tailscale.com"
+ ts "github.com/metacubex/tailscale"
)
var (
diff --git a/cmd/proxy-test-server/proxy-test-server.go b/cmd/proxy-test-server/proxy-test-server.go
index 2c705670446ba..944c53099d613 100644
--- a/cmd/proxy-test-server/proxy-test-server.go
+++ b/cmd/proxy-test-server/proxy-test-server.go
@@ -15,9 +15,9 @@ import (
"os"
"strings"
+ "github.com/metacubex/tailscale/net/connectproxy"
+ "github.com/metacubex/tailscale/tempfork/acme"
"golang.org/x/crypto/acme/autocert"
- "tailscale.com/net/connectproxy"
- "tailscale.com/tempfork/acme"
)
var (
diff --git a/cmd/proxy-to-grafana/proxy-to-grafana.go b/cmd/proxy-to-grafana/proxy-to-grafana.go
index 23f2640597d59..b214a3ac918b3 100644
--- a/cmd/proxy-to-grafana/proxy-to-grafana.go
+++ b/cmd/proxy-to-grafana/proxy-to-grafana.go
@@ -30,7 +30,7 @@
// "src": ["group:eng"],
// "dst": ["tag:grafana"],
// "app": {
-// "tailscale.com/cap/proxy-to-grafana": [{
+// "github.com/metacubex/tailscale/cap/proxy-to-grafana": [{
// "role": "editor",
// }],
// },
@@ -53,9 +53,9 @@ import (
"strings"
"time"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/tailcfg"
- "tailscale.com/tsnet"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsnet"
)
var (
@@ -67,7 +67,7 @@ var (
)
// aclCap is the Tailscale ACL capability used to configure proxy-to-grafana.
-const aclCap tailcfg.PeerCapability = "tailscale.com/cap/proxy-to-grafana"
+const aclCap tailcfg.PeerCapability = "github.com/metacubex/tailscale/cap/proxy-to-grafana"
// aclGrant is an access control rule that assigns Grafana permissions
// while provisioning a user.
diff --git a/cmd/proxy-to-grafana/proxy-to-grafana_test.go b/cmd/proxy-to-grafana/proxy-to-grafana_test.go
index be217043f12d3..e23bfe3b53953 100644
--- a/cmd/proxy-to-grafana/proxy-to-grafana_test.go
+++ b/cmd/proxy-to-grafana/proxy-to-grafana_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,8 +11,8 @@ import (
"net/http/httptest"
"testing"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/tailcfg"
)
type mockWhoisSource struct {
diff --git a/cmd/sniproxy/handlers.go b/cmd/sniproxy/handlers.go
index 157b9b75f885a..44d3a9e46f2cd 100644
--- a/cmd/sniproxy/handlers.go
+++ b/cmd/sniproxy/handlers.go
@@ -6,15 +6,15 @@ package main
import (
"context"
"fmt"
+ "github.com/metacubex/tailscale/util/go120/randv2"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
- "math/rand/v2"
"net"
"net/netip"
- "slices"
"github.com/inetaf/tcpproxy"
- "tailscale.com/net/netutil"
- "tailscale.com/net/netx"
+ "github.com/metacubex/tailscale/net/netutil"
+ "github.com/metacubex/tailscale/net/netx"
)
type tcpRoundRobinHandler struct {
diff --git a/cmd/sniproxy/handlers_test.go b/cmd/sniproxy/handlers_test.go
index ad0637421cecc..8c162eb1a1e04 100644
--- a/cmd/sniproxy/handlers_test.go
+++ b/cmd/sniproxy/handlers_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -13,7 +15,7 @@ import (
"strings"
"testing"
- "tailscale.com/net/memnet"
+ "github.com/metacubex/tailscale/net/memnet"
)
func echoConnOnce(conn net.Conn) {
diff --git a/cmd/sniproxy/server.go b/cmd/sniproxy/server.go
index 0ff301fe92136..721bc81d4de75 100644
--- a/cmd/sniproxy/server.go
+++ b/cmd/sniproxy/server.go
@@ -11,14 +11,14 @@ import (
"sync"
"time"
+ "github.com/metacubex/tailscale/metrics"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/appctype"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/nettype"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/mak"
"golang.org/x/net/dns/dnsmessage"
- "tailscale.com/metrics"
- "tailscale.com/tailcfg"
- "tailscale.com/types/appctype"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/nettype"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/mak"
)
var tsMBox = dnsmessage.MustNewName("support.tailscale.com.")
diff --git a/cmd/sniproxy/server_test.go b/cmd/sniproxy/server_test.go
index 8e06e8abedf8c..ee9e5f1e679d2 100644
--- a/cmd/sniproxy/server_test.go
+++ b/cmd/sniproxy/server_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,8 +11,8 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/tailcfg"
- "tailscale.com/types/appctype"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/appctype"
)
func TestMakeConnectorsFromConfig(t *testing.T) {
diff --git a/cmd/sniproxy/sniproxy.go b/cmd/sniproxy/sniproxy.go
index f7ebc6abaa4e5..f8f1eaa70673e 100644
--- a/cmd/sniproxy/sniproxy.go
+++ b/cmd/sniproxy/sniproxy.go
@@ -21,20 +21,20 @@ import (
"strconv"
"strings"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/tsweb"
+ "github.com/metacubex/tailscale/types/appctype"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/nettype"
+ "github.com/metacubex/tailscale/util/mak"
"github.com/peterbourgon/ff/v3"
- "tailscale.com/client/local"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn"
- "tailscale.com/tailcfg"
- "tailscale.com/tsnet"
- "tailscale.com/tsweb"
- "tailscale.com/types/appctype"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/nettype"
- "tailscale.com/util/mak"
)
-const configCapKey = "tailscale.com/sniproxy"
+const configCapKey = "github.com/metacubex/tailscale/sniproxy"
// portForward is the state for a single port forwarding entry, as passed to the --forward flag.
type portForward struct {
diff --git a/cmd/sniproxy/sniproxy_test.go b/cmd/sniproxy/sniproxy_test.go
index a404799d29d7d..ba58bf557e958 100644
--- a/cmd/sniproxy/sniproxy_test.go
+++ b/cmd/sniproxy/sniproxy_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -19,17 +21,17 @@ import (
"time"
"github.com/google/go-cmp/cmp"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/net/netns"
- "tailscale.com/tailcfg"
- "tailscale.com/tsnet"
- "tailscale.com/tstest/integration"
- "tailscale.com/tstest/integration/testcontrol"
- "tailscale.com/tstest/nettest"
- "tailscale.com/types/appctype"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/tstest/integration"
+ "github.com/metacubex/tailscale/tstest/integration/testcontrol"
+ "github.com/metacubex/tailscale/tstest/nettest"
+ "github.com/metacubex/tailscale/types/appctype"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
)
func TestPortForwardingArguments(t *testing.T) {
diff --git a/cmd/speedtest/speedtest.go b/cmd/speedtest/speedtest.go
index e11c4ad1d90bb..dfc75530bf5cf 100644
--- a/cmd/speedtest/speedtest.go
+++ b/cmd/speedtest/speedtest.go
@@ -22,8 +22,8 @@ import (
"text/tabwriter"
"time"
+ "github.com/metacubex/tailscale/net/speedtest"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/net/speedtest"
)
// Runs the speedtest command as a commandline program
diff --git a/cmd/stunc/stunc.go b/cmd/stunc/stunc.go
index e51cd15ba2248..6c8bb8331d0a4 100644
--- a/cmd/stunc/stunc.go
+++ b/cmd/stunc/stunc.go
@@ -12,7 +12,7 @@ import (
"strconv"
"time"
- "tailscale.com/net/stun"
+ "github.com/metacubex/tailscale/net/stun"
)
func main() {
diff --git a/cmd/stund/depaware.txt b/cmd/stund/depaware.txt
index 7804915dc7e05..bf3347606d056 100644
--- a/cmd/stund/depaware.txt
+++ b/cmd/stund/depaware.txt
@@ -3,12 +3,12 @@ tailscale.com/cmd/stund dependencies: (generated by github.com/tailscale/depawar
💣 crypto/internal/entropy/v1.0.0 from crypto/internal/fips140/drbg
github.com/beorn7/perks/quantile from github.com/prometheus/client_golang/prometheus
💣 github.com/cespare/xxhash/v2 from github.com/prometheus/client_golang/prometheus
- github.com/go-json-experiment/json from tailscale.com/types/opt+
- github.com/go-json-experiment/json/internal from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonflags from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonopts from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonwire from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/jsontext from github.com/go-json-experiment/json+
+ github.com/metacubex/jsonv2 from tailscale.com/types/opt+
+ github.com/metacubex/jsonv2/internal from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonflags from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonopts from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonwire from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/jsontext from github.com/metacubex/jsonv2+
github.com/munnerz/goautoneg from github.com/prometheus/common/expfmt
💣 github.com/prometheus/client_golang/prometheus from tailscale.com/tsweb/promvarz
github.com/prometheus/client_golang/prometheus/internal from github.com/prometheus/client_golang/prometheus
@@ -193,7 +193,7 @@ tailscale.com/cmd/stund dependencies: (generated by github.com/tailscale/depawar
embed from google.golang.org/protobuf/internal/editiondefaults+
encoding from encoding/json+
encoding/asn1 from crypto/x509+
- encoding/base32 from github.com/go-json-experiment/json
+ encoding/base32 from github.com/metacubex/jsonv2
encoding/base64 from encoding/json+
encoding/binary from compress/gzip+
encoding/hex from crypto/x509+
diff --git a/cmd/stund/stund.go b/cmd/stund/stund.go
index a27e520444464..fca52b74725e2 100644
--- a/cmd/stund/stund.go
+++ b/cmd/stund/stund.go
@@ -13,11 +13,11 @@ import (
"os/signal"
"syscall"
- "tailscale.com/net/stunserver"
- "tailscale.com/tsweb"
+ "github.com/metacubex/tailscale/net/stunserver"
+ "github.com/metacubex/tailscale/tsweb"
// Support for prometheus varz in tsweb
- _ "tailscale.com/tsweb/promvarz"
+ _ "github.com/metacubex/tailscale/tsweb/promvarz"
)
var (
diff --git a/cmd/stunstamp/stunstamp.go b/cmd/stunstamp/stunstamp.go
index 743d6aec3c9d8..d437eed2c73b3 100644
--- a/cmd/stunstamp/stunstamp.go
+++ b/cmd/stunstamp/stunstamp.go
@@ -6,17 +6,18 @@ package main
import (
"bytes"
- "cmp"
"context"
"crypto/tls"
"encoding/json"
"errors"
"flag"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ "github.com/metacubex/tailscale/util/go120/randv2"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
"math"
- "math/rand/v2"
"net"
"net/http"
"net/netip"
@@ -24,7 +25,6 @@ import (
"os"
"os/signal"
"runtime"
- "slices"
"strconv"
"strings"
"sync"
@@ -32,16 +32,16 @@ import (
"time"
"github.com/golang/snappy"
+ "github.com/metacubex/tailscale/net/stun"
+ "github.com/metacubex/tailscale/net/tcpinfo"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/backoff"
"github.com/prometheus/prometheus/prompb"
"github.com/tcnksm/go-httpstat"
- "tailscale.com/net/stun"
- "tailscale.com/net/tcpinfo"
- "tailscale.com/tailcfg"
- "tailscale.com/util/backoff"
)
var (
- flagDERPMap = flag.String("derp-map", "https://login.tailscale.com/derpmap/default", "URL to DERP map")
+ flagDERPMap = flag.String("derp-map", "https://login.github.com/metacubex/tailscale/derpmap/default", "URL to DERP map")
flagInterval = flag.Duration("interval", time.Minute, "interval to probe at in time.ParseDuration() format")
flagIPv6 = flag.Bool("ipv6", false, "probe IPv6 addresses")
flagRemoteWriteURL = flag.String("rw-url", "", "prometheus remote write URL")
diff --git a/cmd/stunstamp/stunstamp_linux.go b/cmd/stunstamp/stunstamp_linux.go
index 201e2f83b384c..68c12ee039aa2 100644
--- a/cmd/stunstamp/stunstamp_linux.go
+++ b/cmd/stunstamp/stunstamp_linux.go
@@ -9,19 +9,19 @@ import (
"encoding/binary"
"errors"
"fmt"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"io"
"math"
- "math/rand/v2"
"net/netip"
"syscall"
"time"
"github.com/mdlayher/socket"
+ "github.com/metacubex/tailscale/net/stun"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
"golang.org/x/sys/unix"
- "tailscale.com/net/stun"
)
const (
diff --git a/cmd/systray/systray.go b/cmd/systray/systray.go
index 68a3397820274..c71a84f3a1c97 100644
--- a/cmd/systray/systray.go
+++ b/cmd/systray/systray.go
@@ -9,9 +9,9 @@ package main
import (
"flag"
- "tailscale.com/client/local"
- "tailscale.com/client/systray"
- "tailscale.com/paths"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/client/systray"
+ "github.com/metacubex/tailscale/paths"
)
var socket = flag.String("socket", paths.DefaultTailscaledSocket(), "path to tailscaled socket")
diff --git a/cmd/tailscale/cli/appcroutes.go b/cmd/tailscale/cli/appcroutes.go
index 04cbcdd832258..92cb16c1abbc6 100644
--- a/cmd/tailscale/cli/appcroutes.go
+++ b/cmd/tailscale/cli/appcroutes.go
@@ -8,11 +8,11 @@ import (
"encoding/json"
"flag"
"fmt"
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
+ "github.com/metacubex/tailscale/types/appctype"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/types/appctype"
)
var appcRoutesArgs struct {
@@ -47,7 +47,7 @@ in the the policy app connector 'routes' field.
-n prints the total number of routes advertised by this device, whether learned, set in the policy, or set locally.
For more information about App Connectors, refer to
-https://tailscale.com/kb/1281/app-connectors
+https://github.com/metacubex/tailscale/kb/1281/app-connectors
`),
}
diff --git a/cmd/tailscale/cli/bugreport.go b/cmd/tailscale/cli/bugreport.go
index 3ffaffa8b1fa5..df751f257f94d 100644
--- a/cmd/tailscale/cli/bugreport.go
+++ b/cmd/tailscale/cli/bugreport.go
@@ -9,8 +9,8 @@ import (
"flag"
"fmt"
+ "github.com/metacubex/tailscale/client/local"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/client/local"
)
var bugReportCmd = &ffcli.Command{
diff --git a/cmd/tailscale/cli/cert.go b/cmd/tailscale/cli/cert.go
index 6d78a8d8abf5f..824ded1bf388f 100644
--- a/cmd/tailscale/cli/cert.go
+++ b/cmd/tailscale/cli/cert.go
@@ -20,11 +20,11 @@ import (
"strings"
"time"
+ "github.com/metacubex/tailscale/atomicfile"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/version"
"github.com/peterbourgon/ff/v3/ffcli"
"software.sslmate.com/src/go-pkcs12"
- "tailscale.com/atomicfile"
- "tailscale.com/ipn"
- "tailscale.com/version"
)
func init() {
diff --git a/cmd/tailscale/cli/cli.go b/cmd/tailscale/cli/cli.go
index 16a14461cb556..dc8ab063bf876 100644
--- a/cmd/tailscale/cli/cli.go
+++ b/cmd/tailscale/cli/cli.go
@@ -21,15 +21,15 @@ import (
"text/tabwriter"
"time"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/cmd/tailscale/cli/ffcomplete"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/paths"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/util/testenv"
+ "github.com/metacubex/tailscale/version/distro"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/client/local"
- "tailscale.com/cmd/tailscale/cli/ffcomplete"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/paths"
- "tailscale.com/util/slicesx"
- "tailscale.com/util/testenv"
- "tailscale.com/version/distro"
)
var Stderr io.Writer = os.Stderr
diff --git a/cmd/tailscale/cli/cli_test.go b/cmd/tailscale/cli/cli_test.go
index d2df825d3786b..b30ee01c8e99a 100644
--- a/cmd/tailscale/cli/cli_test.go
+++ b/cmd/tailscale/cli/cli_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,11 +7,11 @@ package cli
import (
"bytes"
- stdcmp "cmp"
"context"
"encoding/json"
"flag"
"fmt"
+ stdcmp "github.com/metacubex/tailscale/util/go120/cmp"
"io"
"net/netip"
"os"
@@ -20,22 +22,22 @@ import (
qt "github.com/frankban/quicktest"
"github.com/google/go-cmp/cmp"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/health/healthmsg"
+ "github.com/metacubex/tailscale/internal/client/tailscale"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstest/deptest"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/types/preftype"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/version/distro"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/envknob"
- "tailscale.com/health/healthmsg"
- "tailscale.com/internal/client/tailscale"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/tka"
- "tailscale.com/tstest"
- "tailscale.com/tstest/deptest"
- "tailscale.com/types/logger"
- "tailscale.com/types/opt"
- "tailscale.com/types/persist"
- "tailscale.com/types/preftype"
- "tailscale.com/util/set"
- "tailscale.com/version/distro"
)
func TestPanicIfAnyEnvCheckedInInit(t *testing.T) {
@@ -1809,12 +1811,12 @@ func TestDeps(t *testing.T) {
GOOS: "linux",
GOARCH: "arm64",
WantDeps: set.Of(
- "tailscale.com/feature/capture/dissector", // want the Lua by default
+ "github.com/metacubex/tailscale/feature/capture/dissector", // want the Lua by default
),
BadDeps: map[string]string{
- "tailscale.com/feature/capture": "don't link capture code",
- "tailscale.com/net/packet": "why we passing packets in the CLI?",
- "tailscale.com/net/flowtrack": "why we tracking flows in the CLI?",
+ "github.com/metacubex/tailscale/feature/capture": "don't link capture code",
+ "github.com/metacubex/tailscale/net/packet": "why we passing packets in the CLI?",
+ "github.com/metacubex/tailscale/net/flowtrack": "why we tracking flows in the CLI?",
},
}.Check(t)
}
@@ -1825,8 +1827,8 @@ func TestDepsNoCapture(t *testing.T) {
GOARCH: "arm64",
Tags: "ts_omit_capture",
BadDeps: map[string]string{
- "tailscale.com/feature/capture": "don't link capture code",
- "tailscale.com/feature/capture/dissector": "don't like the Lua",
+ "github.com/metacubex/tailscale/feature/capture": "don't link capture code",
+ "github.com/metacubex/tailscale/feature/capture/dissector": "don't like the Lua",
},
}.Check(t)
diff --git a/cmd/tailscale/cli/configure-jetkvm.go b/cmd/tailscale/cli/configure-jetkvm.go
index 1956ac836fe74..ba98282dd3a9b 100644
--- a/cmd/tailscale/cli/configure-jetkvm.go
+++ b/cmd/tailscale/cli/configure-jetkvm.go
@@ -14,8 +14,8 @@ import (
"runtime"
"strings"
+ "github.com/metacubex/tailscale/version/distro"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/version/distro"
)
func init() {
diff --git a/cmd/tailscale/cli/configure-kube.go b/cmd/tailscale/cli/configure-kube.go
index 8160025c6858e..5bc69705abb54 100644
--- a/cmd/tailscale/cli/configure-kube.go
+++ b/cmd/tailscale/cli/configure-kube.go
@@ -9,21 +9,21 @@ import (
"errors"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"net/url"
"os"
"path/filepath"
- "slices"
"strings"
"time"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/version"
"github.com/peterbourgon/ff/v3/ffcli"
"k8s.io/client-go/util/homedir"
"sigs.k8s.io/yaml"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/util/dnsname"
- "tailscale.com/version"
)
var configureKubeconfigArgs struct {
@@ -40,7 +40,7 @@ Run this command to configure kubectl to connect to a Kubernetes cluster over Ta
The hostname argument should be set to the Tailscale hostname of the peer running as an auth proxy in the cluster.
-See: https://tailscale.com/s/k8s-auth-proxy
+See: https://github.com/metacubex/tailscale/s/k8s-auth-proxy
`),
FlagSet: (func() *flag.FlagSet {
fs := newFlagSet("kubeconfig")
diff --git a/cmd/tailscale/cli/configure-kube_test.go b/cmd/tailscale/cli/configure-kube_test.go
index 2c2a05ac0c08f..2ef25e8377e00 100644
--- a/cmd/tailscale/cli/configure-kube_test.go
+++ b/cmd/tailscale/cli/configure-kube_test.go
@@ -1,6 +1,7 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_kube
package cli
diff --git a/cmd/tailscale/cli/configure-synology-cert.go b/cmd/tailscale/cli/configure-synology-cert.go
index 32f5bbd70593c..e568c5320ceac 100644
--- a/cmd/tailscale/cli/configure-synology-cert.go
+++ b/cmd/tailscale/cli/configure-synology-cert.go
@@ -11,18 +11,18 @@ import (
"errors"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
"os"
"os/exec"
"path"
"runtime"
- "slices"
"strings"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/version/distro"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn"
- "tailscale.com/version/distro"
)
func init() {
@@ -42,7 +42,7 @@ func synologyConfigureCertCmd() *ffcli.Command {
This command is intended to run periodically as root on a Synology device to
create or refresh the TLS certificate for the tailnet domain.
-See: https://tailscale.com/kb/1153/enabling-https
+See: https://github.com/metacubex/tailscale/kb/1153/enabling-https
`),
FlagSet: (func() *flag.FlagSet {
fs := newFlagSet("synology-cert")
diff --git a/cmd/tailscale/cli/configure-synology-cert_test.go b/cmd/tailscale/cli/configure-synology-cert_test.go
index d79ceb9d362b8..acb23f42a68e3 100644
--- a/cmd/tailscale/cli/configure-synology-cert_test.go
+++ b/cmd/tailscale/cli/configure-synology-cert_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux && !ts_omit_acme
-
package cli
import (
diff --git a/cmd/tailscale/cli/configure-synology.go b/cmd/tailscale/cli/configure-synology.go
index 4cfd4160e066a..647fbedf33e07 100644
--- a/cmd/tailscale/cli/configure-synology.go
+++ b/cmd/tailscale/cli/configure-synology.go
@@ -13,9 +13,9 @@ import (
"runtime"
"strings"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/version/distro"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/hostinfo"
- "tailscale.com/version/distro"
)
// configureHostCmd is the "tailscale configure-host" command which was once
@@ -57,7 +57,7 @@ This command is intended to run at boot as root on a Synology device to
create the /dev/net/tun device and give the tailscaled binary permission
to use it.
-See: https://tailscale.com/s/synology-outbound
+See: https://github.com/metacubex/tailscale/s/synology-outbound
`),
FlagSet: (func() *flag.FlagSet {
fs := newFlagSet("synology")
diff --git a/cmd/tailscale/cli/configure_linux.go b/cmd/tailscale/cli/configure_linux.go
index da04449087558..097e216941069 100644
--- a/cmd/tailscale/cli/configure_linux.go
+++ b/cmd/tailscale/cli/configure_linux.go
@@ -10,8 +10,8 @@ import (
"flag"
"fmt"
+ "github.com/metacubex/tailscale/client/systray"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/client/systray"
)
func init() {
diff --git a/cmd/tailscale/cli/debug-capture.go b/cmd/tailscale/cli/debug-capture.go
index ce282b291a587..13e053ae52bea 100644
--- a/cmd/tailscale/cli/debug-capture.go
+++ b/cmd/tailscale/cli/debug-capture.go
@@ -13,8 +13,8 @@ import (
"os"
"os/exec"
+ "github.com/metacubex/tailscale/feature/capture/dissector"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/feature/capture/dissector"
)
func init() {
diff --git a/cmd/tailscale/cli/debug-peer-relay.go b/cmd/tailscale/cli/debug-peer-relay.go
index 1b28c3f6bb1a4..3b6e837ebbf6f 100644
--- a/cmd/tailscale/cli/debug-peer-relay.go
+++ b/cmd/tailscale/cli/debug-peer-relay.go
@@ -7,14 +7,14 @@ package cli
import (
"bytes"
- "cmp"
"context"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
+ "github.com/metacubex/tailscale/net/udprelay/status"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/net/udprelay/status"
)
func init() {
diff --git a/cmd/tailscale/cli/debug-portmap.go b/cmd/tailscale/cli/debug-portmap.go
index a876971ef00b4..448a8d5518fcf 100644
--- a/cmd/tailscale/cli/debug-portmap.go
+++ b/cmd/tailscale/cli/debug-portmap.go
@@ -14,8 +14,8 @@ import (
"os"
"time"
+ "github.com/metacubex/tailscale/client/local"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/client/local"
)
func init() {
diff --git a/cmd/tailscale/cli/debug.go b/cmd/tailscale/cli/debug.go
index 3531172bbf1f6..e4d88fe261eef 100644
--- a/cmd/tailscale/cli/debug.go
+++ b/cmd/tailscale/cli/debug.go
@@ -6,13 +6,13 @@ package cli
import (
"bufio"
"bytes"
- "cmp"
"context"
"encoding/binary"
"encoding/json"
"errors"
"flag"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"io"
"log"
"net"
@@ -28,26 +28,26 @@ import (
"strings"
"time"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/control/ts2021"
+ "github.com/metacubex/tailscale/feature"
+ _ "github.com/metacubex/tailscale/feature/condregister/useproxy"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/net/ace"
+ "github.com/metacubex/tailscale/net/dnscache"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/paths"
+ "github.com/metacubex/tailscale/safesocket"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/must"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/control/ts2021"
- "tailscale.com/feature"
- _ "tailscale.com/feature/condregister/useproxy"
- "tailscale.com/health"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn"
- "tailscale.com/net/ace"
- "tailscale.com/net/dnscache"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsaddr"
- "tailscale.com/net/tsdial"
- "tailscale.com/paths"
- "tailscale.com/safesocket"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/must"
)
var (
diff --git a/cmd/tailscale/cli/diag.go b/cmd/tailscale/cli/diag.go
index 8a244ba8817bb..2615ed735d9b6 100644
--- a/cmd/tailscale/cli/diag.go
+++ b/cmd/tailscale/cli/diag.go
@@ -12,8 +12,8 @@ import (
"runtime"
"strings"
+ "github.com/metacubex/tailscale/version/distro"
ps "github.com/mitchellh/go-ps"
- "tailscale.com/version/distro"
)
func init() {
diff --git a/cmd/tailscale/cli/dns-query.go b/cmd/tailscale/cli/dns-query.go
index 2993441b3d2fc..61bac09960232 100644
--- a/cmd/tailscale/cli/dns-query.go
+++ b/cmd/tailscale/cli/dns-query.go
@@ -13,9 +13,9 @@ import (
"strings"
"text/tabwriter"
+ "github.com/metacubex/tailscale/cmd/tailscale/cli/jsonoutput"
"github.com/peterbourgon/ff/v3/ffcli"
"golang.org/x/net/dns/dnsmessage"
- "tailscale.com/cmd/tailscale/cli/jsonoutput"
)
var dnsQueryArgs struct {
diff --git a/cmd/tailscale/cli/dns-status.go b/cmd/tailscale/cli/dns-status.go
index 91a62f996cc54..91f1a10992e4f 100644
--- a/cmd/tailscale/cli/dns-status.go
+++ b/cmd/tailscale/cli/dns-status.go
@@ -8,13 +8,13 @@ import (
"encoding/json"
"flag"
"fmt"
- "maps"
- "slices"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
+ "github.com/metacubex/tailscale/cmd/tailscale/cli/jsonoutput"
+ "github.com/metacubex/tailscale/types/dnstype"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/cmd/tailscale/cli/jsonoutput"
- "tailscale.com/types/dnstype"
)
var dnsStatusCmd = &ffcli.Command{
@@ -68,7 +68,7 @@ and includes the following components:
node DNS proxy, will not answer.
For more information about the DNS functionality built into Tailscale, refer to
-https://tailscale.com/kb/1054/dns.
+https://github.com/metacubex/tailscale/kb/1054/dns.
`),
FlagSet: (func() *flag.FlagSet {
fs := newFlagSet("status")
diff --git a/cmd/tailscale/cli/dns.go b/cmd/tailscale/cli/dns.go
index d8db5d466d6b2..a7ffb128e0625 100644
--- a/cmd/tailscale/cli/dns.go
+++ b/cmd/tailscale/cli/dns.go
@@ -17,7 +17,7 @@ The 'tailscale dns' subcommand provides tools for diagnosing the internal DNS
forwarder (100.100.100.100).
For more information about the DNS functionality built into Tailscale, refer to
-https://tailscale.com/kb/1054/dns.
+https://github.com/metacubex/tailscale/kb/1054/dns.
`),
ShortUsage: strings.Join([]string{
dnsStatusCmd.ShortUsage,
diff --git a/cmd/tailscale/cli/dns_test.go b/cmd/tailscale/cli/dns_test.go
index cc01a52702fac..56d5d0e89f1ed 100644
--- a/cmd/tailscale/cli/dns_test.go
+++ b/cmd/tailscale/cli/dns_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/cmd/tailscale/cli/down.go b/cmd/tailscale/cli/down.go
index 6fecbd76cec12..cc9faed80f0fa 100644
--- a/cmd/tailscale/cli/down.go
+++ b/cmd/tailscale/cli/down.go
@@ -8,9 +8,9 @@ import (
"flag"
"fmt"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/ipn"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/ipn"
)
var downCmd = &ffcli.Command{
diff --git a/cmd/tailscale/cli/drive.go b/cmd/tailscale/cli/drive.go
index 280ff3172fb92..59864744d7225 100644
--- a/cmd/tailscale/cli/drive.go
+++ b/cmd/tailscale/cli/drive.go
@@ -11,8 +11,8 @@ import (
"path/filepath"
"strings"
+ "github.com/metacubex/tailscale/drive"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/drive"
)
const (
@@ -202,7 +202,7 @@ Permissions to access shares are controlled via ACLs. For example, to give the g
"src": ["group:home"],
"dst": ["mylaptop"],
"app": {
- "tailscale.com/cap/drive": [{
+ "github.com/metacubex/tailscale/cap/drive": [{
"shares": ["docs"],
"access": "ro"
}]
@@ -218,7 +218,7 @@ On small tailnets, it may be convenient to categorically give all users full acc
"src": ["autogroup:member"],
"dst": ["autogroup:self"],
"app": {
- "tailscale.com/cap/drive": [{
+ "github.com/metacubex/tailscale/cap/drive": [{
"shares": ["*"],
"access": "rw"
}]
diff --git a/cmd/tailscale/cli/drive_macgui.go b/cmd/tailscale/cli/drive_macgui.go
index 8a4594f86c4c9..2f3488b6d7514 100644
--- a/cmd/tailscale/cli/drive_macgui.go
+++ b/cmd/tailscale/cli/drive_macgui.go
@@ -26,7 +26,7 @@ func driveCmdStub() *ffcli.Command {
return errors.New(
"Taildrive CLI commands are not supported when using the macOS GUI app. " +
"Please use the Tailscale menu bar icon to configure Taildrive in Settings.\n\n" +
- "See https://tailscale.com/docs/features/taildrive",
+ "See https://github.com/metacubex/tailscale/docs/features/taildrive",
)
},
}
diff --git a/cmd/tailscale/cli/drive_macgui_test.go b/cmd/tailscale/cli/drive_macgui_test.go
index 11f72b13a578a..404cb5ae16577 100644
--- a/cmd/tailscale/cli/drive_macgui_test.go
+++ b/cmd/tailscale/cli/drive_macgui_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_drive && ts_mac_gui
-
package cli
import (
diff --git a/cmd/tailscale/cli/exitnode.go b/cmd/tailscale/cli/exitnode.go
index 7ba4859d79463..bb2fcd3623716 100644
--- a/cmd/tailscale/cli/exitnode.go
+++ b/cmd/tailscale/cli/exitnode.go
@@ -4,21 +4,21 @@
package cli
import (
- "cmp"
"context"
"errors"
"flag"
"fmt"
- "slices"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
"text/tabwriter"
"github.com/kballard/go-shellquote"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/slicesx"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/envknob"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/util/slicesx"
)
func exitNodeCmd() *ffcli.Command {
diff --git a/cmd/tailscale/cli/exitnode_test.go b/cmd/tailscale/cli/exitnode_test.go
index d7906b929ff57..cfa266cc021cc 100644
--- a/cmd/tailscale/cli/exitnode_test.go
+++ b/cmd/tailscale/cli/exitnode_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,9 +10,9 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
)
func TestFilterFormatAndSortExitNodes(t *testing.T) {
diff --git a/cmd/tailscale/cli/ffcomplete/complete.go b/cmd/tailscale/cli/ffcomplete/complete.go
index 7d280f691a407..4b34e813b1b76 100644
--- a/cmd/tailscale/cli/ffcomplete/complete.go
+++ b/cmd/tailscale/cli/ffcomplete/complete.go
@@ -22,9 +22,9 @@ import (
"strconv"
"strings"
+ "github.com/metacubex/tailscale/cmd/tailscale/cli/ffcomplete/internal"
+ "github.com/metacubex/tailscale/tempfork/spf13/cobra"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/cmd/tailscale/cli/ffcomplete/internal"
- "tailscale.com/tempfork/spf13/cobra"
)
type compOpts struct {
diff --git a/cmd/tailscale/cli/ffcomplete/ffcomplete.go b/cmd/tailscale/cli/ffcomplete/ffcomplete.go
index e6af2515ff26f..2bf38ffceb70a 100644
--- a/cmd/tailscale/cli/ffcomplete/ffcomplete.go
+++ b/cmd/tailscale/cli/ffcomplete/ffcomplete.go
@@ -6,8 +6,8 @@ package ffcomplete
import (
"strings"
- "tailscale.com/cmd/tailscale/cli/ffcomplete/internal"
- "tailscale.com/tempfork/spf13/cobra"
+ "github.com/metacubex/tailscale/cmd/tailscale/cli/ffcomplete/internal"
+ "github.com/metacubex/tailscale/tempfork/spf13/cobra"
)
type ShellCompDirective = cobra.ShellCompDirective
diff --git a/cmd/tailscale/cli/ffcomplete/internal/complete.go b/cmd/tailscale/cli/ffcomplete/internal/complete.go
index 911972518d331..b3a60299bf61e 100644
--- a/cmd/tailscale/cli/ffcomplete/internal/complete.go
+++ b/cmd/tailscale/cli/ffcomplete/internal/complete.go
@@ -9,9 +9,9 @@ import (
"fmt"
"strings"
+ "github.com/metacubex/tailscale/tempfork/spf13/cobra"
"github.com/peterbourgon/ff/v3"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/tempfork/spf13/cobra"
)
var (
diff --git a/cmd/tailscale/cli/ffcomplete/internal/complete_test.go b/cmd/tailscale/cli/ffcomplete/internal/complete_test.go
index 2bba72283b044..e8f52f3eea475 100644
--- a/cmd/tailscale/cli/ffcomplete/internal/complete_test.go
+++ b/cmd/tailscale/cli/ffcomplete/internal/complete_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,9 +12,9 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
+ "github.com/metacubex/tailscale/cmd/tailscale/cli/ffcomplete"
+ "github.com/metacubex/tailscale/cmd/tailscale/cli/ffcomplete/internal"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/cmd/tailscale/cli/ffcomplete"
- "tailscale.com/cmd/tailscale/cli/ffcomplete/internal"
)
func newFlagSet(name string, errh flag.ErrorHandling, flags func(fs *flag.FlagSet)) *flag.FlagSet {
diff --git a/cmd/tailscale/cli/ffcomplete/scripts.go b/cmd/tailscale/cli/ffcomplete/scripts.go
index bccebed7feec1..78b90620893d5 100644
--- a/cmd/tailscale/cli/ffcomplete/scripts.go
+++ b/cmd/tailscale/cli/ffcomplete/scripts.go
@@ -11,8 +11,8 @@ import (
"os"
"strings"
+ "github.com/metacubex/tailscale/tempfork/spf13/cobra"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/tempfork/spf13/cobra"
)
func compCmd(fs *flag.FlagSet) string {
diff --git a/cmd/tailscale/cli/file.go b/cmd/tailscale/cli/file.go
index 489c83deb4fed..3e4d94c8914bb 100644
--- a/cmd/tailscale/cli/file.go
+++ b/cmd/tailscale/cli/file.go
@@ -11,6 +11,7 @@ import (
"errors"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
"mime"
@@ -19,7 +20,6 @@ import (
"os"
"path"
"path/filepath"
- "slices"
"strings"
"sync"
"sync/atomic"
@@ -27,19 +27,19 @@ import (
"unicode/utf8"
"github.com/mattn/go-isatty"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/cmd/tailscale/cli/ffcomplete"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/tailcfg"
+ tsrate "github.com/metacubex/tailscale/tstime/rate"
+ "github.com/metacubex/tailscale/util/quarantine"
+ "github.com/metacubex/tailscale/util/truncate"
+ "github.com/metacubex/tailscale/version"
"github.com/peterbourgon/ff/v3/ffcli"
"golang.org/x/time/rate"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/cmd/tailscale/cli/ffcomplete"
- "tailscale.com/envknob"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/net/tsaddr"
- "tailscale.com/tailcfg"
- tsrate "tailscale.com/tstime/rate"
- "tailscale.com/util/quarantine"
- "tailscale.com/util/truncate"
- "tailscale.com/version"
)
func init() {
diff --git a/cmd/tailscale/cli/funnel.go b/cmd/tailscale/cli/funnel.go
index f16f571e09508..20e89a9c5ceba 100644
--- a/cmd/tailscale/cli/funnel.go
+++ b/cmd/tailscale/cli/funnel.go
@@ -13,9 +13,9 @@ import (
"strconv"
"strings"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tailcfg"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/ipn"
- "tailscale.com/tailcfg"
)
func init() {
diff --git a/cmd/tailscale/cli/id-token.go b/cmd/tailscale/cli/id-token.go
index e2707ee84ca42..dc8ad52c5df10 100644
--- a/cmd/tailscale/cli/id-token.go
+++ b/cmd/tailscale/cli/id-token.go
@@ -7,8 +7,8 @@ import (
"context"
"errors"
+ "github.com/metacubex/tailscale/envknob"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/envknob"
)
var idTokenCmd = &ffcli.Command{
diff --git a/cmd/tailscale/cli/ip.go b/cmd/tailscale/cli/ip.go
index b76ef0a708b3a..e36399c4d9ee5 100644
--- a/cmd/tailscale/cli/ip.go
+++ b/cmd/tailscale/cli/ip.go
@@ -8,11 +8,11 @@ import (
"errors"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/ipn/ipnstate"
)
var ipCmd = &ffcli.Command{
diff --git a/cmd/tailscale/cli/jsonoutput/network-lock-log.go b/cmd/tailscale/cli/jsonoutput/network-lock-log.go
index c7c16e223511d..d1fb2d7ffb4d6 100644
--- a/cmd/tailscale/cli/jsonoutput/network-lock-log.go
+++ b/cmd/tailscale/cli/jsonoutput/network-lock-log.go
@@ -12,8 +12,8 @@ import (
"fmt"
"io"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tka"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tka"
)
// PrintNetworkLockLogJSONV1 prints the stored TKA state as a JSON object to the CLI,
diff --git a/cmd/tailscale/cli/jsonoutput/network-lock-status.go b/cmd/tailscale/cli/jsonoutput/network-lock-status.go
index a1d95b871549c..de9323590d6d6 100644
--- a/cmd/tailscale/cli/jsonoutput/network-lock-status.go
+++ b/cmd/tailscale/cli/jsonoutput/network-lock-status.go
@@ -11,8 +11,8 @@ import (
"fmt"
"io"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tka"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tka"
)
// PrintNetworkLockStatusJSONV1 prints the current Tailnet Lock status
diff --git a/cmd/tailscale/cli/licenses.go b/cmd/tailscale/cli/licenses.go
index 35d636aa2eb84..65965ae49de2e 100644
--- a/cmd/tailscale/cli/licenses.go
+++ b/cmd/tailscale/cli/licenses.go
@@ -6,8 +6,8 @@ package cli
import (
"context"
+ "github.com/metacubex/tailscale/licenses"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/licenses"
)
var licensesCmd = &ffcli.Command{
diff --git a/cmd/tailscale/cli/logout.go b/cmd/tailscale/cli/logout.go
index 90843edc2e299..dfd5d413bc9be 100644
--- a/cmd/tailscale/cli/logout.go
+++ b/cmd/tailscale/cli/logout.go
@@ -9,8 +9,8 @@ import (
"fmt"
"strings"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/client/tailscale/apitype"
)
var logoutArgs struct {
diff --git a/cmd/tailscale/cli/maybe_syspolicy.go b/cmd/tailscale/cli/maybe_syspolicy.go
index a66c1a65df5e4..afb14eca8ec70 100644
--- a/cmd/tailscale/cli/maybe_syspolicy.go
+++ b/cmd/tailscale/cli/maybe_syspolicy.go
@@ -1,8 +1,8 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_syspolicy
+//go:build ts_enable_syspolicy
package cli
-import _ "tailscale.com/feature/syspolicy"
+import _ "github.com/metacubex/tailscale/feature/syspolicy"
diff --git a/cmd/tailscale/cli/metrics.go b/cmd/tailscale/cli/metrics.go
index d16ce76d2725f..57ae93d104892 100644
--- a/cmd/tailscale/cli/metrics.go
+++ b/cmd/tailscale/cli/metrics.go
@@ -9,8 +9,8 @@ import (
"fmt"
"strings"
+ "github.com/metacubex/tailscale/atomicfile"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/atomicfile"
)
var metricsCmd = &ffcli.Command{
@@ -22,7 +22,7 @@ The 'tailscale metrics' command shows Tailscale user-facing metrics (as opposed
to internal metrics printed by 'tailscale debug metrics').
For more information about Tailscale metrics, refer to
-https://tailscale.com/s/client-metrics
+https://github.com/metacubex/tailscale/s/client-metrics
`),
ShortUsage: "tailscale metrics [flags]",
diff --git a/cmd/tailscale/cli/nc.go b/cmd/tailscale/cli/nc.go
index 34490ec212557..00bb1c6bc97e2 100644
--- a/cmd/tailscale/cli/nc.go
+++ b/cmd/tailscale/cli/nc.go
@@ -12,8 +12,8 @@ import (
"strconv"
"strings"
+ "github.com/metacubex/tailscale/cmd/tailscale/cli/ffcomplete"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/cmd/tailscale/cli/ffcomplete"
)
var ncCmd = &ffcli.Command{
diff --git a/cmd/tailscale/cli/netcheck.go b/cmd/tailscale/cli/netcheck.go
index 5e45445c79cd5..921d54a835eb5 100644
--- a/cmd/tailscale/cli/netcheck.go
+++ b/cmd/tailscale/cli/netcheck.go
@@ -17,18 +17,18 @@ import (
"strings"
"time"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/net/netcheck"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/portmapper/portmappertype"
+ "github.com/metacubex/tailscale/net/tlsdial"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/set"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/envknob"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/ipn"
- "tailscale.com/net/netcheck"
- "tailscale.com/net/netmon"
- "tailscale.com/net/portmapper/portmappertype"
- "tailscale.com/net/tlsdial"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/set"
// The "netcheck" command also wants the portmapper linked.
//
@@ -36,7 +36,7 @@ import (
// tailscaled subcommand, to avoid making the CLI also link in the portmapper.
// For now (2025-09-15), keep doing what we've done for the past five years and
// keep linking it here.
- _ "tailscale.com/feature/condregister/portmapper"
+ _ "github.com/metacubex/tailscale/feature/condregister/portmapper"
)
var netcheckCmd = &ffcli.Command{
diff --git a/cmd/tailscale/cli/netcheck_test.go b/cmd/tailscale/cli/netcheck_test.go
index b2c2bceb39dc9..ac8dee8c89f12 100644
--- a/cmd/tailscale/cli/netcheck_test.go
+++ b/cmd/tailscale/cli/netcheck_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/cmd/tailscale/cli/network-lock.go b/cmd/tailscale/cli/network-lock.go
index 4febd56a97365..91b61ea60b12b 100644
--- a/cmd/tailscale/cli/network-lock.go
+++ b/cmd/tailscale/cli/network-lock.go
@@ -21,14 +21,14 @@ import (
"time"
"github.com/mattn/go-isatty"
+ "github.com/metacubex/tailscale/cmd/tailscale/cli/jsonoutput"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/tsconst"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/tkatype"
+ "github.com/metacubex/tailscale/util/prompt"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/cmd/tailscale/cli/jsonoutput"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tka"
- "tailscale.com/tsconst"
- "tailscale.com/types/key"
- "tailscale.com/types/tkatype"
- "tailscale.com/util/prompt"
)
func init() {
diff --git a/cmd/tailscale/cli/network-lock_test.go b/cmd/tailscale/cli/network-lock_test.go
index 8e49265bff181..96159162be5fe 100644
--- a/cmd/tailscale/cli/network-lock_test.go
+++ b/cmd/tailscale/cli/network-lock_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,13 +11,13 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
+ "github.com/metacubex/tailscale/cmd/tailscale/cli/jsonoutput"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/tkatype"
"go4.org/mem"
- "tailscale.com/cmd/tailscale/cli/jsonoutput"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/tka"
- "tailscale.com/types/key"
- "tailscale.com/types/tkatype"
)
func TestNetworkLockLogOutput(t *testing.T) {
diff --git a/cmd/tailscale/cli/ping.go b/cmd/tailscale/cli/ping.go
index 1e8bbd23f15e8..bc322d5624bb2 100644
--- a/cmd/tailscale/cli/ping.go
+++ b/cmd/tailscale/cli/ping.go
@@ -15,11 +15,11 @@ import (
"strings"
"time"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/cmd/tailscale/cli/ffcomplete"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/client/local"
- "tailscale.com/cmd/tailscale/cli/ffcomplete"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
)
var pingCmd = &ffcli.Command{
diff --git a/cmd/tailscale/cli/risks.go b/cmd/tailscale/cli/risks.go
index 6f3ebf37bbebe..f26ead1d6cac1 100644
--- a/cmd/tailscale/cli/risks.go
+++ b/cmd/tailscale/cli/risks.go
@@ -8,8 +8,8 @@ import (
"flag"
"strings"
- "tailscale.com/util/prompt"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/util/prompt"
+ "github.com/metacubex/tailscale/util/testenv"
)
var (
diff --git a/cmd/tailscale/cli/serve_legacy.go b/cmd/tailscale/cli/serve_legacy.go
index 635bcfa3d6fe2..04e68360c70e8 100644
--- a/cmd/tailscale/cli/serve_legacy.go
+++ b/cmd/tailscale/cli/serve_legacy.go
@@ -24,13 +24,13 @@ import (
"strconv"
"strings"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/version"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/client/local"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/util/slicesx"
- "tailscale.com/version"
)
func init() {
@@ -68,7 +68,7 @@ your tailnet.
You can also choose to enable the Tailscale Funnel with:
'tailscale funnel on'. Funnel allows you to publish
a 'tailscale serve' server publicly, open to the entire
-internet. See https://tailscale.com/funnel.
+internet. See https://github.com/metacubex/tailscale/funnel.
EXAMPLES
- To proxy requests to a web server at 127.0.0.1:3000:
diff --git a/cmd/tailscale/cli/serve_legacy_test.go b/cmd/tailscale/cli/serve_legacy_test.go
index 27cbb5712dd0f..37f5a7c1aa59e 100644
--- a/cmd/tailscale/cli/serve_legacy_test.go
+++ b/cmd/tailscale/cli/serve_legacy_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -17,13 +19,13 @@ import (
"strings"
"testing"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/logger"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/client/local"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/types/logger"
)
func TestCleanMountPoint(t *testing.T) {
@@ -789,18 +791,18 @@ func TestVerifyFunnelEnabled(t *testing.T) {
{
name: "fallback-to-non-interactive-flow",
queryFeatureResponse: mockQueryFeatureResponse{resp: nil, err: errors.New("not-allowed")},
- wantErr: "Funnel not available; HTTPS must be enabled. See https://tailscale.com/s/https.",
+ wantErr: "Funnel not available; HTTPS must be enabled. See https://github.com/metacubex/tailscale/s/https.",
},
{
name: "fallback-flow-missing-acl-rule",
queryFeatureResponse: mockQueryFeatureResponse{resp: nil, err: errors.New("not-allowed")},
caps: []tailcfg.NodeCapability{tailcfg.CapabilityHTTPS},
- wantErr: `Funnel not available; "funnel" node attribute not set. See https://tailscale.com/s/no-funnel.`,
+ wantErr: `Funnel not available; "funnel" node attribute not set. See https://github.com/metacubex/tailscale/s/no-funnel.`,
},
{
name: "fallback-flow-enabled",
queryFeatureResponse: mockQueryFeatureResponse{resp: nil, err: errors.New("not-allowed")},
- caps: []tailcfg.NodeCapability{tailcfg.CapabilityHTTPS, tailcfg.NodeAttrFunnel, "https://tailscale.com/cap/funnel-ports?ports=80,443,8080-8090"},
+ caps: []tailcfg.NodeCapability{tailcfg.CapabilityHTTPS, tailcfg.NodeAttrFunnel, "https://github.com/metacubex/tailscale/cap/funnel-ports?ports=80,443,8080-8090"},
wantErr: "", // no error, success
},
{
diff --git a/cmd/tailscale/cli/serve_v2.go b/cmd/tailscale/cli/serve_v2.go
index 13f5c09b8eac5..5dbc50f9e7dfe 100644
--- a/cmd/tailscale/cli/serve_v2.go
+++ b/cmd/tailscale/cli/serve_v2.go
@@ -11,6 +11,7 @@ import (
"errors"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
"math"
@@ -22,24 +23,23 @@ import (
"path/filepath"
"regexp"
"runtime"
- "slices"
"sort"
"strconv"
"strings"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/conffile"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/prompt"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/version"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/client/local"
- "tailscale.com/ipn"
- "tailscale.com/ipn/conffile"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/types/ipproto"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/mak"
- "tailscale.com/util/prompt"
- "tailscale.com/util/set"
- "tailscale.com/util/slicesx"
- "tailscale.com/version"
)
type execFunc func(ctx context.Context, args []string) error
@@ -153,7 +153,7 @@ EXAMPLES
- Expose a service listening on a Unix socket (Linux/macOS/BSD only):
$ tailscale %[1]s unix:/var/run/myservice.sock
-For more examples and use cases visit our docs site https://tailscale.com/kb/1247/funnel-serve-use-cases
+For more examples and use cases visit our docs site https://github.com/metacubex/tailscale/kb/1247/funnel-serve-use-cases
`)
type serveMode int
@@ -320,7 +320,7 @@ func newServeV2Command(e *serveEnv, subcmd serveMode) *ffcli.Command {
"for either a single service, or for all services that this node is hosting. If --service is specified,\n" +
"all endpoint handlers for that service are overwritten. If --all is specified, all endpoint handlers for\n" +
"all services are overwritten.\n\n" +
- "For information on the file format, see tailscale.com/kb/1589/tailscale-services-configuration-file",
+ "For information on the file format, see github.com/metacubex/tailscale/kb/1589/tailscale-services-configuration-file",
Exec: e.runServeSetConfig,
FlagSet: e.newFlags("serve-set-config", func(fs *flag.FlagSet) {
fs.BoolVar(&e.allServices, "all", false, "apply config to all services")
@@ -341,7 +341,7 @@ func (e *serveEnv) validateArgs(subcmd serveMode, args []string) error {
fmt.Fprint(e.stderr(), " You can run the following command instead:\n")
fmt.Fprintf(e.stderr(), "\t- %s\n", translation)
}
- fmt.Fprint(e.stderr(), "\nPlease see https://tailscale.com/kb/1242/tailscale-serve for more information.\n")
+ fmt.Fprint(e.stderr(), "\nPlease see https://github.com/metacubex/tailscale/kb/1242/tailscale-serve for more information.\n")
return errHelpFunc(subcmd)
}
if len(args) == 0 && e.tun {
@@ -956,7 +956,7 @@ var (
msgDisableServiceProxy = "To disable the proxy, run: tailscale serve --service=%s --%s=%d off"
msgDisableServiceTun = "To disable the service in TUN mode, run: tailscale serve --service=%s --tun off"
msgDisableService = "To remove config for the service, run: tailscale serve clear %s"
- msgWarnRemoteDestCompatibility = "Warning: %s doesn't support connecting to remote destinations from non-default route, see tailscale.com/kb/1552/tailscale-services for detail."
+ msgWarnRemoteDestCompatibility = "Warning: %s doesn't support connecting to remote destinations from non-default route, see github.com/metacubex/tailscale/kb/1552/tailscale-services for detail."
msgToExit = "Press Ctrl+C to exit."
)
@@ -1166,7 +1166,7 @@ func (e *serveEnv) applyWebServe(sc *ipn.ServeConfig, dnsName string, srvPort ui
case filepath.IsAbs(target):
if version.IsMacAppStore() || version.IsMacSys() {
// The Tailscale network extension cannot serve arbitrary paths on macOS due to sandbox restrictions (2024-03-26)
- return errors.New("Path serving is not supported on macOS due to sandbox restrictions. To use Tailscale Serve on macOS, switch to the open-source tailscaled distribution. See https://tailscale.com/kb/1065/macos-variants for more information.")
+ return errors.New("Path serving is not supported on macOS due to sandbox restrictions. To use Tailscale Serve on macOS, switch to the open-source tailscaled distribution. See https://github.com/metacubex/tailscale/kb/1065/macos-variants for more information.")
}
target = filepath.Clean(target)
diff --git a/cmd/tailscale/cli/serve_v2_test.go b/cmd/tailscale/cli/serve_v2_test.go
index 1d2a8ef86a2e4..3555e369ee217 100644
--- a/cmd/tailscale/cli/serve_v2_test.go
+++ b/cmd/tailscale/cli/serve_v2_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,22 +10,22 @@ import (
"context"
"encoding/json"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"os"
"path/filepath"
"reflect"
"regexp"
- "slices"
"strconv"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/views"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/types/views"
)
func TestServeDevConfigMutations(t *testing.T) {
diff --git a/cmd/tailscale/cli/serve_v2_unix_test.go b/cmd/tailscale/cli/serve_v2_unix_test.go
index 671cdfbfbd1bc..20e0535e717ce 100644
--- a/cmd/tailscale/cli/serve_v2_unix_test.go
+++ b/cmd/tailscale/cli/serve_v2_unix_test.go
@@ -1,15 +1,15 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build unix
-
package cli
import (
"path/filepath"
"testing"
- "tailscale.com/ipn"
+ "github.com/metacubex/tailscale/ipn"
)
func TestServeUnixSocketCLI(t *testing.T) {
diff --git a/cmd/tailscale/cli/set.go b/cmd/tailscale/cli/set.go
index 6fd4b09ad6790..19593e99e33d6 100644
--- a/cmd/tailscale/cli/set.go
+++ b/cmd/tailscale/cli/set.go
@@ -8,25 +8,25 @@ import (
"errors"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"os/exec"
"runtime"
- "slices"
"strconv"
"strings"
+ "github.com/metacubex/tailscale/cmd/tailscale/cli/ffcomplete"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/net/netutil"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/safesocket"
+ "github.com/metacubex/tailscale/tsconst"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/version"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/cmd/tailscale/cli/ffcomplete"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/ipn"
- "tailscale.com/net/netutil"
- "tailscale.com/net/tsaddr"
- "tailscale.com/safesocket"
- "tailscale.com/tsconst"
- "tailscale.com/types/opt"
- "tailscale.com/types/views"
- "tailscale.com/util/set"
- "tailscale.com/version"
)
var setCmd = &ffcli.Command{
diff --git a/cmd/tailscale/cli/set_test.go b/cmd/tailscale/cli/set_test.go
index e2c3ae5f64116..63bb0e1d96d9d 100644
--- a/cmd/tailscale/cli/set_test.go
+++ b/cmd/tailscale/cli/set_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,8 +11,8 @@ import (
"reflect"
"testing"
- "tailscale.com/ipn"
- "tailscale.com/net/tsaddr"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/net/tsaddr"
)
func TestCalcAdvertiseRoutesForSet(t *testing.T) {
diff --git a/cmd/tailscale/cli/ssh.go b/cmd/tailscale/cli/ssh.go
index 9efab8cf7e47e..9bd920b934f3f 100644
--- a/cmd/tailscale/cli/ssh.go
+++ b/cmd/tailscale/cli/ssh.go
@@ -8,21 +8,21 @@ import (
"context"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
"net/netip"
"os"
"os/user"
"path/filepath"
"runtime"
- "slices"
"strings"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/paths"
+ "github.com/metacubex/tailscale/version"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/envknob"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/net/tsaddr"
- "tailscale.com/paths"
- "tailscale.com/version"
)
var sshCmd = &ffcli.Command{
diff --git a/cmd/tailscale/cli/status.go b/cmd/tailscale/cli/status.go
index 9ce4debda8dea..916c2d3cab9b2 100644
--- a/cmd/tailscale/cli/status.go
+++ b/cmd/tailscale/cli/status.go
@@ -4,12 +4,12 @@
package cli
import (
- "cmp"
"context"
"encoding/json"
"errors"
"flag"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"net"
"net/http"
"net/netip"
@@ -17,13 +17,13 @@ import (
"strings"
"text/tabwriter"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/util/dnsname"
"github.com/peterbourgon/ff/v3/ffcli"
"golang.org/x/net/idna"
- "tailscale.com/feature"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/net/netmon"
- "tailscale.com/util/dnsname"
)
var statusCmd = &ffcli.Command{
diff --git a/cmd/tailscale/cli/switch.go b/cmd/tailscale/cli/switch.go
index bd90c522e3393..a257f32331804 100644
--- a/cmd/tailscale/cli/switch.go
+++ b/cmd/tailscale/cli/switch.go
@@ -13,9 +13,9 @@ import (
"text/tabwriter"
"time"
+ "github.com/metacubex/tailscale/cmd/tailscale/cli/ffcomplete"
+ "github.com/metacubex/tailscale/ipn"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/cmd/tailscale/cli/ffcomplete"
- "tailscale.com/ipn"
)
var switchCmd = &ffcli.Command{
diff --git a/cmd/tailscale/cli/syspolicy.go b/cmd/tailscale/cli/syspolicy.go
index e44b01d5ffa15..2b2bf1c30befc 100644
--- a/cmd/tailscale/cli/syspolicy.go
+++ b/cmd/tailscale/cli/syspolicy.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_syspolicy
+//go:build ts_enable_syspolicy
package cli
@@ -10,12 +10,12 @@ import (
"encoding/json"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"os"
- "slices"
"text/tabwriter"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/util/syspolicy/setting"
)
var syspolicyArgs struct {
diff --git a/cmd/tailscale/cli/systray.go b/cmd/tailscale/cli/systray.go
index 07de5c7868fcf..a3db83acdac00 100644
--- a/cmd/tailscale/cli/systray.go
+++ b/cmd/tailscale/cli/systray.go
@@ -9,8 +9,8 @@ import (
"context"
"flag"
+ "github.com/metacubex/tailscale/client/systray"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/client/systray"
)
var systrayCmd = &ffcli.Command{
diff --git a/cmd/tailscale/cli/up.go b/cmd/tailscale/cli/up.go
index fed7de9ae7e01..7945dba9aacf0 100644
--- a/cmd/tailscale/cli/up.go
+++ b/cmd/tailscale/cli/up.go
@@ -22,26 +22,26 @@ import (
"time"
shellquote "github.com/kballard/go-shellquote"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ _ "github.com/metacubex/tailscale/feature/condregister/awsparamstore"
+ _ "github.com/metacubex/tailscale/feature/condregister/identityfederation"
+ _ "github.com/metacubex/tailscale/feature/condregister/oauthkey"
+ "github.com/metacubex/tailscale/health/healthmsg"
+ "github.com/metacubex/tailscale/internal/client/tailscale"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/net/netutil"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/safesocket"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/preftype"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/qrcodes"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/version/distro"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/feature/buildfeatures"
- _ "tailscale.com/feature/condregister/awsparamstore"
- _ "tailscale.com/feature/condregister/identityfederation"
- _ "tailscale.com/feature/condregister/oauthkey"
- "tailscale.com/health/healthmsg"
- "tailscale.com/internal/client/tailscale"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/net/netutil"
- "tailscale.com/net/tsaddr"
- "tailscale.com/safesocket"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
- "tailscale.com/types/preftype"
- "tailscale.com/types/views"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/qrcodes"
- "tailscale.com/util/syspolicy/policyclient"
- "tailscale.com/version/distro"
)
var upCmd = &ffcli.Command{
@@ -271,7 +271,7 @@ var upArgsGlobal upArgsT
// Ex:
//
// {
-// "AuthURL": "https://login.tailscale.com/a/0123456789abcdef",
+// "AuthURL": "https://login.github.com/metacubex/tailscale/a/0123456789abcdef",
// "QR": "data:image/png;base64,0123...cdef"
// "BackendState": "NeedsLogin"
// }
@@ -280,7 +280,7 @@ var upArgsGlobal upArgsT
// "BackendState": "Running"
// }
type upOutputJSON struct {
- AuthURL string `json:",omitempty"` // Authentication URL of the form https://login.tailscale.com/a/0123456789
+ AuthURL string `json:",omitempty"` // Authentication URL of the form https://login.github.com/metacubex/tailscale/a/0123456789
QR string `json:",omitempty"` // a DataURL (base64) PNG of a QR code AuthURL
BackendState string `json:",omitempty"` // name of state like Running or NeedsMachineAuth
Error string `json:",omitempty"` // description of an error
diff --git a/cmd/tailscale/cli/up_test.go b/cmd/tailscale/cli/up_test.go
index 9af8eae7d9994..fec3cb8ead6da 100644
--- a/cmd/tailscale/cli/up_test.go
+++ b/cmd/tailscale/cli/up_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,7 +9,7 @@ import (
"flag"
"testing"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/util/set"
)
// validUpFlags are the only flags that are valid for tailscale up. The up
diff --git a/cmd/tailscale/cli/update.go b/cmd/tailscale/cli/update.go
index 47177347dba85..46c550a9dde3e 100644
--- a/cmd/tailscale/cli/update.go
+++ b/cmd/tailscale/cli/update.go
@@ -12,11 +12,11 @@ import (
"fmt"
"runtime"
+ "github.com/metacubex/tailscale/clientupdate"
+ "github.com/metacubex/tailscale/util/prompt"
+ "github.com/metacubex/tailscale/version"
+ "github.com/metacubex/tailscale/version/distro"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/clientupdate"
- "tailscale.com/util/prompt"
- "tailscale.com/version"
- "tailscale.com/version/distro"
)
func init() {
@@ -83,7 +83,7 @@ func runUpdate(ctx context.Context, args []string) error {
Confirm: confirmUpdate,
})
if errors.Is(err, errors.ErrUnsupported) {
- return errors.New("The 'update' command is not supported on this platform; see https://tailscale.com/s/client-updates")
+ return errors.New("The 'update' command is not supported on this platform; see https://github.com/metacubex/tailscale/s/client-updates")
}
return err
}
diff --git a/cmd/tailscale/cli/version.go b/cmd/tailscale/cli/version.go
index 3d6590a39bf2e..3be7023e14f1f 100644
--- a/cmd/tailscale/cli/version.go
+++ b/cmd/tailscale/cli/version.go
@@ -9,10 +9,10 @@ import (
"flag"
"fmt"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/version"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/feature"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/version"
)
var versionCmd = &ffcli.Command{
diff --git a/cmd/tailscale/cli/wait.go b/cmd/tailscale/cli/wait.go
index ce9c6aba65b40..9dfff9199061e 100644
--- a/cmd/tailscale/cli/wait.go
+++ b/cmd/tailscale/cli/wait.go
@@ -12,10 +12,10 @@ import (
"strings"
"time"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/backoff"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/ipn"
- "tailscale.com/types/logger"
- "tailscale.com/util/backoff"
)
var waitCmd = &ffcli.Command{
diff --git a/cmd/tailscale/cli/web.go b/cmd/tailscale/cli/web.go
index c13cad2d645ce..437809108a2c5 100644
--- a/cmd/tailscale/cli/web.go
+++ b/cmd/tailscale/cli/web.go
@@ -1,17 +1,17 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_webclient
+//go:build ts_enable_webclient
package cli
import (
- "cmp"
"context"
"crypto/tls"
_ "embed"
"flag"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"log"
"net"
"net/http"
@@ -21,10 +21,10 @@ import (
"os/signal"
"strings"
+ "github.com/metacubex/tailscale/client/web"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tsconst"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/client/web"
- "tailscale.com/ipn"
- "tailscale.com/tsconst"
)
func init() {
diff --git a/cmd/tailscale/cli/web_test.go b/cmd/tailscale/cli/web_test.go
index 727c5644be0b4..88b72d2d3cad8 100644
--- a/cmd/tailscale/cli/web_test.go
+++ b/cmd/tailscale/cli/web_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/cmd/tailscale/depaware.txt b/cmd/tailscale/depaware.txt
index d23ab1f4f658a..59a0ad82baac5 100644
--- a/cmd/tailscale/depaware.txt
+++ b/cmd/tailscale/depaware.txt
@@ -103,12 +103,12 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
github.com/gaissmai/bart/internal/nodes from github.com/gaissmai/bart
github.com/gaissmai/bart/internal/sparse from github.com/gaissmai/bart/internal/nodes
github.com/gaissmai/bart/internal/value from github.com/gaissmai/bart+
- github.com/go-json-experiment/json from tailscale.com/types/opt+
- github.com/go-json-experiment/json/internal from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonflags from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonopts from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonwire from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/jsontext from github.com/go-json-experiment/json+
+ github.com/metacubex/jsonv2 from tailscale.com/types/opt+
+ github.com/metacubex/jsonv2/internal from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonflags from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonopts from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonwire from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/jsontext from github.com/metacubex/jsonv2+
L 💣 github.com/godbus/dbus/v5 from fyne.io/systray+
L github.com/godbus/dbus/v5/introspect from fyne.io/systray+
L github.com/godbus/dbus/v5/prop from fyne.io/systray
diff --git a/cmd/tailscale/deps_test.go b/cmd/tailscale/deps_test.go
index ea7bb15d3a895..16fd83c0a165f 100644
--- a/cmd/tailscale/deps_test.go
+++ b/cmd/tailscale/deps_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,7 +8,7 @@ package main
import (
"testing"
- "tailscale.com/tstest/deptest"
+ "github.com/metacubex/tailscale/tstest/deptest"
)
func TestOmitQRCodes(t *testing.T) {
diff --git a/cmd/tailscale/generate.go b/cmd/tailscale/generate.go
index 36a4fa671dddb..f428043561268 100644
--- a/cmd/tailscale/generate.go
+++ b/cmd/tailscale/generate.go
@@ -3,6 +3,6 @@
package main
-//go:generate go run tailscale.com/cmd/mkmanifest amd64 windows-manifest.xml manifest_windows_amd64.syso
-//go:generate go run tailscale.com/cmd/mkmanifest 386 windows-manifest.xml manifest_windows_386.syso
-//go:generate go run tailscale.com/cmd/mkmanifest arm64 windows-manifest.xml manifest_windows_arm64.syso
+//go:generate go run github.com/metacubex/tailscale/cmd/mkmanifest amd64 windows-manifest.xml manifest_windows_amd64.syso
+//go:generate go run github.com/metacubex/tailscale/cmd/mkmanifest 386 windows-manifest.xml manifest_windows_386.syso
+//go:generate go run github.com/metacubex/tailscale/cmd/mkmanifest arm64 windows-manifest.xml manifest_windows_arm64.syso
diff --git a/cmd/tailscale/tailscale.go b/cmd/tailscale/tailscale.go
index 57a51840832b5..97e9d93016ae8 100644
--- a/cmd/tailscale/tailscale.go
+++ b/cmd/tailscale/tailscale.go
@@ -3,7 +3,7 @@
// The tailscale command is the Tailscale command-line client. It interacts
// with the tailscaled node agent.
-package main // import "tailscale.com/cmd/tailscale"
+package main // import "github.com/metacubex/tailscale/cmd/tailscale"
import (
"fmt"
@@ -11,7 +11,7 @@ import (
"path/filepath"
"strings"
- "tailscale.com/cmd/tailscale/cli"
+ "github.com/metacubex/tailscale/cmd/tailscale/cli"
)
func main() {
diff --git a/cmd/tailscale/tailscale_test.go b/cmd/tailscale/tailscale_test.go
index ca064b6b7a28a..46c4f34714627 100644
--- a/cmd/tailscale/tailscale_test.go
+++ b/cmd/tailscale/tailscale_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,20 +8,20 @@ package main
import (
"testing"
- "tailscale.com/tstest/deptest"
+ "github.com/metacubex/tailscale/tstest/deptest"
)
func TestDeps(t *testing.T) {
deptest.DepChecker{
BadDeps: map[string]string{
- "testing": "do not use testing package in production code",
- "gvisor.dev/gvisor/pkg/buffer": "https://github.com/tailscale/tailscale/issues/9756",
- "gvisor.dev/gvisor/pkg/cpuid": "https://github.com/tailscale/tailscale/issues/9756",
- "gvisor.dev/gvisor/pkg/tcpip": "https://github.com/tailscale/tailscale/issues/9756",
- "gvisor.dev/gvisor/pkg/tcpip/header": "https://github.com/tailscale/tailscale/issues/9756",
- "tailscale.com/wgengine/filter": "brings in bart, etc",
- "github.com/bits-and-blooms/bitset": "unneeded in CLI",
- "tailscale.com/net/ipset": "unneeded in CLI",
+ "testing": "do not use testing package in production code",
+ "github.com/metacubex/gvisor/pkg/buffer": "https://github.com/tailscale/tailscale/issues/9756",
+ "github.com/metacubex/gvisor/pkg/cpuid": "https://github.com/tailscale/tailscale/issues/9756",
+ "github.com/metacubex/gvisor/pkg/tcpip": "https://github.com/tailscale/tailscale/issues/9756",
+ "github.com/metacubex/gvisor/pkg/tcpip/header": "https://github.com/tailscale/tailscale/issues/9756",
+ "github.com/metacubex/tailscale/wgengine/filter": "brings in bart, etc",
+ "github.com/bits-and-blooms/bitset": "unneeded in CLI",
+ "github.com/metacubex/tailscale/net/ipset": "unneeded in CLI",
},
}.Check(t)
}
diff --git a/cmd/tailscaled/debug.go b/cmd/tailscaled/debug.go
index 360075f5b0e2b..2ffde11654aeb 100644
--- a/cmd/tailscaled/debug.go
+++ b/cmd/tailscaled/debug.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_debug
+//go:build ts_enable_debug
package main
@@ -21,17 +21,17 @@ import (
"os"
"time"
- "tailscale.com/derp/derphttp"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/health"
- "tailscale.com/ipn"
- "tailscale.com/net/netmon"
- "tailscale.com/tailcfg"
- "tailscale.com/tsweb/varz"
- "tailscale.com/types/key"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/eventbus"
+ "github.com/metacubex/tailscale/derp/derphttp"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsweb/varz"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/eventbus"
)
var debugArgs struct {
diff --git a/cmd/tailscaled/depaware-min.txt b/cmd/tailscaled/depaware-min.txt
index 8f0c34cf179f8..34aff23fb220c 100644
--- a/cmd/tailscaled/depaware-min.txt
+++ b/cmd/tailscaled/depaware-min.txt
@@ -9,12 +9,12 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
github.com/gaissmai/bart/internal/nodes from github.com/gaissmai/bart
github.com/gaissmai/bart/internal/sparse from github.com/gaissmai/bart/internal/nodes
github.com/gaissmai/bart/internal/value from github.com/gaissmai/bart+
- github.com/go-json-experiment/json from tailscale.com/drive+
- github.com/go-json-experiment/json/internal from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonflags from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonopts from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonwire from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/jsontext from github.com/go-json-experiment/json+
+ github.com/metacubex/jsonv2 from tailscale.com/drive+
+ github.com/metacubex/jsonv2/internal from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonflags from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonopts from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonwire from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/jsontext from github.com/metacubex/jsonv2+
github.com/golang/groupcache/lru from tailscale.com/net/dnscache
💣 github.com/jsimonetti/rtnetlink from tailscale.com/net/netmon
github.com/jsimonetti/rtnetlink/internal/unix from github.com/jsimonetti/rtnetlink
@@ -323,7 +323,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
embed from tailscale.com+
encoding from encoding/json+
encoding/asn1 from crypto/x509+
- encoding/base32 from github.com/go-json-experiment/json
+ encoding/base32 from github.com/metacubex/jsonv2
encoding/base64 from encoding/json+
encoding/binary from compress/gzip+
encoding/hex from crypto/x509+
diff --git a/cmd/tailscaled/depaware-minbox.txt b/cmd/tailscaled/depaware-minbox.txt
index 994310d60ab86..36b269a03a27d 100644
--- a/cmd/tailscaled/depaware-minbox.txt
+++ b/cmd/tailscaled/depaware-minbox.txt
@@ -9,12 +9,12 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
github.com/gaissmai/bart/internal/nodes from github.com/gaissmai/bart
github.com/gaissmai/bart/internal/sparse from github.com/gaissmai/bart/internal/nodes
github.com/gaissmai/bart/internal/value from github.com/gaissmai/bart+
- github.com/go-json-experiment/json from tailscale.com/drive+
- github.com/go-json-experiment/json/internal from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonflags from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonopts from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonwire from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/jsontext from github.com/go-json-experiment/json+
+ github.com/metacubex/jsonv2 from tailscale.com/drive+
+ github.com/metacubex/jsonv2/internal from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonflags from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonopts from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonwire from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/jsontext from github.com/metacubex/jsonv2+
github.com/golang/groupcache/lru from tailscale.com/net/dnscache
💣 github.com/jsimonetti/rtnetlink from tailscale.com/net/netmon
github.com/jsimonetti/rtnetlink/internal/unix from github.com/jsimonetti/rtnetlink
@@ -344,7 +344,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
embed from tailscale.com+
encoding from encoding/json+
encoding/asn1 from crypto/x509+
- encoding/base32 from github.com/go-json-experiment/json
+ encoding/base32 from github.com/metacubex/jsonv2
encoding/base64 from encoding/json+
encoding/binary from compress/gzip+
encoding/hex from crypto/x509+
diff --git a/cmd/tailscaled/depaware.txt b/cmd/tailscaled/depaware.txt
index 57332f5f8928f..0dda0c3997d8c 100644
--- a/cmd/tailscaled/depaware.txt
+++ b/cmd/tailscaled/depaware.txt
@@ -106,12 +106,12 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
github.com/gaissmai/bart/internal/nodes from github.com/gaissmai/bart
github.com/gaissmai/bart/internal/sparse from github.com/gaissmai/bart/internal/nodes
github.com/gaissmai/bart/internal/value from github.com/gaissmai/bart+
- github.com/go-json-experiment/json from tailscale.com/types/opt+
- github.com/go-json-experiment/json/internal from github.com/go-json-experiment/json/internal/jsonflags+
- github.com/go-json-experiment/json/internal/jsonflags from github.com/go-json-experiment/json/internal/jsonopts+
- github.com/go-json-experiment/json/internal/jsonopts from github.com/go-json-experiment/json/jsontext+
- github.com/go-json-experiment/json/internal/jsonwire from github.com/go-json-experiment/json/jsontext+
- github.com/go-json-experiment/json/jsontext from tailscale.com/logtail+
+ github.com/metacubex/jsonv2 from tailscale.com/types/opt+
+ github.com/metacubex/jsonv2/internal from github.com/metacubex/jsonv2/internal/jsonflags+
+ github.com/metacubex/jsonv2/internal/jsonflags from github.com/metacubex/jsonv2/internal/jsonopts+
+ github.com/metacubex/jsonv2/internal/jsonopts from github.com/metacubex/jsonv2/jsontext+
+ github.com/metacubex/jsonv2/internal/jsonwire from github.com/metacubex/jsonv2/jsontext+
+ github.com/metacubex/jsonv2/jsontext from tailscale.com/logtail+
W 💣 github.com/go-ole/go-ole from github.com/go-ole/go-ole/oleutil+
W 💣 github.com/go-ole/go-ole/oleutil from tailscale.com/wgengine/winnet
L 💣 github.com/godbus/dbus/v5 from tailscale.com/net/dns+
diff --git a/cmd/tailscaled/deps_test.go b/cmd/tailscaled/deps_test.go
index be4f65a7dd576..d2890f1ad79b0 100644
--- a/cmd/tailscaled/deps_test.go
+++ b/cmd/tailscaled/deps_test.go
@@ -1,16 +1,18 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package main
import (
- "maps"
- "slices"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
"testing"
- "tailscale.com/feature/featuretags"
- "tailscale.com/tstest/deptest"
+ "github.com/metacubex/tailscale/feature/featuretags"
+ "github.com/metacubex/tailscale/tstest/deptest"
)
func TestOmitSSH(t *testing.T) {
@@ -20,15 +22,15 @@ func TestOmitSSH(t *testing.T) {
GOARCH: "amd64",
Tags: "ts_omit_ssh,ts_include_cli",
BadDeps: map[string]string{
- "golang.org/x/crypto/ssh": msg,
- "tailscale.com/ssh/tailssh": msg,
- "tailscale.com/sessionrecording": msg,
- "github.com/anmitsu/go-shlex": msg,
- "github.com/creack/pty": msg,
- "github.com/kr/fs": msg,
- "github.com/pkg/sftp": msg,
- "github.com/u-root/u-root/pkg/termios": msg,
- "tempfork/gliderlabs/ssh": msg,
+ "golang.org/x/crypto/ssh": msg,
+ "github.com/metacubex/tailscale/ssh/tailssh": msg,
+ "github.com/metacubex/tailscale/sessionrecording": msg,
+ "github.com/anmitsu/go-shlex": msg,
+ "github.com/creack/pty": msg,
+ "github.com/kr/fs": msg,
+ "github.com/pkg/sftp": msg,
+ "github.com/u-root/u-root/pkg/termios": msg,
+ "tempfork/gliderlabs/ssh": msg,
},
}.Check(t)
}
@@ -40,9 +42,9 @@ func TestOmitSyspolicy(t *testing.T) {
GOARCH: "amd64",
Tags: "ts_omit_syspolicy,ts_include_cli",
BadDeps: map[string]string{
- "tailscale.com/util/syspolicy": msg,
- "tailscale.com/util/syspolicy/setting": msg,
- "tailscale.com/util/syspolicy/rsop": msg,
+ "github.com/metacubex/tailscale/util/syspolicy": msg,
+ "github.com/metacubex/tailscale/util/syspolicy/setting": msg,
+ "github.com/metacubex/tailscale/util/syspolicy/rsop": msg,
},
}.Check(t)
}
@@ -53,7 +55,7 @@ func TestOmitLocalClient(t *testing.T) {
GOARCH: "amd64",
Tags: "ts_omit_webclient,ts_omit_relayserver,ts_omit_oauthkey,ts_omit_acme",
BadDeps: map[string]string{
- "tailscale.com/client/local": "unexpected",
+ "github.com/metacubex/tailscale/client/local": "unexpected",
},
}.Check(t)
}
@@ -99,7 +101,7 @@ func TestOmitPortmapper(t *testing.T) {
GOARCH: "amd64",
Tags: "ts_omit_portmapper,ts_include_cli,ts_omit_debugportmapper",
OnDep: func(dep string) {
- if dep == "tailscale.com/net/portmapper" {
+ if dep == "github.com/metacubex/tailscale/net/portmapper" {
t.Errorf("unexpected dep with ts_omit_portmapper: %q", dep)
return
}
@@ -208,7 +210,7 @@ func TestOmitGRO(t *testing.T) {
GOARCH: "amd64",
Tags: "ts_omit_gro,ts_include_cli",
BadDeps: map[string]string{
- "gvisor.dev/gvisor/pkg/tcpip/stack/gro": "unexpected dep with ts_omit_gro",
+ "github.com/metacubex/gvisor/pkg/tcpip/stack/gro": "unexpected dep with ts_omit_gro",
},
}.Check(t)
}
@@ -243,7 +245,7 @@ func TestMinTailscaledNoCLI(t *testing.T) {
"golang.org/x/net/proxy",
"internal/socks",
"github.com/tailscale/peercred",
- "tailscale.com/types/netlogtype",
+ "github.com/metacubex/tailscale/types/netlogtype",
"deephash",
"util/hashx",
}
@@ -266,8 +268,8 @@ func TestMinTailscaledWithCLI(t *testing.T) {
"cbor",
"hujson",
"multierr", // https://github.com/tailscale/tailscale/pull/17379
- "tailscale.com/metrics",
- "tailscale.com/tsweb/varz",
+ "github.com/metacubex/tailscale/metrics",
+ "github.com/metacubex/tailscale/tsweb/varz",
"dirwalk",
"deephash",
"util/hashx",
@@ -284,20 +286,20 @@ func TestMinTailscaledWithCLI(t *testing.T) {
}
},
BadDeps: map[string]string{
- "golang.org/x/net/http2": "unexpected x/net/http2 dep; tailscale/tailscale#17305",
- "expvar": "unexpected expvar dep",
- "runtime/pprof": "unexpected runtime/pprof dep",
- "net/http/pprof": "unexpected net/http/pprof dep",
- "github.com/mdlayher/genetlink": "unexpected genetlink dep",
- "tailscale.com/clientupdate": "unexpected clientupdate dep",
- "filippo.io/edwards25519": "unexpected edwards25519 dep",
- "github.com/hdevalence/ed25519consensus": "unexpected ed25519consensus dep",
- "tailscale.com/clientupdate/distsign": "unexpected distsign dep",
- "archive/tar": "unexpected archive/tar dep",
- "tailscale.com/feature/conn25": "unexpected conn25 dep",
- "regexp": "unexpected regexp dep; bloats binary",
- "github.com/toqueteos/webbrowser": "unexpected webbrowser dep with ts_omit_webbrowser",
- "github.com/mattn/go-colorable": "unexpected go-colorable dep with ts_omit_colorable",
+ "golang.org/x/net/http2": "unexpected x/net/http2 dep; tailscale/tailscale#17305",
+ "expvar": "unexpected expvar dep",
+ "runtime/pprof": "unexpected runtime/pprof dep",
+ "net/http/pprof": "unexpected net/http/pprof dep",
+ "github.com/mdlayher/genetlink": "unexpected genetlink dep",
+ "github.com/metacubex/tailscale/clientupdate": "unexpected clientupdate dep",
+ "filippo.io/edwards25519": "unexpected edwards25519 dep",
+ "github.com/hdevalence/ed25519consensus": "unexpected ed25519consensus dep",
+ "github.com/metacubex/tailscale/clientupdate/distsign": "unexpected distsign dep",
+ "archive/tar": "unexpected archive/tar dep",
+ "github.com/metacubex/tailscale/feature/conn25": "unexpected conn25 dep",
+ "regexp": "unexpected regexp dep; bloats binary",
+ "github.com/toqueteos/webbrowser": "unexpected webbrowser dep with ts_omit_webbrowser",
+ "github.com/mattn/go-colorable": "unexpected go-colorable dep with ts_omit_colorable",
},
}.Check(t)
}
diff --git a/cmd/tailscaled/generate.go b/cmd/tailscaled/generate.go
index 36a4fa671dddb..f428043561268 100644
--- a/cmd/tailscaled/generate.go
+++ b/cmd/tailscaled/generate.go
@@ -3,6 +3,6 @@
package main
-//go:generate go run tailscale.com/cmd/mkmanifest amd64 windows-manifest.xml manifest_windows_amd64.syso
-//go:generate go run tailscale.com/cmd/mkmanifest 386 windows-manifest.xml manifest_windows_386.syso
-//go:generate go run tailscale.com/cmd/mkmanifest arm64 windows-manifest.xml manifest_windows_arm64.syso
+//go:generate go run github.com/metacubex/tailscale/cmd/mkmanifest amd64 windows-manifest.xml manifest_windows_amd64.syso
+//go:generate go run github.com/metacubex/tailscale/cmd/mkmanifest 386 windows-manifest.xml manifest_windows_386.syso
+//go:generate go run github.com/metacubex/tailscale/cmd/mkmanifest arm64 windows-manifest.xml manifest_windows_arm64.syso
diff --git a/cmd/tailscaled/install_windows.go b/cmd/tailscaled/install_windows.go
index d0f40b37d1156..9110bf5fc4ea1 100644
--- a/cmd/tailscaled/install_windows.go
+++ b/cmd/tailscaled/install_windows.go
@@ -12,12 +12,12 @@ import (
"os"
"time"
+ "github.com/metacubex/tailscale/cmd/tailscaled/tailscaledhooks"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/backoff"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/mgr"
- "tailscale.com/cmd/tailscaled/tailscaledhooks"
- "tailscale.com/types/logger"
- "tailscale.com/util/backoff"
)
func init() {
diff --git a/cmd/tailscaled/netstack.go b/cmd/tailscaled/netstack.go
index d896f384fcc98..2dd05c4698719 100644
--- a/cmd/tailscaled/netstack.go
+++ b/cmd/tailscaled/netstack.go
@@ -11,9 +11,9 @@ import (
"net"
"net/netip"
- "tailscale.com/tsd"
- "tailscale.com/types/logger"
- "tailscale.com/wgengine/netstack"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/wgengine/netstack"
)
func init() {
diff --git a/cmd/tailscaled/proxy.go b/cmd/tailscaled/proxy.go
index ea9f54a479dc5..3c3d50a271df7 100644
--- a/cmd/tailscaled/proxy.go
+++ b/cmd/tailscaled/proxy.go
@@ -17,11 +17,11 @@ import (
"net/http/httputil"
"strings"
- "tailscale.com/feature"
- "tailscale.com/net/proxymux"
- "tailscale.com/net/socks5"
- "tailscale.com/net/tsdial"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/net/proxymux"
+ "github.com/metacubex/tailscale/net/socks5"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/types/logger"
)
func init() {
diff --git a/cmd/tailscaled/ssh.go b/cmd/tailscaled/ssh.go
index 8de3117944431..db01782a53e70 100644
--- a/cmd/tailscaled/ssh.go
+++ b/cmd/tailscaled/ssh.go
@@ -6,4 +6,4 @@
package main
// Register implementations of various SSH hooks.
-import _ "tailscale.com/feature/ssh"
+import _ "github.com/metacubex/tailscale/feature/ssh"
diff --git a/cmd/tailscaled/tailscaled.go b/cmd/tailscaled/tailscaled.go
index fe18731ae09a1..7418b307bf426 100644
--- a/cmd/tailscaled/tailscaled.go
+++ b/cmd/tailscaled/tailscaled.go
@@ -8,7 +8,7 @@
//
// It primarily supports Linux, though other systems will likely be
// supported in the future.
-package main // import "tailscale.com/cmd/tailscaled"
+package main // import "github.com/metacubex/tailscale/cmd/tailscaled"
import (
"context"
@@ -27,43 +27,43 @@ import (
"syscall"
"time"
- "tailscale.com/cmd/tailscaled/childproc"
- "tailscale.com/control/controlclient"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- _ "tailscale.com/feature/condregister"
- "tailscale.com/health"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn"
- "tailscale.com/ipn/conffile"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/ipn/ipnserver"
- "tailscale.com/ipn/store"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/logpolicy"
- "tailscale.com/logtail"
- "tailscale.com/net/dns"
- "tailscale.com/net/dnsfallback"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netns"
- "tailscale.com/net/tsdial"
- "tailscale.com/net/tstun"
- "tailscale.com/paths"
- "tailscale.com/safesocket"
- "tailscale.com/syncs"
- "tailscale.com/tsd"
- "tailscale.com/types/flagtype"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/util/osshare"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/policyclient"
- "tailscale.com/version"
- "tailscale.com/version/distro"
- "tailscale.com/wgengine"
- "tailscale.com/wgengine/router"
+ "github.com/metacubex/tailscale/cmd/tailscaled/childproc"
+ "github.com/metacubex/tailscale/control/controlclient"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ _ "github.com/metacubex/tailscale/feature/condregister"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/conffile"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/ipn/ipnserver"
+ "github.com/metacubex/tailscale/ipn/store"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/logpolicy"
+ "github.com/metacubex/tailscale/logtail"
+ "github.com/metacubex/tailscale/net/dns"
+ "github.com/metacubex/tailscale/net/dnsfallback"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/paths"
+ "github.com/metacubex/tailscale/safesocket"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/types/flagtype"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/util/osshare"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/version"
+ "github.com/metacubex/tailscale/version/distro"
+ "github.com/metacubex/tailscale/wgengine"
+ "github.com/metacubex/tailscale/wgengine/router"
)
// defaultTunName returns the default tun device name for the platform.
diff --git a/cmd/tailscaled/tailscaled_bird.go b/cmd/tailscaled/tailscaled_bird.go
index c1c32d2bb493d..eeac6f4a4503e 100644
--- a/cmd/tailscaled/tailscaled_bird.go
+++ b/cmd/tailscaled/tailscaled_bird.go
@@ -6,8 +6,8 @@
package main
import (
- "tailscale.com/chirp"
- "tailscale.com/wgengine"
+ "github.com/metacubex/tailscale/chirp"
+ "github.com/metacubex/tailscale/wgengine"
)
func init() {
diff --git a/cmd/tailscaled/tailscaled_drive.go b/cmd/tailscaled/tailscaled_drive.go
index 6a8590bb82217..79a6f6a663ded 100644
--- a/cmd/tailscaled/tailscaled_drive.go
+++ b/cmd/tailscaled/tailscaled_drive.go
@@ -9,10 +9,10 @@ import (
"errors"
"fmt"
- "tailscale.com/drive/driveimpl"
- "tailscale.com/tsd"
- "tailscale.com/types/logger"
- "tailscale.com/wgengine"
+ "github.com/metacubex/tailscale/drive/driveimpl"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/wgengine"
)
func init() {
diff --git a/cmd/tailscaled/tailscaled_notwindows.go b/cmd/tailscaled/tailscaled_notwindows.go
index 735facc37b861..f30d5903e0caf 100644
--- a/cmd/tailscaled/tailscaled_notwindows.go
+++ b/cmd/tailscaled/tailscaled_notwindows.go
@@ -3,9 +3,9 @@
//go:build !windows && go1.19
-package main // import "tailscale.com/cmd/tailscaled"
+package main // import "github.com/metacubex/tailscale/cmd/tailscaled"
-import "tailscale.com/logpolicy"
+import "github.com/metacubex/tailscale/logpolicy"
func isWindowsService() bool { return false }
diff --git a/cmd/tailscaled/tailscaled_test.go b/cmd/tailscaled/tailscaled_test.go
index ab6482293687b..fdd206b76e266 100644
--- a/cmd/tailscaled/tailscaled_test.go
+++ b/cmd/tailscaled/tailscaled_test.go
@@ -1,20 +1,22 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-package main // import "tailscale.com/cmd/tailscaled"
+package main // import "github.com/metacubex/tailscale/cmd/tailscaled"
import (
"os"
"strings"
"testing"
- "tailscale.com/envknob"
- "tailscale.com/ipn"
- "tailscale.com/net/netmon"
- "tailscale.com/tsd"
- "tailscale.com/tstest/deptest"
- "tailscale.com/types/logid"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/tstest/deptest"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/util/must"
)
func TestNothing(t *testing.T) {
@@ -28,10 +30,10 @@ func TestDeps(t *testing.T) {
GOOS: "darwin",
GOARCH: "arm64",
BadDeps: map[string]string{
- "testing": "do not use testing package in production code",
- "gvisor.dev/gvisor/pkg/hostarch": "will crash on non-4K page sizes; see https://github.com/tailscale/tailscale/issues/8658",
- "net/http/httptest": "do not use httptest in production code",
- "net/http/internal/testcert": "do not use httptest in production code",
+ "testing": "do not use testing package in production code",
+ "github.com/metacubex/gvisor/pkg/hostarch": "will crash on non-4K page sizes; see https://github.com/tailscale/tailscale/issues/8658",
+ "net/http/httptest": "do not use httptest in production code",
+ "net/http/internal/testcert": "do not use httptest in production code",
},
}.Check(t)
@@ -39,10 +41,10 @@ func TestDeps(t *testing.T) {
GOOS: "linux",
GOARCH: "arm64",
BadDeps: map[string]string{
- "testing": "do not use testing package in production code",
- "gvisor.dev/gvisor/pkg/hostarch": "will crash on non-4K page sizes; see https://github.com/tailscale/tailscale/issues/8658",
+ "testing": "do not use testing package in production code",
+ "github.com/metacubex/gvisor/pkg/hostarch": "will crash on non-4K page sizes; see https://github.com/tailscale/tailscale/issues/8658",
"google.golang.org/protobuf/proto": "unexpected",
- "github.com/prometheus/client_golang/prometheus": "use tailscale.com/metrics in tailscaled",
+ "github.com/prometheus/client_golang/prometheus": "use github.com/metacubex/tailscale/metrics in tailscaled",
},
}.Check(t)
}
diff --git a/cmd/tailscaled/tailscaled_windows.go b/cmd/tailscaled/tailscaled_windows.go
index 0ad550d4cc0cd..d5b6251570fe1 100644
--- a/cmd/tailscaled/tailscaled_windows.go
+++ b/cmd/tailscaled/tailscaled_windows.go
@@ -3,7 +3,7 @@
//go:build go1.19
-package main // import "tailscale.com/cmd/tailscaled"
+package main // import "github.com/metacubex/tailscale/cmd/tailscaled"
// TODO: check if administrator, like tswin does.
//
@@ -35,31 +35,31 @@ import (
"syscall"
"time"
- "github.com/dblohm7/wingoes/com"
- "github.com/tailscale/wireguard-go/tun"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/drive/driveimpl"
+ "github.com/metacubex/tailscale/envknob"
+ _ "github.com/metacubex/tailscale/ipn/auditlog"
+ "github.com/metacubex/tailscale/logpolicy"
+ "github.com/metacubex/tailscale/net/dns"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/util/backoff"
+ "github.com/metacubex/tailscale/util/osdiag"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/util/wingoes/com"
+ "github.com/metacubex/tailscale/util/winipcfg"
+ "github.com/metacubex/tailscale/util/winutil"
+ "github.com/metacubex/tailscale/util/winutil/gp"
+ "github.com/metacubex/tailscale/version"
+ "github.com/metacubex/tailscale/wf"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/eventlog"
"golang.zx2c4.com/wintun"
- "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
- "tailscale.com/drive/driveimpl"
- "tailscale.com/envknob"
- _ "tailscale.com/ipn/auditlog"
- "tailscale.com/logpolicy"
- "tailscale.com/net/dns"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tstun"
- "tailscale.com/tsd"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/util/backoff"
- "tailscale.com/util/osdiag"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/policyclient"
- "tailscale.com/util/winutil"
- "tailscale.com/util/winutil/gp"
- "tailscale.com/version"
- "tailscale.com/wf"
)
func init() {
diff --git a/cmd/tailscaled/tailscaledhooks/tailscaledhooks.go b/cmd/tailscaled/tailscaledhooks/tailscaledhooks.go
index 42009d02bf6af..1a959914fd515 100644
--- a/cmd/tailscaled/tailscaledhooks/tailscaledhooks.go
+++ b/cmd/tailscaled/tailscaledhooks/tailscaledhooks.go
@@ -5,7 +5,7 @@
// to add to during init that tailscaled calls at runtime.
package tailscaledhooks
-import "tailscale.com/feature"
+import "github.com/metacubex/tailscale/feature"
// UninstallSystemDaemonWindows is called when the Windows
// system daemon is uninstalled.
diff --git a/cmd/tailscaled/webclient.go b/cmd/tailscaled/webclient.go
index e031277abfc27..ce6b902feb137 100644
--- a/cmd/tailscaled/webclient.go
+++ b/cmd/tailscaled/webclient.go
@@ -1,14 +1,14 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_webclient
+//go:build ts_enable_webclient
package main
import (
- "tailscale.com/client/local"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/paths"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/paths"
)
func init() {
diff --git a/cmd/tailscaled/with_cli.go b/cmd/tailscaled/with_cli.go
index 33da1f448e727..efab5056bb155 100644
--- a/cmd/tailscaled/with_cli.go
+++ b/cmd/tailscaled/with_cli.go
@@ -9,7 +9,7 @@ import (
"fmt"
"os"
- "tailscale.com/cmd/tailscale/cli"
+ "github.com/metacubex/tailscale/cmd/tailscale/cli"
)
func init() {
diff --git a/cmd/testcontrol/testcontrol.go b/cmd/testcontrol/testcontrol.go
index 49e7e429e63e9..75eb6c6a6262e 100644
--- a/cmd/testcontrol/testcontrol.go
+++ b/cmd/testcontrol/testcontrol.go
@@ -10,9 +10,9 @@ import (
"net/http"
"testing"
- "tailscale.com/tstest/integration"
- "tailscale.com/tstest/integration/testcontrol"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/tstest/integration"
+ "github.com/metacubex/tailscale/tstest/integration/testcontrol"
+ "github.com/metacubex/tailscale/types/logger"
)
var (
diff --git a/cmd/testwrapper/args.go b/cmd/testwrapper/args.go
index 22e5d4c902f8e..166e2ffcae881 100644
--- a/cmd/testwrapper/args.go
+++ b/cmd/testwrapper/args.go
@@ -5,9 +5,9 @@ package main
import (
"flag"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"os"
- "slices"
"strconv"
"strings"
"testing"
diff --git a/cmd/testwrapper/args_test.go b/cmd/testwrapper/args_test.go
index 25364fb96d6a1..65de59e1921cb 100644
--- a/cmd/testwrapper/args_test.go
+++ b/cmd/testwrapper/args_test.go
@@ -1,10 +1,12 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package main
import (
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"testing"
)
diff --git a/cmd/testwrapper/flakytest/flakytest.go b/cmd/testwrapper/flakytest/flakytest.go
index 5e1591e817e00..68780368c09d7 100644
--- a/cmd/testwrapper/flakytest/flakytest.go
+++ b/cmd/testwrapper/flakytest/flakytest.go
@@ -15,7 +15,7 @@ import (
"sync"
"testing"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/util/mak"
)
// FlakyTestLogMessage is a sentinel value that is printed to stderr when a
@@ -57,7 +57,7 @@ func Mark(t testing.TB, issue string) {
// old test runs, so cmd/testwrapper doesn't need to be modified.
// TODO(bradfitz): switch testwrapper to look for Action "attr"
// instead:
- // "Action":"attr","Package":"tailscale.com/cmd/testwrapper/flakytest","Test":"TestMarked_Root","Key":"flaky-test-issue-url","Value":"https://github.com/tailscale/tailscale/issues/0"}
+ // "Action":"attr","Package":"github.com/metacubex/tailscale/cmd/testwrapper/flakytest","Test":"TestMarked_Root","Key":"flaky-test-issue-url","Value":"https://github.com/tailscale/tailscale/issues/0"}
// And then remove this Logf a month or so after that.
t.Logf("flakytest: issue tracking this flaky test: %s", issue)
diff --git a/cmd/testwrapper/flakytest/flakytest_test.go b/cmd/testwrapper/flakytest/flakytest_test.go
index 54dd2121bd1f3..a3095a8e868a9 100644
--- a/cmd/testwrapper/flakytest/flakytest_test.go
+++ b/cmd/testwrapper/flakytest/flakytest_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/cmd/testwrapper/testwrapper.go b/cmd/testwrapper/testwrapper.go
index 34338fff2c42c..fcce8476b3310 100644
--- a/cmd/testwrapper/testwrapper.go
+++ b/cmd/testwrapper/testwrapper.go
@@ -10,22 +10,22 @@ package main
import (
"bufio"
"bytes"
- "cmp"
"context"
"encoding/json"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
"os"
"os/exec"
- "slices"
"sort"
"strings"
"time"
- "tailscale.com/cmd/testwrapper/flakytest"
- "tailscale.com/util/slicesx"
+ "github.com/metacubex/tailscale/cmd/testwrapper/flakytest"
+ "github.com/metacubex/tailscale/util/slicesx"
)
const (
@@ -33,7 +33,7 @@ const (
)
type testAttempt struct {
- pkg string // "tailscale.com/types/key"
+ pkg string // "github.com/metacubex/tailscale/types/key"
testName string // "TestFoo"
outcome string // "pass", "fail", "skip"
cached bool // whether package-level (non-testName specific) was pass due to being cached
@@ -120,7 +120,7 @@ func runTests(ctx context.Context, attempt int, pt *packageTests, goTestArgs, te
}
pkg := cmp.Or(
goOutput.Package,
- "build:"+goOutput.ImportPath, // can be "./cmd" while Package is "tailscale.com/cmd" so use separate namespace
+ "build:"+goOutput.ImportPath, // can be "./cmd" while Package is "github.com/metacubex/tailscale/cmd" so use separate namespace
)
pkgTests := resultMap[pkg]
if pkgTests == nil {
@@ -131,8 +131,8 @@ func runTests(ctx context.Context, attempt int, pt *packageTests, goTestArgs, te
}
if goOutput.Test == "" {
// Detect output lines like:
- // ok \ttailscale.com/cmd/testwrapper\t(cached)
- // ok \ttailscale.com/cmd/testwrapper\t(cached)\tcoverage: 17.0% of statements
+ // ok \tgithub.com/metacubex/tailscale/cmd/testwrapper\t(cached)
+ // ok \tgithub.com/metacubex/tailscale/cmd/testwrapper\t(cached)\tcoverage: 17.0% of statements
if goOutput.Package != "" && strings.Contains(goOutput.Output, fmt.Sprintf("%s\t(cached)", goOutput.Package)) {
pkgCached[goOutput.Package] = true
}
@@ -226,7 +226,7 @@ func main() {
// As a special case, if the packages looks like "sharded:1/2" then shell out to
// ./tool/listpkgs to cut up the package list pieces for each sharded builder.
if nOfM, ok := strings.CutPrefix(packages[0], "sharded:"); ok && len(packages) == 1 {
- out, err := exec.Command("go", "run", "tailscale.com/tool/listpkgs", "-shard", nOfM, "./...").Output()
+ out, err := exec.Command("go", "run", "github.com/metacubex/tailscale/tool/listpkgs", "-shard", nOfM, "./...").Output()
if err != nil {
log.Fatalf("failed to list packages for sharded test: %v", err)
}
diff --git a/cmd/testwrapper/testwrapper_test.go b/cmd/testwrapper/testwrapper_test.go
index 46400fd1c0a67..63a3aea3b928a 100644
--- a/cmd/testwrapper/testwrapper_test.go
+++ b/cmd/testwrapper/testwrapper_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -54,7 +56,7 @@ func TestRetry(t *testing.T) {
import (
"os"
"testing"
- "tailscale.com/cmd/testwrapper/flakytest"
+ "github.com/metacubex/tailscale/cmd/testwrapper/flakytest"
)
func TestOK(t *testing.T) {}
@@ -107,7 +109,7 @@ func TestNoRetry(t *testing.T) {
import (
"testing"
- "tailscale.com/cmd/testwrapper/flakytest"
+ "github.com/metacubex/tailscale/cmd/testwrapper/flakytest"
)
func TestFlakeRun(t *testing.T) {
diff --git a/cmd/tl-longchain/tl-longchain.go b/cmd/tl-longchain/tl-longchain.go
index 33d0df3011018..5589a9d2e2e82 100644
--- a/cmd/tl-longchain/tl-longchain.go
+++ b/cmd/tl-longchain/tl-longchain.go
@@ -12,7 +12,7 @@
//
// Note that the Tailscale client this command is executed on must have
// ACL visibility to all other nodes to be able to see their signatures.
-// https://tailscale.com/kb/1087/device-visibility
+// https://github.com/metacubex/tailscale/kb/1087/device-visibility
package main
import (
@@ -22,10 +22,10 @@ import (
"log"
"time"
- "tailscale.com/client/local"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tka"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/types/key"
)
var (
diff --git a/cmd/tsconnect/build-pkg.go b/cmd/tsconnect/build-pkg.go
index 53aacc02ec8ea..babce6a56468c 100644
--- a/cmd/tsconnect/build-pkg.go
+++ b/cmd/tsconnect/build-pkg.go
@@ -12,9 +12,9 @@ import (
"os"
"path"
+ "github.com/metacubex/tailscale/util/precompress"
+ "github.com/metacubex/tailscale/version"
"github.com/tailscale/hujson"
- "tailscale.com/util/precompress"
- "tailscale.com/version"
)
func runBuildPkg() {
diff --git a/cmd/tsconnect/build.go b/cmd/tsconnect/build.go
index 64b6b3582bd62..e88bab0ba5261 100644
--- a/cmd/tsconnect/build.go
+++ b/cmd/tsconnect/build.go
@@ -13,7 +13,7 @@ import (
"path"
"path/filepath"
- "tailscale.com/util/precompress"
+ "github.com/metacubex/tailscale/util/precompress"
)
func runBuild() {
diff --git a/cmd/tsconnect/common.go b/cmd/tsconnect/common.go
index bc9e1ed4ff532..0126084cc7259 100644
--- a/cmd/tsconnect/common.go
+++ b/cmd/tsconnect/common.go
@@ -7,6 +7,7 @@ package main
import (
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
"net"
"os"
@@ -14,7 +15,6 @@ import (
"path"
"path/filepath"
"runtime"
- "slices"
"strconv"
"time"
diff --git a/cmd/tsconnect/serve.go b/cmd/tsconnect/serve.go
index 3e9f097a248a4..d15e93e021fc9 100644
--- a/cmd/tsconnect/serve.go
+++ b/cmd/tsconnect/serve.go
@@ -18,8 +18,8 @@ import (
"path"
"time"
- "tailscale.com/tsweb"
- "tailscale.com/util/precompress"
+ "github.com/metacubex/tailscale/tsweb"
+ "github.com/metacubex/tailscale/util/precompress"
)
//go:embed index.html
diff --git a/cmd/tsconnect/tsconnect.go b/cmd/tsconnect/tsconnect.go
index 6de1f26ad389f..b8bf73d2cee7a 100644
--- a/cmd/tsconnect/tsconnect.go
+++ b/cmd/tsconnect/tsconnect.go
@@ -9,7 +9,7 @@
// with a reload.
// - build: builds the site and writes it to dist/
// - serve: serves the site from dist/ (embedded in the binary)
-package main // import "tailscale.com/cmd/tsconnect"
+package main // import "github.com/metacubex/tailscale/cmd/tsconnect"
import (
"flag"
diff --git a/cmd/tsconnect/wasm/wasm_js.go b/cmd/tsconnect/wasm/wasm_js.go
index f58e4201ab83c..2c4d6e9084b93 100644
--- a/cmd/tsconnect/wasm/wasm_js.go
+++ b/cmd/tsconnect/wasm/wasm_js.go
@@ -15,8 +15,8 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"log"
- "math/rand/v2"
"net"
"net/http"
"net/netip"
@@ -24,24 +24,24 @@ import (
"syscall/js"
"time"
+ "github.com/metacubex/tailscale/control/controlclient"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/ipn/ipnserver"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/logpolicy"
+ "github.com/metacubex/tailscale/logtail"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/safesocket"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/wgengine"
+ "github.com/metacubex/tailscale/wgengine/netstack"
+ "github.com/metacubex/tailscale/words"
"golang.org/x/crypto/ssh"
- "tailscale.com/control/controlclient"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnauth"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/ipn/ipnserver"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/logpolicy"
- "tailscale.com/logtail"
- "tailscale.com/net/netns"
- "tailscale.com/net/tsdial"
- "tailscale.com/safesocket"
- "tailscale.com/tailcfg"
- "tailscale.com/tsd"
- "tailscale.com/types/views"
- "tailscale.com/wgengine"
- "tailscale.com/wgengine/netstack"
- "tailscale.com/words"
)
// ControlURL defines the URL to be used for connection to Control.
diff --git a/cmd/tsidp/depaware.txt b/cmd/tsidp/depaware.txt
index cf1a4c279c865..48214aed1300b 100644
--- a/cmd/tsidp/depaware.txt
+++ b/cmd/tsidp/depaware.txt
@@ -25,12 +25,12 @@ tailscale.com/cmd/tsidp dependencies: (generated by github.com/tailscale/depawar
github.com/gaissmai/bart/internal/nodes from github.com/gaissmai/bart
github.com/gaissmai/bart/internal/sparse from github.com/gaissmai/bart/internal/nodes
github.com/gaissmai/bart/internal/value from github.com/gaissmai/bart+
- github.com/go-json-experiment/json from tailscale.com/types/opt+
- github.com/go-json-experiment/json/internal from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonflags from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonopts from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonwire from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/jsontext from github.com/go-json-experiment/json+
+ github.com/metacubex/jsonv2 from tailscale.com/types/opt+
+ github.com/metacubex/jsonv2/internal from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonflags from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonopts from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonwire from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/jsontext from github.com/metacubex/jsonv2+
L 💣 github.com/godbus/dbus/v5 from tailscale.com/net/dns
github.com/golang/groupcache/lru from tailscale.com/net/dnscache
github.com/google/btree from gvisor.dev/gvisor/pkg/tcpip/transport/tcp
diff --git a/cmd/tsidp/tsidp.go b/cmd/tsidp/tsidp.go
index d6dfc79009796..f5782fe185c71 100644
--- a/cmd/tsidp/tsidp.go
+++ b/cmd/tsidp/tsidp.go
@@ -35,24 +35,24 @@ import (
"sync"
"time"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/rands"
+ "github.com/metacubex/tailscale/version"
"gopkg.in/square/go-jose.v2"
"gopkg.in/square/go-jose.v2/jwt"
- "tailscale.com/client/local"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/envknob"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/tsnet"
- "tailscale.com/types/key"
- "tailscale.com/types/lazy"
- "tailscale.com/types/opt"
- "tailscale.com/types/views"
- "tailscale.com/util/mak"
- "tailscale.com/util/must"
- "tailscale.com/util/rands"
- "tailscale.com/version"
)
// ctxConn is a key to look up a net.Conn stored in an HTTP request's context.
diff --git a/cmd/tsidp/tsidp_test.go b/cmd/tsidp/tsidp_test.go
index baf5aaee14fa8..8d32c50ffbee8 100644
--- a/cmd/tsidp/tsidp_test.go
+++ b/cmd/tsidp/tsidp_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -37,14 +39,14 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/views"
"gopkg.in/square/go-jose.v2"
"gopkg.in/square/go-jose.v2/jwt"
- "tailscale.com/client/local"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/opt"
- "tailscale.com/types/views"
)
// normalizeMap recursively sorts []any values in a map[string]any to ensure
diff --git a/cmd/tsidp/ui.go b/cmd/tsidp/ui.go
index f8717d65e8509..34b0dcd3b2523 100644
--- a/cmd/tsidp/ui.go
+++ b/cmd/tsidp/ui.go
@@ -14,7 +14,7 @@ import (
"strings"
"time"
- "tailscale.com/util/rands"
+ "github.com/metacubex/tailscale/util/rands"
)
//go:embed ui-header.html
diff --git a/cmd/tsnet-proxy/tsnet-proxy.go b/cmd/tsnet-proxy/tsnet-proxy.go
index 0a83fd1a8dac8..a97c40ddce402 100644
--- a/cmd/tsnet-proxy/tsnet-proxy.go
+++ b/cmd/tsnet-proxy/tsnet-proxy.go
@@ -19,7 +19,7 @@
//
// Or run directly from the module, no checkout required:
//
-// go run tailscale.com/cmd/tsnet-proxy@latest myapp 8080
+// go run github.com/metacubex/tailscale/cmd/tsnet-proxy@latest myapp 8080
package main
import (
@@ -36,8 +36,8 @@ import (
"strconv"
"unicode/utf8"
- "tailscale.com/client/local"
- "tailscale.com/tsnet"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/tsnet"
)
func main() {
diff --git a/cmd/tsp/tsp.go b/cmd/tsp/tsp.go
index a59b352d5b060..6e88bb1d09fa2 100644
--- a/cmd/tsp/tsp.go
+++ b/cmd/tsp/tsp.go
@@ -8,22 +8,22 @@ package main
import (
"bytes"
- "cmp"
"context"
"encoding/json"
"errors"
"flag"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"io"
"os"
"reflect"
"strings"
+ "github.com/metacubex/tailscale/control/tsp"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/control/tsp"
- "tailscale.com/hostinfo"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
)
var globalArgs struct {
diff --git a/cmd/tta/bypass_linux.go b/cmd/tta/bypass_linux.go
index 868cd716f8b0f..b0977544d1996 100644
--- a/cmd/tta/bypass_linux.go
+++ b/cmd/tta/bypass_linux.go
@@ -7,8 +7,8 @@ import (
"fmt"
"syscall"
+ "github.com/metacubex/tailscale/net/netmon"
"golang.org/x/sys/unix"
- "tailscale.com/net/netmon"
)
// bypassControlFunc is set as net.Dialer.Control so that sockets dialed by
diff --git a/cmd/tta/ipassign_darwin.go b/cmd/tta/ipassign_darwin.go
index 69a178956736d..a83025ce31e09 100644
--- a/cmd/tta/ipassign_darwin.go
+++ b/cmd/tta/ipassign_darwin.go
@@ -15,8 +15,8 @@ import (
"time"
"unsafe"
+ "github.com/metacubex/tailscale/tstest/natlab/vnet"
"golang.org/x/sys/unix"
- "tailscale.com/tstest/natlab/vnet"
)
const (
diff --git a/cmd/tta/tta.go b/cmd/tta/tta.go
index 5dd1eddb9fedd..442da0c78bdc0 100644
--- a/cmd/tta/tta.go
+++ b/cmd/tta/tta.go
@@ -32,13 +32,13 @@ import (
"sync"
"time"
- "tailscale.com/atomicfile"
- "tailscale.com/client/local"
- "tailscale.com/hostinfo"
- "tailscale.com/util/mak"
- "tailscale.com/util/must"
- "tailscale.com/util/set"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/atomicfile"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/version/distro"
)
// connContextKeyType is the type of connContextKey, which isn't of type
diff --git a/cmd/tta/wgserver_linux.go b/cmd/tta/wgserver_linux.go
index 10d6bbe282ade..39dc53d62778b 100644
--- a/cmd/tta/wgserver_linux.go
+++ b/cmd/tta/wgserver_linux.go
@@ -4,22 +4,22 @@
package main
import (
- "cmp"
"crypto/rand"
"encoding/base64"
"encoding/hex"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"log"
"net/http"
"os"
"os/exec"
"sync"
- "github.com/tailscale/wireguard-go/conn"
- "github.com/tailscale/wireguard-go/device"
- "github.com/tailscale/wireguard-go/tun"
+ "github.com/metacubex/tailscale-wireguard-go/conn"
+ "github.com/metacubex/tailscale-wireguard-go/device"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/wgengine/wgcfg"
"golang.org/x/crypto/curve25519"
- "tailscale.com/wgengine/wgcfg"
)
func init() {
diff --git a/cmd/vet/jsontags/iszero.go b/cmd/vet/jsontags/iszero.go
index fd25cc120c530..5d4fce228d2cb 100644
--- a/cmd/vet/jsontags/iszero.go
+++ b/cmd/vet/jsontags/iszero.go
@@ -7,7 +7,7 @@ import (
"go/types"
"reflect"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/util/set"
)
var _ = reflect.Value.IsZero // refer for hot-linking purposes
@@ -25,25 +25,25 @@ func hasPureIsZeroMethod(t types.Type) bool {
// PureIsZeroMethodsInTailscaleModule is a list of known IsZero methods
// in the "tailscale.com" module that are pure.
var PureIsZeroMethodsInTailscaleModule = map[string]set.Set[string]{
- "tailscale.com/net/packet": set.Of(
+ "github.com/metacubex/tailscale/net/packet": set.Of(
"TailscaleRejectReason",
),
- "tailscale.com/tailcfg": set.Of(
+ "github.com/metacubex/tailscale/tailcfg": set.Of(
"UserID",
"LoginID",
"NodeID",
"StableNodeID",
),
- "tailscale.com/tka": set.Of(
+ "github.com/metacubex/tailscale/tka": set.Of(
"AUMHash",
),
- "tailscale.com/types/geo": set.Of(
+ "github.com/metacubex/tailscale/types/geo": set.Of(
"Point",
),
- "tailscale.com/tstime/mono": set.Of(
+ "github.com/metacubex/tailscale/tstime/mono": set.Of(
"Time",
),
- "tailscale.com/types/key": set.Of(
+ "github.com/metacubex/tailscale/types/key": set.Of(
"NLPrivate",
"NLPublic",
"DERPMesh",
@@ -58,7 +58,7 @@ var PureIsZeroMethodsInTailscaleModule = map[string]set.Set[string]{
"NodePrivate",
"NodePublic",
),
- "tailscale.com/types/netlogtype": set.Of(
+ "github.com/metacubex/tailscale/types/netlogtype": set.Of(
"Connection",
"Counts",
),
diff --git a/cmd/vet/jsontags/report.go b/cmd/vet/jsontags/report.go
index 702de1c4d1c36..abd4aeb2ebfc9 100644
--- a/cmd/vet/jsontags/report.go
+++ b/cmd/vet/jsontags/report.go
@@ -11,8 +11,8 @@ import (
_ "embed"
+ "github.com/metacubex/tailscale/util/set"
"golang.org/x/tools/go/analysis"
- "tailscale.com/util/set"
)
var jsontagsAllowlist map[ReportKind]set.Set[string]
@@ -23,8 +23,8 @@ var jsontagsAllowlist map[ReportKind]set.Set[string]
//
// For example:
//
-// OmitEmptyUnsupportedInV1 tailscale.com/path/to/package.StructType.FieldName
-// OmitEmptyUnsupportedInV1 tailscale.com/path/to/package.*.FieldName
+// OmitEmptyUnsupportedInV1 github.com/metacubex/tailscale/path/to/package.StructType.FieldName
+// OmitEmptyUnsupportedInV1 github.com/metacubex/tailscale/path/to/package.*.FieldName
//
// The struct type name may be "*" for anonymous struct types such
// as those declared within a function or as a type literal in a variable.
@@ -53,8 +53,8 @@ func ParseAllowlist(s string) map[ReportKind]set.Set[string] {
//
// {
// "OmitEmptyUnsupportedInV1": set.Of(
-// "tailscale.com/path/to/package.StructType.FieldName",
-// "tailscale.com/path/to/package.*.FieldName",
+// "github.com/metacubex/tailscale/path/to/package.StructType.FieldName",
+// "github.com/metacubex/tailscale/path/to/package.*.FieldName",
// ),
// }
//
diff --git a/cmd/vet/lowerell/analyzer_test.go b/cmd/vet/lowerell/analyzer_test.go
index c566c2ec43ede..4a189544d79a1 100644
--- a/cmd/vet/lowerell/analyzer_test.go
+++ b/cmd/vet/lowerell/analyzer_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/cmd/vet/subtestnames/analyzer_test.go b/cmd/vet/subtestnames/analyzer_test.go
index b051a0369c4f6..9b67b05303789 100644
--- a/cmd/vet/subtestnames/analyzer_test.go
+++ b/cmd/vet/subtestnames/analyzer_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/cmd/vet/subtestnames/testdata/src/example/example_test.go b/cmd/vet/subtestnames/testdata/src/example/example_test.go
index f76599c324c5e..506db3699ea79 100644
--- a/cmd/vet/subtestnames/testdata/src/example/example_test.go
+++ b/cmd/vet/subtestnames/testdata/src/example/example_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/cmd/vet/vet.go b/cmd/vet/vet.go
index 38ffdb6d02891..66fc27d136b9b 100644
--- a/cmd/vet/vet.go
+++ b/cmd/vet/vet.go
@@ -7,10 +7,10 @@ package main
import (
_ "embed"
+ "github.com/metacubex/tailscale/cmd/vet/jsontags"
+ "github.com/metacubex/tailscale/cmd/vet/lowerell"
+ "github.com/metacubex/tailscale/cmd/vet/subtestnames"
"golang.org/x/tools/go/analysis/unitchecker"
- "tailscale.com/cmd/vet/jsontags"
- "tailscale.com/cmd/vet/lowerell"
- "tailscale.com/cmd/vet/subtestnames"
)
//go:embed jsontags_allowlist
diff --git a/cmd/viewer/tests/tests.go b/cmd/viewer/tests/tests.go
index 060ac9d8e96fa..31ad0e32579db 100644
--- a/cmd/viewer/tests/tests.go
+++ b/cmd/viewer/tests/tests.go
@@ -1,18 +1,18 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-// Package tests serves a list of tests for tailscale.com/cmd/viewer.
+// Package tests serves a list of tests for github.com/metacubex/tailscale/cmd/viewer.
package tests
import (
"fmt"
"net/netip"
+ "github.com/metacubex/tailscale/types/views"
"golang.org/x/exp/constraints"
- "tailscale.com/types/views"
)
-//go:generate go run tailscale.com/cmd/viewer --type=StructWithPtrs,StructWithoutPtrs,Map,StructWithSlices,OnlyGetClone,StructWithEmbedded,GenericIntStruct,GenericNoPtrsStruct,GenericCloneableStruct,StructWithContainers,StructWithTypeAliasFields,GenericTypeAliasStruct,StructWithMapOfViews,StructWithNamedMap,StructWithNamedSlice --clone-only-type=OnlyGetClone
+//go:generate go run github.com/metacubex/tailscale/cmd/viewer --type=StructWithPtrs,StructWithoutPtrs,Map,StructWithSlices,OnlyGetClone,StructWithEmbedded,GenericIntStruct,GenericNoPtrsStruct,GenericCloneableStruct,StructWithContainers,StructWithTypeAliasFields,GenericTypeAliasStruct,StructWithMapOfViews,StructWithNamedMap,StructWithNamedSlice --clone-only-type=OnlyGetClone
type StructWithoutPtrs struct {
Int int
diff --git a/cmd/viewer/tests/tests_clone.go b/cmd/viewer/tests/tests_clone.go
index 3b4182aa05ae8..153f3b6899a2b 100644
--- a/cmd/viewer/tests/tests_clone.go
+++ b/cmd/viewer/tests/tests_clone.go
@@ -1,16 +1,16 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-// Code generated by tailscale.com/cmd/cloner; DO NOT EDIT.
+// Code generated by github.com/metacubex/tailscale/cmd/cloner; DO NOT EDIT.
package tests
import (
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"net/netip"
+ "github.com/metacubex/tailscale/types/views"
"golang.org/x/exp/constraints"
- "tailscale.com/types/views"
)
// Clone makes a deep copy of StructWithPtrs.
@@ -22,13 +22,13 @@ func (src *StructWithPtrs) Clone() *StructWithPtrs {
dst := new(StructWithPtrs)
*dst = *src
if dst.Value != nil {
- dst.Value = new(*src.Value)
+ dst.Value = func() *Value { v := *src.Value; return &v }()
}
if dst.Int != nil {
- dst.Int = new(*src.Int)
+ dst.Int = func() *Int { v := *src.Int; return &v }()
}
if dst.NoView != nil {
- dst.NoView = new(*src.NoView)
+ dst.NoView = func() *NoView { v := *src.NoView; return &v }()
}
return dst
}
@@ -277,7 +277,7 @@ func (src *GenericIntStruct[T]) Clone() *GenericIntStruct[T] {
dst := new(GenericIntStruct[T])
*dst = *src
if dst.Pointer != nil {
- dst.Pointer = new(*src.Pointer)
+ dst.Pointer = func() *Pointer { v := *src.Pointer; return &v }()
}
dst.Slice = append(src.Slice[:0:0], src.Slice...)
dst.Map = maps.Clone(src.Map)
@@ -334,7 +334,7 @@ func (src *GenericNoPtrsStruct[T]) Clone() *GenericNoPtrsStruct[T] {
dst := new(GenericNoPtrsStruct[T])
*dst = *src
if dst.Pointer != nil {
- dst.Pointer = new(*src.Pointer)
+ dst.Pointer = func() *Pointer { v := *src.Pointer; return &v }()
}
dst.Slice = append(src.Slice[:0:0], src.Slice...)
dst.Map = maps.Clone(src.Map)
@@ -492,7 +492,7 @@ func (src *StructWithTypeAliasFields) Clone() *StructWithTypeAliasFields {
dst.WithPtr = *src.WithPtr.Clone()
dst.WithPtrByPtr = src.WithPtrByPtr.Clone()
if dst.WithoutPtrByPtr != nil {
- dst.WithoutPtrByPtr = new(*src.WithoutPtrByPtr)
+ dst.WithoutPtrByPtr = func() *WithoutPtrByPtr { v := *src.WithoutPtrByPtr; return &v }()
}
if src.SliceWithPtrs != nil {
dst.SliceWithPtrs = make([]*StructWithPtrsAlias, len(src.SliceWithPtrs))
diff --git a/cmd/viewer/tests/tests_view.go b/cmd/viewer/tests/tests_view.go
index 29be2d78bb232..e288755e934f6 100644
--- a/cmd/viewer/tests/tests_view.go
+++ b/cmd/viewer/tests/tests_view.go
@@ -10,13 +10,13 @@ import (
"errors"
"net/netip"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/types/views"
"golang.org/x/exp/constraints"
- "tailscale.com/types/views"
)
-//go:generate go run tailscale.com/cmd/cloner -clonefunc=false -type=StructWithPtrs,StructWithoutPtrs,Map,StructWithSlices,OnlyGetClone,StructWithEmbedded,GenericIntStruct,GenericNoPtrsStruct,GenericCloneableStruct,StructWithContainers,StructWithTypeAliasFields,GenericTypeAliasStruct,StructWithMapOfViews,StructWithNamedMap,StructWithNamedSlice
+//go:generate go run github.com/metacubex/tailscale/cmd/cloner -clonefunc=false -type=StructWithPtrs,StructWithoutPtrs,Map,StructWithSlices,OnlyGetClone,StructWithEmbedded,GenericIntStruct,GenericNoPtrsStruct,GenericCloneableStruct,StructWithContainers,StructWithTypeAliasFields,GenericTypeAliasStruct,StructWithMapOfViews,StructWithNamedMap,StructWithNamedSlice
// View returns a read-only view of StructWithPtrs.
func (p *StructWithPtrs) View() StructWithPtrsView {
diff --git a/cmd/viewer/viewer.go b/cmd/viewer/viewer.go
index 21d417878df56..1401686a9716e 100644
--- a/cmd/viewer/viewer.go
+++ b/cmd/viewer/viewer.go
@@ -9,18 +9,18 @@ import (
"bytes"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"go/ast"
"go/token"
"go/types"
"html/template"
"log"
"os"
- "slices"
"strings"
- "tailscale.com/util/codegen"
- "tailscale.com/util/mak"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/util/codegen"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/must"
)
const viewTemplateStr = `{{define "common"}}
@@ -222,8 +222,8 @@ func genView(buf *bytes.Buffer, it *codegen.ImportTracker, typ *types.Named, fie
return
}
it.Import("jsonv1", "encoding/json")
- it.Import("jsonv2", "github.com/go-json-experiment/json")
- it.Import("", "github.com/go-json-experiment/json/jsontext")
+ it.Import("jsonv2", "github.com/metacubex/jsonv2")
+ it.Import("", "github.com/metacubex/jsonv2/jsontext")
it.Import("", "errors")
args := struct {
@@ -305,11 +305,11 @@ func genView(buf *bytes.Buffer, it *codegen.ImportTracker, typ *types.Named, fie
switch elem.String() {
case "byte":
args.FieldType = it.QualifiedName(fieldType)
- it.Import("", "tailscale.com/types/views")
+ it.Import("", "github.com/metacubex/tailscale/types/views")
writeTemplateWithComment("byteSliceField", fname)
default:
args.FieldType = it.QualifiedName(elem)
- it.Import("", "tailscale.com/types/views")
+ it.Import("", "github.com/metacubex/tailscale/types/views")
shallow, deep, base := requiresCloning(elem)
if deep {
switch elem.Underlying().(type) {
@@ -375,7 +375,7 @@ func genView(buf *bytes.Buffer, it *codegen.ImportTracker, typ *types.Named, fie
writeTemplateWithComment("unsupportedField", fname)
continue
}
- it.Import("", "tailscale.com/types/views")
+ it.Import("", "github.com/metacubex/tailscale/types/views")
args.MapKeyType = it.QualifiedName(key)
mElem := m.Elem()
var template string
@@ -740,7 +740,7 @@ func main() {
}
buf := new(bytes.Buffer)
- fmt.Fprintf(buf, "//go:generate go run tailscale.com/cmd/cloner %s\n\n", strings.Join(flagArgs, " "))
+ fmt.Fprintf(buf, "//go:generate go run github.com/metacubex/tailscale/cmd/cloner %s\n\n", strings.Join(flagArgs, " "))
runCloner := false
for _, typeName := range typeNames {
if cloneOnlyType[typeName] {
@@ -772,7 +772,7 @@ func main() {
}
if runCloner {
// When a new package is added or when existing generated files have
- // been deleted, we might run into a case where tailscale.com/cmd/cloner
+ // been deleted, we might run into a case where github.com/metacubex/tailscale/cmd/cloner
// has not run yet. We detect this by verifying that all the structs we
// interacted with have had Clone method already generated. If they
// haven't we ask the caller to rerun generation again so that those get
diff --git a/cmd/viewer/viewer_test.go b/cmd/viewer/viewer_test.go
index e53f1d3c56a4a..bab3c7f63cdf9 100644
--- a/cmd/viewer/viewer_test.go
+++ b/cmd/viewer/viewer_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -13,7 +15,7 @@ import (
"strings"
"testing"
- "tailscale.com/util/codegen"
+ "github.com/metacubex/tailscale/util/codegen"
)
// TestNamedMapWithView tests that a named map type with a user-supplied
@@ -124,13 +126,13 @@ func TestViewerImports(t *testing.T) {
name: "Map",
content: `type Test struct { Map map[string]int }`,
typeNames: []string{"Test"},
- wantImports: [][2]string{{"", "tailscale.com/types/views"}},
+ wantImports: [][2]string{{"", "github.com/metacubex/tailscale/types/views"}},
},
{
name: "Slice",
content: `type Test struct { Slice []int }`,
typeNames: []string{"Test"},
- wantImports: [][2]string{{"", "tailscale.com/types/views"}},
+ wantImports: [][2]string{{"", "github.com/metacubex/tailscale/types/views"}},
},
}
for _, tt := range tests {
diff --git a/cmd/vnet/vnet-main.go b/cmd/vnet/vnet-main.go
index 8a3afe2035a95..e60e039cc2c74 100644
--- a/cmd/vnet/vnet-main.go
+++ b/cmd/vnet/vnet-main.go
@@ -10,6 +10,7 @@ import (
"encoding/binary"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
"net"
@@ -18,13 +19,12 @@ import (
"net/url"
"os"
"path/filepath"
- "slices"
"time"
"github.com/coder/websocket"
- "tailscale.com/tstest/natlab/vnet"
- "tailscale.com/types/logger"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/tstest/natlab/vnet"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/must"
)
var (
diff --git a/cmd/xdpderper/xdpderper.go b/cmd/xdpderper/xdpderper.go
index ea25550bb1189..48815cce73203 100644
--- a/cmd/xdpderper/xdpderper.go
+++ b/cmd/xdpderper/xdpderper.go
@@ -14,13 +14,13 @@ import (
"strings"
"syscall"
+ "github.com/metacubex/tailscale/derp/xdp"
+ "github.com/metacubex/tailscale/net/netutil"
+ "github.com/metacubex/tailscale/tsweb"
"github.com/prometheus/client_golang/prometheus"
- "tailscale.com/derp/xdp"
- "tailscale.com/net/netutil"
- "tailscale.com/tsweb"
// Support for prometheus varz in tsweb
- _ "tailscale.com/tsweb/promvarz"
+ _ "github.com/metacubex/tailscale/tsweb/promvarz"
)
var (
diff --git a/control/controlbase/conn.go b/control/controlbase/conn.go
index 8f6e5a7717f79..adb4169e00423 100644
--- a/control/controlbase/conn.go
+++ b/control/controlbase/conn.go
@@ -16,10 +16,10 @@ import (
"sync"
"time"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/key"
"golang.org/x/crypto/blake2s"
chp "golang.org/x/crypto/chacha20poly1305"
- "tailscale.com/syncs"
- "tailscale.com/types/key"
)
const (
diff --git a/control/controlbase/conn_test.go b/control/controlbase/conn_test.go
index 202d39efae9e7..d161e1e5d00d9 100644
--- a/control/controlbase/conn_test.go
+++ b/control/controlbase/conn_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -17,10 +19,10 @@ import (
"testing/iotest"
"testing/synctest"
+ "github.com/metacubex/tailscale/net/memnet"
+ "github.com/metacubex/tailscale/types/key"
chp "golang.org/x/crypto/chacha20poly1305"
"golang.org/x/net/nettest"
- "tailscale.com/net/memnet"
- "tailscale.com/types/key"
)
const testProtocolVersion = 1
diff --git a/control/controlbase/handshake.go b/control/controlbase/handshake.go
index 919920c344239..c233da0c55f47 100644
--- a/control/controlbase/handshake.go
+++ b/control/controlbase/handshake.go
@@ -15,12 +15,12 @@ import (
"strconv"
"time"
+ "github.com/metacubex/tailscale/types/key"
"go4.org/mem"
"golang.org/x/crypto/blake2s"
chp "golang.org/x/crypto/chacha20poly1305"
"golang.org/x/crypto/curve25519"
"golang.org/x/crypto/hkdf"
- "tailscale.com/types/key"
)
const (
diff --git a/control/controlbase/handshake_test.go b/control/controlbase/handshake_test.go
index f6b5409a8904f..2724414957077 100644
--- a/control/controlbase/handshake_test.go
+++ b/control/controlbase/handshake_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,8 +13,8 @@ import (
"testing"
"time"
- "tailscale.com/net/memnet"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/net/memnet"
+ "github.com/metacubex/tailscale/types/key"
)
func TestHandshake(t *testing.T) {
diff --git a/control/controlbase/interop_test.go b/control/controlbase/interop_test.go
index 87ee7d45876d7..5cc6e9d0acc78 100644
--- a/control/controlbase/interop_test.go
+++ b/control/controlbase/interop_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,8 +13,8 @@ import (
"net"
"testing"
- "tailscale.com/net/memnet"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/net/memnet"
+ "github.com/metacubex/tailscale/types/key"
)
// Can a reference Noise IK client talk to our server?
diff --git a/control/controlbase/noiseexplorer_test.go b/control/controlbase/noiseexplorer_test.go
index 76b6f79be047b..c45eb9eb80bb0 100644
--- a/control/controlbase/noiseexplorer_test.go
+++ b/control/controlbase/noiseexplorer_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// This file contains the implementation of Noise IK from
// https://noiseexplorer.com/ . Unlike the rest of this repository,
// this file is licensed under the terms of the GNU GPL v3. See
diff --git a/control/controlclient/auto.go b/control/controlclient/auto.go
index 05c7552c82185..ad26addba26e5 100644
--- a/control/controlclient/auto.go
+++ b/control/controlclient/auto.go
@@ -12,18 +12,18 @@ import (
"sync/atomic"
"time"
- "tailscale.com/net/sockstats"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/types/persist"
- "tailscale.com/types/structs"
- "tailscale.com/util/backoff"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/execqueue"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/net/sockstats"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/types/structs"
+ "github.com/metacubex/tailscale/util/backoff"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/execqueue"
+ "github.com/metacubex/tailscale/util/testenv"
)
type LoginGoal struct {
@@ -356,7 +356,8 @@ func (c *Auto) authRoutine() {
if err != nil {
c.direct.health.SetAuthRoutineInError(err)
report(err, f)
- if rle, ok := errors.AsType[*rateLimitError](err); ok {
+ var rle *rateLimitError
+ if ok := errors.As(err, &rle); ok {
c.logf("authRoutine: %s", rle)
select {
case <-ctx.Done():
diff --git a/control/controlclient/client.go b/control/controlclient/client.go
index 7d2eaa4fef763..3902c24c36169 100644
--- a/control/controlclient/client.go
+++ b/control/controlclient/client.go
@@ -11,8 +11,8 @@ package controlclient
import (
"context"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
)
// LoginFlags is a bitmask of options to change the behavior of Client.Login
diff --git a/control/controlclient/controlclient_test.go b/control/controlclient/controlclient_test.go
index 5c25af0f4b433..d31f424a85f1f 100644
--- a/control/controlclient/controlclient_test.go
+++ b/control/controlclient/controlclient_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -19,22 +21,22 @@ import (
"testing"
"time"
- "tailscale.com/control/controlknobs"
- "tailscale.com/health"
- "tailscale.com/net/bakedroots"
- "tailscale.com/net/connectproxy"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsdial"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/tstest/integration/testcontrol"
- "tailscale.com/tstest/tlstest"
- "tailscale.com/tstime"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/types/persist"
- "tailscale.com/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/bakedroots"
+ "github.com/metacubex/tailscale/net/connectproxy"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstest/integration/testcontrol"
+ "github.com/metacubex/tailscale/tstest/tlstest"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
)
func fieldsOf(t reflect.Type) (fields []string) {
diff --git a/control/controlclient/direct.go b/control/controlclient/direct.go
index 032999cb9c7f5..b8394bb6d5575 100644
--- a/control/controlclient/direct.go
+++ b/control/controlclient/direct.go
@@ -5,7 +5,6 @@ package controlclient
import (
"bytes"
- "cmp"
"context"
"crypto"
"crypto/sha256"
@@ -15,55 +14,56 @@ import (
"encoding/json"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ "github.com/metacubex/tailscale/util/go120/randv2"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
- "math/rand/v2"
"net"
"net/http"
"net/netip"
"os"
"reflect"
"runtime"
- "slices"
"strconv"
"strings"
"sync/atomic"
"time"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/control/ts2021"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/logtail"
+ "github.com/metacubex/tailscale/net/dnscache"
+ "github.com/metacubex/tailscale/net/dnsfallback"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/net/tlsdial"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/events"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/types/tkatype"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/singleflight"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/util/testenv"
+ "github.com/metacubex/tailscale/util/vizerror"
+ "github.com/metacubex/tailscale/util/zstdframe"
"go4.org/mem"
- "tailscale.com/control/controlknobs"
- "tailscale.com/control/ts2021"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/health"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/logtail"
- "tailscale.com/net/dnscache"
- "tailscale.com/net/dnsfallback"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netx"
- "tailscale.com/net/tlsdial"
- "tailscale.com/net/tsdial"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tka"
- "tailscale.com/tstime"
- "tailscale.com/types/events"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/types/persist"
- "tailscale.com/types/tkatype"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/singleflight"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/policyclient"
- "tailscale.com/util/testenv"
- "tailscale.com/util/vizerror"
- "tailscale.com/util/zstdframe"
)
// Direct is the client that connects to a tailcontrol server for a node.
@@ -153,6 +153,8 @@ type Options struct {
ControlKnobs *controlknobs.Knobs // or nil to ignore
Bus *eventbus.Bus // non-nil, for setting up publishers
+ LookupHook dnscache.LookupHookFunc
+
SkipStartForTests bool // if true, don't call [Auto.Start] to avoid any background goroutines (for tests only)
// StartPaused indicates whether the client should start in a paused state
@@ -282,8 +284,9 @@ func NewDirect(opts Options) (*Direct, error) {
dnsCache := &dnscache.Resolver{
Forward: dnscache.Get().Forward, // use default cache's forwarder
UseLastGood: true,
- LookupIPFallback: dnsfallback.MakeLookupFunc(opts.Logf, netMon),
+ LookupIPFallback: dnsfallback.MakeLookupFunc(opts.Logf, opts.Dialer.SystemDial),
Logf: opts.Logf,
+ LookupHook: opts.LookupHook,
}
httpc := opts.HTTPTestClient
@@ -296,7 +299,13 @@ func NewDirect(opts Options) (*Direct, error) {
}
var interceptedDial *atomic.Bool
if httpc == nil {
- tr := http.DefaultTransport.(*http.Transport).Clone()
+ tr := &http.Transport{
+ ForceAttemptHTTP2: true,
+ MaxIdleConns: 100,
+ IdleConnTimeout: 90 * time.Second,
+ TLSHandshakeTimeout: 10 * time.Second,
+ ExpectContinueTimeout: 1 * time.Second,
+ }
if buildfeatures.HasUseProxy {
tr.Proxy = feature.HookProxyFromEnvironment.GetOrNil()
if f, ok := feature.HookProxySetTransportGetProxyConnectHeader.GetOk(); ok {
@@ -309,7 +318,7 @@ func NewDirect(opts Options) (*Direct, error) {
}
tr.TLSClientConfig.RootCAs = opts.ExtraRootCAs
}
- tr.TLSClientConfig = tlsdial.Config(opts.HealthTracker, tr.TLSClientConfig)
+ tr.TLSClientConfig = tlsdial.ConfigWithLogf(opts.HealthTracker, tr.TLSClientConfig, opts.Logf)
var dialFunc netx.DialFunc
dialFunc, interceptedDial = makeScreenTimeDetectingDialFunc(opts.Dialer.SystemDial)
tr.DialContext = dnscache.Dialer(dialFunc, dnsCache)
@@ -431,7 +440,8 @@ func (c *Direct) SetHostinfo(hi *tailcfg.Hostinfo) bool {
if hi == nil {
panic("nil Hostinfo")
}
- hi = new(*hi)
+ hiCopy := *hi
+ hi = &hiCopy
hi.NetInfo = nil
c.mu.Lock()
defer c.mu.Unlock()
@@ -1595,7 +1605,7 @@ func (c *Direct) answerPing(pr *tailcfg.PingRequest) {
}
return
}
- for t := range strings.SplitSeq(pr.Types, ",") {
+ for _, t := range strings.Split(pr.Types, ",") {
switch pt := tailcfg.PingType(t); pt {
case tailcfg.PingTSMP, tailcfg.PingDisco, tailcfg.PingICMP, tailcfg.PingPeerAPI:
go doPingerPing(c.logf, httpc, pr, c.pinger, pt)
diff --git a/control/controlclient/direct_test.go b/control/controlclient/direct_test.go
index 98741482f1d02..f0a005f8d256b 100644
--- a/control/controlclient/direct_test.go
+++ b/control/controlclient/direct_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -13,13 +15,13 @@ import (
"testing"
"time"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsdial"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
)
func TestSetDiscoPublicKey(t *testing.T) {
diff --git a/control/controlclient/map.go b/control/controlclient/map.go
index 34b5ecc553831..373a0e0b389c7 100644
--- a/control/controlclient/map.go
+++ b/control/controlclient/map.go
@@ -4,38 +4,40 @@
package controlclient
import (
- "cmp"
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
- "maps"
"net"
"net/netip"
"reflect"
"runtime"
"runtime/debug"
- "slices"
"strconv"
"sync"
"time"
- "tailscale.com/control/controlknobs"
- "tailscale.com/envknob"
- "tailscale.com/hostinfo"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/types/views"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
- "tailscale.com/util/slicesx"
- "tailscale.com/wgengine/filter"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/wgengine/filter"
)
type responseWithSource struct {
@@ -522,7 +524,8 @@ func (ms *mapSession) removeUnwantedDiscoUpdatesFromFullNetmapUpdate(resp *tailc
// Overwrite the key and last seen in the full netmap update.
peer.DiscoKey = existingNode.DiscoKey()
if t, ok := existingNode.LastSeen().GetOk(); ok {
- peer.LastSeen = new(t)
+ lastSeen := t
+ peer.LastSeen = &lastSeen
} else {
peer.LastSeen = nil
}
@@ -754,7 +757,8 @@ func (ms *mapSession) updatePeersStateFromResponse(resp *tailcfg.MapResponse) (s
if vp, ok := ms.peers[nodeID]; ok {
mut := vp.AsStruct()
if seen {
- mut.LastSeen = new(clock.Now())
+ lastSeen := clock.Now()
+ mut.LastSeen = &lastSeen
} else {
mut.LastSeen = nil
}
@@ -766,7 +770,8 @@ func (ms *mapSession) updatePeersStateFromResponse(resp *tailcfg.MapResponse) (s
for nodeID, online := range resp.OnlineChange {
if vp, ok := ms.peers[nodeID]; ok {
mut := vp.AsStruct()
- mut.Online = new(online)
+ onlineValue := online
+ mut.Online = &onlineValue
ms.peers[nodeID] = mut.View()
stats.changed++
}
@@ -800,11 +805,13 @@ func (ms *mapSession) updatePeersStateFromResponse(resp *tailcfg.MapResponse) (s
patchDiscoKey.Add(1)
}
if v := pc.Online; v != nil {
- mut.Online = new(*v)
+ online := *v
+ mut.Online = &online
patchOnline.Add(1)
}
if v := pc.LastSeen; v != nil {
- mut.LastSeen = new(*v)
+ lastSeen := *v
+ mut.LastSeen = &lastSeen
patchLastSeen.Add(1)
}
if v := pc.KeyExpiry; v != nil {
@@ -875,14 +882,14 @@ func (ms *mapSession) patchifyPeersChanged(resp *tailcfg.MapResponse) {
}
}
-var nodeFields = sync.OnceValue(getNodeFields)
+var nodeFields = syncs.OnceValue(getNodeFields)
// getNodeFields returns the fields of tailcfg.Node.
func getNodeFields() []string {
- rt := reflect.TypeFor[tailcfg.Node]()
+ rt := reflect.TypeOf((*tailcfg.Node)(nil)).Elem()
ret := make([]string, 0, rt.NumField())
- for f := range rt.Fields() {
- ret = append(ret, f.Name)
+ for i := 0; i < rt.NumField(); i++ {
+ ret = append(ret, rt.Field(i).Name)
}
return ret
}
@@ -961,11 +968,13 @@ func peerChangeDiff(was tailcfg.NodeView, n *tailcfg.Node, onFalse func(string))
}
case "Key":
if was.Key() != n.Key {
- pc().Key = new(n.Key)
+ key := n.Key
+ pc().Key = &key
}
case "KeyExpiry":
if !was.KeyExpiry().Equal(n.KeyExpiry) {
- pc().KeyExpiry = new(n.KeyExpiry)
+ keyExpiry := n.KeyExpiry
+ pc().KeyExpiry = &keyExpiry
}
case "KeySignature":
if !was.KeySignature().Equal(n.KeySignature) {
@@ -978,7 +987,8 @@ func peerChangeDiff(was tailcfg.NodeView, n *tailcfg.Node, onFalse func(string))
}
case "DiscoKey":
if was.DiscoKey() != n.DiscoKey {
- pc().DiscoKey = new(n.DiscoKey)
+ discoKey := n.DiscoKey
+ pc().DiscoKey = &discoKey
}
case "Addresses":
if !views.SliceEqual(was.Addresses(), views.SliceOf(n.Addresses)) {
@@ -1034,13 +1044,14 @@ func peerChangeDiff(was tailcfg.NodeView, n *tailcfg.Node, onFalse func(string))
} else {
// If they have the same length, check that all their keys
// have the same values.
- for k, v := range was.CapMap().All() {
+ was.CapMap().All()(func(k tailcfg.NodeCapability, v views.Slice[tailcfg.RawMessage]) bool {
nv, ok := n.CapMap[k]
if !ok || !views.SliceEqual(v, views.SliceOf(nv)) {
pc().CapMap = maps.Clone(n.CapMap)
- break
+ return false
}
- }
+ return true
+ })
}
case "Tags":
if !views.SliceEqual(was.Tags(), views.SliceOf(n.Tags)) {
@@ -1054,11 +1065,13 @@ func peerChangeDiff(was tailcfg.NodeView, n *tailcfg.Node, onFalse func(string))
}
case "Online":
if wasOnline, ok := was.Online().GetOk(); ok && n.Online != nil && *n.Online != wasOnline {
- pc().Online = new(*n.Online)
+ online := *n.Online
+ pc().Online = &online
}
case "LastSeen":
if wasSeen, ok := was.LastSeen().GetOk(); ok && n.LastSeen != nil && !wasSeen.Equal(*n.LastSeen) {
- pc().LastSeen = new(*n.LastSeen)
+ lastSeen := *n.LastSeen
+ pc().LastSeen = &lastSeen
}
case "MachineAuthorized":
if was.MachineAuthorized() != n.MachineAuthorized {
@@ -1104,14 +1117,14 @@ func peerChangeDiff(was tailcfg.NodeView, n *tailcfg.Node, onFalse func(string))
return nil, false
}
case "ExitNodeDNSResolvers":
- va, vb := was.ExitNodeDNSResolvers(), views.SliceOfViews(n.ExitNodeDNSResolvers)
+ va, vb := was.ExitNodeDNSResolvers(), views.SliceOfViews[*dnstype.Resolver, dnstype.ResolverView](n.ExitNodeDNSResolvers)
if va.Len() != vb.Len() {
onFalse(field)
return nil, false
}
- for i := range va.Len() {
+ for i := 0; i < va.Len(); i++ {
if !va.At(i).Equal(vb.At(i)) {
onFalse(field)
return nil, false
@@ -1134,7 +1147,7 @@ func (ms *mapSession) PeerIDAndKeyByTailscaleIP(ip netip.Addr) (tailcfg.NodeID,
defer ms.peersMu.RUnlock()
for _, n := range ms.peers {
ad := n.Addresses()
- for i := range ad.Len() {
+ for i := 0; i < ad.Len(); i++ {
a := ad.At(i)
if a.Addr() == ip {
return n.ID(), n.Key(), true
diff --git a/control/controlclient/map_debug.go b/control/controlclient/map_debug.go
index 2d6012211cba7..05b2d85c4b534 100644
--- a/control/controlclient/map_debug.go
+++ b/control/controlclient/map_debug.go
@@ -1,11 +1,11 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_debug
+//go:build ts_enable_debug
package controlclient
-import "tailscale.com/metrics"
+import "github.com/metacubex/tailscale/metrics"
var patchifyMissStats = metrics.NewLabelMap("counter_patchify_miss", "why")
diff --git a/control/controlclient/map_test.go b/control/controlclient/map_test.go
index ebebc2e664e4e..cee7462ad6bf7 100644
--- a/control/controlclient/map_test.go
+++ b/control/controlclient/map_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,7 +10,7 @@ import (
"context"
"encoding/json"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"net/netip"
"reflect"
"strings"
@@ -19,24 +21,24 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/usermetric"
+ "github.com/metacubex/tailscale/util/zstdframe"
+ "github.com/metacubex/tailscale/wgengine"
"go4.org/mem"
- "tailscale.com/control/controlknobs"
- "tailscale.com/health"
- "tailscale.com/ipn"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/tstime"
- "tailscale.com/types/dnstype"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/types/persist"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/mak"
- "tailscale.com/util/must"
- "tailscale.com/util/usermetric"
- "tailscale.com/util/zstdframe"
- "tailscale.com/wgengine"
)
func eps(s ...string) []netip.AddrPort {
diff --git a/control/controlclient/sign.go b/control/controlclient/sign.go
index 6cee1265fe99b..15e5816a15650 100644
--- a/control/controlclient/sign.go
+++ b/control/controlclient/sign.go
@@ -9,8 +9,8 @@ import (
"fmt"
"time"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
)
var (
diff --git a/control/controlclient/sign_supported.go b/control/controlclient/sign_supported.go
index f3340d5a6c98f..93f79f4b55be2 100644
--- a/control/controlclient/sign_supported.go
+++ b/control/controlclient/sign_supported.go
@@ -13,11 +13,11 @@ import (
"fmt"
"time"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
"github.com/tailscale/certstore"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/policyclient"
)
// getMachineCertificateSubject returns the exact name of a Subject that needs
diff --git a/control/controlclient/sign_supported_test.go b/control/controlclient/sign_supported_test.go
index 9d4abafbd12f6..6c3faf685f1aa 100644
--- a/control/controlclient/sign_supported_test.go
+++ b/control/controlclient/sign_supported_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build windows && cgo
-
package controlclient
import (
diff --git a/control/controlclient/sign_unsupported.go b/control/controlclient/sign_unsupported.go
index a371cbaf1e609..b58e356d91f51 100644
--- a/control/controlclient/sign_unsupported.go
+++ b/control/controlclient/sign_unsupported.go
@@ -6,9 +6,9 @@
package controlclient
import (
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
// signRegisterRequest on non-supported platforms always returns errNoCertStore.
diff --git a/control/controlclient/status.go b/control/controlclient/status.go
index 46dc8f773f260..20637d73cfbc5 100644
--- a/control/controlclient/status.go
+++ b/control/controlclient/status.go
@@ -6,9 +6,9 @@ package controlclient
import (
"reflect"
- "tailscale.com/types/netmap"
- "tailscale.com/types/persist"
- "tailscale.com/types/structs"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/types/structs"
)
type Status struct {
diff --git a/control/controlhttp/client.go b/control/controlhttp/client.go
index 2aabcbb6418a0..7cdc80ceb6ce7 100644
--- a/control/controlhttp/client.go
+++ b/control/controlhttp/client.go
@@ -20,12 +20,12 @@
package controlhttp
import (
- "cmp"
"context"
"crypto/tls"
"encoding/base64"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"io"
"net"
"net/http"
@@ -36,21 +36,21 @@ import (
"sync/atomic"
"time"
- "tailscale.com/control/controlbase"
- "tailscale.com/control/controlhttp/controlhttpcommon"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/health"
- "tailscale.com/net/dnscache"
- "tailscale.com/net/dnsfallback"
- "tailscale.com/net/netutil"
- "tailscale.com/net/netx"
- "tailscale.com/net/sockstats"
- "tailscale.com/net/tlsdial"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
+ "github.com/metacubex/tailscale/control/controlbase"
+ "github.com/metacubex/tailscale/control/controlhttp/controlhttpcommon"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/dnscache"
+ "github.com/metacubex/tailscale/net/dnsfallback"
+ "github.com/metacubex/tailscale/net/netutil"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/net/sockstats"
+ "github.com/metacubex/tailscale/net/tlsdial"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
)
var stdDialer net.Dialer
@@ -369,9 +369,16 @@ func (a *Dialer) resolver() *dnscache.Resolver {
return a.DNSCache
}
+ var dialer netx.DialFunc
+ if a.Dialer != nil {
+ dialer = a.Dialer
+ } else {
+ dialer = stdDialer.DialContext
+ }
+
return &dnscache.Resolver{
Forward: dnscache.Get().Forward,
- LookupIPFallback: dnsfallback.MakeLookupFunc(a.logf, a.NetMon),
+ LookupIPFallback: dnsfallback.MakeLookupFunc(a.logf, dialer),
UseLastGood: true,
Logf: a.Logf, // not a.logf method; we want to propagate nil-ness
}
@@ -459,7 +466,13 @@ func (a *Dialer) tryURLUpgrade(ctx context.Context, u *url.URL, optAddr netip.Ad
}()
}
- tr := http.DefaultTransport.(*http.Transport).Clone()
+ tr := (&http.Transport{
+ ForceAttemptHTTP2: true,
+ MaxIdleConns: 100,
+ IdleConnTimeout: 90 * time.Second,
+ TLSHandshakeTimeout: 10 * time.Second,
+ ExpectContinueTimeout: 1 * time.Second,
+ }).Clone()
defer tr.CloseIdleConnections()
if optACEHost != "" {
// If using ACE, we don't want to use any HTTP proxy.
@@ -482,7 +495,7 @@ func (a *Dialer) tryURLUpgrade(ctx context.Context, u *url.URL, optAddr netip.Ad
if a.ExtraRootCAs != nil {
tr.TLSClientConfig.RootCAs = a.ExtraRootCAs
}
- tr.TLSClientConfig = tlsdial.Config(a.HealthTracker, tr.TLSClientConfig)
+ tr.TLSClientConfig = tlsdial.ConfigWithLogf(a.HealthTracker, tr.TLSClientConfig, a.Logf)
if !tr.TLSClientConfig.InsecureSkipVerify {
panic("unexpected") // should be set by tlsdial.Config
}
diff --git a/control/controlhttp/client_common.go b/control/controlhttp/client_common.go
index 5e49b0bfcc295..97930b3d5c644 100644
--- a/control/controlhttp/client_common.go
+++ b/control/controlhttp/client_common.go
@@ -4,7 +4,7 @@
package controlhttp
import (
- "tailscale.com/control/controlbase"
+ "github.com/metacubex/tailscale/control/controlbase"
)
// ClientConn is a Tailscale control client as returned by the Dialer.
diff --git a/control/controlhttp/client_js.go b/control/controlhttp/client_js.go
index e9a4e7dbb205a..42ca39b0653e0 100644
--- a/control/controlhttp/client_js.go
+++ b/control/controlhttp/client_js.go
@@ -11,9 +11,9 @@ import (
"net/url"
"github.com/coder/websocket"
- "tailscale.com/control/controlbase"
- "tailscale.com/control/controlhttp/controlhttpcommon"
- "tailscale.com/net/wsconn"
+ "github.com/metacubex/tailscale/control/controlbase"
+ "github.com/metacubex/tailscale/control/controlhttp/controlhttpcommon"
+ "github.com/metacubex/tailscale/net/wsconn"
)
// Variant of Dial that tunnels the request over WebSockets, since we cannot do
diff --git a/control/controlhttp/constants.go b/control/controlhttp/constants.go
index efa8d84990bc1..353daef451d00 100644
--- a/control/controlhttp/constants.go
+++ b/control/controlhttp/constants.go
@@ -10,14 +10,14 @@ import (
"sync/atomic"
"time"
- "tailscale.com/health"
- "tailscale.com/net/dnscache"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netx"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/dnscache"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
)
const (
diff --git a/control/controlhttp/controlhttpserver/controlhttpserver.go b/control/controlhttp/controlhttpserver/controlhttpserver.go
index 7b413829eff78..2f564588fc81a 100644
--- a/control/controlhttp/controlhttpserver/controlhttpserver.go
+++ b/control/controlhttp/controlhttpserver/controlhttpserver.go
@@ -18,11 +18,11 @@ import (
"time"
"github.com/coder/websocket"
- "tailscale.com/control/controlbase"
- "tailscale.com/control/controlhttp/controlhttpcommon"
- "tailscale.com/net/netutil"
- "tailscale.com/net/wsconn"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/control/controlbase"
+ "github.com/metacubex/tailscale/control/controlhttp/controlhttpcommon"
+ "github.com/metacubex/tailscale/net/netutil"
+ "github.com/metacubex/tailscale/net/wsconn"
+ "github.com/metacubex/tailscale/types/key"
)
// AcceptHTTP upgrades the HTTP request given by w and r into a Tailscale
diff --git a/control/controlhttp/http_test.go b/control/controlhttp/http_test.go
index 7f0203cd051df..44bc46d5c14d7 100644
--- a/control/controlhttp/http_test.go
+++ b/control/controlhttp/http_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,6 +9,7 @@ import (
"context"
"crypto/tls"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
"net"
@@ -15,7 +18,6 @@ import (
"net/http/httputil"
"net/netip"
"net/url"
- "slices"
"strconv"
"strings"
"sync"
@@ -23,21 +25,21 @@ import (
"testing/synctest"
"time"
- "tailscale.com/control/controlbase"
- "tailscale.com/control/controlhttp/controlhttpcommon"
- "tailscale.com/control/controlhttp/controlhttpserver"
- "tailscale.com/health"
- "tailscale.com/net/memnet"
- "tailscale.com/net/netmon"
- "tailscale.com/net/socks5"
- "tailscale.com/net/tsdial"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/tstime"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/control/controlbase"
+ "github.com/metacubex/tailscale/control/controlhttp/controlhttpcommon"
+ "github.com/metacubex/tailscale/control/controlhttp/controlhttpserver"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/memnet"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/socks5"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/must"
)
type httpTestParam struct {
diff --git a/control/controlknobs/controlknobs.go b/control/controlknobs/controlknobs.go
index 77a496349c314..d1f6bb827085c 100644
--- a/control/controlknobs/controlknobs.go
+++ b/control/controlknobs/controlknobs.go
@@ -10,9 +10,9 @@ import (
"reflect"
"sync/atomic"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/types/opt"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/opt"
)
// Knobs is the set of knobs that the control plane's coordination server can
@@ -176,7 +176,9 @@ func (k *Knobs) AsDebugJSON() map[string]any {
}
ret := map[string]any{}
rv := reflect.ValueOf(k).Elem() // of *k
- for sf, fv := range rv.Fields() {
+ for i := 0; i < rv.NumField(); i++ {
+ sf := rv.Type().Field(i)
+ fv := rv.Field(i)
switch v := fv.Addr().Interface().(type) {
case *atomic.Bool:
ret[sf.Name] = v.Load()
diff --git a/control/controlknobs/controlknobs_test.go b/control/controlknobs/controlknobs_test.go
index 495535b1e2807..d5f40ee58c902 100644
--- a/control/controlknobs/controlknobs_test.go
+++ b/control/controlknobs/controlknobs_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,7 +9,7 @@ import (
"reflect"
"testing"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
func TestAsDebugJSON(t *testing.T) {
diff --git a/control/ts2021/client.go b/control/ts2021/client.go
index 5770bae090274..98aa10de207eb 100644
--- a/control/ts2021/client.go
+++ b/control/ts2021/client.go
@@ -5,12 +5,13 @@ package ts2021
import (
"bytes"
- "cmp"
"context"
+ "crypto/tls"
"crypto/x509"
"encoding/json"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"log"
"math"
"net"
@@ -20,17 +21,19 @@ import (
"sync"
"time"
- "tailscale.com/control/controlhttp"
- "tailscale.com/health"
- "tailscale.com/net/dnscache"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsdial"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
+ "golang.org/x/net/http2"
+
+ "github.com/metacubex/tailscale/control/controlhttp"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/dnscache"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
)
// Client provides a http.Client to connect to tailcontrol over
@@ -162,15 +165,8 @@ func NewClient(opts ClientOpts) (*Client, error) {
logf: logf,
}
- tr := &http.Transport{
- Protocols: new(http.Protocols),
- MaxConnsPerHost: 1,
- }
- // We force only HTTP/2 for this transport, which is what the control server
- // speaks inside the ts2021 Noise encryption. But Go doesn't know about that,
- // so we use "SetUnencryptedHTTP2" even though it's actually encrypted.
- tr.Protocols.SetUnencryptedHTTP2(true)
- tr.DialTLSContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
+ tr := &http2.Transport{}
+ tr.DialTLSContext = func(ctx context.Context, network, addr string, _ *tls.Config) (net.Conn, error) {
return np.dial(ctx)
}
diff --git a/control/ts2021/client_test.go b/control/ts2021/client_test.go
index da823fc548593..ea13ce007531d 100644
--- a/control/ts2021/client_test.go
+++ b/control/ts2021/client_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -15,15 +17,15 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/control/controlhttp/controlhttpserver"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest/nettest"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/must"
"golang.org/x/net/http2"
- "tailscale.com/control/controlhttp/controlhttpserver"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsdial"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest/nettest"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/util/must"
)
// maxAllowedNoiseVersion is the highest we expect the Tailscale
diff --git a/control/ts2021/conn.go b/control/ts2021/conn.go
index 6832f2df12a4f..f6a01ddd09542 100644
--- a/control/ts2021/conn.go
+++ b/control/ts2021/conn.go
@@ -15,8 +15,8 @@ import (
"io"
"sync"
- "tailscale.com/control/controlbase"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/control/controlbase"
+ "github.com/metacubex/tailscale/tailcfg"
)
// Conn is a wrapper around controlbase.Conn.
@@ -50,7 +50,10 @@ func NewConn(conn *controlbase.Conn, onClose func()) *Conn {
return &Conn{
Conn: conn,
earlyPayloadReady: make(chan struct{}),
- onClose: sync.OnceFunc(onClose),
+ onClose: func() func() {
+ var once sync.Once
+ return func() { once.Do(onClose) }
+ }(),
}
}
diff --git a/control/tsp/map.go b/control/tsp/map.go
index 961c5dd57c0f6..4e53579fd5df4 100644
--- a/control/tsp/map.go
+++ b/control/tsp/map.go
@@ -5,12 +5,12 @@ package tsp
import (
"bytes"
- "cmp"
"context"
"encoding/binary"
"encoding/json"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"io"
"net/http"
"strings"
@@ -18,9 +18,9 @@ import (
"sync/atomic"
"github.com/klauspost/compress/zstd"
- "tailscale.com/control/ts2021"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/control/ts2021"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
)
// errSessionClosed is returned by [MapSession.Next] and
diff --git a/control/tsp/map_test.go b/control/tsp/map_test.go
index ddfde3971800c..ee6b2ae4cd68a 100644
--- a/control/tsp/map_test.go
+++ b/control/tsp/map_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -16,10 +18,10 @@ import (
"time"
"github.com/klauspost/compress/zstd"
- "tailscale.com/health"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest/integration/testcontrol"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest/integration/testcontrol"
+ "github.com/metacubex/tailscale/types/key"
)
func TestMapAgainstTestControl(t *testing.T) {
diff --git a/control/tsp/nodefile.go b/control/tsp/nodefile.go
index 8cae11ba9fe67..e412259ca597d 100644
--- a/control/tsp/nodefile.go
+++ b/control/tsp/nodefile.go
@@ -8,7 +8,7 @@ import (
"fmt"
"os"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/types/key"
)
// ServerInfo identifies a coordination server by its URL and Noise public key.
diff --git a/control/tsp/nodefile_test.go b/control/tsp/nodefile_test.go
index 4a019f25fcbd4..29ff167850ae4 100644
--- a/control/tsp/nodefile_test.go
+++ b/control/tsp/nodefile_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,7 +11,7 @@ import (
"path/filepath"
"testing"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/types/key"
)
func TestNodeFileRoundTrip(t *testing.T) {
diff --git a/control/tsp/register.go b/control/tsp/register.go
index 0d2baf75fe3ef..8520a69eb1b0c 100644
--- a/control/tsp/register.go
+++ b/control/tsp/register.go
@@ -5,17 +5,17 @@ package tsp
import (
"bytes"
- "cmp"
"context"
"encoding/json"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"io"
"net/http"
"strings"
- "tailscale.com/control/ts2021"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/control/ts2021"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
)
// RegisterOpts contains options for registering a node.
diff --git a/control/tsp/tsp.go b/control/tsp/tsp.go
index 23f2fc26115b9..4d1f330d68cfc 100644
--- a/control/tsp/tsp.go
+++ b/control/tsp/tsp.go
@@ -8,24 +8,24 @@ package tsp
import (
"bufio"
"bytes"
- "cmp"
"context"
"encoding/json"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"io"
"net"
"net/http"
"strconv"
"sync"
- "tailscale.com/control/ts2021"
- "tailscale.com/health"
- "tailscale.com/ipn"
- "tailscale.com/net/tsdial"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/control/ts2021"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/version"
)
// DefaultServerURL is the default coordination server base URL,
diff --git a/derp/client_test.go b/derp/client_test.go
index 697aa49617925..c1c9c9154b0bd 100644
--- a/derp/client_test.go
+++ b/derp/client_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,8 +14,8 @@ import (
"testing"
"time"
- "tailscale.com/tstest"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/key"
)
type dummyNetConn struct {
diff --git a/derp/derp.go b/derp/derp.go
index a478c16a06911..a2df90e90e463 100644
--- a/derp/derp.go
+++ b/derp/derp.go
@@ -231,7 +231,7 @@ func readFrame(br *bufio.Reader, maxSize uint32, b []byte) (t FrameType, frameLe
return 0, 0, fmt.Errorf("frame header size %d exceeds reader limit of %d", frameLen, maxSize)
}
- n, err := io.ReadFull(br, b[:min(frameLen, uint32(len(b)))])
+ n, err := io.ReadFull(br, b[:minUint32(frameLen, uint32(len(b)))])
if err != nil {
return 0, 0, err
}
@@ -304,3 +304,10 @@ type ServerInfo struct {
TokenBucketBytesPerSecond int `json:",omitempty"`
TokenBucketBytesBurst int `json:",omitempty"`
}
+
+func minUint32(a, b uint32) uint32 {
+ if a < b {
+ return a
+ }
+ return b
+}
diff --git a/derp/derp_client.go b/derp/derp_client.go
index f786179d62833..db80b8ec22bcc 100644
--- a/derp/derp_client.go
+++ b/derp/derp_client.go
@@ -14,12 +14,12 @@ import (
"sync"
"time"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
"go4.org/mem"
"golang.org/x/time/rate"
- "tailscale.com/syncs"
- "tailscale.com/tstime"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
)
// Client is a DERP client.
diff --git a/derp/derp_test.go b/derp/derp_test.go
index 0edbaff170406..995d3b275512f 100644
--- a/derp/derp_test.go
+++ b/derp/derp_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -18,14 +20,14 @@ import (
"testing"
"time"
- "tailscale.com/derp"
- "tailscale.com/derp/derpserver"
- "tailscale.com/disco"
- "tailscale.com/metrics"
- "tailscale.com/net/memnet"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/derp"
+ "github.com/metacubex/tailscale/derp/derpserver"
+ "github.com/metacubex/tailscale/disco"
+ "github.com/metacubex/tailscale/metrics"
+ "github.com/metacubex/tailscale/net/memnet"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/must"
)
type (
diff --git a/derp/derphttp/derphttp_client.go b/derp/derphttp/derphttp_client.go
index 3c8408e95e1f1..8b741229f46f7 100644
--- a/derp/derphttp/derphttp_client.go
+++ b/derp/derphttp/derphttp_client.go
@@ -11,13 +11,13 @@ package derphttp
import (
"bufio"
- "cmp"
"context"
"crypto/rand"
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"io"
"net"
"net/http"
@@ -28,24 +28,24 @@ import (
"sync"
"time"
+ "github.com/metacubex/tailscale/derp"
+ "github.com/metacubex/tailscale/derp/derpconst"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/dnscache"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/net/sockstats"
+ "github.com/metacubex/tailscale/net/tlsdial"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
"go4.org/mem"
- "tailscale.com/derp"
- "tailscale.com/derp/derpconst"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/health"
- "tailscale.com/net/dnscache"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netns"
- "tailscale.com/net/netx"
- "tailscale.com/net/sockstats"
- "tailscale.com/net/tlsdial"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
)
// Client is a DERP-over-HTTP client.
@@ -584,8 +584,7 @@ func (c *Client) connect(ctx context.Context, caller string) (client *derp.Clien
return c.client, c.connGen, nil
}
-// SetURLDialer sets the dialer to use for dialing URLs.
-// This dialer is only use for clients created with NewClient, not NewRegionClient.
+// SetURLDialer sets the dialer to use for dialing URLs and DERP regions.
// If unset or nil, the default dialer is used.
//
// The primary use for this is the derper mesh mode to connect to each
@@ -648,7 +647,7 @@ func (c *Client) dialRegion(ctx context.Context, reg *tailcfg.DERPRegion) (net.C
}
func (c *Client) tlsClient(nc net.Conn, node *tailcfg.DERPNode) *tls.Conn {
- tlsConf := tlsdial.Config(c.HealthTracker, c.TLSConfig)
+ tlsConf := tlsdial.ConfigWithLogf(c.HealthTracker, c.TLSConfig, c.logf)
// node is allowed to be nil here, tlsServerName falls back to using the URL
// if node is nil.
tlsConf.ServerName = c.tlsServerName(node)
@@ -702,6 +701,9 @@ func (c *Client) DialRegionTLS(ctx context.Context, reg *tailcfg.DERPRegion) (tl
}
func (c *Client) dialContext(ctx context.Context, proto, addr string) (net.Conn, error) {
+ if c.dialer != nil {
+ return c.dialer(ctx, proto, addr)
+ }
return netns.NewDialer(c.logf, c.netMon).DialContext(ctx, proto, addr)
}
diff --git a/derp/derphttp/derphttp_test.go b/derp/derphttp/derphttp_test.go
index 304906b749257..7a4f1b2bcad16 100644
--- a/derp/derphttp/derphttp_test.go
+++ b/derp/derphttp/derphttp_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,26 +13,26 @@ import (
"errors"
"flag"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net"
"net/http"
"net/http/httptest"
- "slices"
"strings"
"sync"
"testing"
"testing/synctest"
"time"
- "tailscale.com/derp"
- "tailscale.com/derp/derphttp"
- "tailscale.com/derp/derpserver"
- "tailscale.com/net/memnet"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netx"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/derp"
+ "github.com/metacubex/tailscale/derp/derphttp"
+ "github.com/metacubex/tailscale/derp/derpserver"
+ "github.com/metacubex/tailscale/net/memnet"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/key"
)
func TestSendRecv(t *testing.T) {
@@ -565,7 +567,7 @@ func TestManualDial(t *testing.T) {
t.Skip("skipping live network test without --live-net-tests")
}
dm := &tailcfg.DERPMap{}
- res, err := http.Get("https://controlplane.tailscale.com/derpmap/default")
+ res, err := http.Get("https://controlplane.github.com/metacubex/tailscale/derpmap/default")
if err != nil {
t.Fatalf("fetching DERPMap: %v", err)
}
@@ -592,7 +594,7 @@ func TestURLDial(t *testing.T) {
t.Skip("skipping live network test without --live-net-tests")
}
dm := &tailcfg.DERPMap{}
- res, err := http.Get("https://controlplane.tailscale.com/derpmap/default")
+ res, err := http.Get("https://controlplane.github.com/metacubex/tailscale/derpmap/default")
if err != nil {
t.Fatalf("fetching DERPMap: %v", err)
}
diff --git a/derp/derphttp/export_test.go b/derp/derphttp/export_test.go
index e3f449277fd6a..8a85686be0df9 100644
--- a/derp/derphttp/export_test.go
+++ b/derp/derphttp/export_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/derp/derphttp/mesh_client.go b/derp/derphttp/mesh_client.go
index d8fa7cd9aae03..82a97db8bab6c 100644
--- a/derp/derphttp/mesh_client.go
+++ b/derp/derphttp/mesh_client.go
@@ -8,9 +8,9 @@ import (
"sync"
"time"
- "tailscale.com/derp"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/derp"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
)
var retryInterval = 5 * time.Second
diff --git a/derp/derphttp/websocket.go b/derp/derphttp/websocket.go
index 295d0a9bd44de..40bbc73c21856 100644
--- a/derp/derphttp/websocket.go
+++ b/derp/derphttp/websocket.go
@@ -11,7 +11,7 @@ import (
"net"
"github.com/coder/websocket"
- "tailscale.com/net/wsconn"
+ "github.com/metacubex/tailscale/net/wsconn"
)
const canWebsockets = true
diff --git a/derp/derpserver/derpserver.go b/derp/derpserver/derpserver.go
index e1b45ba3f1aa3..d6c8fee7fecf3 100644
--- a/derp/derpserver/derpserver.go
+++ b/derp/derpserver/derpserver.go
@@ -20,17 +20,17 @@ import (
"errors"
"expvar"
"fmt"
+ "github.com/metacubex/tailscale/util/go120/randv2"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
"math"
"math/big"
- "math/rand/v2"
"net/http"
"net/netip"
"os"
"os/exec"
"runtime"
- "slices"
"strconv"
"strings"
"sync"
@@ -39,27 +39,27 @@ import (
"github.com/axiomhq/hyperloglog"
"github.com/go4org/hashtriemap"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/derp"
+ "github.com/metacubex/tailscale/derp/derpconst"
+ "github.com/metacubex/tailscale/disco"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/metrics"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/tstime/rate"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/bufiox"
+ "github.com/metacubex/tailscale/util/ctxkey"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/version"
"go4.org/mem"
"golang.org/x/sync/errgroup"
xrate "golang.org/x/time/rate"
- "tailscale.com/client/local"
- "tailscale.com/derp"
- "tailscale.com/derp/derpconst"
- "tailscale.com/disco"
- "tailscale.com/envknob"
- "tailscale.com/metrics"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/tstime/rate"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/util/bufiox"
- "tailscale.com/util/ctxkey"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
- "tailscale.com/util/slicesx"
- "tailscale.com/version"
)
// verboseDropKeys is the set of destination public keys that should
diff --git a/derp/derpserver/derpserver_linux.go b/derp/derpserver/derpserver_linux.go
index c6154661c5486..db894fa236967 100644
--- a/derp/derpserver/derpserver_linux.go
+++ b/derp/derpserver/derpserver_linux.go
@@ -11,7 +11,7 @@ import (
"net"
"time"
- "tailscale.com/net/tcpinfo"
+ "github.com/metacubex/tailscale/net/tcpinfo"
)
func (c *sclient) startStatsLoop(ctx context.Context) {
diff --git a/derp/derpserver/derpserver_test.go b/derp/derpserver/derpserver_test.go
index 9e9dc98024084..6475925a57e23 100644
--- a/derp/derpserver/derpserver_test.go
+++ b/derp/derpserver/derpserver_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,13 +7,13 @@ package derpserver
import (
"bufio"
- "cmp"
"context"
"crypto/x509"
"encoding/asn1"
"encoding/binary"
"expvar"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"log"
"net"
"os"
@@ -25,15 +27,15 @@ import (
"github.com/axiomhq/hyperloglog"
qt "github.com/frankban/quicktest"
+ "github.com/metacubex/tailscale/derp"
+ "github.com/metacubex/tailscale/derp/derpconst"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/set"
"go4.org/mem"
"golang.org/x/time/rate"
- "tailscale.com/derp"
- "tailscale.com/derp/derpconst"
- "tailscale.com/envknob"
- "tailscale.com/tstime"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/util/set"
)
const testMeshKey = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
diff --git a/derp/derpserver/handler.go b/derp/derpserver/handler.go
index f639cb7123c73..068602890f8af 100644
--- a/derp/derpserver/handler.go
+++ b/derp/derpserver/handler.go
@@ -9,7 +9,7 @@ import (
"net/http"
"strings"
- "tailscale.com/derp"
+ "github.com/metacubex/tailscale/derp"
)
// Handler returns an http.Handler to be mounted at /derp, serving s.
diff --git a/derp/export_test.go b/derp/export_test.go
index 9a73dd13e2798..9e281568a134a 100644
--- a/derp/export_test.go
+++ b/derp/export_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/derp/xdp/xdp_linux_test.go b/derp/xdp/xdp_linux_test.go
index d8de2bf62d24d..bb314d68f177a 100644
--- a/derp/xdp/xdp_linux_test.go
+++ b/derp/xdp/xdp_linux_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux
-
package xdp
import (
@@ -13,12 +13,12 @@ import (
"testing"
"github.com/cilium/ebpf"
+ "github.com/metacubex/gvisor/pkg/tcpip"
+ "github.com/metacubex/gvisor/pkg/tcpip/checksum"
+ "github.com/metacubex/gvisor/pkg/tcpip/header"
+ "github.com/metacubex/tailscale/net/stun"
+ "github.com/metacubex/tailscale/tstest"
"golang.org/x/sys/unix"
- "gvisor.dev/gvisor/pkg/tcpip"
- "gvisor.dev/gvisor/pkg/tcpip/checksum"
- "gvisor.dev/gvisor/pkg/tcpip/header"
- "tailscale.com/net/stun"
- "tailscale.com/tstest"
)
type xdpAction uint32
diff --git a/disco/disco.go b/disco/disco.go
index 19a172412ce70..8fb4865b3d110 100644
--- a/disco/disco.go
+++ b/disco/disco.go
@@ -27,8 +27,8 @@ import (
"net/netip"
"time"
+ "github.com/metacubex/tailscale/types/key"
"go4.org/mem"
- "tailscale.com/types/key"
)
// Magic is the 6 byte header of all discovery messages.
@@ -456,7 +456,7 @@ func parseBindUDPRelayEndpointAnswer(ver uint8, p []byte) (m *BindUDPRelayEndpoi
}
// AllocateUDPRelayEndpointRequest is a message sent only over DERP to request
-// allocation of a relay endpoint on a [tailscale.com/net/udprelay.Server]
+// allocation of a relay endpoint on a [github.com/metacubex/tailscale/net/udprelay.Server]
type AllocateUDPRelayEndpointRequest struct {
// ClientDisco are the Disco public keys of the clients that should be
// permitted to handshake with the endpoint.
@@ -474,7 +474,7 @@ const allocateUDPRelayEndpointRequestLen = key.DiscoPublicRawLen*2 + // ClientDi
func (m *AllocateUDPRelayEndpointRequest) AppendMarshal(b []byte) []byte {
ret, p := appendMsgHeader(b, TypeAllocateUDPRelayEndpointRequest, v0, allocateUDPRelayEndpointRequestLen)
- for i := range len(m.ClientDisco) {
+ for i := 0; i < len(m.ClientDisco); i++ {
disco := m.ClientDisco[i].AppendTo(nil)
copy(p, disco)
p = p[key.DiscoPublicRawLen:]
@@ -491,7 +491,7 @@ func parseAllocateUDPRelayEndpointRequest(ver uint8, p []byte) (m *AllocateUDPRe
if len(p) < allocateUDPRelayEndpointRequestLen {
return m, errShort
}
- for i := range len(m.ClientDisco) {
+ for i := 0; i < len(m.ClientDisco); i++ {
m.ClientDisco[i] = key.DiscoPublicFromRaw32(mem.B(p[:key.DiscoPublicRawLen]))
p = p[key.DiscoPublicRawLen:]
}
@@ -538,23 +538,23 @@ const udpRelayEndpointLenMinusAddrPorts = key.DiscoPublicRawLen + // ServerDisco
8 + // BindLifetime
8 // SteadyStateLifetime
-// UDPRelayEndpoint is a mirror of [tailscale.com/net/udprelay/endpoint.ServerEndpoint],
+// UDPRelayEndpoint is a mirror of [github.com/metacubex/tailscale/net/udprelay/endpoint.ServerEndpoint],
// refer to it for field documentation. [UDPRelayEndpoint] is carried in both
// [CallMeMaybeVia] and [AllocateUDPRelayEndpointResponse] messages.
type UDPRelayEndpoint struct {
- // ServerDisco is [tailscale.com/net/udprelay/endpoint.ServerEndpoint.ServerDisco]
+ // ServerDisco is [github.com/metacubex/tailscale/net/udprelay/endpoint.ServerEndpoint.ServerDisco]
ServerDisco key.DiscoPublic
- // ClientDisco is [tailscale.com/net/udprelay/endpoint.ServerEndpoint.ClientDisco]
+ // ClientDisco is [github.com/metacubex/tailscale/net/udprelay/endpoint.ServerEndpoint.ClientDisco]
ClientDisco [2]key.DiscoPublic
- // LamportID is [tailscale.com/net/udprelay/endpoint.ServerEndpoint.LamportID]
+ // LamportID is [github.com/metacubex/tailscale/net/udprelay/endpoint.ServerEndpoint.LamportID]
LamportID uint64
- // VNI is [tailscale.com/net/udprelay/endpoint.ServerEndpoint.VNI]
+ // VNI is [github.com/metacubex/tailscale/net/udprelay/endpoint.ServerEndpoint.VNI]
VNI uint32
- // BindLifetime is [tailscale.com/net/udprelay/endpoint.ServerEndpoint.BindLifetime]
+ // BindLifetime is [github.com/metacubex/tailscale/net/udprelay/endpoint.ServerEndpoint.BindLifetime]
BindLifetime time.Duration
- // SteadyStateLifetime is [tailscale.com/net/udprelay/endpoint.ServerEndpoint.SteadyStateLifetime]
+ // SteadyStateLifetime is [github.com/metacubex/tailscale/net/udprelay/endpoint.ServerEndpoint.SteadyStateLifetime]
SteadyStateLifetime time.Duration
- // AddrPorts is [tailscale.com/net/udprelay/endpoint.ServerEndpoint.AddrPorts]
+ // AddrPorts is [github.com/metacubex/tailscale/net/udprelay/endpoint.ServerEndpoint.AddrPorts]
AddrPorts []netip.AddrPort
}
@@ -564,7 +564,7 @@ func (m *UDPRelayEndpoint) encode(b []byte) {
disco := m.ServerDisco.AppendTo(nil)
copy(b, disco)
b = b[key.DiscoPublicRawLen:]
- for i := range len(m.ClientDisco) {
+ for i := 0; i < len(m.ClientDisco); i++ {
disco = m.ClientDisco[i].AppendTo(nil)
copy(b, disco)
b = b[key.DiscoPublicRawLen:]
@@ -593,7 +593,7 @@ func (m *UDPRelayEndpoint) decode(b []byte) error {
}
m.ServerDisco = key.DiscoPublicFromRaw32(mem.B(b[:key.DiscoPublicRawLen]))
b = b[key.DiscoPublicRawLen:]
- for i := range len(m.ClientDisco) {
+ for i := 0; i < len(m.ClientDisco); i++ {
m.ClientDisco[i] = key.DiscoPublicFromRaw32(mem.B(b[:key.DiscoPublicRawLen]))
b = b[key.DiscoPublicRawLen:]
}
@@ -620,13 +620,13 @@ func (m *UDPRelayEndpoint) decode(b []byte) error {
// CallMeMaybeVia is a message sent only over DERP to request that the recipient
// try to open up a magicsock path back to the sender. The 'Via' in
// CallMeMaybeVia highlights that candidate paths are served through an
-// intermediate relay, likely a [tailscale.com/net/udprelay.Server].
+// intermediate relay, likely a [github.com/metacubex/tailscale/net/udprelay.Server].
//
// Usage of the candidate paths in magicsock requires a 3-way handshake
// involving [BindUDPRelayEndpoint], [BindUDPRelayEndpointChallenge], and
// [BindUDPRelayEndpointAnswer].
//
-// CallMeMaybeVia mirrors [tailscale.com/net/udprelay/endpoint.ServerEndpoint],
+// CallMeMaybeVia mirrors [github.com/metacubex/tailscale/net/udprelay/endpoint.ServerEndpoint],
// which contains field documentation.
//
// The recipient may choose to not open a path back if it's already happy with
diff --git a/disco/disco_test.go b/disco/disco_test.go
index 07b653ceeb950..6c8f22996e0e1 100644
--- a/disco/disco_test.go
+++ b/disco/disco_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,8 +13,8 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/types/key"
"go4.org/mem"
- "tailscale.com/types/key"
)
func TestMarshalAndParse(t *testing.T) {
diff --git a/disco/pcap.go b/disco/pcap.go
index e4a910163f4aa..0c4242340b350 100644
--- a/disco/pcap.go
+++ b/disco/pcap.go
@@ -8,8 +8,8 @@ import (
"encoding/binary"
"net/netip"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
)
// ToPCAPFrame marshals the bytes for a pcap record that describe a disco frame.
diff --git a/doctor/doctor.go b/doctor/doctor.go
index 437df5e756dea..b96956a24a2c3 100644
--- a/doctor/doctor.go
+++ b/doctor/doctor.go
@@ -9,7 +9,7 @@ import (
"context"
"sync"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
// Check is the interface defining a singular check.
diff --git a/doctor/doctor_test.go b/doctor/doctor_test.go
index cd9d00ae6868e..6bcbd7c4d8159 100644
--- a/doctor/doctor_test.go
+++ b/doctor/doctor_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,7 +12,7 @@ import (
"testing"
qt "github.com/frankban/quicktest"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
func TestRunChecks(t *testing.T) {
diff --git a/doctor/ethtool/ethtool.go b/doctor/ethtool/ethtool.go
index 40f39cc21b49a..ff405035a62d8 100644
--- a/doctor/ethtool/ethtool.go
+++ b/doctor/ethtool/ethtool.go
@@ -8,7 +8,7 @@ package ethtool
import (
"context"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
// Check implements the doctor.Check interface.
diff --git a/doctor/ethtool/ethtool_linux.go b/doctor/ethtool/ethtool_linux.go
index 3914158741724..bd80e5ad00105 100644
--- a/doctor/ethtool/ethtool_linux.go
+++ b/doctor/ethtool/ethtool_linux.go
@@ -9,10 +9,10 @@ import (
"net/netip"
"sort"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/set"
"github.com/safchain/ethtool"
- "tailscale.com/net/netmon"
- "tailscale.com/types/logger"
- "tailscale.com/util/set"
)
func ethtoolImpl(logf logger.Logf) error {
diff --git a/doctor/ethtool/ethtool_other.go b/doctor/ethtool/ethtool_other.go
index 91b5f6fdb9a6f..e36edeae606c2 100644
--- a/doctor/ethtool/ethtool_other.go
+++ b/doctor/ethtool/ethtool_other.go
@@ -8,7 +8,7 @@ package ethtool
import (
"runtime"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
func ethtoolImpl(logf logger.Logf) error {
diff --git a/doctor/permissions/permissions.go b/doctor/permissions/permissions.go
index a98ad1e0826a1..984c0ba3bd53d 100644
--- a/doctor/permissions/permissions.go
+++ b/doctor/permissions/permissions.go
@@ -11,8 +11,8 @@ import (
"os/user"
"strings"
+ "github.com/metacubex/tailscale/types/logger"
"golang.org/x/exp/constraints"
- "tailscale.com/types/logger"
)
// Check implements the doctor.Check interface.
diff --git a/doctor/permissions/permissions_bsd.go b/doctor/permissions/permissions_bsd.go
index c72e4d5d7a65c..6445390f75648 100644
--- a/doctor/permissions/permissions_bsd.go
+++ b/doctor/permissions/permissions_bsd.go
@@ -6,8 +6,8 @@
package permissions
import (
+ "github.com/metacubex/tailscale/types/logger"
"golang.org/x/sys/unix"
- "tailscale.com/types/logger"
)
func permissionsImpl(logf logger.Logf) error {
diff --git a/doctor/permissions/permissions_linux.go b/doctor/permissions/permissions_linux.go
index 8f8f12161e949..d340f3ef63d5b 100644
--- a/doctor/permissions/permissions_linux.go
+++ b/doctor/permissions/permissions_linux.go
@@ -10,8 +10,8 @@ import (
"strings"
"unsafe"
+ "github.com/metacubex/tailscale/types/logger"
"golang.org/x/sys/unix"
- "tailscale.com/types/logger"
)
func permissionsImpl(logf logger.Logf) error {
diff --git a/doctor/permissions/permissions_other.go b/doctor/permissions/permissions_other.go
index e96cf4f16277b..aab5a13f1a76a 100644
--- a/doctor/permissions/permissions_other.go
+++ b/doctor/permissions/permissions_other.go
@@ -8,7 +8,7 @@ package permissions
import (
"runtime"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
func permissionsImpl(logf logger.Logf) error {
diff --git a/doctor/permissions/permissions_test.go b/doctor/permissions/permissions_test.go
index c7a292f39e783..a75d1caca43e5 100644
--- a/doctor/permissions/permissions_test.go
+++ b/doctor/permissions/permissions_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/doctor/routetable/routetable.go b/doctor/routetable/routetable.go
index 1751d37448411..7bcdc92cd0bc2 100644
--- a/doctor/routetable/routetable.go
+++ b/doctor/routetable/routetable.go
@@ -8,8 +8,8 @@ package routetable
import (
"context"
- "tailscale.com/net/routetable"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/net/routetable"
+ "github.com/metacubex/tailscale/types/logger"
)
// MaxRoutes is the maximum number of routes that will be displayed.
diff --git a/drive/drive_clone.go b/drive/drive_clone.go
index 724ebc386273d..07688f33bd6bb 100644
--- a/drive/drive_clone.go
+++ b/drive/drive_clone.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-// Code generated by tailscale.com/cmd/cloner; DO NOT EDIT.
+// Code generated by github.com/metacubex/tailscale/cmd/cloner; DO NOT EDIT.
package drive
diff --git a/drive/drive_view.go b/drive/drive_view.go
index 253a2955b2161..a565a3a4c4ec5 100644
--- a/drive/drive_view.go
+++ b/drive/drive_view.go
@@ -9,12 +9,12 @@ import (
jsonv1 "encoding/json"
"errors"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/types/views"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/types/views"
)
-//go:generate go run tailscale.com/cmd/cloner -clonefunc=true -type=Share
+//go:generate go run github.com/metacubex/tailscale/cmd/cloner -clonefunc=true -type=Share
// View returns a read-only view of Share.
func (p *Share) View() ShareView {
diff --git a/drive/driveimpl/birthtiming_test.go b/drive/driveimpl/birthtiming_test.go
index 2bb1259224ff2..19ae0c2d02e2b 100644
--- a/drive/driveimpl/birthtiming_test.go
+++ b/drive/driveimpl/birthtiming_test.go
@@ -1,10 +1,10 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
// BirthTime is not supported on Linux, so only run the test on windows and Mac.
-//go:build windows || darwin
-
package driveimpl
import (
diff --git a/drive/driveimpl/compositedav/compositedav.go b/drive/driveimpl/compositedav/compositedav.go
index c6ec797726643..c0b3973758c2e 100644
--- a/drive/driveimpl/compositedav/compositedav.go
+++ b/drive/driveimpl/compositedav/compositedav.go
@@ -7,20 +7,20 @@
package compositedav
import (
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
"net/http"
"net/http/httputil"
"net/url"
"path"
- "slices"
"strings"
"sync"
+ "github.com/metacubex/tailscale/drive/driveimpl/dirfs"
+ "github.com/metacubex/tailscale/drive/driveimpl/shared"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/logger"
"github.com/tailscale/xnet/webdav"
- "tailscale.com/drive/driveimpl/dirfs"
- "tailscale.com/drive/driveimpl/shared"
- "tailscale.com/tstime"
- "tailscale.com/types/logger"
)
// Child is a child folder of this compositedav.
diff --git a/drive/driveimpl/compositedav/rewriting.go b/drive/driveimpl/compositedav/rewriting.go
index 1f0a69d75978e..53e6bd5b742ce 100644
--- a/drive/driveimpl/compositedav/rewriting.go
+++ b/drive/driveimpl/compositedav/rewriting.go
@@ -11,7 +11,7 @@ import (
"regexp"
"strings"
- "tailscale.com/drive/driveimpl/shared"
+ "github.com/metacubex/tailscale/drive/driveimpl/shared"
)
var (
diff --git a/drive/driveimpl/compositedav/stat_cache.go b/drive/driveimpl/compositedav/stat_cache.go
index 2e53c82419795..b42c3cfdb3800 100644
--- a/drive/driveimpl/compositedav/stat_cache.go
+++ b/drive/driveimpl/compositedav/stat_cache.go
@@ -13,7 +13,7 @@ import (
"time"
"github.com/jellydator/ttlcache/v3"
- "tailscale.com/drive/driveimpl/shared"
+ "github.com/metacubex/tailscale/drive/driveimpl/shared"
)
var (
diff --git a/drive/driveimpl/compositedav/stat_cache_test.go b/drive/driveimpl/compositedav/stat_cache_test.go
index b982a3aad1d17..da31933add281 100644
--- a/drive/driveimpl/compositedav/stat_cache_test.go
+++ b/drive/driveimpl/compositedav/stat_cache_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -13,7 +15,7 @@ import (
"time"
"github.com/google/go-cmp/cmp"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/tstest"
)
var parentPath = "/parent with spaces"
diff --git a/drive/driveimpl/connlistener_test.go b/drive/driveimpl/connlistener_test.go
index 972791c6e530e..5b37c3423dd3a 100644
--- a/drive/driveimpl/connlistener_test.go
+++ b/drive/driveimpl/connlistener_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/drive/driveimpl/dirfs/dirfs.go b/drive/driveimpl/dirfs/dirfs.go
index 3c4297264302d..98efd73069af9 100644
--- a/drive/driveimpl/dirfs/dirfs.go
+++ b/drive/driveimpl/dirfs/dirfs.go
@@ -6,12 +6,12 @@
package dirfs
import (
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
"time"
- "tailscale.com/drive/driveimpl/shared"
- "tailscale.com/tstime"
+ "github.com/metacubex/tailscale/drive/driveimpl/shared"
+ "github.com/metacubex/tailscale/tstime"
)
// Child is subdirectory of an FS.
diff --git a/drive/driveimpl/dirfs/dirfs_test.go b/drive/driveimpl/dirfs/dirfs_test.go
index 559160716bdba..656cf1492dda0 100644
--- a/drive/driveimpl/dirfs/dirfs_test.go
+++ b/drive/driveimpl/dirfs/dirfs_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -14,9 +16,9 @@ import (
"time"
"github.com/google/go-cmp/cmp"
+ "github.com/metacubex/tailscale/drive/driveimpl/shared"
+ "github.com/metacubex/tailscale/tstest"
"github.com/tailscale/xnet/webdav"
- "tailscale.com/drive/driveimpl/shared"
- "tailscale.com/tstest"
)
func TestStat(t *testing.T) {
diff --git a/drive/driveimpl/dirfs/mkdir.go b/drive/driveimpl/dirfs/mkdir.go
index 6ed3ec27ea332..4ea43e646e96b 100644
--- a/drive/driveimpl/dirfs/mkdir.go
+++ b/drive/driveimpl/dirfs/mkdir.go
@@ -7,7 +7,7 @@ import (
"context"
"os"
- "tailscale.com/drive/driveimpl/shared"
+ "github.com/metacubex/tailscale/drive/driveimpl/shared"
)
// Mkdir implements webdav.FileSystem. All attempts to Mkdir a directory that
diff --git a/drive/driveimpl/dirfs/openfile.go b/drive/driveimpl/dirfs/openfile.go
index 71b55ab206e24..166aeb431c1ee 100644
--- a/drive/driveimpl/dirfs/openfile.go
+++ b/drive/driveimpl/dirfs/openfile.go
@@ -8,8 +8,8 @@ import (
"io/fs"
"os"
+ "github.com/metacubex/tailscale/drive/driveimpl/shared"
"github.com/tailscale/xnet/webdav"
- "tailscale.com/drive/driveimpl/shared"
)
// OpenFile implements interface webdav.Filesystem.
diff --git a/drive/driveimpl/dirfs/stat.go b/drive/driveimpl/dirfs/stat.go
index dd0aa976afb8e..6a8d704c47dfe 100644
--- a/drive/driveimpl/dirfs/stat.go
+++ b/drive/driveimpl/dirfs/stat.go
@@ -8,7 +8,7 @@ import (
"io/fs"
"os"
- "tailscale.com/drive/driveimpl/shared"
+ "github.com/metacubex/tailscale/drive/driveimpl/shared"
)
// Stat implements webdav.FileSystem.
diff --git a/drive/driveimpl/drive_test.go b/drive/driveimpl/drive_test.go
index 185ae2a9c2118..41dd4f6060cc0 100644
--- a/drive/driveimpl/drive_test.go
+++ b/drive/driveimpl/drive_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,6 +7,7 @@ package driveimpl
import (
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"io/fs"
"log"
@@ -16,17 +19,16 @@ import (
"path/filepath"
"regexp"
"runtime"
- "slices"
"strings"
"sync"
"testing"
"time"
"github.com/google/go-cmp/cmp"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/drive/driveimpl/shared"
+ "github.com/metacubex/tailscale/tstest"
"github.com/studio-b12/gowebdav"
- "tailscale.com/drive"
- "tailscale.com/drive/driveimpl/shared"
- "tailscale.com/tstest"
)
const (
diff --git a/drive/driveimpl/fileserver.go b/drive/driveimpl/fileserver.go
index 6aedfef2ce522..00052293370a4 100644
--- a/drive/driveimpl/fileserver.go
+++ b/drive/driveimpl/fileserver.go
@@ -12,8 +12,8 @@ import (
"net/http"
"sync"
+ "github.com/metacubex/tailscale/drive/driveimpl/shared"
"github.com/tailscale/xnet/webdav"
- "tailscale.com/drive/driveimpl/shared"
)
// FileServer is a standalone WebDAV server that dynamically serves up shares.
diff --git a/drive/driveimpl/local_impl.go b/drive/driveimpl/local_impl.go
index ab908c0d31d9c..c4b4459842134 100644
--- a/drive/driveimpl/local_impl.go
+++ b/drive/driveimpl/local_impl.go
@@ -10,10 +10,10 @@ import (
"net/http"
"time"
- "tailscale.com/drive"
- "tailscale.com/drive/driveimpl/compositedav"
- "tailscale.com/drive/driveimpl/dirfs"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/drive/driveimpl/compositedav"
+ "github.com/metacubex/tailscale/drive/driveimpl/dirfs"
+ "github.com/metacubex/tailscale/types/logger"
)
const (
diff --git a/drive/driveimpl/remote_impl.go b/drive/driveimpl/remote_impl.go
index 0ff27dc643efe..b62e813c67f46 100644
--- a/drive/driveimpl/remote_impl.go
+++ b/drive/driveimpl/remote_impl.go
@@ -8,6 +8,7 @@ import (
"context"
"encoding/hex"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
"math"
"net"
@@ -17,18 +18,17 @@ import (
"os"
"os/exec"
"os/user"
- "slices"
"strings"
"sync"
"time"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/drive/driveimpl/compositedav"
+ "github.com/metacubex/tailscale/drive/driveimpl/dirfs"
+ "github.com/metacubex/tailscale/drive/driveimpl/shared"
+ "github.com/metacubex/tailscale/safesocket"
+ "github.com/metacubex/tailscale/types/logger"
"github.com/tailscale/xnet/webdav"
- "tailscale.com/drive"
- "tailscale.com/drive/driveimpl/compositedav"
- "tailscale.com/drive/driveimpl/dirfs"
- "tailscale.com/drive/driveimpl/shared"
- "tailscale.com/safesocket"
- "tailscale.com/types/logger"
)
func NewFileSystemForRemote(logf logger.Logf) *FileSystemForRemote {
diff --git a/drive/driveimpl/shared/pathutil_test.go b/drive/driveimpl/shared/pathutil_test.go
index b938f4c1c153f..ea8c65439c16a 100644
--- a/drive/driveimpl/shared/pathutil_test.go
+++ b/drive/driveimpl/shared/pathutil_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/drive/remote.go b/drive/remote.go
index 5f34d0023e6f7..599871b31c1dc 100644
--- a/drive/remote.go
+++ b/drive/remote.go
@@ -3,7 +3,7 @@
package drive
-//go:generate go run tailscale.com/cmd/viewer --type=Share --clonefunc
+//go:generate go run github.com/metacubex/tailscale/cmd/viewer --type=Share --clonefunc
import (
"bytes"
diff --git a/drive/remote_permissions_test.go b/drive/remote_permissions_test.go
index 5d63a503f75d9..480d82234d9ff 100644
--- a/drive/remote_permissions_test.go
+++ b/drive/remote_permissions_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/drive/remote_test.go b/drive/remote_test.go
index c0de1723aee59..4bf6c6ac01f12 100644
--- a/drive/remote_test.go
+++ b/drive/remote_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/drive/remote_unix.go b/drive/remote_unix.go
index 4b367ef5ff79a..2676a91c14cc1 100644
--- a/drive/remote_unix.go
+++ b/drive/remote_unix.go
@@ -5,7 +5,7 @@
package drive
-import "tailscale.com/version"
+import "github.com/metacubex/tailscale/version"
func doAllowShareAs() bool {
// All UNIX platforms use user servers (sub-processes) to access the OS
diff --git a/envknob/envknob.go b/envknob/envknob.go
index 73a0da7005041..68481e0e46863 100644
--- a/envknob/envknob.go
+++ b/envknob/envknob.go
@@ -19,24 +19,24 @@ import (
"bufio"
"errors"
"fmt"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
- "maps"
"os"
"path/filepath"
"runtime"
- "slices"
"strconv"
"strings"
"sync/atomic"
"time"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/syncs"
- "tailscale.com/types/opt"
- "tailscale.com/version"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/version"
+ "github.com/metacubex/tailscale/version/distro"
)
var (
diff --git a/envknob/featureknob/featureknob.go b/envknob/featureknob/featureknob.go
index 049366549fcb3..45bef3ab1785c 100644
--- a/envknob/featureknob/featureknob.go
+++ b/envknob/featureknob/featureknob.go
@@ -9,9 +9,9 @@ import (
"errors"
"runtime"
- "tailscale.com/envknob"
- "tailscale.com/version"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/version"
+ "github.com/metacubex/tailscale/version/distro"
)
// CanRunTailscaleSSH reports whether serving a Tailscale SSH server is
diff --git a/feature/ace/ace.go b/feature/ace/ace.go
index b99516657ed25..29dbe846a4f7d 100644
--- a/feature/ace/ace.go
+++ b/feature/ace/ace.go
@@ -7,9 +7,9 @@ package ace
import (
"net/netip"
- "tailscale.com/control/controlhttp"
- "tailscale.com/net/ace"
- "tailscale.com/net/netx"
+ "github.com/metacubex/tailscale/control/controlhttp"
+ "github.com/metacubex/tailscale/net/ace"
+ "github.com/metacubex/tailscale/net/netx"
)
func init() {
diff --git a/feature/appconnectors/appconnectors.go b/feature/appconnectors/appconnectors.go
index 82d29ce0e6034..3a2e3d664a70e 100644
--- a/feature/appconnectors/appconnectors.go
+++ b/feature/appconnectors/appconnectors.go
@@ -8,8 +8,8 @@ import (
"encoding/json"
"net/http"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/tailcfg"
)
func init() {
diff --git a/feature/awsparamstore/awsparamstore.go b/feature/awsparamstore/awsparamstore.go
index f63f546ed70ed..a8143509b36c8 100644
--- a/feature/awsparamstore/awsparamstore.go
+++ b/feature/awsparamstore/awsparamstore.go
@@ -16,8 +16,8 @@ import (
"github.com/aws/aws-sdk-go-v2/aws/arn"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/ssm"
- "tailscale.com/feature"
- "tailscale.com/internal/client/tailscale"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/internal/client/tailscale"
)
func init() {
diff --git a/feature/awsparamstore/awsparamstore_test.go b/feature/awsparamstore/awsparamstore_test.go
index 9ccea63ec11e1..49afc3bd35c5d 100644
--- a/feature/awsparamstore/awsparamstore_test.go
+++ b/feature/awsparamstore/awsparamstore_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_aws
-
package awsparamstore
import (
diff --git a/feature/buildfeatures/feature_clientmetrics_disabled.go b/feature/buildfeatures/feature_clientmetrics_disabled.go
index 0345ccc609fdf..61dff7935ffdb 100644
--- a/feature/buildfeatures/feature_clientmetrics_disabled.go
+++ b/feature/buildfeatures/feature_clientmetrics_disabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build ts_omit_clientmetrics
+//go:build !ts_enable_clientmetrics
package buildfeatures
// HasClientMetrics is whether the binary was built with support for modular feature "Client metrics support".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_clientmetrics" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_clientmetrics" build tag.
// It's a const so it can be used for dead code elimination.
const HasClientMetrics = false
diff --git a/feature/buildfeatures/feature_clientmetrics_enabled.go b/feature/buildfeatures/feature_clientmetrics_enabled.go
index 2e58155bd5261..018df69ed90bb 100644
--- a/feature/buildfeatures/feature_clientmetrics_enabled.go
+++ b/feature/buildfeatures/feature_clientmetrics_enabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build !ts_omit_clientmetrics
+//go:build ts_enable_clientmetrics
package buildfeatures
// HasClientMetrics is whether the binary was built with support for modular feature "Client metrics support".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_clientmetrics" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_clientmetrics" build tag.
// It's a const so it can be used for dead code elimination.
const HasClientMetrics = true
diff --git a/feature/buildfeatures/feature_dbus_disabled.go b/feature/buildfeatures/feature_dbus_disabled.go
index c09fa7eeb7a34..fc2dff5bf529d 100644
--- a/feature/buildfeatures/feature_dbus_disabled.go
+++ b/feature/buildfeatures/feature_dbus_disabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build ts_omit_dbus
+//go:build !ts_enable_dbus
package buildfeatures
// HasDBus is whether the binary was built with support for modular feature "Linux DBus support".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_dbus" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_dbus" build tag.
// It's a const so it can be used for dead code elimination.
const HasDBus = false
diff --git a/feature/buildfeatures/feature_dbus_enabled.go b/feature/buildfeatures/feature_dbus_enabled.go
index f3cc9f003f0ab..1bf713759961a 100644
--- a/feature/buildfeatures/feature_dbus_enabled.go
+++ b/feature/buildfeatures/feature_dbus_enabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build !ts_omit_dbus
+//go:build ts_enable_dbus
package buildfeatures
// HasDBus is whether the binary was built with support for modular feature "Linux DBus support".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_dbus" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_dbus" build tag.
// It's a const so it can be used for dead code elimination.
const HasDBus = true
diff --git a/feature/buildfeatures/feature_debug_disabled.go b/feature/buildfeatures/feature_debug_disabled.go
index 4faafbb756559..86b991b882210 100644
--- a/feature/buildfeatures/feature_debug_disabled.go
+++ b/feature/buildfeatures/feature_debug_disabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build ts_omit_debug
+//go:build !ts_enable_debug
package buildfeatures
// HasDebug is whether the binary was built with support for modular feature "various debug support, for things that don't have or need their own more specific feature".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_debug" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_debug" build tag.
// It's a const so it can be used for dead code elimination.
const HasDebug = false
diff --git a/feature/buildfeatures/feature_debug_enabled.go b/feature/buildfeatures/feature_debug_enabled.go
index a99dc81044cea..d74cc11967660 100644
--- a/feature/buildfeatures/feature_debug_enabled.go
+++ b/feature/buildfeatures/feature_debug_enabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build !ts_omit_debug
+//go:build ts_enable_debug
package buildfeatures
// HasDebug is whether the binary was built with support for modular feature "various debug support, for things that don't have or need their own more specific feature".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_debug" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_debug" build tag.
// It's a const so it can be used for dead code elimination.
const HasDebug = true
diff --git a/feature/buildfeatures/feature_debugeventbus_disabled.go b/feature/buildfeatures/feature_debugeventbus_disabled.go
index a7cf3dd72e8c6..c7e6a1371ef3a 100644
--- a/feature/buildfeatures/feature_debugeventbus_disabled.go
+++ b/feature/buildfeatures/feature_debugeventbus_disabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build ts_omit_debugeventbus
+//go:build !ts_enable_debugeventbus
package buildfeatures
// HasDebugEventBus is whether the binary was built with support for modular feature "eventbus debug support".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_debugeventbus" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_debugeventbus" build tag.
// It's a const so it can be used for dead code elimination.
const HasDebugEventBus = false
diff --git a/feature/buildfeatures/feature_debugeventbus_enabled.go b/feature/buildfeatures/feature_debugeventbus_enabled.go
index caa4ca30a5039..249db73319363 100644
--- a/feature/buildfeatures/feature_debugeventbus_enabled.go
+++ b/feature/buildfeatures/feature_debugeventbus_enabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build !ts_omit_debugeventbus
+//go:build ts_enable_debugeventbus
package buildfeatures
// HasDebugEventBus is whether the binary was built with support for modular feature "eventbus debug support".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_debugeventbus" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_debugeventbus" build tag.
// It's a const so it can be used for dead code elimination.
const HasDebugEventBus = true
diff --git a/feature/buildfeatures/feature_logtail_disabled.go b/feature/buildfeatures/feature_logtail_disabled.go
index 983055d4742a9..382c128771412 100644
--- a/feature/buildfeatures/feature_logtail_disabled.go
+++ b/feature/buildfeatures/feature_logtail_disabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build ts_omit_logtail
+//go:build !ts_enable_logtail
package buildfeatures
// HasLogTail is whether the binary was built with support for modular feature "upload logs to log.tailscale.com (debug logs for bug reports and also by network flow logs if enabled)".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_logtail" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_logtail" build tag.
// It's a const so it can be used for dead code elimination.
const HasLogTail = false
diff --git a/feature/buildfeatures/feature_logtail_enabled.go b/feature/buildfeatures/feature_logtail_enabled.go
index f9ce154028832..f2a070f19fb1e 100644
--- a/feature/buildfeatures/feature_logtail_enabled.go
+++ b/feature/buildfeatures/feature_logtail_enabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build !ts_omit_logtail
+//go:build ts_enable_logtail
package buildfeatures
// HasLogTail is whether the binary was built with support for modular feature "upload logs to log.tailscale.com (debug logs for bug reports and also by network flow logs if enabled)".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_logtail" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_logtail" build tag.
// It's a const so it can be used for dead code elimination.
const HasLogTail = true
diff --git a/feature/buildfeatures/feature_networkmanager_disabled.go b/feature/buildfeatures/feature_networkmanager_disabled.go
index 9ac3a928b62e0..9424a7276c99f 100644
--- a/feature/buildfeatures/feature_networkmanager_disabled.go
+++ b/feature/buildfeatures/feature_networkmanager_disabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build ts_omit_networkmanager
+//go:build !ts_enable_networkmanager
package buildfeatures
// HasNetworkManager is whether the binary was built with support for modular feature "Linux NetworkManager integration".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_networkmanager" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_networkmanager" build tag.
// It's a const so it can be used for dead code elimination.
const HasNetworkManager = false
diff --git a/feature/buildfeatures/feature_networkmanager_enabled.go b/feature/buildfeatures/feature_networkmanager_enabled.go
index 5dd0431e3a892..a44593b89917c 100644
--- a/feature/buildfeatures/feature_networkmanager_enabled.go
+++ b/feature/buildfeatures/feature_networkmanager_enabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build !ts_omit_networkmanager
+//go:build ts_enable_networkmanager
package buildfeatures
// HasNetworkManager is whether the binary was built with support for modular feature "Linux NetworkManager integration".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_networkmanager" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_networkmanager" build tag.
// It's a const so it can be used for dead code elimination.
const HasNetworkManager = true
diff --git a/feature/buildfeatures/feature_resolved_disabled.go b/feature/buildfeatures/feature_resolved_disabled.go
index e19576e2a9131..618a034ed9548 100644
--- a/feature/buildfeatures/feature_resolved_disabled.go
+++ b/feature/buildfeatures/feature_resolved_disabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build ts_omit_resolved
+//go:build !ts_enable_resolved
package buildfeatures
// HasResolved is whether the binary was built with support for modular feature "Linux systemd-resolved integration".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_resolved" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_resolved" build tag.
// It's a const so it can be used for dead code elimination.
const HasResolved = false
diff --git a/feature/buildfeatures/feature_resolved_enabled.go b/feature/buildfeatures/feature_resolved_enabled.go
index 46e59411784fb..0826658cf4c23 100644
--- a/feature/buildfeatures/feature_resolved_enabled.go
+++ b/feature/buildfeatures/feature_resolved_enabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build !ts_omit_resolved
+//go:build ts_enable_resolved
package buildfeatures
// HasResolved is whether the binary was built with support for modular feature "Linux systemd-resolved integration".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_resolved" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_resolved" build tag.
// It's a const so it can be used for dead code elimination.
const HasResolved = true
diff --git a/feature/buildfeatures/feature_syspolicy_disabled.go b/feature/buildfeatures/feature_syspolicy_disabled.go
index e7b2b3dad1889..0b8496ec4be00 100644
--- a/feature/buildfeatures/feature_syspolicy_disabled.go
+++ b/feature/buildfeatures/feature_syspolicy_disabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build ts_omit_syspolicy
+//go:build !ts_enable_syspolicy
package buildfeatures
// HasSystemPolicy is whether the binary was built with support for modular feature "System policy configuration (MDM) support".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_syspolicy" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_syspolicy" build tag.
// It's a const so it can be used for dead code elimination.
const HasSystemPolicy = false
diff --git a/feature/buildfeatures/feature_syspolicy_enabled.go b/feature/buildfeatures/feature_syspolicy_enabled.go
index 5c3b2794adc1a..f3bf00c8bf96a 100644
--- a/feature/buildfeatures/feature_syspolicy_enabled.go
+++ b/feature/buildfeatures/feature_syspolicy_enabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build !ts_omit_syspolicy
+//go:build ts_enable_syspolicy
package buildfeatures
// HasSystemPolicy is whether the binary was built with support for modular feature "System policy configuration (MDM) support".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_syspolicy" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_syspolicy" build tag.
// It's a const so it can be used for dead code elimination.
const HasSystemPolicy = true
diff --git a/feature/buildfeatures/feature_useproxy_disabled.go b/feature/buildfeatures/feature_useproxy_disabled.go
index 604825ba991ca..e5efc96ac6885 100644
--- a/feature/buildfeatures/feature_useproxy_disabled.go
+++ b/feature/buildfeatures/feature_useproxy_disabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build ts_omit_useproxy
+//go:build !ts_enable_useproxy
package buildfeatures
// HasUseProxy is whether the binary was built with support for modular feature "Support using system proxies as specified by env vars or the system configuration to reach Tailscale servers.".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_useproxy" build tag.
+// Specifically, it's whether the binary was NOT built with the "ts_enable_useproxy" build tag.
// It's a const so it can be used for dead code elimination.
const HasUseProxy = false
diff --git a/feature/buildfeatures/feature_useproxy_enabled.go b/feature/buildfeatures/feature_useproxy_enabled.go
index fe2ecc9ea538a..fd422875be13a 100644
--- a/feature/buildfeatures/feature_useproxy_enabled.go
+++ b/feature/buildfeatures/feature_useproxy_enabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build !ts_omit_useproxy
+//go:build ts_enable_useproxy
package buildfeatures
// HasUseProxy is whether the binary was built with support for modular feature "Support using system proxies as specified by env vars or the system configuration to reach Tailscale servers.".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_useproxy" build tag.
+// Specifically, it's whether the binary was NOT built with the "ts_enable_useproxy" build tag.
// It's a const so it can be used for dead code elimination.
const HasUseProxy = true
diff --git a/feature/buildfeatures/feature_usermetrics_disabled.go b/feature/buildfeatures/feature_usermetrics_disabled.go
index 96441b5138497..63c923426b3e8 100644
--- a/feature/buildfeatures/feature_usermetrics_disabled.go
+++ b/feature/buildfeatures/feature_usermetrics_disabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build ts_omit_usermetrics
+//go:build !ts_enable_usermetrics
package buildfeatures
// HasUserMetrics is whether the binary was built with support for modular feature "Usermetrics (documented, stable) metrics support".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_usermetrics" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_usermetrics" build tag.
// It's a const so it can be used for dead code elimination.
const HasUserMetrics = false
diff --git a/feature/buildfeatures/feature_usermetrics_enabled.go b/feature/buildfeatures/feature_usermetrics_enabled.go
index 427c6fd397657..d3bec81911804 100644
--- a/feature/buildfeatures/feature_usermetrics_enabled.go
+++ b/feature/buildfeatures/feature_usermetrics_enabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build !ts_omit_usermetrics
+//go:build ts_enable_usermetrics
package buildfeatures
// HasUserMetrics is whether the binary was built with support for modular feature "Usermetrics (documented, stable) metrics support".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_usermetrics" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_usermetrics" build tag.
// It's a const so it can be used for dead code elimination.
const HasUserMetrics = true
diff --git a/feature/buildfeatures/feature_webclient_disabled.go b/feature/buildfeatures/feature_webclient_disabled.go
index 9792265c6d559..f66aede264645 100644
--- a/feature/buildfeatures/feature_webclient_disabled.go
+++ b/feature/buildfeatures/feature_webclient_disabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build ts_omit_webclient
+//go:build !ts_enable_webclient
package buildfeatures
// HasWebClient is whether the binary was built with support for modular feature "Web client support".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_webclient" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_webclient" build tag.
// It's a const so it can be used for dead code elimination.
const HasWebClient = false
diff --git a/feature/buildfeatures/feature_webclient_enabled.go b/feature/buildfeatures/feature_webclient_enabled.go
index cb558a5fe7831..f94e322900185 100644
--- a/feature/buildfeatures/feature_webclient_enabled.go
+++ b/feature/buildfeatures/feature_webclient_enabled.go
@@ -3,11 +3,11 @@
// Code generated by gen.go; DO NOT EDIT.
-//go:build !ts_omit_webclient
+//go:build ts_enable_webclient
package buildfeatures
// HasWebClient is whether the binary was built with support for modular feature "Web client support".
-// Specifically, it's whether the binary was NOT built with the "ts_omit_webclient" build tag.
+// Specifically, it's whether the binary was built with the "ts_enable_webclient" build tag.
// It's a const so it can be used for dead code elimination.
const HasWebClient = true
diff --git a/feature/buildfeatures/gen.go b/feature/buildfeatures/gen.go
index cf8e9d49f1f47..cec0774f2be53 100644
--- a/feature/buildfeatures/gen.go
+++ b/feature/buildfeatures/gen.go
@@ -8,13 +8,13 @@
package main
import (
- "cmp"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"os"
"strings"
- "tailscale.com/feature/featuretags"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/feature/featuretags"
+ "github.com/metacubex/tailscale/util/must"
)
const header = `// Copyright (c) Tailscale Inc & contributors
diff --git a/feature/c2n/c2n.go b/feature/c2n/c2n.go
index 331a9af955a07..2ad06532819a9 100644
--- a/feature/c2n/c2n.go
+++ b/feature/c2n/c2n.go
@@ -11,10 +11,10 @@ import (
"net/http"
"time"
- "tailscale.com/control/controlclient"
- "tailscale.com/tailcfg"
- "tailscale.com/tempfork/httprec"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/control/controlclient"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tempfork/httprec"
+ "github.com/metacubex/tailscale/types/logger"
)
func init() {
diff --git a/feature/capture/capture.go b/feature/capture/capture.go
index d7145e7c1ebd7..f604053bb6437 100644
--- a/feature/capture/capture.go
+++ b/feature/capture/capture.go
@@ -13,10 +13,10 @@ import (
"sync"
"time"
- "tailscale.com/feature"
- "tailscale.com/ipn/localapi"
- "tailscale.com/net/packet"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/ipn/localapi"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/util/set"
)
func init() {
diff --git a/feature/clientupdate/clientupdate.go b/feature/clientupdate/clientupdate.go
index 999dd79200de0..60a1023aed7fb 100644
--- a/feature/clientupdate/clientupdate.go
+++ b/feature/clientupdate/clientupdate.go
@@ -20,19 +20,19 @@ import (
"sync"
"time"
- "tailscale.com/clientupdate"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnext"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/ipn/localapi"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
- "tailscale.com/util/httpm"
- "tailscale.com/version"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/clientupdate"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnext"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/ipn/localapi"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/httpm"
+ "github.com/metacubex/tailscale/version"
+ "github.com/metacubex/tailscale/version/distro"
)
func init() {
diff --git a/feature/condlite/expvar/expvar.go b/feature/condlite/expvar/expvar.go
index 68aaf6e2cddf9..9bd22dbf021e5 100644
--- a/feature/condlite/expvar/expvar.go
+++ b/feature/condlite/expvar/expvar.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !(ts_omit_debug && ts_omit_clientmetrics && ts_omit_usermetrics)
+//go:build ts_enable_debug || ts_enable_clientmetrics || ts_enable_usermetrics
// Package expvar contains type aliases for expvar types, to allow conditionally
// excluding the package from builds.
diff --git a/feature/condlite/expvar/omit.go b/feature/condlite/expvar/omit.go
index 188de2af2436f..eb0f960e0219b 100644
--- a/feature/condlite/expvar/omit.go
+++ b/feature/condlite/expvar/omit.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build ts_omit_debug && ts_omit_clientmetrics && ts_omit_usermetrics
+//go:build !ts_enable_debug && !ts_enable_clientmetrics && !ts_enable_usermetrics
package expvar
diff --git a/feature/condregister/awsparamstore/maybe_awsparamstore.go b/feature/condregister/awsparamstore/maybe_awsparamstore.go
index 78c3f31006765..5c7559b028bf4 100644
--- a/feature/condregister/awsparamstore/maybe_awsparamstore.go
+++ b/feature/condregister/awsparamstore/maybe_awsparamstore.go
@@ -5,4 +5,4 @@
package awsparamstore
-import _ "tailscale.com/feature/awsparamstore"
+import _ "github.com/metacubex/tailscale/feature/awsparamstore"
diff --git a/feature/condregister/condregister.go b/feature/condregister/condregister.go
index e0d72b7ac293c..caf53b9a67abd 100644
--- a/feature/condregister/condregister.go
+++ b/feature/condregister/condregister.go
@@ -10,9 +10,9 @@ import (
// Portmapper is special in that the CLI also needs to link it in,
// so it's pulled out into its own package, rather than using a maybe_*.go
// file in condregister.
- _ "tailscale.com/feature/condregister/portmapper"
+ _ "github.com/metacubex/tailscale/feature/condregister/portmapper"
// HTTP proxy support is also needed by the CLI, and tsnet, so it's its
// own package too.
- _ "tailscale.com/feature/condregister/useproxy"
+ _ "github.com/metacubex/tailscale/feature/condregister/useproxy"
)
diff --git a/feature/condregister/identityfederation/maybe_identityfederation.go b/feature/condregister/identityfederation/maybe_identityfederation.go
index 04c37e36faa47..3fe4248ac99f7 100644
--- a/feature/condregister/identityfederation/maybe_identityfederation.go
+++ b/feature/condregister/identityfederation/maybe_identityfederation.go
@@ -5,4 +5,4 @@
package identityfederation
-import _ "tailscale.com/feature/identityfederation"
+import _ "github.com/metacubex/tailscale/feature/identityfederation"
diff --git a/feature/condregister/maybe_ace.go b/feature/condregister/maybe_ace.go
index a926f5b0d8810..486b67aaef27d 100644
--- a/feature/condregister/maybe_ace.go
+++ b/feature/condregister/maybe_ace.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/ace"
+import _ "github.com/metacubex/tailscale/feature/ace"
diff --git a/feature/condregister/maybe_appconnectors.go b/feature/condregister/maybe_appconnectors.go
index 3b872bc1eb90d..c95e0747deeaa 100644
--- a/feature/condregister/maybe_appconnectors.go
+++ b/feature/condregister/maybe_appconnectors.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/appconnectors"
+import _ "github.com/metacubex/tailscale/feature/appconnectors"
diff --git a/feature/condregister/maybe_c2n.go b/feature/condregister/maybe_c2n.go
index 99258956ad8b2..c3f663f4834d0 100644
--- a/feature/condregister/maybe_c2n.go
+++ b/feature/condregister/maybe_c2n.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/c2n"
+import _ "github.com/metacubex/tailscale/feature/c2n"
diff --git a/feature/condregister/maybe_capture.go b/feature/condregister/maybe_capture.go
index 991843cb58194..38ac00045e7b5 100644
--- a/feature/condregister/maybe_capture.go
+++ b/feature/condregister/maybe_capture.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/capture"
+import _ "github.com/metacubex/tailscale/feature/capture"
diff --git a/feature/condregister/maybe_clientupdate.go b/feature/condregister/maybe_clientupdate.go
index df36d8e67b92e..195500947e180 100644
--- a/feature/condregister/maybe_clientupdate.go
+++ b/feature/condregister/maybe_clientupdate.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/clientupdate"
+import _ "github.com/metacubex/tailscale/feature/clientupdate"
diff --git a/feature/condregister/maybe_conn25.go b/feature/condregister/maybe_conn25.go
index 6ce14b2b3f1ce..7d58a3690c19e 100644
--- a/feature/condregister/maybe_conn25.go
+++ b/feature/condregister/maybe_conn25.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/conn25"
+import _ "github.com/metacubex/tailscale/feature/conn25"
diff --git a/feature/condregister/maybe_debugportmapper.go b/feature/condregister/maybe_debugportmapper.go
index 443b21e02d331..46efd89c2acb7 100644
--- a/feature/condregister/maybe_debugportmapper.go
+++ b/feature/condregister/maybe_debugportmapper.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/debugportmapper"
+import _ "github.com/metacubex/tailscale/feature/debugportmapper"
diff --git a/feature/condregister/maybe_desktop_sessions.go b/feature/condregister/maybe_desktop_sessions.go
index bb93a8bcbff7c..2fc2d85605dc3 100644
--- a/feature/condregister/maybe_desktop_sessions.go
+++ b/feature/condregister/maybe_desktop_sessions.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/ipn/desktop"
+import _ "github.com/metacubex/tailscale/ipn/desktop"
diff --git a/feature/condregister/maybe_doctor.go b/feature/condregister/maybe_doctor.go
index 41d504c5394df..e2640169984e7 100644
--- a/feature/condregister/maybe_doctor.go
+++ b/feature/condregister/maybe_doctor.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/doctor"
+import _ "github.com/metacubex/tailscale/feature/doctor"
diff --git a/feature/condregister/maybe_drive.go b/feature/condregister/maybe_drive.go
index 4d979e821852b..5f9683a8c247d 100644
--- a/feature/condregister/maybe_drive.go
+++ b/feature/condregister/maybe_drive.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/drive"
+import _ "github.com/metacubex/tailscale/feature/drive"
diff --git a/feature/condregister/maybe_linkspeed.go b/feature/condregister/maybe_linkspeed.go
index 5e9e9e4004b19..b5fdbb128ca23 100644
--- a/feature/condregister/maybe_linkspeed.go
+++ b/feature/condregister/maybe_linkspeed.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/linkspeed"
+import _ "github.com/metacubex/tailscale/feature/linkspeed"
diff --git a/feature/condregister/maybe_linuxdnsfight.go b/feature/condregister/maybe_linuxdnsfight.go
index 2866fd0d7a891..fb54f6f6a3316 100644
--- a/feature/condregister/maybe_linuxdnsfight.go
+++ b/feature/condregister/maybe_linuxdnsfight.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/linuxdnsfight"
+import _ "github.com/metacubex/tailscale/feature/linuxdnsfight"
diff --git a/feature/condregister/maybe_osrouter.go b/feature/condregister/maybe_osrouter.go
index 771a86e48bfbf..e021ee6209efe 100644
--- a/feature/condregister/maybe_osrouter.go
+++ b/feature/condregister/maybe_osrouter.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/wgengine/router/osrouter"
+import _ "github.com/metacubex/tailscale/wgengine/router/osrouter"
diff --git a/feature/condregister/maybe_portlist.go b/feature/condregister/maybe_portlist.go
index 8de98d528ae48..5cfb4842d2758 100644
--- a/feature/condregister/maybe_portlist.go
+++ b/feature/condregister/maybe_portlist.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/portlist"
+import _ "github.com/metacubex/tailscale/feature/portlist"
diff --git a/feature/condregister/maybe_posture.go b/feature/condregister/maybe_posture.go
index ca056eb3612b8..9160b8c27665c 100644
--- a/feature/condregister/maybe_posture.go
+++ b/feature/condregister/maybe_posture.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/posture"
+import _ "github.com/metacubex/tailscale/feature/posture"
diff --git a/feature/condregister/maybe_relayserver.go b/feature/condregister/maybe_relayserver.go
index 49404bef8a08b..fe430b4bf7c52 100644
--- a/feature/condregister/maybe_relayserver.go
+++ b/feature/condregister/maybe_relayserver.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/relayserver"
+import _ "github.com/metacubex/tailscale/feature/relayserver"
diff --git a/feature/condregister/maybe_sdnotify.go b/feature/condregister/maybe_sdnotify.go
index ac8e180cd791f..468ff1648f97b 100644
--- a/feature/condregister/maybe_sdnotify.go
+++ b/feature/condregister/maybe_sdnotify.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/sdnotify"
+import _ "github.com/metacubex/tailscale/feature/sdnotify"
diff --git a/feature/condregister/maybe_store_aws.go b/feature/condregister/maybe_store_aws.go
index 96de819d1ee39..a2063b0133683 100644
--- a/feature/condregister/maybe_store_aws.go
+++ b/feature/condregister/maybe_store_aws.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/ipn/store/awsstore"
+import _ "github.com/metacubex/tailscale/ipn/store/awsstore"
diff --git a/feature/condregister/maybe_store_kube.go b/feature/condregister/maybe_store_kube.go
index a71ed00e2e248..7c2651bb45ada 100644
--- a/feature/condregister/maybe_store_kube.go
+++ b/feature/condregister/maybe_store_kube.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/ipn/store/kubestore"
+import _ "github.com/metacubex/tailscale/ipn/store/kubestore"
diff --git a/feature/condregister/maybe_syspolicy.go b/feature/condregister/maybe_syspolicy.go
index 66d44ea3804e4..dac73e6909471 100644
--- a/feature/condregister/maybe_syspolicy.go
+++ b/feature/condregister/maybe_syspolicy.go
@@ -1,8 +1,8 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_syspolicy
+//go:build ts_enable_syspolicy
package condregister
-import _ "tailscale.com/feature/syspolicy"
+import _ "github.com/metacubex/tailscale/feature/syspolicy"
diff --git a/feature/condregister/maybe_taildrop.go b/feature/condregister/maybe_taildrop.go
index 264ccff02006f..c5ea96096a962 100644
--- a/feature/condregister/maybe_taildrop.go
+++ b/feature/condregister/maybe_taildrop.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/taildrop"
+import _ "github.com/metacubex/tailscale/feature/taildrop"
diff --git a/feature/condregister/maybe_tailnetlock.go b/feature/condregister/maybe_tailnetlock.go
index 80a3dffe31aee..b7e8c3f055812 100644
--- a/feature/condregister/maybe_tailnetlock.go
+++ b/feature/condregister/maybe_tailnetlock.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/tailnetlock"
+import _ "github.com/metacubex/tailscale/feature/tailnetlock"
diff --git a/feature/condregister/maybe_tap.go b/feature/condregister/maybe_tap.go
index fc3997b17dca4..07d947a747c0a 100644
--- a/feature/condregister/maybe_tap.go
+++ b/feature/condregister/maybe_tap.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/tap"
+import _ "github.com/metacubex/tailscale/feature/tap"
diff --git a/feature/condregister/maybe_tpm.go b/feature/condregister/maybe_tpm.go
index f46a0996f4feb..f9c1e32c7d7c7 100644
--- a/feature/condregister/maybe_tpm.go
+++ b/feature/condregister/maybe_tpm.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/tpm"
+import _ "github.com/metacubex/tailscale/feature/tpm"
diff --git a/feature/condregister/maybe_tundevstats.go b/feature/condregister/maybe_tundevstats.go
index f678a8c9c2f77..5825757da7422 100644
--- a/feature/condregister/maybe_tundevstats.go
+++ b/feature/condregister/maybe_tundevstats.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/tundevstats"
+import _ "github.com/metacubex/tailscale/feature/tundevstats"
diff --git a/feature/condregister/maybe_wakeonlan.go b/feature/condregister/maybe_wakeonlan.go
index 6fc32bb22fe26..d8206bf5389ad 100644
--- a/feature/condregister/maybe_wakeonlan.go
+++ b/feature/condregister/maybe_wakeonlan.go
@@ -5,4 +5,4 @@
package condregister
-import _ "tailscale.com/feature/wakeonlan"
+import _ "github.com/metacubex/tailscale/feature/wakeonlan"
diff --git a/feature/condregister/oauthkey/maybe_oauthkey.go b/feature/condregister/oauthkey/maybe_oauthkey.go
index 9e912f149a3db..98652829afd8c 100644
--- a/feature/condregister/oauthkey/maybe_oauthkey.go
+++ b/feature/condregister/oauthkey/maybe_oauthkey.go
@@ -5,4 +5,4 @@
package oauthkey
-import _ "tailscale.com/feature/oauthkey"
+import _ "github.com/metacubex/tailscale/feature/oauthkey"
diff --git a/feature/condregister/portmapper/maybe_portmapper.go b/feature/condregister/portmapper/maybe_portmapper.go
index e1be2b3ced942..2d7ccd9b6a78e 100644
--- a/feature/condregister/portmapper/maybe_portmapper.go
+++ b/feature/condregister/portmapper/maybe_portmapper.go
@@ -5,4 +5,4 @@
package portmapper
-import _ "tailscale.com/feature/portmapper"
+import _ "github.com/metacubex/tailscale/feature/portmapper"
diff --git a/feature/condregister/useproxy/doc.go b/feature/condregister/useproxy/doc.go
index d5fde367082e2..5b349178f786e 100644
--- a/feature/condregister/useproxy/doc.go
+++ b/feature/condregister/useproxy/doc.go
@@ -2,5 +2,5 @@
// SPDX-License-Identifier: BSD-3-Clause
// Package useproxy registers support for using proxies
-// if it's not disabled via the ts_omit_useproxy build tag.
+// if it's enabled via the ts_enable_useproxy build tag.
package useproxy
diff --git a/feature/condregister/useproxy/useproxy.go b/feature/condregister/useproxy/useproxy.go
index bca17de88f62e..4ca3c465a3d0c 100644
--- a/feature/condregister/useproxy/useproxy.go
+++ b/feature/condregister/useproxy/useproxy.go
@@ -1,8 +1,8 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_useproxy
+//go:build ts_enable_useproxy
package useproxy
-import _ "tailscale.com/feature/useproxy"
+import _ "github.com/metacubex/tailscale/feature/useproxy"
diff --git a/feature/conn25/addrAssignments.go b/feature/conn25/addrAssignments.go
index 6d8a87dbbfdf8..6abde6c931591 100644
--- a/feature/conn25/addrAssignments.go
+++ b/feature/conn25/addrAssignments.go
@@ -9,9 +9,9 @@ import (
"net/netip"
"time"
- "tailscale.com/tstime"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/mak"
)
// domainDst is a key for looking up an existing address assignment by the
diff --git a/feature/conn25/addrAssignments_test.go b/feature/conn25/addrAssignments_test.go
index 7dd984453b9e3..de73d95c0c6db 100644
--- a/feature/conn25/addrAssignments_test.go
+++ b/feature/conn25/addrAssignments_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,7 +13,7 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/tstest"
)
func TestAssignmentsExpire(t *testing.T) {
diff --git a/feature/conn25/conn25.go b/feature/conn25/conn25.go
index 944dc888ddab9..18f7f109edab4 100644
--- a/feature/conn25/conn25.go
+++ b/feature/conn25/conn25.go
@@ -13,37 +13,37 @@ import (
"encoding/json"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net/http"
"net/netip"
- "slices"
"strings"
"sync"
"sync/atomic"
"time"
+ "github.com/metacubex/tailscale/appc"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnext"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/appctype"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/testenv"
+ "github.com/metacubex/tailscale/wgengine/filter"
"go4.org/netipx"
"golang.org/x/net/dns/dnsmessage"
- "tailscale.com/appc"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnext"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/net/packet"
- "tailscale.com/net/tsaddr"
- "tailscale.com/net/tstun"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/types/appctype"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/views"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
- "tailscale.com/util/testenv"
- "tailscale.com/wgengine/filter"
)
// featureName is the name of the feature implemented by this package.
@@ -546,7 +546,7 @@ type ConnectorTransitIPResponse struct {
TransitIPs []TransitIPResponse `json:"transitIPs,omitempty"`
}
-const AppConnectorsExperimentalAttrName = "tailscale.com/app-connectors-experimental"
+const AppConnectorsExperimentalAttrName = "github.com/metacubex/tailscale/app-connectors-experimental"
// ipSets wraps all the IPSets the config needs.
type ipSets struct {
diff --git a/feature/conn25/conn25_test.go b/feature/conn25/conn25_test.go
index c8d20962c26be..754931fe738ab 100644
--- a/feature/conn25/conn25_test.go
+++ b/feature/conn25/conn25_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,33 +7,33 @@ package conn25
import (
"encoding/json"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/http"
"net/http/httptest"
"net/netip"
- "slices"
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnext"
+ "github.com/metacubex/tailscale/net/dns"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/types/appctype"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/set"
"go4.org/mem"
"go4.org/netipx"
"golang.org/x/net/dns/dnsmessage"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnext"
- "tailscale.com/net/dns"
- "tailscale.com/net/packet"
- "tailscale.com/net/tsdial"
- "tailscale.com/net/tstun"
- "tailscale.com/tailcfg"
- "tailscale.com/tsd"
- "tailscale.com/types/appctype"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/opt"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/must"
- "tailscale.com/util/set"
)
func mustIPSetFromPrefix(s string) *netipx.IPSet {
diff --git a/feature/conn25/datapath.go b/feature/conn25/datapath.go
index b5cdd51550042..89d1ec353b209 100644
--- a/feature/conn25/datapath.go
+++ b/feature/conn25/datapath.go
@@ -7,13 +7,13 @@ import (
"errors"
"net/netip"
- "tailscale.com/envknob"
- "tailscale.com/net/flowtrack"
- "tailscale.com/net/packet"
- "tailscale.com/net/packet/checksum"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/logger"
- "tailscale.com/wgengine/filter"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/net/flowtrack"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/packet/checksum"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/wgengine/filter"
)
var (
diff --git a/feature/conn25/datapath_test.go b/feature/conn25/datapath_test.go
index f75b89d29fed0..b24961dddf0d6 100644
--- a/feature/conn25/datapath_test.go
+++ b/feature/conn25/datapath_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,9 +10,9 @@ import (
"net/netip"
"testing"
- "tailscale.com/net/packet"
- "tailscale.com/types/ipproto"
- "tailscale.com/wgengine/filter"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/wgengine/filter"
)
type testConn25 struct {
diff --git a/feature/conn25/flowtable.go b/feature/conn25/flowtable.go
index 27486ded910a2..7443d776e1f07 100644
--- a/feature/conn25/flowtable.go
+++ b/feature/conn25/flowtable.go
@@ -7,8 +7,8 @@ import (
"errors"
"sync"
- "tailscale.com/net/flowtrack"
- "tailscale.com/net/packet"
+ "github.com/metacubex/tailscale/net/flowtrack"
+ "github.com/metacubex/tailscale/net/packet"
)
// PacketAction may modify the packet.
diff --git a/feature/conn25/flowtable_test.go b/feature/conn25/flowtable_test.go
index 8c3cd63a20e77..a658d5bde5827 100644
--- a/feature/conn25/flowtable_test.go
+++ b/feature/conn25/flowtable_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,9 +9,9 @@ import (
"net/netip"
"testing"
- "tailscale.com/net/flowtrack"
- "tailscale.com/net/packet"
- "tailscale.com/types/ipproto"
+ "github.com/metacubex/tailscale/net/flowtrack"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/types/ipproto"
)
func TestFlowTable(t *testing.T) {
diff --git a/feature/conn25/ippool.go b/feature/conn25/ippool.go
index 4ae8918d49397..52c23f78ddb60 100644
--- a/feature/conn25/ippool.go
+++ b/feature/conn25/ippool.go
@@ -7,8 +7,8 @@ import (
"errors"
"net/netip"
+ "github.com/metacubex/tailscale/util/set"
"go4.org/netipx"
- "tailscale.com/util/set"
)
// errPoolExhausted is returned when there are no more addresses to iterate over.
diff --git a/feature/conn25/ippool_test.go b/feature/conn25/ippool_test.go
index 431ea6998ac84..cee46add19561 100644
--- a/feature/conn25/ippool_test.go
+++ b/feature/conn25/ippool_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,8 +10,8 @@ import (
"net/netip"
"testing"
+ "github.com/metacubex/tailscale/util/must"
"go4.org/netipx"
- "tailscale.com/util/must"
)
func TestNext(t *testing.T) {
diff --git a/feature/debugportmapper/debugportmapper.go b/feature/debugportmapper/debugportmapper.go
index 45f3c22084fba..efaf2cfff5109 100644
--- a/feature/debugportmapper/debugportmapper.go
+++ b/feature/debugportmapper/debugportmapper.go
@@ -16,11 +16,11 @@ import (
"sync"
"time"
- "tailscale.com/ipn/localapi"
- "tailscale.com/net/netmon"
- "tailscale.com/net/portmapper"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
+ "github.com/metacubex/tailscale/ipn/localapi"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/portmapper"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
)
func init() {
diff --git a/feature/doctor/doctor.go b/feature/doctor/doctor.go
index 01897f0a6478a..d7c601c459a8a 100644
--- a/feature/doctor/doctor.go
+++ b/feature/doctor/doctor.go
@@ -12,13 +12,13 @@ import (
"net/http"
"time"
- "tailscale.com/doctor"
- "tailscale.com/doctor/ethtool"
- "tailscale.com/doctor/permissions"
- "tailscale.com/doctor/routetable"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/net/tsaddr"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/doctor"
+ "github.com/metacubex/tailscale/doctor/ethtool"
+ "github.com/metacubex/tailscale/doctor/permissions"
+ "github.com/metacubex/tailscale/doctor/routetable"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/types/logger"
)
func init() {
diff --git a/feature/feature.go b/feature/feature.go
index 5bd79db45c4ed..0c06315cf4e75 100644
--- a/feature/feature.go
+++ b/feature/feature.go
@@ -8,7 +8,7 @@ import (
"errors"
"reflect"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/util/testenv"
)
var ErrUnavailable = errors.New("feature not included in this build")
diff --git a/feature/featuretags/featuretags.go b/feature/featuretags/featuretags.go
index e44a4f5922cc2..8feb333bdfda7 100644
--- a/feature/featuretags/featuretags.go
+++ b/feature/featuretags/featuretags.go
@@ -4,7 +4,7 @@
// The featuretags package is a registry of all the ts_omit-able build tags.
package featuretags
-import "tailscale.com/util/set"
+import "github.com/metacubex/tailscale/util/set"
// CLI is a special feature in the [Features] map that works opposite
// from the others: it is opt-in, rather than opt-out, having a different
diff --git a/feature/featuretags/featuretags_test.go b/feature/featuretags/featuretags_test.go
index c8a9f77ae5e10..8c1a934a44531 100644
--- a/feature/featuretags/featuretags_test.go
+++ b/feature/featuretags/featuretags_test.go
@@ -1,17 +1,19 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package featuretags
import (
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"os/exec"
"regexp"
- "slices"
"strings"
"testing"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/util/set"
)
func TestKnownDeps(t *testing.T) {
diff --git a/feature/hooks.go b/feature/hooks.go
index 7611499a19011..16c481d3b0a3a 100644
--- a/feature/hooks.go
+++ b/feature/hooks.go
@@ -7,17 +7,17 @@ import (
"net/http"
"net/url"
"os"
- "sync"
- "tailscale.com/types/logger"
- "tailscale.com/types/persist"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/persist"
)
// HookCanAutoUpdate is a hook for the clientupdate package
// to conditionally initialize.
var HookCanAutoUpdate Hook[func() bool]
-var testAllowAutoUpdate = sync.OnceValue(func() bool {
+var testAllowAutoUpdate = syncs.OnceValue(func() bool {
return os.Getenv("TS_TEST_ALLOW_AUTO_UPDATE") == "1"
})
diff --git a/feature/identityfederation/identityfederation.go b/feature/identityfederation/identityfederation.go
index 51a8018d8644d..5374ff23b4891 100644
--- a/feature/identityfederation/identityfederation.go
+++ b/feature/identityfederation/identityfederation.go
@@ -15,11 +15,11 @@ import (
"strings"
"time"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/internal/client/tailscale"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/wif"
"golang.org/x/oauth2"
- "tailscale.com/feature"
- "tailscale.com/internal/client/tailscale"
- "tailscale.com/ipn"
- "tailscale.com/wif"
)
func init() {
diff --git a/feature/identityfederation/identityfederation_test.go b/feature/identityfederation/identityfederation_test.go
index 9d9e5f4fdeaa5..736aa191f5ea6 100644
--- a/feature/identityfederation/identityfederation_test.go
+++ b/feature/identityfederation/identityfederation_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/feature/linkspeed/linkspeed_linux.go b/feature/linkspeed/linkspeed_linux.go
index 4e36e281ca80c..68b0d449a4bb9 100644
--- a/feature/linkspeed/linkspeed_linux.go
+++ b/feature/linkspeed/linkspeed_linux.go
@@ -8,9 +8,9 @@ package linkspeed
import (
"github.com/mdlayher/genetlink"
"github.com/mdlayher/netlink"
- "github.com/tailscale/wireguard-go/tun"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/net/tstun"
"golang.org/x/sys/unix"
- "tailscale.com/net/tstun"
)
func init() {
diff --git a/feature/linuxdnsfight/linuxdnsfight.go b/feature/linuxdnsfight/linuxdnsfight.go
index ea37ed7a5b9ef..539573ea2efc4 100644
--- a/feature/linuxdnsfight/linuxdnsfight.go
+++ b/feature/linuxdnsfight/linuxdnsfight.go
@@ -11,8 +11,8 @@ import (
"context"
"fmt"
+ "github.com/metacubex/tailscale/net/dns"
"github.com/illarion/gonotify/v3"
- "tailscale.com/net/dns"
)
func init() {
diff --git a/feature/linuxdnsfight/linuxdnsfight_test.go b/feature/linuxdnsfight/linuxdnsfight_test.go
index ce67353db297c..0a81ff0db334f 100644
--- a/feature/linuxdnsfight/linuxdnsfight_test.go
+++ b/feature/linuxdnsfight/linuxdnsfight_test.go
@@ -1,7 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux && !android
package linuxdnsfight
diff --git a/feature/oauthkey/oauthkey.go b/feature/oauthkey/oauthkey.go
index 532f6ec73bab9..78755be5fdd4f 100644
--- a/feature/oauthkey/oauthkey.go
+++ b/feature/oauthkey/oauthkey.go
@@ -13,9 +13,9 @@ import (
"strconv"
"strings"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/internal/client/tailscale"
"golang.org/x/oauth2/clientcredentials"
- "tailscale.com/feature"
- "tailscale.com/internal/client/tailscale"
)
func init() {
diff --git a/feature/oauthkey/oauthkey_test.go b/feature/oauthkey/oauthkey_test.go
index bb1de932662ff..edb41f9210c3b 100644
--- a/feature/oauthkey/oauthkey_test.go
+++ b/feature/oauthkey/oauthkey_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/feature/portlist/portlist.go b/feature/portlist/portlist.go
index 4d2908962bca8..3e715289a3be6 100644
--- a/feature/portlist/portlist.go
+++ b/feature/portlist/portlist.go
@@ -9,16 +9,16 @@ import (
"context"
"sync/atomic"
- "tailscale.com/envknob"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnext"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/ipn/policy"
- "tailscale.com/portlist"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnext"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/ipn/policy"
+ "github.com/metacubex/tailscale/portlist"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/version"
)
func init() {
diff --git a/feature/portmapper/portmapper.go b/feature/portmapper/portmapper.go
index 3d2004993a510..0bd9b2a35719d 100644
--- a/feature/portmapper/portmapper.go
+++ b/feature/portmapper/portmapper.go
@@ -6,12 +6,12 @@
package portmapper
import (
- "tailscale.com/feature"
- "tailscale.com/net/netmon"
- "tailscale.com/net/portmapper"
- "tailscale.com/net/portmapper/portmappertype"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/portmapper"
+ "github.com/metacubex/tailscale/net/portmapper/portmappertype"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
)
func init() {
diff --git a/feature/posture/posture.go b/feature/posture/posture.go
index 0c60d38b07601..57ad2a3737d83 100644
--- a/feature/posture/posture.go
+++ b/feature/posture/posture.go
@@ -11,15 +11,15 @@ import (
"fmt"
"net/http"
- "tailscale.com/health"
- "tailscale.com/ipn/ipnext"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/posture"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/ptype"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn/ipnext"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/posture"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/ptype"
)
func init() {
diff --git a/feature/relayserver/relayserver.go b/feature/relayserver/relayserver.go
index 4f52a7ca748e7..c64c16cb1c29b 100644
--- a/feature/relayserver/relayserver.go
+++ b/feature/relayserver/relayserver.go
@@ -11,21 +11,21 @@ import (
"net/http"
"net/netip"
- "tailscale.com/disco"
- "tailscale.com/feature"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnext"
- "tailscale.com/ipn/localapi"
- "tailscale.com/net/udprelay"
- "tailscale.com/net/udprelay/endpoint"
- "tailscale.com/net/udprelay/status"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/views"
- "tailscale.com/util/eventbus"
- "tailscale.com/wgengine/magicsock"
+ "github.com/metacubex/tailscale/disco"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnext"
+ "github.com/metacubex/tailscale/ipn/localapi"
+ "github.com/metacubex/tailscale/net/udprelay"
+ "github.com/metacubex/tailscale/net/udprelay/endpoint"
+ "github.com/metacubex/tailscale/net/udprelay/status"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/wgengine/magicsock"
)
// featureName is the name of the feature implemented by this package.
diff --git a/feature/relayserver/relayserver_test.go b/feature/relayserver/relayserver_test.go
index 97f4eb87418b6..8bfc391daaea8 100644
--- a/feature/relayserver/relayserver_test.go
+++ b/feature/relayserver/relayserver_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,20 +7,20 @@ package relayserver
import (
"errors"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"reflect"
- "slices"
"testing"
- "tailscale.com/ipn"
- "tailscale.com/net/udprelay/endpoint"
- "tailscale.com/net/udprelay/status"
- "tailscale.com/tailcfg"
- "tailscale.com/tsd"
- "tailscale.com/tstime"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/views"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/net/udprelay/endpoint"
+ "github.com/metacubex/tailscale/net/udprelay/status"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/views"
)
func Test_extension_profileStateChanged(t *testing.T) {
diff --git a/feature/sdnotify.go b/feature/sdnotify.go
index 45f280c8116f2..1a133f43be04e 100644
--- a/feature/sdnotify.go
+++ b/feature/sdnotify.go
@@ -6,7 +6,7 @@ package feature
import (
"runtime"
- "tailscale.com/feature/buildfeatures"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
)
// HookSystemdReady sends a readiness to systemd. This will unblock service
diff --git a/feature/sdnotify/sdnotify_linux.go b/feature/sdnotify/sdnotify_linux.go
index 6a3df879638c9..362650d8a4dad 100644
--- a/feature/sdnotify/sdnotify_linux.go
+++ b/feature/sdnotify/sdnotify_linux.go
@@ -12,7 +12,7 @@ import (
"sync"
"github.com/mdlayher/sdnotify"
- "tailscale.com/feature"
+ "github.com/metacubex/tailscale/feature"
)
func init() {
diff --git a/feature/ssh/ssh.go b/feature/ssh/ssh.go
index bd22005916d60..9b43ac5338662 100644
--- a/feature/ssh/ssh.go
+++ b/feature/ssh/ssh.go
@@ -8,4 +8,4 @@
package ssh
// Register implementations of various SSH hooks.
-import _ "tailscale.com/ssh/tailssh"
+import _ "github.com/metacubex/tailscale/ssh/tailssh"
diff --git a/feature/syspolicy/syspolicy.go b/feature/syspolicy/syspolicy.go
index dce2eb0b18bbb..50015070ca83a 100644
--- a/feature/syspolicy/syspolicy.go
+++ b/feature/syspolicy/syspolicy.go
@@ -4,4 +4,4 @@
// Package syspolicy provides an interface for system-wide policy management.
package syspolicy
-import _ "tailscale.com/util/syspolicy" // for its registration side effects
+import _ "github.com/metacubex/tailscale/util/syspolicy" // for its registration side effects
diff --git a/feature/taildrop/delete.go b/feature/taildrop/delete.go
index dc5036006a2f6..29af0efe423bd 100644
--- a/feature/taildrop/delete.go
+++ b/feature/taildrop/delete.go
@@ -11,9 +11,9 @@ import (
"sync"
"time"
- "tailscale.com/ipn"
- "tailscale.com/tstime"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/logger"
)
// deleteDelay is the amount of time to wait before we delete a file.
diff --git a/feature/taildrop/delete_test.go b/feature/taildrop/delete_test.go
index 2b740a3fb2d6c..97a1da4af0d3a 100644
--- a/feature/taildrop/delete_test.go
+++ b/feature/taildrop/delete_test.go
@@ -1,20 +1,22 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package taildrop
import (
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"os"
- "slices"
"testing"
"time"
"github.com/google/go-cmp/cmp"
- "tailscale.com/ipn"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/tstest"
- "tailscale.com/tstime"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/must"
)
func TestDeleter(t *testing.T) {
diff --git a/feature/taildrop/ext.go b/feature/taildrop/ext.go
index abf574ebc5407..ea3caa0ee1ffa 100644
--- a/feature/taildrop/ext.go
+++ b/feature/taildrop/ext.go
@@ -4,30 +4,30 @@
package taildrop
import (
- "cmp"
"context"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
- "maps"
"path/filepath"
"runtime"
- "slices"
"strings"
"sync"
"sync/atomic"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/cmd/tailscaled/tailscaledhooks"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnext"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/types/empty"
- "tailscale.com/types/logger"
- "tailscale.com/util/osshare"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/cmd/tailscaled/tailscaledhooks"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnext"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/empty"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/osshare"
+ "github.com/metacubex/tailscale/util/set"
)
func init() {
diff --git a/feature/taildrop/integration_test.go b/feature/taildrop/integration_test.go
index ad66aa827faa0..f2407635bb791 100644
--- a/feature/taildrop/integration_test.go
+++ b/feature/taildrop/integration_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,12 +14,12 @@ import (
"testing"
"time"
- "tailscale.com/client/local"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/tstest/integration"
- "tailscale.com/tstest/integration/testcontrol"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstest/integration"
+ "github.com/metacubex/tailscale/tstest/integration/testcontrol"
)
// TODO(bradfitz): add test where control doesn't send tailcfg.CapabilityFileSharing
diff --git a/feature/taildrop/localapi.go b/feature/taildrop/localapi.go
index 2af057ae8d88c..fadf1751de848 100644
--- a/feature/taildrop/localapi.go
+++ b/feature/taildrop/localapi.go
@@ -8,8 +8,8 @@ import (
"context"
"encoding/json"
"fmt"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"io"
- "maps"
"mime"
"mime/multipart"
"net/http"
@@ -19,16 +19,16 @@ import (
"strings"
"time"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/ipn/localapi"
- "tailscale.com/tailcfg"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/httphdr"
- "tailscale.com/util/mak"
- "tailscale.com/util/progresstracking"
- "tailscale.com/util/rands"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/ipn/localapi"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/httphdr"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/progresstracking"
+ "github.com/metacubex/tailscale/util/rands"
)
func init() {
diff --git a/feature/taildrop/paths.go b/feature/taildrop/paths.go
index 76054ef4d58b3..a40805655f72f 100644
--- a/feature/taildrop/paths.go
+++ b/feature/taildrop/paths.go
@@ -8,7 +8,7 @@ import (
"os"
"path/filepath"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/version/distro"
)
// SetDirectFileRoot sets the directory where received files are written.
diff --git a/feature/taildrop/peerapi.go b/feature/taildrop/peerapi.go
index 8b92c8c85b0cd..df4c2616e386d 100644
--- a/feature/taildrop/peerapi.go
+++ b/feature/taildrop/peerapi.go
@@ -12,11 +12,11 @@ import (
"strings"
"time"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/httphdr"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/httphdr"
)
func init() {
diff --git a/feature/taildrop/peerapi_test.go b/feature/taildrop/peerapi_test.go
index 65f881be906b7..adf6d7a415cd2 100644
--- a/feature/taildrop/peerapi_test.go
+++ b/feature/taildrop/peerapi_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -18,13 +20,13 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/tstime"
- "tailscale.com/types/logger"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/must"
)
// peerAPIHandler serves the PeerAPI for a source specific client.
diff --git a/feature/taildrop/resume_test.go b/feature/taildrop/resume_test.go
index 69dd547a123e0..6498bd0080e1c 100644
--- a/feature/taildrop/resume_test.go
+++ b/feature/taildrop/resume_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,7 +14,7 @@ import (
"testing"
"testing/iotest"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/util/must"
)
func TestResume(t *testing.T) {
diff --git a/feature/taildrop/retrieve.go b/feature/taildrop/retrieve.go
index dd1b75b174db7..51ab89ee68be2 100644
--- a/feature/taildrop/retrieve.go
+++ b/feature/taildrop/retrieve.go
@@ -13,9 +13,9 @@ import (
"sort"
"time"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/util/backoff"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/util/backoff"
+ "github.com/metacubex/tailscale/util/set"
)
// HasFilesWaiting reports whether any files are buffered in [Handler.Dir].
diff --git a/feature/taildrop/send.go b/feature/taildrop/send.go
index 668166d4409cf..6763e3c82a66c 100644
--- a/feature/taildrop/send.go
+++ b/feature/taildrop/send.go
@@ -9,10 +9,10 @@ import (
"sync"
"time"
- "tailscale.com/envknob"
- "tailscale.com/ipn"
- "tailscale.com/tstime"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/version/distro"
)
type incomingFileKey struct {
diff --git a/feature/taildrop/send_test.go b/feature/taildrop/send_test.go
index c1def2afdd106..2fcf82d53e10c 100644
--- a/feature/taildrop/send_test.go
+++ b/feature/taildrop/send_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,8 +11,8 @@ import (
"strings"
"testing"
- "tailscale.com/tstime"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/must"
)
func TestPutFile(t *testing.T) {
diff --git a/feature/taildrop/taildrop.go b/feature/taildrop/taildrop.go
index 9839b8330e597..4a30762dc2285 100644
--- a/feature/taildrop/taildrop.go
+++ b/feature/taildrop/taildrop.go
@@ -17,11 +17,11 @@ import (
"unicode"
"unicode/utf8"
- "tailscale.com/ipn"
- "tailscale.com/syncs"
- "tailscale.com/tstime"
- "tailscale.com/types/logger"
- "tailscale.com/util/multierr"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/multierr"
)
var (
diff --git a/feature/taildrop/taildrop_test.go b/feature/taildrop/taildrop_test.go
index 5c48412e044ba..f35ad6c656ad5 100644
--- a/feature/taildrop/taildrop_test.go
+++ b/feature/taildrop/taildrop_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/feature/taildrop/target_test.go b/feature/taildrop/target_test.go
index 7948c488293bf..8defc1fb7ed6d 100644
--- a/feature/taildrop/target_test.go
+++ b/feature/taildrop/target_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,9 +9,9 @@ import (
"fmt"
"testing"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnext"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnext"
+ "github.com/metacubex/tailscale/tailcfg"
)
func TestFileTargets(t *testing.T) {
diff --git a/feature/tailnetlock/tailnetlock.go b/feature/tailnetlock/tailnetlock.go
index 325a13b087bc0..4002fecebfaf3 100644
--- a/feature/tailnetlock/tailnetlock.go
+++ b/feature/tailnetlock/tailnetlock.go
@@ -10,10 +10,10 @@ import (
"net/http"
"strconv"
- "tailscale.com/cmd/tailscale/cli/jsonoutput"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/cmd/tailscale/cli/jsonoutput"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
)
func init() {
diff --git a/feature/tailnetlock/tailnetlock_test.go b/feature/tailnetlock/tailnetlock_test.go
index bad2941097ee4..e2afecf25cf27 100644
--- a/feature/tailnetlock/tailnetlock_test.go
+++ b/feature/tailnetlock/tailnetlock_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,10 +12,10 @@ import (
"strings"
"testing"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/tka"
- "tailscale.com/types/key"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/util/must"
)
func TestHandleC2NDebugTKA(t *testing.T) {
diff --git a/feature/tap/tap_linux.go b/feature/tap/tap_linux.go
index e66f74ba4d1e4..8a731ed1ad18c 100644
--- a/feature/tap/tap_linux.go
+++ b/feature/tap/tap_linux.go
@@ -14,22 +14,22 @@ import (
"os/exec"
"sync"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/logger"
"github.com/insomniacslk/dhcp/dhcpv4"
- "github.com/tailscale/wireguard-go/tun"
+ "github.com/metacubex/gvisor/pkg/tcpip"
+ "github.com/metacubex/gvisor/pkg/tcpip/checksum"
+ "github.com/metacubex/gvisor/pkg/tcpip/header"
+ "github.com/metacubex/gvisor/pkg/tcpip/network/ipv4"
+ "github.com/metacubex/gvisor/pkg/tcpip/network/ipv6"
+ "github.com/metacubex/gvisor/pkg/tcpip/transport/udp"
"golang.org/x/sys/unix"
- "gvisor.dev/gvisor/pkg/tcpip"
- "gvisor.dev/gvisor/pkg/tcpip/checksum"
- "gvisor.dev/gvisor/pkg/tcpip/header"
- "gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
- "gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
- "gvisor.dev/gvisor/pkg/tcpip/transport/udp"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/packet"
- "tailscale.com/net/tsaddr"
- "tailscale.com/net/tstun"
- "tailscale.com/syncs"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/logger"
)
// TODO: this was randomly generated once. Maybe do it per process start? But
diff --git a/feature/tpm/attestation.go b/feature/tpm/attestation.go
index 8955d5b98f605..b9d5b464140dc 100644
--- a/feature/tpm/attestation.go
+++ b/feature/tpm/attestation.go
@@ -14,9 +14,9 @@ import (
"github.com/google/go-tpm/tpm2"
"github.com/google/go-tpm/tpm2/transport"
+ "github.com/metacubex/tailscale/types/key"
"golang.org/x/crypto/cryptobyte"
"golang.org/x/crypto/cryptobyte/asn1"
- "tailscale.com/types/key"
)
type attestationKey struct {
diff --git a/feature/tpm/attestation_test.go b/feature/tpm/attestation_test.go
index 06518b63a9059..9f583b9230c51 100644
--- a/feature/tpm/attestation_test.go
+++ b/feature/tpm/attestation_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/feature/tpm/tpm.go b/feature/tpm/tpm.go
index e257aa7bc2174..d67d03656a25e 100644
--- a/feature/tpm/tpm.go
+++ b/feature/tpm/tpm.go
@@ -10,29 +10,29 @@ import (
"encoding/json"
"errors"
"fmt"
- "iter"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
"os"
"path/filepath"
"runtime"
- "slices"
"strings"
"sync"
"github.com/google/go-tpm/tpm2"
"github.com/google/go-tpm/tpm2/transport"
+ "github.com/metacubex/tailscale/atomicfile"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/store"
+ "github.com/metacubex/tailscale/paths"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/testenv"
"golang.org/x/crypto/nacl/secretbox"
- "tailscale.com/atomicfile"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn"
- "tailscale.com/ipn/store"
- "tailscale.com/paths"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/util/testenv"
)
var (
diff --git a/feature/tpm/tpm_test.go b/feature/tpm/tpm_test.go
index 02fb13f58c908..7120c2c1dda16 100644
--- a/feature/tpm/tpm_test.go
+++ b/feature/tpm/tpm_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,20 +11,20 @@ import (
"encoding/json"
"errors"
"fmt"
- "iter"
- "maps"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"os"
"path/filepath"
- "slices"
"strconv"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
- "tailscale.com/ipn"
- "tailscale.com/ipn/store"
- "tailscale.com/types/logger"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/store"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/mak"
)
func TestPropToString(t *testing.T) {
diff --git a/feature/tundevstats/tundevstats_linux.go b/feature/tundevstats/tundevstats_linux.go
index 13d5169c2a9ac..f6b8eb8460d34 100644
--- a/feature/tundevstats/tundevstats_linux.go
+++ b/feature/tundevstats/tundevstats_linux.go
@@ -15,12 +15,12 @@ import (
"time"
"unsafe"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/util/clientmetric"
"github.com/mdlayher/netlink"
- "github.com/tailscale/wireguard-go/tun"
"golang.org/x/sys/unix"
- "tailscale.com/feature"
- "tailscale.com/net/tstun"
- "tailscale.com/util/clientmetric"
)
func init() {
@@ -35,7 +35,7 @@ func init() {
}
// poller polls TUN device stats via netlink, and surfaces them via
-// [tailscale.com/util/clientmetric].
+// [github.com/metacubex/tailscale/util/clientmetric].
type poller struct {
conn *netlink.Conn
ifIndex uint32
@@ -102,7 +102,7 @@ func newPoller(tdev tun.Device) (io.Closer, error) {
const (
// pollInterval is how frequently [poller] polls TUN device statistics. Its
- // value mirrors [tailscale.com/util/clientmetric.minMetricEncodeInterval],
+ // value mirrors [github.com/metacubex/tailscale/util/clientmetric.minMetricEncodeInterval],
// which is the minimum interval between clientmetrics emissions.
pollInterval = 15 * time.Second
)
diff --git a/feature/tundevstats/tundevstats_linux_test.go b/feature/tundevstats/tundevstats_linux_test.go
index 05468039beb17..8e309dd3f2e7a 100644
--- a/feature/tundevstats/tundevstats_linux_test.go
+++ b/feature/tundevstats/tundevstats_linux_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,9 +14,9 @@ import (
"time"
"unsafe"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
"github.com/mdlayher/netlink"
"github.com/mdlayher/netlink/nltest"
- "github.com/tailscale/wireguard-go/tun"
"golang.org/x/sys/unix"
)
diff --git a/feature/useproxy/useproxy.go b/feature/useproxy/useproxy.go
index 96be23710caa1..1bb893841f666 100644
--- a/feature/useproxy/useproxy.go
+++ b/feature/useproxy/useproxy.go
@@ -5,8 +5,8 @@
package useproxy
import (
- "tailscale.com/feature"
- "tailscale.com/net/tshttpproxy"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/net/tshttpproxy"
)
func init() {
diff --git a/feature/wakeonlan/wakeonlan.go b/feature/wakeonlan/wakeonlan.go
index 5a567ad44237d..19d71098f218a 100644
--- a/feature/wakeonlan/wakeonlan.go
+++ b/feature/wakeonlan/wakeonlan.go
@@ -15,12 +15,12 @@ import (
"unicode"
"github.com/kortschak/wol"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/tailcfg"
- "tailscale.com/util/clientmetric"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/clientmetric"
)
func init() {
diff --git a/go.mod b/go.mod
index 89038db40de32..5c0cb042bc1b6 100644
--- a/go.mod
+++ b/go.mod
@@ -1,509 +1,49 @@
-module tailscale.com
+module github.com/metacubex/tailscale
-go 1.26.3
+go 1.20
require (
- filippo.io/mkcert v1.4.4
- fyne.io/systray v1.11.1-0.20250812065214-4856ac3adc3c
- github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9
- github.com/akutz/memconn v0.1.0
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa
- github.com/andybalholm/brotli v1.1.0
- github.com/atotto/clipboard v0.1.4
- github.com/aws/aws-sdk-go-v2 v1.41.0
- github.com/aws/aws-sdk-go-v2/config v1.29.5
- github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.58
- github.com/aws/aws-sdk-go-v2/service/s3 v1.75.3
- github.com/aws/aws-sdk-go-v2/service/ssm v1.44.7
- github.com/axiomhq/hyperloglog v0.0.0-20240319100328-84253e514e02
- github.com/bradfitz/go-tool-cache v0.0.0-20260216153636-9e5201344fe5
- github.com/bradfitz/monogok v0.0.0-20260429173803-229ef7981a6b
- github.com/bramvdbogaerde/go-scp v1.4.0
- github.com/cilium/ebpf v0.16.0
github.com/coder/websocket v1.8.12
- github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6
- github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
- github.com/creachadair/mds v0.25.9
- github.com/creachadair/msync v0.7.1
- github.com/creachadair/taskgroup v0.13.2
- github.com/creack/pty v1.1.24
- github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa
- github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e
- github.com/distribution/reference v0.6.0
- github.com/djherbis/times v1.6.0
- github.com/dsnet/try v0.0.3
- github.com/elastic/crd-ref-docs v0.0.12
- github.com/evanw/esbuild v0.19.11
- github.com/fogleman/gg v1.3.0
- github.com/frankban/quicktest v1.14.6
github.com/fxamacker/cbor/v2 v2.9.0
- github.com/gaissmai/bart v0.26.1
- github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced
- github.com/go-logr/zapr v1.3.0
- github.com/go-ole/go-ole v1.3.0
- github.com/go4org/hashtriemap v0.0.0-20251130024219-545ba229f689
- github.com/go4org/plan9netshell v0.0.0-20250324183649-788daa080737
- github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466
- github.com/gokrazy/breakglass v0.0.0-20251229072214-9dbc0478d486
- github.com/gokrazy/gokrazy v0.0.0-20260418085648-c38c3134b8a7
- github.com/gokrazy/kernel.arm64 v0.0.0-20260403054012-807489e0272a
- github.com/gokrazy/serial-busybox v0.0.0-20250119153030-ac58ba7574e7
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8
- github.com/golang/snappy v0.0.4
- github.com/golangci/golangci-lint v1.57.1
- github.com/google/go-cmp v0.7.0
- github.com/google/go-containerregistry v0.21.5
- github.com/google/go-tpm v0.9.4
- github.com/google/gopacket v1.1.19
- github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806
- github.com/google/uuid v1.6.0
- github.com/goreleaser/nfpm/v2 v2.33.1
- github.com/hashicorp/go-hclog v1.6.2
- github.com/hashicorp/raft v1.7.2
- github.com/hashicorp/raft-boltdb/v2 v2.3.1
- github.com/hdevalence/ed25519consensus v0.2.0
github.com/huin/goupnp v1.3.0
- github.com/illarion/gonotify/v3 v3.0.2
- github.com/inetaf/tcpproxy v0.0.0-20250203165043-ded522cbd03f
- github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2
- github.com/jellydator/ttlcache/v3 v3.1.0
- github.com/jsimonetti/rtnetlink v1.4.0
- github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
- github.com/kdomanski/iso9660 v0.4.0
- github.com/klauspost/compress v1.18.5
- github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a
- github.com/mattn/go-colorable v0.1.13
- github.com/mattn/go-isatty v0.0.20
- github.com/mdlayher/genetlink v1.3.2
- github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42
- github.com/mdlayher/sdnotify v1.0.0
- github.com/miekg/dns v1.1.58
+ github.com/klauspost/compress v1.17.9
+ github.com/metacubex/edwards25519 v1.2.0
+ github.com/metacubex/jsonv2 v0.0.0-20260518173308-f4597c22f1df
github.com/mitchellh/go-ps v1.0.0
- github.com/peterbourgon/ff/v3 v3.4.0
- github.com/pires/go-proxyproto v0.8.1
- github.com/pkg/errors v0.9.1
- github.com/pkg/sftp v1.13.6
- github.com/prometheus/client_golang v1.23.0
- github.com/prometheus/common v0.65.0
- github.com/prometheus/prometheus v0.49.2-0.20240125131847-c3b8ef1694ff
- github.com/robert-nix/ansihtml v1.0.1
- github.com/safchain/ethtool v0.3.0
- github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
- github.com/studio-b12/gowebdav v0.9.0
+ github.com/pires/go-proxyproto v0.8.0
github.com/tailscale/certstore v0.1.1-0.20260409135935-3638fb84b77d
- github.com/tailscale/depaware v0.0.0-20251001183927-9c2ad255ef3f
- github.com/tailscale/gliderssh v0.3.4-0.20260330083525-c1389c70ff89
- github.com/tailscale/goexpect v0.0.0-20210902213824-6e8c725cea41
- github.com/tailscale/gokrazy-kernel v0.0.0-20240728225134-3d23beabda2e
- github.com/tailscale/golang-x-crypto v0.0.0-20250404221719-a5573b049869
- github.com/tailscale/hujson v0.0.0-20260302212456-ecc657c15afd
- github.com/tailscale/mkctr v0.0.0-20260107121656-ea857e3e500b
- github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7
- github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc
- github.com/tailscale/setec v0.0.0-20251203133219-2ab774e4129a
- github.com/tailscale/ts-gokrazy v0.0.0-20260429180033-fe741c6deb44
- github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976
- github.com/tailscale/wf v0.0.0-20240214030419-6fbb0a674ee6
- github.com/tailscale/wireguard-go v0.0.0-20260427181203-e3ac4a0afb4e
- github.com/tailscale/xnet v0.0.0-20240729143630-8497ac4dab2e
- github.com/tc-hib/winres v0.2.1
- github.com/tcnksm/go-httpstat v0.2.0
- github.com/toqueteos/webbrowser v1.2.0
- github.com/u-root/u-root v0.14.0
- github.com/vishvananda/netns v0.0.5
- go.uber.org/zap v1.27.0
+ github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a
go4.org/mem v0.0.0-20240501181205-ae6ca9944745
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
- golang.org/x/crypto v0.50.0
- golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b
- golang.org/x/mod v0.35.0
- golang.org/x/net v0.53.0
- golang.org/x/oauth2 v0.36.0
- golang.org/x/sync v0.20.0
- golang.org/x/sys v0.43.0
- golang.org/x/term v0.42.0
- golang.org/x/time v0.12.0
- golang.org/x/tools v0.44.0
- golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2
- golang.zx2c4.com/wireguard/windows v0.5.3
- gopkg.in/square/go-jose.v2 v2.6.0
- gvisor.dev/gvisor v0.0.0-20260224225140-573d5e7127a8
- helm.sh/helm/v3 v3.19.0
- honnef.co/go/tools v0.7.0
- k8s.io/api v0.34.0
- k8s.io/apimachinery v0.34.0
- k8s.io/apiserver v0.34.0
- k8s.io/client-go v0.34.0
- sigs.k8s.io/controller-runtime v0.19.4
- sigs.k8s.io/controller-tools v0.17.0
- sigs.k8s.io/kind v0.30.0
- sigs.k8s.io/yaml v1.6.0
- software.sslmate.com/src/go-pkcs12 v0.4.0
- tailscale.com/client/tailscale/v2 v2.9.0
+ golang.org/x/crypto v0.33.0
+ golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e
+ golang.org/x/net v0.35.0
+ golang.org/x/oauth2 v0.24.0
+ golang.org/x/sync v0.11.0
+ golang.org/x/sys v0.30.0
+ golang.org/x/term v0.29.0
+ golang.org/x/time v0.10.0
)
require (
- 9fans.net/go v0.0.8-0.20250307142834-96bdba94b63f // indirect
- al.essio.dev/pkg/shellescape v1.5.1 // indirect
- github.com/4meepo/tagalign v1.3.3 // indirect
- github.com/Antonboom/testifylint v1.2.0 // indirect
- github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
- github.com/GaijinEntertainment/go-exhaustruct/v3 v3.2.0 // indirect
- github.com/MakeNowJust/heredoc v1.0.0 // indirect
- github.com/Masterminds/sprig v2.22.0+incompatible // indirect
- github.com/Masterminds/squirrel v1.5.4 // indirect
- github.com/Microsoft/go-winio v0.6.2 // indirect
- github.com/OpenPeeDeeP/depguard/v2 v2.2.0 // indirect
- github.com/alecthomas/go-check-sumtype v0.1.4 // indirect
- github.com/alexkohler/nakedret/v2 v2.0.4 // indirect
- github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
- github.com/armon/go-metrics v0.4.1 // indirect
- github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
- github.com/beevik/ntp v0.3.0 // indirect
- github.com/blang/semver/v4 v4.0.0 // indirect
- github.com/boltdb/bolt v1.3.1 // indirect
- github.com/bombsimon/wsl/v4 v4.2.1 // indirect
- github.com/butuzov/mirror v1.1.0 // indirect
- github.com/catenacyber/perfsprint v0.7.1 // indirect
- github.com/ccojocar/zxcvbn-go v1.0.2 // indirect
- github.com/chai2010/gettext-go v1.0.2 // indirect
- github.com/ckaznocha/intrange v0.1.0 // indirect
- github.com/containerd/containerd v1.7.29 // indirect
- github.com/containerd/errdefs v1.0.0 // indirect
- github.com/containerd/errdefs/pkg v0.3.0 // indirect
- github.com/containerd/log v0.1.0 // indirect
- github.com/containerd/platforms v1.0.0-rc.2 // indirect
- github.com/containerd/typeurl/v2 v2.2.3 // indirect
- github.com/cyphar/filepath-securejoin v0.6.1 // indirect
- github.com/deckarep/golang-set/v2 v2.8.0 // indirect
- github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc // indirect
- github.com/docker/go-connections v0.6.0 // indirect
- github.com/docker/go-events v0.0.0-20250808211157-605354379745 // indirect
- github.com/docker/go-units v0.5.0 // indirect
- github.com/evanphx/json-patch v5.9.11+incompatible // indirect
- github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
- github.com/felixge/httpsnoop v1.0.4 // indirect
- github.com/ghostiam/protogetter v0.3.5 // indirect
- github.com/go-errors/errors v1.4.2 // indirect
- github.com/go-gorp/gorp/v3 v3.1.0 // indirect
- github.com/go-logr/stdr v1.2.2 // indirect
- github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
- github.com/gobuffalo/flect v1.0.3 // indirect
- github.com/goccy/go-yaml v1.12.0 // indirect
- github.com/gokrazy/gokapi v0.0.0-20250222071133-506fdb322775 // indirect
- github.com/gokrazy/internal v0.0.0-20251208203110-3c1aa9087c82 // indirect
- github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
- github.com/golangci/plugin-module-register v0.1.1 // indirect
- github.com/google/gnostic-models v0.7.0 // indirect
- github.com/google/go-github/v66 v66.0.0 // indirect
- github.com/google/go-querystring v1.1.0 // indirect
- github.com/google/renameio/v2 v2.0.2 // indirect
- github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
- github.com/gorilla/securecookie v1.1.2 // indirect
- github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
- github.com/gosuri/uitable v0.0.4 // indirect
- github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
- github.com/hashicorp/errwrap v1.1.0 // indirect
- github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
- github.com/hashicorp/go-metrics v0.5.4 // indirect
- github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect
- github.com/hashicorp/go-multierror v1.1.1 // indirect
- github.com/hashicorp/golang-lru v0.6.0 // indirect
- github.com/jjti/go-spancheck v0.5.3 // indirect
- github.com/jmoiron/sqlx v1.4.0 // indirect
+ github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 // indirect
+ github.com/google/go-cmp v0.6.0 // indirect
github.com/josharian/native v1.1.0 // indirect
- github.com/karamaru-alpha/copyloopvar v1.0.8 // indirect
- github.com/kenshaw/evdev v0.1.0 // indirect
- github.com/kr/pty v1.1.8 // indirect
- github.com/kylelemons/godebug v1.1.0 // indirect
- github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
- github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
- github.com/lib/pq v1.10.9 // indirect
- github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
- github.com/macabu/inamedparam v0.1.3 // indirect
- github.com/mdlayher/packet v1.1.2 // indirect
- github.com/mdlayher/watchdog v0.0.0-20221003142519-49be0df7b3b5 // indirect
- github.com/mitchellh/go-wordwrap v1.0.1 // indirect
- github.com/moby/buildkit v0.20.2 // indirect
- github.com/moby/docker-image-spec v1.3.1 // indirect
- github.com/moby/moby/api v1.54.1 // indirect
- github.com/moby/moby/client v0.4.0 // indirect
- github.com/moby/spdystream v0.5.0 // indirect
- github.com/moby/term v0.5.2 // indirect
- github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
- github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
- github.com/pelletier/go-toml v1.9.5 // indirect
- github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
- github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
- github.com/puzpuzpuz/xsync v1.5.2 // indirect
- github.com/rtr7/dhcp4 v0.0.0-20220302171438-18c84d089b46 // indirect
- github.com/rubenv/sql-migrate v1.8.0 // indirect
- github.com/russross/blackfriday/v2 v2.1.0 // indirect
- github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect
- github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
- github.com/stacklok/frizbee v0.1.7 // indirect
- github.com/vishvananda/netlink v1.3.1 // indirect
- github.com/xen0n/gosmopolitan v1.2.2 // indirect
- github.com/xlab/treeprint v1.2.0 // indirect
- github.com/ykadowak/zerologlint v0.1.5 // indirect
- go-simpler.org/musttag v0.9.0 // indirect
- go-simpler.org/sloglint v0.5.0 // indirect
- go.etcd.io/bbolt v1.4.2 // indirect
- go.opentelemetry.io/auto/sdk v1.2.1 // indirect
- go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 // indirect
- go.opentelemetry.io/otel v1.39.0 // indirect
- go.opentelemetry.io/otel/metric v1.39.0 // indirect
- go.opentelemetry.io/otel/trace v1.39.0 // indirect
- go.uber.org/automaxprocs v1.5.3 // indirect
- go.yaml.in/yaml/v2 v2.4.2 // indirect
- go.yaml.in/yaml/v3 v3.0.4 // indirect
- golang.org/x/crypto/x509roots/fallback v0.0.0-20260113154411-7d0074ccc6f1 // indirect
- golang.org/x/telemetry v0.0.0-20260409153401-be6f6cb8b1fa // indirect
- golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect
- golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect
- google.golang.org/grpc v1.78.0 // indirect
- gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
- k8s.io/cli-runtime v0.34.0 // indirect
- k8s.io/component-base v0.34.0 // indirect
- k8s.io/kubectl v0.34.0 // indirect
- oras.land/oras-go/v2 v2.6.0 // indirect
- sigs.k8s.io/kustomize/api v0.20.1 // indirect
- sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect
- sigs.k8s.io/randfill v1.0.0 // indirect
- sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
+ github.com/jsimonetti/rtnetlink v1.4.0 // indirect
+ github.com/mdlayher/netlink v1.7.2 // indirect
+ github.com/mdlayher/socket v0.5.0 // indirect
+ github.com/safchain/ethtool v0.3.0 // indirect
+ github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc // indirect
)
require (
- 4d63.com/gocheckcompilerdirectives v1.2.1 // indirect
- 4d63.com/gochecknoglobals v0.2.1 // indirect
- dario.cat/mergo v1.0.1 // indirect
- filippo.io/edwards25519 v1.2.0 // indirect
- github.com/Abirdcfly/dupword v0.0.14 // indirect
- github.com/AlekSi/pointer v1.2.0
- github.com/Antonboom/errname v0.1.12 // indirect
- github.com/Antonboom/nilnil v0.1.7 // indirect
- github.com/BurntSushi/toml v1.5.0 // indirect
- github.com/Djarvur/go-err113 v0.1.0 // indirect
- github.com/Masterminds/goutils v1.1.1 // indirect
- github.com/Masterminds/semver v1.5.0 // indirect
- github.com/Masterminds/semver/v3 v3.4.0 // indirect
- github.com/Masterminds/sprig/v3 v3.3.0 // indirect
- github.com/ProtonMail/go-crypto v1.1.6 // indirect
- github.com/alexkohler/prealloc v1.0.0 // indirect
- github.com/alingse/asasalint v0.0.11 // indirect
- github.com/ashanbrown/forbidigo v1.6.0 // indirect
- github.com/ashanbrown/makezero v1.1.1 // indirect
- github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.8 // indirect
- github.com/aws/aws-sdk-go-v2/credentials v1.17.58 // indirect
- github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.27
- github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 // indirect
- github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 // indirect
- github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 // indirect
- github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.31 // indirect
- github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect
- github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.5.5 // indirect
- github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 // indirect
- github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.12 // indirect
- github.com/aws/aws-sdk-go-v2/service/sso v1.24.14 // indirect
- github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13 // indirect
- github.com/aws/aws-sdk-go-v2/service/sts v1.41.5
- github.com/aws/smithy-go v1.24.0
- github.com/beorn7/perks v1.0.1 // indirect
- github.com/bkielbasa/cyclop v1.2.1 // indirect
- github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb // indirect
- github.com/blizzy78/varnamelen v0.8.0 // indirect
- github.com/breml/bidichk v0.2.7 // indirect
- github.com/breml/errchkjson v0.3.6 // indirect
- github.com/butuzov/ireturn v0.3.0 // indirect
- github.com/cavaliergopher/cpio v1.0.1 // indirect
- github.com/cespare/xxhash/v2 v2.3.0 // indirect
- github.com/charithe/durationcheck v0.0.10 // indirect
- github.com/chavacava/garif v0.1.0 // indirect
- github.com/cloudflare/circl v1.6.3 // indirect
- github.com/containerd/stargz-snapshotter/estargz v0.18.2 // indirect
- github.com/curioswitch/go-reassign v0.2.0 // indirect
- github.com/daixiang0/gci v0.12.3 // indirect
- github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
- github.com/denis-tingaikin/go-header v0.5.0 // indirect
- github.com/docker/cli v29.4.0+incompatible // indirect
- github.com/docker/docker-credential-helpers v0.9.3 // indirect
- github.com/emicklei/go-restful/v3 v3.12.2 // indirect
- github.com/emirpasic/gods v1.18.1 // indirect
- github.com/ettle/strcase v0.2.0 // indirect
- github.com/evanphx/json-patch/v5 v5.9.0 // indirect
- github.com/fatih/color v1.18.0
- github.com/fatih/structtag v1.2.0 // indirect
- github.com/firefart/nonamedreturns v1.0.4 // indirect
- github.com/fsnotify/fsnotify v1.9.0
- github.com/fzipp/gocyclo v0.6.0 // indirect
- github.com/go-critic/go-critic v0.11.2 // indirect
- github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
- github.com/go-git/go-billy/v5 v5.8.0 // indirect
- github.com/go-git/go-git/v5 v5.17.1 // indirect
- github.com/go-logr/logr v1.4.3 // indirect
- github.com/go-openapi/jsonpointer v0.21.0 // indirect
- github.com/go-openapi/jsonreference v0.20.4 // indirect
- github.com/go-openapi/swag v0.23.0 // indirect
- github.com/go-toolsmith/astcast v1.1.0 // indirect
- github.com/go-toolsmith/astcopy v1.1.0 // indirect
- github.com/go-toolsmith/astequal v1.2.0 // indirect
- github.com/go-toolsmith/astfmt v1.1.0 // indirect
- github.com/go-toolsmith/astp v1.1.0 // indirect
- github.com/go-toolsmith/strparse v1.1.0 // indirect
- github.com/go-toolsmith/typep v1.1.0 // indirect
- github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect
- github.com/gobwas/glob v0.2.3 // indirect
- github.com/gofrs/flock v0.12.1 // indirect
- github.com/gogo/protobuf v1.3.2 // indirect
- github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect
- github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e // indirect
- github.com/golangci/misspell v0.4.1 // indirect
- github.com/golangci/revgrep v0.5.2 // indirect
- github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed // indirect
github.com/google/btree v1.1.3 // indirect
- github.com/google/goterm v0.0.0-20200907032337-555d40f16ae2 // indirect
- github.com/google/rpmpack v0.5.0 // indirect
- github.com/gordonklaus/ineffassign v0.1.0 // indirect
- github.com/goreleaser/chglog v0.5.0 // indirect
- github.com/goreleaser/fileglob v1.3.0 // indirect
- github.com/gorilla/csrf v1.7.3
- github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
- github.com/gostaticanalysis/comment v1.4.2 // indirect
- github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect
- github.com/gostaticanalysis/nilerr v0.1.1 // indirect
- github.com/hashicorp/go-version v1.6.0 // indirect
- github.com/hashicorp/hcl v1.0.0 // indirect
- github.com/hexops/gotextdiff v1.0.3 // indirect
- github.com/huandu/xstrings v1.5.0 // indirect
- github.com/imdario/mergo v0.3.16 // indirect
- github.com/inconshreveable/mousetrap v1.1.0 // indirect
- github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
- github.com/jgautheron/goconst v1.7.0 // indirect
- github.com/jingyugao/rowserrcheck v1.1.1 // indirect
- github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect
- github.com/jmespath/go-jmespath v0.4.0 // indirect
- github.com/josharian/intern v1.0.0 // indirect
- github.com/json-iterator/go v1.1.12 // indirect
- github.com/julz/importas v0.1.0 // indirect
- github.com/kevinburke/ssh_config v1.2.0 // indirect
- github.com/kisielk/errcheck v1.7.0 // indirect
- github.com/kkHAIKE/contextcheck v1.1.4 // indirect
- github.com/klauspost/pgzip v1.2.6 // indirect
- github.com/kr/fs v0.1.0 // indirect
- github.com/kr/pretty v0.3.1 // indirect
- github.com/kr/text v0.2.0 // indirect
- github.com/kulti/thelper v0.6.3 // indirect
- github.com/kunwardeep/paralleltest v1.0.10 // indirect
- github.com/kyoh86/exportloopref v0.1.11 // indirect
- github.com/ldez/gomoddirectives v0.2.3 // indirect
- github.com/ldez/tagliatelle v0.5.0 // indirect
- github.com/leonklingele/grouper v1.1.1 // indirect
- github.com/lufeee/execinquery v1.2.1 // indirect
- github.com/magiconair/properties v1.8.7 // indirect
- github.com/mailru/easyjson v0.7.7 // indirect
- github.com/maratori/testableexamples v1.0.0 // indirect
- github.com/maratori/testpackage v1.1.1 // indirect
- github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect
- github.com/mattn/go-runewidth v0.0.14 // indirect
- github.com/mdlayher/socket v0.5.0
- github.com/mgechev/revive v1.3.7 // indirect
- github.com/mitchellh/copystructure v1.2.0 // indirect
- github.com/mitchellh/go-homedir v1.1.0 // indirect
- github.com/mitchellh/mapstructure v1.5.0 // indirect
- github.com/mitchellh/reflectwalk v1.0.2 // indirect
- github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
- github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
- github.com/moricho/tparallel v0.3.1 // indirect
- github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
- github.com/nakabonne/nestif v0.3.1 // indirect
- github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
- github.com/nishanths/exhaustive v0.12.0 // indirect
- github.com/nishanths/predeclared v0.2.2 // indirect
- github.com/nunnatsa/ginkgolinter v0.16.1 // indirect
- github.com/olekukonko/tablewriter v0.0.5 // indirect
- github.com/opencontainers/go-digest v1.0.0 // indirect
- github.com/opencontainers/image-spec v1.1.1 // indirect
- github.com/pelletier/go-toml/v2 v2.2.0 // indirect
- github.com/pierrec/lz4/v4 v4.1.25 // indirect
- github.com/pjbgf/sha1cd v0.3.2 // indirect
- github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e // indirect
- github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
- github.com/polyfloyd/go-errorlint v1.4.8 // indirect
- github.com/prometheus/client_model v0.6.2
- github.com/prometheus/procfs v0.16.1 // indirect
- github.com/quasilyte/go-ruleguard v0.4.2 // indirect
- github.com/quasilyte/gogrep v0.5.0 // indirect
- github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
- github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
- github.com/rivo/uniseg v0.4.4 // indirect
- github.com/rogpeppe/go-internal v1.14.1 // indirect
- github.com/ryancurrah/gomodguard v1.3.1 // indirect
- github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect
- github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect
- github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
- github.com/sashamelentyev/usestdlibvars v1.25.0 // indirect
- github.com/securego/gosec/v2 v2.19.0 // indirect
- github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
- github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect
- github.com/shopspring/decimal v1.4.0 // indirect
- github.com/sirupsen/logrus v1.9.4 // indirect
- github.com/sivchari/containedctx v1.0.3 // indirect
- github.com/sivchari/tenv v1.7.1 // indirect
- github.com/skeema/knownhosts v1.3.1 // indirect
- github.com/sonatard/noctx v0.0.2 // indirect
- github.com/sourcegraph/go-diff v0.7.0
- github.com/spf13/afero v1.11.0 // indirect
- github.com/spf13/cast v1.7.0 // indirect
- github.com/spf13/cobra v1.10.2 // indirect
- github.com/spf13/jwalterweatherman v1.1.0 // indirect
- github.com/spf13/pflag v1.0.10 // indirect
- github.com/spf13/viper v1.16.0 // indirect
- github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
- github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect
- github.com/stretchr/objx v0.5.2 // indirect
- github.com/stretchr/testify v1.11.1
- github.com/subosito/gotenv v1.4.2 // indirect
- github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect
+ github.com/metacubex/bart v0.26.0
+ github.com/metacubex/gvisor v0.0.0-20251227095601-261ec1326fe8
+ github.com/metacubex/tailscale-wireguard-go v0.0.0-20260623093519-06ea214022e4
github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55
- github.com/tdakkota/asciicheck v0.2.0 // indirect
- github.com/tetafro/godot v1.4.16 // indirect
- github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 // indirect
- github.com/timonwong/loggercheck v0.9.4 // indirect
- github.com/tomarrell/wrapcheck/v2 v2.8.3 // indirect
- github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
- github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect
- github.com/ulikunitz/xz v0.5.15
- github.com/ultraware/funlen v0.1.0 // indirect
- github.com/ultraware/whitespace v0.1.0 // indirect
- github.com/uudashr/gocognit v1.1.2 // indirect
- github.com/vbatts/tar-split v0.12.2 // indirect
github.com/x448/float16 v0.8.4 // indirect
- github.com/xanzy/ssh-agent v0.3.3 // indirect
- github.com/yagipy/maintidx v1.0.0 // indirect
- github.com/yeya24/promlinter v0.2.0 // indirect
- gitlab.com/bosi/decorder v0.4.1 // indirect
- gitlab.com/digitalxero/go-conventional-commit v1.0.7 // indirect
- go.uber.org/multierr v1.11.0 // indirect
- golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect
- golang.org/x/image v0.27.0 // indirect
- golang.org/x/text v0.36.0 // indirect
- gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
- google.golang.org/protobuf v1.36.11 // indirect
- gopkg.in/inf.v0 v0.9.1 // indirect
- gopkg.in/ini.v1 v1.67.0 // indirect
- gopkg.in/warnings.v0 v0.1.2 // indirect
- gopkg.in/yaml.v2 v2.4.0 // indirect
- gopkg.in/yaml.v3 v3.0.1
- howett.net/plist v1.0.0 // indirect
- k8s.io/apiextensions-apiserver v0.34.0
- k8s.io/klog/v2 v2.130.1 // indirect
- k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
- k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
- mvdan.cc/gofumpt v0.6.0 // indirect
- mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14 // indirect
- sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
+ golang.org/x/text v0.22.0 // indirect
)
-
-tool github.com/stacklok/frizbee
diff --git a/go.sum b/go.sum
index b5e8950c31940..b80963fd4449f 100644
--- a/go.sum
+++ b/go.sum
@@ -27,6 +27,7 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
+cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
@@ -125,6 +126,7 @@ github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pO
github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE=
github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw=
github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I=
+github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
@@ -235,6 +237,7 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk=
@@ -281,6 +284,7 @@ github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creachadair/mds v0.25.9 h1:080Hr8laN2h+l3NeVCGMBpXtIPnl9mz8e4HLraGPqtA=
github.com/creachadair/mds v0.25.9/go.mod h1:4hatI3hRM+qhzuAmqPRFvaBM8mONkS7nsLxkcuTYUIs=
+github.com/creachadair/msync v0.5.6/go.mod h1:cHf8G0YBAfVk619K3RT7UARb8n6HAOCj0SZf4oUNkyM=
github.com/creachadair/msync v0.7.1 h1:SeZmuEBXQPe5GqV/C94ER7QIZPwtvFbeQiykzt/7uho=
github.com/creachadair/msync v0.7.1/go.mod h1:8CcFlLsSujfHE5wWm19uUBLHIPDAUr6LXDwneVMO008=
github.com/creachadair/taskgroup v0.13.2 h1:3KyqakBuFsm3KkXi/9XIb0QcA8tEzLHLgaoidf0MdVc=
@@ -296,11 +300,10 @@ github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1
github.com/daixiang0/gci v0.12.3 h1:yOZI7VAxAGPQmkb1eqt5g/11SUlwoat1fSblGLmdiQc=
github.com/daixiang0/gci v0.12.3/go.mod h1:xtHP9N7AHdNvtRNfcx9gwTDfw7FRJx4bZUsiEfiNNAI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa h1:h8TfIT1xc8FWbwwpmHn1J5i43Y0uZP97GqasGCzSRJk=
-github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa/go.mod h1:Nx87SkVqTKd8UtT+xu7sM/l+LgXs6c0aHrlKusR+2EQ=
github.com/deckarep/golang-set/v2 v2.8.0 h1:swm0rlPCmdWn9mESxKOjWk8hXSqoxOp+ZlfuyaAdFlQ=
github.com/deckarep/golang-set/v2 v2.8.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
github.com/denis-tingaikin/go-header v0.5.0 h1:SRdnP5ZKvcO9KKRP1KJrhFR3RrlGuD+42t4429eC9k8=
@@ -403,8 +406,6 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs=
github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw=
-github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced h1:Q311OHjMh/u5E2TITc++WlTP5We0xNseRMkHDyvhW7I=
-github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
@@ -562,6 +563,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-containerregistry v0.21.5 h1:KTJG9Pn/jC0VdZR6ctV3/jcN+q6/Iqlx0sTVz3ywZlM=
@@ -765,6 +768,8 @@ github.com/kisielk/errcheck v1.7.0/go.mod h1:1kLL+jV4e+CFfueBmI1dSK2ADDyQnlrnrY/
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt0GMb8=
github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg=
+github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
+github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
@@ -842,6 +847,8 @@ github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxU
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy56gw=
github.com/mdlayher/genetlink v1.3.2/go.mod h1:tcC3pkCrPUGIKKsCsp0B3AdaaKuHtaxoJRz3cc+528o=
+github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
+github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42 h1:A1Cq6Ysb0GM0tpKMbdCXCIfBclan4oHk1Jb+Hrejirg=
github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42/go.mod h1:BB4YCPDOzfy7FniQ/lxuYQ3dgmM2cZumHbK8RpTjN2o=
github.com/mdlayher/packet v1.1.2 h1:3Up1NG6LZrsgDVn6X4L9Ge/iyRyxFEFD9o6Pr3Q1nQY=
@@ -853,6 +860,16 @@ github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI
github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI=
github.com/mdlayher/watchdog v0.0.0-20221003142519-49be0df7b3b5 h1:80FAK3TW5lVymfHu3kvB1QvTZvy9Kmx1lx6sT5Ep16s=
github.com/mdlayher/watchdog v0.0.0-20221003142519-49be0df7b3b5/go.mod h1:z0QjVpjpK4jksEkffQwS3+abQ3XFTm1bnimyDzWyUk0=
+github.com/metacubex/bart v0.26.0 h1:d/bBTvVatfVWGfQbiDpYKI1bXUJgjaabB2KpK1Tnk6w=
+github.com/metacubex/bart v0.26.0/go.mod h1:DCcyfP4MC+Zy7sLK7XeGuMw+P5K9mIRsYOBgiE8icsI=
+github.com/metacubex/edwards25519 v1.2.0 h1:pIQZLBsjQgg3Nl/c86YYFEUAbL5qQRnPq4LrgIw0KK4=
+github.com/metacubex/edwards25519 v1.2.0/go.mod h1:NCQF3J/Ki7382FJuokwsywEIIEI/gro/3smyXgQJsx0=
+github.com/metacubex/gvisor v0.0.0-20251227095601-261ec1326fe8 h1:hUL81H0Ic/XIDkvtn9M1pmfDdfid7JzYQToY4Ps1TvQ=
+github.com/metacubex/gvisor v0.0.0-20251227095601-261ec1326fe8/go.mod h1:8LpS0IJW1VmWzUm3ylb0e2SK5QDm5lO/2qwWLZgRpBU=
+github.com/metacubex/jsonv2 v0.0.0-20260518173308-f4597c22f1df h1:S0vBzqjXok24VopstOgPd1JdgglW9tXehrqvwpQWbQ8=
+github.com/metacubex/jsonv2 v0.0.0-20260518173308-f4597c22f1df/go.mod h1:F4sVXat6QjPXkNsKRDyyG3BhSkxPFFnRPEIwmmyCgbg=
+github.com/metacubex/tailscale-wireguard-go v0.0.0-20260623093519-06ea214022e4 h1:ui12xOUPsCAYwzI7+7Hw2mVhrAbWDGNQZcrBiELhGk0=
+github.com/metacubex/tailscale-wireguard-go v0.0.0-20260623093519-06ea214022e4/go.mod h1:W00EeoPdd2jbV3+ZUa0m2b7FdKx5B1LFsXvEpy7cToQ=
github.com/mgechev/revive v1.3.7 h1:502QY0vQGe9KtYJ9FpxMz9rL+Fc/P13CI5POL4uHCcE=
github.com/mgechev/revive v1.3.7/go.mod h1:RJ16jUbF0OWC3co/+XTxmFNgEpUPwnnA0BRllX2aDNA=
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
@@ -942,8 +959,12 @@ github.com/peterbourgon/ff/v3 v3.4.0 h1:QBvM/rizZM1cB0p0lGMdmR7HxZeI/ZrBWB4DqLkM
github.com/peterbourgon/ff/v3 v3.4.0/go.mod h1:zjJVUhx+twciwfDl0zBcFzl4dW8axCRyXE/eKY9RztQ=
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI=
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
+github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE=
+github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.25 h1:kocOqRffaIbU5djlIBr7Wh+cx82C0vtFb0fOurZHqD0=
github.com/pierrec/lz4/v4 v4.1.25/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4=
+github.com/pires/go-proxyproto v0.8.0 h1:5unRmEAPbHXHuLjDg01CxJWf91cw3lKHc/0xzKpXEe0=
+github.com/pires/go-proxyproto v0.8.0/go.mod h1:iknsfgnH8EkjrMeMyvfKByp9TiBZCKZM0jx2xmKqnVY=
github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0=
github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
@@ -959,6 +980,7 @@ github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo=
github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -988,6 +1010,8 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
+github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
+github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
@@ -1141,6 +1165,8 @@ github.com/tailscale/gokrazy-kernel v0.0.0-20240728225134-3d23beabda2e h1:tyUUge
github.com/tailscale/gokrazy-kernel v0.0.0-20240728225134-3d23beabda2e/go.mod h1:7Mth+m9bq2IHusSsexMNyupHWPL8RxwOuSvBlSGtgDY=
github.com/tailscale/golang-x-crypto v0.0.0-20250404221719-a5573b049869 h1:SRL6irQkKGQKKLzvQP/ke/2ZuB7Py5+XuqtOgSj+iMM=
github.com/tailscale/golang-x-crypto v0.0.0-20250404221719-a5573b049869/go.mod h1:ikbF+YT089eInTp9f2vmvy4+ZVnW5hzX1q2WknxSprQ=
+github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a h1:SJy1Pu0eH1C29XwJucQo73FrleVK6t4kYz4NVhp34Yw=
+github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a/go.mod h1:DFSS3NAGHthKo1gTlmEcSBiZrRJXi28rLNd/1udP1c8=
github.com/tailscale/hujson v0.0.0-20260302212456-ecc657c15afd h1:Rf9uhF1+VJ7ZHqxrG8pJ6YacmHvVCmByDmGbAWCc/gA=
github.com/tailscale/hujson v0.0.0-20260302212456-ecc657c15afd/go.mod h1:EbW0wDK/qEUYI0A5bqq0C2kF8JTQwWONmGDBbzsxxHo=
github.com/tailscale/mkctr v0.0.0-20260107121656-ea857e3e500b h1:QKqCnmp0qHWUHySySKjpuhZANzRn7XrTVZWUuUgJ3lQ=
@@ -1157,16 +1183,12 @@ github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 h1:U
github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976/go.mod h1:agQPE6y6ldqCOui2gkIh7ZMztTkIQKH049tv8siLuNQ=
github.com/tailscale/wf v0.0.0-20240214030419-6fbb0a674ee6 h1:l10Gi6w9jxvinoiq15g8OToDdASBni4CyJOdHY1Hr8M=
github.com/tailscale/wf v0.0.0-20240214030419-6fbb0a674ee6/go.mod h1:ZXRML051h7o4OcI0d3AaILDIad/Xw0IkXaHM17dic1Y=
-github.com/tailscale/wireguard-go v0.0.0-20260427181203-e3ac4a0afb4e h1:GexFR7ak1iz26fxg8HWCpOEqAOL8UEZJ7J3JxeCalDs=
-github.com/tailscale/wireguard-go v0.0.0-20260427181203-e3ac4a0afb4e/go.mod h1:6SerzcvHWQchKO2BfNdmquA77CHSECZuFl+D9fp4RnI=
github.com/tailscale/xnet v0.0.0-20240729143630-8497ac4dab2e h1:zOGKqN5D5hHhiYUp091JqK7DPCqSARyUfduhGUY8Bek=
github.com/tailscale/xnet v0.0.0-20240729143630-8497ac4dab2e/go.mod h1:orPd6JZXXRyuDusYilywte7k094d7dycXXU5YnWsrwg=
github.com/tc-hib/winres v0.2.1 h1:YDE0FiP0VmtRaDn7+aaChp1KiF4owBiJa5l964l5ujA=
github.com/tc-hib/winres v0.2.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk=
github.com/tcnksm/go-httpstat v0.2.0 h1:rP7T5e5U2HfmOBmZzGgGZjBQ5/GluWUylujl0tJ04I0=
github.com/tcnksm/go-httpstat v0.2.0/go.mod h1:s3JVJFtQxtBEBC9dwcdTTXS9xFnM3SXAZwPG41aurT8=
-github.com/tdakkota/asciicheck v0.2.0 h1:o8jvnUANo0qXtnslk2d3nMKTFNlOnJjRrNcj0j9qkHM=
-github.com/tdakkota/asciicheck v0.2.0/go.mod h1:Qb7Y9EgjCLJGup51gDHFzbI08/gbGhL/UVhYIPWG2rg=
github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA=
github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0=
github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag=
@@ -1190,8 +1212,8 @@ github.com/u-root/gobusybox/src v0.0.0-20240225013946-a274a8d5d83a h1:eg5FkNoQp7
github.com/u-root/gobusybox/src v0.0.0-20240225013946-a274a8d5d83a/go.mod h1:e/8TmrdreH0sZOw2DFKBaUV7bvDWRq6SeM9PzkuVM68=
github.com/u-root/u-root v0.14.0 h1:Ka4T10EEML7dQ5XDvO9c3MBN8z4nuSnGjcd1jmU2ivg=
github.com/u-root/u-root v0.14.0/go.mod h1:hAyZorapJe4qzbLWlAkmSVCJGbfoU9Pu4jpJ1WMluqE=
-github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 h1:pyC9PaHYZFgEKFdlp3G8RaCKgVpHZnecvArXvPXcFkM=
-github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701/go.mod h1:P3a5rG4X7tI17Nn3aOIAYr5HbIMukwXG0urG0WuL8OA=
+github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 h1:tHNk7XK9GkmKUR6Gh8gVBKXc2MVSZ4G/NnWLtzw4gNA=
+github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY=
github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ultraware/funlen v0.1.0 h1:BuqclbkY6pO+cvxoq7OsktIXZpgBSkYTQtmwhAK81vI=
@@ -1319,6 +1341,12 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
+golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
+golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
+golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
+golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
+golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
+golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
golang.org/x/crypto/x509roots/fallback v0.0.0-20260113154411-7d0074ccc6f1 h1:EBHQuS9qI8xJ96+YRgVV2ahFLUYbWpt1rf3wPfXN2wQ=
@@ -1333,8 +1361,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
-golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=
-golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
+golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk=
+golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f h1:phY1HzDcf18Aq9A8KkmRtY9WvOFIxN8wgfvy6Zm1DV8=
@@ -1370,6 +1398,10 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1411,6 +1443,13 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
+golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
+golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
+golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
+golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
+golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -1419,6 +1458,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
+golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1434,6 +1475,12 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
+golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1500,9 +1547,18 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
+golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
+golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
+golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
golang.org/x/telemetry v0.0.0-20260409153401-be6f6cb8b1fa h1:efT73AJZfAAUV7SOip6pWGkwJDzIGiKBZGVzHYa+ve4=
golang.org/x/telemetry v0.0.0-20260409153401-be6f6cb8b1fa/go.mod h1:kHjTxDEnAu6/Nl9lDkzjWpR+bmKfxeiRuSDlsMb70gE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -1511,6 +1567,13 @@ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
+golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
+golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
+golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
+golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
+golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1523,11 +1586,20 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
+golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
+golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -1594,6 +1666,9 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
+golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
+golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c=
golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI=
golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM=
@@ -1606,10 +1681,6 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk=
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
-golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
-golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
-golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE=
-golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI=
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
@@ -1693,6 +1764,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
+google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
diff --git a/gokrazy/gokrazy_test.go b/gokrazy/gokrazy_test.go
index 76398d49bf594..94ad50647a628 100644
--- a/gokrazy/gokrazy_test.go
+++ b/gokrazy/gokrazy_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/gokrazy/natlabapp.arm64/gokrazydeps.go b/gokrazy/natlabapp.arm64/gokrazydeps.go
index 001ab89b840ea..a7bd4b27d0a84 100644
--- a/gokrazy/natlabapp.arm64/gokrazydeps.go
+++ b/gokrazy/natlabapp.arm64/gokrazydeps.go
@@ -6,11 +6,11 @@
package gokrazydeps
import (
+ _ "github.com/metacubex/tailscale/cmd/tailscale"
+ _ "github.com/metacubex/tailscale/cmd/tailscaled"
+ _ "github.com/metacubex/tailscale/cmd/tta"
_ "github.com/gokrazy/gokrazy/cmd/dhcp"
_ "github.com/gokrazy/kernel.arm64"
_ "github.com/gokrazy/serial-busybox"
_ "github.com/tailscale/ts-gokrazy/gokrazyinit"
- _ "tailscale.com/cmd/tailscale"
- _ "tailscale.com/cmd/tailscaled"
- _ "tailscale.com/cmd/tta"
)
diff --git a/gokrazy/natlabapp/gokrazydeps.go b/gokrazy/natlabapp/gokrazydeps.go
index 2e4c1361c48ce..027fc4acfb498 100644
--- a/gokrazy/natlabapp/gokrazydeps.go
+++ b/gokrazy/natlabapp/gokrazydeps.go
@@ -6,11 +6,11 @@
package gokrazydeps
import (
+ _ "github.com/metacubex/tailscale/cmd/tailscale"
+ _ "github.com/metacubex/tailscale/cmd/tailscaled"
+ _ "github.com/metacubex/tailscale/cmd/tta"
_ "github.com/gokrazy/gokrazy/cmd/dhcp"
_ "github.com/gokrazy/serial-busybox"
_ "github.com/tailscale/gokrazy-kernel"
_ "github.com/tailscale/ts-gokrazy/gokrazyinit"
- _ "tailscale.com/cmd/tailscale"
- _ "tailscale.com/cmd/tailscaled"
- _ "tailscale.com/cmd/tta"
)
diff --git a/gokrazy/tsapp/gokrazydeps.go b/gokrazy/tsapp/gokrazydeps.go
index 22bdc3a499425..f25e8a56dc237 100644
--- a/gokrazy/tsapp/gokrazydeps.go
+++ b/gokrazy/tsapp/gokrazydeps.go
@@ -6,6 +6,8 @@
package gokrazydeps
import (
+ _ "github.com/metacubex/tailscale/cmd/tailscale"
+ _ "github.com/metacubex/tailscale/cmd/tailscaled"
_ "github.com/gokrazy/breakglass"
_ "github.com/gokrazy/gokrazy/cmd/dhcp"
_ "github.com/gokrazy/gokrazy/cmd/ntp"
@@ -13,6 +15,4 @@ import (
_ "github.com/gokrazy/serial-busybox"
_ "github.com/tailscale/gokrazy-kernel"
_ "github.com/tailscale/ts-gokrazy/gokrazyinit"
- _ "tailscale.com/cmd/tailscale"
- _ "tailscale.com/cmd/tailscaled"
)
diff --git a/gomod_test.go b/gomod_test.go
index a9a3c437d9341..4a10d39e4044e 100644
--- a/gomod_test.go
+++ b/gomod_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/health/health.go b/health/health.go
index 1829bd482ad6f..7a79537f9fbc4 100644
--- a/health/health.go
+++ b/health/health.go
@@ -9,7 +9,7 @@ import (
"context"
"errors"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"net/http"
"os"
"runtime"
@@ -18,16 +18,16 @@ import (
"sync/atomic"
"time"
- "tailscale.com/envknob"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/types/opt"
- "tailscale.com/util/cibuild"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/mak"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/util/cibuild"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/version"
)
var (
@@ -170,7 +170,9 @@ func (t *Tracker) awaitEventClientDone(ec *eventbus.Client) {
timer.Stop()
}
t.timer.Stop()
- clear(t.pendingVisibleTimers)
+ for k := range t.pendingVisibleTimers {
+ delete(t.pendingVisibleTimers, k)
+ }
}
func (t *Tracker) now() time.Time {
diff --git a/health/health_test.go b/health/health_test.go
index ccd49b19af360..dd2f6131afc37 100644
--- a/health/health_test.go
+++ b/health/health_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,9 +9,9 @@ import (
"errors"
"flag"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"reflect"
- "slices"
"strconv"
"testing"
"testing/synctest"
@@ -17,16 +19,16 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/metrics"
- "tailscale.com/tailcfg"
- "tailscale.com/tsconst"
- "tailscale.com/tstest"
- "tailscale.com/tstime"
- "tailscale.com/types/opt"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/usermetric"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/metrics"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsconst"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/usermetric"
+ "github.com/metacubex/tailscale/version"
)
var doDebug = flag.Bool("debug", false, "Enable debug logging")
diff --git a/health/healthmsg/healthmsg.go b/health/healthmsg/healthmsg.go
index c6efb0d574db4..08c9a14942fcc 100644
--- a/health/healthmsg/healthmsg.go
+++ b/health/healthmsg/healthmsg.go
@@ -10,6 +10,6 @@ package healthmsg
const (
WarnAcceptRoutesOff = "Some peers are advertising routes but --accept-routes is false"
TailscaleSSHOnBut = "Tailscale SSH enabled, but " // + ... something from caller
- LockedOut = "this node is locked out; it will not have connectivity until it is signed. For more info, see https://tailscale.com/s/locked-out"
- InMemoryTailnetLockState = "Tailnet Lock state is only being stored in-memory. Set --statedir to store state on disk, which is more secure. See https://tailscale.com/kb/1226/tailnet-lock#tailnet-lock-state"
+ LockedOut = "this node is locked out; it will not have connectivity until it is signed. For more info, see https://github.com/metacubex/tailscale/s/locked-out"
+ InMemoryTailnetLockState = "Tailnet Lock state is only being stored in-memory. Set --statedir to store state on disk, which is more secure. See https://github.com/metacubex/tailscale/kb/1226/tailnet-lock#tailnet-lock-state"
)
diff --git a/health/state.go b/health/state.go
index 61d36797ceaf0..56157c5e6b15d 100644
--- a/health/state.go
+++ b/health/state.go
@@ -9,9 +9,9 @@ import (
"encoding/json"
"time"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/tailcfg"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/mak"
)
// State contains the health status of the backend, and is
diff --git a/health/usermetrics.go b/health/usermetrics.go
index b1af0c5852010..a763861593a68 100644
--- a/health/usermetrics.go
+++ b/health/usermetrics.go
@@ -1,15 +1,15 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_health && !ts_omit_usermetrics
+//go:build !ts_omit_health && ts_enable_usermetrics
package health
import (
"expvar"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/util/usermetric"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/util/usermetric"
)
const MetricLabelWarning = "warning"
diff --git a/health/usermetrics_omit.go b/health/usermetrics_omit.go
index 8a37d8ad8a311..a4be121b8542f 100644
--- a/health/usermetrics_omit.go
+++ b/health/usermetrics_omit.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build ts_omit_health || ts_omit_usermetrics
+//go:build ts_omit_health || !ts_enable_usermetrics
package health
diff --git a/health/warnings.go b/health/warnings.go
index 416cb8ab0cc70..93164edac792b 100644
--- a/health/warnings.go
+++ b/health/warnings.go
@@ -8,9 +8,9 @@ import (
"runtime"
"time"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/tsconst"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/tsconst"
+ "github.com/metacubex/tailscale/version"
)
func condRegister(f func() *Warnable) *Warnable {
diff --git a/hostinfo/hostinfo.go b/hostinfo/hostinfo.go
index 11b0a25ccc238..06c75ca6b3668 100644
--- a/hostinfo/hostinfo.go
+++ b/hostinfo/hostinfo.go
@@ -18,16 +18,17 @@ import (
"sync/atomic"
"time"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/result"
+ "github.com/metacubex/tailscale/util/cloudenv"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/lineiter"
+ "github.com/metacubex/tailscale/version"
+ "github.com/metacubex/tailscale/version/distro"
"go4.org/mem"
- "tailscale.com/envknob"
- "tailscale.com/tailcfg"
- "tailscale.com/types/lazy"
- "tailscale.com/types/opt"
- "tailscale.com/util/cloudenv"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/lineiter"
- "tailscale.com/version"
- "tailscale.com/version/distro"
)
var started = time.Now()
@@ -83,6 +84,10 @@ var (
deviceModel func() string
)
+func funcPtr[T any](fn func() T) *func() T {
+ return &fn
+}
+
func condCall[T any](fn func() T) T {
var zero T
if fn == nil {
@@ -92,8 +97,8 @@ func condCall[T any](fn func() T) T {
}
var (
- lazyInContainer = &lazyAtomicValue[opt.Bool]{f: new(inContainer)}
- lazyGoArchVar = &lazyAtomicValue[string]{f: new(goArchVar)}
+ lazyInContainer = &lazyAtomicValue[opt.Bool]{f: funcPtr(inContainer)}
+ lazyGoArchVar = &lazyAtomicValue[string]{f: funcPtr(goArchVar)}
)
type lazyAtomicValue[T any] struct {
@@ -242,11 +247,12 @@ func desktop() (ret opt.Bool) {
}
seenDesktop := false
- for lr := range lineiter.File("/proc/net/unix") {
+ lineiter.File("/proc/net/unix")(func(lr result.Of[[]byte]) bool {
line, _ := lr.Value()
seenDesktop = seenDesktop || mem.Contains(mem.B(line), mem.S(".X11-unix"))
seenDesktop = seenDesktop || mem.Contains(mem.B(line), mem.S("/wayland-1"))
- }
+ return true
+ })
ret.Set(seenDesktop)
// Only cache after a minute - compositors might not have started yet.
@@ -315,21 +321,23 @@ func inContainer() opt.Bool {
ret.Set(true)
return ret
}
- for lr := range lineiter.File("/proc/1/cgroup") {
+ lineiter.File("/proc/1/cgroup")(func(lr result.Of[[]byte]) bool {
line, _ := lr.Value()
if mem.Contains(mem.B(line), mem.S("/docker/")) ||
mem.Contains(mem.B(line), mem.S("/lxc/")) {
ret.Set(true)
- break
+ return false
}
- }
- for lr := range lineiter.File("/proc/mounts") {
+ return true
+ })
+ lineiter.File("/proc/mounts")(func(lr result.Of[[]byte]) bool {
line, _ := lr.Value()
if mem.Contains(mem.B(line), mem.S("lxcfs /proc/cpuinfo fuse.lxcfs")) {
ret.Set(true)
- break
+ return false
}
- }
+ return true
+ })
return ret
}
diff --git a/hostinfo/hostinfo_container_linux_test.go b/hostinfo/hostinfo_container_linux_test.go
index 0c14776e712b7..acc1f117b9e42 100644
--- a/hostinfo/hostinfo_container_linux_test.go
+++ b/hostinfo/hostinfo_container_linux_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux && !android && ts_package_container
-
package hostinfo
import (
diff --git a/hostinfo/hostinfo_darwin.go b/hostinfo/hostinfo_darwin.go
index 338ab9792c215..ca40c4bbcab75 100644
--- a/hostinfo/hostinfo_darwin.go
+++ b/hostinfo/hostinfo_darwin.go
@@ -18,7 +18,7 @@ func init() {
}
var (
- lazyOSVersion = &lazyAtomicValue[string]{f: new(osVersionDarwin)}
+ lazyOSVersion = &lazyAtomicValue[string]{f: funcPtr(osVersionDarwin)}
)
func packageTypeDarwin() string {
diff --git a/hostinfo/hostinfo_freebsd.go b/hostinfo/hostinfo_freebsd.go
index 580d97a6d1027..7a739636b6715 100644
--- a/hostinfo/hostinfo_freebsd.go
+++ b/hostinfo/hostinfo_freebsd.go
@@ -10,8 +10,8 @@ import (
"os"
"os/exec"
+ "github.com/metacubex/tailscale/version/distro"
"golang.org/x/sys/unix"
- "tailscale.com/version/distro"
)
func init() {
@@ -21,8 +21,8 @@ func init() {
}
var (
- lazyVersionMeta = &lazyAtomicValue[versionMeta]{f: new(freebsdVersionMeta)}
- lazyOSVersion = &lazyAtomicValue[string]{f: new(osVersionFreeBSD)}
+ lazyVersionMeta = &lazyAtomicValue[versionMeta]{f: funcPtr(freebsdVersionMeta)}
+ lazyOSVersion = &lazyAtomicValue[string]{f: funcPtr(osVersionFreeBSD)}
)
func distroNameFreeBSD() string {
diff --git a/hostinfo/hostinfo_linux.go b/hostinfo/hostinfo_linux.go
index 6b21d81529264..a0dcb42dda3cb 100644
--- a/hostinfo/hostinfo_linux.go
+++ b/hostinfo/hostinfo_linux.go
@@ -10,9 +10,10 @@ import (
"os"
"strings"
+ "github.com/metacubex/tailscale/types/result"
+ "github.com/metacubex/tailscale/util/lineiter"
+ "github.com/metacubex/tailscale/version/distro"
"golang.org/x/sys/unix"
- "tailscale.com/util/lineiter"
- "tailscale.com/version/distro"
)
func init() {
@@ -25,8 +26,8 @@ func init() {
}
var (
- lazyVersionMeta = &lazyAtomicValue[versionMeta]{f: new(linuxVersionMeta)}
- lazyOSVersion = &lazyAtomicValue[string]{f: new(osVersionLinux)}
+ lazyVersionMeta = &lazyAtomicValue[versionMeta]{f: funcPtr(linuxVersionMeta)}
+ lazyOSVersion = &lazyAtomicValue[string]{f: funcPtr(osVersionLinux)}
)
type versionMeta struct {
@@ -68,7 +69,7 @@ func deviceModelLinux() string {
}
func getQnapQtsVersion(versionInfo string) string {
- for field := range strings.FieldsSeq(versionInfo) {
+ for _, field := range strings.Fields(versionInfo) {
if suffix, ok := strings.CutPrefix(field, "QTSFW_"); ok {
return suffix
}
@@ -105,18 +106,19 @@ func linuxVersionMeta() (meta versionMeta) {
}
m := map[string]string{}
- for lr := range lineiter.File(propFile) {
+ lineiter.File(propFile)(func(lr result.Of[[]byte]) bool {
line, err := lr.Value()
if err != nil {
- break
+ return false
}
before, after, ok := bytes.Cut(line, []byte{'='})
if !ok {
- continue
+ return true
}
k, v := string(before), strings.Trim(string(after), `"'`)
m[k] = v
- }
+ return true
+ })
if v := m["VERSION_CODENAME"]; v != "" {
meta.DistroCodeName = v
diff --git a/hostinfo/hostinfo_linux_test.go b/hostinfo/hostinfo_linux_test.go
index ebf285e94baeb..588c4a38f0f64 100644
--- a/hostinfo/hostinfo_linux_test.go
+++ b/hostinfo/hostinfo_linux_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux && !android && !ts_package_container
-
package hostinfo
import (
diff --git a/hostinfo/hostinfo_plan9.go b/hostinfo/hostinfo_plan9.go
index 27a2543b38ff0..30a749e2a0230 100644
--- a/hostinfo/hostinfo_plan9.go
+++ b/hostinfo/hostinfo_plan9.go
@@ -8,8 +8,8 @@ import (
"os"
"strings"
- "tailscale.com/tailcfg"
- "tailscale.com/types/lazy"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/lazy"
)
func init() {
diff --git a/hostinfo/hostinfo_test.go b/hostinfo/hostinfo_test.go
index 6508d5d995e3b..703960c75e4ce 100644
--- a/hostinfo/hostinfo_test.go
+++ b/hostinfo/hostinfo_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/hostinfo/hostinfo_uname.go b/hostinfo/hostinfo_uname.go
index 0185da49d8bc9..7b79d320d3cd9 100644
--- a/hostinfo/hostinfo_uname.go
+++ b/hostinfo/hostinfo_uname.go
@@ -15,7 +15,7 @@ func init() {
unameMachine = lazyUnameMachine.Get
}
-var lazyUnameMachine = &lazyAtomicValue[string]{f: new(unameMachineUnix)}
+var lazyUnameMachine = &lazyAtomicValue[string]{f: funcPtr(unameMachineUnix)}
func unameMachineUnix() string {
switch runtime.GOOS {
diff --git a/hostinfo/hostinfo_windows.go b/hostinfo/hostinfo_windows.go
index 59b57433e0c65..1ff9c8fd9ef77 100644
--- a/hostinfo/hostinfo_windows.go
+++ b/hostinfo/hostinfo_windows.go
@@ -9,10 +9,10 @@ import (
"path/filepath"
"strings"
+ "github.com/metacubex/tailscale/util/winutil"
+ "github.com/metacubex/tailscale/util/winutil/winenv"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
- "tailscale.com/util/winutil"
- "tailscale.com/util/winutil/winenv"
)
func init() {
@@ -22,9 +22,9 @@ func init() {
}
var (
- lazyDistroName = &lazyAtomicValue[string]{f: new(distroNameWindows)}
- lazyOSVersion = &lazyAtomicValue[string]{f: new(osVersionWindows)}
- lazyPackageType = &lazyAtomicValue[string]{f: new(packageTypeWindows)}
+ lazyDistroName = &lazyAtomicValue[string]{f: funcPtr(distroNameWindows)}
+ lazyOSVersion = &lazyAtomicValue[string]{f: funcPtr(osVersionWindows)}
+ lazyPackageType = &lazyAtomicValue[string]{f: funcPtr(packageTypeWindows)}
)
func distroNameWindows() string {
diff --git a/internal/client/tailscale/awsparamstore.go b/internal/client/tailscale/awsparamstore.go
index bb0a31d45cc8a..89aa546e4efd8 100644
--- a/internal/client/tailscale/awsparamstore.go
+++ b/internal/client/tailscale/awsparamstore.go
@@ -6,7 +6,7 @@ package tailscale
import (
"context"
- "tailscale.com/feature"
+ "github.com/metacubex/tailscale/feature"
)
// ResolvePrefixAWSParameterStore is the string prefix for values that can be
diff --git a/internal/client/tailscale/identityfederation.go b/internal/client/tailscale/identityfederation.go
index 8c60c1c3c59a5..6d192b8800d21 100644
--- a/internal/client/tailscale/identityfederation.go
+++ b/internal/client/tailscale/identityfederation.go
@@ -6,7 +6,7 @@ package tailscale
import (
"context"
- "tailscale.com/feature"
+ "github.com/metacubex/tailscale/feature"
)
// HookResolveAuthKeyViaWIF resolves to [identityfederation.resolveAuthKey] when the
diff --git a/internal/client/tailscale/oauthkeys.go b/internal/client/tailscale/oauthkeys.go
index 43d5b0744fefe..cc4209098a97b 100644
--- a/internal/client/tailscale/oauthkeys.go
+++ b/internal/client/tailscale/oauthkeys.go
@@ -6,7 +6,7 @@ package tailscale
import (
"context"
- "tailscale.com/feature"
+ "github.com/metacubex/tailscale/feature"
)
// HookResolveAuthKey resolves to [oauthkey.ResolveAuthKey] when the
diff --git a/internal/client/tailscale/tailscale.go b/internal/client/tailscale/tailscale.go
index 1e6b576fb0cc1..b38f4943039c8 100644
--- a/internal/client/tailscale/tailscale.go
+++ b/internal/client/tailscale/tailscale.go
@@ -12,7 +12,7 @@ import (
"io"
"net/http"
- tsclient "tailscale.com/client/tailscale"
+ tsclient "github.com/metacubex/tailscale/client/tailscale"
)
// maxSize is the maximum read size (10MB) of responses from the server.
@@ -22,46 +22,46 @@ func init() {
tsclient.I_Acknowledge_This_API_Is_Unstable = true
}
-// AuthMethod is an alias to tailscale.com/client/tailscale.
+// AuthMethod is an alias to github.com/metacubex/tailscale/client/tailscale.
type AuthMethod = tsclient.AuthMethod
-// APIKey is an alias to tailscale.com/client/tailscale.
+// APIKey is an alias to github.com/metacubex/tailscale/client/tailscale.
type APIKey = tsclient.APIKey
-// Device is an alias to tailscale.com/client/tailscale.
+// Device is an alias to github.com/metacubex/tailscale/client/tailscale.
type Device = tsclient.Device
-// DeviceFieldsOpts is an alias to tailscale.com/client/tailscale.
+// DeviceFieldsOpts is an alias to github.com/metacubex/tailscale/client/tailscale.
type DeviceFieldsOpts = tsclient.DeviceFieldsOpts
-// Key is an alias to tailscale.com/client/tailscale.
+// Key is an alias to github.com/metacubex/tailscale/client/tailscale.
type Key = tsclient.Key
-// KeyCapabilities is an alias to tailscale.com/client/tailscale.
+// KeyCapabilities is an alias to github.com/metacubex/tailscale/client/tailscale.
type KeyCapabilities = tsclient.KeyCapabilities
-// KeyDeviceCapabilities is an alias to tailscale.com/client/tailscale.
+// KeyDeviceCapabilities is an alias to github.com/metacubex/tailscale/client/tailscale.
type KeyDeviceCapabilities = tsclient.KeyDeviceCapabilities
-// KeyDeviceCreateCapabilities is an alias to tailscale.com/client/tailscale.
+// KeyDeviceCreateCapabilities is an alias to github.com/metacubex/tailscale/client/tailscale.
type KeyDeviceCreateCapabilities = tsclient.KeyDeviceCreateCapabilities
-// ErrResponse is an alias to tailscale.com/client/tailscale.
+// ErrResponse is an alias to github.com/metacubex/tailscale/client/tailscale.
type ErrResponse = tsclient.ErrResponse
-// NewClient is an alias to tailscale.com/client/tailscale.
+// NewClient is an alias to github.com/metacubex/tailscale/client/tailscale.
func NewClient(tailnet string, auth AuthMethod) *Client {
return &Client{
Client: tsclient.NewClient(tailnet, auth),
}
}
-// Client is a wrapper of tailscale.com/client/tailscale.
+// Client is a wrapper of github.com/metacubex/tailscale/client/tailscale.
type Client struct {
*tsclient.Client
}
-// HandleErrorResponse is an alias to tailscale.com/client/tailscale.
+// HandleErrorResponse is an alias to github.com/metacubex/tailscale/client/tailscale.
func HandleErrorResponse(b []byte, resp *http.Response) error {
return tsclient.HandleErrorResponse(b, resp)
}
diff --git a/internal/client/tailscale/vip_service.go b/internal/client/tailscale/vip_service.go
index 5c35a0c299621..46e78b5f9ae40 100644
--- a/internal/client/tailscale/vip_service.go
+++ b/internal/client/tailscale/vip_service.go
@@ -10,8 +10,8 @@ import (
"fmt"
"net/http"
- "tailscale.com/tailcfg"
- "tailscale.com/util/httpm"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/httpm"
)
// VIPService is a Tailscale VIPService with Tailscale API JSON representation.
diff --git a/ipn/auditlog/auditlog.go b/ipn/auditlog/auditlog.go
index 0d6bd278d1996..905c7646bf90f 100644
--- a/ipn/auditlog/auditlog.go
+++ b/ipn/auditlog/auditlog.go
@@ -13,11 +13,11 @@ import (
"sync"
"time"
- "tailscale.com/ipn"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
- "tailscale.com/util/rands"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/rands"
+ "github.com/metacubex/tailscale/util/set"
)
// transaction represents an audit log that has not yet been sent to the control plane.
diff --git a/ipn/auditlog/auditlog_test.go b/ipn/auditlog/auditlog_test.go
index 5e499cc674fcb..fa1719c3225ee 100644
--- a/ipn/auditlog/auditlog_test.go
+++ b/ipn/auditlog/auditlog_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,9 +14,9 @@ import (
"time"
qt "github.com/frankban/quicktest"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
)
// loggerForTest creates an auditLogger for you and cleans it up
diff --git a/ipn/auditlog/extension.go b/ipn/auditlog/extension.go
index 293d3742c97f9..bf9a058da00e8 100644
--- a/ipn/auditlog/extension.go
+++ b/ipn/auditlog/extension.go
@@ -9,15 +9,15 @@ import (
"fmt"
"time"
- "tailscale.com/control/controlclient"
- "tailscale.com/feature"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnauth"
- "tailscale.com/ipn/ipnext"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/types/lazy"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/control/controlclient"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
+ "github.com/metacubex/tailscale/ipn/ipnext"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/types/logger"
)
// featureName is the name of the feature implemented by this package.
diff --git a/ipn/auditlog/store.go b/ipn/auditlog/store.go
index 07c9717726147..094fa4a86d392 100644
--- a/ipn/auditlog/store.go
+++ b/ipn/auditlog/store.go
@@ -9,10 +9,10 @@ import (
"path/filepath"
"runtime"
- "tailscale.com/ipn/store"
- "tailscale.com/types/lazy"
- "tailscale.com/types/logger"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/ipn/store"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/must"
)
var storeFilePath lazy.SyncValue[string]
diff --git a/ipn/backend.go b/ipn/backend.go
index 51617e08e575d..906cc7cfdd33f 100644
--- a/ipn/backend.go
+++ b/ipn/backend.go
@@ -8,15 +8,15 @@ import (
"strings"
"time"
- "tailscale.com/drive"
- "tailscale.com/health"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/types/empty"
- "tailscale.com/types/key"
- "tailscale.com/types/netmap"
- "tailscale.com/types/structs"
- "tailscale.com/types/views"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/empty"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/structs"
+ "github.com/metacubex/tailscale/types/views"
)
type State int
diff --git a/ipn/backend_test.go b/ipn/backend_test.go
index bfb6d6bc41540..1c0c6d46da293 100644
--- a/ipn/backend_test.go
+++ b/ipn/backend_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,8 +8,8 @@ package ipn
import (
"testing"
- "tailscale.com/health"
- "tailscale.com/types/empty"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/types/empty"
)
func TestNotifyString(t *testing.T) {
diff --git a/ipn/conf.go b/ipn/conf.go
index de127a28a0d7b..0d6e4ba68e4a8 100644
--- a/ipn/conf.go
+++ b/ipn/conf.go
@@ -8,9 +8,9 @@ import (
"fmt"
"net/netip"
- "tailscale.com/tailcfg"
- "tailscale.com/types/opt"
- "tailscale.com/types/preftype"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/preftype"
)
// ConfigVAlpha is the config file format for the "alpha0" version.
diff --git a/ipn/conf_test.go b/ipn/conf_test.go
index 41b5c4506f827..b3ac9f4c73269 100644
--- a/ipn/conf_test.go
+++ b/ipn/conf_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/ipn/conffile/cloudconf.go b/ipn/conffile/cloudconf.go
index ac9f640c34275..83612b726c375 100644
--- a/ipn/conffile/cloudconf.go
+++ b/ipn/conffile/cloudconf.go
@@ -10,9 +10,9 @@ import (
"net/http"
"strings"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/omit"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/omit"
)
func getEC2MetadataToken() (string, error) {
diff --git a/ipn/conffile/conffile.go b/ipn/conffile/conffile.go
index c221a3d8c8d94..c2a1c5b45cc47 100644
--- a/ipn/conffile/conffile.go
+++ b/ipn/conffile/conffile.go
@@ -12,8 +12,8 @@ import (
"os"
"runtime"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/ipn"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/ipn"
)
// Config describes a config file.
diff --git a/ipn/conffile/serveconf.go b/ipn/conffile/serveconf.go
index 0d336029246f4..0d73e445fa25a 100644
--- a/ipn/conffile/serveconf.go
+++ b/ipn/conffile/serveconf.go
@@ -13,11 +13,11 @@ import (
"path"
"strings"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/tailcfg"
- "tailscale.com/types/opt"
- "tailscale.com/util/mak"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/util/mak"
)
// ServicesConfigFile is the config file format for services configuration.
diff --git a/ipn/desktop/extension.go b/ipn/desktop/extension.go
index 3e96a9c4c7929..c292be33f949f 100644
--- a/ipn/desktop/extension.go
+++ b/ipn/desktop/extension.go
@@ -10,16 +10,16 @@
package desktop
import (
- "cmp"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"sync"
- "tailscale.com/feature"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnext"
- "tailscale.com/types/logger"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnext"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
// featureName is the name of the feature implemented by this package.
diff --git a/ipn/desktop/session.go b/ipn/desktop/session.go
index b5656d99bd4f2..7695e1115ece6 100644
--- a/ipn/desktop/session.go
+++ b/ipn/desktop/session.go
@@ -6,7 +6,7 @@ package desktop
import (
"fmt"
- "tailscale.com/ipn/ipnauth"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
)
// SessionID is a unique identifier of a desktop session.
diff --git a/ipn/desktop/sessions_notwindows.go b/ipn/desktop/sessions_notwindows.go
index 396d57eff39b2..94b90a1651f4c 100644
--- a/ipn/desktop/sessions_notwindows.go
+++ b/ipn/desktop/sessions_notwindows.go
@@ -5,7 +5,7 @@
package desktop
-import "tailscale.com/types/logger"
+import "github.com/metacubex/tailscale/types/logger"
// NewSessionManager returns a new [SessionManager] for the current platform,
// [ErrNotImplemented] if the platform is not supported, or an error if the
diff --git a/ipn/desktop/sessions_windows.go b/ipn/desktop/sessions_windows.go
index 7d51900f9f730..0707606f65738 100644
--- a/ipn/desktop/sessions_windows.go
+++ b/ipn/desktop/sessions_windows.go
@@ -12,11 +12,11 @@ import (
"syscall"
"unsafe"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/set"
"golang.org/x/sys/windows"
- "tailscale.com/ipn/ipnauth"
- "tailscale.com/types/logger"
- "tailscale.com/util/must"
- "tailscale.com/util/set"
)
// wtsManager is a [SessionManager] implementation for Windows.
diff --git a/ipn/doc.go b/ipn/doc.go
index b39310cf51b4b..8d755ca4f7159 100644
--- a/ipn/doc.go
+++ b/ipn/doc.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:generate go run tailscale.com/cmd/viewer -type=LoginProfile,Prefs,ServeConfig,ServiceConfig,TCPPortHandler,HTTPHandler,WebServerConfig
+//go:generate go run github.com/metacubex/tailscale/cmd/viewer -type=LoginProfile,Prefs,ServeConfig,ServiceConfig,TCPPortHandler,HTTPHandler,WebServerConfig
// Package ipn implements the interactions between the Tailscale cloud
// control plane and the local network stack.
diff --git a/ipn/ipn_clone.go b/ipn/ipn_clone.go
index e179438cdcfcb..65cef3611bae3 100644
--- a/ipn/ipn_clone.go
+++ b/ipn/ipn_clone.go
@@ -1,19 +1,19 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-// Code generated by tailscale.com/cmd/cloner; DO NOT EDIT.
+// Code generated by github.com/metacubex/tailscale/cmd/cloner; DO NOT EDIT.
package ipn
import (
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"net/netip"
- "tailscale.com/drive"
- "tailscale.com/tailcfg"
- "tailscale.com/types/opt"
- "tailscale.com/types/persist"
- "tailscale.com/types/preftype"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/types/preftype"
)
// Clone makes a deep copy of LoginProfile.
@@ -62,7 +62,7 @@ func (src *Prefs) Clone() *Prefs {
}
}
if dst.RelayServerPort != nil {
- dst.RelayServerPort = new(*src.RelayServerPort)
+ dst.RelayServerPort = func() *uint16 { v := *src.RelayServerPort; return &v }()
}
dst.RelayServerStaticEndpoints = append(src.RelayServerStaticEndpoints[:0:0], src.RelayServerStaticEndpoints...)
dst.Persist = src.Persist.Clone()
@@ -122,7 +122,8 @@ func (src *ServeConfig) Clone() *ServeConfig {
if v == nil {
dst.TCP[k] = nil
} else {
- dst.TCP[k] = new(*v)
+ vv := *v
+ dst.TCP[k] = &vv
}
}
}
@@ -184,7 +185,8 @@ func (src *ServiceConfig) Clone() *ServiceConfig {
if v == nil {
dst.TCP[k] = nil
} else {
- dst.TCP[k] = new(*v)
+ vv := *v
+ dst.TCP[k] = &vv
}
}
}
diff --git a/ipn/ipn_test.go b/ipn/ipn_test.go
index 2689faa8e37cd..ff85eb8bf9dad 100644
--- a/ipn/ipn_test.go
+++ b/ipn/ipn_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,17 +8,17 @@ package ipn
import (
"testing"
- "tailscale.com/tstest/deptest"
+ "github.com/metacubex/tailscale/tstest/deptest"
)
func TestDeps(t *testing.T) {
deptest.DepChecker{
BadDeps: map[string]string{
- "testing": "do not use testing package in production code",
- "gvisor.dev/gvisor/pkg/buffer": "https://github.com/tailscale/tailscale/issues/9756",
- "gvisor.dev/gvisor/pkg/cpuid": "https://github.com/tailscale/tailscale/issues/9756",
- "gvisor.dev/gvisor/pkg/tcpip": "https://github.com/tailscale/tailscale/issues/9756",
- "gvisor.dev/gvisor/pkg/tcpip/header": "https://github.com/tailscale/tailscale/issues/9756",
+ "testing": "do not use testing package in production code",
+ "github.com/metacubex/gvisor/pkg/buffer": "https://github.com/tailscale/tailscale/issues/9756",
+ "github.com/metacubex/gvisor/pkg/cpuid": "https://github.com/tailscale/tailscale/issues/9756",
+ "github.com/metacubex/gvisor/pkg/tcpip": "https://github.com/tailscale/tailscale/issues/9756",
+ "github.com/metacubex/gvisor/pkg/tcpip/header": "https://github.com/tailscale/tailscale/issues/9756",
},
}.Check(t)
}
diff --git a/ipn/ipn_view.go b/ipn/ipn_view.go
index 4e9d46bda30a0..13bb590f130a8 100644
--- a/ipn/ipn_view.go
+++ b/ipn/ipn_view.go
@@ -10,17 +10,17 @@ import (
"errors"
"net/netip"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/drive"
- "tailscale.com/tailcfg"
- "tailscale.com/types/opt"
- "tailscale.com/types/persist"
- "tailscale.com/types/preftype"
- "tailscale.com/types/views"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/types/preftype"
+ "github.com/metacubex/tailscale/types/views"
)
-//go:generate go run tailscale.com/cmd/cloner -clonefunc=false -type=LoginProfile,Prefs,ServeConfig,ServiceConfig,TCPPortHandler,HTTPHandler,WebServerConfig
+//go:generate go run github.com/metacubex/tailscale/cmd/cloner -clonefunc=false -type=LoginProfile,Prefs,ServeConfig,ServiceConfig,TCPPortHandler,HTTPHandler,WebServerConfig
// View returns a read-only view of LoginProfile.
func (p *LoginProfile) View() LoginProfileView {
diff --git a/ipn/ipnauth/actor.go b/ipn/ipnauth/actor.go
index 0fa4735f9fe69..78564c987deca 100644
--- a/ipn/ipnauth/actor.go
+++ b/ipn/ipnauth/actor.go
@@ -8,9 +8,9 @@ import (
"encoding/json"
"fmt"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/ipn"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tailcfg"
)
// AuditLogFunc is any function that can be used to log audit actions performed by an [Actor].
diff --git a/ipn/ipnauth/actor_windows.go b/ipn/ipnauth/actor_windows.go
index 0345bc5fdb2fe..a53e9dcc2c179 100644
--- a/ipn/ipnauth/actor_windows.go
+++ b/ipn/ipnauth/actor_windows.go
@@ -7,9 +7,9 @@ import (
"context"
"errors"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/types/lazy"
"golang.org/x/sys/windows"
- "tailscale.com/ipn"
- "tailscale.com/types/lazy"
)
// WindowsActor implements [Actor].
diff --git a/ipn/ipnauth/ipnauth.go b/ipn/ipnauth/ipnauth.go
index d48ec1f140c58..03d4b96eb5ec8 100644
--- a/ipn/ipnauth/ipnauth.go
+++ b/ipn/ipnauth/ipnauth.go
@@ -14,15 +14,15 @@ import (
"runtime"
"strconv"
- "tailscale.com/envknob"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/ipn"
- "tailscale.com/safesocket"
- "tailscale.com/types/logger"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/groupmember"
- "tailscale.com/util/winutil"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/safesocket"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/groupmember"
+ "github.com/metacubex/tailscale/util/winutil"
+ "github.com/metacubex/tailscale/version/distro"
)
// ErrNotImplemented is returned by ConnIdentity.WindowsToken when it is not
diff --git a/ipn/ipnauth/ipnauth_omit_unixsocketidentity.go b/ipn/ipnauth/ipnauth_omit_unixsocketidentity.go
index fce0143e43c38..9dca779cdc3f8 100644
--- a/ipn/ipnauth/ipnauth_omit_unixsocketidentity.go
+++ b/ipn/ipnauth/ipnauth_omit_unixsocketidentity.go
@@ -8,7 +8,7 @@ package ipnauth
import (
"net"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
// GetConnIdentity extracts the identity information from the connection
diff --git a/ipn/ipnauth/ipnauth_unix_creds.go b/ipn/ipnauth/ipnauth_unix_creds.go
index d031d3b6e09c2..fc800efcc6ff1 100644
--- a/ipn/ipnauth/ipnauth_unix_creds.go
+++ b/ipn/ipnauth/ipnauth_unix_creds.go
@@ -8,8 +8,8 @@ package ipnauth
import (
"net"
+ "github.com/metacubex/tailscale/types/logger"
"github.com/tailscale/peercred"
- "tailscale.com/types/logger"
)
// GetConnIdentity extracts the identity information from the connection
diff --git a/ipn/ipnauth/ipnauth_windows.go b/ipn/ipnauth/ipnauth_windows.go
index b4591ea3a03f8..0c01202699606 100644
--- a/ipn/ipnauth/ipnauth_windows.go
+++ b/ipn/ipnauth/ipnauth_windows.go
@@ -9,11 +9,11 @@ import (
"runtime"
"unsafe"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/safesocket"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/winutil"
"golang.org/x/sys/windows"
- "tailscale.com/ipn"
- "tailscale.com/safesocket"
- "tailscale.com/types/logger"
- "tailscale.com/util/winutil"
)
// GetConnIdentity extracts the identity information from the connection
diff --git a/ipn/ipnauth/policy.go b/ipn/ipnauth/policy.go
index 692005e5516d0..cf4e1fe9d56bf 100644
--- a/ipn/ipnauth/policy.go
+++ b/ipn/ipnauth/policy.go
@@ -7,12 +7,12 @@ import (
"errors"
"fmt"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/ipn"
- "tailscale.com/tailcfg"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
type actorWithPolicyChecks struct{ Actor }
diff --git a/ipn/ipnauth/self.go b/ipn/ipnauth/self.go
index 0379aede4076c..2f522707e3d96 100644
--- a/ipn/ipnauth/self.go
+++ b/ipn/ipnauth/self.go
@@ -6,7 +6,7 @@ package ipnauth
import (
"context"
- "tailscale.com/ipn"
+ "github.com/metacubex/tailscale/ipn"
)
// Self is a caller identity that represents the tailscaled itself and therefore
diff --git a/ipn/ipnauth/test_actor.go b/ipn/ipnauth/test_actor.go
index 667fb84137ca6..ce13ea55d0e66 100644
--- a/ipn/ipnauth/test_actor.go
+++ b/ipn/ipnauth/test_actor.go
@@ -4,11 +4,11 @@
package ipnauth
import (
- "cmp"
"context"
"errors"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
- "tailscale.com/ipn"
+ "github.com/metacubex/tailscale/ipn"
)
var _ Actor = (*TestActor)(nil)
diff --git a/ipn/ipnext/ipnext.go b/ipn/ipnext/ipnext.go
index 5ca50498a81ab..44d095825bf08 100644
--- a/ipn/ipnext/ipnext.go
+++ b/ipn/ipnext/ipnext.go
@@ -8,22 +8,22 @@ package ipnext
import (
"errors"
"fmt"
- "iter"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
"net/netip"
- "tailscale.com/control/controlclient"
- "tailscale.com/feature"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnauth"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/tsd"
- "tailscale.com/tstime"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/mapx"
- "tailscale.com/types/views"
- "tailscale.com/wgengine/filter"
+ "github.com/metacubex/tailscale/control/controlclient"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/mapx"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/wgengine/filter"
)
// Extension augments LocalBackend with additional functionality.
diff --git a/ipn/ipnlocal/breaktcp_linux.go b/ipn/ipnlocal/breaktcp_linux.go
index 1d7ea0f314b11..0ba9ed6d78f19 100644
--- a/ipn/ipnlocal/breaktcp_linux.go
+++ b/ipn/ipnlocal/breaktcp_linux.go
@@ -15,7 +15,7 @@ func init() {
func breakTCPConnsLinux() error {
var matched int
- for fd := range 1000 {
+ for fd := 0; fd < 1000; fd++ {
_, err := unix.GetsockoptTCPInfo(fd, unix.IPPROTO_TCP, unix.TCP_INFO)
if err == nil {
matched++
diff --git a/ipn/ipnlocal/bus.go b/ipn/ipnlocal/bus.go
index 8be50801001b9..3a49efce612e7 100644
--- a/ipn/ipnlocal/bus.go
+++ b/ipn/ipnlocal/bus.go
@@ -7,9 +7,9 @@ import (
"context"
"time"
- "tailscale.com/ipn"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
)
type rateLimitingBusSender struct {
diff --git a/ipn/ipnlocal/bus_test.go b/ipn/ipnlocal/bus_test.go
index 048e5bff4d6de..f885b8dc7ca91 100644
--- a/ipn/ipnlocal/bus_test.go
+++ b/ipn/ipnlocal/bus_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,19 +7,19 @@ package ipnlocal
import (
"context"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"reflect"
- "slices"
"testing"
"time"
- "tailscale.com/drive"
- "tailscale.com/ipn"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/tstime"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/types/views"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/views"
)
func TestIsNotableNotify(t *testing.T) {
diff --git a/ipn/ipnlocal/c2n.go b/ipn/ipnlocal/c2n.go
index bf8cf2e038a64..9f7afad6f901a 100644
--- a/ipn/ipnlocal/c2n.go
+++ b/ipn/ipnlocal/c2n.go
@@ -15,20 +15,19 @@ import (
"strings"
"time"
- "tailscale.com/control/controlclient"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/health"
- "tailscale.com/ipn"
- "tailscale.com/net/sockstats"
- "tailscale.com/tailcfg"
- "tailscale.com/types/netmap"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/goroutines"
- "tailscale.com/util/httpm"
- "tailscale.com/util/set"
- "tailscale.com/util/testenv"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/control/controlclient"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/goroutines"
+ "github.com/metacubex/tailscale/util/httpm"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/testenv"
+ "github.com/metacubex/tailscale/version"
)
// c2nHandlers maps an HTTP method and URI path (without query parameters) to
@@ -49,8 +48,6 @@ func init() {
RegisterC2N("POST /logtail/flush", handleC2NLogtailFlush)
}
if buildfeatures.HasDebug {
- RegisterC2N("POST /sockstats", handleC2NSockStats)
-
// pprof:
// we only expose a subset of typical pprof endpoints for security.
RegisterC2N("/debug/pprof/heap", handleC2NPprof)
@@ -288,17 +285,6 @@ func handleC2NPprof(b *LocalBackend, w http.ResponseWriter, r *http.Request) {
c2nPprof(w, r, profile)
}
-func handleC2NSockStats(b *LocalBackend, w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "text/plain")
- if b.sockstatLogger == nil {
- http.Error(w, "no sockstatLogger", http.StatusInternalServerError)
- return
- }
- b.sockstatLogger.Flush()
- fmt.Fprintf(w, "logid: %s\n", b.sockstatLogger.LogID())
- fmt.Fprintf(w, "debug info: %v\n", sockstats.DebugInfo())
-}
-
func handleC2NSetNetfilterKind(b *LocalBackend, w http.ResponseWriter, r *http.Request) {
b.logf("c2n: POST /netfilter-kind received")
diff --git a/ipn/ipnlocal/c2n_pprof.go b/ipn/ipnlocal/c2n_pprof.go
index 783ba16ff93c5..71a1deb38cd95 100644
--- a/ipn/ipnlocal/c2n_pprof.go
+++ b/ipn/ipnlocal/c2n_pprof.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !js && !wasm && !ts_omit_debug
+//go:build !js && !wasm && ts_enable_debug
package ipnlocal
diff --git a/ipn/ipnlocal/c2n_test.go b/ipn/ipnlocal/c2n_test.go
index e5b15e79a2577..2b861f369b5dd 100644
--- a/ipn/ipnlocal/c2n_test.go
+++ b/ipn/ipnlocal/c2n_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,9 +7,9 @@ package ipnlocal
import (
"bytes"
- "cmp"
"crypto/x509"
"encoding/json"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"net/http/httptest"
"net/url"
"os"
@@ -16,16 +18,16 @@ import (
"testing"
"time"
- "tailscale.com/health"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/types/views"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/must"
gcmp "github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
diff --git a/ipn/ipnlocal/captiveportal.go b/ipn/ipnlocal/captiveportal.go
index ae310c7cc785a..a59888cc55637 100644
--- a/ipn/ipnlocal/captiveportal.go
+++ b/ipn/ipnlocal/captiveportal.go
@@ -9,9 +9,9 @@ import (
"context"
"time"
- "tailscale.com/health"
- "tailscale.com/net/captivedetection"
- "tailscale.com/util/clientmetric"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/captivedetection"
+ "github.com/metacubex/tailscale/util/clientmetric"
)
func init() {
@@ -161,7 +161,7 @@ func (b *LocalBackend) performCaptiveDetection() {
return
}
- d := captivedetection.NewDetector(b.logf)
+ d := captivedetection.NewDetector(b.logf, b.Dialer().SystemDial)
b.mu.Lock() // for b.hostinfo
cn := b.currentNode()
dm := cn.DERPMap()
diff --git a/ipn/ipnlocal/cert.go b/ipn/ipnlocal/cert.go
index eab70b295e5bd..ff1b5fca262c5 100644
--- a/ipn/ipnlocal/cert.go
+++ b/ipn/ipnlocal/cert.go
@@ -20,33 +20,33 @@ import (
"encoding/pem"
"errors"
"fmt"
+ randv2 "github.com/metacubex/tailscale/util/go120/randv2"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
- randv2 "math/rand/v2"
"net"
"net/http"
"os"
"path/filepath"
"runtime"
- "slices"
"strings"
"time"
- "tailscale.com/atomicfile"
- "tailscale.com/envknob"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn"
- "tailscale.com/ipn/store"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/net/bakedroots"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tempfork/acme"
- "tailscale.com/types/logger"
- "tailscale.com/util/testenv"
- "tailscale.com/version"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/atomicfile"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/store"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/net/bakedroots"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tempfork/acme"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/testenv"
+ "github.com/metacubex/tailscale/version"
+ "github.com/metacubex/tailscale/version/distro"
)
func init() {
diff --git a/ipn/ipnlocal/cert_test.go b/ipn/ipnlocal/cert_test.go
index 56d6df77f3128..e6115df161bcd 100644
--- a/ipn/ipnlocal/cert_test.go
+++ b/ipn/ipnlocal/cert_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ios && !android && !js
-
package ipnlocal
import (
@@ -14,22 +14,22 @@ import (
"crypto/x509/pkix"
"embed"
"encoding/pem"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"math/big"
"os"
"path/filepath"
- "slices"
"testing"
"time"
"github.com/google/go-cmp/cmp"
- "tailscale.com/envknob"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/util/must"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/set"
)
func TestCertRequest(t *testing.T) {
diff --git a/ipn/ipnlocal/diskcache.go b/ipn/ipnlocal/diskcache.go
index 3235869e6fab3..47c757b0c7abf 100644
--- a/ipn/ipnlocal/diskcache.go
+++ b/ipn/ipnlocal/diskcache.go
@@ -8,9 +8,9 @@ import (
"errors"
"fmt"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/ipn/ipnlocal/netmapcache"
- "tailscale.com/types/netmap"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/ipn/ipnlocal/netmapcache"
+ "github.com/metacubex/tailscale/types/netmap"
)
// diskCache is the state netmap caching to disk.
@@ -92,15 +92,16 @@ func (b *LocalBackend) discardDiskCacheLocked() {
// clearStoreLocked discards all the keys in the specified store.
func (b *LocalBackend) clearStoreLocked(ctx context.Context, store netmapcache.Store) error {
var errs []error
- for key, err := range store.List(ctx, "") {
+ store.List(ctx, "")(func(key string, err error) bool {
if err != nil {
errs = append(errs, fmt.Errorf("list cache contest: %w", err))
- break
+ return false
}
if err := store.Remove(ctx, key); err != nil {
errs = append(errs, fmt.Errorf("discard cache key %q: %w", key, err))
}
- }
+ return true
+ })
return errors.Join(errs...)
}
diff --git a/ipn/ipnlocal/diskcache_test.go b/ipn/ipnlocal/diskcache_test.go
index 748ff6a408e64..a1f5aa817002c 100644
--- a/ipn/ipnlocal/diskcache_test.go
+++ b/ipn/ipnlocal/diskcache_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,11 +9,11 @@ import (
"net/netip"
"testing"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/types/netmap"
- "tailscale.com/util/eventbus"
- "tailscale.com/wgengine/magicsock"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/wgengine/magicsock"
)
// newCacheTestNetmap returns a minimal valid netmap suitable for testing disk
diff --git a/ipn/ipnlocal/dnsconfig_test.go b/ipn/ipnlocal/dnsconfig_test.go
index 9d30029ff8659..7eafd700536cb 100644
--- a/ipn/ipnlocal/dnsconfig_test.go
+++ b/ipn/ipnlocal/dnsconfig_test.go
@@ -1,26 +1,28 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package ipnlocal
import (
- "cmp"
"encoding/json"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"net/netip"
"reflect"
"testing"
- "tailscale.com/appc"
- "tailscale.com/ipn"
- "tailscale.com/net/dns"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/types/dnstype"
- "tailscale.com/types/netmap"
- "tailscale.com/types/opt"
- "tailscale.com/util/cloudenv"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/appc"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/net/dns"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/util/cloudenv"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/set"
)
func ipps(ippStrs ...string) (ipps []netip.Prefix) {
diff --git a/ipn/ipnlocal/drive.go b/ipn/ipnlocal/drive.go
index 110ffff2a765d..d04fcbda017cf 100644
--- a/ipn/ipnlocal/drive.go
+++ b/ipn/ipnlocal/drive.go
@@ -8,19 +8,19 @@ package ipnlocal
import (
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net/http"
"net/netip"
"os"
- "slices"
-
- "tailscale.com/drive"
- "tailscale.com/ipn"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/types/views"
- "tailscale.com/util/httpm"
+
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/httpm"
)
func init() {
@@ -77,7 +77,7 @@ func (b *LocalBackend) driveSetShareLocked(share *drive.Share) (views.SliceView[
addedShare := false
var shares []*drive.Share
- for _, existing := range existingShares.All() {
+ existingShares.All()(func(_ int, existing drive.ShareView) bool {
if existing.Name() != share.Name {
if !addedShare && existing.Name() > share.Name {
// Add share in order
@@ -86,7 +86,8 @@ func (b *LocalBackend) driveSetShareLocked(share *drive.Share) (views.SliceView[
}
shares = append(shares, existing.AsStruct())
}
- }
+ return true
+ })
if !addedShare {
shares = append(shares, share)
}
@@ -134,10 +135,12 @@ func (b *LocalBackend) driveRenameShareLocked(oldName, newName string) (views.Sl
}
found := false
+ var loopErr error
var shares []*drive.Share
- for _, existing := range existingShares.All() {
+ existingShares.All()(func(_ int, existing drive.ShareView) bool {
if existing.Name() == newName {
- return existingShares, os.ErrExist
+ loopErr = os.ErrExist
+ return false
}
if existing.Name() == oldName {
share := existing.AsStruct()
@@ -147,6 +150,10 @@ func (b *LocalBackend) driveRenameShareLocked(oldName, newName string) (views.Sl
} else {
shares = append(shares, existing.AsStruct())
}
+ return true
+ })
+ if loopErr != nil {
+ return existingShares, loopErr
}
if !found {
@@ -195,13 +202,14 @@ func (b *LocalBackend) driveRemoveShareLocked(name string) (views.SliceView[*dri
found := false
var shares []*drive.Share
- for _, existing := range existingShares.All() {
+ existingShares.All()(func(_ int, existing drive.ShareView) bool {
if existing.Name() != name {
shares = append(shares, existing.AsStruct())
} else {
found = true
}
- }
+ return true
+ })
if !found {
return existingShares, os.ErrNotExist
@@ -241,7 +249,7 @@ func (b *LocalBackend) driveNotifyShares(shares views.SliceView[*drive.Share, dr
// Ensures shares is not nil to distinguish "no shares" from "not notifying shares"
if shares.IsNil() {
- shares = views.SliceOfViews(make([]*drive.Share, 0))
+ shares = views.SliceOfViews[*drive.Share, drive.ShareView](make([]*drive.Share, 0))
}
b.send(ipn.Notify{DriveShares: shares})
}
@@ -268,7 +276,7 @@ func driveShareViewsEqual(a *views.SliceView[*drive.Share, drive.ShareView], b v
return false
}
- for i := range a.Len() {
+ for i := 0; i < a.Len(); i++ {
if !drive.ShareViewsEqual(a.At(i), b.At(i)) {
return false
}
diff --git a/ipn/ipnlocal/drive_test.go b/ipn/ipnlocal/drive_test.go
index aca05432b8276..b9ea1bd50ffaa 100644
--- a/ipn/ipnlocal/drive_test.go
+++ b/ipn/ipnlocal/drive_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_drive
-
package ipnlocal
import (
diff --git a/ipn/ipnlocal/drive_tomove.go b/ipn/ipnlocal/drive_tomove.go
index ccea48f7a5106..5c270891ce815 100644
--- a/ipn/ipnlocal/drive_tomove.go
+++ b/ipn/ipnlocal/drive_tomove.go
@@ -7,7 +7,7 @@
package ipnlocal
-import "tailscale.com/tailcfg"
+import "github.com/metacubex/tailscale/tailcfg"
const (
// DriveLocalPort is the port on which the Taildrive listens for location
diff --git a/ipn/ipnlocal/expiry.go b/ipn/ipnlocal/expiry.go
index 461dce2fda055..a03c4c9a105ba 100644
--- a/ipn/ipnlocal/expiry.go
+++ b/ipn/ipnlocal/expiry.go
@@ -6,14 +6,14 @@ package ipnlocal
import (
"time"
- "tailscale.com/control/controlclient"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/util/eventbus"
+ "github.com/metacubex/tailscale/control/controlclient"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/eventbus"
)
// For extra defense-in-depth, when we're testing expired nodes we check
diff --git a/ipn/ipnlocal/expiry_test.go b/ipn/ipnlocal/expiry_test.go
index 1d85d81d1819d..d2857f5989e23 100644
--- a/ipn/ipnlocal/expiry_test.go
+++ b/ipn/ipnlocal/expiry_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,11 +12,11 @@ import (
"testing"
"time"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/types/key"
- "tailscale.com/types/netmap"
- "tailscale.com/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
)
func TestFlagExpiredPeers(t *testing.T) {
diff --git a/ipn/ipnlocal/extension_host.go b/ipn/ipnlocal/extension_host.go
index 0c4b1d933f724..cf7bebac2ea39 100644
--- a/ipn/ipnlocal/extension_host.go
+++ b/ipn/ipnlocal/extension_host.go
@@ -7,23 +7,23 @@ import (
"context"
"errors"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"reflect"
- "slices"
"strings"
"sync"
"sync/atomic"
"time"
- "tailscale.com/control/controlclient"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnauth"
- "tailscale.com/ipn/ipnext"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
- "tailscale.com/util/execqueue"
- "tailscale.com/util/mak"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/control/controlclient"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
+ "github.com/metacubex/tailscale/ipn/ipnext"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/execqueue"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/testenv"
)
// ExtensionHost is a bridge between the [LocalBackend] and the registered [ipnext.Extension]s.
@@ -183,23 +183,26 @@ func newExtensionHost(logf logger.Logf, b Backend, overrideExts ...*ipnext.Defin
extDef = slices.Values(overrideExts)
}
- for d := range extDef {
- ext, err := d.MakeExtension(logf, b)
- if errors.Is(err, ipnext.SkipExtension) {
+ extDef(func(d *ipnext.Definition) bool {
+ ext, makeErr := d.MakeExtension(logf, b)
+ if errors.Is(makeErr, ipnext.SkipExtension) {
// The extension wants to be skipped.
- host.logf("%q: %v", d.Name(), err)
- continue
- } else if err != nil {
- return nil, fmt.Errorf("failed to create %q extension: %v", d.Name(), err)
+ host.logf("%q: %v", d.Name(), makeErr)
+ return true
+ } else if makeErr != nil {
+ err = fmt.Errorf("failed to create %q extension: %v", d.Name(), makeErr)
+ return false
}
host.allExtensions = append(host.allExtensions, ext)
if d.Name() != ext.Name() {
- return nil, fmt.Errorf("extension name %q does not match the registered name %q", ext.Name(), d.Name())
+ err = fmt.Errorf("extension name %q does not match the registered name %q", ext.Name(), d.Name())
+ return false
}
if _, ok := host.extensionsByName[ext.Name()]; ok {
- return nil, fmt.Errorf("duplicate extension name %q", ext.Name())
+ err = fmt.Errorf("duplicate extension name %q", ext.Name())
+ return false
} else {
mak.Set(&host.extensionsByName, ext.Name(), ext)
}
@@ -207,14 +210,18 @@ func newExtensionHost(logf logger.Logf, b Backend, overrideExts ...*ipnext.Defin
typ := reflect.TypeOf(ext)
if _, ok := host.extByType.Load(typ); ok {
if _, ok := ext.(interface{ PermitDoubleRegister() }); !ok {
- return nil, fmt.Errorf("duplicate extension type %T", ext)
+ err = fmt.Errorf("duplicate extension type %T", ext)
+ return false
}
}
host.extByType.Store(typ, ext)
+ return true
+ })
+ if err != nil {
+ return nil, err
}
return host, nil
}
-
func (h *ExtensionHost) NodeBackend() ipnext.NodeBackend {
if h == nil {
return nil
@@ -308,7 +315,7 @@ func (h *ExtensionHost) FindExtensionByName(name string) any {
}
// extensionIfaceType is the runtime type of the [ipnext.Extension] interface.
-var extensionIfaceType = reflect.TypeFor[ipnext.Extension]()
+var extensionIfaceType = reflect.TypeOf((*ipnext.Extension)(nil)).Elem()
// GetExt returns the extension of type T registered with lb.
// If lb is nil or the extension is not found, it returns zero, false.
@@ -317,7 +324,7 @@ func GetExt[T ipnext.Extension](lb *LocalBackend) (_ T, ok bool) {
if lb == nil {
return zero, false
}
- if ext, ok := lb.extHost.extensionOfType(reflect.TypeFor[T]()); ok {
+ if ext, ok := lb.extHost.extensionOfType(reflect.TypeOf((*T)(nil)).Elem()); ok {
return ext.(T), true
}
return zero, false
@@ -606,12 +613,13 @@ func (h *ExtensionHost) shutdownExtensions() {
// a deadlock if the h.mu is already held.
//
// Shutdown is called in the reverse order of Init.
- for _, ext := range slices.Backward(extensions) {
+ slices.Backward(extensions)(func(_ int, ext ipnext.Extension) bool {
if err := ext.Shutdown(); err != nil {
// Extension shutdown errors are never fatal, but we log them for debugging purposes.
h.logf("%q: shutdown callback failed: %v", ext.Name(), err)
}
- }
+ return true
+ })
}
// enqueueBackendOperation enqueues a function to perform an operation on the [Backend].
diff --git a/ipn/ipnlocal/extension_host_test.go b/ipn/ipnlocal/extension_host_test.go
index 58955dc6c7a67..00d058041d33b 100644
--- a/ipn/ipnlocal/extension_host_test.go
+++ b/ipn/ipnlocal/extension_host_test.go
@@ -1,15 +1,17 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package ipnlocal
import (
- "cmp"
"context"
"errors"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"reflect"
- "slices"
"strconv"
"strings"
"sync"
@@ -19,21 +21,21 @@ import (
deepcmp "github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/health"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnauth"
- "tailscale.com/ipn/ipnext"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/tailcfg"
- "tailscale.com/tsd"
- "tailscale.com/tstest"
- "tailscale.com/tstime"
- "tailscale.com/types/key"
- "tailscale.com/types/lazy"
- "tailscale.com/types/logger"
- "tailscale.com/types/persist"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
+ "github.com/metacubex/tailscale/ipn/ipnext"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/must"
)
// defaultCmpOpts are the default options used for deepcmp comparisons in tests.
diff --git a/ipn/ipnlocal/hwattest.go b/ipn/ipnlocal/hwattest.go
index 07c09dc7fe043..3b46ba9684791 100644
--- a/ipn/ipnlocal/hwattest.go
+++ b/ipn/ipnlocal/hwattest.go
@@ -8,10 +8,10 @@ package ipnlocal
import (
"errors"
- "tailscale.com/feature"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/persist"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/persist"
)
func init() {
diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go
index c864a81a0c722..3fe7ed3d9d48c 100644
--- a/ipn/ipnlocal/local.go
+++ b/ipn/ipnlocal/local.go
@@ -7,16 +7,17 @@ package ipnlocal
import (
"bufio"
- "cmp"
"context"
"crypto/sha256"
"encoding/binary"
"encoding/json"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ "github.com/metacubex/tailscale/util/go120/randv2"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"math"
- "math/rand/v2"
"net"
"net/http"
"net/netip"
@@ -25,88 +26,85 @@ import (
"path/filepath"
"reflect"
"runtime"
- "slices"
"strconv"
"strings"
"sync"
"sync/atomic"
"time"
+ "github.com/metacubex/tailscale/appc"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/control/controlclient"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/envknob/featureknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/health/healthmsg"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/conffile"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
+ "github.com/metacubex/tailscale/ipn/ipnext"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/net/dns"
+ "github.com/metacubex/tailscale/net/dnscache"
+ "github.com/metacubex/tailscale/net/dnsfallback"
+ "github.com/metacubex/tailscale/net/ipset"
+ "github.com/metacubex/tailscale/net/netcheck"
+ "github.com/metacubex/tailscale/net/netkernelconf"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/net/netutil"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/paths"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/appctype"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/empty"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/types/preftype"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/checkchange"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/execqueue"
+ "github.com/metacubex/tailscale/util/goroutines"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/osuser"
+ "github.com/metacubex/tailscale/util/rands"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/util/syspolicy/ptype"
+ "github.com/metacubex/tailscale/util/testenv"
+ "github.com/metacubex/tailscale/util/usermetric"
+ "github.com/metacubex/tailscale/util/vizerror"
+ "github.com/metacubex/tailscale/version"
+ "github.com/metacubex/tailscale/version/distro"
+ "github.com/metacubex/tailscale/wgengine"
+ "github.com/metacubex/tailscale/wgengine/filter"
+ "github.com/metacubex/tailscale/wgengine/magicsock"
+ "github.com/metacubex/tailscale/wgengine/router"
+ "github.com/metacubex/tailscale/wgengine/wgcfg"
+ "github.com/metacubex/tailscale/wgengine/wgcfg/nmcfg"
"go4.org/mem"
"go4.org/netipx"
"golang.org/x/net/dns/dnsmessage"
- "tailscale.com/appc"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/control/controlclient"
- "tailscale.com/control/controlknobs"
- "tailscale.com/drive"
- "tailscale.com/envknob"
- "tailscale.com/envknob/featureknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/health"
- "tailscale.com/health/healthmsg"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn"
- "tailscale.com/ipn/conffile"
- "tailscale.com/ipn/ipnauth"
- "tailscale.com/ipn/ipnext"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/log/sockstatlog"
- "tailscale.com/logpolicy"
- "tailscale.com/net/dns"
- "tailscale.com/net/dnscache"
- "tailscale.com/net/dnsfallback"
- "tailscale.com/net/ipset"
- "tailscale.com/net/netcheck"
- "tailscale.com/net/netkernelconf"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netns"
- "tailscale.com/net/netutil"
- "tailscale.com/net/packet"
- "tailscale.com/net/tsaddr"
- "tailscale.com/net/tsdial"
- "tailscale.com/paths"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tsd"
- "tailscale.com/tstime"
- "tailscale.com/types/appctype"
- "tailscale.com/types/dnstype"
- "tailscale.com/types/empty"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/types/netmap"
- "tailscale.com/types/opt"
- "tailscale.com/types/persist"
- "tailscale.com/types/preftype"
- "tailscale.com/types/views"
- "tailscale.com/util/checkchange"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/execqueue"
- "tailscale.com/util/goroutines"
- "tailscale.com/util/mak"
- "tailscale.com/util/osuser"
- "tailscale.com/util/rands"
- "tailscale.com/util/set"
- "tailscale.com/util/slicesx"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/policyclient"
- "tailscale.com/util/syspolicy/ptype"
- "tailscale.com/util/testenv"
- "tailscale.com/util/usermetric"
- "tailscale.com/util/vizerror"
- "tailscale.com/version"
- "tailscale.com/version/distro"
- "tailscale.com/wgengine"
- "tailscale.com/wgengine/filter"
- "tailscale.com/wgengine/magicsock"
- "tailscale.com/wgengine/router"
- "tailscale.com/wgengine/wgcfg"
- "tailscale.com/wgengine/wgcfg/nmcfg"
)
var controlDebugFlags = getControlDebugFlags()
@@ -216,7 +214,6 @@ type LocalBackend struct {
exposeRemoteWebClientAtomicBool atomic.Bool // TODO(nickkhyl): move to nodeBackend
shutdownCalled bool // if Shutdown has been called
debugSink packet.CaptureSink
- sockstatLogger *sockstatlog.Logger
// getTCPHandlerForFunnelFlow returns a handler for an incoming TCP flow for
// the provided srcAddr and dstPort if one exists.
@@ -408,6 +405,8 @@ type LocalBackend struct {
// bind the node identity to this device.
hardwareAttested atomic.Bool
+ lookupHook dnscache.LookupHookFunc
+
// getCertForTest is used to retrieve TLS certificates in tests.
// See [LocalBackend.ConfigureCertsForTest].
getCertForTest func(hostname string) (*TLSCertKeyPair, error)
@@ -471,7 +470,7 @@ type clientGen func(controlclient.Options) (controlclient.Client, error)
// If dialer is nil, a new one is made.
//
// The logID may be the zero value if logging is not in use.
-func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, loginFlags controlclient.LoginFlags) (_ *LocalBackend, err error) {
+func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, loginFlags controlclient.LoginFlags, lookupHook ...dnscache.LookupHookFunc) (_ *LocalBackend, err error) {
e := sys.Engine.Get()
store := sys.StateStore.Get()
dialer := sys.Dialer.Get()
@@ -494,6 +493,10 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, lo
if sds, ok := store.(ipn.StateStoreDialerSetter); ok {
sds.SetDialer(dialer.SystemDial)
}
+ var lookupHookFunc dnscache.LookupHookFunc
+ if len(lookupHook) > 0 {
+ lookupHookFunc = lookupHook[0]
+ }
envknob.LogCurrent(logf)
@@ -534,6 +537,7 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, lo
captiveCtx: captiveCtx,
captiveCancel: nil, // so that we start checkCaptivePortalLoop when Running
needsCaptiveDetection: make(chan bool),
+ lookupHook: lookupHookFunc,
}
nb := newNodeBackend(ctx, b.logf, b.sys.Bus.Get())
@@ -563,14 +567,6 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, lo
}()
netMon := sys.NetMon.Get()
- b.sockstatLogger, err = sockstatlog.NewLogger(logpolicy.LogsDir(logf), logf, logID, netMon, sys.HealthTracker.Get(), sys.Bus.Get())
- if err != nil {
- logf("error setting up sockstat logger: %v", err)
- }
- // Enable sockstats logs only on non-mobile unstable builds
- if version.IsUnstableBuild() && !version.IsMobile() && b.sockstatLogger != nil {
- b.sockstatLogger.SetLoggingEnabled(true)
- }
// Default filter blocks everything and logs nothing, until Start() is called.
noneFilter := filter.NewAllowNone(logf, &netipx.IPSet{})
@@ -771,16 +767,6 @@ func (b *LocalBackend) SetComponentDebugLogging(component string, until time.Tim
case "magicsock":
setEnabled = b.MagicConn().SetDebugLoggingEnabled
case "sockstats":
- if b.sockstatLogger != nil {
- setEnabled = func(v bool) {
- b.sockstatLogger.SetLoggingEnabled(v)
- // Flush (and thus upload) logs when the enabled period ends,
- // so that the logs are available for debugging.
- if !v {
- b.sockstatLogger.Flush()
- }
- }
- }
case "syspolicy":
setEnabled = b.polc.SetDebugLoggingEnabled
}
@@ -1239,12 +1225,6 @@ func (b *LocalBackend) Shutdown() {
b.mu.Unlock()
b.webClientShutdown()
- if b.sockstatLogger != nil {
- ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
- defer cancel()
- b.sockstatLogger.Shutdown(ctx)
- }
-
b.unregisterSysPolicyWatch()
if cc != nil {
cc.Shutdown()
@@ -1385,7 +1365,7 @@ func (b *LocalBackend) UpdateStatus(sb *ipnstate.StatusBuilder) {
var tailscaleIPs []netip.Addr
if nm != nil {
addrs := nm.GetAddresses()
- for i := range addrs.Len() {
+ for i := 0; i < addrs.Len(); i++ {
if addr := addrs.At(i); addr.IsSingleIP() {
sb.AddTailscaleIP(addr.Addr())
tailscaleIPs = append(tailscaleIPs, addr.Addr())
@@ -1409,10 +1389,11 @@ func (b *LocalBackend) UpdateStatus(sb *ipnstate.StatusBuilder) {
ss.Capabilities = make([]tailcfg.NodeCapability, 1, cm.Len()+1)
ss.Capabilities[0] = "HTTPS://TAILSCALE.COM/s/DEPRECATED-NODE-CAPS#see-https://github.com/tailscale/tailscale/issues/11508"
ss.CapMap = make(tailcfg.NodeCapMap, sn.CapMap().Len())
- for k, v := range cm.All() {
+ cm.All()(func(k tailcfg.NodeCapability, v views.Slice[tailcfg.RawMessage]) bool {
ss.CapMap[k] = v.AsSlice()
ss.Capabilities = append(ss.Capabilities, k)
- }
+ return true
+ })
slices.Sort(ss.Capabilities[1:])
}
}
@@ -1448,7 +1429,7 @@ func (b *LocalBackend) populatePeerStatusLocked(sb *ipnstate.StatusBuilder) {
exitNodeID := b.pm.CurrentPrefs().ExitNodeID()
for _, p := range cn.Peers() {
tailscaleIPs := make([]netip.Addr, 0, p.Addresses().Len())
- for i := range p.Addresses().Len() {
+ for i := 0; i < p.Addresses().Len(); i++ {
addr := p.Addresses().At(i)
if addr.IsSingleIP() && tsaddr.IsTailscaleIP(addr.Addr()) {
tailscaleIPs = append(tailscaleIPs, addr.Addr())
@@ -1475,9 +1456,10 @@ func (b *LocalBackend) populatePeerStatusLocked(sb *ipnstate.StatusBuilder) {
}
if cm := p.CapMap(); cm.Len() > 0 {
ps.CapMap = make(tailcfg.NodeCapMap, cm.Len())
- for k, v := range cm.All() {
+ cm.All()(func(k tailcfg.NodeCapability, v views.Slice[tailcfg.RawMessage]) bool {
ps.CapMap[k] = v.AsSlice()
- }
+ return true
+ })
}
peerStatusFromNode(ps, p)
@@ -1823,7 +1805,8 @@ func (b *LocalBackend) setControlClientStatusLocked(c controlclient.Client, st c
b.logf("Failed to save new controlclient state: %v", err)
}
- b.sendToLocked(ipn.Notify{Prefs: new(prefs.View())}, allClients)
+ prefsView := prefs.View()
+ b.sendToLocked(ipn.Notify{Prefs: &prefsView}, allClients)
}
// initTKALocked is dependent on CurrentProfile.ID, which is initialized
@@ -2606,7 +2589,7 @@ func (b *LocalBackend) controlDebugFlags() []string {
//
// TODO(danderson): this function is trying to do too many things at
// once: it loads state, or imports it, or updates prefs sometimes,
-// contains some settings that are one-shot things done by `tailscale
+// contains some settings that are one-shot things done by ailscale
// up` because we had nowhere else to put them, and there's no clear
// guarantee that switching from one user's state to another is
// actually a supported operation (it should be, but it's very unclear
@@ -2823,6 +2806,7 @@ func (b *LocalBackend) startLocked(opts ipn.Options) error {
Shutdown: ccShutdown,
Bus: b.sys.Bus.Get(),
StartPaused: prefs.Sync().EqualBool(false),
+ LookupHook: b.lookupHook,
})
if err != nil {
return err
@@ -2858,9 +2842,10 @@ func (b *LocalBackend) startLocked(opts ipn.Options) error {
if fs, ok := b.sys.DriveForRemote.GetOK(); ok {
currentShares := b.pm.CurrentPrefs().DriveShares()
var shares []*drive.Share
- for _, share := range currentShares.All() {
+ currentShares.All()(func(_ int, share drive.ShareView) bool {
shares = append(shares, share.AsStruct())
- }
+ return true
+ })
fs.SetShares(shares)
}
@@ -2975,7 +2960,7 @@ func (b *LocalBackend) updateFilterLocked(prefs ipn.PrefsView) {
logNetsB.RemovePrefix(tsaddr.ChromeOSVMRange())
if haveNetmap {
addrs = netMap.GetAddresses()
- for i := range addrs.Len() {
+ for i := 0; i < addrs.Len(); i++ {
localNetsB.AddPrefix(addrs.At(i))
}
packetFilter = netMap.PacketFilter
@@ -2993,7 +2978,7 @@ func (b *LocalBackend) updateFilterLocked(prefs ipn.PrefsView) {
}
if prefs.Valid() {
if buildfeatures.HasAdvertiseRoutes {
- for _, r := range prefs.AdvertiseRoutes().All() {
+ prefs.AdvertiseRoutes().All()(func(_ int, r netip.Prefix) bool {
if r.Bits() == 0 {
// When offering a default route to the world, we
// filter out locally reachable LANs, so that the
@@ -3004,12 +2989,12 @@ func (b *LocalBackend) updateFilterLocked(prefs ipn.PrefsView) {
localInterfaceRoutes, hostIPs, err := interfaceRoutes()
if err != nil {
b.logf("getting local interface routes: %v", err)
- continue
+ return true
}
s, err := shrinkDefaultRoute(r, localInterfaceRoutes, hostIPs)
if err != nil {
b.logf("computing default route filter: %v", err)
- continue
+ return true
}
localNetsB.AddSet(s)
} else {
@@ -3019,7 +3004,8 @@ func (b *LocalBackend) updateFilterLocked(prefs ipn.PrefsView) {
// in the audit logs.
logNetsB.AddPrefix(r)
}
- }
+ return true
+ })
}
// App connectors handle DNS requests for app domains over PeerAPI (corp#11961),
@@ -3097,9 +3083,10 @@ func packetFilterPermitsUnlockedNodes(peers map[tailcfg.NodeID]tailcfg.NodeView,
continue
}
numUnlocked++
- for _, pfx := range p.AllowedIPs().All() { // not only addresses!
+ p.AllowedIPs().All()(func(_ int, pfx netip.Prefix) bool { // not only addresses!
b.AddPrefix(pfx)
- }
+ return true
+ })
}
if numUnlocked == 0 {
return false
@@ -3324,13 +3311,16 @@ func (b *LocalBackend) WatchNotificationsAs(ctx context.Context, actor ipnauth.A
ini = &ipn.Notify{Version: version.Long()}
if mask&ipn.NotifyInitialState != 0 {
ini.SessionID = sessionID
- ini.State = new(b.state)
+ state := b.state
+ ini.State = &state
if b.state == ipn.NeedsLogin && b.authURL != "" {
- ini.BrowseToURL = new(b.authURL)
+ authURL := b.authURL
+ ini.BrowseToURL = &authURL
}
}
if mask&ipn.NotifyInitialPrefs != 0 {
- ini.Prefs = new(b.sanitizedPrefsLocked())
+ prefs := b.sanitizedPrefsLocked()
+ ini.Prefs = &prefs
}
if mask&ipn.NotifyInitialNetMap != 0 {
ini.NetMap = cn.NetMap()
@@ -3588,7 +3578,8 @@ func (b *LocalBackend) sendTo(n ipn.Notify, recipient notificationTarget) {
// sendToLocked is like [LocalBackend.sendTo], but assumes b.mu is already held.
func (b *LocalBackend) sendToLocked(n ipn.Notify, recipient notificationTarget) {
if n.Prefs != nil {
- n.Prefs = new(stripKeysFromPrefs(*n.Prefs))
+ prefs := stripKeysFromPrefs(*n.Prefs)
+ n.Prefs = &prefs
}
if n.Version == "" {
n.Version = version.Long()
@@ -3606,7 +3597,8 @@ func (b *LocalBackend) sendToLocked(n ipn.Notify, recipient notificationTarget)
if n.PeerChanges != nil {
// Take a shallow copy of n so we can elide the PeerChanges or the Netmap
// based on the session's mask.
- nOut = new(n)
+ nCopy := n
+ nOut = &nCopy
if sess.mask&ipn.NotifyPeerChanges != 0 {
// Skip the full Netmap
nOut.NetMap = nil
@@ -3625,7 +3617,7 @@ func (b *LocalBackend) sendToLocked(n ipn.Notify, recipient notificationTarget)
// setAuthURLLocked sets the authURL and triggers [LocalBackend.popBrowserAuthNow] if the URL has changed.
// This method is called when a new authURL is received from the control plane, meaning that either a user
-// has started a new interactive login (e.g., by running `tailscale login` or clicking Login in the GUI),
+// has started a new interactive login (e.g., by running ailscale login` or clicking Login in the GUI),
// or the control plane was unable to authenticate this node non-interactively (e.g., due to key expiration).
// A non-nil b.authActor indicates that an interactive login is in progress and was initiated by the specified actor.
//
@@ -4380,7 +4372,7 @@ func (b *LocalBackend) checkSSHPrefsLocked(p *ipn.Prefs) error {
// Assume that we do have the SSH capability if don't have a netmap yet.
if !b.currentNode().SelfHasCapOr(tailcfg.CapabilitySSH, true) {
if b.isDefaultServerLocked() {
- return errors.New("Unable to enable local Tailscale SSH server; not enabled on Tailnet. See https://tailscale.com/s/ssh")
+ return errors.New("Unable to enable local Tailscale SSH server; not enabled on Tailnet. See https://github.com/metacubex/tailscale/s/ssh")
}
return errors.New("Unable to enable local Tailscale SSH server; not enabled on Tailnet.")
}
@@ -4409,7 +4401,7 @@ func (b *LocalBackend) sshOnButUnusableHealthCheckMessageLocked() (healthMessage
if !isDefault {
return healthmsg.TailscaleSSHOnBut + "access controls don't allow anyone to access this device. Update your tailnet's ACLs to allow access."
}
- return healthmsg.TailscaleSSHOnBut + "access controls don't allow anyone to access this device. Update your tailnet's ACLs at https://tailscale.com/s/ssh-policy"
+ return healthmsg.TailscaleSSHOnBut + "access controls don't allow anyone to access this device. Update your tailnet's ACLs at https://github.com/metacubex/tailscale/s/ssh-policy"
}
func (b *LocalBackend) isDefaultServerLocked() bool {
@@ -4635,14 +4627,14 @@ func (b *LocalBackend) changeDisablesExitNodeLocked(prefs ipn.PrefsView, change
// First, apply the adjustments to a copy of the changes,
// e.g., clear AutoExitNode if ExitNodeID is set.
- tmpChange := new(*change)
+ tmpChange := *change
tmpChange.Prefs = *change.Prefs.Clone()
- b.adjustEditPrefsLocked(prefs, tmpChange)
+ b.adjustEditPrefsLocked(prefs, &tmpChange)
// Then apply the adjusted changes to a copy of the current prefs,
// and resolve the exit node in the prefs.
tmpPrefs := prefs.AsStruct()
- tmpPrefs.ApplyEdits(tmpChange)
+ tmpPrefs.ApplyEdits(&tmpChange)
b.resolveExitNodeInPrefsLocked(tmpPrefs)
// If ExitNodeID is empty after applying the changes,
@@ -4931,7 +4923,7 @@ func (b *LocalBackend) setPrefsLocked(newp *ipn.Prefs) ipn.PrefsView {
} else if prefs.WantRunning() {
// Reset the always-on override if WantRunning is true in the new prefs,
// such as when the user toggles the Connected switch in the GUI
- // or runs `tailscale up`.
+ // or runs ailscale up`.
b.resetAlwaysOnOverrideLocked()
}
@@ -5237,7 +5229,7 @@ func (b *LocalBackend) reconfigAppConnectorLocked(nm *netmap.NetworkMap, prefs i
if !buildfeatures.HasAppConnectors {
return
}
- const appConnectorCapName = "tailscale.com/app-connectors"
+ const appConnectorCapName = "github.com/metacubex/tailscale/app-connectors"
defer func() {
if b.hostinfo != nil {
b.hostinfo.AppConnector.Set(b.appConnector != nil)
@@ -5691,7 +5683,7 @@ func (b *LocalBackend) initPeerAPIListenerLocked() {
isNetstack := b.sys.IsNetstack()
peerAPIPorts := make(map[netip.Addr]int)
- for i, a := range addrs.All() {
+ addrs.All()(func(i int, a netip.Prefix) bool {
var ln net.Listener
var err error
skipListen := i > 0 && isNetstack
@@ -5706,15 +5698,15 @@ func (b *LocalBackend) initPeerAPIListenerLocked() {
b.logf("[v1] possibly transient peerapi listen(%q) error, will try again on linkChange: %v", a.Addr(), err)
// Expected. But we fix it later in linkChange
// ("peerAPIListeners too low").
- continue
+ return true
}
// Sandboxed macOS specifically requires the interface index to be non-zero.
if version.IsSandboxedMacOS() && tsIfIndex == 0 {
b.logf("[v1] peerapi listen(%q) error: interface index is 0 on darwin; try restarting tailscaled", a.Addr())
- continue
+ return true
}
b.logf("[unexpected] peerapi listen(%q) error: %v", a.Addr(), err)
- continue
+ return true
}
}
pln := &peerAPIListener{
@@ -5733,7 +5725,8 @@ func (b *LocalBackend) initPeerAPIListenerLocked() {
go pln.serve()
b.peerAPIListeners = append(b.peerAPIListeners, pln)
peerAPIPorts[a.Addr()] = pln.port
- }
+ return true
+ })
b.peerAPIPorts.Store(peerAPIPorts)
b.goTracker.Go(b.doSetHostinfoFilterServices)
@@ -6119,9 +6112,10 @@ func (b *LocalBackend) enterStateLocked(newState ipn.State) {
if feature.CanSystemdStatus {
var addrStrs []string
addrs := netMap.GetAddresses()
- for _, p := range addrs.All() {
+ addrs.All()(func(_ int, p netip.Prefix) bool {
addrStrs = append(addrStrs, p.Addr().String())
- }
+ return true
+ })
feature.SystemdStatus("Connected; %s; %s", activeLogin, strings.Join(addrStrs, " "))
}
default:
@@ -6522,7 +6516,8 @@ func (b *LocalBackend) resolveExitNodeLocked() (changed bool) {
b.goTracker.Go(b.doSetHostinfoFilterServices)
}
- b.sendToLocked(ipn.Notify{Prefs: new(prefs.View())}, allClients)
+ prefsView := prefs.View()
+ b.sendToLocked(ipn.Notify{Prefs: &prefsView}, allClients)
return true
}
@@ -6678,11 +6673,12 @@ func (b *LocalBackend) setNetMapLocked(nm *netmap.NetworkMap) {
b.metrics.approvedRoutes.Set(0)
} else if nm.SelfNode.Valid() {
var approved float64
- for _, route := range nm.SelfNode.AllowedIPs().All() {
+ nm.SelfNode.AllowedIPs().All()(func(_ int, route netip.Prefix) bool {
if !views.SliceContains(nm.SelfNode.Addresses(), route) && !tsaddr.IsExitRoute(route) {
approved++
}
- }
+ return true
+ })
b.metrics.approvedRoutes.Set(approved)
}
}
@@ -6900,14 +6896,15 @@ func (b *LocalBackend) SetDNS(ctx context.Context, name, value string) error {
func peerAPIPorts(peer tailcfg.NodeView) (p4, p6 uint16) {
svcs := peer.Hostinfo().Services()
- for _, s := range svcs.All() {
+ svcs.All()(func(_ int, s tailcfg.Service) bool {
switch s.Proto {
case tailcfg.PeerAPI4:
p4 = s.Port
case tailcfg.PeerAPI6:
p6 = s.Port
}
- }
+ return true
+ })
return
}
@@ -6971,7 +6968,7 @@ func (b *LocalBackend) CheckUDPGROForwarding() error {
// acting as Tailscale subnet routers or exit nodes. Currently (9/5/2024) this
// functionality is considered experimental and only safe to use via explicit
// user opt-in for ephemeral devices, such as containers.
-// https://tailscale.com/kb/1320/performance-best-practices#linux-optimizations-for-subnet-routers-and-exit-nodes
+// https://github.com/metacubex/tailscale/kb/1320/performance-best-practices#linux-optimizations-for-subnet-routers-and-exit-nodes
func (b *LocalBackend) SetUDPGROForwarding() error {
if b.sys.IsNetstackRouter() {
return errors.New("UDP GRO forwarding cannot be enabled in userspace mode")
@@ -7013,7 +7010,7 @@ func (b *LocalBackend) OfferingExitNode() bool {
}
var def4, def6 bool
ar := b.pm.CurrentPrefs().AdvertiseRoutes()
- for i := range ar.Len() {
+ for i := 0; i < ar.Len(); i++ {
r := ar.At(i)
if r.Bits() != 0 {
continue
@@ -7142,9 +7139,10 @@ func wireguardExitNodeDNSResolvers(nm *netmap.NetworkMap, peers map[tailcfg.Node
resolvers := p.ExitNodeDNSResolvers()
if !resolvers.IsNil() && resolvers.Len() > 0 {
copies := make([]*dnstype.Resolver, resolvers.Len())
- for i, r := range resolvers.All() {
+ resolvers.All()(func(i int, r dnstype.ResolverView) bool {
copies[i] = r.AsStruct()
- }
+ return true
+ })
return copies, true
}
}
@@ -7165,10 +7163,16 @@ func peerCanProxyDNS(p tailcfg.NodeView) bool {
// If p.Cap is not populated (e.g. older control server), then do the old
// thing of searching through services.
services := p.Hostinfo().Services()
- for _, s := range services.All() {
+ var ok bool
+ services.All()(func(_ int, s tailcfg.Service) bool {
if s.Proto == tailcfg.PeerAPIDNS && s.Port >= 1 {
- return true
+ ok = true
+ return false
}
+ return true
+ })
+ if ok {
+ return true
}
return false
}
@@ -7303,14 +7307,14 @@ var warnSyncDisabled = health.Register(&health.Warnable{
Code: "sync-disabled",
Title: "Tailscale Sync is Disabled",
Severity: health.SeverityHigh,
- Text: health.StaticMessage("Tailscale control plane syncing is disabled; run `tailscale set --sync` to restore"),
+ Text: health.StaticMessage("Tailscale control plane syncing is disabled; run ailscale set --sync` to restore"),
})
var warnSSHSELinuxWarnable = health.Register(&health.Warnable{
Code: "ssh-unavailable-selinux-enabled",
Title: "Tailscale SSH and SELinux",
Severity: health.SeverityLow,
- Text: health.StaticMessage("SELinux is enabled; Tailscale SSH may not work. See https://tailscale.com/s/ssh-selinux"),
+ Text: health.StaticMessage("SELinux is enabled; Tailscale SSH may not work. See https://github.com/metacubex/tailscale/s/ssh-selinux"),
})
// warnNoSNATWithExitNode is a warnable for when a node is advertising as an
@@ -7407,7 +7411,7 @@ func (b *LocalBackend) handleQuad100Port80Conn(w http.ResponseWriter, r *http.Re
return
}
io.WriteString(w, "Local addresses:
\n")
- for i := range addrs.Len() {
+ for i := 0; i < addrs.Len(); i++ {
fmt.Fprintf(w, "- %v
\n", addrs.At(i).Addr())
}
io.WriteString(w, "
\n")
@@ -7916,7 +7920,7 @@ func suggestExitNode(report *netcheck.Report, nb *nodeBackend, prevSuggestion ta
// The traffic-steering feature flag is enabled on this tailnet.
res, err = suggestExitNodeUsingTrafficSteering(nb, allowList)
default:
- // The control plane will always strip the `traffic-steering`
+ // The control plane will always strip the raffic-steering`
// node attribute if it isn’t enabled for this tailnet, even if
// it is set in the policy file: tailscale/corp#34401
res, err = suggestExitNodeUsingDERP(report, nb, prevSuggestion, selectRegion, selectNode, allowList)
@@ -8221,7 +8225,7 @@ func randomRegion(regions views.Slice[int]) int {
// present, otherwise a uniformly random node will be selected.
func randomNode(nodes views.Slice[tailcfg.NodeView], prefer tailcfg.StableNodeID) tailcfg.NodeView {
if !prefer.IsZero() {
- for i := range nodes.Len() {
+ for i := 0; i < nodes.Len(); i++ {
nv := nodes.At(i)
if nv.StableID() == prefer {
return nv
diff --git a/ipn/ipnlocal/local_test.go b/ipn/ipnlocal/local_test.go
index 21188d784019f..cb8ad3a163788 100644
--- a/ipn/ipnlocal/local_test.go
+++ b/ipn/ipnlocal/local_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,7 +11,8 @@ import (
"encoding/json"
"errors"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"math"
"net"
"net/http"
@@ -17,7 +20,6 @@ import (
"os"
"path/filepath"
"reflect"
- "slices"
"strings"
"sync"
"sync/atomic"
@@ -26,57 +28,57 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
+ "github.com/metacubex/tailscale/appc"
+ "github.com/metacubex/tailscale/appc/appctest"
+ "github.com/metacubex/tailscale/control/controlclient"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/drive/driveimpl"
+ "github.com/metacubex/tailscale/feature"
+ _ "github.com/metacubex/tailscale/feature/condregister/portmapper"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/conffile"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
+ "github.com/metacubex/tailscale/ipn/ipnlocal/netmapcache"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/net/netcheck"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstest/deptest"
+ "github.com/metacubex/tailscale/tstest/typewalk"
+ "github.com/metacubex/tailscale/types/appctype"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/syspolicy"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/policytest"
+ "github.com/metacubex/tailscale/util/syspolicy/source"
+ "github.com/metacubex/tailscale/wgengine"
+ "github.com/metacubex/tailscale/wgengine/filter"
+ "github.com/metacubex/tailscale/wgengine/filter/filtertype"
+ "github.com/metacubex/tailscale/wgengine/wgcfg"
memro "go4.org/mem"
"go4.org/netipx"
"golang.org/x/net/dns/dnsmessage"
- "tailscale.com/appc"
- "tailscale.com/appc/appctest"
- "tailscale.com/control/controlclient"
- "tailscale.com/control/controlknobs"
- "tailscale.com/drive"
- "tailscale.com/drive/driveimpl"
- "tailscale.com/feature"
- _ "tailscale.com/feature/condregister/portmapper"
- "tailscale.com/health"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn"
- "tailscale.com/ipn/conffile"
- "tailscale.com/ipn/ipnauth"
- "tailscale.com/ipn/ipnlocal/netmapcache"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/net/netcheck"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsaddr"
- "tailscale.com/net/tsdial"
- "tailscale.com/tailcfg"
- "tailscale.com/tsd"
- "tailscale.com/tstest"
- "tailscale.com/tstest/deptest"
- "tailscale.com/tstest/typewalk"
- "tailscale.com/types/appctype"
- "tailscale.com/types/dnstype"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/types/netmap"
- "tailscale.com/types/opt"
- "tailscale.com/types/persist"
- "tailscale.com/types/views"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/mak"
- "tailscale.com/util/must"
- "tailscale.com/util/set"
- "tailscale.com/util/syspolicy"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/policytest"
- "tailscale.com/util/syspolicy/source"
- "tailscale.com/wgengine"
- "tailscale.com/wgengine/filter"
- "tailscale.com/wgengine/filter/filtertype"
- "tailscale.com/wgengine/wgcfg"
)
func inRemove(ip netip.Addr) bool {
@@ -2854,7 +2856,7 @@ func TestReconfigureAppConnector(t *testing.T) {
Name: "example.ts.net",
Tags: []string{"tag:example"},
CapMap: (tailcfg.NodeCapMap)(map[tailcfg.NodeCapability][]tailcfg.RawMessage{
- "tailscale.com/app-connectors": {tailcfg.RawMessage(appCfg)},
+ "github.com/metacubex/tailscale/app-connectors": {tailcfg.RawMessage(appCfg)},
}),
}).View(),
}
@@ -4666,9 +4668,9 @@ func TestValidPopBrowserURL(t *testing.T) {
popBrowserURL string
want bool
}{
- {"saas_login", "https://login.tailscale.com", "https://login.tailscale.com/a/foo", true},
- {"saas_controlplane", "https://controlplane.tailscale.com", "https://controlplane.tailscale.com/a/foo", true},
- {"saas_root", "https://login.tailscale.com", "https://tailscale.com/", true},
+ {"saas_login", "https://login.tailscale.com", "https://login.github.com/metacubex/tailscale/a/foo", true},
+ {"saas_controlplane", "https://controlplane.tailscale.com", "https://controlplane.github.com/metacubex/tailscale/a/foo", true},
+ {"saas_root", "https://login.tailscale.com", "https://github.com/metacubex/tailscale/", true},
{"saas_bad_hostname", "https://login.tailscale.com", "https://example.com/a/foo", false},
{"localhost", "http://localhost", "http://localhost/a/foo", true},
{"custom_control_url_https", "https://example.com", "https://example.com/a/foo", true},
@@ -7542,9 +7544,9 @@ func TestDeps(t *testing.T) {
deptest.DepChecker{
OnImport: func(pkg string) {
switch pkg {
- case "tailscale.com/util/syspolicy",
- "tailscale.com/util/syspolicy/setting",
- "tailscale.com/util/syspolicy/rsop":
+ case "github.com/metacubex/tailscale/util/syspolicy",
+ "github.com/metacubex/tailscale/util/syspolicy/setting",
+ "github.com/metacubex/tailscale/util/syspolicy/rsop":
t.Errorf("ipn/ipnlocal: importing syspolicy package %q is not allowed; only policyclient and its deps should be used by ipn/ipnlocal", pkg)
}
},
diff --git a/ipn/ipnlocal/loglines_test.go b/ipn/ipnlocal/loglines_test.go
index 733c7381b2016..90960047f3ec8 100644
--- a/ipn/ipnlocal/loglines_test.go
+++ b/ipn/ipnlocal/loglines_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,17 +10,17 @@ import (
"testing"
"time"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/tailcfg"
- "tailscale.com/tsd"
- "tailscale.com/tstest"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/types/persist"
- "tailscale.com/wgengine"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/wgengine"
)
// TestLocalLogLines tests to make sure that the log lines required for log parsing are
diff --git a/ipn/ipnlocal/netmapcache/netmapcache.go b/ipn/ipnlocal/netmapcache/netmapcache.go
index 1b8347f0b8d18..63d00e2796f0a 100644
--- a/ipn/ipnlocal/netmapcache/netmapcache.go
+++ b/ipn/ipnlocal/netmapcache/netmapcache.go
@@ -7,27 +7,28 @@
package netmapcache
import (
- "cmp"
"context"
"crypto/sha256"
"encoding/hex"
jsonv1 "encoding/json"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io/fs"
- "iter"
"os"
"path/filepath"
- "slices"
"strings"
"time"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/tailcfg"
- "tailscale.com/types/netmap"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
- "tailscale.com/wgengine/filter"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/wgengine/filter"
)
var (
@@ -106,10 +107,10 @@ func (c *Cache) writeJSON(ctx context.Context, key cacheKey, v any) error {
func (c *Cache) removeUnwantedKeys(ctx context.Context) error {
var errs []error
- for key, err := range c.store.List(ctx, "") {
+ c.store.List(ctx, "")(func(key string, err error) bool {
if err != nil {
errs = append(errs, err)
- break
+ return false
}
ckey := cacheKey(key)
if !c.wantKeys.Contains(ckey) {
@@ -118,7 +119,8 @@ func (c *Cache) removeUnwantedKeys(ctx context.Context) error {
}
delete(c.lastWrote, ckey) // even if removal failed, we don't want it
}
- }
+ return true
+ })
return errors.Join(errs...)
}
@@ -202,7 +204,9 @@ func (c *Cache) Store(ctx context.Context, nm *netmap.NetworkMap) error {
return errors.New("no user in netmap")
}
- clear(c.wantKeys)
+ for k := range c.wantKeys {
+ delete(c.wantKeys, k)
+ }
if err := c.writeJSON(ctx, miscKey, netmapMisc{
MachineKey: &nm.MachineKey,
CollectServices: &nm.CollectServices,
@@ -274,12 +278,14 @@ func (c *Cache) Load(ctx context.Context) (*netmap.NetworkMap, error) {
if s := nm.SelfNode; s.Valid() {
nm.NodeKey = s.Key()
nm.AllCaps = make(set.Set[tailcfg.NodeCapability])
- for _, c := range s.Capabilities().All() {
+ s.Capabilities().All()(func(_ int, c tailcfg.NodeCapability) bool {
nm.AllCaps.Add(c)
- }
- for c := range s.CapMap().All() {
+ return true
+ })
+ s.CapMap().All()(func(c tailcfg.NodeCapability, _ views.Slice[tailcfg.RawMessage]) bool {
nm.AllCaps.Add(c)
- }
+ return true
+ })
}
// Unmarshal the contents of each specified cache entry directly into the
@@ -304,26 +310,39 @@ func (c *Cache) Load(ctx context.Context) (*netmap.NetworkMap, error) {
return nil, err
}
- for key, err := range c.store.List(ctx, string(peerKeyPrefix)) {
+ var listErr error
+ c.store.List(ctx, string(peerKeyPrefix))(func(key string, err error) bool {
if err != nil {
- return nil, err
+ listErr = err
+ return false
}
var peer tailcfg.NodeView
if err := c.readJSON(ctx, cacheKey(key), &netmapNode{Node: &peer}); err != nil {
- return nil, err
+ listErr = err
+ return false
}
nm.Peers = append(nm.Peers, peer)
+ return true
+ })
+ if listErr != nil {
+ return nil, listErr
}
slices.SortFunc(nm.Peers, func(a, b tailcfg.NodeView) int { return cmp.Compare(a.ID(), b.ID()) })
- for key, err := range c.store.List(ctx, string(userKeyPrefix)) {
+ c.store.List(ctx, string(userKeyPrefix))(func(key string, err error) bool {
if err != nil {
- return nil, err
+ listErr = err
+ return false
}
var up tailcfg.UserProfileView
if err := c.readJSON(ctx, cacheKey(key), &netmapUserProfile{UserProfile: &up}); err != nil {
- return nil, err
+ listErr = err
+ return false
}
mak.Set(&nm.UserProfiles, up.ID(), up)
+ return true
+ })
+ if listErr != nil {
+ return nil, listErr
}
if err := c.readJSON(ctx, sshPolicyKey, &netmapSSH{SSHPolicy: &nm.SSHPolicy}); err != nil {
return nil, err
diff --git a/ipn/ipnlocal/netmapcache/netmapcache_test.go b/ipn/ipnlocal/netmapcache/netmapcache_test.go
index ca66a17133a5e..3f770c237652b 100644
--- a/ipn/ipnlocal/netmapcache/netmapcache_test.go
+++ b/ipn/ipnlocal/netmapcache/netmapcache_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,28 +11,28 @@ import (
"errors"
"flag"
"fmt"
- "iter"
- "maps"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"os"
"reflect"
- "slices"
"strings"
"testing"
"github.com/creachadair/mds/mtest"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/ipn/ipnlocal/netmapcache"
- "tailscale.com/tailcfg"
- "tailscale.com/tka"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/key"
- "tailscale.com/types/netmap"
- "tailscale.com/types/views"
- "tailscale.com/util/set"
- "tailscale.com/wgengine/filter"
- "tailscale.com/wgengine/filter/filtertype"
+ "github.com/metacubex/tailscale/ipn/ipnlocal/netmapcache"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/wgengine/filter"
+ "github.com/metacubex/tailscale/wgengine/filter/filtertype"
)
// Input values for valid-looking placeholder values for keys, hashes, etc.
@@ -83,7 +85,7 @@ func init() {
CapGrant: []tailcfg.CapGrant{{
Dsts: []netip.Prefix{netip.MustParsePrefix("192.168.4.0/24")},
CapMap: tailcfg.PeerCapMap{
- "tailscale.com/testcap": []tailcfg.RawMessage{`"apple"`, `"pear"`},
+ "github.com/metacubex/tailscale/testcap": []tailcfg.RawMessage{`"apple"`, `"pear"`},
},
}},
},
diff --git a/ipn/ipnlocal/netmapcache/types.go b/ipn/ipnlocal/netmapcache/types.go
index c9f9efc1e3b21..dbb285ef8e0e8 100644
--- a/ipn/ipnlocal/netmapcache/types.go
+++ b/ipn/ipnlocal/netmapcache/types.go
@@ -4,10 +4,10 @@
package netmapcache
import (
- "tailscale.com/tailcfg"
- "tailscale.com/tka"
- "tailscale.com/types/key"
- "tailscale.com/types/views"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/views"
)
// The fields in the following wrapper types are all pointers, even when their
diff --git a/ipn/ipnlocal/netstack.go b/ipn/ipnlocal/netstack.go
index eac9568b7f765..215de3e5f213b 100644
--- a/ipn/ipnlocal/netstack.go
+++ b/ipn/ipnlocal/netstack.go
@@ -10,7 +10,7 @@ import (
"net/netip"
"time"
- "gvisor.dev/gvisor/pkg/tcpip"
+ "github.com/metacubex/gvisor/pkg/tcpip"
)
// TCPHandlerForDst returns a TCP handler for connections to dst, or nil if
@@ -51,7 +51,8 @@ func (b *LocalBackend) TCPHandlerForDst(src, dst netip.AddrPort) (handler func(c
// tell the difference between a long lived connection that is idle
// vs a connection that is dead because the peer has gone away.
// We pick 72h as that is typically sufficient for a long weekend.
- opts = append(opts, new(tcpip.KeepaliveIdleOption(72*time.Hour)))
+ keepaliveIdle := tcpip.KeepaliveIdleOption(72 * time.Hour)
+ opts = append(opts, &keepaliveIdle)
return b.handleSSHConn, opts
}
// TODO(will,sonia): allow customizing web client port ?
diff --git a/ipn/ipnlocal/network-lock.go b/ipn/ipnlocal/network-lock.go
index 75d5d95114162..8d4eb0db7c89b 100644
--- a/ipn/ipnlocal/network-lock.go
+++ b/ipn/ipnlocal/network-lock.go
@@ -15,31 +15,31 @@ import (
"encoding/json"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net/http"
"net/netip"
"os"
"path/filepath"
- "slices"
"time"
- "tailscale.com/health"
- "tailscale.com/health/healthmsg"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/net/tsaddr"
- "tailscale.com/tailcfg"
- "tailscale.com/tka"
- "tailscale.com/tsconst"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/types/persist"
- "tailscale.com/types/tkatype"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/health/healthmsg"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/tsconst"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/types/tkatype"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/testenv"
)
// TODO(tom): RPC retry/backoff was broken and has been removed. Fix?
@@ -485,10 +485,16 @@ func (b *LocalBackend) tkaBootstrapFromGenesisLocked(g tkatype.MarshaledAUM, per
}
bootstrapStateID := fmt.Sprintf("%d:%d", genesis.State.StateID1, genesis.State.StateID2)
- for _, stateID := range persist.DisallowedTKAStateIDs().All() {
+ var disallowed bool
+ persist.DisallowedTKAStateIDs().All()(func(_ int, stateID string) bool {
if stateID == bootstrapStateID {
- return fmt.Errorf("TKA with stateID of %q is disallowed on this node", stateID)
+ disallowed = true
+ return false
}
+ return true
+ })
+ if disallowed {
+ return fmt.Errorf("TKA with stateID of %q is disallowed on this node", bootstrapStateID)
}
}
@@ -575,7 +581,7 @@ func (b *LocalBackend) NetworkLockStatus() *ipnstate.NetworkLockStatus {
}
filtered := make([]*ipnstate.TKAPeer, len(b.tka.filtered))
- for i := range len(filtered) {
+ for i := 0; i < len(filtered); i++ {
filtered[i] = b.tka.filtered[i].Clone()
}
@@ -612,11 +618,12 @@ func tkaStateFromPeer(p tailcfg.NodeView) ipnstate.TKAPeer {
TailscaleIPs: make([]netip.Addr, 0, p.Addresses().Len()),
NodeKey: p.Key(),
}
- for _, addr := range p.Addresses().All() {
+ p.Addresses().All()(func(_ int, addr netip.Prefix) bool {
if addr.IsSingleIP() && tsaddr.IsTailscaleIP(addr.Addr()) {
fp.TailscaleIPs = append(fp.TailscaleIPs, addr.Addr())
}
- }
+ return true
+ })
var decoded tka.NodeKeySignature
if err := decoded.Unserialize(p.KeySignature().AsSlice()); err == nil {
fp.NodeKeySignature = decoded
@@ -926,7 +933,7 @@ func (b *LocalBackend) NetworkLockLog(maxEntries int) ([]ipnstate.NetworkLockUpd
var out []ipnstate.NetworkLockUpdate
cursor := b.tka.authority.Head()
- for range maxEntries {
+ for i := 0; i < maxEntries; i++ {
aum, err := b.tka.storage.AUM(cursor)
if err != nil {
if err == os.ErrNotExist {
diff --git a/ipn/ipnlocal/network-lock_test.go b/ipn/ipnlocal/network-lock_test.go
index 1fceb748a32ce..a1d235152dcf8 100644
--- a/ipn/ipnlocal/network-lock_test.go
+++ b/ipn/ipnlocal/network-lock_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_tailnetlock
-
package ipnlocal
import (
@@ -22,25 +22,25 @@ import (
go4mem "go4.org/mem"
"github.com/google/go-cmp/cmp"
- "tailscale.com/control/controlclient"
- "tailscale.com/health"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsdial"
- "tailscale.com/tailcfg"
- "tailscale.com/tka"
- "tailscale.com/tsd"
- "tailscale.com/tstest"
- "tailscale.com/tstest/tkatest"
- "tailscale.com/types/key"
- "tailscale.com/types/netmap"
- "tailscale.com/types/persist"
- "tailscale.com/types/tkatype"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/must"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/control/controlclient"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstest/tkatest"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/types/tkatype"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/set"
)
func fakeControlClient(t *testing.T, c *http.Client) *controlclient.Auto {
diff --git a/ipn/ipnlocal/node_backend.go b/ipn/ipnlocal/node_backend.go
index 59c26ebe5a041..ab33479fce5bd 100644
--- a/ipn/ipnlocal/node_backend.go
+++ b/ipn/ipnlocal/node_backend.go
@@ -4,33 +4,33 @@
package ipnlocal
import (
- "cmp"
"context"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
"sync"
"sync/atomic"
+ "github.com/metacubex/tailscale/appc"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/net/dns"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/util/testenv"
+ "github.com/metacubex/tailscale/wgengine/filter"
"go4.org/netipx"
- "tailscale.com/appc"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/ipn"
- "tailscale.com/net/dns"
- "tailscale.com/net/tsaddr"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/types/dnstype"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/types/views"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/mak"
- "tailscale.com/util/slicesx"
- "tailscale.com/util/testenv"
- "tailscale.com/wgengine/filter"
)
// nodeBackend is node-specific [LocalBackend] state. It is usually the current node.
@@ -318,7 +318,7 @@ func (nb *nodeBackend) peerCapsLocked(src netip.Addr) tailcfg.PeerCapMap {
return nil
}
addrs := nb.netMap.GetAddresses()
- for i := range addrs.Len() {
+ for i := 0; i < addrs.Len(); i++ {
a := addrs.At(i)
if !a.IsSingleIP() {
continue
@@ -380,12 +380,15 @@ func (nb *nodeBackend) PeerHasCap(peer tailcfg.NodeView, wantCap tailcfg.PeerCap
nb.mu.Lock()
defer nb.mu.Unlock()
- for _, ap := range peer.Addresses().All() {
+ var ok bool
+ peer.Addresses().All()(func(_ int, ap netip.Prefix) bool {
if nb.peerHasCapLocked(ap.Addr(), wantCap) {
- return true
+ ok = true
+ return false
}
- }
- return false
+ return true
+ })
+ return ok
}
func (nb *nodeBackend) peerHasCapLocked(addr netip.Addr, wantCap tailcfg.PeerCapability) bool {
@@ -440,12 +443,15 @@ func (nb *nodeBackend) peerIsReachable(ctx context.Context, p tailcfg.NodeView)
}
func nodeIP(n tailcfg.NodeView, pred func(netip.Addr) bool) netip.Addr {
- for _, pfx := range n.Addresses().All() {
+ var ip netip.Addr
+ n.Addresses().All()(func(_ int, pfx netip.Prefix) bool {
if pfx.IsSingleIP() && pred(pfx.Addr()) {
- return pfx.Addr()
+ ip = pfx.Addr()
+ return false
}
- }
- return netip.Addr{}
+ return true
+ })
+ return ip
}
func (nb *nodeBackend) NetMap() *netmap.NetworkMap {
@@ -460,12 +466,12 @@ func (nb *nodeBackend) netMapWithPeers() *netmap.NetworkMap {
if nb.netMap == nil {
return nil
}
- nm := new(*nb.netMap) // shallow clone
+ nm := *nb.netMap // shallow clone
nm.Peers = slicesx.MapValues(nb.peers)
slices.SortFunc(nm.Peers, func(a, b tailcfg.NodeView) int {
return cmp.Compare(a.ID(), b.ID())
})
- return nm
+ return &nm
}
func (nb *nodeBackend) SetNetMap(nm *netmap.NetworkMap) {
@@ -536,11 +542,12 @@ func (nb *nodeBackend) updateNodeByAddrLocked() {
nb.nodeByAddr[k] = 0
}
addNode := func(n tailcfg.NodeView) {
- for _, ipp := range n.Addresses().All() {
+ n.Addresses().All()(func(_ int, ipp netip.Prefix) bool {
if ipp.IsSingleIP() {
nb.nodeByAddr[ipp.Addr()] = n.ID()
}
- }
+ return true
+ })
}
if nm.SelfNode.Valid() {
addNode(nm.SelfNode)
@@ -820,19 +827,20 @@ func dnsConfigForNetmap(nm *netmap.NetworkMap, peers map[tailcfg.NodeID]tailcfg.
return // TODO: propagate error?
}
var have4 bool
- for _, addr := range addrs.All() {
+ addrs.All()(func(_ int, addr netip.Prefix) bool {
if addr.Addr().Is4() {
have4 = true
- break
+ return false
}
- }
+ return true
+ })
var ips []netip.Addr
- for _, addr := range addrs.All() {
+ addrs.All()(func(_ int, addr netip.Prefix) bool {
if selfV6Only {
if addr.Addr().Is6() {
ips = append(ips, addr.Addr())
}
- continue
+ return true
}
// If this node has an IPv4 address, then
// remove peers' IPv6 addresses for now, as we
@@ -843,10 +851,11 @@ func dnsConfigForNetmap(nm *netmap.NetworkMap, peers map[tailcfg.NodeID]tailcfg.
// tracks adding the right capability reporting to
// enable AAAA in MagicDNS.
if addr.Addr().Is6() && have4 && !wantAAAA {
- continue
+ return true
}
ips = append(ips, addr.Addr())
- }
+ return true
+ })
dcfg.Hosts[fqdn] = ips
}
set(nm.SelfName(), nm.GetAddresses())
diff --git a/ipn/ipnlocal/node_backend_test.go b/ipn/ipnlocal/node_backend_test.go
index ca61624b8419b..e1fc611325534 100644
--- a/ipn/ipnlocal/node_backend_test.go
+++ b/ipn/ipnlocal/node_backend_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,10 +11,10 @@ import (
"testing"
"time"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/types/netmap"
- "tailscale.com/util/eventbus"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/eventbus"
)
func TestNodeBackendReadiness(t *testing.T) {
diff --git a/ipn/ipnlocal/peerapi.go b/ipn/ipnlocal/peerapi.go
index d72a519ab1feb..3557ff600f739 100644
--- a/ipn/ipnlocal/peerapi.go
+++ b/ipn/ipnlocal/peerapi.go
@@ -9,6 +9,7 @@ import (
"encoding/json"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"hash/crc32"
"html"
"io"
@@ -17,28 +18,27 @@ import (
"net/netip"
"os"
"runtime"
- "slices"
"strconv"
"strings"
"sync"
"time"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netutil"
+ "github.com/metacubex/tailscale/net/sockstats"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/wgengine/filter"
"golang.org/x/net/dns/dnsmessage"
"golang.org/x/net/http/httpguts"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/health"
- "tailscale.com/hostinfo"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netutil"
- "tailscale.com/net/sockstats"
- "tailscale.com/tailcfg"
- "tailscale.com/types/netmap"
- "tailscale.com/types/views"
- "tailscale.com/util/clientmetric"
- "tailscale.com/wgengine/filter"
)
// initListenConfig, if non-nil, is called during peerAPIListener setup. It is used only
@@ -103,7 +103,7 @@ func (s *peerAPIServer) listen(ip netip.Addr, tunIfIndex int) (ln net.Listener,
// deterministic that people will bake this into clients.
// We try a few times just in case something's already
// listening on that port (on all interfaces, probably).
- for try := range uint8(5) {
+ for try := uint8(0); try < 5; try++ {
a16 := ip.As16()
hashData := a16[len(a16)-3:]
hashData[0] += try
@@ -207,11 +207,8 @@ func (pln *peerAPIListener) ServeConn(src netip.AddrPort, c net.Conn) {
peerUser: peerUser,
}
httpServer := &http.Server{
- Handler: h,
- Protocols: new(http.Protocols),
+ Handler: h,
}
- httpServer.Protocols.SetHTTP1(true)
- httpServer.Protocols.SetUnencryptedHTTP2(true) // over WireGuard; "unencrypted" means no TLS
go httpServer.Serve(netutil.NewOneConnListener(c, nil))
}
@@ -226,7 +223,7 @@ type peerAPIHandler struct {
}
// PeerAPIHandler is the interface implemented by [peerAPIHandler] and needed by
-// module features registered via tailscale.com/feature/*.
+// module features registered via github.com/metacubex/tailscale/feature/*.
type PeerAPIHandler interface {
Peer() tailcfg.NodeView
PeerCaps() tailcfg.PeerCapMap
@@ -973,9 +970,9 @@ func peerAPIBase(nm *netmap.NetworkMap, peer tailcfg.NodeView) string {
var have4, have6 bool
addrs := nm.GetAddresses()
- for _, a := range addrs.All() {
+ addrs.All()(func(_ int, a netip.Prefix) bool {
if !a.IsSingleIP() {
- continue
+ return true
}
switch {
case a.Addr().Is4():
@@ -983,7 +980,8 @@ func peerAPIBase(nm *netmap.NetworkMap, peer tailcfg.NodeView) string {
case a.Addr().Is6():
have6 = true
}
- }
+ return true
+ })
p4, p6 := peerAPIPorts(peer)
switch {
case have4 && p4 != 0:
diff --git a/ipn/ipnlocal/peerapi_drive.go b/ipn/ipnlocal/peerapi_drive.go
index d42843577059b..9bfeb284adc75 100644
--- a/ipn/ipnlocal/peerapi_drive.go
+++ b/ipn/ipnlocal/peerapi_drive.go
@@ -10,9 +10,9 @@ import (
"path/filepath"
"strings"
- "tailscale.com/drive"
- "tailscale.com/tailcfg"
- "tailscale.com/util/httpm"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/httpm"
)
const (
diff --git a/ipn/ipnlocal/peerapi_macios_ext.go b/ipn/ipnlocal/peerapi_macios_ext.go
index 70c1fb850e249..3c589f351a6f1 100644
--- a/ipn/ipnlocal/peerapi_macios_ext.go
+++ b/ipn/ipnlocal/peerapi_macios_ext.go
@@ -9,7 +9,7 @@ import (
"net"
"net/netip"
- "tailscale.com/net/netns"
+ "github.com/metacubex/tailscale/net/netns"
)
func init() {
diff --git a/ipn/ipnlocal/peerapi_test.go b/ipn/ipnlocal/peerapi_test.go
index 63abf089c2abc..fbd99065e2d81 100644
--- a/ipn/ipnlocal/peerapi_test.go
+++ b/ipn/ipnlocal/peerapi_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,31 +8,31 @@ package ipnlocal
import (
"context"
"encoding/json"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/http"
"net/http/httptest"
"net/netip"
- "slices"
"strings"
"testing"
+ "github.com/metacubex/tailscale/appc"
+ "github.com/metacubex/tailscale/appc/appctest"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/appctype"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/usermetric"
+ "github.com/metacubex/tailscale/wgengine"
+ "github.com/metacubex/tailscale/wgengine/filter"
"go4.org/netipx"
"golang.org/x/net/dns/dnsmessage"
- "tailscale.com/appc"
- "tailscale.com/appc/appctest"
- "tailscale.com/health"
- "tailscale.com/ipn"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/tailcfg"
- "tailscale.com/tsd"
- "tailscale.com/tstest"
- "tailscale.com/types/appctype"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/must"
- "tailscale.com/util/usermetric"
- "tailscale.com/wgengine"
- "tailscale.com/wgengine/filter"
)
type peerAPITestEnv struct {
diff --git a/ipn/ipnlocal/prefs_metrics.go b/ipn/ipnlocal/prefs_metrics.go
index 7e7a2a5e3a1d0..f92cabc54b14d 100644
--- a/ipn/ipnlocal/prefs_metrics.go
+++ b/ipn/ipnlocal/prefs_metrics.go
@@ -6,10 +6,10 @@ package ipnlocal
import (
"errors"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/ipn"
- "tailscale.com/tailcfg"
- "tailscale.com/util/clientmetric"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/clientmetric"
)
// Counter metrics for edit/change events
diff --git a/ipn/ipnlocal/profiles.go b/ipn/ipnlocal/profiles.go
index 4e073e5c9aeba..02e4bcc6f6e7d 100644
--- a/ipn/ipnlocal/profiles.go
+++ b/ipn/ipnlocal/profiles.go
@@ -4,29 +4,29 @@
package ipnlocal
import (
- "cmp"
"crypto"
"crypto/rand"
"encoding/json"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"runtime"
- "slices"
"strings"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/health"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnext"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/persist"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnext"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/testenv"
)
var debug = envknob.RegisterBool("TS_DEBUG_PROFILES")
diff --git a/ipn/ipnlocal/profiles_notwindows.go b/ipn/ipnlocal/profiles_notwindows.go
index 389dedc9e7015..f5e0b2365ff52 100644
--- a/ipn/ipnlocal/profiles_notwindows.go
+++ b/ipn/ipnlocal/profiles_notwindows.go
@@ -9,8 +9,8 @@ import (
"fmt"
"runtime"
- "tailscale.com/ipn"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/version"
)
func (pm *profileManager) loadLegacyPrefs(ipn.WindowsUserID) (string, ipn.PrefsView, error) {
diff --git a/ipn/ipnlocal/profiles_test.go b/ipn/ipnlocal/profiles_test.go
index ec92673e50b29..0162255153850 100644
--- a/ipn/ipnlocal/profiles_test.go
+++ b/ipn/ipnlocal/profiles_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -13,17 +15,17 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- _ "tailscale.com/clientupdate" // for feature registration side effects
- "tailscale.com/feature"
- "tailscale.com/health"
- "tailscale.com/ipn"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/persist"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/must"
+ _ "github.com/metacubex/tailscale/clientupdate" // for feature registration side effects
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/must"
)
func TestProfileCurrentUserSwitch(t *testing.T) {
diff --git a/ipn/ipnlocal/profiles_windows.go b/ipn/ipnlocal/profiles_windows.go
index a0b5bbfdd49fb..f3667796925ec 100644
--- a/ipn/ipnlocal/profiles_windows.go
+++ b/ipn/ipnlocal/profiles_windows.go
@@ -11,9 +11,9 @@ import (
"os/user"
"path/filepath"
- "tailscale.com/atomicfile"
- "tailscale.com/ipn"
- "tailscale.com/util/winutil/policy"
+ "github.com/metacubex/tailscale/atomicfile"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/util/winutil/policy"
)
const (
diff --git a/ipn/ipnlocal/serve.go b/ipn/ipnlocal/serve.go
index 83b8027d7c02c..a1722e98bb6fd 100644
--- a/ipn/ipnlocal/serve.go
+++ b/ipn/ipnlocal/serve.go
@@ -15,8 +15,9 @@ import (
"encoding/json"
"errors"
"fmt"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
- "maps"
"mime"
"net"
"net/http"
@@ -25,7 +26,6 @@ import (
"net/url"
"os"
"path"
- "slices"
"strconv"
"strings"
"sync"
@@ -33,22 +33,22 @@ import (
"time"
"unicode/utf8"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netutil"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/backoff"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/ctxkey"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/version"
"github.com/pires/go-proxyproto"
"go4.org/mem"
- "tailscale.com/ipn"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netutil"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/types/lazy"
- "tailscale.com/types/logger"
- "tailscale.com/types/views"
- "tailscale.com/util/backoff"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/ctxkey"
- "tailscale.com/util/mak"
- "tailscale.com/util/slicesx"
- "tailscale.com/version"
)
func init() {
@@ -287,7 +287,7 @@ func (b *LocalBackend) updateServeTCPPortNetMapAddrListenersLocked(ports []uint1
}
addrs := nm.GetAddresses()
- for _, a := range addrs.All() {
+ addrs.All()(func(_ int, a netip.Prefix) bool {
for _, p := range ports {
addrPort := netip.AddrPortFrom(a.Addr(), p)
if _, ok := b.serveListeners[addrPort]; ok {
@@ -299,7 +299,8 @@ func (b *LocalBackend) updateServeTCPPortNetMapAddrListenersLocked(ports []uint1
go sl.Run()
}
- }
+ return true
+ })
}
func generateServeConfigETag(sc ipn.ServeConfigView) (string, error) {
@@ -382,7 +383,7 @@ func (b *LocalBackend) setServeConfigLocked(config *ipn.ServeConfig, etag string
if b.serveConfig.Valid() {
has = b.serveConfig.Foreground().Contains
}
- for k := range prevConfig.Foreground().All() {
+ prevConfig.Foreground().All()(func(k string, _ ipn.ServeConfigView) bool {
if !has(k) {
for _, sess := range b.notifyWatchers {
if sess.sessionID == k {
@@ -390,7 +391,8 @@ func (b *LocalBackend) setServeConfigLocked(config *ipn.ServeConfig, etag string
}
}
}
- }
+ return true
+ })
}
return nil
@@ -506,15 +508,16 @@ func (b *LocalBackend) vipServicesFromPrefsLocked(prefs ipn.PrefsView) []*tailcf
// keyed by service name
var services map[tailcfg.ServiceName]*tailcfg.VIPService
if b.serveConfig.Valid() {
- for svc, config := range b.serveConfig.Services().All() {
+ b.serveConfig.Services().All()(func(svc tailcfg.ServiceName, config ipn.ServiceConfigView) bool {
mak.Set(&services, svc, &tailcfg.VIPService{
Name: svc,
Ports: config.ServicePortRange(),
})
- }
+ return true
+ })
}
- for _, s := range prefs.AdvertiseServices().All() {
+ prefs.AdvertiseServices().All()(func(_ int, s string) bool {
sn := tailcfg.ServiceName(s)
if services == nil || services[sn] == nil {
mak.Set(&services, sn, &tailcfg.VIPService{
@@ -522,7 +525,8 @@ func (b *LocalBackend) vipServicesFromPrefsLocked(prefs ipn.PrefsView) []*tailcf
})
}
services[sn].Active = true
- }
+ return true
+ })
servicesList := slicesx.MapValues(services)
// [slicesx.MapValues] provides the values in an indeterminate order, but since we'll
@@ -996,10 +1000,7 @@ func (rp *reverseProxy) getTransport() *http.Transport {
// The Transport gets created lazily, at most once.
func (rp *reverseProxy) getH2CTransport() http.RoundTripper {
return rp.h2cTransport.Get(func() *http.Transport {
- var p http.Protocols
- p.SetUnencryptedHTTP2(true)
tr := &http.Transport{
- Protocols: &p,
DialTLSContext: func(ctx context.Context, network string, addr string) (net.Conn, error) {
if rp.socketPath != "" {
var d net.Dialer
@@ -1281,7 +1282,7 @@ func expandProxyArg(s string) (targetURL string, insecureSkipVerify bool) {
}
func allNumeric(s string) bool {
- for i := range len(s) {
+ for i := 0; i < len(s); i++ {
if s[i] < '0' || s[i] > '9' {
return false
}
@@ -1338,16 +1339,16 @@ func (b *LocalBackend) setServeProxyHandlersLocked() {
return
}
var backends map[string]bool
- for _, conf := range b.serveConfig.Webs() {
- for _, h := range conf.Handlers().All() {
+ b.serveConfig.Webs()(func(_ ipn.HostPort, conf ipn.WebServerConfigView) bool {
+ conf.Handlers().All()(func(_ string, h ipn.HTTPHandlerView) bool {
backend := h.Proxy()
if backend == "" {
// Only create proxy handlers for servers with a proxy backend.
- continue
+ return true
}
mak.Set(&backends, backend, true)
if _, ok := b.serveProxyHandlers.Load(backend); ok {
- continue
+ return true
}
b.logf("serve: creating a new proxy handler for %s", backend)
@@ -1356,11 +1357,13 @@ func (b *LocalBackend) setServeProxyHandlersLocked() {
// The backend endpoint (h.Proxy) should have been validated by expandProxyTarget
// in the CLI, so just log the error here.
b.logf("[unexpected] could not create proxy for %v: %s", backend, err)
- continue
+ return true
}
b.serveProxyHandlers.Store(backend, p)
- }
- }
+ return true
+ })
+ return true
+ })
// Clean up handlers for proxy backends that are no longer present
// in configuration.
@@ -1497,26 +1500,29 @@ func serveSetTCPPortsInterceptedFromNetmapAndPrefsLocked(b *LocalBackend, prefs
b.reloadServeConfigLocked(prefs)
if b.serveConfig.Valid() {
servePorts := make([]uint16, 0, 3)
- for port := range b.serveConfig.TCPs() {
+ b.serveConfig.TCPs()(func(port uint16, _ ipn.TCPPortHandlerView) bool {
if port > 0 {
servePorts = append(servePorts, uint16(port))
}
- }
+ return true
+ })
handlePorts = append(handlePorts, servePorts...)
- for svc, cfg := range b.serveConfig.Services().All() {
+ b.serveConfig.Services().All()(func(svc tailcfg.ServiceName, cfg ipn.ServiceConfigView) bool {
servicePorts := make([]uint16, 0, 3)
- for port := range cfg.TCP().All() {
+ cfg.TCP().All()(func(port uint16, _ ipn.TCPPortHandlerView) bool {
if port > 0 {
servicePorts = append(servicePorts, uint16(port))
}
- }
+ return true
+ })
if _, ok := vipServicesPorts[svc]; !ok {
mak.Set(&vipServicesPorts, svc, servicePorts)
} else {
mak.Set(&vipServicesPorts, svc, append(vipServicesPorts[svc], servicePorts...))
}
- }
+ return true
+ })
b.setServeProxyHandlersLocked()
@@ -1665,12 +1671,18 @@ func validateServeConfigUpdate(existing, incoming ipn.ServeConfigView) error {
}
// For Services, TUN mode is mutually exclusive with L4 or L7 handlers.
- for svcName, svcCfg := range incoming.Services().All() {
+ var err error
+ incoming.Services().All()(func(svcName tailcfg.ServiceName, svcCfg ipn.ServiceConfigView) bool {
hasTCP := svcCfg.TCP().Len() > 0
hasWeb := svcCfg.Web().Len() > 0
if svcCfg.Tun() && (hasTCP || hasWeb) {
- return fmt.Errorf("cannot configure TUN mode in combination with TCP or web handlers for %s", svcName)
+ err = fmt.Errorf("cannot configure TUN mode in combination with TCP or web handlers for %s", svcName)
+ return false
}
+ return true
+ })
+ if err != nil {
+ return err
}
if !existing.Valid() {
@@ -1678,57 +1690,78 @@ func validateServeConfigUpdate(existing, incoming ipn.ServeConfigView) error {
}
// New foreground listeners must be on open ports.
- for sessionID, incomingFg := range incoming.Foreground().All() {
+ incoming.Foreground().All()(func(sessionID string, incomingFg ipn.ServeConfigView) bool {
if !existing.Foreground().Has(sessionID) {
// This is a new session.
- for port := range incomingFg.TCPs() {
+ incomingFg.TCPs()(func(port uint16, _ ipn.TCPPortHandlerView) bool {
if _, exists := existing.FindTCP(port); exists {
- return fmt.Errorf("listener already exists for port %d", port)
+ err = fmt.Errorf("listener already exists for port %d", port)
+ return false
}
- }
+ return true
+ })
}
+ return err == nil
+ })
+ if err != nil {
+ return err
}
// New background listeners cannot overwrite existing foreground listeners.
- for port := range incoming.TCP().All() {
+ incoming.TCP().All()(func(port uint16, _ ipn.TCPPortHandlerView) bool {
if _, exists := existing.FindForegroundTCP(port); exists {
- return fmt.Errorf("foreground listener already exists for port %d", port)
+ err = fmt.Errorf("foreground listener already exists for port %d", port)
+ return false
}
+ return true
+ })
+ if err != nil {
+ return err
}
// Incoming configuration cannot change the serve type in use by a port.
- for port, incomingHandler := range incoming.TCP().All() {
+ incoming.TCP().All()(func(port uint16, incomingHandler ipn.TCPPortHandlerView) bool {
existingHandler, exists := existing.FindTCP(port)
if !exists {
- continue
+ return true
}
existingServeType := serveTypeFromPortHandler(existingHandler)
incomingServeType := serveTypeFromPortHandler(incomingHandler)
if incomingServeType != existingServeType {
- return fmt.Errorf("want to serve %q, but port %d is already serving %q", incomingServeType, port, existingServeType)
+ err = fmt.Errorf("want to serve %q, but port %d is already serving %q", incomingServeType, port, existingServeType)
+ return false
}
+ return true
+ })
+ if err != nil {
+ return err
}
// Validations for Tailscale Services.
- for svcName, incomingSvcCfg := range incoming.Services().All() {
+ incoming.Services().All()(func(svcName tailcfg.ServiceName, incomingSvcCfg ipn.ServiceConfigView) bool {
existingSvcCfg, exists := existing.Services().GetOk(svcName)
if !exists {
- continue
+ return true
}
// Incoming configuration cannot change the serve type in use by a port.
- for port, incomingHandler := range incomingSvcCfg.TCP().All() {
+ incomingSvcCfg.TCP().All()(func(port uint16, incomingHandler ipn.TCPPortHandlerView) bool {
existingHandler, exists := existingSvcCfg.TCP().GetOk(port)
if !exists {
- continue
+ return true
}
existingServeType := serveTypeFromPortHandler(existingHandler)
incomingServeType := serveTypeFromPortHandler(incomingHandler)
if incomingServeType != existingServeType {
- return fmt.Errorf("want to serve %q, but port %d is already serving %q for %s", incomingServeType, port, existingServeType, svcName)
+ err = fmt.Errorf("want to serve %q, but port %d is already serving %q for %s", incomingServeType, port, existingServeType, svcName)
+ return false
}
+ return true
+ })
+ if err != nil {
+ return false
}
existingHasTCP := existingSvcCfg.TCP().Len() > 0
@@ -1736,7 +1769,8 @@ func validateServeConfigUpdate(existing, incoming ipn.ServeConfigView) error {
// A Service cannot turn on TUN mode if TCP or web handlers exist.
if incomingSvcCfg.Tun() && (existingHasTCP || existingHasWeb) {
- return fmt.Errorf("cannot turn on TUN mode with existing TCP or web handlers for %s", svcName)
+ err = fmt.Errorf("cannot turn on TUN mode with existing TCP or web handlers for %s", svcName)
+ return false
}
incomingHasTCP := incomingSvcCfg.TCP().Len() > 0
@@ -1744,8 +1778,13 @@ func validateServeConfigUpdate(existing, incoming ipn.ServeConfigView) error {
// A Service cannot add TCP or web handlers if TUN mode is enabled.
if (incomingHasTCP || incomingHasWeb) && existingSvcCfg.Tun() {
- return fmt.Errorf("cannot add TCP or web handlers as TUN mode is enabled for %s", svcName)
+ err = fmt.Errorf("cannot add TCP or web handlers as TUN mode is enabled for %s", svcName)
+ return false
}
+ return true
+ })
+ if err != nil {
+ return err
}
return nil
diff --git a/ipn/ipnlocal/serve_disabled.go b/ipn/ipnlocal/serve_disabled.go
index e9d2678a80d8b..dbeb7e4ebe796 100644
--- a/ipn/ipnlocal/serve_disabled.go
+++ b/ipn/ipnlocal/serve_disabled.go
@@ -12,8 +12,8 @@
package ipnlocal
import (
- "tailscale.com/ipn"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tailcfg"
)
const serveEnabled = false
diff --git a/ipn/ipnlocal/serve_test.go b/ipn/ipnlocal/serve_test.go
index 05f4936b2c299..41b4482aa9976 100644
--- a/ipn/ipnlocal/serve_test.go
+++ b/ipn/ipnlocal/serve_test.go
@@ -1,18 +1,18 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_serve
-
package ipnlocal
import (
"bytes"
- "cmp"
"context"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"io"
"mime"
"net/http"
@@ -26,22 +26,22 @@ import (
"testing"
"time"
- "tailscale.com/control/controlclient"
- "tailscale.com/health"
- "tailscale.com/ipn"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/tailcfg"
- "tailscale.com/tsd"
- "tailscale.com/tstest"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/types/netmap"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/mak"
- "tailscale.com/util/must"
- "tailscale.com/util/syspolicy/policyclient"
- "tailscale.com/wgengine"
- "tailscale.com/wgengine/filter"
+ "github.com/metacubex/tailscale/control/controlclient"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/wgengine"
+ "github.com/metacubex/tailscale/wgengine/filter"
)
func TestExpandProxyArg(t *testing.T) {
@@ -748,7 +748,7 @@ func TestServeHTTPProxyHeaders(t *testing.T) {
{"Tailscale-User-Login", "someone@example.com"},
{"Tailscale-User-Name", "Some One"},
{"Tailscale-User-Profile-Pic", "https://example.com/photo.jpg"},
- {"Tailscale-Headers-Info", "https://tailscale.com/s/serve-headers"},
+ {"Tailscale-Headers-Info", "https://github.com/metacubex/tailscale/s/serve-headers"},
},
},
{
@@ -888,7 +888,7 @@ func TestServeHTTPProxyGrantHeader(t *testing.T) {
{"Tailscale-User-Login", "someone@example.com"},
{"Tailscale-User-Name", "Some One"},
{"Tailscale-User-Profile-Pic", "https://example.com/photo.jpg"},
- {"Tailscale-Headers-Info", "https://tailscale.com/s/serve-headers"},
+ {"Tailscale-Headers-Info", "https://github.com/metacubex/tailscale/s/serve-headers"},
{"Tailscale-App-Capabilities", `{"example.com/cap/interesting":[{"role":"🐿"}]}`},
},
},
diff --git a/ipn/ipnlocal/serve_unix_test.go b/ipn/ipnlocal/serve_unix_test.go
index 9e641e0e521ba..f4cedbfd1a082 100644
--- a/ipn/ipnlocal/serve_unix_test.go
+++ b/ipn/ipnlocal/serve_unix_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build unix
-
package ipnlocal
import (
@@ -18,7 +18,7 @@ import (
"testing"
"time"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/tstest"
)
func TestExpandProxyArgUnix(t *testing.T) {
diff --git a/ipn/ipnlocal/state_test.go b/ipn/ipnlocal/state_test.go
index 104c29a3f3e2b..a86c60c6a911a 100644
--- a/ipn/ipnlocal/state_test.go
+++ b/ipn/ipnlocal/state_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,7 +9,7 @@ import (
"context"
"errors"
"fmt"
- "math/rand/v2"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"net/netip"
"strings"
"sync"
@@ -19,36 +21,36 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/control/controlclient"
- "tailscale.com/envknob"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnauth"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/net/dns"
- "tailscale.com/net/netmon"
- "tailscale.com/net/packet"
- "tailscale.com/net/tsdial"
- "tailscale.com/tailcfg"
- "tailscale.com/tsd"
- "tailscale.com/tstest"
- "tailscale.com/types/dnstype"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/types/netmap"
- "tailscale.com/types/persist"
- "tailscale.com/types/preftype"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/mak"
- "tailscale.com/util/must"
- "tailscale.com/wgengine"
- "tailscale.com/wgengine/filter"
- "tailscale.com/wgengine/magicsock"
- "tailscale.com/wgengine/router"
- "tailscale.com/wgengine/wgcfg"
- "tailscale.com/wgengine/wgint"
+ "github.com/metacubex/tailscale/control/controlclient"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/net/dns"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/types/preftype"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/wgengine"
+ "github.com/metacubex/tailscale/wgengine/filter"
+ "github.com/metacubex/tailscale/wgengine/magicsock"
+ "github.com/metacubex/tailscale/wgengine/router"
+ "github.com/metacubex/tailscale/wgengine/wgcfg"
+ "github.com/metacubex/tailscale/wgengine/wgint"
)
// notifyThrottler receives notifications from an ipn.Backend, blocking
diff --git a/ipn/ipnlocal/tailnetlock_disabled.go b/ipn/ipnlocal/tailnetlock_disabled.go
index 0668437b163c6..1308ae6f7eadb 100644
--- a/ipn/ipnlocal/tailnetlock_disabled.go
+++ b/ipn/ipnlocal/tailnetlock_disabled.go
@@ -6,10 +6,10 @@
package ipnlocal
import (
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tka"
- "tailscale.com/types/netmap"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/types/netmap"
)
type tkaState struct {
diff --git a/ipn/ipnlocal/web_client.go b/ipn/ipnlocal/web_client.go
index 6ab68858ee701..4601e8f0f0171 100644
--- a/ipn/ipnlocal/web_client.go
+++ b/ipn/ipnlocal/web_client.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ios && !android && !ts_omit_webclient
+//go:build !ios && !android && ts_enable_webclient
package ipnlocal
@@ -17,14 +17,14 @@ import (
"sync"
"time"
- "tailscale.com/client/local"
- "tailscale.com/client/web"
- "tailscale.com/net/netutil"
- "tailscale.com/tailcfg"
- "tailscale.com/tsconst"
- "tailscale.com/types/logger"
- "tailscale.com/util/backoff"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/client/web"
+ "github.com/metacubex/tailscale/net/netutil"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsconst"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/backoff"
+ "github.com/metacubex/tailscale/util/mak"
)
const webClientPort = tsconst.WebListenPort
@@ -123,17 +123,18 @@ func (b *LocalBackend) updateWebClientListenersLocked() {
}
addrs := nm.GetAddresses()
- for _, pfx := range addrs.All() {
+ addrs.All()(func(_ int, pfx netip.Prefix) bool {
addrPort := netip.AddrPortFrom(pfx.Addr(), webClientPort)
if _, ok := b.webClientListeners[addrPort]; ok {
- continue // already listening
+ return true // already listening
}
sl := b.newWebClientListener(context.Background(), addrPort, b.logf)
mak.Set(&b.webClientListeners, addrPort, sl)
go sl.Run()
- }
+ return true
+ })
}
// newWebClientListener returns a listener for local connections to the built-in web client
diff --git a/ipn/ipnlocal/web_client_stub.go b/ipn/ipnlocal/web_client_stub.go
index 02798b4f709e9..4e4daeea2d608 100644
--- a/ipn/ipnlocal/web_client_stub.go
+++ b/ipn/ipnlocal/web_client_stub.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build ios || android || ts_omit_webclient
+//go:build ios || android || !ts_enable_webclient
package ipnlocal
diff --git a/ipn/ipnserver/actor.go b/ipn/ipnserver/actor.go
index 985a6ef7a712d..491760d077bea 100644
--- a/ipn/ipnserver/actor.go
+++ b/ipn/ipnserver/actor.go
@@ -12,13 +12,13 @@ import (
"runtime"
"time"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnauth"
- "tailscale.com/types/logger"
- "tailscale.com/util/ctxkey"
- "tailscale.com/util/osuser"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/ctxkey"
+ "github.com/metacubex/tailscale/util/osuser"
+ "github.com/metacubex/tailscale/version"
)
var _ ipnauth.Actor = (*actor)(nil)
diff --git a/ipn/ipnserver/proxyconnect.go b/ipn/ipnserver/proxyconnect.go
index c8348a76c2b6a..61b7178f79279 100644
--- a/ipn/ipnserver/proxyconnect.go
+++ b/ipn/ipnserver/proxyconnect.go
@@ -10,9 +10,9 @@ import (
"net"
"net/http"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/logpolicy"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/logpolicy"
)
// handleProxyConnectConn handles a CONNECT request to
diff --git a/ipn/ipnserver/server.go b/ipn/ipnserver/server.go
index 19efaf9895b94..b9446b9cb97ac 100644
--- a/ipn/ipnserver/server.go
+++ b/ipn/ipnserver/server.go
@@ -22,20 +22,20 @@ import (
"sync/atomic"
"unicode"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/ipn/ipnauth"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/ipn/localapi"
- "tailscale.com/net/netmon"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/ipn/localapi"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/testenv"
)
// Server is an IPN backend and its set of 0 or more active localhost
diff --git a/ipn/ipnserver/server_fortest.go b/ipn/ipnserver/server_fortest.go
index 70148f030e6b0..cd543f6645446 100644
--- a/ipn/ipnserver/server_fortest.go
+++ b/ipn/ipnserver/server_fortest.go
@@ -7,7 +7,7 @@ import (
"context"
"net/http"
- "tailscale.com/ipn/ipnauth"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
)
// BlockWhileInUseByOtherForTest blocks while the actor can't connect to the server because
diff --git a/ipn/ipnserver/server_test.go b/ipn/ipnserver/server_test.go
index 45a8d622d3e73..27f1c742b2fdb 100644
--- a/ipn/ipnserver/server_test.go
+++ b/ipn/ipnserver/server_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,13 +13,13 @@ import (
"sync"
"testing"
- "tailscale.com/client/local"
- "tailscale.com/envknob"
- "tailscale.com/ipn"
- "tailscale.com/ipn/lapitest"
- "tailscale.com/tsd"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/policytest"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/lapitest"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/policytest"
)
func TestUserConnectDisconnectNonWindows(t *testing.T) {
diff --git a/ipn/ipnserver/waiterset_test.go b/ipn/ipnserver/waiterset_test.go
index b8a143212c1a3..068551f69a456 100644
--- a/ipn/ipnserver/waiterset_test.go
+++ b/ipn/ipnserver/waiterset_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/ipn/ipnstate/ipnstate.go b/ipn/ipnstate/ipnstate.go
index 17e6ac870bead..704c7516f05e1 100644
--- a/ipn/ipnstate/ipnstate.go
+++ b/ipn/ipnstate/ipnstate.go
@@ -8,24 +8,24 @@ package ipnstate
import (
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"html"
"io"
"log"
"net/netip"
- "slices"
"sort"
"strings"
"time"
- "tailscale.com/tailcfg"
- "tailscale.com/tka"
- "tailscale.com/types/key"
- "tailscale.com/types/views"
- "tailscale.com/util/dnsname"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/version"
)
-//go:generate go run tailscale.com/cmd/cloner -clonefunc=false -type=TKAPeer
+//go:generate go run github.com/metacubex/tailscale/cmd/cloner -clonefunc=false -type=TKAPeer
// Status represents the entire state of the IPN network.
type Status struct {
@@ -242,7 +242,7 @@ type PeerStatus struct {
AllowedIPs *views.Slice[netip.Prefix] `json:",omitempty"`
// Tags are the list of ACL tags applied to this node.
- // See tailscale.com/tailcfg#Node.Tags for more information.
+ // See github.com/metacubex/tailscale/tailcfg#Node.Tags for more information.
Tags *views.Slice[string] `json:",omitempty"`
// PrimaryRoutes are the routes this node is currently the primary
@@ -534,7 +534,8 @@ func (sb *StatusBuilder) AddPeer(peer key.NodePublic, st *PeerStatus) {
e.Expired = true
}
if t := st.KeyExpiry; t != nil {
- e.KeyExpiry = new(*t)
+ keyExpiry := *t
+ e.KeyExpiry = &keyExpiry
}
if v := st.CapMap; v != nil {
e.CapMap = v
diff --git a/ipn/ipnstate/ipnstate_clone.go b/ipn/ipnstate/ipnstate_clone.go
index 9af066832b27f..b26467ea8c659 100644
--- a/ipn/ipnstate/ipnstate_clone.go
+++ b/ipn/ipnstate/ipnstate_clone.go
@@ -1,16 +1,16 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-// Code generated by tailscale.com/cmd/cloner; DO NOT EDIT.
+// Code generated by github.com/metacubex/tailscale/cmd/cloner; DO NOT EDIT.
package ipnstate
import (
"net/netip"
- "tailscale.com/tailcfg"
- "tailscale.com/tka"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/types/key"
)
// Clone makes a deep copy of TKAPeer.
diff --git a/ipn/lapitest/backend.go b/ipn/lapitest/backend.go
index b622d098f4f55..dab1bcac105a6 100644
--- a/ipn/lapitest/backend.go
+++ b/ipn/lapitest/backend.go
@@ -6,11 +6,11 @@ package lapitest
import (
"testing"
- "tailscale.com/control/controlclient"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/types/logid"
- "tailscale.com/wgengine"
+ "github.com/metacubex/tailscale/control/controlclient"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/wgengine"
)
// NewBackend returns a new [ipnlocal.LocalBackend] for testing purposes.
diff --git a/ipn/lapitest/client.go b/ipn/lapitest/client.go
index c2c07dfbaf689..a78fe14a776ba 100644
--- a/ipn/lapitest/client.go
+++ b/ipn/lapitest/client.go
@@ -7,9 +7,9 @@ import (
"context"
"testing"
- "tailscale.com/client/local"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnauth"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
)
// Client wraps a [local.Client] for testing purposes.
diff --git a/ipn/lapitest/example_test.go b/ipn/lapitest/example_test.go
index 648c97880cdb8..45630af1856ab 100644
--- a/ipn/lapitest/example_test.go
+++ b/ipn/lapitest/example_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,7 +9,7 @@ import (
"context"
"testing"
- "tailscale.com/ipn"
+ "github.com/metacubex/tailscale/ipn"
)
func TestClientServer(t *testing.T) {
diff --git a/ipn/lapitest/opts.go b/ipn/lapitest/opts.go
index 5ed2f97573b90..5752dc7fffe9f 100644
--- a/ipn/lapitest/opts.go
+++ b/ipn/lapitest/opts.go
@@ -9,12 +9,12 @@ import (
"fmt"
"testing"
- "tailscale.com/control/controlclient"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/tsd"
- "tailscale.com/tstest"
- "tailscale.com/types/lazy"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/control/controlclient"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/types/logger"
)
// Option is any optional configuration that can be passed to [NewServer] or [NewBackend].
diff --git a/ipn/lapitest/server.go b/ipn/lapitest/server.go
index 2686682af15c9..23b0cd9614b63 100644
--- a/ipn/lapitest/server.go
+++ b/ipn/lapitest/server.go
@@ -13,17 +13,17 @@ import (
"sync"
"testing"
- "tailscale.com/client/local"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/envknob"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnauth"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/ipn/ipnserver"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/util/mak"
- "tailscale.com/util/rands"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/ipn/ipnserver"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/rands"
)
// A Server is an in-process LocalAPI server that can be used in end-to-end tests.
diff --git a/ipn/localapi/cert.go b/ipn/localapi/cert.go
index cd8afa03bf599..ce3df02643987 100644
--- a/ipn/localapi/cert.go
+++ b/ipn/localapi/cert.go
@@ -11,7 +11,7 @@ import (
"strings"
"time"
- "tailscale.com/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
)
func init() {
diff --git a/ipn/localapi/debug.go b/ipn/localapi/debug.go
index 6f222bef08ac3..9184ad2540244 100644
--- a/ipn/localapi/debug.go
+++ b/ipn/localapi/debug.go
@@ -1,33 +1,33 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_debug
+//go:build ts_enable_debug
package localapi
import (
- "cmp"
"context"
"encoding/json"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net"
"net/http"
"net/netip"
"reflect"
- "slices"
"strconv"
"sync"
"time"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/ipn"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/httpm"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/httpm"
)
func init() {
@@ -143,15 +143,17 @@ func (h *Handler) serveDebugDialTypes(w http.ResponseWriter, r *http.Request) {
var wg sync.WaitGroup
for _, dialer := range dialers {
-
- wg.Go(func() {
+ dialer := dialer
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
conn, err := dialer.dial(ctx, network, addr)
results <- result{dialer.name, conn, err}
- })
+ }()
}
wg.Wait()
- for range len(dialers) {
+ for i := 0; i < len(dialers); i++ {
res := <-results
fmt.Fprintf(w, "[%s] connected=%v err=%v\n", res.name, res.conn != nil, res.err)
if res.conn != nil {
diff --git a/ipn/localapi/debugderp.go b/ipn/localapi/debugderp.go
index 52987ee0a18e6..6ab30475ff364 100644
--- a/ipn/localapi/debugderp.go
+++ b/ipn/localapi/debugderp.go
@@ -1,30 +1,30 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_debug
+//go:build ts_enable_debug
package localapi
import (
- "cmp"
"context"
"crypto/tls"
"encoding/json"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"net"
"net/http"
"net/netip"
"strconv"
"time"
- "tailscale.com/derp/derphttp"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/netns"
- "tailscale.com/net/stun"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/nettype"
+ "github.com/metacubex/tailscale/derp/derphttp"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/net/stun"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/nettype"
)
func (h *Handler) serveDebugDERPRegion(w http.ResponseWriter, r *http.Request) {
@@ -161,12 +161,26 @@ func (h *Handler) serveDebugDERPRegion(w http.ResponseWriter, r *http.Request) {
return
}
} else {
- addrs, err := net.DefaultResolver.LookupNetIP(ctx, "ip4", derpNode.HostName)
+ lookup := h.b.Dialer().LookupHook
+ if lookup == nil {
+ st.Errors = append(st.Errors, "No LookupHook configured")
+ return
+ }
+ addrs, err := lookup(ctx, derpNode.HostName)
if err != nil {
st.Errors = append(st.Errors, fmt.Sprintf("Error resolving node %q IPv4 addresses: %v", derpNode.HostName, err))
return
}
- addr = addrs[0]
+ for _, _addr := range addrs {
+ if _addr.Is4() {
+ addr = _addr
+ break
+ }
+ }
+ if !addr.IsValid() {
+ st.Errors = append(st.Errors, fmt.Sprintf("Node %q has no IPv4 addresses", derpNode.HostName))
+ return
+ }
}
addrPort := netip.AddrPortFrom(addr, uint16(cmp.Or(derpNode.STUNPort, 3478)))
@@ -257,7 +271,7 @@ func (h *Handler) serveDebugDERPRegion(w http.ResponseWriter, r *http.Request) {
// Next, repeatedly get the server key to see if the node is
// behind a load balancer (incorrectly).
serverPubKeys := make(map[key.NodePublic]bool)
- for i := range 5 {
+ for i := 0; i < 5; i++ {
func() {
rc := derphttp.NewRegionClient(fakePrivKey, h.logf, h.b.NetMon(), func() *tailcfg.DERPRegion {
return &tailcfg.DERPRegion{
diff --git a/ipn/localapi/localapi.go b/ipn/localapi/localapi.go
index 9d4977e48e2cc..999ce52b08291 100644
--- a/ipn/localapi/localapi.go
+++ b/ipn/localapi/localapi.go
@@ -6,52 +6,52 @@ package localapi
import (
"bytes"
- "cmp"
"crypto/subtle"
"encoding/json"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net"
"net/http"
"net/netip"
"net/url"
"runtime"
- "slices"
"strconv"
"strings"
"sync"
"time"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/logtail"
+ "github.com/metacubex/tailscale/net/neterror"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/net/netutil"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/appctype"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/httpm"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/osdiag"
+ "github.com/metacubex/tailscale/util/rands"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/version"
+ "github.com/metacubex/tailscale/wgengine/magicsock"
"golang.org/x/net/dns/dnsmessage"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnauth"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/logtail"
- "tailscale.com/net/neterror"
- "tailscale.com/net/netns"
- "tailscale.com/net/netutil"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/types/appctype"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/httpm"
- "tailscale.com/util/mak"
- "tailscale.com/util/osdiag"
- "tailscale.com/util/rands"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/version"
- "tailscale.com/wgengine/magicsock"
)
var (
@@ -866,10 +866,12 @@ func InUseOtherUserIPNStream(w http.ResponseWriter, r *http.Request, err error)
if r.Method != httpm.GET || r.URL.Path != "/localapi/v0/watch-ipn-bus" {
return false
}
+ state := ipn.InUseOtherUser
+ errMessage := err.Error()
js, err := json.Marshal(&ipn.Notify{
Version: version.Long(),
- State: new(ipn.InUseOtherUser),
- ErrMessage: new(err.Error()),
+ State: &state,
+ ErrMessage: &errMessage,
})
if err != nil {
return false
diff --git a/ipn/localapi/localapi_drive.go b/ipn/localapi/localapi_drive.go
index e1dee441e0fde..6fc8adace0c7b 100644
--- a/ipn/localapi/localapi_drive.go
+++ b/ipn/localapi/localapi_drive.go
@@ -13,8 +13,8 @@ import (
"os"
"path"
- "tailscale.com/drive"
- "tailscale.com/util/httpm"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/util/httpm"
)
func init() {
diff --git a/ipn/localapi/localapi_test.go b/ipn/localapi/localapi_test.go
index 84d8e1e0f7b10..4d7f934b730dc 100644
--- a/ipn/localapi/localapi_test.go
+++ b/ipn/localapi/localapi_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,6 +11,7 @@ import (
"encoding/json"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"go/ast"
"go/parser"
"go/token"
@@ -19,27 +22,26 @@ import (
"net/netip"
"net/url"
"os"
- "slices"
"strconv"
"strings"
"testing"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/health"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnauth"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/tailcfg"
- "tailscale.com/tsd"
- "tailscale.com/tstest"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/slicesx"
- "tailscale.com/wgengine"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/wgengine"
)
func handlerForTest(t testing.TB, h *Handler) *Handler {
diff --git a/ipn/localapi/pprof.go b/ipn/localapi/pprof.go
index fabdb18e24d87..1a3ad175ad918 100644
--- a/ipn/localapi/pprof.go
+++ b/ipn/localapi/pprof.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ios && !android && !js && !ts_omit_debug
+//go:build !ios && !android && !js && ts_enable_debug
// We don't include it on mobile where we're more memory constrained and
// there's no CLI to get at the results anyway.
diff --git a/ipn/localapi/serve.go b/ipn/localapi/serve.go
index 1f677f7ab3a05..525c843f4dfea 100644
--- a/ipn/localapi/serve.go
+++ b/ipn/localapi/serve.go
@@ -12,10 +12,10 @@ import (
"net/http"
"runtime"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/util/httpm"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/util/httpm"
+ "github.com/metacubex/tailscale/version"
)
func init() {
diff --git a/ipn/localapi/syspolicy_api.go b/ipn/localapi/syspolicy_api.go
index 9962f342bd884..94aabbf8b5f42 100644
--- a/ipn/localapi/syspolicy_api.go
+++ b/ipn/localapi/syspolicy_api.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_syspolicy
+//go:build ts_enable_syspolicy
package localapi
@@ -11,9 +11,9 @@ import (
"net/http"
"strings"
- "tailscale.com/util/httpm"
- "tailscale.com/util/syspolicy/rsop"
- "tailscale.com/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/httpm"
+ "github.com/metacubex/tailscale/util/syspolicy/rsop"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
)
func init() {
diff --git a/ipn/localapi/tailnetlock.go b/ipn/localapi/tailnetlock.go
index e2a2850cf331d..64ed26aa1f099 100644
--- a/ipn/localapi/tailnetlock.go
+++ b/ipn/localapi/tailnetlock.go
@@ -11,10 +11,10 @@ import (
"net/http"
"strconv"
- "tailscale.com/tka"
- "tailscale.com/types/key"
- "tailscale.com/types/tkatype"
- "tailscale.com/util/httpm"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/tkatype"
+ "github.com/metacubex/tailscale/util/httpm"
)
func init() {
diff --git a/ipn/policy/policy.go b/ipn/policy/policy.go
index bbc78a254e141..743a103fe4d1b 100644
--- a/ipn/policy/policy.go
+++ b/ipn/policy/policy.go
@@ -6,7 +6,7 @@
package policy
import (
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/tailcfg"
)
// IsInterestingService reports whether service s on the given operating
diff --git a/ipn/prefs.go b/ipn/prefs.go
index 9125df2c1a76b..ac8a11d7d9567 100644
--- a/ipn/prefs.go
+++ b/ipn/prefs.go
@@ -5,34 +5,34 @@ package ipn
import (
"bytes"
- "cmp"
"encoding/json"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
"net/netip"
"os"
"path/filepath"
"reflect"
"runtime"
- "slices"
"strings"
- "tailscale.com/atomicfile"
- "tailscale.com/drive"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/tsaddr"
- "tailscale.com/tailcfg"
- "tailscale.com/types/opt"
- "tailscale.com/types/persist"
- "tailscale.com/types/preftype"
- "tailscale.com/types/views"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/policyclient"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/atomicfile"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/types/preftype"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/version"
)
// DefaultControlURL is the URL base of the control plane
@@ -439,7 +439,9 @@ func applyPrefsEdits(src, dst reflect.Value, mask map[string]reflect.Value) {
func maskFields(v reflect.Value) map[string]reflect.Value {
mask := make(map[string]reflect.Value)
- for sf, fv := range v.Fields() {
+ for i := 0; i < v.NumField(); i++ {
+ sf := v.Type().Field(i)
+ fv := v.Field(i)
if !strings.HasSuffix(sf.Name, "Set") {
continue
}
diff --git a/ipn/prefs_test.go b/ipn/prefs_test.go
index 31dd2c55a3182..61d65f3576ca3 100644
--- a/ipn/prefs_test.go
+++ b/ipn/prefs_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -14,16 +16,16 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/types/preftype"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
"go4.org/mem"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/net/netaddr"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/types/key"
- "tailscale.com/types/opt"
- "tailscale.com/types/persist"
- "tailscale.com/types/preftype"
- "tailscale.com/util/syspolicy/policyclient"
)
func fieldsOf(t reflect.Type) (fields []string) {
diff --git a/ipn/serve.go b/ipn/serve.go
index 21d15ab818fc9..62de4d0090003 100644
--- a/ipn/serve.go
+++ b/ipn/serve.go
@@ -6,21 +6,21 @@ package ipn
import (
"errors"
"fmt"
- "iter"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net"
"net/netip"
"net/url"
"runtime"
- "slices"
"strconv"
"strings"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/types/ipproto"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
)
// ServeConfigKey returns a StateKey that stores the
@@ -609,10 +609,10 @@ func CheckFunnelAccess(port uint16, node *ipnstate.PeerStatus) error {
// for Tailscale Funnel usage.
func NodeCanFunnel(node *ipnstate.PeerStatus) error {
if !node.HasCap(tailcfg.CapabilityHTTPS) {
- return errors.New("Funnel not available; HTTPS must be enabled. See https://tailscale.com/s/https.")
+ return errors.New("Funnel not available; HTTPS must be enabled. See https://github.com/metacubex/tailscale/s/https.")
}
if !node.HasCap(tailcfg.NodeAttrFunnel) {
- return errors.New("Funnel not available; \"funnel\" node attribute not set. See https://tailscale.com/s/no-funnel.")
+ return errors.New("Funnel not available; \"funnel\" node attribute not set. See https://github.com/metacubex/tailscale/s/no-funnel.")
}
return nil
}
@@ -673,7 +673,7 @@ func CheckFunnelPort(wantedPort uint16, node *ipnstate.PeerStatus) error {
return deny("")
}
wantedPortString := strconv.Itoa(int(wantedPort))
- for ps := range strings.SplitSeq(portsStr, ",") {
+ for _, ps := range strings.Split(portsStr, ",") {
if ps == "" {
continue
}
@@ -796,43 +796,36 @@ func ExpandProxyTargetValue(target string, supportedSchemes []string, defaultSch
// The key is the port number.
func (v ServeConfigView) TCPs() iter.Seq2[uint16, TCPPortHandlerView] {
return func(yield func(uint16, TCPPortHandlerView) bool) {
- for k, v := range v.TCP().All() {
- if !yield(k, v) {
- return
- }
- }
- for _, conf := range v.Foreground().All() {
- for k, v := range conf.TCP().All() {
- if !yield(k, v) {
- return
- }
- }
- }
+ v.TCP().All()(func(k uint16, v TCPPortHandlerView) bool {
+ return yield(k, v)
+ })
+ v.Foreground().All()(func(_ string, conf ServeConfigView) bool {
+ conf.TCP().All()(func(k uint16, v TCPPortHandlerView) bool {
+ return yield(k, v)
+ })
+ return true
+ })
}
}
// Webs returns an iterator over both background and foreground Web configurations.
func (v ServeConfigView) Webs() iter.Seq2[HostPort, WebServerConfigView] {
return func(yield func(HostPort, WebServerConfigView) bool) {
- for k, v := range v.Web().All() {
- if !yield(k, v) {
- return
- }
- }
- for _, conf := range v.Foreground().All() {
- for k, v := range conf.Web().All() {
- if !yield(k, v) {
- return
- }
- }
- }
- for _, service := range v.Services().All() {
- for k, v := range service.Web().All() {
- if !yield(k, v) {
- return
- }
- }
- }
+ v.Web().All()(func(k HostPort, v WebServerConfigView) bool {
+ return yield(k, v)
+ })
+ v.Foreground().All()(func(_ string, conf ServeConfigView) bool {
+ conf.Web().All()(func(k HostPort, v WebServerConfigView) bool {
+ return yield(k, v)
+ })
+ return true
+ })
+ v.Services().All()(func(_ tailcfg.ServiceName, service ServiceConfigView) bool {
+ service.Web().All()(func(k HostPort, v WebServerConfigView) bool {
+ return yield(k, v)
+ })
+ return true
+ })
}
}
@@ -870,10 +863,14 @@ func (v ServeConfigView) FindTCP(port uint16) (res TCPPortHandlerView, ok bool)
// prefers a foreground match first followed by a background search if none
// existed.
func (v ServeConfigView) FindWeb(hp HostPort) (res WebServerConfigView, ok bool) {
- for _, conf := range v.Foreground().All() {
- if res, ok := conf.Web().GetOk(hp); ok {
- return res, ok
+ v.Foreground().All()(func(_ string, conf ServeConfigView) bool {
+ if res, ok = conf.Web().GetOk(hp); ok {
+ return false
}
+ return true
+ })
+ if ok {
+ return res, ok
}
return v.Web().GetOk(hp)
}
@@ -881,12 +878,13 @@ func (v ServeConfigView) FindWeb(hp HostPort) (res WebServerConfigView, ok bool)
// FindForegroundTCP returns the first foreground TCP handler matching the input
// port.
func (v ServeConfigView) FindForegroundTCP(port uint16) (res TCPPortHandlerView, ok bool) {
- for _, conf := range v.Foreground().All() {
- if res, ok := conf.TCP().GetOk(port); ok {
- return res, ok
+ v.Foreground().All()(func(_ string, conf ServeConfigView) bool {
+ if res, ok = conf.TCP().GetOk(port); ok {
+ return false
}
- }
- return res, false
+ return true
+ })
+ return res, ok
}
// HasAllowFunnel returns whether this config has at least one AllowFunnel
@@ -895,12 +893,15 @@ func (v ServeConfigView) HasAllowFunnel() bool {
if v.AllowFunnel().Len() > 0 {
return true
}
- for _, conf := range v.Foreground().All() {
+ found := false
+ v.Foreground().All()(func(_ string, conf ServeConfigView) bool {
if conf.AllowFunnel().Len() > 0 {
- return true
+ found = true
+ return false
}
- }
- return false
+ return true
+ })
+ return found
}
// FindFunnel reports whether target exists in either the background AllowFunnel
@@ -909,12 +910,15 @@ func (v ServeConfigView) HasFunnelForTarget(target HostPort) bool {
if v.AllowFunnel().Get(target) {
return true
}
- for _, conf := range v.Foreground().All() {
+ found := false
+ v.Foreground().All()(func(_ string, conf ServeConfigView) bool {
if conf.AllowFunnel().Get(target) {
- return true
+ found = true
+ return false
}
- }
- return false
+ return true
+ })
+ return found
}
// ServicePortRange returns the list of tailcfg.ProtoPortRange that represents
@@ -930,11 +934,12 @@ func (v ServiceConfigView) ServicePortRange() []tailcfg.ProtoPortRange {
// Deduplicate the ports.
servePorts := make(set.Set[uint16])
- for port := range v.TCP().All() {
+ v.TCP().All()(func(port uint16, _ TCPPortHandlerView) bool {
if port > 0 {
servePorts.Add(uint16(port))
}
- }
+ return true
+ })
dedupedServePorts := servePorts.Slice()
slices.Sort(dedupedServePorts)
diff --git a/ipn/serve_expand_test.go b/ipn/serve_expand_test.go
index 33f808d62ec05..5f55fcfd0b5e0 100644
--- a/ipn/serve_expand_test.go
+++ b/ipn/serve_expand_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/ipn/serve_test.go b/ipn/serve_test.go
index bf043ca39f372..7a04fa2f753e1 100644
--- a/ipn/serve_test.go
+++ b/ipn/serve_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,13 +8,13 @@ package ipn
import (
"testing"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
)
func TestCheckFunnelAccess(t *testing.T) {
caps := func(c ...tailcfg.NodeCapability) []tailcfg.NodeCapability { return c }
- const portAttr tailcfg.NodeCapability = "https://tailscale.com/cap/funnel-ports?ports=443,8080-8090,8443,"
+ const portAttr tailcfg.NodeCapability = "https://github.com/metacubex/tailscale/cap/funnel-ports?ports=443,8080-8090,8443,"
tests := []struct {
port uint16
caps []tailcfg.NodeCapability
diff --git a/ipn/store.go b/ipn/store.go
index 1bd3e5a3b4e6b..b6a1fd9a4847c 100644
--- a/ipn/store.go
+++ b/ipn/store.go
@@ -11,7 +11,7 @@ import (
"net"
"strconv"
- "tailscale.com/health"
+ "github.com/metacubex/tailscale/health"
)
// ErrStateNotExist is returned by StateStore.ReadState when the
diff --git a/ipn/store/awsstore/store_aws.go b/ipn/store/awsstore/store_aws.go
index feb86e457805a..e259e6b7985ed 100644
--- a/ipn/store/awsstore/store_aws.go
+++ b/ipn/store/awsstore/store_aws.go
@@ -19,10 +19,10 @@ import (
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/ssm"
ssmTypes "github.com/aws/aws-sdk-go-v2/service/ssm/types"
- "tailscale.com/ipn"
- "tailscale.com/ipn/store"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/store"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/types/logger"
)
func init() {
diff --git a/ipn/store/awsstore/store_aws_test.go b/ipn/store/awsstore/store_aws_test.go
index ba2274bf1c09e..e2b14874841cf 100644
--- a/ipn/store/awsstore/store_aws_test.go
+++ b/ipn/store/awsstore/store_aws_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_aws
-
package awsstore
import (
@@ -13,8 +13,8 @@ import (
"github.com/aws/aws-sdk-go-v2/aws/arn"
"github.com/aws/aws-sdk-go-v2/service/ssm"
ssmTypes "github.com/aws/aws-sdk-go-v2/service/ssm/types"
- "tailscale.com/ipn"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tstest"
)
type mockedAWSSSMClient struct {
diff --git a/ipn/store/kubestore/store_kube.go b/ipn/store/kubestore/store_kube.go
index f7d1b90cd1e2c..57caa629fa012 100644
--- a/ipn/store/kubestore/store_kube.go
+++ b/ipn/store/kubestore/store_kube.go
@@ -14,16 +14,16 @@ import (
"strings"
"time"
- "tailscale.com/envknob"
- "tailscale.com/ipn"
- "tailscale.com/ipn/store"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/kube/kubeapi"
- "tailscale.com/kube/kubeclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/types/logger"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/store"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/kube/kubeapi"
+ "github.com/metacubex/tailscale/kube/kubeclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/mak"
)
func init() {
@@ -494,9 +494,9 @@ func (s *Store) certSecretSelector() map[string]string {
}
pgName := s.podName[:p]
return map[string]string{
- kubetypes.LabelSecretType: kubetypes.LabelSecretTypeCerts,
- kubetypes.LabelManaged: "true",
- "tailscale.com/proxy-group": pgName,
+ kubetypes.LabelSecretType: kubetypes.LabelSecretTypeCerts,
+ kubetypes.LabelManaged: "true",
+ "github.com/metacubex/tailscale/proxy-group": pgName,
}
}
diff --git a/ipn/store/kubestore/store_kube_test.go b/ipn/store/kubestore/store_kube_test.go
index 1e6f711d686e2..e1c16f7170e22 100644
--- a/ipn/store/kubestore/store_kube_test.go
+++ b/ipn/store/kubestore/store_kube_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,12 +14,12 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
- "tailscale.com/envknob"
- "tailscale.com/ipn"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/kube/kubeapi"
- "tailscale.com/kube/kubeclient"
- "tailscale.com/kube/kubetypes"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/kube/kubeapi"
+ "github.com/metacubex/tailscale/kube/kubeclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
)
func TestKubernetesPodMigrationWithTPMAttestationKey(t *testing.T) {
@@ -608,9 +610,9 @@ func TestNewWithClient(t *testing.T) {
)
certSecretsLabels := map[string]string{
- "tailscale.com/secret-type": kubetypes.LabelSecretTypeCerts,
- "tailscale.com/managed": "true",
- "tailscale.com/proxy-group": "ingress-proxies",
+ "github.com/metacubex/tailscale/secret-type": kubetypes.LabelSecretTypeCerts,
+ "github.com/metacubex/tailscale/managed": "true",
+ "github.com/metacubex/tailscale/proxy-group": "ingress-proxies",
}
// Helper function to create Secret objects for testing
@@ -674,9 +676,9 @@ func TestNewWithClient(t *testing.T) {
makeSecret("app2.tailnetxyz.ts.net", certSecretsLabels, "2"),
makeSecret("some-other-secret", nil, "3"),
makeSecret("app3.other-proxies.ts.net", map[string]string{
- "tailscale.com/secret-type": kubetypes.LabelSecretTypeCerts,
- "tailscale.com/managed": "true",
- "tailscale.com/proxy-group": "some-other-proxygroup",
+ "github.com/metacubex/tailscale/secret-type": kubetypes.LabelSecretTypeCerts,
+ "github.com/metacubex/tailscale/managed": "true",
+ "github.com/metacubex/tailscale/proxy-group": "some-other-proxygroup",
}, "4"),
},
wantMemoryStoreContents: map[ipn.StateKey][]byte{
@@ -698,9 +700,9 @@ func TestNewWithClient(t *testing.T) {
makeSecret("app2.tailnetxyz.ts.net", certSecretsLabels, "2"),
makeSecret("some-other-secret", nil, "3"),
makeSecret("app3.other-proxies.ts.net", map[string]string{
- "tailscale.com/secret-type": kubetypes.LabelSecretTypeCerts,
- "tailscale.com/managed": "true",
- "tailscale.com/proxy-group": "some-other-proxygroup",
+ "github.com/metacubex/tailscale/secret-type": kubetypes.LabelSecretTypeCerts,
+ "github.com/metacubex/tailscale/managed": "true",
+ "github.com/metacubex/tailscale/proxy-group": "some-other-proxygroup",
}, "4"),
},
wantMemoryStoreContents: map[ipn.StateKey][]byte{
diff --git a/ipn/store/mem/store_mem.go b/ipn/store/mem/store_mem.go
index 247714c9a2b47..32251ba46d0cd 100644
--- a/ipn/store/mem/store_mem.go
+++ b/ipn/store/mem/store_mem.go
@@ -9,10 +9,10 @@ import (
"encoding/json"
"sync"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/mak"
xmaps "golang.org/x/exp/maps"
- "tailscale.com/ipn"
- "tailscale.com/types/logger"
- "tailscale.com/util/mak"
)
// New returns a new Store.
diff --git a/ipn/store/stores.go b/ipn/store/stores.go
index fd51f8c38540d..91023131e6c6e 100644
--- a/ipn/store/stores.go
+++ b/ipn/store/stores.go
@@ -9,22 +9,22 @@ import (
"encoding/json"
"errors"
"fmt"
- "iter"
- "maps"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"os"
"path/filepath"
"runtime"
- "slices"
"strings"
"sync"
- "tailscale.com/atomicfile"
- "tailscale.com/ipn"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/paths"
- "tailscale.com/types/logger"
- "tailscale.com/util/mak"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/atomicfile"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/paths"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/testenv"
)
// Provider returns a StateStore for the provided path.
@@ -322,10 +322,16 @@ func maybeMigrateLocalStateFile(logf logger.Logf, path string) error {
// Copy all the items. This is pretty inefficient, because both stores
// write the file to disk for each WriteState, but that's ok for a one-time
// migration.
- for k, v := range fromExp.All() {
+ var copyErr error
+ fromExp.All()(func(k ipn.StateKey, v []byte) bool {
if err := to.WriteState(k, v); err != nil {
- return err
+ copyErr = err
+ return false
}
+ return true
+ })
+ if copyErr != nil {
+ return copyErr
}
// Finally, overwrite the state file with the new one we created at
diff --git a/ipn/store/stores_test.go b/ipn/store/stores_test.go
index 345b1c10376d9..06aaed0fd3a4a 100644
--- a/ipn/store/stores_test.go
+++ b/ipn/store/stores_test.go
@@ -1,17 +1,19 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package store
import (
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"path/filepath"
"testing"
- "tailscale.com/ipn"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/tstest"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/logger"
)
func TestNewStore(t *testing.T) {
diff --git a/ipn/store_test.go b/ipn/store_test.go
index fc42fdbec3610..b56e26a6e5619 100644
--- a/ipn/store_test.go
+++ b/ipn/store_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,11 +7,11 @@ package ipn
import (
"bytes"
- "iter"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
"sync"
"testing"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/util/mak"
)
type memStore struct {
diff --git a/jsondb/db.go b/jsondb/db.go
index c45ab4cd39913..464b49ae42e30 100644
--- a/jsondb/db.go
+++ b/jsondb/db.go
@@ -11,7 +11,7 @@ import (
"io/fs"
"os"
- "tailscale.com/atomicfile"
+ "github.com/metacubex/tailscale/atomicfile"
)
// DB is a database backed by a JSON file.
diff --git a/jsondb/db_test.go b/jsondb/db_test.go
index 18797ebd174e6..99806c9c227c5 100644
--- a/jsondb/db_test.go
+++ b/jsondb/db_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/k8s-operator/api-proxy/proxy.go b/k8s-operator/api-proxy/proxy.go
index acc7b62341b83..59d049521cdf4 100644
--- a/k8s-operator/api-proxy/proxy.go
+++ b/k8s-operator/api-proxy/proxy.go
@@ -21,23 +21,23 @@ import (
"strings"
"time"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ ksr "github.com/metacubex/tailscale/k8s-operator/sessionrecording"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/sessionrecording"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/ctxkey"
+ "github.com/metacubex/tailscale/util/set"
"github.com/pires/go-proxyproto"
"go.uber.org/zap"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/client-go/rest"
"k8s.io/client-go/transport"
- "tailscale.com/client/local"
- "tailscale.com/client/tailscale/apitype"
- ksr "tailscale.com/k8s-operator/sessionrecording"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/net/netx"
- "tailscale.com/sessionrecording"
- "tailscale.com/tailcfg"
- "tailscale.com/tsnet"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/ctxkey"
- "tailscale.com/util/set"
)
var (
@@ -64,7 +64,13 @@ func NewAPIServerProxy(zlog *zap.SugaredLogger, restConfig *rest.Config, ts *tsn
return nil, fmt.Errorf("could not get rest.TransportConfig(): %w", err)
}
- tr := http.DefaultTransport.(*http.Transport).Clone()
+ tr := (&http.Transport{
+ ForceAttemptHTTP2: true,
+ MaxIdleConns: 100,
+ IdleConnTimeout: 90 * time.Second,
+ TLSHandshakeTimeout: 10 * time.Second,
+ ExpectContinueTimeout: 1 * time.Second,
+ }).Clone()
tr.TLSClientConfig, err = transport.TLSConfigFor(cfg)
if err != nil {
return nil, fmt.Errorf("could not get transport.TLSConfigFor(): %w", err)
diff --git a/k8s-operator/api-proxy/proxy_events_test.go b/k8s-operator/api-proxy/proxy_events_test.go
index 1426f170c5207..3caf507b2f773 100644
--- a/k8s-operator/api-proxy/proxy_events_test.go
+++ b/k8s-operator/api-proxy/proxy_events_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package apiproxy
import (
@@ -17,12 +17,12 @@ import (
"reflect"
"testing"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/sessionrecording"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsnet"
"go.uber.org/zap"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/net/netx"
- "tailscale.com/sessionrecording"
- "tailscale.com/tailcfg"
- "tailscale.com/tsnet"
)
type fakeSender struct {
diff --git a/k8s-operator/api-proxy/proxy_test.go b/k8s-operator/api-proxy/proxy_test.go
index 5d1606d764e45..b2af4991b16d2 100644
--- a/k8s-operator/api-proxy/proxy_test.go
+++ b/k8s-operator/api-proxy/proxy_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package apiproxy
import (
@@ -12,10 +12,10 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/must"
"go.uber.org/zap"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/tailcfg"
- "tailscale.com/util/must"
)
func TestImpersonationHeaders(t *testing.T) {
diff --git a/k8s-operator/apis/v1alpha1/register.go b/k8s-operator/apis/v1alpha1/register.go
index 125d7419866ea..9bb45de47d9a1 100644
--- a/k8s-operator/apis/v1alpha1/register.go
+++ b/k8s-operator/apis/v1alpha1/register.go
@@ -8,7 +8,7 @@ package v1alpha1
import (
"fmt"
- "tailscale.com/k8s-operator/apis"
+ "github.com/metacubex/tailscale/k8s-operator/apis"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
diff --git a/k8s-operator/apis/v1alpha1/types_connector.go b/k8s-operator/apis/v1alpha1/types_connector.go
index af2df58af2fd9..bacaca6e59101 100644
--- a/k8s-operator/apis/v1alpha1/types_connector.go
+++ b/k8s-operator/apis/v1alpha1/types_connector.go
@@ -31,7 +31,7 @@ var ConnectorKind = "Connector"
// exit node.
// Connector is a cluster-scoped resource.
// More info:
-// https://tailscale.com/kb/1441/kubernetes-operator-connector
+// https://github.com/metacubex/tailscale/kb/1441/kubernetes-operator-connector
type Connector struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
@@ -67,9 +67,9 @@ type ConnectorSpec struct {
// To autoapprove the subnet routes or exit node defined by a Connector,
// you can configure Tailscale ACLs to give these tags the necessary
// permissions.
- // See https://tailscale.com/kb/1337/acl-syntax#autoapprovers.
+ // See https://github.com/metacubex/tailscale/kb/1337/acl-syntax#autoapprovers.
// If you specify custom tags here, you must also make the operator an owner of these tags.
- // See https://tailscale.com/kb/1236/kubernetes-operator/#setting-up-the-kubernetes-operator.
+ // See https://github.com/metacubex/tailscale/kb/1236/kubernetes-operator/#setting-up-the-kubernetes-operator.
// Tags cannot be changed once a Connector node has been created.
// Tag values must be in form ^tag:[a-zA-Z][a-zA-Z0-9-]*$.
// +optional
@@ -99,7 +99,7 @@ type ConnectorSpec struct {
ProxyClass string `json:"proxyClass,omitempty"`
// SubnetRouter defines subnet routes that the Connector device should
// expose to tailnet as a Tailscale subnet router.
- // https://tailscale.com/kb/1019/subnets/
+ // https://github.com/metacubex/tailscale/kb/1019/subnets/
// If this field is unset, the device does not get configured as a Tailscale subnet router.
// This field is mutually exclusive with the appConnector field.
// +optional
@@ -117,19 +117,19 @@ type ConnectorSpec struct {
// can be whitelisted, it is also your responsibility to ensure that cluster traffic from the connector flows
// via that predictable IP, for example by enforcing that cluster egress traffic is routed via an egress NAT
// device with a static IP address.
- // https://tailscale.com/kb/1281/app-connectors
+ // https://github.com/metacubex/tailscale/kb/1281/app-connectors
// +optional
AppConnector *AppConnector `json:"appConnector,omitempty"`
// ExitNode defines whether the Connector device should act as a Tailscale exit node. Defaults to false.
// This field is mutually exclusive with the appConnector field.
- // https://tailscale.com/kb/1103/exit-nodes
+ // https://github.com/metacubex/tailscale/kb/1103/exit-nodes
// +optional
ExitNode bool `json:"exitNode"`
// Replicas specifies how many devices to create. Set this to enable
// high availability for app connectors, subnet routers, or exit nodes.
- // https://tailscale.com/kb/1115/high-availability. Defaults to 1.
+ // https://github.com/metacubex/tailscale/kb/1115/high-availability. Defaults to 1.
// +optional
// +kubebuilder:validation:Minimum=0
Replicas *int32 `json:"replicas,omitempty"`
@@ -147,7 +147,7 @@ type SubnetRouter struct {
// AdvertiseRoutes refer to CIDRs that the subnet router should make
// available. Route values must be strings that represent a valid IPv4
// or IPv6 CIDR range. Values can be Tailscale 4via6 subnet routes.
- // https://tailscale.com/kb/1201/4via6-subnets/
+ // https://github.com/metacubex/tailscale/kb/1201/4via6-subnets/
AdvertiseRoutes Routes `json:"advertiseRoutes"`
}
@@ -157,7 +157,7 @@ type AppConnector struct {
// If not set, routes for the domains will be discovered dynamically.
// If set, the app connector will immediately be able to route traffic using the preconfigured routes, but may
// also dynamically discover other routes.
- // https://tailscale.com/kb/1332/apps-best-practices#preconfiguration
+ // https://github.com/metacubex/tailscale/kb/1332/apps-best-practices#preconfiguration
// +optional
Routes Routes `json:"routes"`
}
diff --git a/k8s-operator/apis/v1alpha1/types_proxyclass.go b/k8s-operator/apis/v1alpha1/types_proxyclass.go
index 3c2fe76868ae3..6d9019d8247fc 100644
--- a/k8s-operator/apis/v1alpha1/types_proxyclass.go
+++ b/k8s-operator/apis/v1alpha1/types_proxyclass.go
@@ -7,7 +7,7 @@ package v1alpha1
import (
"fmt"
- "iter"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
"strings"
corev1 "k8s.io/api/core/v1"
@@ -25,12 +25,12 @@ var ProxyClassKind = "ProxyClass"
// ProxyClass describes a set of configuration parameters that can be applied to
// proxy resources created by the Tailscale Kubernetes operator.
// To apply a given ProxyClass to resources created for a tailscale Ingress or
-// Service, use tailscale.com/proxy-class= label. To apply a
+// Service, use github.com/metacubex/tailscale/proxy-class= label. To apply a
// given ProxyClass to resources created for a Connector, use
// connector.spec.proxyClass field.
// ProxyClass is a cluster scoped resource.
// More info:
-// https://tailscale.com/kb/1445/kubernetes-operator-customization#cluster-resource-customization-using-proxyclass-custom-resource
+// https://github.com/metacubex/tailscale/kb/1445/kubernetes-operator-customization#cluster-resource-customization-using-proxyclass-custom-resource
type ProxyClass struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
@@ -61,7 +61,7 @@ type ProxyClassSpec struct {
StatefulSet *StatefulSet `json:"statefulSet"`
// Configuration for proxy metrics. Metrics are currently not supported
// for egress proxies and for Ingress proxies that have been configured
- // with tailscale.com/experimental-forward-cluster-traffic-via-ingress
+ // with github.com/metacubex/tailscale/experimental-forward-cluster-traffic-via-ingress
// annotation. Note that the metrics are currently considered unstable
// and will likely change in breaking ways in the future - we only
// recommend that you use those for debugging purposes.
@@ -88,7 +88,7 @@ type ProxyClassSpec struct {
UseLetsEncryptStagingEnvironment bool `json:"useLetsEncryptStagingEnvironment,omitempty"`
// Configuration for 'static endpoints' on proxies in order to facilitate
// direct connections from other devices on the tailnet.
- // See https://tailscale.com/kb/1445/kubernetes-operator-customization#static-endpoints.
+ // See https://github.com/metacubex/tailscale/kb/1445/kubernetes-operator-customization#static-endpoints.
// +optional
StaticEndpoints *StaticEndpointsConfig `json:"staticEndpoints,omitempty"`
}
@@ -211,7 +211,7 @@ type TailscaleConfig struct {
// routes advertized by other nodes on the tailnet, such as subnet
// routes.
// This is equivalent of passing --accept-routes flag to a tailscale Linux client.
- // https://tailscale.com/kb/1019/subnets#use-your-subnet-routes-from-other-devices
+ // https://github.com/metacubex/tailscale/kb/1019/subnets#use-your-subnet-routes-from-other-devices
// Defaults to false.
AcceptRoutes bool `json:"acceptRoutes,omitempty"`
}
diff --git a/k8s-operator/apis/v1alpha1/types_proxygroup.go b/k8s-operator/apis/v1alpha1/types_proxygroup.go
index 00c196628ab86..fc56b417dc2c1 100644
--- a/k8s-operator/apis/v1alpha1/types_proxygroup.go
+++ b/k8s-operator/apis/v1alpha1/types_proxygroup.go
@@ -23,13 +23,13 @@ import (
// and egress ProxyGroups also allow for serving many annotated Services from a
// single set of proxies to minimise resource consumption.
//
-// For ingress and egress, use the tailscale.com/proxy-group annotation on a
+// For ingress and egress, use the github.com/metacubex/tailscale/proxy-group annotation on a
// Service to specify that the proxy should be implemented by a ProxyGroup
// instead of a single dedicated proxy.
//
// More info:
-// * https://tailscale.com/kb/1438/kubernetes-operator-cluster-egress
-// * https://tailscale.com/kb/1439/kubernetes-operator-cluster-ingress
+// * https://github.com/metacubex/tailscale/kb/1438/kubernetes-operator-cluster-egress
+// * https://github.com/metacubex/tailscale/kb/1439/kubernetes-operator-cluster-ingress
//
// For kube-apiserver, the ProxyGroup is a standalone resource. Use the
// spec.kubeAPIServer field to configure options specific to the kube-apiserver
@@ -65,7 +65,7 @@ type ProxyGroupSpec struct {
// Tags that the Tailscale devices will be tagged with. Defaults to [tag:k8s].
// If you specify custom tags here, make sure you also make the operator
// an owner of these tags.
- // See https://tailscale.com/kb/1236/kubernetes-operator/#setting-up-the-kubernetes-operator.
+ // See https://github.com/metacubex/tailscale/kb/1236/kubernetes-operator/#setting-up-the-kubernetes-operator.
// Tags cannot be changed once a ProxyGroup device has been created.
// Tag values must be in form ^tag:[a-zA-Z][a-zA-Z0-9-]*$.
// +optional
diff --git a/k8s-operator/apis/v1alpha1/types_recorder.go b/k8s-operator/apis/v1alpha1/types_recorder.go
index 284c3b0ae48f4..8d513191ed0ff 100644
--- a/k8s-operator/apis/v1alpha1/types_recorder.go
+++ b/k8s-operator/apis/v1alpha1/types_recorder.go
@@ -21,7 +21,7 @@ import (
// it will store recordings in a local ephemeral volume. If you want to persist
// recordings, you can configure an S3-compatible API for storage.
//
-// More info: https://tailscale.com/kb/1484/kubernetes-operator-deploying-tsrecorder
+// More info: https://github.com/metacubex/tailscale/kb/1484/kubernetes-operator-deploying-tsrecorder
type Recorder struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
@@ -55,7 +55,7 @@ type RecorderSpec struct {
// Tags that the Tailscale device will be tagged with. Defaults to [tag:k8s].
// If you specify custom tags here, make sure you also make the operator
// an owner of these tags.
- // See https://tailscale.com/kb/1236/kubernetes-operator/#setting-up-the-kubernetes-operator.
+ // See https://github.com/metacubex/tailscale/kb/1236/kubernetes-operator/#setting-up-the-kubernetes-operator.
// Tags cannot be changed once a Recorder node has been created.
// Tag values must be in form ^tag:[a-zA-Z][a-zA-Z0-9-]*$.
// +optional
@@ -66,7 +66,7 @@ type RecorderSpec struct {
// Set to true to enable the Recorder UI. The UI lists and plays recorded sessions.
// The UI will be served at :443. Defaults to false.
- // Corresponds to --ui tsrecorder flag https://tailscale.com/kb/1246/tailscale-ssh-session-recording#deploy-a-recorder-node.
+ // Corresponds to --ui tsrecorder flag https://github.com/metacubex/tailscale/kb/1246/tailscale-ssh-session-recording#deploy-a-recorder-node.
// Required if S3 storage is not set up, to ensure that recordings are accessible.
// +optional
EnableUI bool `json:"enableUI,omitempty"`
diff --git a/k8s-operator/apis/v1alpha1/types_tsdnsconfig.go b/k8s-operator/apis/v1alpha1/types_tsdnsconfig.go
index 529114c2e1957..56a72c55909e9 100644
--- a/k8s-operator/apis/v1alpha1/types_tsdnsconfig.go
+++ b/k8s-operator/apis/v1alpha1/types_tsdnsconfig.go
@@ -44,7 +44,7 @@ var DNSConfigKind = "DNSConfig"
// DNSConfig is a singleton - you must not create more than one.
// NB: if you want cluster workloads to be able to refer to Tailscale Ingress
// using its MagicDNS name, you must also annotate the Ingress resource with
-// tailscale.com/experimental-forward-cluster-traffic-via-ingress annotation to
+// github.com/metacubex/tailscale/experimental-forward-cluster-traffic-via-ingress annotation to
// ensure that the proxy created for the Ingress listens on its Pod IP address.
type DNSConfig struct {
metav1.TypeMeta `json:",inline"`
diff --git a/k8s-operator/conditions.go b/k8s-operator/conditions.go
index 89b83dd5f83cc..4171aae3da9fc 100644
--- a/k8s-operator/conditions.go
+++ b/k8s-operator/conditions.go
@@ -6,7 +6,7 @@
package kube
import (
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"time"
"go.uber.org/zap"
@@ -14,8 +14,8 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/tstime"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/tstime"
)
// SetConnectorCondition ensures that Connector status has a condition with the
diff --git a/k8s-operator/conditions_test.go b/k8s-operator/conditions_test.go
index 940a300d88ba8..786ed5abb3373 100644
--- a/k8s-operator/conditions_test.go
+++ b/k8s-operator/conditions_test.go
@@ -1,19 +1,19 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package kube
import (
"testing"
"time"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/tstest"
"github.com/stretchr/testify/assert"
"go.uber.org/zap"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/tstest"
)
func TestSetConnectorCondition(t *testing.T) {
diff --git a/k8s-operator/reconciler/proxygrouppolicy/proxygrouppolicy.go b/k8s-operator/reconciler/proxygrouppolicy/proxygrouppolicy.go
index b4c311046bc7c..120535f10beac 100644
--- a/k8s-operator/reconciler/proxygrouppolicy/proxygrouppolicy.go
+++ b/k8s-operator/reconciler/proxygrouppolicy/proxygrouppolicy.go
@@ -5,7 +5,7 @@
// Package proxygrouppolicy provides reconciliation logic for the ProxyGroupPolicy custom resource definition. It is
// responsible for generating ValidatingAdmissionPolicy resources that limit users to a set number of ProxyGroup
-// names that can be used within Service and Ingress resources via the "tailscale.com/proxy-group" annotation.
+// names that can be used within Service and Ingress resources via the "github.com/metacubex/tailscale/proxy-group" annotation.
package proxygrouppolicy
import (
@@ -23,8 +23,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/util/set"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/util/set"
)
type (
@@ -188,7 +188,7 @@ const (
// Empty allowlist behavior:
// If the list is empty, any present annotation will fail membership,
// effectively acting as "deny-all".
- ingressCEL = `request.kind.kind != "Ingress" || !("tailscale.com/proxy-group" in object.metadata.annotations) || object.metadata.annotations["tailscale.com/proxy-group"] in [%s]`
+ ingressCEL = `request.kind.kind != "Ingress" || !("github.com/metacubex/tailscale/proxy-group" in object.metadata.annotations) || object.metadata.annotations["github.com/metacubex/tailscale/proxy-group"] in [%s]`
// ingressServiceCEL enforces proxy-group annotation rules for Services
// that are using the tailscale load balancer.
@@ -202,7 +202,7 @@ const (
// - If annotation is present → must be in allowlist
//
// This makes ingress policy apply ONLY to tailscale Services.
- ingressServiceCEL = `request.kind.kind != "Service" || !((has(object.spec.loadBalancerClass) && object.spec.loadBalancerClass == "tailscale") || ("tailscale.com/expose" in object.metadata.annotations && object.metadata.annotations["tailscale.com/expose"] == "true")) || (!("tailscale.com/proxy-group" in object.metadata.annotations) || object.metadata.annotations["tailscale.com/proxy-group"] in [%s])`
+ ingressServiceCEL = `request.kind.kind != "Service" || !((has(object.spec.loadBalancerClass) && object.spec.loadBalancerClass == "tailscale") || ("github.com/metacubex/tailscale/expose" in object.metadata.annotations && object.metadata.annotations["github.com/metacubex/tailscale/expose"] == "true")) || (!("github.com/metacubex/tailscale/proxy-group" in object.metadata.annotations) || object.metadata.annotations["github.com/metacubex/tailscale/proxy-group"] in [%s])`
// egressCEL enforces proxy-group annotation rules for Services that
// are NOT using the tailscale load balancer.
//
@@ -210,7 +210,7 @@ const (
//
// - If Service uses loadBalancerClass "tailscale" → allow
// (ingress policy handles those)
- // - If Service uses "tailscale.com/expose" → allow
+ // - If Service uses "github.com/metacubex/tailscale/expose" → allow
// (ingress policy handles those)
// - If annotation is absent → allow
// - If annotation is present → must be in allowlist
@@ -220,7 +220,7 @@ const (
//
// This expression is mutually exclusive with ingressServiceCEL,
// preventing policy conflicts.
- egressCEL = `((has(object.spec.loadBalancerClass) && object.spec.loadBalancerClass == "tailscale") || ("tailscale.com/expose" in object.metadata.annotations && object.metadata.annotations["tailscale.com/expose"] == "true")) || !("tailscale.com/proxy-group" in object.metadata.annotations) || object.metadata.annotations["tailscale.com/proxy-group"] in [%s]`
+ egressCEL = `((has(object.spec.loadBalancerClass) && object.spec.loadBalancerClass == "tailscale") || ("github.com/metacubex/tailscale/expose" in object.metadata.annotations && object.metadata.annotations["github.com/metacubex/tailscale/expose"] == "true")) || !("github.com/metacubex/tailscale/proxy-group" in object.metadata.annotations) || object.metadata.annotations["github.com/metacubex/tailscale/proxy-group"] in [%s]`
)
func (r *Reconciler) generateIngressPolicy(ctx context.Context, namespace string, names set.Set[string]) (*admr.ValidatingAdmissionPolicy, error) {
@@ -329,8 +329,8 @@ func (r *Reconciler) generateEgressPolicy(ctx context.Context, namespace string,
}
const (
- denyMessage = `Annotation "tailscale.com/proxy-group" cannot be used on this resource in this namespace`
- messageFormat = `If set, annotation "tailscale.com/proxy-group" must be one of [%s]`
+ denyMessage = `Annotation "github.com/metacubex/tailscale/proxy-group" cannot be used on this resource in this namespace`
+ messageFormat = `If set, annotation "github.com/metacubex/tailscale/proxy-group" must be one of [%s]`
)
func generateValidation(names set.Set[string], format string) admr.Validation {
diff --git a/k8s-operator/reconciler/proxygrouppolicy/proxygrouppolicy_test.go b/k8s-operator/reconciler/proxygrouppolicy/proxygrouppolicy_test.go
index d5c0b6d353e21..89a6208bd1290 100644
--- a/k8s-operator/reconciler/proxygrouppolicy/proxygrouppolicy_test.go
+++ b/k8s-operator/reconciler/proxygrouppolicy/proxygrouppolicy_test.go
@@ -1,10 +1,12 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package proxygrouppolicy_test
import (
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
"testing"
@@ -15,8 +17,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/reconciler/proxygrouppolicy"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/reconciler/proxygrouppolicy"
)
func TestReconciler_Reconcile(t *testing.T) {
diff --git a/k8s-operator/reconciler/reconciler.go b/k8s-operator/reconciler/reconciler.go
index fcad7201e31e4..dba9a9025d0fe 100644
--- a/k8s-operator/reconciler/reconciler.go
+++ b/k8s-operator/reconciler/reconciler.go
@@ -8,14 +8,14 @@
package reconciler
import (
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"sigs.k8s.io/controller-runtime/pkg/client"
)
const (
// FinalizerName is the common finalizer used across all Tailscale Kubernetes resources.
- FinalizerName = "tailscale.com/finalizer"
+ FinalizerName = "github.com/metacubex/tailscale/finalizer"
)
// SetFinalizer adds the finalizer to the resource if not already present.
diff --git a/k8s-operator/reconciler/reconciler_test.go b/k8s-operator/reconciler/reconciler_test.go
index 2db77e7aad419..500656f53d0d2 100644
--- a/k8s-operator/reconciler/reconciler_test.go
+++ b/k8s-operator/reconciler/reconciler_test.go
@@ -1,18 +1,18 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package reconciler_test
import (
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"testing"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "tailscale.com/k8s-operator/reconciler"
+ "github.com/metacubex/tailscale/k8s-operator/reconciler"
)
func TestFinalizers(t *testing.T) {
diff --git a/k8s-operator/reconciler/tailnet/mocks_test.go b/k8s-operator/reconciler/tailnet/mocks_test.go
index 3931e4d33bbb5..ec804fb2902d2 100644
--- a/k8s-operator/reconciler/tailnet/mocks_test.go
+++ b/k8s-operator/reconciler/tailnet/mocks_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package tailnet_test
import (
@@ -11,7 +11,7 @@ import (
"tailscale.com/client/tailscale/v2"
- "tailscale.com/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
)
type (
diff --git a/k8s-operator/reconciler/tailnet/tailnet.go b/k8s-operator/reconciler/tailnet/tailnet.go
index e30bb21702e39..bdbef6cf0ae60 100644
--- a/k8s-operator/reconciler/tailnet/tailnet.go
+++ b/k8s-operator/reconciler/tailnet/tailnet.go
@@ -27,15 +27,15 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"tailscale.com/client/tailscale/v2"
- "tailscale.com/ipn"
- operatorutils "tailscale.com/k8s-operator"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/reconciler"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tstime"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/ipn"
+ operatorutils "github.com/metacubex/tailscale/k8s-operator"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/reconciler"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/set"
)
type (
diff --git a/k8s-operator/reconciler/tailnet/tailnet_test.go b/k8s-operator/reconciler/tailnet/tailnet_test.go
index 513ed7b84dcd1..d374f8ab8eaa3 100644
--- a/k8s-operator/reconciler/tailnet/tailnet_test.go
+++ b/k8s-operator/reconciler/tailnet/tailnet_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package tailnet_test
import (
@@ -16,10 +16,10 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
- tsapi "tailscale.com/k8s-operator/apis/v1alpha1"
- "tailscale.com/k8s-operator/reconciler/tailnet"
- "tailscale.com/k8s-operator/tsclient"
- "tailscale.com/tstest"
+ tsapi "github.com/metacubex/tailscale/k8s-operator/apis/v1alpha1"
+ "github.com/metacubex/tailscale/k8s-operator/reconciler/tailnet"
+ "github.com/metacubex/tailscale/k8s-operator/tsclient"
+ "github.com/metacubex/tailscale/tstest"
)
func TestReconciler_Reconcile(t *testing.T) {
diff --git a/k8s-operator/sessionrecording/fakes/fakes.go b/k8s-operator/sessionrecording/fakes/fakes.go
index 26f57e4eb4b69..e504d722c1e9c 100644
--- a/k8s-operator/sessionrecording/fakes/fakes.go
+++ b/k8s-operator/sessionrecording/fakes/fakes.go
@@ -17,8 +17,8 @@ import (
"testing"
"time"
- "tailscale.com/sessionrecording"
- "tailscale.com/tstime"
+ "github.com/metacubex/tailscale/sessionrecording"
+ "github.com/metacubex/tailscale/tstime"
)
func New(conn net.Conn, wb bytes.Buffer, rb bytes.Buffer, closed bool) net.Conn {
diff --git a/k8s-operator/sessionrecording/hijacker.go b/k8s-operator/sessionrecording/hijacker.go
index cdbeeddb43ac8..88d75354f2a70 100644
--- a/k8s-operator/sessionrecording/hijacker.go
+++ b/k8s-operator/sessionrecording/hijacker.go
@@ -20,17 +20,17 @@ import (
"net/netip"
"strings"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/k8s-operator/sessionrecording/spdy"
+ "github.com/metacubex/tailscale/k8s-operator/sessionrecording/tsrecorder"
+ "github.com/metacubex/tailscale/k8s-operator/sessionrecording/ws"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/sessionrecording"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/clientmetric"
"go.uber.org/zap"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/k8s-operator/sessionrecording/spdy"
- "tailscale.com/k8s-operator/sessionrecording/tsrecorder"
- "tailscale.com/k8s-operator/sessionrecording/ws"
- "tailscale.com/net/netx"
- "tailscale.com/sessionrecording"
- "tailscale.com/tailcfg"
- "tailscale.com/tsnet"
- "tailscale.com/tstime"
- "tailscale.com/util/clientmetric"
)
const (
diff --git a/k8s-operator/sessionrecording/hijacker_test.go b/k8s-operator/sessionrecording/hijacker_test.go
index ac243c2e8bc82..f64ea6e36eb76 100644
--- a/k8s-operator/sessionrecording/hijacker_test.go
+++ b/k8s-operator/sessionrecording/hijacker_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package sessionrecording
import (
@@ -16,13 +16,13 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/k8s-operator/sessionrecording/fakes"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/tstest"
"go.uber.org/zap"
- "tailscale.com/client/tailscale/apitype"
- "tailscale.com/k8s-operator/sessionrecording/fakes"
- "tailscale.com/net/netx"
- "tailscale.com/tailcfg"
- "tailscale.com/tsnet"
- "tailscale.com/tstest"
)
func Test_Hijacker(t *testing.T) {
diff --git a/k8s-operator/sessionrecording/spdy/conn.go b/k8s-operator/sessionrecording/spdy/conn.go
index 682003055acb8..9b9e7c6deb616 100644
--- a/k8s-operator/sessionrecording/spdy/conn.go
+++ b/k8s-operator/sessionrecording/spdy/conn.go
@@ -18,10 +18,10 @@ import (
"sync"
"sync/atomic"
+ "github.com/metacubex/tailscale/k8s-operator/sessionrecording/tsrecorder"
+ "github.com/metacubex/tailscale/sessionrecording"
"go.uber.org/zap"
corev1 "k8s.io/api/core/v1"
- "tailscale.com/k8s-operator/sessionrecording/tsrecorder"
- "tailscale.com/sessionrecording"
)
// New wraps the provided network connection and returns a connection whose reads and writes will get triggered as data is received on the hijacked connection.
diff --git a/k8s-operator/sessionrecording/spdy/conn_test.go b/k8s-operator/sessionrecording/spdy/conn_test.go
index 232fa8e2c2227..eff25c3b77c94 100644
--- a/k8s-operator/sessionrecording/spdy/conn_test.go
+++ b/k8s-operator/sessionrecording/spdy/conn_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package spdy
import (
@@ -13,11 +13,11 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/k8s-operator/sessionrecording/fakes"
+ "github.com/metacubex/tailscale/k8s-operator/sessionrecording/tsrecorder"
+ "github.com/metacubex/tailscale/sessionrecording"
+ "github.com/metacubex/tailscale/tstest"
"go.uber.org/zap"
- "tailscale.com/k8s-operator/sessionrecording/fakes"
- "tailscale.com/k8s-operator/sessionrecording/tsrecorder"
- "tailscale.com/sessionrecording"
- "tailscale.com/tstest"
)
// Test_Writes tests that 1 or more Write calls to spdyRemoteConnRecorder
diff --git a/k8s-operator/sessionrecording/spdy/frame_test.go b/k8s-operator/sessionrecording/spdy/frame_test.go
index 1b7e54f4cc1fb..5504006b02603 100644
--- a/k8s-operator/sessionrecording/spdy/frame_test.go
+++ b/k8s-operator/sessionrecording/spdy/frame_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package spdy
import (
diff --git a/k8s-operator/sessionrecording/tsrecorder/tsrecorder.go b/k8s-operator/sessionrecording/tsrecorder/tsrecorder.go
index 40a96d6d29ac7..8eb7279bee3c0 100644
--- a/k8s-operator/sessionrecording/tsrecorder/tsrecorder.go
+++ b/k8s-operator/sessionrecording/tsrecorder/tsrecorder.go
@@ -13,10 +13,10 @@ import (
"sync"
"time"
+ "github.com/metacubex/tailscale/sessionrecording"
+ "github.com/metacubex/tailscale/tstime"
"github.com/pkg/errors"
"go.uber.org/zap"
- "tailscale.com/sessionrecording"
- "tailscale.com/tstime"
)
func New(conn io.WriteCloser, clock tstime.Clock, start time.Time, failOpen bool, logger *zap.SugaredLogger) *Client {
diff --git a/k8s-operator/sessionrecording/ws/conn.go b/k8s-operator/sessionrecording/ws/conn.go
index ed0ecc7ac7f0d..0dd73c025c122 100644
--- a/k8s-operator/sessionrecording/ws/conn.go
+++ b/k8s-operator/sessionrecording/ws/conn.go
@@ -17,10 +17,10 @@ import (
"net"
"sync"
+ "github.com/metacubex/tailscale/k8s-operator/sessionrecording/tsrecorder"
+ "github.com/metacubex/tailscale/sessionrecording"
"go.uber.org/zap"
"k8s.io/apimachinery/pkg/util/remotecommand"
- "tailscale.com/k8s-operator/sessionrecording/tsrecorder"
- "tailscale.com/sessionrecording"
)
// New wraps the provided network connection and returns a connection whose reads and writes will get triggered as data is received on the hijacked connection.
diff --git a/k8s-operator/sessionrecording/ws/conn_test.go b/k8s-operator/sessionrecording/ws/conn_test.go
index ea9aca19296d5..e6c487f3aa07e 100644
--- a/k8s-operator/sessionrecording/ws/conn_test.go
+++ b/k8s-operator/sessionrecording/ws/conn_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package ws
import (
@@ -13,12 +13,12 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/k8s-operator/sessionrecording/fakes"
+ "github.com/metacubex/tailscale/k8s-operator/sessionrecording/tsrecorder"
+ "github.com/metacubex/tailscale/sessionrecording"
+ "github.com/metacubex/tailscale/tstest"
"go.uber.org/zap"
"k8s.io/apimachinery/pkg/util/remotecommand"
- "tailscale.com/k8s-operator/sessionrecording/fakes"
- "tailscale.com/k8s-operator/sessionrecording/tsrecorder"
- "tailscale.com/sessionrecording"
- "tailscale.com/tstest"
)
func Test_conn_Read(t *testing.T) {
diff --git a/k8s-operator/sessionrecording/ws/message_test.go b/k8s-operator/sessionrecording/ws/message_test.go
index 07d55ce4dcbd5..4d5ddadf14f6b 100644
--- a/k8s-operator/sessionrecording/ws/message_test.go
+++ b/k8s-operator/sessionrecording/ws/message_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package ws
import (
diff --git a/k8s-operator/utils.go b/k8s-operator/utils.go
index d83d98e0cc8ca..42655fb775a64 100644
--- a/k8s-operator/utils.go
+++ b/k8s-operator/utils.go
@@ -11,7 +11,7 @@ import (
"encoding/hex"
"fmt"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/tailcfg"
)
const (
diff --git a/k8s-operator/utils_test.go b/k8s-operator/utils_test.go
index 7a30df6b4e708..3ee30d5ec6c2d 100644
--- a/k8s-operator/utils_test.go
+++ b/k8s-operator/utils_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package kube
import (
diff --git a/kube/authkey/authkey.go b/kube/authkey/authkey.go
index f544a0c81f010..b50b0accd68fb 100644
--- a/kube/authkey/authkey.go
+++ b/kube/authkey/authkey.go
@@ -19,11 +19,11 @@ import (
"log"
"time"
- "tailscale.com/ipn"
- "tailscale.com/ipn/conffile"
- "tailscale.com/kube/kubeapi"
- "tailscale.com/kube/kubeclient"
- "tailscale.com/kube/kubetypes"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/conffile"
+ "github.com/metacubex/tailscale/kube/kubeapi"
+ "github.com/metacubex/tailscale/kube/kubeclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
)
const (
diff --git a/kube/authkey/authkey_test.go b/kube/authkey/authkey_test.go
index 268bc46d6ac3e..214d01ca9cb82 100644
--- a/kube/authkey/authkey_test.go
+++ b/kube/authkey/authkey_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package authkey
import (
@@ -12,10 +12,10 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
- "tailscale.com/ipn"
- "tailscale.com/kube/kubeapi"
- "tailscale.com/kube/kubeclient"
- "tailscale.com/kube/kubetypes"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/kube/kubeapi"
+ "github.com/metacubex/tailscale/kube/kubeclient"
+ "github.com/metacubex/tailscale/kube/kubetypes"
)
func TestSetReissueAuthKey(t *testing.T) {
diff --git a/kube/certs/certs.go b/kube/certs/certs.go
index fd7c82a100dd7..5a83d46e3f734 100644
--- a/kube/certs/certs.go
+++ b/kube/certs/certs.go
@@ -8,16 +8,16 @@ package certs
import (
"context"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net"
- "slices"
"sync"
"time"
- "tailscale.com/ipn"
- "tailscale.com/kube/localclient"
- "tailscale.com/types/logger"
- "tailscale.com/util/goroutines"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/kube/localclient"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/goroutines"
+ "github.com/metacubex/tailscale/util/mak"
)
// CertManager is responsible for issuing certificates for known domains and for
diff --git a/kube/certs/certs_test.go b/kube/certs/certs_test.go
index 27fe12752001c..ded3ca92857fc 100644
--- a/kube/certs/certs_test.go
+++ b/kube/certs/certs_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,9 +11,9 @@ import (
"testing"
"time"
- "tailscale.com/ipn"
- "tailscale.com/kube/localclient"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/kube/localclient"
+ "github.com/metacubex/tailscale/tailcfg"
)
// TestEnsureCertLoops tests that the certManager correctly starts and stops
diff --git a/kube/egressservices/egressservices_test.go b/kube/egressservices/egressservices_test.go
index 27d818cab970a..d1307ffd407e2 100644
--- a/kube/egressservices/egressservices_test.go
+++ b/kube/egressservices/egressservices_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/kube/health/healthz.go b/kube/health/healthz.go
index e9b459fc19e76..52c139267d7a5 100644
--- a/kube/health/healthz.go
+++ b/kube/health/healthz.go
@@ -13,10 +13,10 @@ import (
"net/http"
"sync"
- "tailscale.com/client/local"
- "tailscale.com/ipn"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/types/logger"
)
// Healthz is a simple health check server, if enabled it returns 200 OK if
diff --git a/kube/k8s-proxy/conf/conf.go b/kube/k8s-proxy/conf/conf.go
index 62ef67feecb16..55358ba8dd8be 100644
--- a/kube/k8s-proxy/conf/conf.go
+++ b/kube/k8s-proxy/conf/conf.go
@@ -13,10 +13,10 @@ import (
"fmt"
"net/netip"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/opt"
"github.com/tailscale/hujson"
- "tailscale.com/kube/kubetypes"
- "tailscale.com/tailcfg"
- "tailscale.com/types/opt"
)
const v1Alpha1 = "v1alpha1"
diff --git a/kube/k8s-proxy/conf/conf_test.go b/kube/k8s-proxy/conf/conf_test.go
index 0c26b4242e92f..d0a46e37a324e 100644
--- a/kube/k8s-proxy/conf/conf_test.go
+++ b/kube/k8s-proxy/conf/conf_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package conf
import (
diff --git a/kube/kubeclient/client.go b/kube/kubeclient/client.go
index 5f5ab138eb65e..8ebac745aca6a 100644
--- a/kube/kubeclient/client.go
+++ b/kube/kubeclient/client.go
@@ -28,8 +28,8 @@ import (
"sync"
"time"
- "tailscale.com/kube/kubeapi"
- "tailscale.com/tstime"
+ "github.com/metacubex/tailscale/kube/kubeapi"
+ "github.com/metacubex/tailscale/tstime"
)
const (
diff --git a/kube/kubeclient/client_test.go b/kube/kubeclient/client_test.go
index 9778c7e6fa1ad..816a48bdb2fdc 100644
--- a/kube/kubeclient/client_test.go
+++ b/kube/kubeclient/client_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -13,8 +15,8 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
- "tailscale.com/kube/kubeapi"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/kube/kubeapi"
+ "github.com/metacubex/tailscale/tstest"
)
func Test_client_Event(t *testing.T) {
diff --git a/kube/kubeclient/fake_client.go b/kube/kubeclient/fake_client.go
index 7fb102764a939..537f5958c21b4 100644
--- a/kube/kubeclient/fake_client.go
+++ b/kube/kubeclient/fake_client.go
@@ -7,7 +7,7 @@ import (
"context"
"net"
- "tailscale.com/kube/kubeapi"
+ "github.com/metacubex/tailscale/kube/kubeapi"
)
var _ Client = &FakeClient{}
diff --git a/kube/kubetypes/grants.go b/kube/kubetypes/grants.go
index 8f17a28546d94..4dda717ebfc59 100644
--- a/kube/kubetypes/grants.go
+++ b/kube/kubetypes/grants.go
@@ -22,7 +22,7 @@ type KubernetesCapRule struct {
// name matches the `Recorder` field with equal semantics for Tailscale
// SSH session recorder. This field is set by users in ACL grants and is
// then parsed by control, which resolves the tags and populates `RecorderAddrs``.
- // https://tailscale.com/kb/1246/tailscale-ssh-session-recording#turn-on-session-recording-in-acls
+ // https://github.com/metacubex/tailscale/kb/1246/tailscale-ssh-session-recording#turn-on-session-recording-in-acls
Recorders []string `json:"recorder,omitempty"`
// RecorderAddrs is a list of addresses that should be addresses of one
// or more tsrecorder instance(s). If set, any `kubectl exec` session
@@ -38,11 +38,11 @@ type KubernetesCapRule struct {
// Default is to fail open.
// The field name matches `EnforceRecorder` field with equal semantics for Tailscale SSH
// session recorder.
- // https://tailscale.com/kb/1246/tailscale-ssh-session-recording#turn-on-session-recording-in-your-tailnet-policy-file
+ // https://github.com/metacubex/tailscale/kb/1246/tailscale-ssh-session-recording#turn-on-session-recording-in-your-tailnet-policy-file
EnforceRecorder bool `json:"enforceRecorder,omitempty"`
// EnableEvents defines whether kubectl API request events (beta)
// should be recorded or not.
- // https://tailscale.com/kb/1246/tailscale-ssh-session-recording#turn-on-session-recording-in-your-tailnet-policy-file
+ // https://github.com/metacubex/tailscale/kb/1246/tailscale-ssh-session-recording#turn-on-session-recording-in-your-tailnet-policy-file
EnableEvents bool `json:"enableEvents,omitempty"`
}
diff --git a/kube/kubetypes/types.go b/kube/kubetypes/types.go
index 9f1b29064acca..dcbb02bc8d00e 100644
--- a/kube/kubetypes/types.go
+++ b/kube/kubetypes/types.go
@@ -55,8 +55,8 @@ const (
EgessServicesPreshutdownEP = "/internal-egress-services-preshutdown"
- LabelManaged = "tailscale.com/managed"
- LabelSecretType = "tailscale.com/secret-type" // "config", "state" "certs"
+ LabelManaged = "github.com/metacubex/tailscale/managed"
+ LabelSecretType = "github.com/metacubex/tailscale/secret-type" // "config", "state" "certs"
LabelSecretTypeConfig = "config"
LabelSecretTypeState = "state"
diff --git a/kube/kubetypes/types_test.go b/kube/kubetypes/types_test.go
index 86b3962ef1b01..07e7c9a440898 100644
--- a/kube/kubetypes/types_test.go
+++ b/kube/kubetypes/types_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/kube/localclient/fake-client.go b/kube/localclient/fake-client.go
index 7ecada1134cd8..ff6cccd4255fd 100644
--- a/kube/localclient/fake-client.go
+++ b/kube/localclient/fake-client.go
@@ -7,7 +7,7 @@ import (
"context"
"fmt"
- "tailscale.com/ipn"
+ "github.com/metacubex/tailscale/ipn"
)
type FakeLocalClient struct {
diff --git a/kube/localclient/local-client.go b/kube/localclient/local-client.go
index f759568ba195f..731e5acc9762b 100644
--- a/kube/localclient/local-client.go
+++ b/kube/localclient/local-client.go
@@ -9,8 +9,8 @@ import (
"context"
"io"
- "tailscale.com/client/local"
- "tailscale.com/ipn"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/ipn"
)
// LocalClient is roughly a subset of the local.Client struct's methods, used
diff --git a/kube/metrics/metrics.go b/kube/metrics/metrics.go
index 062f18b8b95b5..10a28dd487740 100644
--- a/kube/metrics/metrics.go
+++ b/kube/metrics/metrics.go
@@ -12,8 +12,8 @@ import (
"io"
"net/http"
- "tailscale.com/client/local"
- "tailscale.com/client/tailscale/apitype"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/client/tailscale/apitype"
)
// metrics is a simple metrics HTTP server, if enabled it forwards requests to
diff --git a/kube/services/services.go b/kube/services/services.go
index 0c27f888f5f7d..282329f894535 100644
--- a/kube/services/services.go
+++ b/kube/services/services.go
@@ -10,10 +10,10 @@ import (
"fmt"
"time"
- "tailscale.com/client/local"
- "tailscale.com/ipn"
- "tailscale.com/kube/localclient"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/kube/localclient"
+ "github.com/metacubex/tailscale/types/logger"
)
// EnsureServicesAdvertised is a function that gets called on containerboot
@@ -41,7 +41,7 @@ func EnsureServicesAdvertised(ctx context.Context, services []string, lc localcl
// primary no matter how long we wait. We would need a mechanism to await
// netmap updates for peers to know for sure.
//
- // See https://tailscale.com/kb/1115/high-availability for more details.
+ // See https://github.com/metacubex/tailscale/kb/1115/high-availability for more details.
// TODO(tomhjp): Wait for a netmap update instead of sleeping when control
// supports that.
select {
@@ -88,7 +88,7 @@ func EnsureServicesNotAdvertised(ctx context.Context, lc *local.Client, logf log
// primary no matter how long we wait. We would need a mechanism to await
// netmap updates for peers to know for sure.
//
- // See https://tailscale.com/kb/1115/high-availability for more details.
+ // See https://github.com/metacubex/tailscale/kb/1115/high-availability for more details.
// TODO(tomhjp): Wait for a netmap update instead of sleeping when control
// supports that.
select {
diff --git a/kube/state/state.go b/kube/state/state.go
index 220eb439f80a4..5723f2ab4eba1 100644
--- a/kube/state/state.go
+++ b/kube/state/state.go
@@ -15,11 +15,11 @@ import (
"encoding/json"
"fmt"
- "tailscale.com/ipn"
- "tailscale.com/kube/kubetypes"
- klc "tailscale.com/kube/localclient"
- "tailscale.com/tailcfg"
- "tailscale.com/util/deephash"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/kube/kubetypes"
+ klc "github.com/metacubex/tailscale/kube/localclient"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/deephash"
)
const (
diff --git a/kube/state/state_test.go b/kube/state/state_test.go
index 5c438377e814f..c1c0518d8f95d 100644
--- a/kube/state/state_test.go
+++ b/kube/state/state_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !plan9
-
package state
import (
@@ -13,11 +13,11 @@ import (
"time"
"github.com/google/go-cmp/cmp"
- "tailscale.com/ipn"
- "tailscale.com/ipn/store"
- klc "tailscale.com/kube/localclient"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/store"
+ klc "github.com/metacubex/tailscale/kube/localclient"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
)
func TestSetInitialStateKeys(t *testing.T) {
diff --git a/license_test.go b/license_test.go
index cac195c49c5a4..9a4f15b2c2480 100644
--- a/license_test.go
+++ b/license_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,7 +14,7 @@ import (
"strings"
"testing"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/util/set"
)
func normalizeLineEndings(b []byte) []byte {
diff --git a/licenses/android.md b/licenses/android.md
index 07c97948e1da3..930874647ea74 100644
--- a/licenses/android.md
+++ b/licenses/android.md
@@ -14,7 +14,7 @@ Client][]. See also the dependencies in the [Tailscale CLI][].
- [github.com/djherbis/times](https://pkg.go.dev/github.com/djherbis/times) ([MIT](https://github.com/djherbis/times/blob/v1.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.9.0/LICENSE))
- [github.com/gaissmai/bart](https://pkg.go.dev/github.com/gaissmai/bart) ([MIT](https://github.com/gaissmai/bart/blob/v0.26.1/LICENSE))
- - [github.com/go-json-experiment/json](https://pkg.go.dev/github.com/go-json-experiment/json) ([BSD-3-Clause](https://github.com/go-json-experiment/json/blob/ebf49471dced/LICENSE))
+ - [github.com/metacubex/jsonv2](https://pkg.go.dev/github.com/metacubex/jsonv2) ([BSD-3-Clause](https://github.com/metacubex/jsonv2/blob/ebf49471dced/LICENSE))
- [github.com/golang/groupcache/lru](https://pkg.go.dev/github.com/golang/groupcache/lru) ([Apache-2.0](https://github.com/golang/groupcache/blob/2c02b8208cf8/LICENSE))
- [github.com/google/btree](https://pkg.go.dev/github.com/google/btree) ([Apache-2.0](https://github.com/google/btree/blob/v1.1.3/LICENSE))
- [github.com/google/go-tpm](https://pkg.go.dev/github.com/google/go-tpm) ([Apache-2.0](https://github.com/google/go-tpm/blob/v0.9.4/LICENSE))
diff --git a/licenses/apple.md b/licenses/apple.md
index a7bc6af8cb94b..7303f81def4ff 100644
--- a/licenses/apple.md
+++ b/licenses/apple.md
@@ -35,7 +35,7 @@ See also the dependencies in the [Tailscale CLI][].
- [github.com/djherbis/times](https://pkg.go.dev/github.com/djherbis/times) ([MIT](https://github.com/djherbis/times/blob/v1.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.9.0/LICENSE))
- [github.com/gaissmai/bart](https://pkg.go.dev/github.com/gaissmai/bart) ([MIT](https://github.com/gaissmai/bart/blob/v0.26.1/LICENSE))
- - [github.com/go-json-experiment/json](https://pkg.go.dev/github.com/go-json-experiment/json) ([BSD-3-Clause](https://github.com/go-json-experiment/json/blob/4849db3c2f7e/LICENSE))
+ - [github.com/metacubex/jsonv2](https://pkg.go.dev/github.com/metacubex/jsonv2) ([BSD-3-Clause](https://github.com/metacubex/jsonv2/blob/4849db3c2f7e/LICENSE))
- [github.com/godbus/dbus/v5](https://pkg.go.dev/github.com/godbus/dbus/v5) ([BSD-2-Clause](https://github.com/godbus/dbus/blob/76236955d466/LICENSE))
- [github.com/golang/groupcache/lru](https://pkg.go.dev/github.com/golang/groupcache/lru) ([Apache-2.0](https://github.com/golang/groupcache/blob/2c02b8208cf8/LICENSE))
- [github.com/google/btree](https://pkg.go.dev/github.com/google/btree) ([Apache-2.0](https://github.com/google/btree/blob/v1.1.3/LICENSE))
diff --git a/licenses/licenses.go b/licenses/licenses.go
index a4bf51befe773..791c954cb462e 100644
--- a/licenses/licenses.go
+++ b/licenses/licenses.go
@@ -10,12 +10,12 @@ import "runtime"
func LicensesURL() string {
switch runtime.GOOS {
case "android":
- return "https://tailscale.com/licenses/android"
+ return "https://github.com/metacubex/tailscale/licenses/android"
case "darwin", "ios":
- return "https://tailscale.com/licenses/apple"
+ return "https://github.com/metacubex/tailscale/licenses/apple"
case "windows":
- return "https://tailscale.com/licenses/windows"
+ return "https://github.com/metacubex/tailscale/licenses/windows"
default:
- return "https://tailscale.com/licenses/tailscale"
+ return "https://github.com/metacubex/tailscale/licenses/tailscale"
}
}
diff --git a/licenses/tailscale.md b/licenses/tailscale.md
index 01fdec26f327c..23e8e40002327 100644
--- a/licenses/tailscale.md
+++ b/licenses/tailscale.md
@@ -45,7 +45,7 @@ Some packages may only be included on certain architectures or operating systems
- [github.com/fogleman/gg](https://pkg.go.dev/github.com/fogleman/gg) ([MIT](https://github.com/fogleman/gg/blob/v1.3.0/LICENSE.md))
- [github.com/fxamacker/cbor/v2](https://pkg.go.dev/github.com/fxamacker/cbor/v2) ([MIT](https://github.com/fxamacker/cbor/blob/v2.9.0/LICENSE))
- [github.com/gaissmai/bart](https://pkg.go.dev/github.com/gaissmai/bart) ([MIT](https://github.com/gaissmai/bart/blob/v0.26.1/LICENSE))
- - [github.com/go-json-experiment/json](https://pkg.go.dev/github.com/go-json-experiment/json) ([BSD-3-Clause](https://github.com/go-json-experiment/json/blob/ebf49471dced/LICENSE))
+ - [github.com/metacubex/jsonv2](https://pkg.go.dev/github.com/metacubex/jsonv2) ([BSD-3-Clause](https://github.com/metacubex/jsonv2/blob/ebf49471dced/LICENSE))
- [github.com/go-ole/go-ole](https://pkg.go.dev/github.com/go-ole/go-ole) ([MIT](https://github.com/go-ole/go-ole/blob/v1.3.0/LICENSE))
- [github.com/godbus/dbus/v5](https://pkg.go.dev/github.com/godbus/dbus/v5) ([BSD-2-Clause](https://github.com/godbus/dbus/blob/76236955d466/LICENSE))
- [github.com/golang/freetype/raster](https://pkg.go.dev/github.com/golang/freetype/raster) ([Unknown](Unknown))
diff --git a/licenses/windows.md b/licenses/windows.md
index 33c142550ddcd..dbef7cda0a1e6 100644
--- a/licenses/windows.md
+++ b/licenses/windows.md
@@ -19,7 +19,7 @@ Windows][]. See also the dependencies in the [Tailscale CLI][].
- [github.com/dblohm7/wingoes](https://pkg.go.dev/github.com/dblohm7/wingoes) ([BSD-3-Clause](https://github.com/dblohm7/wingoes/blob/b75a8a7d7eb0/LICENSE))
- [github.com/djherbis/times](https://pkg.go.dev/github.com/djherbis/times) ([MIT](https://github.com/djherbis/times/blob/v1.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.9.0/LICENSE))
- - [github.com/go-json-experiment/json](https://pkg.go.dev/github.com/go-json-experiment/json) ([BSD-3-Clause](https://github.com/go-json-experiment/json/blob/4849db3c2f7e/LICENSE))
+ - [github.com/metacubex/jsonv2](https://pkg.go.dev/github.com/metacubex/jsonv2) ([BSD-3-Clause](https://github.com/metacubex/jsonv2/blob/4849db3c2f7e/LICENSE))
- [github.com/golang/groupcache/lru](https://pkg.go.dev/github.com/golang/groupcache/lru) ([Apache-2.0](https://github.com/golang/groupcache/blob/2c02b8208cf8/LICENSE))
- [github.com/google/btree](https://pkg.go.dev/github.com/google/btree) ([Apache-2.0](https://github.com/google/btree/blob/v1.1.3/LICENSE))
- [github.com/google/go-cmp/cmp](https://pkg.go.dev/github.com/google/go-cmp/cmp) ([BSD-3-Clause](https://github.com/google/go-cmp/blob/v0.7.0/LICENSE))
diff --git a/log/filelogger/log.go b/log/filelogger/log.go
index 268cf1bba7583..3776be19a402d 100644
--- a/log/filelogger/log.go
+++ b/log/filelogger/log.go
@@ -16,7 +16,7 @@ import (
"sync"
"time"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
const (
diff --git a/log/filelogger/log_test.go b/log/filelogger/log_test.go
index 32c3d0e90bf1b..4391c0ed0aed0 100644
--- a/log/filelogger/log_test.go
+++ b/log/filelogger/log_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/log/sockstatlog/logger.go b/log/sockstatlog/logger.go
index 30d16fbcc8c6c..0d1bd5fe8fb95 100644
--- a/log/sockstatlog/logger.go
+++ b/log/sockstatlog/logger.go
@@ -17,17 +17,17 @@ import (
"sync/atomic"
"time"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/health"
- "tailscale.com/logpolicy"
- "tailscale.com/logtail"
- "tailscale.com/logtail/filch"
- "tailscale.com/net/netmon"
- "tailscale.com/net/sockstats"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/logpolicy"
+ "github.com/metacubex/tailscale/logtail"
+ "github.com/metacubex/tailscale/logtail/filch"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/sockstats"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/mak"
)
// pollInterval specifies how often to poll for socket stats.
diff --git a/log/sockstatlog/logger_test.go b/log/sockstatlog/logger_test.go
index 9176cfe53ab57..03bbab5c00a44 100644
--- a/log/sockstatlog/logger_test.go
+++ b/log/sockstatlog/logger_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,10 +10,10 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
- "tailscale.com/net/sockstats"
- "tailscale.com/tstest"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
+ "github.com/metacubex/tailscale/net/sockstats"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
)
func TestResourceCleanup(t *testing.T) {
diff --git a/logpolicy/logpolicy.go b/logpolicy/logpolicy.go
index 7a0027dad74ea..f2fdc606e9134 100644
--- a/logpolicy/logpolicy.go
+++ b/logpolicy/logpolicy.go
@@ -28,36 +28,36 @@ import (
"sync"
"time"
+ "github.com/metacubex/tailscale/atomicfile"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/log/filelogger"
+ "github.com/metacubex/tailscale/logtail"
+ "github.com/metacubex/tailscale/logtail/filch"
+ "github.com/metacubex/tailscale/net/dnscache"
+ "github.com/metacubex/tailscale/net/dnsfallback"
+ "github.com/metacubex/tailscale/net/netknob"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/net/tlsdial"
+ "github.com/metacubex/tailscale/paths"
+ "github.com/metacubex/tailscale/safesocket"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/racebuild"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/util/testenv"
+ "github.com/metacubex/tailscale/version"
+ "github.com/metacubex/tailscale/version/distro"
"golang.org/x/term"
- "tailscale.com/atomicfile"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/health"
- "tailscale.com/hostinfo"
- "tailscale.com/log/filelogger"
- "tailscale.com/logtail"
- "tailscale.com/logtail/filch"
- "tailscale.com/net/dnscache"
- "tailscale.com/net/dnsfallback"
- "tailscale.com/net/netknob"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netns"
- "tailscale.com/net/netx"
- "tailscale.com/net/tlsdial"
- "tailscale.com/paths"
- "tailscale.com/safesocket"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/must"
- "tailscale.com/util/racebuild"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/policyclient"
- "tailscale.com/util/testenv"
- "tailscale.com/version"
- "tailscale.com/version/distro"
)
var getLogTargetOnce struct {
@@ -830,7 +830,7 @@ func dialContext(ctx context.Context, netw, addr string, netMon *netmon.Monitor,
dnsCache := &dnscache.Resolver{
Forward: dnscache.Get().Forward, // use default cache's forwarder
UseLastGood: true,
- LookupIPFallback: dnsfallback.MakeLookupFunc(logf, netMon),
+ LookupIPFallback: dnsfallback.MakeLookupFunc(logf, nd.DialContext),
}
dialer := dnscache.Dialer(nd.DialContext, dnsCache)
c, err = dialer(ctx, netw, addr)
@@ -863,6 +863,10 @@ type TransportOptions struct {
// If nil, [log.Printf] will be used instead.
Logf logger.Logf
+ // DialContext is an optional dialer to use for log uploads.
+ // If nil, [MakeDialFunc] is used.
+ DialContext netx.DialFunc
+
// TLSClientConfig is an optional TLS configuration to use.
// If non-nil, the configuration will be cloned.
TLSClientConfig *tls.Config
@@ -878,7 +882,13 @@ func (opts TransportOptions) New() http.RoundTripper {
opts.NetMon = netmon.NewStatic()
}
// Start with a copy of http.DefaultTransport and tweak it a bit.
- tr := http.DefaultTransport.(*http.Transport).Clone()
+ tr := (&http.Transport{
+ ForceAttemptHTTP2: true,
+ MaxIdleConns: 100,
+ IdleConnTimeout: 90 * time.Second,
+ TLSHandshakeTimeout: 10 * time.Second,
+ ExpectContinueTimeout: 1 * time.Second,
+ }).Clone()
if opts.TLSClientConfig != nil {
tr.TLSClientConfig = opts.TLSClientConfig.Clone()
}
@@ -899,7 +909,11 @@ func (opts TransportOptions) New() http.RoundTripper {
if opts.Logf == nil {
opts.Logf = log.Printf
}
- tr.DialContext = MakeDialFunc(opts.NetMon, opts.Logf)
+ if opts.DialContext != nil {
+ tr.DialContext = opts.DialContext
+ } else {
+ tr.DialContext = MakeDialFunc(opts.NetMon, opts.Logf)
+ }
// We're uploading logs ideally infrequently, with specific timing that will
// change over time. Try to keep the connection open, to avoid repeatedly
@@ -921,7 +935,7 @@ func (opts TransportOptions) New() http.RoundTripper {
tr.TLSNextProto = map[string]func(authority string, c *tls.Conn) http.RoundTripper{}
}
- tr.TLSClientConfig = tlsdial.Config(opts.Health, tr.TLSClientConfig)
+ tr.TLSClientConfig = tlsdial.ConfigWithLogf(opts.Health, tr.TLSClientConfig, opts.Logf)
// Force TLS 1.3 since we know log.tailscale.com supports it.
tr.TLSClientConfig.MinVersion = tls.VersionTLS13
diff --git a/logpolicy/logpolicy_test.go b/logpolicy/logpolicy_test.go
index 64e54467c496b..a62c977cac491 100644
--- a/logpolicy/logpolicy_test.go
+++ b/logpolicy/logpolicy_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,7 +11,7 @@ import (
"reflect"
"testing"
- "tailscale.com/logtail"
+ "github.com/metacubex/tailscale/logtail"
)
func resetLogTarget() {
diff --git a/logpolicy/maybe_syspolicy.go b/logpolicy/maybe_syspolicy.go
index 7cdaabcc7c77a..acb44186f341e 100644
--- a/logpolicy/maybe_syspolicy.go
+++ b/logpolicy/maybe_syspolicy.go
@@ -1,8 +1,8 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_syspolicy
+//go:build ts_enable_syspolicy
package logpolicy
-import _ "tailscale.com/feature/syspolicy"
+import _ "github.com/metacubex/tailscale/feature/syspolicy"
diff --git a/logtail/buffer.go b/logtail/buffer.go
index bc39783ea768a..048d0b2a7e836 100644
--- a/logtail/buffer.go
+++ b/logtail/buffer.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_logtail
+//go:build ts_enable_logtail
package logtail
@@ -11,8 +11,8 @@ import (
"expvar"
"fmt"
- "tailscale.com/metrics"
- "tailscale.com/syncs"
+ "github.com/metacubex/tailscale/metrics"
+ "github.com/metacubex/tailscale/syncs"
)
type Buffer interface {
diff --git a/logtail/config.go b/logtail/config.go
index 0ee5999059fb5..9a6bebda8d4df 100644
--- a/logtail/config.go
+++ b/logtail/config.go
@@ -8,9 +8,9 @@ import (
"net/http"
"time"
- "tailscale.com/tstime"
- "tailscale.com/types/logid"
- "tailscale.com/util/eventbus"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/util/eventbus"
)
// DefaultHost is the default host name to upload logs to when
diff --git a/logtail/example/logadopt/logadopt.go b/logtail/example/logadopt/logadopt.go
index f9104231644b4..c28ec86011701 100644
--- a/logtail/example/logadopt/logadopt.go
+++ b/logtail/example/logadopt/logadopt.go
@@ -25,7 +25,7 @@ func main() {
}
log.SetFlags(0)
- req, err := http.NewRequest("POST", "https://log.tailscale.com/instances", strings.NewReader(url.Values{
+ req, err := http.NewRequest("POST", "https://log.github.com/metacubex/tailscale/instances", strings.NewReader(url.Values{
"collection": []string{*collection},
"instances": []string{*publicID},
"adopt": []string{"true"},
diff --git a/logtail/example/logreprocess/logreprocess.go b/logtail/example/logreprocess/logreprocess.go
index d434da1b187db..c4c098f5c88e8 100644
--- a/logtail/example/logreprocess/logreprocess.go
+++ b/logtail/example/logreprocess/logreprocess.go
@@ -15,7 +15,7 @@ import (
"strings"
"time"
- "tailscale.com/types/logid"
+ "github.com/metacubex/tailscale/types/logid"
)
func main() {
@@ -37,7 +37,7 @@ func main() {
}()
}
- req, err := http.NewRequest("GET", "https://log.tailscale.com/c/"+*collection+"?stream=true", nil)
+ req, err := http.NewRequest("GET", "https://log.github.com/metacubex/tailscale/c/"+*collection+"?stream=true", nil)
if err != nil {
log.Fatal(err)
}
diff --git a/logtail/example/logtail/logtail.go b/logtail/example/logtail/logtail.go
index 24f98090f57c8..07bbdd5dad2e5 100644
--- a/logtail/example/logtail/logtail.go
+++ b/logtail/example/logtail/logtail.go
@@ -11,8 +11,8 @@ import (
"log"
"os"
- "tailscale.com/logtail"
- "tailscale.com/types/logid"
+ "github.com/metacubex/tailscale/logtail"
+ "github.com/metacubex/tailscale/types/logid"
)
func main() {
diff --git a/logtail/filch/filch.go b/logtail/filch/filch.go
index 8ae9123060e73..5e06f4b11021f 100644
--- a/logtail/filch/filch.go
+++ b/logtail/filch/filch.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_logtail
+//go:build ts_enable_logtail
// Package filch is a file system queue that pilfers your stderr.
// (A FILe CHannel that filches.)
@@ -9,21 +9,42 @@ package filch
import (
"bytes"
- "cmp"
"errors"
"expvar"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"os"
- "slices"
"sync"
- "tailscale.com/metrics"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/metrics"
+ "github.com/metacubex/tailscale/util/must"
)
var stderrFD = 2 // a variable for testing
+func maxInt[T ~int | ~int64](a, b T) T {
+ if a > b {
+ return a
+ }
+ return b
+}
+
+func byteLines(b []byte, yield func([]byte) bool) {
+ for len(b) > 0 {
+ i := bytes.IndexByte(b, '\n')
+ if i < 0 {
+ yield(b)
+ return
+ }
+ if !yield(b[:i+1]) {
+ return
+ }
+ b = b[i+1:]
+ }
+}
+
var errTooLong = errors.New("filch: line too long")
var errClosed = errors.New("filch: buffer is closed")
@@ -148,7 +169,7 @@ func (f *Filch) consumeReadBuffer(n int) {
}
func (f *Filch) appendReadBuffer(n int) {
f.rdBuf = f.rdBuf[:len(f.rdBuf)+n]
- f.rdBufMaxLen = max(f.rdBufMaxLen, len(f.rdBuf))
+ f.rdBufMaxLen = maxInt(f.rdBufMaxLen, len(f.rdBuf))
}
// TryReadline implements the logtail.Buffer interface.
@@ -256,14 +277,20 @@ func (f *Filch) Write(b []byte) (n int, err error) {
if len(b) == 0 || b[len(b)-1] != '\n' {
newline = "\n"
f.wrBuf = append(append(f.wrBuf[:0], b...), newline...)
- f.wrBufMaxLen = max(f.wrBufMaxLen, len(f.wrBuf))
+ f.wrBufMaxLen = maxInt(f.wrBufMaxLen, len(f.wrBuf))
b = f.wrBuf
}
if len(b) > f.maxLineSize {
- for line := range bytes.Lines(b) {
+ tooLongLine := false
+ byteLines(b, func(line []byte) bool {
if len(line) > f.maxLineSize {
- return 0, errTooLong
+ tooLongLine = true
+ return false
}
+ return true
+ })
+ if tooLongLine {
+ return 0, errTooLong
}
}
n, err = f.newer.Write(b)
@@ -276,7 +303,7 @@ func (f *Filch) Write(b []byte) (n int, err error) {
func (f *Filch) statAndUpdateBytes() {
if fi, err := f.newer.Stat(); err == nil {
prevSize := f.newlyWrittenBytes + f.newlyFilchedBytes
- filchedBytes := max(0, fi.Size()-prevSize)
+ filchedBytes := maxInt(0, fi.Size()-prevSize)
f.writeBytes.Add(filchedBytes)
f.filchedBytes.Add(filchedBytes)
f.storedBytes.Add(filchedBytes)
@@ -321,7 +348,7 @@ func (f *Filch) rotateLocked() error {
// Update dropped bytes.
if pos, err := f.older.Seek(0, io.SeekCurrent); err == nil {
rdPos := pos - int64(len(f.unreadReadBuffer())) // adjust for data already read into the read buffer
- f.droppedBytes.Add(max(0, fi.Size()-rdPos))
+ f.droppedBytes.Add(maxInt(0, fi.Size()-rdPos))
}
// Truncate the older file and write relative to the start.
@@ -375,7 +402,7 @@ func (f *Filch) rotateLocked() error {
if err != nil {
return err
}
- filchedBytes := max(0, fi.Size()-prevSize)
+ filchedBytes := maxInt(0, fi.Size()-prevSize)
f.writeBytes.Add(filchedBytes)
f.filchedBytes.Add(filchedBytes)
f.storedBytes.Set(fi.Size()) // newer has been truncated, so only older matters
@@ -456,8 +483,8 @@ func New(filePrefix string, opts Options) (f *Filch, err error) {
}
f = new(Filch)
- f.maxLineSize = int(cmp.Or(max(0, opts.MaxLineSize), DefaultMaxLineSize))
- f.maxFileSize = int64(cmp.Or(max(0, opts.MaxFileSize), DefaultMaxFileSize))
+ f.maxLineSize = int(cmp.Or(maxInt(0, opts.MaxLineSize), DefaultMaxLineSize))
+ f.maxFileSize = int64(cmp.Or(maxInt(0, opts.MaxFileSize), DefaultMaxFileSize))
f.maxFileSize /= 2 // since there are two log files that combine to equal MaxFileSize
// Neither, either, or both files may exist and contain logs from
diff --git a/logtail/filch/filch_omit.go b/logtail/filch/filch_omit.go
index c4edc1bcd392f..60b6c5150dfb9 100644
--- a/logtail/filch/filch_omit.go
+++ b/logtail/filch/filch_omit.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build ts_omit_logtail
+//go:build !ts_enable_logtail
package filch
diff --git a/logtail/filch/filch_stub.go b/logtail/filch/filch_stub.go
index 0bb2c306c05dc..e2c8e16c39c1c 100644
--- a/logtail/filch/filch_stub.go
+++ b/logtail/filch/filch_stub.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_logtail && (wasm || plan9 || tamago)
+//go:build ts_enable_logtail && (wasm || plan9 || tamago)
package filch
diff --git a/logtail/filch/filch_test.go b/logtail/filch/filch_test.go
index 2538233cfd84c..9ed9be3b31e01 100644
--- a/logtail/filch/filch_test.go
+++ b/logtail/filch/filch_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,9 +9,9 @@ import (
"bytes"
"encoding/json"
"fmt"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"io"
"math"
- "math/rand/v2"
"os"
"path/filepath"
"runtime"
@@ -19,9 +21,9 @@ import (
"testing"
"time"
- jsonv2 "github.com/go-json-experiment/json"
- "tailscale.com/tstest"
- "tailscale.com/util/must"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/util/must"
)
func init() { alwaysStatForTests = true }
diff --git a/logtail/filch/filch_unix.go b/logtail/filch/filch_unix.go
index 0817e131190bb..7336056c01529 100644
--- a/logtail/filch/filch_unix.go
+++ b/logtail/filch/filch_unix.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_logtail && !windows && !wasm && !plan9 && !tamago
+//go:build ts_enable_logtail && !windows && !wasm && !plan9 && !tamago
package filch
diff --git a/logtail/filch/filch_windows.go b/logtail/filch/filch_windows.go
index 3bffe8662396d..f2dc1134db4d4 100644
--- a/logtail/filch/filch_windows.go
+++ b/logtail/filch/filch_windows.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_logtail && windows
+//go:build ts_enable_logtail && windows
package filch
diff --git a/logtail/logtail.go b/logtail/logtail.go
index a45f1bfe9da8b..d42f7335eb9c0 100644
--- a/logtail/logtail.go
+++ b/logtail/logtail.go
@@ -1,44 +1,44 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_logtail
+//go:build ts_enable_logtail
// Package logtail sends logs to log.tailscale.com.
package logtail
import (
"bytes"
- "cmp"
"context"
"crypto/rand"
"encoding/binary"
"expvar"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ mrand "github.com/metacubex/tailscale/util/go120/randv2"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
- mrand "math/rand/v2"
"net/http"
"os"
"runtime"
- "slices"
"strconv"
"sync"
"sync/atomic"
"time"
- "github.com/creachadair/msync/trigger"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/envknob"
- "tailscale.com/metrics"
- "tailscale.com/net/netmon"
- "tailscale.com/net/sockstats"
- "tailscale.com/tstime"
- tslogger "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/set"
- "tailscale.com/util/truncate"
- "tailscale.com/util/zstdframe"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/metrics"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/sockstats"
+ "github.com/metacubex/tailscale/tstime"
+ tslogger "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/go120/trigger"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/truncate"
+ "github.com/metacubex/tailscale/util/zstdframe"
)
// maxSize is the maximum size that a single log entry can be.
diff --git a/logtail/logtail_omit.go b/logtail/logtail_omit.go
index 98f1c6a0e5d6b..f7c3fb7a2c2c6 100644
--- a/logtail/logtail_omit.go
+++ b/logtail/logtail_omit.go
@@ -1,18 +1,18 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build ts_omit_logtail
+//go:build !ts_enable_logtail
package logtail
import (
"context"
- tslogger "tailscale.com/types/logger"
- "tailscale.com/types/logid"
+ tslogger "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
)
-// Noop implementations of everything when ts_omit_logtail is set.
+// Noop implementations of everything when logtail is not enabled.
type Logger struct{}
diff --git a/logtail/logtail_test.go b/logtail/logtail_test.go
index 8273097c3aebf..c1f6b302973f9 100644
--- a/logtail/logtail_test.go
+++ b/logtail/logtail_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -18,12 +20,12 @@ import (
"testing/synctest"
"time"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/net/memnet"
- "tailscale.com/tstest"
- "tailscale.com/tstime"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/must"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/net/memnet"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/must"
)
// TestMain installs a safety net that refuses non-localhost dials for any
diff --git a/metrics/fds_linux.go b/metrics/fds_linux.go
index b0abf946b7ef6..7c746ba765374 100644
--- a/metrics/fds_linux.go
+++ b/metrics/fds_linux.go
@@ -7,8 +7,8 @@ import (
"io/fs"
"sync"
+ "github.com/metacubex/tailscale/util/dirwalk"
"go4.org/mem"
- "tailscale.com/util/dirwalk"
)
// counter is a reusable counter for counting file descriptors.
diff --git a/metrics/metrics.go b/metrics/metrics.go
index 6540dcc13d66d..78ac35e1623ed 100644
--- a/metrics/metrics.go
+++ b/metrics/metrics.go
@@ -8,11 +8,11 @@ package metrics
import (
"expvar"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
- "slices"
"strings"
- "tailscale.com/syncs"
+ "github.com/metacubex/tailscale/syncs"
)
// Set is a string-to-Var map variable that satisfies the expvar.Var
diff --git a/metrics/metrics_test.go b/metrics/metrics_test.go
index 8478cdedc8de8..838e87e7204f7 100644
--- a/metrics/metrics_test.go
+++ b/metrics/metrics_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,7 +10,7 @@ import (
"runtime"
"testing"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/tstest"
)
func TestLabelMap(t *testing.T) {
diff --git a/metrics/multilabelmap.go b/metrics/multilabelmap.go
index fa31819d9c3f8..698f4a6d85d03 100644
--- a/metrics/multilabelmap.go
+++ b/metrics/multilabelmap.go
@@ -64,7 +64,9 @@ func LabelString(k any) string {
sb.WriteString("{")
first := true
- for ft, fv := range rv.Fields() {
+ for i := 0; i < rv.NumField(); i++ {
+ ft := t.Field(i)
+ fv := rv.Field(i)
if !first {
sb.WriteString(",")
}
diff --git a/metrics/multilabelmap_test.go b/metrics/multilabelmap_test.go
index 0fa730992bc16..85960bba9e62c 100644
--- a/metrics/multilabelmap_test.go
+++ b/metrics/multilabelmap_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/misc/genreadme/genreadme.go b/misc/genreadme/genreadme.go
index 97a8d9e1640cc..7d1b673860159 100644
--- a/misc/genreadme/genreadme.go
+++ b/misc/genreadme/genreadme.go
@@ -26,7 +26,7 @@ import (
"strings"
"github.com/creachadair/taskgroup"
- "tailscale.com/tempfork/pkgdoc"
+ "github.com/metacubex/tailscale/tempfork/pkgdoc"
)
// modulePath is the current module's import path, read from go.mod at startup.
diff --git a/misc/git_hook/git-hook.go b/misc/git_hook/git-hook.go
index 2cf3ff421ccdf..828114f9dda15 100644
--- a/misc/git_hook/git-hook.go
+++ b/misc/git_hook/git-hook.go
@@ -19,7 +19,7 @@ import (
"os"
"strings"
- "tailscale.com/misc/git_hook/githook"
+ "github.com/metacubex/tailscale/misc/git_hook/githook"
)
var pushRemotes = []string{
diff --git a/misc/install-git-hooks.go b/misc/install-git-hooks.go
index 813a456016788..724743ddc0757 100644
--- a/misc/install-git-hooks.go
+++ b/misc/install-git-hooks.go
@@ -10,7 +10,7 @@ package main
import (
"log"
- "tailscale.com/misc/git_hook/githook"
+ "github.com/metacubex/tailscale/misc/git_hook/githook"
)
func main() {
diff --git a/net/ace/ace.go b/net/ace/ace.go
index 9b1264dc0927b..cbc297313d14c 100644
--- a/net/ace/ace.go
+++ b/net/ace/ace.go
@@ -10,11 +10,11 @@ package ace
import (
"bufio"
- "cmp"
"context"
"crypto/tls"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"net"
"net/http"
"net/netip"
diff --git a/net/art/art_test.go b/net/art/art_test.go
index 004f31b8ba3b5..944a7a29aa1bb 100644
--- a/net/art/art_test.go
+++ b/net/art/art_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,7 +9,7 @@ import (
"os"
"testing"
- "tailscale.com/util/cibuild"
+ "github.com/metacubex/tailscale/util/cibuild"
)
func TestMain(m *testing.M) {
diff --git a/net/art/stride_table_test.go b/net/art/stride_table_test.go
index 8279a545e132d..2bd834cf94678 100644
--- a/net/art/stride_table_test.go
+++ b/net/art/stride_table_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/art/table_test.go b/net/art/table_test.go
index 5c35ac7dafd77..43e2bbca8559d 100644
--- a/net/art/table_test.go
+++ b/net/art/table_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/bakedroots/bakedroots.go b/net/bakedroots/bakedroots.go
index 70d947c6b725d..23a924fce6f5b 100644
--- a/net/bakedroots/bakedroots.go
+++ b/net/bakedroots/bakedroots.go
@@ -10,7 +10,7 @@ import (
"fmt"
"sync"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/util/testenv"
)
// Get returns the baked-in roots.
diff --git a/net/bakedroots/bakedroots_test.go b/net/bakedroots/bakedroots_test.go
index 12a656d4edae9..f14a63c97c7c0 100644
--- a/net/bakedroots/bakedroots_test.go
+++ b/net/bakedroots/bakedroots_test.go
@@ -1,10 +1,12 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package bakedroots
import (
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"testing"
)
diff --git a/net/batching/conn.go b/net/batching/conn.go
index 1843a2cfced5a..835f0b7a08282 100644
--- a/net/batching/conn.go
+++ b/net/batching/conn.go
@@ -7,10 +7,10 @@ package batching
import (
"net/netip"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/types/nettype"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
- "tailscale.com/net/packet"
- "tailscale.com/types/nettype"
)
var (
diff --git a/net/batching/conn_default.go b/net/batching/conn_default.go
index 77c4c8b6a8adc..b040c9bde34a2 100644
--- a/net/batching/conn_default.go
+++ b/net/batching/conn_default.go
@@ -6,7 +6,7 @@
package batching
import (
- "tailscale.com/types/nettype"
+ "github.com/metacubex/tailscale/types/nettype"
)
// TryUpgradeToConn is no-op on all platforms except linux.
diff --git a/net/batching/conn_linux.go b/net/batching/conn_linux.go
index ea11f439a88bd..d0e288d456b6f 100644
--- a/net/batching/conn_linux.go
+++ b/net/batching/conn_linux.go
@@ -4,7 +4,6 @@
package batching
import (
- "encoding/binary"
"errors"
"fmt"
"net"
@@ -17,14 +16,14 @@ import (
"time"
"unsafe"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/net/neterror"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/types/nettype"
+ "github.com/metacubex/tailscale/util/clientmetric"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
"golang.org/x/sys/unix"
- "tailscale.com/hostinfo"
- "tailscale.com/net/neterror"
- "tailscale.com/net/packet"
- "tailscale.com/types/nettype"
- "tailscale.com/util/clientmetric"
)
// xnetBatchReaderWriter defines the batching i/o methods of
@@ -349,7 +348,7 @@ func getRXQOverflowsFromControl(control []byte) (uint32, error) {
return 0, err
}
if len(data) >= 4 {
- return binary.NativeEndian.Uint32(data), nil
+ return nativeEndian.Uint32(data), nil
}
return 0, nil
}
@@ -455,7 +454,7 @@ func getGSOSizeFromControl(control []byte) (int, error) {
return 0, err
}
if len(data) >= 2 {
- return int(binary.NativeEndian.Uint16(data)), nil
+ return int(nativeEndian.Uint16(data)), nil
}
return 0, nil
}
@@ -477,7 +476,7 @@ func setGSOSizeInControl(control *[]byte, gsoSize uint16) {
hdr.Level = unix.SOL_UDP
hdr.Type = unix.UDP_SEGMENT
hdr.SetLen(unix.CmsgLen(2))
- binary.NativeEndian.PutUint16((*control)[unix.SizeofCmsghdr:], gsoSize)
+ nativeEndian.PutUint16((*control)[unix.SizeofCmsghdr:], gsoSize)
*control = (*control)[:unix.CmsgSpace(2)]
}
diff --git a/net/batching/conn_linux_test.go b/net/batching/conn_linux_test.go
index fa4eef33c5820..042774532cabb 100644
--- a/net/batching/conn_linux_test.go
+++ b/net/batching/conn_linux_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,10 +14,10 @@ import (
"unsafe"
qt "github.com/frankban/quicktest"
- "github.com/tailscale/wireguard-go/conn"
+ "github.com/metacubex/tailscale-wireguard-go/conn"
+ "github.com/metacubex/tailscale/net/packet"
"golang.org/x/net/ipv6"
"golang.org/x/sys/unix"
- "tailscale.com/net/packet"
)
func Test_linuxBatchingConn_splitCoalescedMessages(t *testing.T) {
diff --git a/net/batching/native_endian.go b/net/batching/native_endian.go
new file mode 100644
index 0000000000000..1467eb104196d
--- /dev/null
+++ b/net/batching/native_endian.go
@@ -0,0 +1,17 @@
+// Copyright (c) Tailscale Inc & contributors
+// SPDX-License-Identifier: BSD-3-Clause
+
+package batching
+
+import (
+ "encoding/binary"
+ "unsafe"
+)
+
+var nativeEndian binary.ByteOrder = func() binary.ByteOrder {
+ var x uint16 = 0x0102
+ if *(*byte)(unsafe.Pointer(&x)) == 0x02 {
+ return binary.LittleEndian
+ }
+ return binary.BigEndian
+}()
diff --git a/net/captivedetection/captivedetection.go b/net/captivedetection/captivedetection.go
index dfd4bbd875608..d5029387c0f46 100644
--- a/net/captivedetection/captivedetection.go
+++ b/net/captivedetection/captivedetection.go
@@ -14,13 +14,12 @@ import (
"strconv"
"strings"
"sync"
- "syscall"
"time"
- "tailscale.com/net/netmon"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
)
// Detector checks whether the system is behind a captive portal.
@@ -30,17 +29,16 @@ type Detector struct {
// httpClient is the HTTP client that is used for captive portal detection. It is configured
// to not follow redirects, have a short timeout and no keep-alive.
httpClient *http.Client
- // currIfIndex is the index of the interface that is currently being used by the httpClient.
- currIfIndex int
- // mu guards currIfIndex.
- mu syncs.Mutex
+ // dialer specifies how captive portal detection dials endpoints. If nil,
+ // detection is skipped instead of falling back to net.DefaultResolver.
+ dialer netx.DialFunc
// logf is the logger used for logging messages. If it is nil, log.Printf is used.
logf logger.Logf
}
// NewDetector creates a new Detector instance for captive portal detection.
-func NewDetector(logf logger.Logf) *Detector {
- d := &Detector{logf: logf}
+func NewDetector(logf logger.Logf, dialer netx.DialFunc) *Detector {
+ d := &Detector{logf: logf, dialer: dialer}
d.httpClient = &http.Client{
// No redirects allowed
CheckRedirect: func(req *http.Request, via []*http.Request) error {
@@ -74,6 +72,10 @@ const Timeout = 3 * time.Second
// This function might take a while to return, as it will attempt to detect a captive portal on all available interfaces
// by performing multiple HTTP requests. It should be called in a separate goroutine if you want to avoid blocking.
func (d *Detector) Detect(ctx context.Context, netMon *netmon.Monitor, derpMap *tailcfg.DERPMap, preferredDERPRegionID int) (found bool) {
+ if d.dialer == nil {
+ d.logf("[v1] DetectCaptivePortal: no dialer configured, returning false")
+ return false
+ }
return d.detectCaptivePortalWithGOOS(ctx, netMon, derpMap, preferredDERPRegionID, runtime.GOOS)
}
@@ -146,7 +148,7 @@ func interfaceNameDoesNotNeedCaptiveDetection(ifName string, goos string) bool {
func (d *Detector) detectOnInterface(ctx context.Context, ifIndex int, endpoints []Endpoint) bool {
defer d.httpClient.CloseIdleConnections()
- use := min(len(endpoints), 5)
+ use := minInt(len(endpoints), 5)
endpoints = endpoints[:use]
d.logf("[v2] %d available captive portal detection endpoints; trying %v", len(endpoints), use)
@@ -218,10 +220,6 @@ func (d *Detector) verifyCaptivePortalEndpoint(ctx context.Context, e Endpoint,
req.Header.Set("X-Tailscale-Challenge", chal)
}
- d.mu.Lock()
- d.currIfIndex = ifIndex
- d.mu.Unlock()
-
// Make the actual request, and check if the response looks like a captive portal or not.
r, err := d.httpClient.Do(req)
if err != nil {
@@ -232,17 +230,12 @@ func (d *Detector) verifyCaptivePortalEndpoint(ctx context.Context, e Endpoint,
}
func (d *Detector) dialContext(ctx context.Context, network, addr string) (net.Conn, error) {
- d.mu.Lock()
- defer d.mu.Unlock()
-
- ifIndex := d.currIfIndex
+ return d.dialer(ctx, network, addr)
+}
- dl := &net.Dialer{
- Timeout: Timeout,
- Control: func(network, address string, c syscall.RawConn) error {
- return setSocketInterfaceIndex(c, ifIndex, d.logf)
- },
+func minInt(a, b int) int {
+ if a < b {
+ return a
}
-
- return dl.DialContext(ctx, network, addr)
+ return b
}
diff --git a/net/captivedetection/captivedetection_test.go b/net/captivedetection/captivedetection_test.go
index 6b09ca0cc9672..df47a4c1281de 100644
--- a/net/captivedetection/captivedetection_test.go
+++ b/net/captivedetection/captivedetection_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,6 +7,7 @@ package captivedetection
import (
"context"
+ "net"
"net/http"
"net/http/httptest"
"net/url"
@@ -15,11 +18,11 @@ import (
"testing"
"time"
- "tailscale.com/derp/derpserver"
- "tailscale.com/net/netmon"
- "tailscale.com/syncs"
- "tailscale.com/tstest/nettest"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/derp/derpserver"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tstest/nettest"
+ "github.com/metacubex/tailscale/util/must"
)
func TestAvailableEndpointsAlwaysAtLeastTwo(t *testing.T) {
@@ -38,7 +41,7 @@ func TestAvailableEndpointsAlwaysAtLeastTwo(t *testing.T) {
}
func TestDetectCaptivePortalReturnsFalse(t *testing.T) {
- d := NewDetector(t.Logf)
+ d := NewDetector(t.Logf, (&net.Dialer{}).DialContext)
found := d.Detect(context.Background(), netmon.NewStatic(), nil, 0)
if found {
t.Errorf("DetectCaptivePortal returned true, expected false.")
@@ -48,7 +51,7 @@ func TestDetectCaptivePortalReturnsFalse(t *testing.T) {
func TestEndpointsAreUpAndReturnExpectedResponse(t *testing.T) {
nettest.SkipIfNoNetwork(t)
- d := NewDetector(t.Logf)
+ d := NewDetector(t.Logf, (&net.Dialer{}).DialContext)
endpoints := availableEndpoints(nil, 0, t.Logf, runtime.GOOS)
t.Logf("testing %d endpoints", len(endpoints))
@@ -90,7 +93,7 @@ func TestEndpointsAreUpAndReturnExpectedResponse(t *testing.T) {
}
func TestCaptivePortalRequest(t *testing.T) {
- d := NewDetector(t.Logf)
+ d := NewDetector(t.Logf, (&net.Dialer{}).DialContext)
now := time.Now()
d.clock = func() time.Time { return now }
@@ -130,7 +133,7 @@ func TestCaptivePortalRequest(t *testing.T) {
}
func TestAgainstDERPHandler(t *testing.T) {
- d := NewDetector(t.Logf)
+ d := NewDetector(t.Logf, (&net.Dialer{}).DialContext)
ctx := t.Context()
diff --git a/net/captivedetection/endpoints.go b/net/captivedetection/endpoints.go
index 5c1d31d0c35a4..f440e01289a28 100644
--- a/net/captivedetection/endpoints.go
+++ b/net/captivedetection/endpoints.go
@@ -4,17 +4,17 @@
package captivedetection
import (
- "cmp"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net/http"
"net/url"
- "slices"
+ "github.com/metacubex/tailscale/net/dnsfallback"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
"go4.org/mem"
- "tailscale.com/net/dnsfallback"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
)
// EndpointProvider is an enum that represents the source of an Endpoint.
diff --git a/net/captivedetection/rawconn.go b/net/captivedetection/rawconn.go
index 3c6f65f84692e..14d08ae2fb5de 100644
--- a/net/captivedetection/rawconn.go
+++ b/net/captivedetection/rawconn.go
@@ -8,7 +8,7 @@ package captivedetection
import (
"syscall"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
// setSocketInterfaceIndex sets the IP_BOUND_IF socket option on the given RawConn.
diff --git a/net/captivedetection/rawconn_apple.go b/net/captivedetection/rawconn_apple.go
index ee8e7c4c3f6b9..cdeb0535b39ea 100644
--- a/net/captivedetection/rawconn_apple.go
+++ b/net/captivedetection/rawconn_apple.go
@@ -8,8 +8,8 @@ package captivedetection
import (
"syscall"
+ "github.com/metacubex/tailscale/types/logger"
"golang.org/x/sys/unix"
- "tailscale.com/types/logger"
)
// setSocketInterfaceIndex sets the IP_BOUND_IF socket option on the given RawConn.
diff --git a/net/connectproxy/connectproxy.go b/net/connectproxy/connectproxy.go
index a63c6acf7b7c8..26b3edf2c71f1 100644
--- a/net/connectproxy/connectproxy.go
+++ b/net/connectproxy/connectproxy.go
@@ -12,8 +12,8 @@ import (
"net/http"
"time"
- "tailscale.com/net/netx"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/types/logger"
)
// Handler is an HTTP CONNECT proxy handler.
diff --git a/net/dns/config.go b/net/dns/config.go
index 0b09fe1a8f609..13d3334d2e94e 100644
--- a/net/dns/config.go
+++ b/net/dns/config.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:generate go run tailscale.com/cmd/viewer --type=Config --clonefunc
+//go:generate go run github.com/metacubex/tailscale/cmd/viewer --type=Config --clonefunc
// Package dns contains code to configure and manage DNS settings.
package dns
@@ -9,19 +9,19 @@ package dns
import (
"bufio"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"reflect"
- "slices"
"sort"
- "tailscale.com/control/controlknobs"
- "tailscale.com/envknob"
- "tailscale.com/net/dns/publicdns"
- "tailscale.com/net/dns/resolver"
- "tailscale.com/net/tsaddr"
- "tailscale.com/types/dnstype"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/net/dns/publicdns"
+ "github.com/metacubex/tailscale/net/dns/resolver"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/set"
)
// Config is a DNS configuration.
diff --git a/net/dns/dbus.go b/net/dns/dbus.go
index f80136196376a..4528eb465b56b 100644
--- a/net/dns/dbus.go
+++ b/net/dns/dbus.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux && !android && !ts_omit_dbus
+//go:build linux && !android && ts_enable_dbus
package dns
diff --git a/net/dns/debian_resolvconf.go b/net/dns/debian_resolvconf.go
index 128b26f2aceca..0301809794d62 100644
--- a/net/dns/debian_resolvconf.go
+++ b/net/dns/debian_resolvconf.go
@@ -14,8 +14,8 @@ import (
"os/exec"
"path/filepath"
- "tailscale.com/atomicfile"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/atomicfile"
+ "github.com/metacubex/tailscale/types/logger"
)
//go:embed resolvconf-workaround.sh
diff --git a/net/dns/direct.go b/net/dns/direct.go
index f6f2fd6019047..8f5d1257ce0d4 100644
--- a/net/dns/direct.go
+++ b/net/dns/direct.go
@@ -11,6 +11,7 @@ import (
"crypto/rand"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"io/fs"
"net/netip"
@@ -18,20 +19,19 @@ import (
"os/exec"
"path/filepath"
"runtime"
- "slices"
"strings"
"sync"
"sync/atomic"
"time"
- "tailscale.com/feature"
- "tailscale.com/health"
- "tailscale.com/net/dns/resolvconffile"
- "tailscale.com/net/tsaddr"
- "tailscale.com/types/logger"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/eventbus"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/dns/resolvconffile"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/version/distro"
)
// writeResolvConf writes DNS configuration in resolv.conf format to the given writer.
@@ -454,7 +454,7 @@ var resolvTrampleWarnable = health.Register(&health.Warnable{
Code: "resolv-conf-overwritten",
Severity: health.SeverityMedium,
Title: "DNS configuration issue",
- Text: health.StaticMessage("System DNS config not ideal. /etc/resolv.conf overwritten. See https://tailscale.com/s/dns-fight"),
+ Text: health.StaticMessage("System DNS config not ideal. /etc/resolv.conf overwritten. See https://github.com/metacubex/tailscale/s/dns-fight"),
})
// checkForFileTrample checks whether /etc/resolv.conf has been trampled
diff --git a/net/dns/direct_linux_test.go b/net/dns/direct_linux_test.go
index c053db178505c..b0643cb9470f4 100644
--- a/net/dns/direct_linux_test.go
+++ b/net/dns/direct_linux_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux
-
package dns
import (
@@ -14,8 +14,8 @@ import (
"testing/synctest"
"time"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
)
func TestDNSTrampleRecovery(t *testing.T) {
@@ -50,7 +50,7 @@ func TestDNSTrampleRecovery(t *testing.T) {
}
const want = `# resolv.conf(5) file generated by tailscale
-# For more info, see https://tailscale.com/s/resolvconf-overwrite
+# For more info, see https://github.com/metacubex/tailscale/s/resolvconf-overwrite
# DO NOT EDIT THIS FILE BY HAND -- CHANGES WILL BE OVERWRITTEN
nameserver 8.8.8.8
diff --git a/net/dns/direct_test.go b/net/dns/direct_test.go
index c96323571c1f9..3029010ede6f5 100644
--- a/net/dns/direct_test.go
+++ b/net/dns/direct_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -16,7 +18,7 @@ import (
"testing"
qt "github.com/frankban/quicktest"
- "tailscale.com/util/dnsname"
+ "github.com/metacubex/tailscale/util/dnsname"
)
func TestDirectManager(t *testing.T) {
@@ -91,7 +93,7 @@ func testDirect(t *testing.T, fs wholeFileFS) {
t.Fatal(err)
}
want := `# resolv.conf(5) file generated by tailscale
-# For more info, see https://tailscale.com/s/resolvconf-overwrite
+# For more info, see https://github.com/metacubex/tailscale/s/resolvconf-overwrite
# DO NOT EDIT THIS FILE BY HAND -- CHANGES WILL BE OVERWRITTEN
nameserver 8.8.8.8
diff --git a/net/dns/direct_unix_test.go b/net/dns/direct_unix_test.go
index 068c5633645a5..36563ed428786 100644
--- a/net/dns/direct_unix_test.go
+++ b/net/dns/direct_unix_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build unix
-
package dns
import (
diff --git a/net/dns/dns_clone.go b/net/dns/dns_clone.go
index 760cd514daa38..168ac2dc463ef 100644
--- a/net/dns/dns_clone.go
+++ b/net/dns/dns_clone.go
@@ -1,16 +1,16 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-// Code generated by tailscale.com/cmd/cloner; DO NOT EDIT.
+// Code generated by github.com/metacubex/tailscale/cmd/cloner; DO NOT EDIT.
package dns
import (
"net/netip"
- "tailscale.com/types/dnstype"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/set"
)
// Clone makes a deep copy of Config.
diff --git a/net/dns/dns_view.go b/net/dns/dns_view.go
index 70cb89dcaf128..9dfac67a1b7c0 100644
--- a/net/dns/dns_view.go
+++ b/net/dns/dns_view.go
@@ -10,15 +10,15 @@ import (
"errors"
"net/netip"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/types/dnstype"
- "tailscale.com/types/views"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/set"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/set"
)
-//go:generate go run tailscale.com/cmd/cloner -clonefunc=true -type=Config
+//go:generate go run github.com/metacubex/tailscale/cmd/cloner -clonefunc=true -type=Config
// View returns a read-only view of Config.
func (p *Config) View() ConfigView {
diff --git a/net/dns/errors_go120.go b/net/dns/errors_go120.go
new file mode 100644
index 0000000000000..ea511c95b5419
--- /dev/null
+++ b/net/dns/errors_go120.go
@@ -0,0 +1,7 @@
+//go:build !go1.21
+
+package dns
+
+import "errors"
+
+var ErrUnsupported = errors.New("unsupported operation")
diff --git a/net/dns/errors_go121.go b/net/dns/errors_go121.go
new file mode 100644
index 0000000000000..e5fa89372cc81
--- /dev/null
+++ b/net/dns/errors_go121.go
@@ -0,0 +1,7 @@
+//go:build go1.21
+
+package dns
+
+import "errors"
+
+var ErrUnsupported = errors.ErrUnsupported
diff --git a/net/dns/ini_test.go b/net/dns/ini_test.go
index 0e5b966a8674f..688369ce72b7f 100644
--- a/net/dns/ini_test.go
+++ b/net/dns/ini_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build windows
-
package dns
import (
diff --git a/net/dns/manager.go b/net/dns/manager.go
index 8daa13cbc6981..32a23805e392c 100644
--- a/net/dns/manager.go
+++ b/net/dns/manager.go
@@ -9,30 +9,30 @@ import (
"encoding/binary"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net"
"net/netip"
"runtime"
- "slices"
"strings"
"sync"
"sync/atomic"
"time"
- "tailscale.com/control/controlknobs"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/health"
- "tailscale.com/net/dns/resolver"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsdial"
- "tailscale.com/syncs"
- "tailscale.com/types/dnstype"
- "tailscale.com/types/logger"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/slicesx"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/dns/resolver"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
var (
diff --git a/net/dns/manager_darwin.go b/net/dns/manager_darwin.go
index 90686b2466a93..afac9c7c132f9 100644
--- a/net/dns/manager_darwin.go
+++ b/net/dns/manager_darwin.go
@@ -4,195 +4,16 @@
package dns
import (
- "bytes"
- "fmt"
- "io/fs"
- "os"
- "strings"
-
- "go4.org/mem"
- "tailscale.com/control/controlknobs"
- "tailscale.com/health"
- "tailscale.com/net/dns/resolvconffile"
- "tailscale.com/net/tsaddr"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/mak"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
-// NewOSConfigurator creates a new OS configurator.
-//
-// The health tracker, bus and the knobs may be nil and are ignored on this platform.
-func NewOSConfigurator(logf logger.Logf, _ *health.Tracker, _ *eventbus.Bus, _ policyclient.Client, _ *controlknobs.Knobs, ifName string) (OSConfigurator, error) {
- return &darwinConfigurator{
- logf: logf,
- ifName: ifName,
- resolverDir: "/etc/resolver",
- resolvConfPath: "/etc/resolv.conf",
- }, nil
-}
-
-// darwinConfigurator is the tailscaled-on-macOS DNS OS configurator that
-// maintains the Split DNS nameserver entries pointing MagicDNS DNS suffixes
-// to 100.100.100.100 using the macOS /etc/resolver/$SUFFIX files.
-type darwinConfigurator struct {
- logf logger.Logf
- ifName string
- resolverDir string // default "/etc/resolver"
- resolvConfPath string // default "/etc/resolv.conf"
-}
-
-func (c *darwinConfigurator) Close() error {
- c.removeResolverFiles(func(domain string) bool { return true })
- return nil
-}
-
-func (c *darwinConfigurator) SupportsSplitDNS() bool {
- return true
-}
-
-func (c *darwinConfigurator) SetDNS(cfg OSConfig) error {
- var buf bytes.Buffer
- buf.WriteString(macResolverFileHeader)
- for _, ip := range cfg.Nameservers {
- buf.WriteString("nameserver ")
- buf.WriteString(ip.String())
- buf.WriteString("\n")
- }
-
- if err := os.MkdirAll(c.resolverDir, 0755); err != nil {
- return err
- }
-
- root, err := os.OpenRoot(c.resolverDir)
- if err != nil {
- return err
- }
- defer root.Close()
-
- var keep map[string]bool
-
- // Add a dummy file to /etc/resolver with a "search ..." directive if we have
- // search suffixes to add.
- if len(cfg.SearchDomains) > 0 {
- const searchFile = "search.tailscale" // fake DNS suffix+TLD to put our search
- mak.Set(&keep, searchFile, true)
- var sbuf bytes.Buffer
- sbuf.WriteString(macResolverFileHeader)
- sbuf.WriteString("search")
- for _, d := range cfg.SearchDomains {
- sbuf.WriteString(" ")
- sbuf.WriteString(string(d.WithoutTrailingDot()))
- }
- sbuf.WriteString("\n")
- if err := root.WriteFile(searchFile, sbuf.Bytes(), 0644); err != nil {
- return err
- }
- }
-
- for _, d := range cfg.MatchDomains {
- fileBase := string(d.WithoutTrailingDot())
- mak.Set(&keep, fileBase, true)
-
- if !isValidResolverFileName(fileBase) {
- c.logf("[unexpected] invalid resolver domain %q with slashes or colons", fileBase)
- return fmt.Errorf("invalid resolver domain %q: must not contain slashes or colons", fileBase)
- }
-
- if err := root.WriteFile(fileBase, buf.Bytes(), 0644); err != nil {
- return err
- }
- }
- return c.removeResolverFiles(func(domain string) bool { return !keep[domain] })
-}
-
-func isValidResolverFileName(name string) bool {
- // Verify that the filename doesn't contain any characters that
- // might cause issues when used as a filename; os.Root is a
- // defense against path traversal, but prefer a nice error here
- // if we can. These aren't valid for domain names anyway.
- if strings.Contains(name, "/") || strings.Contains(name, "\\") {
- return false
- }
-
- if strings.Contains(name, ":") {
- return false
- }
- return true
-}
-
-// GetBaseConfig returns the current OS DNS configuration, extracting it from /etc/resolv.conf.
-// We should really be using the SystemConfiguration framework to get this information, as this
-// is not a stable public API, and is provided mostly as a compatibility effort with Unix
-// tools. Apple might break this in the future. But honestly, parsing the output of `scutil --dns`
-// is *even more* likely to break in the future.
-func (c *darwinConfigurator) GetBaseConfig() (OSConfig, error) {
- cfg := OSConfig{}
-
- resolvConf, err := resolvconffile.ParseFile(c.resolvConfPath)
- if err != nil {
- c.logf("failed to parse %s: %v", c.resolvConfPath, err)
- return cfg, ErrGetBaseConfigNotSupported
- }
-
- for _, ns := range resolvConf.Nameservers {
- if ns == tsaddr.TailscaleServiceIP() || ns == tsaddr.TailscaleServiceIPv6() {
- // If we find Quad100 in /etc/resolv.conf, we should ignore it
- c.logf("ignoring 100.100.100.100 resolver IP found in /etc/resolv.conf")
- continue
- }
- cfg.Nameservers = append(cfg.Nameservers, ns)
- }
- cfg.SearchDomains = resolvConf.SearchDomains
-
- if len(cfg.Nameservers) == 0 {
- // Log a warning in case we couldn't find any nameservers in /etc/resolv.conf.
- c.logf("no nameservers found in %s, DNS resolution might fail", c.resolvConfPath)
- }
-
- return cfg, nil
-}
-
-const macResolverFileHeader = "# Added by tailscaled\n"
-
-// removeResolverFiles deletes all files in /etc/resolver for which the shouldDelete
-// func returns true.
-func (c *darwinConfigurator) removeResolverFiles(shouldDelete func(domain string) bool) error {
- root, err := os.OpenRoot(c.resolverDir)
- if os.IsNotExist(err) {
- return nil
- }
- if err != nil {
- return err
- }
- defer root.Close()
-
- dents, err := fs.ReadDir(root.FS(), ".")
- if err != nil {
- return err
- }
- for _, de := range dents {
- if !de.Type().IsRegular() {
- continue
- }
- name := de.Name()
- if !shouldDelete(name) {
- continue
- }
- contents, err := root.ReadFile(name)
- if err != nil {
- if os.IsNotExist(err) { // race?
- continue
- }
- return err
- }
- if !mem.HasPrefix(mem.B(contents), mem.S(macResolverFileHeader)) {
- continue
- }
- if err := root.Remove(name); err != nil {
- return err
- }
- }
- return nil
+// NewOSConfigurator creates a no-op OS configurator on macOS for embedded use.
+// Mihomo owns system DNS configuration and consumes Tailscale DNS through its
+// own DNS transport instead of letting tsnet write /etc/resolver files.
+func NewOSConfigurator(logger.Logf, *health.Tracker, *eventbus.Bus, policyclient.Client, *controlknobs.Knobs, string) (OSConfigurator, error) {
+ return NewNoopManager()
}
diff --git a/net/dns/manager_darwin_test.go b/net/dns/manager_darwin_test.go
index 8596f9575bc64..683689bb7811f 100644
--- a/net/dns/manager_darwin_test.go
+++ b/net/dns/manager_darwin_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,15 +7,15 @@ package dns
import (
"errors"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"os"
"path/filepath"
- "slices"
"testing"
- "tailscale.com/types/logger"
- "tailscale.com/util/dnsname"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/dnsname"
)
func newTestConfigurator(t *testing.T) *darwinConfigurator {
diff --git a/net/dns/manager_default.go b/net/dns/manager_default.go
index b514a741799a4..2eded8588b0ce 100644
--- a/net/dns/manager_default.go
+++ b/net/dns/manager_default.go
@@ -6,11 +6,11 @@
package dns
import (
- "tailscale.com/control/controlknobs"
- "tailscale.com/health"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
// NewOSConfigurator creates a new OS configurator.
diff --git a/net/dns/manager_freebsd.go b/net/dns/manager_freebsd.go
index deea462ed049d..4427b4dfd4328 100644
--- a/net/dns/manager_freebsd.go
+++ b/net/dns/manager_freebsd.go
@@ -7,11 +7,11 @@ import (
"fmt"
"os"
- "tailscale.com/control/controlknobs"
- "tailscale.com/health"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
// NewOSConfigurator creates a new OS configurator.
diff --git a/net/dns/manager_linux.go b/net/dns/manager_linux.go
index 392b64ba989ca..e62bc63354777 100644
--- a/net/dns/manager_linux.go
+++ b/net/dns/manager_linux.go
@@ -14,16 +14,16 @@ import (
"sync"
"time"
- "tailscale.com/control/controlknobs"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/health"
- "tailscale.com/net/netaddr"
- "tailscale.com/types/logger"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/syspolicy/policyclient"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/version/distro"
)
type kv struct {
@@ -76,17 +76,17 @@ func NewOSConfigurator(logf logger.Logf, health *health.Tracker, bus *eventbus.B
if f, ok := optDBusPing.GetOk(); ok {
env.dbusPing = f
} else {
- env.dbusPing = func(_, _ string) error { return errors.ErrUnsupported }
+ env.dbusPing = func(_, _ string) error { return ErrUnsupported }
}
if f, ok := optDBusReadString.GetOk(); ok {
env.dbusReadString = f
} else {
- env.dbusReadString = func(_, _, _, _ string) (string, error) { return "", errors.ErrUnsupported }
+ env.dbusReadString = func(_, _, _, _ string) (string, error) { return "", ErrUnsupported }
}
if f, ok := optNMIsUsingResolved.GetOk(); ok {
env.nmIsUsingResolved = f
} else {
- env.nmIsUsingResolved = func() error { return errors.ErrUnsupported }
+ env.nmIsUsingResolved = func() error { return ErrUnsupported }
}
env.nmVersionBetween, _ = optNMVersionBetween.GetOk() // GetOk to not panic if nil; unused if optNMIsUsingResolved returns an error
mode, err := dnsMode(logf, health, env)
@@ -327,7 +327,7 @@ func dnsMode(logf logger.Logf, health *health.Tracker, env newOSConfigEnv) (ret
return "direct", nil
}
- health.SetDNSManagerHealth(errors.New("systemd-resolved and NetworkManager are wired together incorrectly; MagicDNS will probably not work. For more info, see https://tailscale.com/s/resolved-nm"))
+ health.SetDNSManagerHealth(errors.New("systemd-resolved and NetworkManager are wired together incorrectly; MagicDNS will probably not work. For more info, see https://github.com/metacubex/tailscale/s/resolved-nm"))
dbg("nm-safe", "no")
return "systemd-resolved", nil
default:
@@ -380,7 +380,7 @@ func isLibnssResolveUsed(env newOSConfigEnv) error {
if err != nil {
return fmt.Errorf("reading /etc/resolv.conf: %w", err)
}
- for line := range strings.SplitSeq(string(bs), "\n") {
+ for _, line := range strings.Split(string(bs), "\n") {
fields := strings.Fields(line)
if len(fields) < 2 || fields[0] != "hosts:" {
continue
diff --git a/net/dns/manager_linux_test.go b/net/dns/manager_linux_test.go
index c3c99307ad62d..9002e06c4e852 100644
--- a/net/dns/manager_linux_test.go
+++ b/net/dns/manager_linux_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,8 +12,8 @@ import (
"strings"
"testing"
- "tailscale.com/tstest"
- "tailscale.com/util/cmpver"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/util/cmpver"
)
func TestLinuxDNSMode(t *testing.T) {
diff --git a/net/dns/manager_openbsd.go b/net/dns/manager_openbsd.go
index fe4641bbd1ee1..efd6bd4423dcf 100644
--- a/net/dns/manager_openbsd.go
+++ b/net/dns/manager_openbsd.go
@@ -8,11 +8,11 @@ import (
"fmt"
"os"
- "tailscale.com/control/controlknobs"
- "tailscale.com/health"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
type kv struct {
diff --git a/net/dns/manager_plan9.go b/net/dns/manager_plan9.go
index d7619f414d45f..39d250b6b292f 100644
--- a/net/dns/manager_plan9.go
+++ b/net/dns/manager_plan9.go
@@ -17,12 +17,12 @@ import (
"strings"
"unicode"
- "tailscale.com/control/controlknobs"
- "tailscale.com/health"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/set"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
func NewOSConfigurator(logf logger.Logf, ht *health.Tracker, _ *eventbus.Bus, _ policyclient.Client, knobs *controlknobs.Knobs, interfaceName string) (OSConfigurator, error) {
diff --git a/net/dns/manager_plan9_test.go b/net/dns/manager_plan9_test.go
index cc09b360e0c09..dd4fe50e686dc 100644
--- a/net/dns/manager_plan9_test.go
+++ b/net/dns/manager_plan9_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build plan9
-
package dns
import "testing"
diff --git a/net/dns/manager_solaris.go b/net/dns/manager_solaris.go
index 3324e2b07af23..932942e241ec8 100644
--- a/net/dns/manager_solaris.go
+++ b/net/dns/manager_solaris.go
@@ -4,11 +4,11 @@
package dns
import (
- "tailscale.com/control/controlknobs"
- "tailscale.com/health"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
func NewOSConfigurator(logf logger.Logf, health *health.Tracker, bus *eventbus.Bus, _ policyclient.Client, _ *controlknobs.Knobs, iface string) (OSConfigurator, error) {
diff --git a/net/dns/manager_tcp_test.go b/net/dns/manager_tcp_test.go
index 67d6d15cd42ed..4c9c390508d53 100644
--- a/net/dns/manager_tcp_test.go
+++ b/net/dns/manager_tcp_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -14,14 +16,14 @@ import (
"time"
"github.com/google/go-cmp/cmp"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
dns "golang.org/x/net/dns/dnsmessage"
- "tailscale.com/control/controlknobs"
- "tailscale.com/health"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsdial"
- "tailscale.com/tstest"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/eventbus/eventbustest"
)
func mkDNSRequest(domain dnsname.FQDN, tp dns.Type, modify func(*dns.Builder)) []byte {
diff --git a/net/dns/manager_test.go b/net/dns/manager_test.go
index 8a67aca5cd545..08abeec68fb4a 100644
--- a/net/dns/manager_test.go
+++ b/net/dns/manager_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,13 +9,13 @@ import (
"bytes"
"context"
"errors"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net/http"
"net/http/httptest"
"net/netip"
"reflect"
"runtime"
- "slices"
"strings"
"sync"
"testing"
@@ -22,19 +24,19 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/dns/publicdns"
+ "github.com/metacubex/tailscale/net/dns/resolver"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/httpm"
dns "golang.org/x/net/dns/dnsmessage"
- "tailscale.com/control/controlknobs"
- "tailscale.com/health"
- "tailscale.com/net/dns/publicdns"
- "tailscale.com/net/dns/resolver"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsaddr"
- "tailscale.com/net/tsdial"
- "tailscale.com/tstest"
- "tailscale.com/types/dnstype"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/httpm"
)
type fakeOSConfigurator struct {
diff --git a/net/dns/manager_windows.go b/net/dns/manager_windows.go
index 1e412b2d20617..db5f9328a6cee 100644
--- a/net/dns/manager_windows.go
+++ b/net/dns/manager_windows.go
@@ -8,33 +8,33 @@ import (
"bytes"
"errors"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"os"
"os/exec"
"path/filepath"
- "slices"
"sort"
"strings"
"syscall"
"time"
+ "github.com/metacubex/tailscale/atomicfile"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/util/syspolicy/ptype"
+ "github.com/metacubex/tailscale/util/winipcfg"
+ "github.com/metacubex/tailscale/util/winutil"
+ "github.com/metacubex/tailscale/util/winutil/winenv"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
- "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
- "tailscale.com/atomicfile"
- "tailscale.com/control/controlknobs"
- "tailscale.com/envknob"
- "tailscale.com/health"
- "tailscale.com/syncs"
- "tailscale.com/types/logger"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/policyclient"
- "tailscale.com/util/syspolicy/ptype"
- "tailscale.com/util/winutil"
- "tailscale.com/util/winutil/winenv"
)
const (
@@ -262,7 +262,7 @@ func (m *windowsManager) setHosts(hosts []*HostEntry) error {
// This can fail spuriously with an access denied error, so retry it a
// few times.
- for range 5 {
+ for i := 0; i < 5; i++ {
if err = atomicfile.WriteFile(hostsFile, outB, fileMode); err == nil {
return nil
}
diff --git a/net/dns/manager_windows_test.go b/net/dns/manager_windows_test.go
index d1c65ed2bffd6..2ce82f724b63d 100644
--- a/net/dns/manager_windows_test.go
+++ b/net/dns/manager_windows_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -13,13 +15,13 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/util/winutil"
+ "github.com/metacubex/tailscale/util/winutil/gp"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
- "tailscale.com/types/logger"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/syspolicy/policyclient"
- "tailscale.com/util/winutil"
- "tailscale.com/util/winutil/gp"
)
const testGPRuleID = "{7B1B6151-84E6-41A3-8967-62F7F7B45687}"
diff --git a/net/dns/native_endian.go b/net/dns/native_endian.go
new file mode 100644
index 0000000000000..a7070d0ae43eb
--- /dev/null
+++ b/net/dns/native_endian.go
@@ -0,0 +1,17 @@
+// Copyright (c) Tailscale Inc & contributors
+// SPDX-License-Identifier: BSD-3-Clause
+
+package dns
+
+import (
+ "encoding/binary"
+ "unsafe"
+)
+
+var nativeEndian binary.ByteOrder = func() binary.ByteOrder {
+ var x uint16 = 0x0102
+ if *(*byte)(unsafe.Pointer(&x)) == 0x02 {
+ return binary.LittleEndian
+ }
+ return binary.BigEndian
+}()
diff --git a/net/dns/nm.go b/net/dns/nm.go
index 99f032431ce57..40c370d6234a2 100644
--- a/net/dns/nm.go
+++ b/net/dns/nm.go
@@ -1,13 +1,12 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux && !android && !ts_omit_networkmanager
+//go:build linux && !android && ts_enable_networkmanager
package dns
import (
"context"
- "encoding/binary"
"errors"
"fmt"
"net"
@@ -16,9 +15,9 @@ import (
"time"
"github.com/godbus/dbus/v5"
- "tailscale.com/net/tsaddr"
- "tailscale.com/util/cmpver"
- "tailscale.com/util/dnsname"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/util/cmpver"
+ "github.com/metacubex/tailscale/util/dnsname"
)
const (
@@ -138,7 +137,7 @@ func (m *nmManager) trySet(ctx context.Context, config OSConfig) error {
for _, ip := range config.Nameservers {
b := ip.As16()
if ip.Is4() {
- dnsv4 = append(dnsv4, binary.NativeEndian.Uint32(b[12:]))
+ dnsv4 = append(dnsv4, nativeEndian.Uint32(b[12:]))
} else {
dnsv6 = append(dnsv6, b[:])
}
diff --git a/net/dns/nrpt_windows.go b/net/dns/nrpt_windows.go
index 6d9cf71b7a427..4072b6722665b 100644
--- a/net/dns/nrpt_windows.go
+++ b/net/dns/nrpt_windows.go
@@ -9,13 +9,13 @@ import (
"sync"
"sync/atomic"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/winutil"
+ "github.com/metacubex/tailscale/util/winutil/gp"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
- "tailscale.com/types/logger"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/set"
- "tailscale.com/util/winutil"
- "tailscale.com/util/winutil/gp"
)
const (
diff --git a/net/dns/openresolv.go b/net/dns/openresolv.go
index 2a4ed174e3f09..5af66080eb8e6 100644
--- a/net/dns/openresolv.go
+++ b/net/dns/openresolv.go
@@ -11,7 +11,7 @@ import (
"os/exec"
"strings"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
// openresolvManager manages DNS configuration using the openresolv
@@ -82,7 +82,7 @@ func (m openresolvManager) GetBaseConfig() (OSConfig, error) {
// Remove the "tailscale" snippet from the list.
args := []string{"-l"}
- for f := range strings.SplitSeq(strings.TrimSpace(string(bs)), " ") {
+ for _, f := range strings.Split(strings.TrimSpace(string(bs)), " ") {
if f == "tailscale" {
continue
}
diff --git a/net/dns/osconfig.go b/net/dns/osconfig.go
index f871335ade38c..1f3098313193c 100644
--- a/net/dns/osconfig.go
+++ b/net/dns/osconfig.go
@@ -7,13 +7,13 @@ import (
"bufio"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
"strings"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/types/logger"
- "tailscale.com/util/dnsname"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/dnsname"
)
// An OSConfigurator applies DNS settings to the operating system.
diff --git a/net/dns/osconfig_test.go b/net/dns/osconfig_test.go
index 93b13c57d482b..634b6c5f0181a 100644
--- a/net/dns/osconfig_test.go
+++ b/net/dns/osconfig_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,8 +11,8 @@ import (
"reflect"
"testing"
- "tailscale.com/tstest"
- "tailscale.com/util/dnsname"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/util/dnsname"
)
func TestOSConfigPrintable(t *testing.T) {
diff --git a/net/dns/publicdns/publicdns.go b/net/dns/publicdns/publicdns.go
index 3666bd77847c9..2b78f0c5141aa 100644
--- a/net/dns/publicdns/publicdns.go
+++ b/net/dns/publicdns/publicdns.go
@@ -10,17 +10,17 @@ import (
"encoding/binary"
"encoding/hex"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
"math/big"
"net/netip"
- "slices"
"sort"
"strconv"
"strings"
"sync"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/util/testenv"
)
// dohOfIP maps from public DNS IPs to their DoH base URL.
diff --git a/net/dns/publicdns/publicdns_test.go b/net/dns/publicdns/publicdns_test.go
index 4f494930b21e9..a6077a11b157c 100644
--- a/net/dns/publicdns/publicdns_test.go
+++ b/net/dns/publicdns/publicdns_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/dns/resolvconffile/resolvconffile.go b/net/dns/resolvconffile/resolvconffile.go
index 7a3b90474b5d0..c63015be3fd7f 100644
--- a/net/dns/resolvconffile/resolvconffile.go
+++ b/net/dns/resolvconffile/resolvconffile.go
@@ -19,7 +19,7 @@ import (
"os"
"strings"
- "tailscale.com/util/dnsname"
+ "github.com/metacubex/tailscale/util/dnsname"
)
// Path is the canonical location of resolv.conf.
@@ -40,7 +40,7 @@ type Config struct {
func (c *Config) Write(w io.Writer) error {
buf := new(bytes.Buffer)
io.WriteString(buf, "# resolv.conf(5) file generated by tailscale\n")
- io.WriteString(buf, "# For more info, see https://tailscale.com/s/resolvconf-overwrite\n")
+ io.WriteString(buf, "# For more info, see https://github.com/metacubex/tailscale/s/resolvconf-overwrite\n")
io.WriteString(buf, "# DO NOT EDIT THIS FILE BY HAND -- CHANGES WILL BE OVERWRITTEN\n\n")
for _, ns := range c.Nameservers {
io.WriteString(buf, "nameserver ")
diff --git a/net/dns/resolvconffile/resolvconffile_test.go b/net/dns/resolvconffile/resolvconffile_test.go
index 21d9e493d56df..c6fa9f3565e7f 100644
--- a/net/dns/resolvconffile/resolvconffile_test.go
+++ b/net/dns/resolvconffile/resolvconffile_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,7 +11,7 @@ import (
"strings"
"testing"
- "tailscale.com/util/dnsname"
+ "github.com/metacubex/tailscale/util/dnsname"
)
func TestParse(t *testing.T) {
diff --git a/net/dns/resolvd.go b/net/dns/resolvd.go
index 56fedfef94daf..ff297488a9bcb 100644
--- a/net/dns/resolvd.go
+++ b/net/dns/resolvd.go
@@ -12,8 +12,8 @@ import (
"regexp"
"strings"
- "tailscale.com/net/dns/resolvconffile"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/net/dns/resolvconffile"
+ "github.com/metacubex/tailscale/types/logger"
)
func newResolvdManager(logf logger.Logf, interfaceName string) (*resolvdManager, error) {
diff --git a/net/dns/resolved.go b/net/dns/resolved.go
index 754570fdc1779..30aa45711733d 100644
--- a/net/dns/resolved.go
+++ b/net/dns/resolved.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux && !android && !ts_omit_resolved
+//go:build linux && !android && ts_enable_resolved
package dns
@@ -13,11 +13,11 @@ import (
"time"
"github.com/godbus/dbus/v5"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/backoff"
+ "github.com/metacubex/tailscale/util/dnsname"
"golang.org/x/sys/unix"
- "tailscale.com/health"
- "tailscale.com/types/logger"
- "tailscale.com/util/backoff"
- "tailscale.com/util/dnsname"
)
// DBus entities we talk to.
diff --git a/net/dns/resolver/debug.go b/net/dns/resolver/debug.go
index 8d700ce54a143..c0a2bce723f57 100644
--- a/net/dns/resolver/debug.go
+++ b/net/dns/resolver/debug.go
@@ -11,9 +11,9 @@ import (
"sync/atomic"
"time"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/health"
- "tailscale.com/syncs"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/syncs"
)
func init() {
@@ -71,7 +71,7 @@ func (fl *fwdLog) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "DNS forwards
")
now := time.Now()
- for i := range len(fl.ent) {
+ for i := 0; i < len(fl.ent); i++ {
ent := fl.ent[(i+fl.pos)%len(fl.ent)]
if ent.Domain == "" {
continue
diff --git a/net/dns/resolver/doh_test.go b/net/dns/resolver/doh_test.go
index b7045c3211e6b..5d9a38f65aea5 100644
--- a/net/dns/resolver/doh_test.go
+++ b/net/dns/resolver/doh_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,8 +11,8 @@ import (
"net/http"
"testing"
+ "github.com/metacubex/tailscale/net/dns/publicdns"
"golang.org/x/net/dns/dnsmessage"
- "tailscale.com/net/dns/publicdns"
)
var testDoH = flag.Bool("test-doh", false, "do real DoH tests against the network")
diff --git a/net/dns/resolver/forwarder.go b/net/dns/resolver/forwarder.go
index 3f586b60f381a..a554c5185d64d 100644
--- a/net/dns/resolver/forwarder.go
+++ b/net/dns/resolver/forwarder.go
@@ -12,8 +12,8 @@ import (
"encoding/binary"
"errors"
"fmt"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"io"
- "maps"
"net"
"net/http"
"net/netip"
@@ -25,29 +25,29 @@ import (
"sync/atomic"
"time"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/dns/publicdns"
+ "github.com/metacubex/tailscale/net/dnscache"
+ "github.com/metacubex/tailscale/net/neterror"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/net/sockstats"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/nettype"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/cloudenv"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/race"
+ "github.com/metacubex/tailscale/version"
dns "golang.org/x/net/dns/dnsmessage"
- "tailscale.com/control/controlknobs"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/health"
- "tailscale.com/net/dns/publicdns"
- "tailscale.com/net/dnscache"
- "tailscale.com/net/neterror"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netx"
- "tailscale.com/net/sockstats"
- "tailscale.com/net/tsdial"
- "tailscale.com/syncs"
- "tailscale.com/types/dnstype"
- "tailscale.com/types/logger"
- "tailscale.com/types/nettype"
- "tailscale.com/types/views"
- "tailscale.com/util/cloudenv"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/mak"
- "tailscale.com/util/race"
- "tailscale.com/version"
)
// headerBytes is the number of bytes in a DNS message header.
@@ -539,7 +539,7 @@ func (f *forwarder) getKnownDoHClientForProvider(urlBase string) (c *http.Client
})
tlsConfig := &tls.Config{
// Enforce TLS 1.3, as all of our supported DNS-over-HTTPS servers are compatible with it
- // (see tailscale.com/net/dns/publicdns/publicdns.go).
+ // (see github.com/metacubex/tailscale/net/dns/publicdns/publicdns.go).
MinVersion: tls.VersionTLS13,
}
c = &http.Client{
@@ -743,7 +743,8 @@ func (f *forwarder) send(ctx context.Context, fq *forwardQuery, rr resolverAndDe
}
// If we got a truncated UDP response, return that instead of an error.
- if trErr, ok := errors.AsType[truncatedResponseError](err); ok {
+ var trErr truncatedResponseError
+ if ok := errors.As(err, &trErr); ok {
return trErr.res, nil
}
return nil, err
@@ -1295,7 +1296,8 @@ func (f *forwarder) forwardWithDestChan(ctx context.Context, query packet, respo
// available; otherwise synthesize a SERVFAIL response. Note the
// rcode guard: firstErr may be a REFUSED rcodeResponseError if it
// arrived before the SERVFAIL that set sawNonRefused.
- if rcodeErr, ok := errors.AsType[rcodeResponseError](firstErr); ok && rcodeErr.rcode == dns.RCodeServerFailure {
+ var rcodeErr rcodeResponseError
+ if ok := errors.As(firstErr, &rcodeErr); ok && rcodeErr.rcode == dns.RCodeServerFailure {
res = packet{rcodeErr.res, query.family, query.addr}
} else {
r, err := servfailResponse(query)
@@ -1308,7 +1310,8 @@ func (f *forwarder) forwardWithDestChan(ctx context.Context, query packet, respo
} else {
// !sawNonRefused means every error was an rcodeResponseError with rcode REFUSED,
// so firstErr is guaranteed to wrap one.
- rcodeErr, ok := errors.AsType[rcodeResponseError](firstErr)
+ var rcodeErr rcodeResponseError
+ ok := errors.As(firstErr, &rcodeErr)
if !ok {
f.logf("unexpected: all errors were REFUSED but firstErr is not rcodeResponseError: %v", firstErr)
return firstErr
diff --git a/net/dns/resolver/forwarder_test.go b/net/dns/resolver/forwarder_test.go
index ebe4041a69820..99951d6cc8c81 100644
--- a/net/dns/resolver/forwarder_test.go
+++ b/net/dns/resolver/forwarder_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,26 +11,26 @@ import (
"encoding/binary"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net"
"net/netip"
"reflect"
- "slices"
"strings"
"sync"
"sync/atomic"
"testing"
"time"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
dns "golang.org/x/net/dns/dnsmessage"
- "tailscale.com/control/controlknobs"
- "tailscale.com/health"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsdial"
- "tailscale.com/tstest"
- "tailscale.com/types/dnstype"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/eventbus/eventbustest"
)
func (rr resolverAndDelay) String() string {
diff --git a/net/dns/resolver/macios_ext.go b/net/dns/resolver/macios_ext.go
index c9b6626523d84..6f1006b467491 100644
--- a/net/dns/resolver/macios_ext.go
+++ b/net/dns/resolver/macios_ext.go
@@ -9,8 +9,8 @@ import (
"errors"
"net"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netns"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netns"
)
func init() {
diff --git a/net/dns/resolver/tsdns.go b/net/dns/resolver/tsdns.go
index 4b2db5705ea46..6d5c6b8524d11 100644
--- a/net/dns/resolver/tsdns.go
+++ b/net/dns/resolver/tsdns.go
@@ -11,35 +11,35 @@ import (
"encoding/hex"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net"
"net/netip"
"os"
"runtime"
- "slices"
"strconv"
"strings"
"sync"
"time"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/dns/resolvconffile"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/cloudenv"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/set"
dns "golang.org/x/net/dns/dnsmessage"
- "tailscale.com/control/controlknobs"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/health"
- "tailscale.com/net/dns/resolvconffile"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsaddr"
- "tailscale.com/net/tsdial"
- "tailscale.com/syncs"
- "tailscale.com/types/dnstype"
- "tailscale.com/types/logger"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/cloudenv"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/set"
)
const dnsSymbolicFQDN = "magicdns.localhost-tailscale-daemon."
diff --git a/net/dns/resolver/tsdns_server_test.go b/net/dns/resolver/tsdns_server_test.go
index 9e18918b9d6e4..0a91cfb7e3316 100644
--- a/net/dns/resolver/tsdns_server_test.go
+++ b/net/dns/resolver/tsdns_server_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/dns/resolver/tsdns_test.go b/net/dns/resolver/tsdns_test.go
index 381ceedb4e194..4cf947ba6e6a5 100644
--- a/net/dns/resolver/tsdns_test.go
+++ b/net/dns/resolver/tsdns_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -21,18 +23,18 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/set"
miekdns "github.com/miekg/dns"
dns "golang.org/x/net/dns/dnsmessage"
- "tailscale.com/health"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsdial"
- "tailscale.com/tstest"
- "tailscale.com/types/dnstype"
- "tailscale.com/types/logger"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/set"
)
var (
diff --git a/net/dns/utf_test.go b/net/dns/utf_test.go
index 7ae5a6854d34c..4e03829267da2 100644
--- a/net/dns/utf_test.go
+++ b/net/dns/utf_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/dns/wsl_windows.go b/net/dns/wsl_windows.go
index b0e62170b2e04..ae09770aadacd 100644
--- a/net/dns/wsl_windows.go
+++ b/net/dns/wsl_windows.go
@@ -15,10 +15,10 @@ import (
"syscall"
"time"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/winutil"
"golang.org/x/sys/windows"
- "tailscale.com/health"
- "tailscale.com/types/logger"
- "tailscale.com/util/winutil"
)
// wslDistros reports the names of the installed WSL2 linux distributions.
@@ -174,7 +174,8 @@ func (fs wslFS) Truncate(name string) error { return fs.WriteFile(name, nil, 064
func (fs wslFS) ReadFile(name string) ([]byte, error) {
b, err := wslCombinedOutput(fs.cmd("cat", "--", name))
- if ee, ok := errors.AsType[*exec.ExitError](err); ok && ee.ExitCode() == 1 {
+ var ee *exec.ExitError
+ if ok := errors.As(err, &ee); ok && ee.ExitCode() == 1 {
return nil, os.ErrNotExist
}
return b, err
diff --git a/net/dnscache/dnscache.go b/net/dnscache/dnscache.go
index 8300917248773..19ddfe8956b99 100644
--- a/net/dnscache/dnscache.go
+++ b/net/dnscache/dnscache.go
@@ -18,20 +18,29 @@ import (
"sync/atomic"
"time"
- "tailscale.com/envknob"
- "tailscale.com/net/netx"
- "tailscale.com/syncs"
- "tailscale.com/types/logger"
- "tailscale.com/util/cloudenv"
- "tailscale.com/util/singleflight"
- "tailscale.com/util/slicesx"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/singleflight"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/util/testenv"
)
var zaddr netip.Addr
+var defaultForwardResolver = &net.Resolver{
+ PreferGo: preferGoResolver(),
+ Dial: defaultResolverDial,
+}
+
+func defaultResolverDial(ctx context.Context, network, address string) (net.Conn, error) {
+ var d net.Dialer
+ return d.DialContext(ctx, network, "223.5.5.5:53")
+}
+
var single = &Resolver{
- Forward: &net.Resolver{PreferGo: preferGoResolver()},
+ Forward: defaultForwardResolver,
}
func preferGoResolver() bool {
@@ -73,6 +82,8 @@ type Resolver struct {
// to use if Forward returns an error or no results.
LookupIPFallback func(ctx context.Context, host string) ([]netip.Addr, error)
+ LookupHook LookupHookFunc
+
// TTL is how long to keep entries cached
//
// If zero, a default (currently 10 minutes) is used.
@@ -119,7 +130,7 @@ func (r *Resolver) fwd() *net.Resolver {
if r.Forward != nil {
return r.Forward
}
- return net.DefaultResolver
+ return defaultForwardResolver
}
// dlogf logs a debug message if debug logging is enabled either globally via
@@ -136,26 +147,6 @@ func (r *Resolver) dlogf(format string, args ...any) {
}
}
-// cloudHostResolver returns a Resolver for the current cloud hosting environment.
-// It currently only supports Google Cloud.
-func (r *Resolver) cloudHostResolver() (v *net.Resolver, ok bool) {
- switch runtime.GOOS {
- case "android", "ios", "darwin":
- return nil, false
- }
- ip := cloudenv.Get().ResolverIP()
- if ip == "" {
- return nil, false
- }
- return &net.Resolver{
- PreferGo: true,
- Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
- var d net.Dialer
- return d.DialContext(ctx, network, net.JoinHostPort(ip, "53"))
- },
- }, true
-}
-
func (r *Resolver) ttl() time.Duration {
if r.TTL > 0 {
return r.TTL
@@ -297,16 +288,12 @@ func (r *Resolver) lookupIP(ctx context.Context, host string) (ip, ip6 netip.Add
var ips []netip.Addr
if r.LookupIPForTest != nil && testenv.InTest() {
ips, err = r.LookupIPForTest(ctx, host)
+ } else if r.LookupHook != nil {
+ ips, err = r.LookupHook(lookupCtx, host)
} else {
ips, err = r.fwd().LookupNetIP(lookupCtx, "ip", host)
}
- if err != nil || len(ips) == 0 {
- if resolver, ok := r.cloudHostResolver(); ok {
- r.dlogf("resolving %q via cloud resolver", host)
- ips, err = resolver.LookupNetIP(lookupCtx, "ip", host)
- }
- }
- if (err != nil || len(ips) == 0) && r.LookupIPFallback != nil {
+ if (err != nil || len(ips) == 0) && r.LookupIPFallback != nil && r.LookupHook == nil {
lookupCtx, lookupCancel := context.WithTimeout(ctx, 30*time.Second)
defer lookupCancel()
if err != nil {
diff --git a/net/dnscache/dnscache_test.go b/net/dnscache/dnscache_test.go
index 9306c62cc90ee..2687b85a8d36a 100644
--- a/net/dnscache/dnscache_test.go
+++ b/net/dnscache/dnscache_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,14 +10,14 @@ import (
"errors"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net"
"net/netip"
"reflect"
- "slices"
"testing"
"time"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/tstest"
)
var dialTest = flag.String("dial-test", "", "if non-empty, addr:port to test dial")
diff --git a/net/dnscache/export.go b/net/dnscache/export.go
new file mode 100644
index 0000000000000..a3fa3afe44ea9
--- /dev/null
+++ b/net/dnscache/export.go
@@ -0,0 +1,8 @@
+package dnscache
+
+import (
+ "context"
+ "net/netip"
+)
+
+type LookupHookFunc func(ctx context.Context, host string) ([]netip.Addr, error)
diff --git a/net/dnscache/messagecache.go b/net/dnscache/messagecache.go
index 9bdedf19e6308..e8c7f39ff7e37 100644
--- a/net/dnscache/messagecache.go
+++ b/net/dnscache/messagecache.go
@@ -4,10 +4,10 @@
package dnscache
import (
- "cmp"
"encoding/binary"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"io"
"sync"
"time"
diff --git a/net/dnscache/messagecache_test.go b/net/dnscache/messagecache_test.go
index 79fa49360a281..1d85c12d08126 100644
--- a/net/dnscache/messagecache_test.go
+++ b/net/dnscache/messagecache_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,8 +14,8 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/tstest"
"golang.org/x/net/dns/dnsmessage"
- "tailscale.com/tstest"
)
func TestMessageCache(t *testing.T) {
diff --git a/net/dnsfallback/dnsfallback.go b/net/dnsfallback/dnsfallback.go
index 5467127762ecd..c5686d33d8136 100644
--- a/net/dnsfallback/dnsfallback.go
+++ b/net/dnsfallback/dnsfallback.go
@@ -25,24 +25,22 @@ import (
"sync/atomic"
"time"
- "tailscale.com/atomicfile"
- "tailscale.com/feature"
- "tailscale.com/health"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netns"
- "tailscale.com/net/tlsdial"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
- "tailscale.com/util/slicesx"
+ "github.com/metacubex/tailscale/atomicfile"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/net/tlsdial"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/slicesx"
)
// MakeLookupFunc creates a function that can be used to resolve hostnames
// (e.g. as a LookupIPFallback from dnscache.Resolver).
-// The netMon parameter is optional; if non-nil it's used to do faster interface lookups.
-func MakeLookupFunc(logf logger.Logf, netMon *netmon.Monitor) func(ctx context.Context, host string) ([]netip.Addr, error) {
+func MakeLookupFunc(logf logger.Logf, dialer netx.DialFunc) func(ctx context.Context, host string) ([]netip.Addr, error) {
fr := &fallbackResolver{
logf: logf,
- netMon: netMon,
+ dialer: dialer,
}
return fr.Lookup
}
@@ -51,7 +49,7 @@ func MakeLookupFunc(logf logger.Logf, netMon *netmon.Monitor) func(ctx context.C
// function.
type fallbackResolver struct {
logf logger.Logf
- netMon *netmon.Monitor // or nil
+ dialer netx.DialFunc
healthTracker *health.Tracker // or nil
// for tests
@@ -59,10 +57,10 @@ type fallbackResolver struct {
}
func (fr *fallbackResolver) Lookup(ctx context.Context, host string) ([]netip.Addr, error) {
- return lookup(ctx, host, fr.logf, fr.healthTracker, fr.netMon)
+ return lookup(ctx, host, fr.logf, fr.healthTracker, fr.dialer)
}
-func lookup(ctx context.Context, host string, logf logger.Logf, ht *health.Tracker, netMon *netmon.Monitor) ([]netip.Addr, error) {
+func lookup(ctx context.Context, host string, logf logger.Logf, ht *health.Tracker, dialer netx.DialFunc) ([]netip.Addr, error) {
if ip, err := netip.ParseAddr(host); err == nil && ip.IsValid() {
return []netip.Addr{ip}, nil
}
@@ -110,7 +108,7 @@ func lookup(ctx context.Context, host string, logf logger.Logf, ht *health.Track
logf("trying bootstrapDNS(%q, %q) for %q ...", cand.dnsName, cand.ip, host)
ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
defer cancel()
- dm, err := bootstrapDNSMap(ctx, cand.dnsName, cand.ip, host, logf, ht, netMon)
+ dm, err := bootstrapDNSMap(ctx, cand.dnsName, cand.ip, host, logf, ht, dialer)
if err != nil {
logf("bootstrapDNS(%q, %q) for %q error: %v", cand.dnsName, cand.ip, host, err)
continue
@@ -131,15 +129,20 @@ func lookup(ctx context.Context, host string, logf logger.Logf, ht *health.Track
// queryName is the name being sought (e.g. "controlplane.tailscale.com"), passed as hint.
//
// ht may be nil.
-func bootstrapDNSMap(ctx context.Context, serverName string, serverIP netip.Addr, queryName string, logf logger.Logf, ht *health.Tracker, netMon *netmon.Monitor) (dnsMap, error) {
- dialer := netns.NewDialer(logf, netMon)
- tr := http.DefaultTransport.(*http.Transport).Clone()
+func bootstrapDNSMap(ctx context.Context, serverName string, serverIP netip.Addr, queryName string, logf logger.Logf, ht *health.Tracker, dialer netx.DialFunc) (dnsMap, error) {
+ tr := (&http.Transport{
+ ForceAttemptHTTP2: true,
+ MaxIdleConns: 100,
+ IdleConnTimeout: 90 * time.Second,
+ TLSHandshakeTimeout: 10 * time.Second,
+ ExpectContinueTimeout: 1 * time.Second,
+ }).Clone()
tr.DisableKeepAlives = true // This transport is meant to be used once.
tr.Proxy = feature.HookProxyFromEnvironment.GetOrNil()
tr.DialContext = func(ctx context.Context, netw, addr string) (net.Conn, error) {
- return dialer.DialContext(ctx, "tcp", net.JoinHostPort(serverIP.String(), "443"))
+ return dialer(ctx, "tcp", net.JoinHostPort(serverIP.String(), "443"))
}
- tr.TLSClientConfig = tlsdial.Config(ht, tr.TLSClientConfig)
+ tr.TLSClientConfig = tlsdial.ConfigWithLogf(ht, tr.TLSClientConfig, logf)
c := &http.Client{Transport: tr}
req, err := http.NewRequestWithContext(ctx, "GET", "https://"+serverName+"/bootstrap-dns?q="+url.QueryEscape(queryName), nil)
if err != nil {
@@ -161,7 +164,7 @@ func bootstrapDNSMap(ctx context.Context, serverName string, serverIP netip.Addr
}
// dnsMap is the JSON type returned by the DERP /bootstrap-dns handler:
-// https://derp10.tailscale.com/bootstrap-dns
+// https://derp10.github.com/metacubex/tailscale/bootstrap-dns
type dnsMap map[string][]netip.Addr
// GetDERPMap returns a fallback DERP map that is always available, useful for basic
diff --git a/net/dnsfallback/dnsfallback_test.go b/net/dnsfallback/dnsfallback_test.go
index 4e816c3405e3a..c1f6d501d54d5 100644
--- a/net/dnsfallback/dnsfallback_test.go
+++ b/net/dnsfallback/dnsfallback_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,10 +14,10 @@ import (
"reflect"
"testing"
- "tailscale.com/net/netmon"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
)
func TestGetDERPMap(t *testing.T) {
diff --git a/net/dnsfallback/update-dns-fallbacks.go b/net/dnsfallback/update-dns-fallbacks.go
index 173b464582257..e85056b1a3011 100644
--- a/net/dnsfallback/update-dns-fallbacks.go
+++ b/net/dnsfallback/update-dns-fallbacks.go
@@ -12,11 +12,11 @@ import (
"net/http"
"os"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/tailcfg"
)
func main() {
- res, err := http.Get("https://login.tailscale.com/derpmap/default")
+ res, err := http.Get("https://login.github.com/metacubex/tailscale/derpmap/default")
if err != nil {
log.Fatal(err)
}
diff --git a/net/flowtrack/flowtrack.go b/net/flowtrack/flowtrack.go
index 5df34a5095219..cb0cc0859b1d6 100644
--- a/net/flowtrack/flowtrack.go
+++ b/net/flowtrack/flowtrack.go
@@ -15,7 +15,7 @@ import (
"fmt"
"net/netip"
- "tailscale.com/types/ipproto"
+ "github.com/metacubex/tailscale/types/ipproto"
)
// MakeTuple makes a Tuple out of netip.AddrPort values.
diff --git a/net/flowtrack/flowtrack_test.go b/net/flowtrack/flowtrack_test.go
index 21e2021e1216f..9e778cbec4c65 100644
--- a/net/flowtrack/flowtrack_test.go
+++ b/net/flowtrack/flowtrack_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,8 +10,8 @@ import (
"net/netip"
"testing"
- "tailscale.com/tstest"
- "tailscale.com/types/ipproto"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/ipproto"
)
func TestCache(t *testing.T) {
diff --git a/net/ipset/ipset.go b/net/ipset/ipset.go
index 140814d96676c..826e926c10f8b 100644
--- a/net/ipset/ipset.go
+++ b/net/ipset/ipset.go
@@ -8,9 +8,9 @@ package ipset
import (
"net/netip"
- "github.com/gaissmai/bart"
- "tailscale.com/types/views"
- "tailscale.com/util/set"
+ "github.com/metacubex/bart"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/set"
)
// FalseContainsIPFunc is shorthand for NewContainsIPFunc(views.Slice[netip.Prefix]{}).
@@ -75,9 +75,10 @@ func NewContainsIPFunc(addrs views.Slice[netip.Prefix]) func(ip netip.Addr) bool
pathForTest("bart")
// Built a bart table.
t := &bart.Lite{}
- for _, p := range addrs.All() {
+ addrs.All()(func(_ int, p netip.Prefix) bool {
t.Insert(p)
- }
+ return true
+ })
return t.Contains
}
// Fast paths for 1 and 2 IPs:
@@ -92,8 +93,9 @@ func NewContainsIPFunc(addrs views.Slice[netip.Prefix]) func(ip netip.Addr) bool
// General case:
pathForTest("ip-map")
m := set.Set[netip.Addr]{}
- for _, p := range addrs.All() {
+ addrs.All()(func(_ int, p netip.Prefix) bool {
m.Add(p.Addr())
- }
+ return true
+ })
return ipInMap(m)
}
diff --git a/net/ipset/ipset_test.go b/net/ipset/ipset_test.go
index 291416f380ef6..2a02bdc285860 100644
--- a/net/ipset/ipset_test.go
+++ b/net/ipset/ipset_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,8 +9,8 @@ import (
"net/netip"
"testing"
- "tailscale.com/tstest"
- "tailscale.com/types/views"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/views"
)
func pp(ss ...string) (ret []netip.Prefix) {
diff --git a/net/ktimeout/ktimeout_linux_test.go b/net/ktimeout/ktimeout_linux_test.go
index dc3dbe12b9363..fdf1b43d0120c 100644
--- a/net/ktimeout/ktimeout_linux_test.go
+++ b/net/ktimeout/ktimeout_linux_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,8 +11,8 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/util/must"
"golang.org/x/sys/unix"
- "tailscale.com/util/must"
)
func TestSetUserTimeout(t *testing.T) {
diff --git a/net/ktimeout/ktimeout_test.go b/net/ktimeout/ktimeout_test.go
index f361d35cbbbe5..7b5707b2e1576 100644
--- a/net/ktimeout/ktimeout_test.go
+++ b/net/ktimeout/ktimeout_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/memnet/conn_test.go b/net/memnet/conn_test.go
index 340c4c6ee00eb..37a4e7fa5ac17 100644
--- a/net/memnet/conn_test.go
+++ b/net/memnet/conn_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/memnet/listener_test.go b/net/memnet/listener_test.go
index 6c767ed57be7a..22e1212c8a7a4 100644
--- a/net/memnet/listener_test.go
+++ b/net/memnet/listener_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/memnet/memnet.go b/net/memnet/memnet.go
index 25b1062a19cec..b9c08e9dbf96e 100644
--- a/net/memnet/memnet.go
+++ b/net/memnet/memnet.go
@@ -13,8 +13,8 @@ import (
"net"
"net/netip"
- "tailscale.com/net/netx"
- "tailscale.com/syncs"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/syncs"
)
var _ netx.Network = (*Network)(nil)
diff --git a/net/memnet/memnet_test.go b/net/memnet/memnet_test.go
index d5a53ba81cb9f..7a4707e8dbfb9 100644
--- a/net/memnet/memnet_test.go
+++ b/net/memnet/memnet_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/memnet/pipe_test.go b/net/memnet/pipe_test.go
index ebd9dd8c2323f..fd3cc9ff1339a 100644
--- a/net/memnet/pipe_test.go
+++ b/net/memnet/pipe_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/netaddr/netaddr.go b/net/netaddr/netaddr.go
index 7057a8eec58e8..80a51b0a81096 100644
--- a/net/netaddr/netaddr.go
+++ b/net/netaddr/netaddr.go
@@ -47,3 +47,23 @@ func FromStdIPNet(std *net.IPNet) (prefix netip.Prefix, ok bool) {
return netip.PrefixFrom(ip, ones), true
}
+
+func FromStdNetAddr(addr net.Addr) netip.AddrPort {
+ if addr == nil {
+ return netip.AddrPort{}
+ }
+ if rawAddr, ok := addr.(interface{ RawAddr() net.Addr }); ok { // mihomo special interface
+ if rawAddr := rawAddr.RawAddr(); rawAddr != nil {
+ if ap := FromStdNetAddr(rawAddr); ap.IsValid() {
+ return ap
+ }
+ }
+ }
+ if addr, ok := addr.(interface{ AddrPort() netip.AddrPort }); ok { // *net.UDPAddr, *net.TCPAddr
+ if ap := addr.AddrPort(); ap.IsValid() {
+ return ap
+ }
+ }
+ ap, _ := netip.ParseAddrPort(addr.String())
+ return ap
+}
diff --git a/net/netcheck/captiveportal.go b/net/netcheck/captiveportal.go
index 310e98ce73a79..d092b5cc968f7 100644
--- a/net/netcheck/captiveportal.go
+++ b/net/netcheck/captiveportal.go
@@ -9,8 +9,8 @@ import (
"context"
"time"
- "tailscale.com/net/captivedetection"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/net/captivedetection"
+ "github.com/metacubex/tailscale/tailcfg"
)
func init() {
@@ -28,7 +28,7 @@ func startCaptivePortalDetection(ctx context.Context, rs *reportState, dm *tailc
tmr := time.AfterFunc(c.captivePortalDelay(), func() {
defer close(ch)
- d := captivedetection.NewDetector(c.logf)
+ d := captivedetection.NewDetector(c.logf, c.Dialer)
found := d.Detect(ctx, c.NetMon, dm, preferredDERP)
rs.report.CaptivePortal.Set(found)
})
diff --git a/net/netcheck/netcheck.go b/net/netcheck/netcheck.go
index a64c358c5c09f..6b74baa5ec674 100644
--- a/net/netcheck/netcheck.go
+++ b/net/netcheck/netcheck.go
@@ -6,14 +6,14 @@ package netcheck
import (
"bufio"
- "cmp"
"context"
"crypto/tls"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"io"
"log"
- "maps"
"net"
"net/http"
"net/netip"
@@ -23,28 +23,29 @@ import (
"syscall"
"time"
- "tailscale.com/derp"
- "tailscale.com/derp/derphttp"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/hostinfo"
- "tailscale.com/net/dnscache"
- "tailscale.com/net/neterror"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netns"
- "tailscale.com/net/ping"
- "tailscale.com/net/portmapper/portmappertype"
- "tailscale.com/net/sockstats"
- "tailscale.com/net/stun"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
- "tailscale.com/types/nettype"
- "tailscale.com/types/opt"
- "tailscale.com/types/views"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/derp"
+ "github.com/metacubex/tailscale/derp/derphttp"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/net/dnscache"
+ "github.com/metacubex/tailscale/net/neterror"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/net/ping"
+ "github.com/metacubex/tailscale/net/portmapper/portmappertype"
+ "github.com/metacubex/tailscale/net/sockstats"
+ "github.com/metacubex/tailscale/net/stun"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/nettype"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/mak"
)
// Debugging and experimentation tweakables.
@@ -202,6 +203,14 @@ type Client struct {
// If nil, log.Printf is used.
Logf logger.Logf
+ // Dialer optionally specifies how TCP probes are dialed.
+ // If nil, the default netns dialer is used.
+ Dialer netx.DialFunc
+
+ // PacketListener optionally specifies how non-TCP probes are dialed
+ // If nil, the default netns dialer is used.
+ PacketListener netx.ListenPacketFunc
+
// TimeNow, if non-nil, is used instead of time.Now.
TimeNow func() time.Time
@@ -227,6 +236,10 @@ type Client struct {
// If false, the default net.Resolver will be used, with no caching.
UseDNSCache bool
+ // LookupHook optionally specifies how tsnet resolves non-Tailscale
+ // infrastructure hostnames such as control and DERP.
+ LookupHook dnscache.LookupHookFunc
+
// if non-zero, force this DERP region to be preferred in all reports where
// the DERP is found to be reachable.
ForcePreferredDERP int
@@ -545,7 +558,7 @@ func makeProbePlanInitial(dm *tailcfg.DERPMap, ifState *netmon.State) (plan prob
var p4 []probe
var p6 []probe
- for try := range 3 {
+ for try := 0; try < 3; try++ {
n := reg.Nodes[try%len(reg.Nodes)]
delay := time.Duration(try) * defaultInitialRetransmitTime
if n.IPv4 != "none" && ((ifState.HaveV4 && nodeMight4(n)) || n.IsTestNode()) {
@@ -975,11 +988,13 @@ func (c *Client) GetReport(ctx context.Context, dm *tailcfg.DERPMap, opts *GetRe
// need to close the underlying Pinger after a timeout
// or when all ICMP probes are done, regardless of
// whether the HTTPS probes have finished.
- wg.Go(func() {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
if err := c.measureAllICMPLatency(ctx, rs, need); err != nil {
c.logf("[v1] measureAllICMPLatency: %v", err)
}
- })
+ }()
}
wg.Add(len(need))
c.logf("netcheck: UDP is blocked, trying HTTPS")
@@ -1070,7 +1085,9 @@ func (c *Client) runHTTPOnlyChecks(ctx context.Context, last *Report, rs *report
if len(rg.Nodes) == 0 {
continue
}
- wg.Go(func() {
+ wg.Add(1)
+ go func(rg *tailcfg.DERPRegion) {
+ defer wg.Done()
node := rg.Nodes[0]
req, _ := http.NewRequestWithContext(ctx, "HEAD", "https://"+node.HostName+"/derp/probe", nil)
// One warm-up one to get HTTP connection set
@@ -1095,7 +1112,7 @@ func (c *Client) runHTTPOnlyChecks(ctx context.Context, last *Report, rs *report
}
d := c.timeNow().Sub(t0)
rs.addNodeLatency(node, netip.AddrPort{}, d)
- })
+ }(rg)
}
wg.Wait()
return nil
@@ -1111,6 +1128,7 @@ func (c *Client) measureHTTPSLatency(ctx context.Context, reg *tailcfg.DERPRegio
var ip netip.Addr
dc := derphttp.NewNetcheckClient(c.logf, c.NetMon)
+ dc.SetURLDialer(c.Dialer)
defer dc.Close()
// DialRegionTLS may dial multiple times if a node is not available, as such
@@ -1195,7 +1213,11 @@ func (c *Client) measureAllICMPLatency(ctx context.Context, rs *reportState, nee
ctx, done := context.WithTimeout(ctx, icmpProbeTimeout)
defer done()
- p := ping.New(ctx, c.logf, netns.Listener(c.logf, c.NetMon))
+ lp := c.PacketListener
+ if lp == nil {
+ lp = netns.Listener(c.logf, c.NetMon).ListenPacket
+ }
+ p := ping.New(ctx, c.logf, lp)
defer p.Close()
c.logf("UDP is blocked, trying ICMP")
@@ -1623,31 +1645,19 @@ func (c *Client) nodeAddrPort(ctx context.Context, n *tailcfg.DERPNode, port int
return zero, false
}
- // The default lookup function if we don't set UseDNSCache is to use net.DefaultResolver.
- lookupIPAddr := func(ctx context.Context, host string) ([]netip.Addr, error) {
- addrs, err := net.DefaultResolver.LookupIPAddr(ctx, host)
- if err != nil {
- return nil, err
- }
-
- var naddrs []netip.Addr
- for _, addr := range addrs {
- na, ok := netip.AddrFromSlice(addr.IP)
- if !ok {
- continue
- }
- naddrs = append(naddrs, na.Unmap())
- }
- return naddrs, nil
+ if c.LookupHook == nil {
+ return zero, false
}
+ lookupIPAddr := c.LookupHook
+
c.mu.Lock()
if c.UseDNSCache {
if c.resolver == nil {
c.resolver = &dnscache.Resolver{
- Forward: net.DefaultResolver,
UseLastGood: true,
Logf: c.logf,
+ LookupHook: c.LookupHook,
}
}
resolver := c.resolver
diff --git a/net/netcheck/netcheck_test.go b/net/netcheck/netcheck_test.go
index 0fd3460fa57af..dad840a153de7 100644
--- a/net/netcheck/netcheck_test.go
+++ b/net/netcheck/netcheck_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,22 +9,22 @@ import (
"bytes"
"context"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net"
"net/http"
"net/netip"
"reflect"
- "slices"
"strconv"
"strings"
"testing"
"time"
- "tailscale.com/derp"
- "tailscale.com/net/netmon"
- "tailscale.com/net/stun/stuntest"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest/nettest"
+ "github.com/metacubex/tailscale/derp"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/stun/stuntest"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest/nettest"
)
func newTestClient(t testing.TB) *Client {
diff --git a/net/netcheck/standalone.go b/net/netcheck/standalone.go
index 88d5b4cc5a7f1..4d35d07ea8156 100644
--- a/net/netcheck/standalone.go
+++ b/net/netcheck/standalone.go
@@ -8,11 +8,11 @@ import (
"errors"
"net/netip"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/netns"
- "tailscale.com/net/stun"
- "tailscale.com/types/logger"
- "tailscale.com/types/nettype"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/net/stun"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/nettype"
)
// Standalone creates the necessary UDP sockets on the given bindAddr and starts
diff --git a/net/neterror/neterror_linux.go b/net/neterror/neterror_linux.go
index a99452de5d3b8..9add4fd1d213c 100644
--- a/net/neterror/neterror_linux.go
+++ b/net/neterror/neterror_linux.go
@@ -12,7 +12,8 @@ import (
func init() {
shouldDisableUDPGSO = func(err error) bool {
- if serr, ok := errors.AsType[*os.SyscallError](err); ok {
+ var serr *os.SyscallError
+ if errors.As(err, &serr) {
// EIO is returned by udp_send_skb() if the device driver does not
// have tx checksumming enabled, which is a hard requirement of
// UDP_SEGMENT. See:
diff --git a/net/neterror/neterror_linux_test.go b/net/neterror/neterror_linux_test.go
index d8846219afad2..f6fc8461d7da7 100644
--- a/net/neterror/neterror_linux_test.go
+++ b/net/neterror/neterror_linux_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/netkernelconf/netkernelconf_linux.go b/net/netkernelconf/netkernelconf_linux.go
index b8c165ac558cf..6ec253facf9ba 100644
--- a/net/netkernelconf/netkernelconf_linux.go
+++ b/net/netkernelconf/netkernelconf_linux.go
@@ -23,7 +23,7 @@ const (
// It returns a non-nil err in the case that an error is encountered while
// performing the check.
func CheckUDPGROForwarding(tunInterface, defaultRouteInterface string) (warn, err error) {
- const kbLink = "\nSee https://tailscale.com/s/ethtool-config-udp-gro"
+ const kbLink = "\nSee https://github.com/metacubex/tailscale/s/ethtool-config-udp-gro"
errWithPrefix := func(format string, a ...any) error {
const errPrefix = "couldn't check system's UDP GRO forwarding configuration, "
return fmt.Errorf(errPrefix+format, a...)
@@ -61,7 +61,7 @@ func CheckUDPGROForwarding(tunInterface, defaultRouteInterface string) (warn, er
// SetUDPGROForwarding enables UDP GRO forwarding for the provided default
// interface. It validates if the provided tun interface has UDP segmentation
// enabled and, if not, returns an error. See
-// https://tailscale.com/kb/1320/performance-best-practices#linux-optimizations-for-subnet-routers-and-exit-nodes
+// https://github.com/metacubex/tailscale/kb/1320/performance-best-practices#linux-optimizations-for-subnet-routers-and-exit-nodes
func SetUDPGROForwarding(tunInterface, defaultInterface string) error {
e, err := ethtool.NewEthtool()
if err != nil {
diff --git a/net/netmon/defaultroute_darwin.go b/net/netmon/defaultroute_darwin.go
index 121535937bc22..922de893f0156 100644
--- a/net/netmon/defaultroute_darwin.go
+++ b/net/netmon/defaultroute_darwin.go
@@ -11,7 +11,7 @@ import (
"log"
"net"
- "tailscale.com/syncs"
+ "github.com/metacubex/tailscale/syncs"
)
var (
diff --git a/net/netmon/interfaces.go b/net/netmon/interfaces.go
index c7a2cb213e893..9ede9b330c1f5 100644
--- a/net/netmon/interfaces.go
+++ b/net/netmon/interfaces.go
@@ -7,7 +7,7 @@ import (
"errors"
"net"
- "tailscale.com/syncs"
+ "github.com/metacubex/tailscale/syncs"
)
type ifProps struct {
diff --git a/net/netmon/interfaces_android.go b/net/netmon/interfaces_android.go
index 2cd7f23f6f164..99fa3990d8848 100644
--- a/net/netmon/interfaces_android.go
+++ b/net/netmon/interfaces_android.go
@@ -10,11 +10,12 @@ import (
"os/exec"
"sync/atomic"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/result"
+ "github.com/metacubex/tailscale/util/lineiter"
"go4.org/mem"
"golang.org/x/sys/unix"
- "tailscale.com/net/netaddr"
- "tailscale.com/syncs"
- "tailscale.com/util/lineiter"
)
var (
@@ -48,43 +49,45 @@ func likelyHomeRouterIPAndroid() (ret netip.Addr, myIP netip.Addr, ok bool) {
}
lineNum := 0
var f []mem.RO
- for lr := range lineiter.File(procNetRoutePath) {
+ lineiter.File(procNetRoutePath)(func(lr result.Of[[]byte]) bool {
line, err := lr.Value()
if err != nil {
procNetRouteErr.Store(true)
- return likelyHomeRouterIP()
+ ret, myIP, ok = likelyHomeRouterIP()
+ return false
}
lineNum++
if lineNum == 1 {
// Skip header line.
- continue
+ return true
}
if lineNum > maxProcNetRouteRead {
- break
+ return false
}
f = mem.AppendFields(f[:0], mem.B(line))
if len(f) < 4 {
- continue
+ return true
}
gwHex, flagsHex := f[2], f[3]
flags, err := mem.ParseUint(flagsHex, 16, 16)
if err != nil {
- continue // ignore error, skip line and keep going
+ return true // ignore error, skip line and keep going
}
if flags&(unix.RTF_UP|unix.RTF_GATEWAY) != unix.RTF_UP|unix.RTF_GATEWAY {
- continue
+ return true
}
ipu32, err := mem.ParseUint(gwHex, 16, 32)
if err != nil {
- continue // ignore error, skip line and keep going
+ return true // ignore error, skip line and keep going
}
ip := netaddr.IPv4(byte(ipu32), byte(ipu32>>8), byte(ipu32>>16), byte(ipu32>>24))
if ip.IsPrivate() {
ret = ip
- break
+ return false
}
- }
+ return true
+ })
if ret.IsValid() {
// Try to get the local IP of the interface associated with
// this route to short-circuit finding the IP associated with
@@ -136,26 +139,27 @@ func likelyHomeRouterIPHelper() (ret netip.Addr, _ netip.Addr, ok bool) {
return
}
// Search for line like "default via 10.0.2.2 dev radio0 table 1016 proto static mtu 1500 "
- for lr := range lineiter.Reader(out) {
+ lineiter.Reader(out)(func(lr result.Of[[]byte]) bool {
line, err := lr.Value()
if err != nil {
- break
+ return false
}
const pfx = "default via "
if !mem.HasPrefix(mem.B(line), mem.S(pfx)) {
- continue
+ return true
}
line = line[len(pfx):]
sp := bytes.IndexByte(line, ' ')
if sp == -1 {
- continue
+ return true
}
ipb := line[:sp]
if ip, err := netip.ParseAddr(string(ipb)); err == nil && ip.Is4() {
ret = ip
log.Printf("interfaces: found Android default route %v", ip)
}
- }
+ return true
+ })
cmd.Process.Kill()
cmd.Wait()
return ret, netip.Addr{}, ret.IsValid()
diff --git a/net/netmon/interfaces_bsd.go b/net/netmon/interfaces_bsd.go
index 4c09aa55eeb31..793a02fd40fde 100644
--- a/net/netmon/interfaces_bsd.go
+++ b/net/netmon/interfaces_bsd.go
@@ -15,9 +15,9 @@ import (
"net/netip"
"syscall"
+ "github.com/metacubex/tailscale/net/netaddr"
"golang.org/x/net/route"
"golang.org/x/sys/unix"
- "tailscale.com/net/netaddr"
)
// ErrNoGatewayIndexFound is returned by DefaultRouteInterfaceIndex when no
diff --git a/net/netmon/interfaces_darwin.go b/net/netmon/interfaces_darwin.go
index c0f588fd20c1b..615b24aeaa0b9 100644
--- a/net/netmon/interfaces_darwin.go
+++ b/net/netmon/interfaces_darwin.go
@@ -10,10 +10,10 @@ import (
"syscall"
"unsafe"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/util/mak"
"golang.org/x/net/route"
"golang.org/x/sys/unix"
- "tailscale.com/syncs"
- "tailscale.com/util/mak"
)
// fetchRoutingTable calls route.FetchRIB, fetching NET_RT_DUMP2.
diff --git a/net/netmon/interfaces_darwin_test.go b/net/netmon/interfaces_darwin_test.go
index e4b84a144a432..c49ad8d1ee52f 100644
--- a/net/netmon/interfaces_darwin_test.go
+++ b/net/netmon/interfaces_darwin_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,9 +11,9 @@ import (
"os/exec"
"testing"
+ "github.com/metacubex/tailscale/util/lineiter"
+ "github.com/metacubex/tailscale/version"
"go4.org/mem"
- "tailscale.com/util/lineiter"
- "tailscale.com/version"
)
func TestLikelyHomeRouterIPSyscallExec(t *testing.T) {
diff --git a/net/netmon/interfaces_default_route_test.go b/net/netmon/interfaces_default_route_test.go
index 76424aef7af2f..286661b79c100 100644
--- a/net/netmon/interfaces_default_route_test.go
+++ b/net/netmon/interfaces_default_route_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux || (darwin && !ts_macext)
-
package netmon
import (
diff --git a/net/netmon/interfaces_linux.go b/net/netmon/interfaces_linux.go
index 64cb0b9af2ce6..01dc8e70cebee 100644
--- a/net/netmon/interfaces_linux.go
+++ b/net/netmon/interfaces_linux.go
@@ -20,11 +20,12 @@ import (
"github.com/jsimonetti/rtnetlink"
"github.com/mdlayher/netlink"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/types/result"
+ "github.com/metacubex/tailscale/util/lineiter"
"go4.org/mem"
"golang.org/x/sys/unix"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/net/netaddr"
- "tailscale.com/util/lineiter"
)
func init() {
@@ -51,43 +52,44 @@ func likelyHomeRouterIPLinux() (ret netip.Addr, myIP netip.Addr, ok bool) {
}
lineNum := 0
var f []mem.RO
- for lr := range lineiter.File(procNetRoutePath) {
+ lineiter.File(procNetRoutePath)(func(lr result.Of[[]byte]) bool {
line, err := lr.Value()
if err != nil {
procNetRouteErr.Store(true)
log.Printf("interfaces: failed to read /proc/net/route: %v", err)
- return ret, myIP, false
+ return false
}
lineNum++
if lineNum == 1 {
// Skip header line.
- continue
+ return true
}
if lineNum > maxProcNetRouteRead {
- break
+ return false
}
f = mem.AppendFields(f[:0], mem.B(line))
if len(f) < 4 {
- continue
+ return true
}
gwHex, flagsHex := f[2], f[3]
flags, err := mem.ParseUint(flagsHex, 16, 16)
if err != nil {
- continue // ignore error, skip line and keep going
+ return true // ignore error, skip line and keep going
}
if flags&(unix.RTF_UP|unix.RTF_GATEWAY) != unix.RTF_UP|unix.RTF_GATEWAY {
- continue
+ return true
}
ipu32, err := mem.ParseUint(gwHex, 16, 32)
if err != nil {
- continue // ignore error, skip line and keep going
+ return true // ignore error, skip line and keep going
}
ip := netaddr.IPv4(byte(ipu32), byte(ipu32>>8), byte(ipu32>>16), byte(ipu32>>24))
if ip.IsPrivate() {
ret = ip
- break
+ return false
}
- }
+ return true
+ })
if ret.IsValid() {
// Try to get the local IP of the interface associated with
// this route to short-circuit finding the IP associated with
diff --git a/net/netmon/interfaces_linux_test.go b/net/netmon/interfaces_linux_test.go
index 5a29c4b8b3ada..81680ccaefb8a 100644
--- a/net/netmon/interfaces_linux_test.go
+++ b/net/netmon/interfaces_linux_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,7 +13,7 @@ import (
"path/filepath"
"testing"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/tstest"
)
// test the specific /proc/net/route path as found on Google Cloud Run instances
diff --git a/net/netmon/interfaces_test.go b/net/netmon/interfaces_test.go
index bd81eb96a42bf..b5c185628de36 100644
--- a/net/netmon/interfaces_test.go
+++ b/net/netmon/interfaces_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,7 +11,7 @@ import (
"net/netip"
"testing"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/tstest"
)
func TestGetState(t *testing.T) {
diff --git a/net/netmon/interfaces_windows.go b/net/netmon/interfaces_windows.go
index 070b08ba658e2..b6db0598b6c33 100644
--- a/net/netmon/interfaces_windows.go
+++ b/net/netmon/interfaces_windows.go
@@ -11,10 +11,10 @@ import (
"syscall"
"unsafe"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/tsconst"
+ "github.com/metacubex/tailscale/util/winipcfg"
"golang.org/x/sys/windows"
- "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/tsconst"
)
const (
diff --git a/net/netmon/interfaces_windows_test.go b/net/netmon/interfaces_windows_test.go
index 13526612eb477..b1073173e995b 100644
--- a/net/netmon/interfaces_windows_test.go
+++ b/net/netmon/interfaces_windows_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/netmon/loghelper.go b/net/netmon/loghelper.go
index bddbd4d616462..f52517e2d1b00 100644
--- a/net/netmon/loghelper.go
+++ b/net/netmon/loghelper.go
@@ -8,8 +8,8 @@ import (
"sync"
"time"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
)
const cooldownSeconds = 300
@@ -27,10 +27,16 @@ func LinkChangeLogLimiter(ctx context.Context, logf logger.Logf, nm *Monitor) lo
// Any link changes that are flagged as likely require a rebind are
// interesting enough that we should log them.
if cd.RebindLikelyRequired {
- formatLastSeen.Clear()
+ formatLastSeen.Range(func(key, value any) bool {
+ formatLastSeen.Delete(key)
+ return true
+ })
}
})
- context.AfterFunc(ctx, sub.Close)
+ go func() {
+ <-ctx.Done()
+ sub.Close()
+ }()
return func(format string, args ...any) {
// get the current timestamp
now := time.Now().Unix()
diff --git a/net/netmon/loghelper_test.go b/net/netmon/loghelper_test.go
index 64231e595120a..7da9bdc8dd573 100644
--- a/net/netmon/loghelper_test.go
+++ b/net/netmon/loghelper_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,8 +12,8 @@ import (
"testing"
"testing/synctest"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
)
func TestLinkChangeLogLimiter(t *testing.T) { synctest.Test(t, syncTestLinkChangeLogLimiter) }
diff --git a/net/netmon/netmon.go b/net/netmon/netmon.go
index a7120cdd3375a..755e5258aa488 100644
--- a/net/netmon/netmon.go
+++ b/net/netmon/netmon.go
@@ -9,20 +9,20 @@ package netmon
import (
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
"net/netip"
"runtime"
- "slices"
"strings"
"sync"
"time"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/syncs"
- "tailscale.com/types/logger"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/set"
)
// pollWallTimeInterval is how often we check the time to check
@@ -32,6 +32,13 @@ import (
// us check the wall time sooner than this.
const pollWallTimeInterval = 15 * time.Second
+// postWakePollDuration is how long to keep polling interfaces after a time
+// jump. The first wake snapshot can run before Wi-Fi or DHCP has recovered,
+// and the OS does not always deliver another address or route notification.
+const postWakePollDuration = 10 * time.Minute
+
+const postWakePollCount = int(postWakePollDuration / pollWallTimeInterval)
+
// majorTimeJumpThreshold is the minimum sleep duration that warrants
// treating a time jump as a major event requiring socket rebinding,
// even if the interface state appears unchanged. After a long sleep,
@@ -77,18 +84,19 @@ type Monitor struct {
stop chan struct{} // closed on Stop
static bool // static Monitor that doesn't actually monitor
- mu syncs.Mutex // guards all following fields
- cbs set.HandleSet[ChangeFunc]
- ifState *State
- gwValid bool // whether gw and gwSelfIP are valid
- gw netip.Addr // our gateway's IP
- gwSelfIP netip.Addr // our own IP address (that corresponds to gw)
- started bool
- closed bool
- goroutines sync.WaitGroup
- wallTimer *time.Timer // nil until Started; re-armed AfterFunc per tick
- lastWall time.Time
- jumpDuration time.Duration // wall-clock time elapsed during detected time jump; 0 if no time jump observed since reset
+ mu syncs.Mutex // guards all following fields
+ cbs set.HandleSet[ChangeFunc]
+ ifState *State
+ gwValid bool // whether gw and gwSelfIP are valid
+ gw netip.Addr // our gateway's IP
+ gwSelfIP netip.Addr // our own IP address (that corresponds to gw)
+ started bool
+ closed bool
+ goroutines sync.WaitGroup
+ wallTimer *time.Timer // nil until Started; re-armed AfterFunc per tick
+ lastWall time.Time
+ jumpDuration time.Duration // wall-clock time elapsed during detected time jump; 0 if no time jump observed since reset
+ postWakePolls int // additional interface polls after a detected wake
}
// ChangeFunc is a callback function registered with Monitor that's called when the
@@ -702,7 +710,11 @@ func (m *Monitor) pollWallTime() {
return
}
if m.checkWallTimeAdvanceLocked() {
+ m.postWakePolls = postWakePollCount
m.InjectEvent()
+ } else if m.postWakePolls > 0 {
+ m.postWakePolls--
+ m.Poll()
}
m.wallTimer.Reset(pollWallTimeInterval)
}
diff --git a/net/netmon/netmon_darwin.go b/net/netmon/netmon_darwin.go
index 588cbf6161845..633c700d789f5 100644
--- a/net/netmon/netmon_darwin.go
+++ b/net/netmon/netmon_darwin.go
@@ -9,11 +9,11 @@ import (
"strings"
"sync"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
"golang.org/x/net/route"
"golang.org/x/sys/unix"
- "tailscale.com/net/netaddr"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
)
func init() {
diff --git a/net/netmon/netmon_darwin_test.go b/net/netmon/netmon_darwin_test.go
index e57b5ca84c146..8cf4cc2c38b6c 100644
--- a/net/netmon/netmon_darwin_test.go
+++ b/net/netmon/netmon_darwin_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/netmon/netmon_freebsd.go b/net/netmon/netmon_freebsd.go
index 8e99532c589b6..9ceddbe8bda69 100644
--- a/net/netmon/netmon_freebsd.go
+++ b/net/netmon/netmon_freebsd.go
@@ -9,8 +9,8 @@ import (
"net"
"strings"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
)
// unspecifiedMessage is a minimal message implementation that should not
diff --git a/net/netmon/netmon_linux.go b/net/netmon/netmon_linux.go
index b7d87f995634f..c9284755f7daf 100644
--- a/net/netmon/netmon_linux.go
+++ b/net/netmon/netmon_linux.go
@@ -12,11 +12,11 @@ import (
"github.com/jsimonetti/rtnetlink"
"github.com/mdlayher/netlink"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
"golang.org/x/sys/unix"
- "tailscale.com/envknob"
- "tailscale.com/net/tsaddr"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
)
var debugNetlinkMessages = envknob.RegisterBool("TS_DEBUG_NETLINK")
diff --git a/net/netmon/netmon_linux_test.go b/net/netmon/netmon_linux_test.go
index c4e59059ac4c4..493a8f557dbc4 100644
--- a/net/netmon/netmon_linux_test.go
+++ b/net/netmon/netmon_linux_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux && !android
-
package netmon
import (
diff --git a/net/netmon/netmon_polling.go b/net/netmon/netmon_polling.go
index bdeb43005782b..8855c5ed94517 100644
--- a/net/netmon/netmon_polling.go
+++ b/net/netmon/netmon_polling.go
@@ -6,8 +6,8 @@
package netmon
import (
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
)
func newOSMon(_ *eventbus.Bus, logf logger.Logf, m *Monitor) (osMon, error) {
diff --git a/net/netmon/netmon_test.go b/net/netmon/netmon_test.go
index a3ba4e03e17de..2fe55c7208dd5 100644
--- a/net/netmon/netmon_test.go
+++ b/net/netmon/netmon_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -13,9 +15,9 @@ import (
"testing"
"time"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/mak"
)
func TestMonitorStartClose(t *testing.T) {
diff --git a/net/netmon/netmon_windows.go b/net/netmon/netmon_windows.go
index 91c137de0e328..d7c486ba10467 100644
--- a/net/netmon/netmon_windows.go
+++ b/net/netmon/netmon_windows.go
@@ -10,10 +10,10 @@ import (
"sync"
"time"
- "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
- "tailscale.com/net/tsaddr"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/winipcfg"
)
var (
diff --git a/net/netmon/polling.go b/net/netmon/polling.go
index 806f0b0451fe1..768419bda8839 100644
--- a/net/netmon/polling.go
+++ b/net/netmon/polling.go
@@ -13,7 +13,7 @@ import (
"sync"
"time"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
func newPollingMon(logf logger.Logf, m *Monitor) (osMon, error) {
diff --git a/net/netmon/state.go b/net/netmon/state.go
index 94554dcc39c1e..228f6e9a1d9a3 100644
--- a/net/netmon/state.go
+++ b/net/netmon/state.go
@@ -6,21 +6,21 @@ package netmon
import (
"bytes"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net"
"net/http"
"net/netip"
"runtime"
- "slices"
"sort"
"strings"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/hostinfo"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/tsaddr"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/util/mak"
)
// forceAllIPv6Endpoints is a debug knob that when set forces the client to
diff --git a/net/netmon/wake_retry_test.go b/net/netmon/wake_retry_test.go
new file mode 100644
index 0000000000000..f4f9121e1173b
--- /dev/null
+++ b/net/netmon/wake_retry_test.go
@@ -0,0 +1,127 @@
+// Copyright (c) Tailscale Inc & contributors
+// SPDX-License-Identifier: BSD-3-Clause
+
+package netmon
+
+import (
+ "net"
+ "sync/atomic"
+ "testing"
+ "time"
+
+ "github.com/metacubex/tailscale/util/eventbus"
+)
+
+func TestPollWallTimeRetriesAfterWake(t *testing.T) {
+ m := &Monitor{
+ change: make(chan bool, 1),
+ lastWall: wallTime().Add(-time.Hour),
+ wallTimer: time.NewTimer(time.Hour),
+ }
+ defer m.wallTimer.Stop()
+
+ m.pollWallTime()
+ select {
+ case forceCallbacks := <-m.change:
+ if !forceCallbacks {
+ t.Fatal("initial wake event did not force callbacks")
+ }
+ default:
+ t.Fatal("time jump did not inject a wake event")
+ }
+
+ // Simulate debounce consuming the wake event while the physical interface
+ // is still down. Windows sometimes does not deliver another interface event
+ // after Wi-Fi finishes reconnecting.
+ m.mu.Lock()
+ m.resetTimeJumpedLocked()
+ m.lastWall = wallTime()
+ m.mu.Unlock()
+
+ for retry := 0; retry < postWakePollCount; retry++ {
+ m.pollWallTime()
+ select {
+ case forceCallbacks := <-m.change:
+ if forceCallbacks {
+ t.Fatalf("post-wake retry %d unexpectedly forced callbacks", retry+1)
+ }
+ default:
+ t.Fatalf("post-wake interface poll %d was not scheduled", retry+1)
+ }
+ }
+
+ m.pollWallTime()
+ select {
+ case <-m.change:
+ t.Fatalf("post-wake polling continued past %v", postWakePollDuration)
+ default:
+ }
+}
+
+func TestWakeRetryObservesRecoveredInterfaceWithoutOSEvent(t *testing.T) {
+ var interfaceUp atomic.Bool
+ interfaceUp.Store(true)
+
+ ipnet := func(s string) net.Addr {
+ ip, prefix, err := net.ParseCIDR(s)
+ if err != nil {
+ t.Fatal(err)
+ }
+ prefix.IP = ip
+ return prefix
+ }
+ oldInterfaceGetter := altNetInterfaces
+ altNetInterfaces = func() ([]Interface, error) {
+ flags := net.FlagBroadcast | net.FlagMulticast
+ var addrs []net.Addr
+ if interfaceUp.Load() {
+ flags |= net.FlagUp | net.FlagRunning
+ addrs = []net.Addr{ipnet("192.0.2.10/24")}
+ }
+ return []Interface{{
+ Interface: &net.Interface{Index: 100, MTU: 1500, Name: "wake-test0", Flags: flags},
+ AltAddrs: addrs,
+ }}, nil
+ }
+ t.Cleanup(func() { altNetInterfaces = oldInterfaceGetter })
+
+ bus := eventbus.New()
+ defer bus.Close()
+ m, err := New(bus, t.Logf)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer m.Close()
+
+ states := make(chan bool, 2)
+ m.RegisterChangeCallback(func(delta *ChangeDelta) {
+ states <- delta.AnyInterfaceUp()
+ })
+ m.Start()
+
+ interfaceUp.Store(false)
+ m.mu.Lock()
+ m.lastWall = wallTime().Add(-time.Hour)
+ m.mu.Unlock()
+ m.pollWallTime()
+ select {
+ case up := <-states:
+ if up {
+ t.Fatal("wake snapshot unexpectedly reported an interface up")
+ }
+ case <-time.After(5 * time.Second):
+ t.Fatal("timeout waiting for offline wake snapshot")
+ }
+
+ // The interface recovers without a Windows address or route event.
+ interfaceUp.Store(true)
+ m.pollWallTime()
+ select {
+ case up := <-states:
+ if !up {
+ t.Fatal("post-wake poll did not observe the recovered interface")
+ }
+ case <-time.After(5 * time.Second):
+ t.Fatal("timeout waiting for post-wake interface recovery")
+ }
+}
diff --git a/net/netns/netns.go b/net/netns/netns.go
index fe7ff4dcbadd8..0fe8ca635b567 100644
--- a/net/netns/netns.go
+++ b/net/netns/netns.go
@@ -20,9 +20,9 @@ import (
"runtime"
"sync/atomic"
- "tailscale.com/net/netknob"
- "tailscale.com/net/netmon"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/net/netknob"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/types/logger"
)
var disabled atomic.Bool
diff --git a/net/netns/netns_android.go b/net/netns/netns_android.go
index 7c5fe3214dcbf..da7a4f2339a7a 100644
--- a/net/netns/netns_android.go
+++ b/net/netns/netns_android.go
@@ -10,8 +10,8 @@ import (
"sync"
"syscall"
- "tailscale.com/net/netmon"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/types/logger"
)
var (
diff --git a/net/netns/netns_darwin.go b/net/netns/netns_darwin.go
index e5d01542edfb4..548d08e0a07a2 100644
--- a/net/netns/netns_darwin.go
+++ b/net/netns/netns_darwin.go
@@ -15,13 +15,13 @@ import (
"strings"
"syscall"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/version"
"golang.org/x/net/route"
"golang.org/x/sys/unix"
- "tailscale.com/envknob"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsaddr"
- "tailscale.com/types/logger"
- "tailscale.com/version"
)
func control(logf logger.Logf, netMon *netmon.Monitor) func(network, address string, c syscall.RawConn) error {
diff --git a/net/netns/netns_darwin_test.go b/net/netns/netns_darwin_test.go
index 768b095b82739..434d7cbc63e72 100644
--- a/net/netns/netns_darwin_test.go
+++ b/net/netns/netns_darwin_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,7 +8,7 @@ package netns
import (
"testing"
- "tailscale.com/net/netmon"
+ "github.com/metacubex/tailscale/net/netmon"
)
func TestGetInterfaceIndex(t *testing.T) {
diff --git a/net/netns/netns_default.go b/net/netns/netns_default.go
index 33f4c1333e395..4d7a0c84efbcf 100644
--- a/net/netns/netns_default.go
+++ b/net/netns/netns_default.go
@@ -8,8 +8,8 @@ package netns
import (
"syscall"
- "tailscale.com/net/netmon"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/types/logger"
)
func control(logger.Logf, *netmon.Monitor) func(network, address string, c syscall.RawConn) error {
diff --git a/net/netns/netns_linux.go b/net/netns/netns_linux.go
index 02b2dd89b197f..16e88dd6855c4 100644
--- a/net/netns/netns_linux.go
+++ b/net/netns/netns_linux.go
@@ -12,11 +12,11 @@ import (
"sync"
"syscall"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/tsconst"
+ "github.com/metacubex/tailscale/types/logger"
"golang.org/x/sys/unix"
- "tailscale.com/envknob"
- "tailscale.com/net/netmon"
- "tailscale.com/tsconst"
- "tailscale.com/types/logger"
)
// socketMarkWorksOnce is the sync.Once & cached value for useSocketMark.
diff --git a/net/netns/netns_linux_test.go b/net/netns/netns_linux_test.go
index e467ee41405d6..8bab4a77904f2 100644
--- a/net/netns/netns_linux_test.go
+++ b/net/netns/netns_linux_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/netns/netns_openbsd.go b/net/netns/netns_openbsd.go
index 47968bd42f35e..57fe8dac5bc9e 100644
--- a/net/netns/netns_openbsd.go
+++ b/net/netns/netns_openbsd.go
@@ -13,9 +13,9 @@ import (
"sync"
"syscall"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/types/logger"
"golang.org/x/sys/unix"
- "tailscale.com/net/netmon"
- "tailscale.com/types/logger"
)
var (
diff --git a/net/netns/netns_test.go b/net/netns/netns_test.go
index 9ecc19b424f95..436feca2affe6 100644
--- a/net/netns/netns_test.go
+++ b/net/netns/netns_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/netns/netns_windows.go b/net/netns/netns_windows.go
index 686c813f6b1d1..0e425c259d933 100644
--- a/net/netns/netns_windows.go
+++ b/net/netns/netns_windows.go
@@ -10,13 +10,13 @@ import (
"strings"
"syscall"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/tsconst"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/winipcfg"
"golang.org/x/sys/cpu"
"golang.org/x/sys/windows"
- "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
- "tailscale.com/envknob"
- "tailscale.com/net/netmon"
- "tailscale.com/tsconst"
- "tailscale.com/types/logger"
)
func interfaceIndex(iface *winipcfg.IPAdapterAddresses) uint32 {
diff --git a/net/netns/netns_windows_test.go b/net/netns/netns_windows_test.go
index 67e7b3de86c09..55103464d0e7a 100644
--- a/net/netns/netns_windows_test.go
+++ b/net/netns/netns_windows_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,9 +9,9 @@ import (
"strings"
"testing"
+ "github.com/metacubex/tailscale/tsconst"
+ "github.com/metacubex/tailscale/util/winipcfg"
"golang.org/x/sys/windows"
- "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
- "tailscale.com/tsconst"
)
func TestGetInterfaceIndex(t *testing.T) {
diff --git a/net/netns/socks.go b/net/netns/socks.go
index 7746e91778353..deb1f7b1674e1 100644
--- a/net/netns/socks.go
+++ b/net/netns/socks.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ios && !js && !android && !ts_omit_useproxy
+//go:build !ios && !js && !android && ts_enable_useproxy
package netns
diff --git a/net/netns/zsyscall_windows.go b/net/netns/zsyscall_windows.go
index 3d8f06e097340..875ab1a063c0c 100644
--- a/net/netns/zsyscall_windows.go
+++ b/net/netns/zsyscall_windows.go
@@ -6,8 +6,8 @@ import (
"syscall"
"unsafe"
+ "github.com/metacubex/tailscale/util/winipcfg"
"golang.org/x/sys/windows"
- "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
)
var _ unsafe.Pointer
diff --git a/net/netstat/netstat_test.go b/net/netstat/netstat_test.go
index 8407db778f001..d7555f4dac2a0 100644
--- a/net/netstat/netstat_test.go
+++ b/net/netstat/netstat_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/netstat/netstat_windows.go b/net/netstat/netstat_windows.go
index 4b3edbdf8134b..fa1f2ea1b3fe2 100644
--- a/net/netstat/netstat_windows.go
+++ b/net/netstat/netstat_windows.go
@@ -10,9 +10,9 @@ import (
"net/netip"
"unsafe"
+ "github.com/metacubex/tailscale/net/netaddr"
"golang.org/x/sys/cpu"
"golang.org/x/sys/windows"
- "tailscale.com/net/netaddr"
)
// OSMetadata includes any additional OS-specific information that may be
diff --git a/net/netutil/default_interface_portable_test.go b/net/netutil/default_interface_portable_test.go
index b54733747524f..420c7a7d168b3 100644
--- a/net/netutil/default_interface_portable_test.go
+++ b/net/netutil/default_interface_portable_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/netutil/ip_forward.go b/net/netutil/ip_forward.go
index bc0f1961dfcbc..6286c21dfdcdc 100644
--- a/net/netutil/ip_forward.go
+++ b/net/netutil/ip_forward.go
@@ -14,7 +14,7 @@ import (
"strconv"
"strings"
- "tailscale.com/net/netmon"
+ "github.com/metacubex/tailscale/net/netmon"
)
// protocolsRequiredForForwarding reports whether IPv4 and/or IPv6 protocols are
@@ -73,7 +73,7 @@ func CheckIPForwarding(routes []netip.Prefix, state *netmon.State) (warn, err er
if state == nil {
return nil, fmt.Errorf("Couldn't check system's IP forwarding configuration; no link state")
}
- const kbLink = "\nSee https://tailscale.com/s/ip-forwarding"
+ const kbLink = "\nSee https://github.com/metacubex/tailscale/s/ip-forwarding"
wantV4, wantV6 := protocolsRequiredForForwarding(routes, state)
if !wantV4 && !wantV6 {
return nil, nil
diff --git a/net/netutil/netutil.go b/net/netutil/netutil.go
index 13882988594d1..44f8f49f5c908 100644
--- a/net/netutil/netutil.go
+++ b/net/netutil/netutil.go
@@ -9,7 +9,7 @@ import (
"io"
"net"
- "tailscale.com/syncs"
+ "github.com/metacubex/tailscale/syncs"
)
// NewOneConnListener returns a net.Listener that returns c on its
diff --git a/net/netutil/netutil_test.go b/net/netutil/netutil_test.go
index 2c40d8d9ee68e..305cd677d798b 100644
--- a/net/netutil/netutil_test.go
+++ b/net/netutil/netutil_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/netutil/routes.go b/net/netutil/routes.go
index 26f2de97c5767..cbe5382e1d9f1 100644
--- a/net/netutil/routes.go
+++ b/net/netutil/routes.go
@@ -10,7 +10,7 @@ import (
"sort"
"strings"
- "tailscale.com/net/tsaddr"
+ "github.com/metacubex/tailscale/net/tsaddr"
)
func validateViaPrefix(ipp netip.Prefix) error {
@@ -41,8 +41,8 @@ func CalcAdvertiseRoutes(advertiseRoutes string, advertiseDefaultRoute bool) ([]
routeMap := map[netip.Prefix]bool{}
if advertiseRoutes != "" {
var default4, default6 bool
- advroutes := strings.SplitSeq(advertiseRoutes, ",")
- for s := range advroutes {
+ advroutes := strings.Split(advertiseRoutes, ",")
+ for _, s := range advroutes {
ipp, err := netip.ParsePrefix(s)
if err != nil {
return nil, fmt.Errorf("%q is not a valid IP address or CIDR prefix", s)
diff --git a/net/netx/netx.go b/net/netx/netx.go
index fba6567c4c312..02804bec7682a 100644
--- a/net/netx/netx.go
+++ b/net/netx/netx.go
@@ -17,6 +17,11 @@ import (
// by net/http.Transport.DialContext, etc.
type DialFunc func(ctx context.Context, network, address string) (net.Conn, error)
+// ListenPacketFunc is a function that listens on a network address.
+//
+// It's the type implemented by net.ListenPacket.'
+type ListenPacketFunc func(ctx context.Context, network, address string) (net.PacketConn, error)
+
// Network describes a network that can listen and dial. The two common
// implementations are [RealNetwork], using the net package to use the real
// network, or [memnet.Network], using an in-memory network (typically for testing)
diff --git a/net/packet/capture.go b/net/packet/capture.go
index 630a4b1610c2b..3bfdb8dcee349 100644
--- a/net/packet/capture.go
+++ b/net/packet/capture.go
@@ -16,7 +16,7 @@ import (
// within the lifetime of the function.
type CaptureCallback func(CapturePath, time.Time, []byte, CaptureMeta)
-// CaptureSink is the minimal interface from [tailscale.com/feature/capture]'s
+// CaptureSink is the minimal interface from [github.com/metacubex/tailscale/feature/capture]'s
// Sink type that is needed by the core (magicsock/LocalBackend/wgengine/etc).
// This lets the relativel heavy feature/capture package be optionally linked.
type CaptureSink interface {
diff --git a/net/packet/checksum/checksum.go b/net/packet/checksum/checksum.go
index e6918e7ae1c9f..189dcab3530f4 100644
--- a/net/packet/checksum/checksum.go
+++ b/net/packet/checksum/checksum.go
@@ -8,8 +8,8 @@ import (
"encoding/binary"
"net/netip"
- "tailscale.com/net/packet"
- "tailscale.com/types/ipproto"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/types/ipproto"
)
// UpdateSrcAddr updates the source address in the packet buffer (e.g. during
diff --git a/net/packet/checksum/checksum_test.go b/net/packet/checksum/checksum_test.go
index ab7c783b3e96a..469bc1a0a302d 100644
--- a/net/packet/checksum/checksum_test.go
+++ b/net/packet/checksum/checksum_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,14 +7,14 @@ package checksum
import (
"encoding/binary"
- "math/rand/v2"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"net/netip"
"testing"
- "gvisor.dev/gvisor/pkg/tcpip"
- "gvisor.dev/gvisor/pkg/tcpip/checksum"
- "gvisor.dev/gvisor/pkg/tcpip/header"
- "tailscale.com/net/packet"
+ "github.com/metacubex/gvisor/pkg/tcpip"
+ "github.com/metacubex/gvisor/pkg/tcpip/checksum"
+ "github.com/metacubex/gvisor/pkg/tcpip/header"
+ "github.com/metacubex/tailscale/net/packet"
)
func fullHeaderChecksumV4(b []byte) uint16 {
diff --git a/net/packet/geneve_test.go b/net/packet/geneve_test.go
index 43a64efde0e80..6b95a9b70c36b 100644
--- a/net/packet/geneve_test.go
+++ b/net/packet/geneve_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/packet/icmp4.go b/net/packet/icmp4.go
index 492a0e9dfee98..f823bc745c621 100644
--- a/net/packet/icmp4.go
+++ b/net/packet/icmp4.go
@@ -6,7 +6,7 @@ package packet
import (
"encoding/binary"
- "tailscale.com/types/ipproto"
+ "github.com/metacubex/tailscale/types/ipproto"
)
// icmp4HeaderLength is the size of the ICMPv4 packet header, not
diff --git a/net/packet/icmp6.go b/net/packet/icmp6.go
index a91db53c9e50c..c46552152b51d 100644
--- a/net/packet/icmp6.go
+++ b/net/packet/icmp6.go
@@ -6,7 +6,7 @@ package packet
import (
"encoding/binary"
- "tailscale.com/types/ipproto"
+ "github.com/metacubex/tailscale/types/ipproto"
)
// icmp6HeaderLength is the size of the ICMPv6 packet header, not
diff --git a/net/packet/icmp6_test.go b/net/packet/icmp6_test.go
index 51de86a4a2d01..6413c2d32ee28 100644
--- a/net/packet/icmp6_test.go
+++ b/net/packet/icmp6_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,7 +9,7 @@ import (
"net/netip"
"testing"
- "tailscale.com/types/ipproto"
+ "github.com/metacubex/tailscale/types/ipproto"
)
func TestICMPv6PingResponse(t *testing.T) {
diff --git a/net/packet/ip4.go b/net/packet/ip4.go
index 1964acf1b7900..022cc8ece7ae4 100644
--- a/net/packet/ip4.go
+++ b/net/packet/ip4.go
@@ -8,7 +8,7 @@ import (
"errors"
"net/netip"
- "tailscale.com/types/ipproto"
+ "github.com/metacubex/tailscale/types/ipproto"
)
// ip4HeaderLength is the length of an IPv4 header with no IP options.
diff --git a/net/packet/ip6.go b/net/packet/ip6.go
index eb92f1450f523..d27e3327fa7c5 100644
--- a/net/packet/ip6.go
+++ b/net/packet/ip6.go
@@ -7,7 +7,7 @@ import (
"encoding/binary"
"net/netip"
- "tailscale.com/types/ipproto"
+ "github.com/metacubex/tailscale/types/ipproto"
)
// ip6HeaderLength is the length of an IPv6 header with no IP options.
diff --git a/net/packet/packet.go b/net/packet/packet.go
index b41e0dcd93301..db28cbf6a5044 100644
--- a/net/packet/packet.go
+++ b/net/packet/packet.go
@@ -10,8 +10,8 @@ import (
"net/netip"
"strings"
- "tailscale.com/net/netaddr"
- "tailscale.com/types/ipproto"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/types/ipproto"
)
const unknown = ipproto.Unknown
diff --git a/net/packet/packet_test.go b/net/packet/packet_test.go
index 4dbf88009b20a..be270307d6021 100644
--- a/net/packet/packet_test.go
+++ b/net/packet/packet_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,9 +14,9 @@ import (
"testing"
"unicode"
- "tailscale.com/tstest"
- "tailscale.com/types/ipproto"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/util/must"
)
const (
diff --git a/net/packet/tsmp.go b/net/packet/tsmp.go
index ad1db311a64c2..ee1a4d4210de8 100644
--- a/net/packet/tsmp.go
+++ b/net/packet/tsmp.go
@@ -15,9 +15,9 @@ import (
"fmt"
"net/netip"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/key"
"go4.org/mem"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/key"
)
const minTSMPSize = 7 // the rejected body is 7 bytes
diff --git a/net/packet/tsmp_test.go b/net/packet/tsmp_test.go
index 01bb836d76971..e89f75d6ecfc9 100644
--- a/net/packet/tsmp_test.go
+++ b/net/packet/tsmp_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,12 +8,12 @@ package packet
import (
"bytes"
"encoding/hex"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
"testing"
+ "github.com/metacubex/tailscale/types/key"
"go4.org/mem"
- "tailscale.com/types/key"
)
func TestTailscaleRejectedHeader(t *testing.T) {
diff --git a/net/packet/udp4.go b/net/packet/udp4.go
index a42222f785292..c35603d45a7f3 100644
--- a/net/packet/udp4.go
+++ b/net/packet/udp4.go
@@ -6,7 +6,7 @@ package packet
import (
"encoding/binary"
- "tailscale.com/types/ipproto"
+ "github.com/metacubex/tailscale/types/ipproto"
)
// udpHeaderLength is the size of the UDP packet header, not including
diff --git a/net/packet/udp6.go b/net/packet/udp6.go
index 8d7f380884cbb..545516e64d18c 100644
--- a/net/packet/udp6.go
+++ b/net/packet/udp6.go
@@ -6,7 +6,7 @@ package packet
import (
"encoding/binary"
- "tailscale.com/types/ipproto"
+ "github.com/metacubex/tailscale/types/ipproto"
)
// UDP6Header is an IPv6+UDP header.
diff --git a/net/ping/ping.go b/net/ping/ping.go
index 42d381c7311cb..55a66d8dcfd0d 100644
--- a/net/ping/ping.go
+++ b/net/ping/ping.go
@@ -20,12 +20,13 @@ import (
"sync/atomic"
"time"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/mak"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
- "tailscale.com/syncs"
- "tailscale.com/types/logger"
- "tailscale.com/util/mak"
)
const (
@@ -75,7 +76,7 @@ type Pinger struct {
Verbose bool // verbose logging
Logf logger.Logf // optional logging function; if nil, logs to the standard logger
- lp ListenPacketer
+ lp netx.ListenPacketFunc
// closed guards against send incrementing the waitgroup concurrently with close.
closed atomic.Bool
@@ -95,7 +96,7 @@ type Pinger struct {
// New creates a new Pinger. The Context provided will be used to create
// network listeners, and to set an absolute deadline (if any) on the net.Conn
-func New(ctx context.Context, logf logger.Logf, lp ListenPacketer) *Pinger {
+func New(ctx context.Context, logf logger.Logf, lp netx.ListenPacketFunc) *Pinger {
var id [2]byte
if _, err := io.ReadFull(rand.Reader, id[:]); err != nil {
panic("net/ping: New:" + err.Error())
@@ -124,7 +125,7 @@ func (p *Pinger) mkconn(ctx context.Context, typ, addr string) (net.PacketConn,
// Darwin/iOS, strips the IPv4 header on read via IP_STRIPHDR.
c, err = icmp.ListenPacket(typ, addr)
} else {
- c, err = p.lp.ListenPacket(ctx, typ, addr)
+ c, err = p.lp(ctx, typ, addr)
}
if err != nil {
return nil, err
diff --git a/net/ping/ping_test.go b/net/ping/ping_test.go
index 9fe12de7e9a54..917855c1a24b2 100644
--- a/net/ping/ping_test.go
+++ b/net/ping/ping_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,11 +13,11 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/util/mak"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
- "tailscale.com/tstest"
- "tailscale.com/util/mak"
)
var (
diff --git a/net/portmapper/igd_test.go b/net/portmapper/igd_test.go
index 9426790639563..ca16e42161638 100644
--- a/net/portmapper/igd_test.go
+++ b/net/portmapper/igd_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -14,13 +16,13 @@ import (
"sync/atomic"
"testing"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/netmon"
- "tailscale.com/syncs"
- "tailscale.com/tstest"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/testenv"
)
// TestIGD is an IGD (Internet Gateway Device) for testing. It supports fake
diff --git a/net/portmapper/pcp.go b/net/portmapper/pcp.go
index 0332295b8cfa0..844854d733cd3 100644
--- a/net/portmapper/pcp.go
+++ b/net/portmapper/pcp.go
@@ -17,7 +17,7 @@ import (
// https://www.rfc-editor.org/rfc/pdfrfc/rfc6887.txt.pdf
// https://tools.ietf.org/html/rfc6887
-//go:generate go run tailscale.com/cmd/addlicense -file pcpresultcode_string.go go run golang.org/x/tools/cmd/stringer -type=pcpResultCode -trimprefix=pcpCode
+//go:generate go run github.com/metacubex/tailscale/cmd/addlicense -file pcpresultcode_string.go go run golang.org/x/tools/cmd/stringer -type=pcpResultCode -trimprefix=pcpCode
type pcpResultCode uint8
diff --git a/net/portmapper/pcp_test.go b/net/portmapper/pcp_test.go
index ef2621f7dc401..68988cdb71ae7 100644
--- a/net/portmapper/pcp_test.go
+++ b/net/portmapper/pcp_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,7 +10,7 @@ import (
"net/netip"
"testing"
- "tailscale.com/net/netaddr"
+ "github.com/metacubex/tailscale/net/netaddr"
)
var examplePCPMapResponse = []byte{2, 129, 0, 0, 0, 0, 28, 32, 0, 2, 155, 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 112, 9, 24, 241, 208, 251, 45, 157, 76, 10, 188, 17, 0, 0, 0, 4, 210, 4, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 135, 180, 175, 246}
diff --git a/net/portmapper/portmapper.go b/net/portmapper/portmapper.go
index 37d7730c51f0d..907fc8fe34bbe 100644
--- a/net/portmapper/portmapper.go
+++ b/net/portmapper/portmapper.go
@@ -9,28 +9,28 @@ import (
"context"
"encoding/binary"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net"
"net/http"
"net/netip"
- "slices"
"sync/atomic"
"time"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/neterror"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/net/portmapper/portmappertype"
+ "github.com/metacubex/tailscale/net/sockstats"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/nettype"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/eventbus"
"go4.org/mem"
- "tailscale.com/envknob"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/neterror"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netns"
- "tailscale.com/net/portmapper/portmappertype"
- "tailscale.com/net/sockstats"
- "tailscale.com/syncs"
- "tailscale.com/types/logger"
- "tailscale.com/types/nettype"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/eventbus"
)
var (
@@ -783,7 +783,7 @@ func (c *Client) createOrGetMapping(ctx context.Context) (mapping mapping, exter
}
}
-//go:generate go run tailscale.com/cmd/addlicense -file pmpresultcode_string.go go run golang.org/x/tools/cmd/stringer -type=pmpResultCode -trimprefix=pmpCode
+//go:generate go run github.com/metacubex/tailscale/cmd/addlicense -file pmpresultcode_string.go go run golang.org/x/tools/cmd/stringer -type=pmpResultCode -trimprefix=pmpCode
type pmpResultCode uint16
diff --git a/net/portmapper/portmapper_test.go b/net/portmapper/portmapper_test.go
index beb14cb8074eb..ba1e6dbfda0a6 100644
--- a/net/portmapper/portmapper_test.go
+++ b/net/portmapper/portmapper_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,8 +13,8 @@ import (
"testing"
"time"
- "tailscale.com/net/portmapper/portmappertype"
- "tailscale.com/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/net/portmapper/portmappertype"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
)
func TestCreateOrGetMapping(t *testing.T) {
diff --git a/net/portmapper/portmappertype/portmappertype.go b/net/portmapper/portmappertype/portmappertype.go
index 3b756e0ed04b2..5142cf389b418 100644
--- a/net/portmapper/portmappertype/portmappertype.go
+++ b/net/portmapper/portmappertype/portmappertype.go
@@ -11,10 +11,10 @@ import (
"net/netip"
"time"
- "tailscale.com/feature"
- "tailscale.com/net/netmon"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
)
// HookNewPortMapper is a hook to install the portmapper creation function.
diff --git a/net/portmapper/select_test.go b/net/portmapper/select_test.go
index b7370c24139f1..8bb3ff28208b7 100644
--- a/net/portmapper/select_test.go
+++ b/net/portmapper/select_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/portmapper/upnp.go b/net/portmapper/upnp.go
index e3971a2ae0f97..a5add42d6a292 100644
--- a/net/portmapper/upnp.go
+++ b/net/portmapper/upnp.go
@@ -10,17 +10,17 @@ package portmapper
import (
"bufio"
"bytes"
- "cmp"
"context"
"encoding/xml"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ "github.com/metacubex/tailscale/util/go120/randv2"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
- "math/rand/v2"
"net"
"net/http"
"net/netip"
"net/url"
- "slices"
"strings"
"sync/atomic"
"time"
@@ -28,11 +28,11 @@ import (
"github.com/huin/goupnp"
"github.com/huin/goupnp/dcps/internetgateway2"
"github.com/huin/goupnp/soap"
- "tailscale.com/envknob"
- "tailscale.com/net/netns"
- "tailscale.com/types/logger"
- "tailscale.com/util/ctxkey"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/ctxkey"
+ "github.com/metacubex/tailscale/util/mak"
)
// upnpHTTPClientKey is a context key for storing an HTTP client to use
diff --git a/net/portmapper/upnp_test.go b/net/portmapper/upnp_test.go
index 15b03517708e4..2d6a85823e0ff 100644
--- a/net/portmapper/upnp_test.go
+++ b/net/portmapper/upnp_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,6 +9,7 @@ import (
"context"
"encoding/xml"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net"
"net/http"
@@ -14,12 +17,11 @@ import (
"net/netip"
"reflect"
"regexp"
- "slices"
"sync/atomic"
"testing"
- "tailscale.com/net/portmapper/portmappertype"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/net/portmapper/portmappertype"
+ "github.com/metacubex/tailscale/tstest"
)
// Google Wifi
diff --git a/net/porttrack/porttrack.go b/net/porttrack/porttrack.go
index f71154f78e631..ab273e8f3747d 100644
--- a/net/porttrack/porttrack.go
+++ b/net/porttrack/porttrack.go
@@ -28,7 +28,7 @@ import (
"strings"
"sync"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/util/testenv"
)
const magicPrefix = "testport-report-"
diff --git a/net/porttrack/porttrack_test.go b/net/porttrack/porttrack_test.go
index 06412d87554fc..c9aa8bfe81cb7 100644
--- a/net/porttrack/porttrack_test.go
+++ b/net/porttrack/porttrack_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/proxymux/mux_test.go b/net/proxymux/mux_test.go
index 6e84e57d8ef80..e07fe7c83f3df 100644
--- a/net/proxymux/mux_test.go
+++ b/net/proxymux/mux_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,7 +13,7 @@ import (
"net/url"
"testing"
- "tailscale.com/net/socks5"
+ "github.com/metacubex/tailscale/net/socks5"
)
func TestSplitSOCKSAndHTTP(t *testing.T) {
diff --git a/net/routetable/routetable.go b/net/routetable/routetable.go
index bfa62af7b3ce3..c67bf26cf5add 100644
--- a/net/routetable/routetable.go
+++ b/net/routetable/routetable.go
@@ -11,7 +11,7 @@ import (
"net/netip"
"strconv"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
var (
diff --git a/net/routetable/routetable_bsd.go b/net/routetable/routetable_bsd.go
index f5306d8942a02..577f0519b7f2b 100644
--- a/net/routetable/routetable_bsd.go
+++ b/net/routetable/routetable_bsd.go
@@ -15,10 +15,10 @@ import (
"strings"
"syscall"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/types/logger"
"golang.org/x/net/route"
"golang.org/x/sys/unix"
- "tailscale.com/net/netmon"
- "tailscale.com/types/logger"
)
type RouteEntryBSD struct {
diff --git a/net/routetable/routetable_bsd_test.go b/net/routetable/routetable_bsd_test.go
index df515c5788681..827705e9c5fca 100644
--- a/net/routetable/routetable_bsd_test.go
+++ b/net/routetable/routetable_bsd_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build darwin || freebsd
-
package routetable
import (
@@ -13,9 +13,9 @@ import (
"runtime"
"testing"
+ "github.com/metacubex/tailscale/net/netmon"
"golang.org/x/net/route"
"golang.org/x/sys/unix"
- "tailscale.com/net/netmon"
)
func TestRouteEntryFromMsg(t *testing.T) {
diff --git a/net/routetable/routetable_linux.go b/net/routetable/routetable_linux.go
index 479aa8fd8f0af..419d8618f95db 100644
--- a/net/routetable/routetable_linux.go
+++ b/net/routetable/routetable_linux.go
@@ -11,11 +11,11 @@ import (
"net/netip"
"strconv"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/types/logger"
"github.com/tailscale/netlink"
"golang.org/x/sys/unix"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/netmon"
- "tailscale.com/types/logger"
)
// RouteEntryLinux is the structure that makes up the Sys field of the
diff --git a/net/routetable/routetable_linux_test.go b/net/routetable/routetable_linux_test.go
index 4d03b7f9d5466..a337272cae460 100644
--- a/net/routetable/routetable_linux_test.go
+++ b/net/routetable/routetable_linux_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux
-
package routetable
import (
diff --git a/net/sockopts/sockopts.go b/net/sockopts/sockopts.go
index aa10d977f6468..8df5395f348c4 100644
--- a/net/sockopts/sockopts.go
+++ b/net/sockopts/sockopts.go
@@ -8,7 +8,7 @@ import (
"net"
"runtime"
- "tailscale.com/types/nettype"
+ "github.com/metacubex/tailscale/types/nettype"
)
// BufferDirection represents either the read/receive or write/send direction
diff --git a/net/sockopts/sockopts_default.go b/net/sockopts/sockopts_default.go
index 6b728d34c6a42..397672bf98b74 100644
--- a/net/sockopts/sockopts_default.go
+++ b/net/sockopts/sockopts_default.go
@@ -6,7 +6,7 @@
package sockopts
import (
- "tailscale.com/types/nettype"
+ "github.com/metacubex/tailscale/types/nettype"
)
// SetBufferSize sets pconn's buffer to size for direction. size may be silently
diff --git a/net/sockopts/sockopts_linux.go b/net/sockopts/sockopts_linux.go
index 216c589225d39..a7df25409525f 100644
--- a/net/sockopts/sockopts_linux.go
+++ b/net/sockopts/sockopts_linux.go
@@ -9,7 +9,7 @@ import (
"net"
"syscall"
- "tailscale.com/types/nettype"
+ "github.com/metacubex/tailscale/types/nettype"
)
// SetBufferSize sets pconn's buffer to size for direction. It attempts
diff --git a/net/sockopts/sockopts_notwindows.go b/net/sockopts/sockopts_notwindows.go
index 880860a58036f..a73f52c2b05e9 100644
--- a/net/sockopts/sockopts_notwindows.go
+++ b/net/sockopts/sockopts_notwindows.go
@@ -6,7 +6,7 @@
package sockopts
import (
- "tailscale.com/types/nettype"
+ "github.com/metacubex/tailscale/types/nettype"
)
// SetICMPErrImmunity is no-op on non-Windows.
diff --git a/net/sockopts/sockopts_unix_test.go b/net/sockopts/sockopts_unix_test.go
index d474326a14df8..56084d9824c99 100644
--- a/net/sockopts/sockopts_unix_test.go
+++ b/net/sockopts/sockopts_unix_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build unix
-
package sockopts
import (
@@ -10,7 +10,7 @@ import (
"syscall"
"testing"
- "tailscale.com/types/nettype"
+ "github.com/metacubex/tailscale/types/nettype"
)
func TestSetBufferSize(t *testing.T) {
diff --git a/net/sockopts/sockopts_windows.go b/net/sockopts/sockopts_windows.go
index 9533fd2a4ca9f..b7325bdcd8922 100644
--- a/net/sockopts/sockopts_windows.go
+++ b/net/sockopts/sockopts_windows.go
@@ -10,8 +10,8 @@ import (
"net"
"unsafe"
+ "github.com/metacubex/tailscale/types/nettype"
"golang.org/x/sys/windows"
- "tailscale.com/types/nettype"
)
// SetICMPErrImmunity sets socket options on pconn to prevent ICMP reception,
diff --git a/net/socks5/socks5.go b/net/socks5/socks5.go
index f67dc1ecc202a..f28ef29eb7e3b 100644
--- a/net/socks5/socks5.go
+++ b/net/socks5/socks5.go
@@ -18,14 +18,14 @@ import (
"encoding/binary"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
"net"
- "slices"
"strconv"
"time"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
// Authentication METHODs described in RFC 1928, section 3.
diff --git a/net/socks5/socks5_test.go b/net/socks5/socks5_test.go
index 84ef4be7bc651..cc2bb97ee0964 100644
--- a/net/socks5/socks5_test.go
+++ b/net/socks5/socks5_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/sockstats/sockstats.go b/net/sockstats/sockstats.go
index 14a58d19d800d..5bc4462b886ab 100644
--- a/net/sockstats/sockstats.go
+++ b/net/sockstats/sockstats.go
@@ -11,8 +11,8 @@ package sockstats
import (
"context"
- "tailscale.com/net/netmon"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/types/logger"
)
// SockStats contains statistics for sockets instrumented with the
diff --git a/net/sockstats/sockstats_noop.go b/net/sockstats/sockstats_noop.go
index b586a04cbee29..2a60b825d2e20 100644
--- a/net/sockstats/sockstats_noop.go
+++ b/net/sockstats/sockstats_noop.go
@@ -8,8 +8,8 @@ package sockstats
import (
"context"
- "tailscale.com/net/netmon"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/types/logger"
)
const IsAvailable = false
diff --git a/net/sockstats/sockstats_tsgo.go b/net/sockstats/sockstats_tsgo.go
index 46ac75c990d48..101e151595925 100644
--- a/net/sockstats/sockstats_tsgo.go
+++ b/net/sockstats/sockstats_tsgo.go
@@ -14,11 +14,11 @@ import (
"syscall"
"time"
- "tailscale.com/net/netmon"
- "tailscale.com/syncs"
- "tailscale.com/types/logger"
- "tailscale.com/util/clientmetric"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/version"
)
const IsAvailable = true
diff --git a/net/sockstats/sockstats_tsgo_test.go b/net/sockstats/sockstats_tsgo_test.go
index b06ffa8946c44..037f692d31f9e 100644
--- a/net/sockstats/sockstats_tsgo_test.go
+++ b/net/sockstats/sockstats_tsgo_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build tailscale_go && (darwin || ios || android || ts_enable_sockstats)
-
package sockstats
import (
diff --git a/net/speedtest/speedtest_test.go b/net/speedtest/speedtest_test.go
index eb851eb26e332..97008a2fd385f 100644
--- a/net/speedtest/speedtest_test.go
+++ b/net/speedtest/speedtest_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,7 +11,7 @@ import (
"testing"
"time"
- "tailscale.com/cmd/testwrapper/flakytest"
+ "github.com/metacubex/tailscale/cmd/testwrapper/flakytest"
)
var manualTest = flag.Bool("do-speedtest", false, "if true, run the speedtest TestDownload test. Otherwise skip it because it's slow and flaky; see https://github.com/tailscale/tailscale/issues/17338")
diff --git a/net/stun/stun_test.go b/net/stun/stun_test.go
index c26a6a5c7320e..9d421dcc82d14 100644
--- a/net/stun/stun_test.go
+++ b/net/stun/stun_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,8 +12,8 @@ import (
"net/netip"
"testing"
- "tailscale.com/net/stun"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/net/stun"
+ "github.com/metacubex/tailscale/util/must"
)
// TODO(bradfitz): fuzz this.
diff --git a/net/stun/stuntest/stuntest.go b/net/stun/stuntest/stuntest.go
index 0d3988ce800a9..2c7096cc34f8b 100644
--- a/net/stun/stuntest/stuntest.go
+++ b/net/stun/stuntest/stuntest.go
@@ -14,10 +14,10 @@ import (
"sync"
"testing"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/stun"
- "tailscale.com/tailcfg"
- "tailscale.com/types/nettype"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/stun"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/nettype"
)
type stunStats struct {
diff --git a/net/stunserver/stunserver.go b/net/stunserver/stunserver.go
index 97df8cb4d79e9..3a44651e5e45c 100644
--- a/net/stunserver/stunserver.go
+++ b/net/stunserver/stunserver.go
@@ -14,8 +14,8 @@ import (
"net/netip"
"time"
- "tailscale.com/metrics"
- "tailscale.com/net/stun"
+ "github.com/metacubex/tailscale/metrics"
+ "github.com/metacubex/tailscale/net/stun"
)
var (
diff --git a/net/stunserver/stunserver_test.go b/net/stunserver/stunserver_test.go
index f9efe21f30494..05f52ea24bed1 100644
--- a/net/stunserver/stunserver_test.go
+++ b/net/stunserver/stunserver_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,8 +12,8 @@ import (
"testing"
"time"
- "tailscale.com/net/stun"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/net/stun"
+ "github.com/metacubex/tailscale/util/must"
)
func TestSTUNServer(t *testing.T) {
diff --git a/net/tcpinfo/tcpinfo_test.go b/net/tcpinfo/tcpinfo_test.go
index 6baac934a00f0..05f6ea0edd3dd 100644
--- a/net/tcpinfo/tcpinfo_test.go
+++ b/net/tcpinfo/tcpinfo_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/tlsdial/blockblame/blockblame.go b/net/tlsdial/blockblame/blockblame.go
index f2d7db27c1a5e..97fc19eec0625 100644
--- a/net/tlsdial/blockblame/blockblame.go
+++ b/net/tlsdial/blockblame/blockblame.go
@@ -11,7 +11,7 @@ import (
"strings"
"sync"
- "tailscale.com/feature/buildfeatures"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
)
// VerifyCertificate checks if the given certificate c is issued by a firewall manufacturer
diff --git a/net/tlsdial/blockblame/blockblame_test.go b/net/tlsdial/blockblame/blockblame_test.go
index 3d08bf811601c..001532ae94500 100644
--- a/net/tlsdial/blockblame/blockblame_test.go
+++ b/net/tlsdial/blockblame/blockblame_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/tlsdial/deps_test.go b/net/tlsdial/deps_test.go
index 3600af537cd85..e76d920a727b7 100644
--- a/net/tlsdial/deps_test.go
+++ b/net/tlsdial/deps_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build for_go_mod_tidy_only
-
package tlsdial
import _ "filippo.io/mkcert"
diff --git a/net/tlsdial/tlsdial.go b/net/tlsdial/tlsdial.go
index 417c925b77161..7b4690bec8897 100644
--- a/net/tlsdial/tlsdial.go
+++ b/net/tlsdial/tlsdial.go
@@ -26,13 +26,14 @@ import (
"sync/atomic"
"time"
- "tailscale.com/derp/derpconst"
- "tailscale.com/envknob"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/health"
- "tailscale.com/hostinfo"
- "tailscale.com/net/bakedroots"
- "tailscale.com/net/tlsdial/blockblame"
+ "github.com/metacubex/tailscale/derp/derpconst"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/net/bakedroots"
+ "github.com/metacubex/tailscale/net/tlsdial/blockblame"
+ "github.com/metacubex/tailscale/types/logger"
)
var counterFallbackOK int32 // atomic
@@ -67,6 +68,10 @@ var mitmBlockWarnable = health.Register(&health.Warnable{
//
// If ht is non-nil, it's used to report health errors.
func Config(ht *health.Tracker, base *tls.Config) *tls.Config {
+ return ConfigWithLogf(ht, base, nil)
+}
+
+func ConfigWithLogf(ht *health.Tracker, base *tls.Config, logf logger.Logf) *tls.Config {
var extraRoots *x509.CertPool
if base != nil {
extraRoots = base.RootCAs
@@ -138,7 +143,7 @@ func Config(ht *health.Tracker, base *tls.Config) *tls.Config {
// Show a dedicated warning.
m, ok := blockblame.VerifyCertificate(cert)
if ok {
- log.Printf("tlsdial: server cert seen while dialing %q looks like %q equipment (could be blocking Tailscale)", dialedHost, m.Name)
+ tlsLogf(logf, "tlsdial: server cert seen while dialing %q looks like %q equipment (could be blocking Tailscale)", dialedHost, m.Name)
ht.SetUnhealthy(mitmBlockWarnable, health.Args{"manufacturer": m.Name})
} else {
ht.SetHealthy(mitmBlockWarnable)
@@ -157,7 +162,7 @@ func Config(ht *health.Tracker, base *tls.Config) *tls.Config {
ht.SetTLSConnectionError(cs.ServerName, nil)
if selfSignedIssuer != "" {
// Log the self-signed issuer, but don't treat it as an error.
- log.Printf("tlsdial: warning: server cert for %q passed x509 validation but is self-signed by %q", dialedHost, selfSignedIssuer)
+ tlsLogf(logf, "tlsdial: warning: server cert for %q passed x509 validation but is self-signed by %q", dialedHost, selfSignedIssuer)
}
}
}()
@@ -174,7 +179,7 @@ func Config(ht *health.Tracker, base *tls.Config) *tls.Config {
}
_, errSys := cs.PeerCertificates[0].Verify(opts)
if debug() {
- log.Printf("tlsdial(sys %q): %v", dialedHost, errSys)
+ tlsLogf(logf, "tlsdial(sys %q): %v", dialedHost, errSys)
}
if errSys == nil && !debug() {
return nil
@@ -186,7 +191,7 @@ func Config(ht *health.Tracker, base *tls.Config) *tls.Config {
opts.Roots = extraRoots
_, errExtra := cs.PeerCertificates[0].Verify(opts)
if debug() {
- log.Printf("tlsdial(extra %q): %v", dialedHost, errExtra)
+ tlsLogf(logf, "tlsdial(extra %q): %v", dialedHost, errExtra)
}
if errExtra == nil {
atomic.AddInt32(&counterFallbackOK, 1)
@@ -204,14 +209,14 @@ func Config(ht *health.Tracker, base *tls.Config) *tls.Config {
opts.Roots = bakedroots.Get()
_, bakedErr := cs.PeerCertificates[0].Verify(opts)
if debug() {
- log.Printf("tlsdial(bake %q): %v", dialedHost, bakedErr)
+ tlsLogf(logf, "tlsdial(bake %q): %v", dialedHost, bakedErr)
} else if bakedErr != nil {
if _, loaded := tlsdialWarningPrinted.LoadOrStore(dialedHost, true); !loaded {
if errSys != nil {
if extraRoots != nil {
- log.Printf("tlsdial: error: server cert for %q failed system roots, extra roots & Let's Encrypt root validation", dialedHost)
+ tlsLogf(logf, "tlsdial: error: server cert for %q failed system roots, extra roots & Let's Encrypt root validation", dialedHost)
} else {
- log.Printf("tlsdial: error: server cert for %q failed both system roots & Let's Encrypt root validation", dialedHost)
+ tlsLogf(logf, "tlsdial: error: server cert for %q failed both system roots & Let's Encrypt root validation", dialedHost)
}
}
}
@@ -228,6 +233,14 @@ func Config(ht *health.Tracker, base *tls.Config) *tls.Config {
return conf
}
+func tlsLogf(logf logger.Logf, format string, args ...any) {
+ if logf != nil {
+ logf(format, args...)
+ return
+ }
+ log.Printf(format, args...)
+}
+
func certIsSelfSigned(cert *x509.Certificate) bool {
// A certificate is determined to be self-signed if the certificate's
// subject is the same as its issuer.
diff --git a/net/tlsdial/tlsdial_test.go b/net/tlsdial/tlsdial_test.go
index 9ef0f76884c53..8c14713d83f69 100644
--- a/net/tlsdial/tlsdial_test.go
+++ b/net/tlsdial/tlsdial_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -14,9 +16,9 @@ import (
"sync/atomic"
"testing"
- "tailscale.com/health"
- "tailscale.com/net/bakedroots"
- "tailscale.com/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/bakedroots"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
)
func TestFallbackRootWorks(t *testing.T) {
diff --git a/net/tsaddr/tsaddr.go b/net/tsaddr/tsaddr.go
index 1eac9eb77cfde..22ac642c2deb0 100644
--- a/net/tsaddr/tsaddr.go
+++ b/net/tsaddr/tsaddr.go
@@ -7,13 +7,13 @@ package tsaddr
import (
"encoding/binary"
"errors"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
"sync"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/types/views"
"go4.org/netipx"
- "tailscale.com/net/netaddr"
- "tailscale.com/types/views"
)
// ChromeOSVMRange returns the subset of the CGNAT IPv4 range used by
@@ -28,7 +28,7 @@ var chromeOSRange oncePrefix
// CGNATRange returns the Carrier Grade NAT address range that
// is the superset range that Tailscale assigns out of.
-// See https://tailscale.com/s/cgnat
+// See https://github.com/metacubex/tailscale/s/cgnat
// Note that Tailscale does not assign out of the ChromeOSVMRange.
func CGNATRange() netip.Prefix {
cgnatRange.Do(func() { mustPrefix(&cgnatRange.v, "100.64.0.0/10") })
@@ -186,36 +186,43 @@ func PrefixIs6(p netip.Prefix) bool { return p.Addr().Is6() }
// IPv6 /0 route.
func ContainsExitRoutes(rr views.Slice[netip.Prefix]) bool {
var v4, v6 bool
- for _, r := range rr.All() {
+ rr.All()(func(_ int, r netip.Prefix) bool {
if r == allIPv4 {
v4 = true
} else if r == allIPv6 {
v6 = true
}
- }
+ return true
+ })
return v4 && v6
}
// ContainsExitRoute reports whether rr contains at least one of IPv4 or
// IPv6 /0 (exit) routes.
func ContainsExitRoute(rr views.Slice[netip.Prefix]) bool {
- for _, r := range rr.All() {
+ found := false
+ rr.All()(func(_ int, r netip.Prefix) bool {
if r.Bits() == 0 {
- return true
+ found = true
+ return false
}
- }
- return false
+ return true
+ })
+ return found
}
// ContainsNonExitSubnetRoutes reports whether v contains Subnet
// Routes other than ExitNode Routes.
func ContainsNonExitSubnetRoutes(rr views.Slice[netip.Prefix]) bool {
- for _, r := range rr.All() {
+ found := false
+ rr.All()(func(_ int, r netip.Prefix) bool {
if r.Bits() != 0 {
- return true
+ found = true
+ return false
}
- }
- return false
+ return true
+ })
+ return found
}
// WithoutExitRoutes returns rr unchanged if it has only 1 or 0 /0
@@ -226,11 +233,12 @@ func WithoutExitRoutes(rr views.Slice[netip.Prefix]) views.Slice[netip.Prefix] {
return rr
}
var out []netip.Prefix
- for _, r := range rr.All() {
+ rr.All()(func(_ int, r netip.Prefix) bool {
if r.Bits() > 0 {
out = append(out, r)
}
- }
+ return true
+ })
return views.SliceOf(out)
}
@@ -242,11 +250,12 @@ func WithoutExitRoute(rr views.Slice[netip.Prefix]) views.Slice[netip.Prefix] {
return rr
}
var out []netip.Prefix
- for _, r := range rr.All() {
+ rr.All()(func(_ int, r netip.Prefix) bool {
if r.Bits() > 0 {
out = append(out, r)
}
- }
+ return true
+ })
return views.SliceOf(out)
}
@@ -278,7 +287,7 @@ func SortPrefixes(p []netip.Prefix) {
// in that match f.
func FilterPrefixesCopy(in views.Slice[netip.Prefix], f func(netip.Prefix) bool) []netip.Prefix {
var out []netip.Prefix
- for i := range in.Len() {
+ for i := 0; i < in.Len(); i++ {
if v := in.At(i); f(v) {
out = append(out, v)
}
diff --git a/net/tsaddr/tsaddr_test.go b/net/tsaddr/tsaddr_test.go
index ac5a07fff94f5..d3982bd1dc778 100644
--- a/net/tsaddr/tsaddr_test.go
+++ b/net/tsaddr/tsaddr_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,8 +11,8 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/net/netaddr"
- "tailscale.com/types/views"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/types/views"
)
func TestInCrostiniRange(t *testing.T) {
diff --git a/net/tsdial/dnsmap.go b/net/tsdial/dnsmap.go
index d7204463f66ed..5fd77c924fd71 100644
--- a/net/tsdial/dnsmap.go
+++ b/net/tsdial/dnsmap.go
@@ -12,8 +12,8 @@ import (
"strconv"
"strings"
- "tailscale.com/types/netmap"
- "tailscale.com/util/dnsname"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/dnsname"
)
// dnsMap maps MagicDNS names (both base + FQDN) to their first IP.
@@ -42,27 +42,28 @@ func dnsMapFromNetworkMap(nm *netmap.NetworkMap) dnsMap {
if dnsname.HasSuffix(name, suffix) {
ret[canonMapKey(dnsname.TrimSuffix(name, suffix))] = ip
}
- for _, p := range addrs.All() {
+ addrs.All()(func(_ int, p netip.Prefix) bool {
if p.Addr().Is4() {
have4 = true
}
- }
+ return true
+ })
}
for _, p := range nm.Peers {
if p.Name() == "" {
continue
}
- for _, pfx := range p.Addresses().All() {
+ p.Addresses().All()(func(_ int, pfx netip.Prefix) bool {
ip := pfx.Addr()
if ip.Is4() && !have4 {
- continue
+ return true
}
ret[canonMapKey(p.Name())] = ip
if dnsname.HasSuffix(p.Name(), suffix) {
ret[canonMapKey(dnsname.TrimSuffix(p.Name(), suffix))] = ip
}
- break
- }
+ return false
+ })
}
for _, rec := range nm.DNS.ExtraRecords {
if rec.Type != "" {
diff --git a/net/tsdial/dnsmap_test.go b/net/tsdial/dnsmap_test.go
index b2a50fa0c4549..a950da079f4c7 100644
--- a/net/tsdial/dnsmap_test.go
+++ b/net/tsdial/dnsmap_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,8 +10,8 @@ import (
"reflect"
"testing"
- "tailscale.com/tailcfg"
- "tailscale.com/types/netmap"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/netmap"
)
func nodeViews(v []*tailcfg.Node) []tailcfg.NodeView {
diff --git a/net/tsdial/dohclient.go b/net/tsdial/dohclient.go
index 59b0da04d25f4..0dd57097dd8fc 100644
--- a/net/tsdial/dohclient.go
+++ b/net/tsdial/dohclient.go
@@ -13,7 +13,7 @@ import (
"net/http"
"time"
- "tailscale.com/net/dnscache"
+ "github.com/metacubex/tailscale/net/dnscache"
)
// dohConn is a net.PacketConn suitable for returning from
diff --git a/net/tsdial/dohclient_test.go b/net/tsdial/dohclient_test.go
index 63e5dbd997826..23ba9983f8340 100644
--- a/net/tsdial/dohclient_test.go
+++ b/net/tsdial/dohclient_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/tsdial/peerapi_macios_ext.go b/net/tsdial/peerapi_macios_ext.go
index fa40feef04524..4fc062368c3e0 100644
--- a/net/tsdial/peerapi_macios_ext.go
+++ b/net/tsdial/peerapi_macios_ext.go
@@ -14,7 +14,7 @@ import (
"net"
"syscall"
- "tailscale.com/net/netns"
+ "github.com/metacubex/tailscale/net/netns"
)
func init() {
diff --git a/net/tsdial/tsdial.go b/net/tsdial/tsdial.go
index ca08810a3da0e..484105addae23 100644
--- a/net/tsdial/tsdial.go
+++ b/net/tsdial/tsdial.go
@@ -18,23 +18,23 @@ import (
"syscall"
"time"
- "github.com/gaissmai/bart"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/net/dnscache"
- "tailscale.com/net/netknob"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netns"
- "tailscale.com/net/netx"
- "tailscale.com/net/tsaddr"
- "tailscale.com/syncs"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/mak"
- "tailscale.com/util/testenv"
- "tailscale.com/version"
+ "github.com/metacubex/bart"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/net/dnscache"
+ "github.com/metacubex/tailscale/net/netknob"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/testenv"
+ "github.com/metacubex/tailscale/version"
)
// NewDialer returns a new Dialer that can dial out of tailscaled.
@@ -75,6 +75,18 @@ type Dialer struct {
// If nil, it's not used.
NetstackDialUDP func(context.Context, netip.AddrPort) (net.Conn, error)
+ // SystemDialer optionally specifies how tsnet dials non-Tailscale
+ // infrastructure such as control, DERP, STUN, and logtail.
+ SystemDialer netx.DialFunc
+
+ // SystemPacketListener optionally specifies how tsnet opens UDP sockets
+ // for non-Tailscale infrastructure such as STUN and peer paths.
+ SystemPacketListener netx.ListenPacketFunc
+
+ // LookupHook optionally specifies how tsnet resolves non-Tailscale
+ // infrastructure hostnames such as control and DERP.
+ LookupHook dnscache.LookupHookFunc
+
peerClientOnce sync.Once
peerClient *http.Client
@@ -382,8 +394,8 @@ func (d *Dialer) userDialResolve(ctx context.Context, network, addr string) (net
return netip.AddrPort{}, err
}
- var r net.Resolver
if buildfeatures.HasUseExitNode && buildfeatures.HasPeerAPIClient && exitDNSDoH != "" {
+ var r net.Resolver
r.PreferGo = true
r.Dial = func(ctx context.Context, network, address string) (net.Conn, error) {
return &dohConn{
@@ -393,17 +405,43 @@ func (d *Dialer) userDialResolve(ctx context.Context, network, addr string) (net
dnsCache: d.dnsCache,
}, nil
}
+
+ ips, err := r.LookupIP(ctx, ipNetOfNetwork(network), host)
+ if err != nil {
+ return netip.AddrPort{}, err
+ }
+ if len(ips) == 0 {
+ return netip.AddrPort{}, fmt.Errorf("DNS lookup returned no results for %q", host)
+ }
+ ip, _ := netip.AddrFromSlice(ips[0])
+ return netip.AddrPortFrom(ip.Unmap(), port), nil
}
- ips, err := r.LookupIP(ctx, ipNetOfNetwork(network), host)
- if err != nil {
- return netip.AddrPort{}, err
+ if ip, err := netip.ParseAddr(host); err == nil {
+ return netip.AddrPortFrom(ip.Unmap(), port), nil
}
- if len(ips) == 0 {
- return netip.AddrPort{}, fmt.Errorf("DNS lookup returned no results for %q", host)
+ var ips []netip.Addr
+ if d.LookupHook != nil {
+ ips, err = d.LookupHook(ctx, host)
+ if err != nil {
+ return netip.AddrPort{}, err
+ }
}
- ip, _ := netip.AddrFromSlice(ips[0])
- return netip.AddrPortFrom(ip.Unmap(), port), nil
+ for _, ip := range ips {
+ ip = ip.Unmap()
+ if strings.HasSuffix(network, "4") {
+ if ip.Is4() {
+ return netip.AddrPortFrom(ip, port), nil
+ }
+ } else if strings.HasSuffix(network, "6") {
+ if ip.Is6() {
+ return netip.AddrPortFrom(ip, port), nil
+ }
+ } else {
+ return netip.AddrPortFrom(ip, port), nil
+ }
+ }
+ return netip.AddrPort{}, fmt.Errorf("DNS lookup returned no results for %q", host)
}
// ipNetOfNetwork returns "ip", "ip4", or "ip6" corresponding
@@ -425,6 +463,32 @@ func (d *Dialer) logf(format string, args ...any) {
}
}
+// SystemPacketListen returns a net.PacketConn that listens on the
+// provided network address. It prefers going over the default interface
+// and closes existing connections if the default interface changes. It is
+// used to listen for DERP packets.
+func (d *Dialer) SystemPacketListen(ctx context.Context, network, address string) (net.PacketConn, error) {
+ d.mu.Lock()
+ if d.netMon == nil && d.SystemPacketListener == nil {
+ d.mu.Unlock()
+ if testenv.InTest() {
+ panic("SystemPacketListen requires a netmon.Monitor; call SetNetMon first")
+ }
+ return nil, errors.New("SystemPacketListen requires a netmon.Monitor; call SetNetMon first")
+ }
+ closed := d.closed
+ d.mu.Unlock()
+ if closed {
+ return nil, net.ErrClosed
+ }
+
+ listener := d.SystemPacketListener
+ if listener == nil {
+ listener = netns.Listener(d.logf, d.netMon).ListenPacket
+ }
+ return listener(ctx, network, address)
+}
+
// SetSystemDialerForTest sets an alternate function to use for SystemDial
// instead of netns.Dialer. This is intended for use with nettest.MemoryNetwork.
func (d *Dialer) SetSystemDialerForTest(fn netx.DialFunc) {
@@ -438,7 +502,7 @@ func (d *Dialer) SetSystemDialerForTest(fn netx.DialFunc) {
// Control and (in the future, as of 2022-04-27) DERPs..
func (d *Dialer) SystemDial(ctx context.Context, network, addr string) (net.Conn, error) {
d.mu.Lock()
- if d.netMon == nil && d.sysDialForTest == nil {
+ if d.netMon == nil && d.sysDialForTest == nil && d.SystemDialer == nil {
d.mu.Unlock()
if testenv.InTest() {
panic("SystemDial requires a netmon.Monitor; call SetNetMon first")
@@ -455,6 +519,8 @@ func (d *Dialer) SystemDial(ctx context.Context, network, addr string) (net.Conn
var err error
if d.sysDialForTest != nil {
c, err = d.sysDialForTest(ctx, network, addr)
+ } else if d.SystemDialer != nil {
+ c, err = d.SystemDialer(ctx, network, addr)
} else {
d.netnsDialerOnce.Do(func() {
d.netnsDialer = netns.NewDialer(d.logf, d.netMon)
@@ -510,9 +576,7 @@ func (d *Dialer) UserDial(ctx context.Context, network, addr string) (net.Conn,
if version.IsMacGUIVariant() && tsaddr.IsTailscaleIP(ipp.Addr()) {
return d.getPeerDialer().DialContext(ctx, network, ipp.String())
}
- // TODO(bradfitz): netns, etc
- var stdDialer net.Dialer
- return stdDialer.DialContext(ctx, network, ipp.String())
+ return d.SystemDial(ctx, network, ipp.String())
}
// UserDialPlan resolves addr and reports whether the dialer would
@@ -596,7 +660,13 @@ func (d *Dialer) PeerAPIHTTPClient() *http.Client {
panic("unreachable")
}
d.peerClientOnce.Do(func() {
- t := http.DefaultTransport.(*http.Transport).Clone()
+ t := &http.Transport{
+ ForceAttemptHTTP2: true,
+ MaxIdleConns: 100,
+ IdleConnTimeout: 90 * time.Second,
+ TLSHandshakeTimeout: 10 * time.Second,
+ ExpectContinueTimeout: 1 * time.Second,
+ }
t.Dial = nil
t.DialContext = d.dialPeerAPI
// Do not use the environment proxy for PeerAPI.
diff --git a/net/tsdial/tsdial_test.go b/net/tsdial/tsdial_test.go
index 92960acbe38b1..00d4ed549a98c 100644
--- a/net/tsdial/tsdial_test.go
+++ b/net/tsdial/tsdial_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,7 +10,7 @@ import (
"net/netip"
"testing"
- "github.com/gaissmai/bart"
+ "github.com/metacubex/bart"
)
func TestUserDialPlan(t *testing.T) {
diff --git a/net/tshttpproxy/tshttpproxy.go b/net/tshttpproxy/tshttpproxy.go
index 1ea444c8f5e99..8bbe517534886 100644
--- a/net/tshttpproxy/tshttpproxy.go
+++ b/net/tshttpproxy/tshttpproxy.go
@@ -19,8 +19,8 @@ import (
"sync"
"time"
+ "github.com/metacubex/tailscale/util/mak"
"golang.org/x/net/http/httpproxy"
- "tailscale.com/util/mak"
)
// InvalidateCache invalidates the package-level cache for ProxyFromEnvironment.
diff --git a/net/tshttpproxy/tshttpproxy_linux.go b/net/tshttpproxy/tshttpproxy_linux.go
index 30096e214a982..b6b04e6b03dea 100644
--- a/net/tshttpproxy/tshttpproxy_linux.go
+++ b/net/tshttpproxy/tshttpproxy_linux.go
@@ -9,8 +9,8 @@ import (
"net/http"
"net/url"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/version/distro"
)
func init() {
diff --git a/net/tshttpproxy/tshttpproxy_synology.go b/net/tshttpproxy/tshttpproxy_synology.go
index a632753f7bc1b..bcd6fb65bfc13 100644
--- a/net/tshttpproxy/tshttpproxy_synology.go
+++ b/net/tshttpproxy/tshttpproxy_synology.go
@@ -17,7 +17,8 @@ import (
"sync"
"time"
- "tailscale.com/util/lineiter"
+ "github.com/metacubex/tailscale/types/result"
+ "github.com/metacubex/tailscale/util/lineiter"
)
// These vars are overridden for tests.
@@ -76,22 +77,29 @@ func synologyProxiesFromConfig() (*url.URL, *url.URL, error) {
func parseSynologyConfig(r io.Reader) (*url.URL, *url.URL, error) {
cfg := map[string]string{}
- for lr := range lineiter.Reader(r) {
+ var parseErr error
+ lineiter.Reader(r)(func(lr result.Of[[]byte]) bool {
line, err := lr.Value()
if err != nil {
- return nil, nil, err
+ parseErr = err
+ return false
}
// accept and skip over empty lines
line = bytes.TrimSpace(line)
if len(line) == 0 {
- continue
+ return true
}
key, value, ok := strings.Cut(string(line), "=")
if !ok {
- return nil, nil, fmt.Errorf("missing \"=\" in proxy.conf line: %q", line)
+ parseErr = fmt.Errorf("missing \"=\" in proxy.conf line: %q", line)
+ return false
}
cfg[string(key)] = string(value)
+ return true
+ })
+ if parseErr != nil {
+ return nil, nil, parseErr
}
if cfg["proxy_enabled"] != "yes" {
diff --git a/net/tshttpproxy/tshttpproxy_synology_test.go b/net/tshttpproxy/tshttpproxy_synology_test.go
index 7360bb6f8fe29..e5c4ea3e050ee 100644
--- a/net/tshttpproxy/tshttpproxy_synology_test.go
+++ b/net/tshttpproxy/tshttpproxy_synology_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux
-
package tshttpproxy
import (
@@ -17,7 +17,7 @@ import (
"testing"
"time"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/tstest"
)
func TestSynologyProxyFromConfigCached(t *testing.T) {
diff --git a/net/tshttpproxy/tshttpproxy_test.go b/net/tshttpproxy/tshttpproxy_test.go
index b391c74d89df0..e0fc8f8fba4c5 100644
--- a/net/tshttpproxy/tshttpproxy_test.go
+++ b/net/tshttpproxy/tshttpproxy_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,7 +14,7 @@ import (
"testing"
"time"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/util/must"
)
func TestGetAuthHeaderNoResult(t *testing.T) {
diff --git a/net/tshttpproxy/tshttpproxy_windows.go b/net/tshttpproxy/tshttpproxy_windows.go
index 1a80be3ff370f..95cdc216fb836 100644
--- a/net/tshttpproxy/tshttpproxy_windows.go
+++ b/net/tshttpproxy/tshttpproxy_windows.go
@@ -18,13 +18,13 @@ import (
"unsafe"
"github.com/alexbrainman/sspi/negotiate"
- "github.com/dblohm7/wingoes"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/cmpver"
+ "github.com/metacubex/tailscale/util/wingoes"
"golang.org/x/sys/windows"
- "tailscale.com/hostinfo"
- "tailscale.com/syncs"
- "tailscale.com/types/logger"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/cmpver"
)
func init() {
@@ -237,7 +237,7 @@ func (pi *winHTTPProxyInfo) free() {
}
}
-var getProxyForURLOpts = sync.OnceValue(func() *winHTTPAutoProxyOptions {
+var getProxyForURLOpts = syncs.OnceValue(func() *winHTTPAutoProxyOptions {
opts := &winHTTPAutoProxyOptions{
DwFlags: winHTTP_AUTOPROXY_AUTO_DETECT,
DwAutoDetectFlags: winHTTP_AUTO_DETECT_TYPE_DHCP | winHTTP_AUTO_DETECT_TYPE_DNS_A,
diff --git a/net/tstun/fake.go b/net/tstun/fake.go
index f7925116e80bd..578c72b77aba5 100644
--- a/net/tstun/fake.go
+++ b/net/tstun/fake.go
@@ -7,7 +7,7 @@ import (
"io"
"os"
- "github.com/tailscale/wireguard-go/tun"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
)
type fakeTUN struct {
diff --git a/net/tstun/ifstatus_noop.go b/net/tstun/ifstatus_noop.go
deleted file mode 100644
index 420326c2fda38..0000000000000
--- a/net/tstun/ifstatus_noop.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) Tailscale Inc & contributors
-// SPDX-License-Identifier: BSD-3-Clause
-
-//go:build !windows
-
-package tstun
-
-import (
- "time"
-
- "github.com/tailscale/wireguard-go/tun"
- "tailscale.com/types/logger"
-)
-
-// Dummy implementation that does nothing.
-func waitInterfaceUp(iface tun.Device, timeout time.Duration, logf logger.Logf) error {
- return nil
-}
diff --git a/net/tstun/ifstatus_windows.go b/net/tstun/ifstatus_windows.go
deleted file mode 100644
index 64c898fd3aef2..0000000000000
--- a/net/tstun/ifstatus_windows.go
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) Tailscale Inc & contributors
-// SPDX-License-Identifier: BSD-3-Clause
-
-package tstun
-
-import (
- "fmt"
- "sync"
- "time"
-
- "github.com/tailscale/wireguard-go/tun"
- "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
- "tailscale.com/types/logger"
-)
-
-// ifaceWatcher waits for an interface to be up.
-type ifaceWatcher struct {
- logf logger.Logf
- luid winipcfg.LUID
-
- mu sync.Mutex // guards following
- done bool
- sig chan bool
-}
-
-// callback is the callback we register with Windows to call when IP interface changes.
-func (iw *ifaceWatcher) callback(notificationType winipcfg.MibNotificationType, iface *winipcfg.MibIPInterfaceRow) {
- // Probably should check only when MibParameterNotification, but just in case included MibAddInstance also.
- if notificationType == winipcfg.MibParameterNotification || notificationType == winipcfg.MibAddInstance {
- // Out of paranoia, start a goroutine to finish our work, to return to Windows out of this callback.
- go iw.isUp()
- }
-}
-
-func (iw *ifaceWatcher) isUp() bool {
- iw.mu.Lock()
- defer iw.mu.Unlock()
-
- if iw.done {
- // We already know that it's up
- return true
- }
-
- if iw.getOperStatus() != winipcfg.IfOperStatusUp {
- return false
- }
-
- iw.done = true
- iw.sig <- true
- return true
-}
-
-func (iw *ifaceWatcher) getOperStatus() winipcfg.IfOperStatus {
- ifc, err := iw.luid.Interface()
- if err != nil {
- iw.logf("iw.luid.Interface error: %v", err)
- return 0
- }
- return ifc.OperStatus
-}
-
-func waitInterfaceUp(iface tun.Device, timeout time.Duration, logf logger.Logf) error {
- iw := &ifaceWatcher{
- luid: winipcfg.LUID(iface.(*tun.NativeTun).LUID()),
- logf: logger.WithPrefix(logf, "waitInterfaceUp: "),
- }
-
- // Just in case check the status first
- if iw.getOperStatus() == winipcfg.IfOperStatusUp {
- iw.logf("TUN interface already up; no need to wait")
- return nil
- }
-
- iw.sig = make(chan bool, 1)
- cb, err := winipcfg.RegisterInterfaceChangeCallback(iw.callback)
- if err != nil {
- iw.logf("RegisterInterfaceChangeCallback error: %v", err)
- return err
- }
- defer cb.Unregister()
-
- t0 := time.Now()
- expires := t0.Add(timeout)
- ticker := time.NewTicker(10 * time.Second)
- defer ticker.Stop()
-
- for {
- iw.logf("waiting for TUN interface to come up...")
-
- select {
- case <-iw.sig:
- iw.logf("TUN interface is up after %v", time.Since(t0))
- return nil
- case <-ticker.C:
- }
-
- if iw.isUp() {
- // Very unlikely to happen - either NotifyIpInterfaceChange doesn't work
- // or it came up in the same moment as tick. Indicate this in the log message.
- iw.logf("TUN interface is up after %v (on poll, without notification)", time.Since(t0))
- return nil
- }
-
- if expires.Before(time.Now()) {
- iw.logf("timeout waiting %v for TUN interface to come up", timeout)
- return fmt.Errorf("timeout waiting for TUN interface to come up")
- }
- }
-}
diff --git a/net/tstun/mtu.go b/net/tstun/mtu.go
index 6eceb6833b964..f04cb1defcec8 100644
--- a/net/tstun/mtu.go
+++ b/net/tstun/mtu.go
@@ -4,7 +4,7 @@
package tstun
import (
- "tailscale.com/envknob"
+ "github.com/metacubex/tailscale/envknob"
)
// The MTU (Maximum Transmission Unit) of a network interface is the largest
@@ -132,7 +132,7 @@ func WireToTUNMTU(w WireMTU) TUNMTU {
// 3. If TS_DEBUG_ENABLE_PMTUD is not set, the Safe MTU
func DefaultTUNMTU() TUNMTU {
if m, ok := envknob.LookupUintSized("TS_DEBUG_MTU", 10, 32); ok {
- return min(TUNMTU(m), maxTUNMTU)
+ return minTUNMTU(TUNMTU(m), maxTUNMTU)
}
debugPMTUD, _ := envknob.LookupBool("TS_DEBUG_ENABLE_PMTUD")
@@ -159,3 +159,10 @@ func SafeWireMTU() WireMTU {
func DefaultWireMTU() WireMTU {
return TUNToWireMTU(DefaultTUNMTU())
}
+
+func minTUNMTU(a, b TUNMTU) TUNMTU {
+ if a < b {
+ return a
+ }
+ return b
+}
diff --git a/net/tstun/mtu_test.go b/net/tstun/mtu_test.go
index 6129e0c140a85..4bcba9f5bed4a 100644
--- a/net/tstun/mtu_test.go
+++ b/net/tstun/mtu_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/net/tstun/netstack_enabled.go b/net/tstun/netstack_enabled.go
index 440013c7e9510..9b757af81b6fb 100644
--- a/net/tstun/netstack_enabled.go
+++ b/net/tstun/netstack_enabled.go
@@ -6,7 +6,7 @@
package tstun
import (
- "gvisor.dev/gvisor/pkg/tcpip/stack"
+ "github.com/metacubex/gvisor/pkg/tcpip/stack"
)
type (
diff --git a/net/tstun/tstun_stub.go b/net/tstun/tstun_stub.go
deleted file mode 100644
index 27d530bc8b95c..0000000000000
--- a/net/tstun/tstun_stub.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) Tailscale Inc & contributors
-// SPDX-License-Identifier: BSD-3-Clause
-
-//go:build aix || solaris || illumos
-
-package tstun
-
-import (
- "github.com/tailscale/wireguard-go/tun"
- "tailscale.com/types/logger"
-)
-
-func New(logf logger.Logf, tunName string) (tun.Device, string, error) {
- panic("not implemented")
-}
-
-func Diagnose(logf logger.Logf, tunName string, err error) {
- panic("not implemented")
-}
diff --git a/net/tstun/tun.go b/net/tstun/tun.go
deleted file mode 100644
index 42b0d239c39d4..0000000000000
--- a/net/tstun/tun.go
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright (c) Tailscale Inc & contributors
-// SPDX-License-Identifier: BSD-3-Clause
-
-//go:build !wasm && !tamago && !aix && !solaris && !illumos
-
-// Package tun creates a tuntap device, working around OS-specific
-// quirks if necessary.
-package tstun
-
-import (
- "errors"
- "fmt"
- "log"
- "os"
- "runtime"
- "strings"
- "time"
-
- "github.com/tailscale/wireguard-go/tun"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/types/logger"
-)
-
-// CreateTAP is the hook maybe set by feature/tap.
-var CreateTAP feature.Hook[func(logf logger.Logf, tapName, bridgeName string) (tun.Device, error)]
-
-// HookSetLinkAttrs is the hook maybe set by feature/linkspeed.
-var HookSetLinkAttrs feature.Hook[func(tun.Device) error]
-
-// modprobeTunHook is a Linux-specific hook to run "/sbin/modprobe tun".
-var modprobeTunHook feature.Hook[func() error]
-
-// New returns a tun.Device for the requested device name, along with
-// the OS-dependent name that was allocated to the device.
-func New(logf logger.Logf, tunName string) (tun.Device, string, error) {
- var dev tun.Device
- var err error
- if strings.HasPrefix(tunName, "tap:") {
- if runtime.GOOS != "linux" {
- return nil, "", errors.New("tap only works on Linux")
- }
- if !CreateTAP.IsSet() { // if the ts_omit_tap tag is used
- return nil, "", errors.New("tap is not supported in this build")
- }
- f := strings.Split(tunName, ":")
- var tapName, bridgeName string
- switch len(f) {
- case 2:
- tapName = f[1]
- case 3:
- tapName, bridgeName = f[1], f[2]
- default:
- return nil, "", errors.New("bogus tap argument")
- }
- dev, err = CreateTAP.Get()(logf, tapName, bridgeName)
- } else {
- if runtime.GOOS == "plan9" {
- cleanUpPlan9Interfaces()
- }
- // Try to create the TUN device up to two times. If it fails
- // the first time and we're on Linux, try a desperate
- // "modprobe tun" to load the tun module and try again.
- for try := range 2 {
- dev, err = tun.CreateTUN(tunName, int(DefaultTUNMTU()))
- if err == nil || !modprobeTunHook.IsSet() {
- if try > 0 {
- logf("created TUN device %q after doing `modprobe tun`", tunName)
- }
- break
- }
- if modprobeTunHook.Get()() != nil {
- // modprobe failed; no point trying again.
- break
- }
- }
- }
- if err != nil {
- return nil, "", err
- }
- if err := waitInterfaceUp(dev, 90*time.Second, logf); err != nil {
- dev.Close()
- return nil, "", err
- }
- if buildfeatures.HasLinkSpeed {
- if f, ok := HookSetLinkAttrs.GetOk(); ok {
- if err := f(dev); err != nil {
- logf("setting link attributes: %v", err)
- }
- }
- }
- name, err := interfaceName(dev)
- if err != nil {
- dev.Close()
- return nil, "", err
- }
- return dev, name, nil
-}
-
-func cleanUpPlan9Interfaces() {
- maybeUnbind := func(n int) {
- b, err := os.ReadFile(fmt.Sprintf("/net/ipifc/%d/status", n))
- if err != nil {
- return
- }
- status := string(b)
- if !(strings.HasPrefix(status, "device maxtu ") ||
- strings.Contains(status, "fd7a:115c:a1e0:")) {
- return
- }
- f, err := os.OpenFile(fmt.Sprintf("/net/ipifc/%d/ctl", n), os.O_RDWR, 0)
- if err != nil {
- return
- }
- defer f.Close()
- if _, err := fmt.Fprintf(f, "unbind\n"); err != nil {
- log.Printf("unbind interface %v: %v", n, err)
- return
- }
- log.Printf("tun: unbound stale interface %v", n)
- }
-
- // A common case: after unclean shutdown we might leave interfaces
- // behind. Look for our straggler(s) and clean them up.
- for n := 2; n < 5; n++ {
- maybeUnbind(n)
- }
-}
-
-// tunDiagnoseFailure, if non-nil, does OS-specific diagnostics of why
-// TUN failed to work.
-var tunDiagnoseFailure func(tunName string, logf logger.Logf, err error)
-
-// Diagnose tries to explain a tuntap device creation failure.
-// It pokes around the system and logs some diagnostic info that might
-// help debug why tun creation failed. Because device creation has
-// already failed and the program's about to end, log a lot.
-//
-// The tunName is the name of the tun device that was requested but failed.
-// The err error is how the tun creation failed.
-func Diagnose(logf logger.Logf, tunName string, err error) {
- if tunDiagnoseFailure != nil {
- tunDiagnoseFailure(tunName, logf, err)
- } else {
- logf("no TUN failure diagnostics for OS %q", runtime.GOOS)
- }
-}
diff --git a/net/tstun/tun_linux.go b/net/tstun/tun_linux.go
deleted file mode 100644
index fb4a8a415dac7..0000000000000
--- a/net/tstun/tun_linux.go
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) Tailscale Inc & contributors
-// SPDX-License-Identifier: BSD-3-Clause
-
-package tstun
-
-import (
- "bytes"
- "errors"
- "os"
- "os/exec"
- "strings"
- "syscall"
-
- "tailscale.com/types/logger"
- "tailscale.com/version/distro"
-)
-
-func init() {
- tunDiagnoseFailure = diagnoseLinuxTUNFailure
- modprobeTunHook.Set(func() error {
- _, err := modprobeTun()
- return err
- })
-}
-
-func modprobeTun() ([]byte, error) {
- return exec.Command("/sbin/modprobe", "tun").CombinedOutput()
-}
-
-func diagnoseLinuxTUNFailure(tunName string, logf logger.Logf, createErr error) {
- if errors.Is(createErr, syscall.EBUSY) {
- logf("TUN device %s is busy; another process probably still has it open (from old version of Tailscale that had a bug)", tunName)
- logf("To fix, kill the process that has it open. Find with:\n\n$ sudo lsof -n /dev/net/tun\n\n")
- logf("... and then kill those PID(s)")
- return
- }
-
- var un syscall.Utsname
- err := syscall.Uname(&un)
- if err != nil {
- logf("no TUN, and failed to look up kernel version: %v", err)
- return
- }
- kernel := utsReleaseField(&un)
- logf("Linux kernel version: %s", kernel)
-
- modprobeOut, err := modprobeTun()
- if err == nil {
- logf("'modprobe tun' successful")
- // Either tun is currently loaded, or it's statically
- // compiled into the kernel (which modprobe checks
- // with /lib/modules/$(uname -r)/modules.builtin)
- //
- // So if there's a problem at this point, it's
- // probably because /dev/net/tun doesn't exist.
- const dev = "/dev/net/tun"
- if fi, err := os.Stat(dev); err != nil {
- logf("tun module loaded in kernel, but %s does not exist", dev)
- } else {
- logf("%s: %v", dev, fi.Mode())
- }
-
- // We failed to find why it failed. Just let our
- // caller report the error it got from wireguard-go.
- return
- }
- logf("is CONFIG_TUN enabled in your kernel? `modprobe tun` failed with: %s", modprobeOut)
-
- switch distro.Get() {
- case distro.Debian:
- dpkgOut, err := exec.Command("dpkg", "-S", "kernel/drivers/net/tun.ko").CombinedOutput()
- if len(bytes.TrimSpace(dpkgOut)) == 0 || err != nil {
- logf("tun module not loaded nor found on disk")
- return
- }
- if !bytes.Contains(dpkgOut, []byte(kernel)) {
- logf("kernel/drivers/net/tun.ko found on disk, but not for current kernel; are you in middle of a system update and haven't rebooted? found: %s", dpkgOut)
- }
- case distro.Arch:
- findOut, err := exec.Command("find", "/lib/modules/", "-path", "*/net/tun.ko*").CombinedOutput()
- if len(bytes.TrimSpace(findOut)) == 0 || err != nil {
- logf("tun module not loaded nor found on disk")
- return
- }
- if !bytes.Contains(findOut, []byte(kernel)) {
- logf("kernel/drivers/net/tun.ko found on disk, but not for current kernel; are you in middle of a system update and haven't rebooted? found: %s", findOut)
- }
- case distro.OpenWrt:
- // OpenWRT switched to using apk as a package manager as of OpenWrt 25.12.0.
- // Find out what is used on this system and use that, Maybe we can get rid
- // of opkg in the future but for now keep checking.
-
- if path, err := exec.LookPath("apk"); err == nil && path != "" {
- // Test with apk
- out, err := exec.Command("apk", "info").CombinedOutput()
- if err != nil {
- logf("error querying OpenWrt installed packages with apk: %s", out)
- return
- }
- for _, pkg := range []string{"kmod-tun", "ca-bundle"} {
- if !bytes.Contains(out, []byte(pkg)) {
- logf("Missing required package %s; run: apk add %s", pkg, pkg)
- }
- }
- } else { // Check for package with opkg (legacy)
- out, err := exec.Command("opkg", "list-installed").CombinedOutput()
- if err != nil {
- logf("error querying OpenWrt installed packages with opkg: %s", out)
- return
- }
- for _, pkg := range []string{"kmod-tun", "ca-bundle"} {
- if !bytes.Contains(out, []byte(pkg+" - ")) {
- logf("Missing required package %s; run: opkg install %s", pkg, pkg)
- }
- }
- }
- }
-}
-
-func utsReleaseField(u *syscall.Utsname) string {
- var sb strings.Builder
- for _, v := range u.Release {
- if v == 0 {
- break
- }
- sb.WriteByte(byte(v))
- }
- return strings.TrimSpace(sb.String())
-}
diff --git a/net/tstun/tun_macos.go b/net/tstun/tun_macos.go
deleted file mode 100644
index fb8eb9450fb7e..0000000000000
--- a/net/tstun/tun_macos.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) Tailscale Inc & contributors
-// SPDX-License-Identifier: BSD-3-Clause
-
-//go:build darwin && !ios
-
-package tstun
-
-import (
- "os"
-
- "tailscale.com/types/logger"
-)
-
-func init() {
- tunDiagnoseFailure = diagnoseDarwinTUNFailure
-}
-
-func diagnoseDarwinTUNFailure(tunName string, logf logger.Logf, err error) {
- if os.Getuid() != 0 {
- logf("failed to create TUN device as non-root user; use 'sudo tailscaled', or run under launchd with 'sudo tailscaled install-system-daemon'")
- }
- if tunName != "utun" {
- logf("failed to create TUN device %q; try using tun device \"utun\" instead for automatic selection", tunName)
- }
-}
diff --git a/net/tstun/tun_notwindows.go b/net/tstun/tun_notwindows.go
deleted file mode 100644
index 73f80fea12ce8..0000000000000
--- a/net/tstun/tun_notwindows.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) Tailscale Inc & contributors
-// SPDX-License-Identifier: BSD-3-Clause
-
-//go:build !windows
-
-package tstun
-
-import "github.com/tailscale/wireguard-go/tun"
-
-func interfaceName(dev tun.Device) (string, error) {
- return dev.Name()
-}
diff --git a/net/tstun/tun_windows.go b/net/tstun/tun_windows.go
deleted file mode 100644
index 96721021b2022..0000000000000
--- a/net/tstun/tun_windows.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) Tailscale Inc & contributors
-// SPDX-License-Identifier: BSD-3-Clause
-
-package tstun
-
-import (
- "github.com/tailscale/wireguard-go/tun"
- "golang.org/x/sys/windows"
- "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
-)
-
-func init() {
- tun.WintunTunnelType = "Tailscale"
- guid, err := windows.GUIDFromString("{37217669-42da-4657-a55b-0d995d328250}")
- if err != nil {
- panic(err)
- }
- tun.WintunStaticRequestedGUID = &guid
-}
-
-func interfaceName(dev tun.Device) (string, error) {
- guid, err := winipcfg.LUID(dev.(*tun.NativeTun).LUID()).GUID()
- if err != nil {
- return "", err
- }
- return guid.String(), nil
-}
diff --git a/net/tstun/wrap.go b/net/tstun/wrap.go
index cd75aff5ccffd..ea30c1eda1a43 100644
--- a/net/tstun/wrap.go
+++ b/net/tstun/wrap.go
@@ -6,42 +6,42 @@ package tstun
import (
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net/netip"
"os"
"reflect"
"runtime"
- "slices"
"strings"
"sync"
"sync/atomic"
"time"
- "github.com/gaissmai/bart"
- "github.com/tailscale/wireguard-go/conn"
- "github.com/tailscale/wireguard-go/device"
- "github.com/tailscale/wireguard-go/tun"
+ "github.com/metacubex/bart"
+ "github.com/metacubex/tailscale-wireguard-go/conn"
+ "github.com/metacubex/tailscale-wireguard-go/device"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/disco"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/packet/checksum"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tstime/mono"
+ "github.com/metacubex/tailscale/types/events"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netlogfunc"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/usermetric"
+ "github.com/metacubex/tailscale/wgengine/filter"
+ "github.com/metacubex/tailscale/wgengine/netstack/gro"
+ "github.com/metacubex/tailscale/wgengine/wgcfg"
"go4.org/mem"
- "tailscale.com/disco"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/net/packet"
- "tailscale.com/net/packet/checksum"
- "tailscale.com/net/tsaddr"
- "tailscale.com/syncs"
- "tailscale.com/tstime/mono"
- "tailscale.com/types/events"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/netlogfunc"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/usermetric"
- "tailscale.com/wgengine/filter"
- "tailscale.com/wgengine/netstack/gro"
- "tailscale.com/wgengine/wgcfg"
)
const maxBufferSize = device.MaxMessageSize
@@ -1399,11 +1399,11 @@ func (t *Wrapper) InjectInboundPacketBuffer(pkt *netstack_PacketBuffer, buffs []
return err
}
}
- for i := range n {
+ for i := 0; i < n; i++ {
buffs[i] = buffs[i][:PacketStartOffset+sizes[i]]
}
defer func() {
- for i := range n {
+ for i := 0; i < n; i++ {
buffs[i] = buffs[i][:cap(buffs[i])]
}
}()
diff --git a/net/tstun/wrap_linux.go b/net/tstun/wrap_linux.go
index a4e76de5a9d20..c40e47cdb41b3 100644
--- a/net/tstun/wrap_linux.go
+++ b/net/tstun/wrap_linux.go
@@ -10,13 +10,13 @@ import (
"net/netip"
"runtime"
- "github.com/tailscale/wireguard-go/tun"
+ "github.com/metacubex/gvisor/pkg/tcpip"
+ "github.com/metacubex/gvisor/pkg/tcpip/checksum"
+ "github.com/metacubex/gvisor/pkg/tcpip/header"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/net/tsaddr"
"golang.org/x/sys/unix"
- "gvisor.dev/gvisor/pkg/tcpip"
- "gvisor.dev/gvisor/pkg/tcpip/checksum"
- "gvisor.dev/gvisor/pkg/tcpip/header"
- "tailscale.com/envknob"
- "tailscale.com/net/tsaddr"
)
// SetLinkFeaturesPostUp configures link features on t based on select TS_TUN_
diff --git a/net/tstun/wrap_test.go b/net/tstun/wrap_test.go
index 57b300513fec8..5fb8ca471b606 100644
--- a/net/tstun/wrap_test.go
+++ b/net/tstun/wrap_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -20,28 +22,28 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "github.com/tailscale/wireguard-go/tun/tuntest"
+ "github.com/metacubex/gvisor/pkg/buffer"
+ "github.com/metacubex/gvisor/pkg/tcpip/stack"
+ "github.com/metacubex/tailscale-wireguard-go/tun/tuntest"
+ "github.com/metacubex/tailscale/disco"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstime/mono"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netlogtype"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/usermetric"
+ "github.com/metacubex/tailscale/wgengine/filter"
+ "github.com/metacubex/tailscale/wgengine/netstack/gro"
+ "github.com/metacubex/tailscale/wgengine/wgcfg"
"go4.org/mem"
"go4.org/netipx"
- "gvisor.dev/gvisor/pkg/buffer"
- "gvisor.dev/gvisor/pkg/tcpip/stack"
- "tailscale.com/disco"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/packet"
- "tailscale.com/tstest"
- "tailscale.com/tstime/mono"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/netlogtype"
- "tailscale.com/types/views"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/must"
- "tailscale.com/util/usermetric"
- "tailscale.com/wgengine/filter"
- "tailscale.com/wgengine/netstack/gro"
- "tailscale.com/wgengine/wgcfg"
)
func udp4(src, dst string, sport, dport uint16) []byte {
diff --git a/net/udprelay/endpoint/endpoint.go b/net/udprelay/endpoint/endpoint.go
index 7b8368b615e52..c8d49159958d1 100644
--- a/net/udprelay/endpoint/endpoint.go
+++ b/net/udprelay/endpoint/endpoint.go
@@ -2,23 +2,23 @@
// SPDX-License-Identifier: BSD-3-Clause
// Package endpoint contains types relating to UDP relay server endpoints. It
-// does not import tailscale.com/net/udprelay.
+// does not import github.com/metacubex/tailscale/net/udprelay.
package endpoint
import (
"net/netip"
"time"
- "tailscale.com/tstime"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/key"
)
// ServerRetryAfter is the default
-// [tailscale.com/net/udprelay.ErrServerNotReady.RetryAfter] value.
+// [github.com/metacubex/tailscale/net/udprelay.ErrServerNotReady.RetryAfter] value.
const ServerRetryAfter = time.Second * 3
// ServerEndpoint contains details for an endpoint served by a
-// [tailscale.com/net/udprelay.Server].
+// [github.com/metacubex/tailscale/net/udprelay.Server].
type ServerEndpoint struct {
// ServerDisco is the Server's Disco public key used as part of the 3-way
// bind handshake. Server will use the same ServerDisco for its lifetime.
diff --git a/net/udprelay/endpoint/endpoint_test.go b/net/udprelay/endpoint/endpoint_test.go
index 23fd88ad3e0bd..b910bd88a03da 100644
--- a/net/udprelay/endpoint/endpoint_test.go
+++ b/net/udprelay/endpoint/endpoint_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,8 +14,8 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/tstime"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/key"
)
func TestServerEndpointJSONUnmarshal(t *testing.T) {
diff --git a/net/udprelay/metrics.go b/net/udprelay/metrics.go
index 6e22acd03ce70..83361f24c3263 100644
--- a/net/udprelay/metrics.go
+++ b/net/udprelay/metrics.go
@@ -6,8 +6,8 @@ package udprelay
import (
"expvar"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/usermetric"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/usermetric"
)
var (
diff --git a/net/udprelay/metrics_test.go b/net/udprelay/metrics_test.go
index da90550b88920..62d330cf344d0 100644
--- a/net/udprelay/metrics_test.go
+++ b/net/udprelay/metrics_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,11 +7,11 @@ package udprelay
import (
"fmt"
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"testing"
qt "github.com/frankban/quicktest"
- "tailscale.com/util/usermetric"
+ "github.com/metacubex/tailscale/util/usermetric"
)
func TestMetricsLifecycle(t *testing.T) {
diff --git a/net/udprelay/server.go b/net/udprelay/server.go
index 3b0f729897ca8..4cc2ae78d8997 100644
--- a/net/udprelay/server.go
+++ b/net/udprelay/server.go
@@ -13,40 +13,40 @@ import (
"encoding/binary"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net"
"net/netip"
"runtime"
- "slices"
"strconv"
"sync"
"syscall"
"time"
+ "github.com/metacubex/tailscale/disco"
+ "github.com/metacubex/tailscale/net/batching"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/netcheck"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/sockopts"
+ "github.com/metacubex/tailscale/net/stun"
+ "github.com/metacubex/tailscale/net/udprelay/endpoint"
+ "github.com/metacubex/tailscale/net/udprelay/status"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/tstime/mono"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/nettype"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/cloudinfo"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/usermetric"
"go4.org/mem"
"golang.org/x/crypto/blake2s"
"golang.org/x/net/ipv6"
- "tailscale.com/disco"
- "tailscale.com/net/batching"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/netcheck"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netns"
- "tailscale.com/net/packet"
- "tailscale.com/net/sockopts"
- "tailscale.com/net/stun"
- "tailscale.com/net/udprelay/endpoint"
- "tailscale.com/net/udprelay/status"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/tstime/mono"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/nettype"
- "tailscale.com/types/views"
- "tailscale.com/util/cloudinfo"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/set"
- "tailscale.com/util/usermetric"
)
const (
diff --git a/net/udprelay/server_test.go b/net/udprelay/server_test.go
index 00b9c2423bd3c..309f7478f33ba 100644
--- a/net/udprelay/server_test.go
+++ b/net/udprelay/server_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -15,15 +17,15 @@ import (
qt "github.com/frankban/quicktest"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
+ "github.com/metacubex/tailscale/disco"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/tstime/mono"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/usermetric"
"go4.org/mem"
"golang.org/x/crypto/blake2s"
- "tailscale.com/disco"
- "tailscale.com/net/packet"
- "tailscale.com/tstime/mono"
- "tailscale.com/types/key"
- "tailscale.com/types/views"
- "tailscale.com/util/mak"
- "tailscale.com/util/usermetric"
)
type testClient struct {
diff --git a/net/wsconn/wsconn.go b/net/wsconn/wsconn.go
index fed734cf5ffd8..260a3fad319b1 100644
--- a/net/wsconn/wsconn.go
+++ b/net/wsconn/wsconn.go
@@ -16,7 +16,7 @@ import (
"time"
"github.com/coder/websocket"
- "tailscale.com/syncs"
+ "github.com/metacubex/tailscale/syncs"
)
// NetConn converts a *websocket.Conn into a net.Conn.
diff --git a/packages/deb/deb_test.go b/packages/deb/deb_test.go
index fb8a6454c3ab7..491e6bb977fd1 100644
--- a/packages/deb/deb_test.go
+++ b/packages/deb/deb_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/paths/migrate.go b/paths/migrate.go
index 22f947611f4cd..691b6849684b0 100644
--- a/paths/migrate.go
+++ b/paths/migrate.go
@@ -7,7 +7,7 @@ import (
"os"
"path/filepath"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
// TryConfigFileMigration carefully copies the contents of oldFile to
diff --git a/paths/paths.go b/paths/paths.go
index 398d8b23d8988..ad71f793a0e3b 100644
--- a/paths/paths.go
+++ b/paths/paths.go
@@ -11,8 +11,8 @@ import (
"path/filepath"
"runtime"
- "tailscale.com/syncs"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/version/distro"
)
// AppSharedDir is a string set by the iOS or Android app on start
diff --git a/paths/paths_unix.go b/paths/paths_unix.go
index b1556b233104f..82f97b6db4595 100644
--- a/paths/paths_unix.go
+++ b/paths/paths_unix.go
@@ -11,8 +11,8 @@ import (
"path/filepath"
"runtime"
+ "github.com/metacubex/tailscale/version/distro"
"golang.org/x/sys/unix"
- "tailscale.com/version/distro"
)
func init() {
@@ -48,7 +48,7 @@ func stateFileUnix() string {
}
try := path
- for range 3 { // check writability of the file, /var/lib/tailscale, and /var/lib
+ for i := 0; i < 3; i++ { // check writability of the file, /var/lib/tailscale, and /var/lib
err := unix.Access(try, unix.O_RDWR)
if err == nil {
return path
diff --git a/paths/paths_windows.go b/paths/paths_windows.go
index 850a1c97b52a0..ce359aabcf8c3 100644
--- a/paths/paths_windows.go
+++ b/paths/paths_windows.go
@@ -8,8 +8,8 @@ import (
"path/filepath"
"strings"
+ "github.com/metacubex/tailscale/util/winutil"
"golang.org/x/sys/windows"
- "tailscale.com/util/winutil"
)
func init() {
diff --git a/pkgdoc_test.go b/pkgdoc_test.go
index d0f0d66bd3a1d..41e1d012bb573 100644
--- a/pkgdoc_test.go
+++ b/pkgdoc_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/portlist/clean_test.go b/portlist/clean_test.go
index e7a5f6a0ca4ac..6a27146cea22e 100644
--- a/portlist/clean_test.go
+++ b/portlist/clean_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/portlist/netstat_test.go b/portlist/netstat_test.go
index 7048e90b2ffea..3b1a7851a0f80 100644
--- a/portlist/netstat_test.go
+++ b/portlist/netstat_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build darwin && !ios
-
package portlist
import (
diff --git a/portlist/poller.go b/portlist/poller.go
index a8e611054eb1b..e0f0199498728 100644
--- a/portlist/poller.go
+++ b/portlist/poller.go
@@ -9,12 +9,12 @@ package portlist
import (
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"runtime"
- "slices"
"sync"
"time"
- "tailscale.com/envknob"
+ "github.com/metacubex/tailscale/envknob"
)
var (
diff --git a/portlist/portlist_linux.go b/portlist/portlist_linux.go
index 159c4beb3a74a..165c0320cf1dc 100644
--- a/portlist/portlist_linux.go
+++ b/portlist/portlist_linux.go
@@ -19,10 +19,10 @@ import (
"time"
"unsafe"
+ "github.com/metacubex/tailscale/util/dirwalk"
+ "github.com/metacubex/tailscale/util/mak"
"go4.org/mem"
"golang.org/x/sys/unix"
- "tailscale.com/util/dirwalk"
- "tailscale.com/util/mak"
)
func init() {
diff --git a/portlist/portlist_linux_test.go b/portlist/portlist_linux_test.go
index 4b541f8e7dd70..987bd633f5c49 100644
--- a/portlist/portlist_linux_test.go
+++ b/portlist/portlist_linux_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/portlist/portlist_test.go b/portlist/portlist_test.go
index 922cb7a1ef562..b8c5a477087b7 100644
--- a/portlist/portlist_test.go
+++ b/portlist/portlist_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,7 +10,7 @@ import (
"runtime"
"testing"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/tstest"
)
func maybeSkip(t testing.TB) {
diff --git a/portlist/portlist_windows.go b/portlist/portlist_windows.go
index bd603dbfd8f91..8101a576ca10f 100644
--- a/portlist/portlist_windows.go
+++ b/portlist/portlist_windows.go
@@ -6,7 +6,7 @@ package portlist
import (
"time"
- "tailscale.com/net/netstat"
+ "github.com/metacubex/tailscale/net/netstat"
)
func init() {
diff --git a/posture/hwaddr.go b/posture/hwaddr.go
index 2075331f16727..0a00e5ea0045a 100644
--- a/posture/hwaddr.go
+++ b/posture/hwaddr.go
@@ -4,10 +4,10 @@
package posture
import (
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
- "tailscale.com/net/netmon"
+ "github.com/metacubex/tailscale/net/netmon"
)
// GetHardwareAddrs returns the hardware addresses of all non-loopback
diff --git a/posture/serialnumber_macos.go b/posture/serialnumber_macos.go
index fed0d4111fb83..7d9a56b8676b0 100644
--- a/posture/serialnumber_macos.go
+++ b/posture/serialnumber_macos.go
@@ -58,8 +58,8 @@ import (
"fmt"
"strings"
- "tailscale.com/types/logger"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
// GetSerialNumber returns the platform serial sumber as reported by IOKit.
diff --git a/posture/serialnumber_macos_test.go b/posture/serialnumber_macos_test.go
index 5f1aec5cd790b..b8e751a674a43 100644
--- a/posture/serialnumber_macos_test.go
+++ b/posture/serialnumber_macos_test.go
@@ -1,17 +1,17 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build cgo && darwin && !ios
-
package posture
import (
"fmt"
"testing"
- "tailscale.com/types/logger"
- "tailscale.com/util/cibuild"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/cibuild"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
func TestGetSerialNumberMac(t *testing.T) {
diff --git a/posture/serialnumber_notmacos.go b/posture/serialnumber_notmacos.go
index e076b8f3dcfdf..bedba6ea591fb 100644
--- a/posture/serialnumber_notmacos.go
+++ b/posture/serialnumber_notmacos.go
@@ -12,8 +12,8 @@ import (
"strings"
"github.com/digitalocean/go-smbios/smbios"
- "tailscale.com/types/logger"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
// getByteFromSmbiosStructure retrieves a 8-bit unsigned integer at the given specOffset.
diff --git a/posture/serialnumber_notmacos_test.go b/posture/serialnumber_notmacos_test.go
index 1009ea6b4a208..4409f2addf3b0 100644
--- a/posture/serialnumber_notmacos_test.go
+++ b/posture/serialnumber_notmacos_test.go
@@ -1,18 +1,18 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
// Build on Windows, Linux and *BSD
-//go:build windows || (linux && !android) || freebsd || openbsd || dragonfly || netbsd
-
package posture
import (
"fmt"
"testing"
- "tailscale.com/types/logger"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
func TestGetSerialNumberNotMac(t *testing.T) {
diff --git a/posture/serialnumber_stub.go b/posture/serialnumber_stub.go
index 6df9b4079650b..33ec22deffa74 100644
--- a/posture/serialnumber_stub.go
+++ b/posture/serialnumber_stub.go
@@ -14,8 +14,8 @@ import (
"errors"
"fmt"
- "tailscale.com/types/logger"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
// GetSerialNumber returns client machine serial number(s).
diff --git a/posture/serialnumber_syspolicy.go b/posture/serialnumber_syspolicy.go
index 448fdb677abef..a4fafa17e204e 100644
--- a/posture/serialnumber_syspolicy.go
+++ b/posture/serialnumber_syspolicy.go
@@ -8,9 +8,9 @@ package posture
import (
"fmt"
- "tailscale.com/types/logger"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
// GetSerialNumbers returns the serial number of the device as reported by an
diff --git a/posture/serialnumber_test.go b/posture/serialnumber_test.go
index 20e726d9ff530..9b1a7e6a9da9b 100644
--- a/posture/serialnumber_test.go
+++ b/posture/serialnumber_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,8 +8,8 @@ package posture
import (
"testing"
- "tailscale.com/types/logger"
- "tailscale.com/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
)
func TestGetSerialNumber(t *testing.T) {
diff --git a/prober/derp.go b/prober/derp.go
index dadda6fce2208..a9419207ebbcf 100644
--- a/prober/derp.go
+++ b/prober/derp.go
@@ -5,7 +5,6 @@ package prober
import (
"bytes"
- "cmp"
"context"
crand "crypto/rand"
"crypto/tls"
@@ -14,34 +13,35 @@ import (
"errors"
"expvar"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
- "maps"
"math"
"net"
"net/http"
"net/netip"
- "slices"
"strconv"
"strings"
"sync"
"time"
+ wgconn "github.com/metacubex/tailscale-wireguard-go/conn"
+ "github.com/metacubex/tailscale-wireguard-go/device"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/derp"
+ "github.com/metacubex/tailscale/derp/derphttp"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/stun"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
"github.com/prometheus/client_golang/prometheus"
- wgconn "github.com/tailscale/wireguard-go/conn"
- "github.com/tailscale/wireguard-go/device"
- "github.com/tailscale/wireguard-go/tun"
"go4.org/netipx"
- "tailscale.com/client/local"
- "tailscale.com/derp"
- "tailscale.com/derp/derphttp"
- "tailscale.com/net/netmon"
- "tailscale.com/net/stun"
- "tailscale.com/net/tstun"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
)
// derpProber dynamically manages several probes for each DERP server
@@ -1210,7 +1210,13 @@ func newConn(ctx context.Context, dm *tailcfg.DERPMap, n *tailcfg.DERPNode, isPr
var httpOrFileClient = &http.Client{Transport: httpOrFileTransport()}
func httpOrFileTransport() http.RoundTripper {
- tr := http.DefaultTransport.(*http.Transport).Clone()
+ tr := (&http.Transport{
+ ForceAttemptHTTP2: true,
+ MaxIdleConns: 100,
+ IdleConnTimeout: 90 * time.Second,
+ TLSHandshakeTimeout: 10 * time.Second,
+ ExpectContinueTimeout: 1 * time.Second,
+ }).Clone()
tr.RegisterProtocol("file", http.NewFileTransport(http.Dir("/")))
return tr
}
diff --git a/prober/derp_test.go b/prober/derp_test.go
index 364d57481ae20..15b99ced0696b 100644
--- a/prober/derp_test.go
+++ b/prober/derp_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -14,12 +16,12 @@ import (
"testing"
"time"
- "tailscale.com/derp"
- "tailscale.com/derp/derphttp"
- "tailscale.com/derp/derpserver"
- "tailscale.com/net/netmon"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/derp"
+ "github.com/metacubex/tailscale/derp/derphttp"
+ "github.com/metacubex/tailscale/derp/derpserver"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
)
func TestDerpProber(t *testing.T) {
diff --git a/prober/dns.go b/prober/dns.go
index cfef252716ae9..7eee5ec457d1f 100644
--- a/prober/dns.go
+++ b/prober/dns.go
@@ -10,7 +10,7 @@ import (
"net/netip"
"sync"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
// ForEachAddrOpts contains options for ForEachAddr. The zero value for all
diff --git a/prober/dns_example_test.go b/prober/dns_example_test.go
index 625ecec0c1411..442c3b5b5a236 100644
--- a/prober/dns_example_test.go
+++ b/prober/dns_example_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -15,8 +17,8 @@ import (
"os/signal"
"time"
- "tailscale.com/prober"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/prober"
+ "github.com/metacubex/tailscale/types/logger"
)
const (
diff --git a/prober/dns_test.go b/prober/dns_test.go
index 4eaea199ae289..89a4d47bb0b8e 100644
--- a/prober/dns_test.go
+++ b/prober/dns_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,12 +8,12 @@ package prober
import (
"context"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
"sync"
"testing"
- "tailscale.com/syncs"
+ "github.com/metacubex/tailscale/syncs"
)
func TestForEachAddr(t *testing.T) {
diff --git a/prober/histogram.go b/prober/histogram.go
index 5c52894f9eb02..2a5ad7caf37e1 100644
--- a/prober/histogram.go
+++ b/prober/histogram.go
@@ -4,7 +4,7 @@
package prober
import (
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"sync"
)
diff --git a/prober/histogram_test.go b/prober/histogram_test.go
index 2c7deea354a89..d959753c6870f 100644
--- a/prober/histogram_test.go
+++ b/prober/histogram_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/prober/http.go b/prober/http.go
index 144ed3fb55195..67c6e351be156 100644
--- a/prober/http.go
+++ b/prober/http.go
@@ -9,6 +9,7 @@ import (
"fmt"
"io"
"net/http"
+ "time"
)
const maxHTTPBody = 4 << 20 // MiB
@@ -35,7 +36,13 @@ func probeHTTP(ctx context.Context, url string, want []byte) error {
// Get a completely new transport each time, so we don't reuse a
// past connection.
- tr := http.DefaultTransport.(*http.Transport).Clone()
+ tr := (&http.Transport{
+ ForceAttemptHTTP2: true,
+ MaxIdleConns: 100,
+ IdleConnTimeout: 90 * time.Second,
+ TLSHandshakeTimeout: 10 * time.Second,
+ ExpectContinueTimeout: 1 * time.Second,
+ }).Clone()
defer tr.CloseIdleConnections()
c := &http.Client{
Transport: tr,
diff --git a/prober/prober.go b/prober/prober.go
index 40eef2faf43b1..02d54a077a9e5 100644
--- a/prober/prober.go
+++ b/prober/prober.go
@@ -8,24 +8,24 @@ package prober
import (
"bytes"
- "cmp"
"container/ring"
"context"
"encoding/json"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"hash/fnv"
"log"
- "maps"
"math/rand"
"net/http"
- "slices"
"sync"
"time"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tsweb"
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/sync/errgroup"
- "tailscale.com/syncs"
- "tailscale.com/tsweb"
)
// recentHistSize is the number of recent probe results and latencies to keep
diff --git a/prober/prober_test.go b/prober/prober_test.go
index 14b75d5b5c2b1..cac776eff6430 100644
--- a/prober/prober_test.go
+++ b/prober/prober_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -21,9 +23,9 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tsweb"
"github.com/prometheus/client_golang/prometheus/testutil"
- "tailscale.com/tstest"
- "tailscale.com/tsweb"
)
const (
diff --git a/prober/status.go b/prober/status.go
index a06d3d55c4e6c..5821704926e1d 100644
--- a/prober/status.go
+++ b/prober/status.go
@@ -11,8 +11,8 @@ import (
"strings"
"time"
- "tailscale.com/tsweb"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/tsweb"
+ "github.com/metacubex/tailscale/util/mak"
)
//go:embed status.html
diff --git a/prober/tls.go b/prober/tls.go
index 1247f9502e8f6..a30b556b76a7b 100644
--- a/prober/tls.go
+++ b/prober/tls.go
@@ -9,10 +9,10 @@ import (
"crypto/x509"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net/http"
"net/netip"
- "slices"
"time"
)
diff --git a/prober/tls_test.go b/prober/tls_test.go
index a32693762f291..6a5e0b7a93118 100644
--- a/prober/tls_test.go
+++ b/prober/tls_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/proxymap/proxymap.go b/proxymap/proxymap.go
index 2407371513d89..7ba52f469487c 100644
--- a/proxymap/proxymap.go
+++ b/proxymap/proxymap.go
@@ -11,8 +11,8 @@ import (
"strings"
"time"
- "tailscale.com/syncs"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/util/mak"
)
// Mapper tracks which localhost ip:ports correspond to which remote Tailscale
diff --git a/release/dist/cli/cli.go b/release/dist/cli/cli.go
index ca4977f5d2cbe..95245d11e9730 100644
--- a/release/dist/cli/cli.go
+++ b/release/dist/cli/cli.go
@@ -16,9 +16,9 @@ import (
"strings"
"time"
+ "github.com/metacubex/tailscale/clientupdate/distsign"
+ "github.com/metacubex/tailscale/release/dist"
"github.com/peterbourgon/ff/v3/ffcli"
- "tailscale.com/clientupdate/distsign"
- "tailscale.com/release/dist"
)
// CLI returns a CLI root command to build release packages.
diff --git a/release/dist/dist.go b/release/dist/dist.go
index 094d0a0e04c46..f685daa1388f1 100644
--- a/release/dist/dist.go
+++ b/release/dist/dist.go
@@ -20,7 +20,7 @@ import (
"sync"
"time"
- "tailscale.com/version/mkversion"
+ "github.com/metacubex/tailscale/version/mkversion"
)
// A Target is something that can be build in a Build.
diff --git a/release/dist/memoize.go b/release/dist/memoize.go
index bdf0f68ff9fd6..752ac99c8bf38 100644
--- a/release/dist/memoize.go
+++ b/release/dist/memoize.go
@@ -6,7 +6,7 @@ package dist
import (
"sync"
- "tailscale.com/util/deephash"
+ "github.com/metacubex/tailscale/util/deephash"
)
// MemoizedFn is a function that memoize.Do can call.
diff --git a/release/dist/qnap/pkgs.go b/release/dist/qnap/pkgs.go
index b505b1ac0e908..fd925161b7338 100644
--- a/release/dist/qnap/pkgs.go
+++ b/release/dist/qnap/pkgs.go
@@ -9,15 +9,15 @@ package qnap
import (
"embed"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io/fs"
"log"
"os"
"os/exec"
"path/filepath"
- "slices"
"sync"
- "tailscale.com/release/dist"
+ "github.com/metacubex/tailscale/release/dist"
)
type target struct {
@@ -168,7 +168,7 @@ var buildFiles embed.FS
// The qnapBuilds.tmpDir is filled with the contents of the buildFiles embedded
// FS for building.
//
-// We do this to allow for this tailscale.com/release/dist/qnap package to be
+// We do this to allow for this github.com/metacubex/tailscale/release/dist/qnap package to be
// used from both the corp and OSS repos. When built from OSS source directly,
// this is a superfluous extra step, but when imported as a go module to another
// repo (such as corp), we must do this to allow for the module's build files
@@ -220,11 +220,11 @@ func (m *qnapBuilds) buildInnerPackage(b *dist.Build, goenv map[string]string) (
if err := b.BuildWebClientAssets(); err != nil {
return nil, err
}
- ts, err := b.BuildGoBinary("tailscale.com/cmd/tailscale", goenv)
+ ts, err := b.BuildGoBinary("github.com/metacubex/tailscale/cmd/tailscale", goenv)
if err != nil {
return nil, err
}
- tsd, err := b.BuildGoBinary("tailscale.com/cmd/tailscaled", goenv)
+ tsd, err := b.BuildGoBinary("github.com/metacubex/tailscale/cmd/tailscaled", goenv)
if err != nil {
return nil, err
}
diff --git a/release/dist/qnap/targets.go b/release/dist/qnap/targets.go
index 3eef3cbbe693d..7298e59e177fb 100644
--- a/release/dist/qnap/targets.go
+++ b/release/dist/qnap/targets.go
@@ -4,9 +4,9 @@
package qnap
import (
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
- "tailscale.com/release/dist"
+ "github.com/metacubex/tailscale/release/dist"
)
// Targets defines the dist.Targets for QNAP devices.
diff --git a/release/dist/synology/pkgs.go b/release/dist/synology/pkgs.go
index c2fe6528e4dfe..87b747d7d07ba 100644
--- a/release/dist/synology/pkgs.go
+++ b/release/dist/synology/pkgs.go
@@ -18,7 +18,7 @@ import (
"path/filepath"
"time"
- "tailscale.com/release/dist"
+ "github.com/metacubex/tailscale/release/dist"
)
type target struct {
@@ -204,11 +204,11 @@ func (m *synologyBuilds) buildInnerPackage(b *dist.Build, dsmVersion int, goenv
if err := b.BuildWebClientAssets(); err != nil {
return nil, err
}
- ts, err := b.BuildGoBinary("tailscale.com/cmd/tailscale", goenv)
+ ts, err := b.BuildGoBinary("github.com/metacubex/tailscale/cmd/tailscale", goenv)
if err != nil {
return nil, err
}
- tsd, err := b.BuildGoBinary("tailscale.com/cmd/tailscaled", goenv)
+ tsd, err := b.BuildGoBinary("github.com/metacubex/tailscale/cmd/tailscaled", goenv)
if err != nil {
return nil, err
}
diff --git a/release/dist/synology/targets.go b/release/dist/synology/targets.go
index 2f08510557d8d..3f446d7ad1703 100644
--- a/release/dist/synology/targets.go
+++ b/release/dist/synology/targets.go
@@ -3,7 +3,7 @@
package synology
-import "tailscale.com/release/dist"
+import "github.com/metacubex/tailscale/release/dist"
var v5Models = []string{
"armv5",
diff --git a/release/dist/unixpkgs/pkgs.go b/release/dist/unixpkgs/pkgs.go
index 6e140d580b904..7f81512d84551 100644
--- a/release/dist/unixpkgs/pkgs.go
+++ b/release/dist/unixpkgs/pkgs.go
@@ -17,7 +17,7 @@ import (
"github.com/goreleaser/nfpm/v2"
"github.com/goreleaser/nfpm/v2/files"
- "tailscale.com/release/dist"
+ "github.com/metacubex/tailscale/release/dist"
)
type tgzTarget struct {
@@ -53,11 +53,11 @@ func (t *tgzTarget) Build(b *dist.Build) ([]string, error) {
if err := b.BuildWebClientAssets(); err != nil {
return nil, err
}
- ts, err := b.BuildGoBinary("tailscale.com/cmd/tailscale", t.goEnv)
+ ts, err := b.BuildGoBinary("github.com/metacubex/tailscale/cmd/tailscale", t.goEnv)
if err != nil {
return nil, err
}
- tsd, err := b.BuildGoBinary("tailscale.com/cmd/tailscaled", t.goEnv)
+ tsd, err := b.BuildGoBinary("github.com/metacubex/tailscale/cmd/tailscaled", t.goEnv)
if err != nil {
return nil, err
}
@@ -130,7 +130,7 @@ func (t *tgzTarget) Build(b *dist.Build) ([]string, error) {
if err := addDir(dir); err != nil {
return nil, err
}
- tailscaledDir, err := b.GoPkg("tailscale.com/cmd/tailscaled")
+ tailscaledDir, err := b.GoPkg("github.com/metacubex/tailscale/cmd/tailscaled")
if err != nil {
return nil, err
}
@@ -194,20 +194,20 @@ func (t *debTarget) Build(b *dist.Build) ([]string, error) {
if err := b.BuildWebClientAssets(); err != nil {
return nil, err
}
- ts, err := b.BuildGoBinary("tailscale.com/cmd/tailscale", t.goEnv)
+ ts, err := b.BuildGoBinary("github.com/metacubex/tailscale/cmd/tailscale", t.goEnv)
if err != nil {
return nil, err
}
- tsd, err := b.BuildGoBinary("tailscale.com/cmd/tailscaled", t.goEnv)
+ tsd, err := b.BuildGoBinary("github.com/metacubex/tailscale/cmd/tailscaled", t.goEnv)
if err != nil {
return nil, err
}
- tailscaledDir, err := b.GoPkg("tailscale.com/cmd/tailscaled")
+ tailscaledDir, err := b.GoPkg("github.com/metacubex/tailscale/cmd/tailscaled")
if err != nil {
return nil, err
}
- repoDir, err := b.GoPkg("tailscale.com")
+ repoDir, err := b.GoPkg("github.com/metacubex/tailscale")
if err != nil {
return nil, err
}
@@ -341,20 +341,20 @@ func (t *rpmTarget) Build(b *dist.Build) ([]string, error) {
if err := b.BuildWebClientAssets(); err != nil {
return nil, err
}
- ts, err := b.BuildGoBinary("tailscale.com/cmd/tailscale", t.goEnv)
+ ts, err := b.BuildGoBinary("github.com/metacubex/tailscale/cmd/tailscale", t.goEnv)
if err != nil {
return nil, err
}
- tsd, err := b.BuildGoBinary("tailscale.com/cmd/tailscaled", t.goEnv)
+ tsd, err := b.BuildGoBinary("github.com/metacubex/tailscale/cmd/tailscaled", t.goEnv)
if err != nil {
return nil, err
}
- tailscaledDir, err := b.GoPkg("tailscale.com/cmd/tailscaled")
+ tailscaledDir, err := b.GoPkg("github.com/metacubex/tailscale/cmd/tailscaled")
if err != nil {
return nil, err
}
- repoDir, err := b.GoPkg("tailscale.com")
+ repoDir, err := b.GoPkg("github.com/metacubex/tailscale")
if err != nil {
return nil, err
}
diff --git a/release/dist/unixpkgs/targets.go b/release/dist/unixpkgs/targets.go
index b5f96fc38b3f0..403f4eaf10a9f 100644
--- a/release/dist/unixpkgs/targets.go
+++ b/release/dist/unixpkgs/targets.go
@@ -8,7 +8,7 @@ import (
"sort"
"strings"
- "tailscale.com/release/dist"
+ "github.com/metacubex/tailscale/release/dist"
_ "github.com/goreleaser/nfpm/v2/deb"
_ "github.com/goreleaser/nfpm/v2/rpm"
diff --git a/safesocket/basic_test.go b/safesocket/basic_test.go
index 9cef300497422..3b6c0052407d3 100644
--- a/safesocket/basic_test.go
+++ b/safesocket/basic_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/safesocket/pipe_windows_test.go b/safesocket/pipe_windows_test.go
index 5d4e68cc251c9..cd516cd87e0fb 100644
--- a/safesocket/pipe_windows_test.go
+++ b/safesocket/pipe_windows_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,7 +9,7 @@ import (
"fmt"
"testing"
- "tailscale.com/util/winutil"
+ "github.com/metacubex/tailscale/util/winutil"
)
func init() {
diff --git a/safesocket/safesocket.go b/safesocket/safesocket.go
index 60291e1340558..8a7372c0bd4a7 100644
--- a/safesocket/safesocket.go
+++ b/safesocket/safesocket.go
@@ -12,8 +12,8 @@ import (
"runtime"
"time"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
)
type closeable interface {
diff --git a/safesocket/safesocket_darwin.go b/safesocket/safesocket_darwin.go
index aa67baaf82596..95493d5cc9be5 100644
--- a/safesocket/safesocket_darwin.go
+++ b/safesocket/safesocket_darwin.go
@@ -20,8 +20,8 @@ import (
"sync"
"time"
+ "github.com/metacubex/tailscale/version"
"golang.org/x/sys/unix"
- "tailscale.com/version"
)
func init() {
diff --git a/safesocket/safesocket_darwin_test.go b/safesocket/safesocket_darwin_test.go
index d828a80f5dfe2..8ec367ebf7041 100644
--- a/safesocket/safesocket_darwin_test.go
+++ b/safesocket/safesocket_darwin_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,7 +10,7 @@ import (
"strings"
"testing"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/tstest"
)
// TestSetCredentials verifies that calling SetCredentials
diff --git a/safesocket/safesocket_test.go b/safesocket/safesocket_test.go
index be2dd193d8e32..20afeefe49714 100644
--- a/safesocket/safesocket_test.go
+++ b/safesocket/safesocket_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/safeweb/http.go b/safeweb/http.go
index d52412bd35cc2..369074550421c 100644
--- a/safeweb/http.go
+++ b/safeweb/http.go
@@ -70,18 +70,18 @@
package safeweb
import (
- "cmp"
"context"
crand "crypto/rand"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"html/template"
"log"
- "maps"
"net"
"net/http"
"net/url"
"path"
- "slices"
"strings"
"github.com/gorilla/csrf"
diff --git a/safeweb/http_test.go b/safeweb/http_test.go
index fb298eb6ea18f..137cf1446d861 100644
--- a/safeweb/http_test.go
+++ b/safeweb/http_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/sessionrecording/connect.go b/sessionrecording/connect.go
index 6135688ca0153..c043d92e109bc 100644
--- a/sessionrecording/connect.go
+++ b/sessionrecording/connect.go
@@ -18,9 +18,9 @@ import (
"sync/atomic"
"time"
- "tailscale.com/net/netx"
- "tailscale.com/tailcfg"
- "tailscale.com/util/httpm"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/httpm"
)
const (
@@ -380,7 +380,13 @@ func (u *readCounter) Read(buf []byte) (int, error) {
// clientHTTP1 returns a claassic http.Client with a per-dial context. It uses
// dialCtx and adds a 5s timeout to it.
func clientHTTP1(dialCtx context.Context, dial netx.DialFunc) *http.Client {
- tr := http.DefaultTransport.(*http.Transport).Clone()
+ tr := (&http.Transport{
+ ForceAttemptHTTP2: true,
+ MaxIdleConns: 100,
+ IdleConnTimeout: 90 * time.Second,
+ TLSHandshakeTimeout: 10 * time.Second,
+ ExpectContinueTimeout: 1 * time.Second,
+ }).Clone()
tr.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
perAttemptCtx, cancel := context.WithTimeout(ctx, perDialAttemptTimeout)
defer cancel()
diff --git a/sessionrecording/connect_test.go b/sessionrecording/connect_test.go
index 3d1feff12f8de..5aa97134612c6 100644
--- a/sessionrecording/connect_test.go
+++ b/sessionrecording/connect_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -19,9 +21,9 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/net/memnet"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
- "tailscale.com/net/memnet"
)
func TestConnectToRecorder(t *testing.T) {
diff --git a/sessionrecording/event.go b/sessionrecording/event.go
index 0597048a2113f..f249987dc0d49 100644
--- a/sessionrecording/event.go
+++ b/sessionrecording/event.go
@@ -6,7 +6,7 @@ package sessionrecording
import (
"net/url"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/tailcfg"
)
const (
diff --git a/sessionrecording/header.go b/sessionrecording/header.go
index 95b70962cefd8..3fcd10412cee3 100644
--- a/sessionrecording/header.go
+++ b/sessionrecording/header.go
@@ -3,7 +3,7 @@
package sessionrecording
-import "tailscale.com/tailcfg"
+import "github.com/metacubex/tailscale/tailcfg"
// CastHeader is the header of an asciinema file.
type CastHeader struct {
diff --git a/ssh/tailssh/accept_env.go b/ssh/tailssh/accept_env.go
index 6354d41d76a6b..9966085c8c764 100644
--- a/ssh/tailssh/accept_env.go
+++ b/ssh/tailssh/accept_env.go
@@ -5,7 +5,7 @@ package tailssh
import (
"fmt"
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
)
diff --git a/ssh/tailssh/accept_env_test.go b/ssh/tailssh/accept_env_test.go
index fef13877a85c5..c9917cf8c5ee9 100644
--- a/ssh/tailssh/accept_env_test.go
+++ b/ssh/tailssh/accept_env_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/ssh/tailssh/auditd_linux.go b/ssh/tailssh/auditd_linux.go
index bddb901d5cebe..79b31019870d5 100644
--- a/ssh/tailssh/auditd_linux.go
+++ b/ssh/tailssh/auditd_linux.go
@@ -12,8 +12,8 @@ import (
"os"
"syscall"
+ "github.com/metacubex/tailscale/types/logger"
"golang.org/x/sys/unix"
- "tailscale.com/types/logger"
)
const (
diff --git a/ssh/tailssh/auditd_linux_test.go b/ssh/tailssh/auditd_linux_test.go
index c3c2302fe9e66..e7783ff5ddf89 100644
--- a/ssh/tailssh/auditd_linux_test.go
+++ b/ssh/tailssh/auditd_linux_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux && !android
-
package tailssh
import (
diff --git a/ssh/tailssh/c2n.go b/ssh/tailssh/c2n.go
index 621be74d4baba..3b3149356eeea 100644
--- a/ssh/tailssh/c2n.go
+++ b/ssh/tailssh/c2n.go
@@ -8,15 +8,15 @@ package tailssh
import (
"bytes"
"encoding/json"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/http"
"os/exec"
"runtime"
- "slices"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/lineiter"
"go4.org/mem"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/tailcfg"
- "tailscale.com/util/lineiter"
)
func handleC2NSSHUsernames(b *ipnlocal.LocalBackend, w http.ResponseWriter, r *http.Request) {
diff --git a/ssh/tailssh/hostkeys.go b/ssh/tailssh/hostkeys.go
index 8046a021a9308..5ae1a92a517e5 100644
--- a/ssh/tailssh/hostkeys.go
+++ b/ssh/tailssh/hostkeys.go
@@ -21,9 +21,9 @@ import (
"strings"
"sync"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/mak"
"golang.org/x/crypto/ssh"
- "tailscale.com/types/logger"
- "tailscale.com/util/mak"
)
// keyTypes are the SSH key types that we either try to read from the
diff --git a/ssh/tailssh/hostkeys_test.go b/ssh/tailssh/hostkeys_test.go
index 24a876454ea6e..13c0b3e01aa52 100644
--- a/ssh/tailssh/hostkeys_test.go
+++ b/ssh/tailssh/hostkeys_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux || (darwin && !ios)
-
package tailssh
import (
diff --git a/ssh/tailssh/incubator.go b/ssh/tailssh/incubator.go
index 48c65e8e51446..d51fc8c38f862 100644
--- a/ssh/tailssh/incubator.go
+++ b/ssh/tailssh/incubator.go
@@ -17,6 +17,7 @@ import (
"errors"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"io/fs"
"log"
@@ -25,7 +26,6 @@ import (
"os/exec"
"path/filepath"
"runtime"
- "slices"
"sort"
"strconv"
"strings"
@@ -34,16 +34,16 @@ import (
"time"
"github.com/creack/pty"
+ "github.com/metacubex/tailscale/cmd/tailscaled/childproc"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/version/distro"
"github.com/pkg/sftp"
gliderssh "github.com/tailscale/gliderssh"
"github.com/u-root/u-root/pkg/termios"
"golang.org/x/crypto/ssh"
"golang.org/x/sys/unix"
- "tailscale.com/cmd/tailscaled/childproc"
- "tailscale.com/hostinfo"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
- "tailscale.com/version/distro"
)
const (
diff --git a/ssh/tailssh/incubator_linux.go b/ssh/tailssh/incubator_linux.go
index cff46160758f3..1f62f9b4cae27 100644
--- a/ssh/tailssh/incubator_linux.go
+++ b/ssh/tailssh/incubator_linux.go
@@ -14,7 +14,7 @@ import (
"unsafe"
"github.com/godbus/dbus/v5"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
func init() {
diff --git a/ssh/tailssh/incubator_plan9.go b/ssh/tailssh/incubator_plan9.go
index 8d0031413e4a4..d851b8f6f056b 100644
--- a/ssh/tailssh/incubator_plan9.go
+++ b/ssh/tailssh/incubator_plan9.go
@@ -24,10 +24,10 @@ import (
"sync/atomic"
"github.com/go4org/plan9netshell"
+ "github.com/metacubex/tailscale/cmd/tailscaled/childproc"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
"github.com/pkg/sftp"
- "tailscale.com/cmd/tailscaled/childproc"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
)
func init() {
diff --git a/ssh/tailssh/privs_test.go b/ssh/tailssh/privs_test.go
index bd483e2b48fa2..21d6b28b1a9eb 100644
--- a/ssh/tailssh/privs_test.go
+++ b/ssh/tailssh/privs_test.go
@@ -1,13 +1,14 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux || darwin || freebsd || openbsd || netbsd || dragonfly
-
package tailssh
import (
"encoding/json"
"errors"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"os"
"os/exec"
"os/user"
@@ -15,13 +16,12 @@ import (
"reflect"
"regexp"
"runtime"
- "slices"
"strconv"
"syscall"
"testing"
- "tailscale.com/tstest"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/logger"
)
func TestDoDropPrivileges(t *testing.T) {
diff --git a/ssh/tailssh/tailssh.go b/ssh/tailssh/tailssh.go
index e01f78eb3ae50..5e9568f7189d0 100644
--- a/ssh/tailssh/tailssh.go
+++ b/ssh/tailssh/tailssh.go
@@ -13,8 +13,8 @@ import (
"encoding/json"
"errors"
"fmt"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"io"
- "maps"
"net"
"net/http"
"net/netip"
@@ -30,22 +30,22 @@ import (
"syscall"
"time"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/sessionrecording"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/backoff"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/httpm"
+ "github.com/metacubex/tailscale/util/mak"
gliderssh "github.com/tailscale/gliderssh"
"golang.org/x/crypto/ssh"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/net/tsaddr"
- "tailscale.com/net/tsdial"
- "tailscale.com/sessionrecording"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/util/backoff"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/httpm"
- "tailscale.com/util/mak"
)
var (
diff --git a/ssh/tailssh/tailssh_integration_test.go b/ssh/tailssh/tailssh_integration_test.go
index 7b70a6d512b3b..70961bc8816ae 100644
--- a/ssh/tailssh/tailssh_integration_test.go
+++ b/ssh/tailssh/tailssh_integration_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build integrationtest
-
package tailssh
import (
@@ -29,15 +29,15 @@ import (
"github.com/bramvdbogaerde/go-scp"
"github.com/google/go-cmp/cmp"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/set"
"github.com/pkg/sftp"
gliderssh "github.com/tailscale/gliderssh"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
- "tailscale.com/net/tsdial"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/netmap"
- "tailscale.com/util/set"
)
// This file contains integration tests of the SSH functionality. These tests
diff --git a/ssh/tailssh/tailssh_test.go b/ssh/tailssh/tailssh_test.go
index 04c9cd2f51d9e..5ee8b8a877436 100644
--- a/ssh/tailssh/tailssh_test.go
+++ b/ssh/tailssh/tailssh_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux || darwin
-
package tailssh
import (
@@ -14,6 +14,7 @@ import (
"encoding/json"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net"
"net/http"
@@ -24,7 +25,6 @@ import (
"os/user"
"reflect"
"runtime"
- "slices"
"strconv"
"strings"
"sync"
@@ -33,27 +33,27 @@ import (
"testing/synctest"
"time"
+ "github.com/metacubex/tailscale/cmd/testwrapper/flakytest"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/net/memnet"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/sessionrecording"
+ "github.com/metacubex/tailscale/tailcfg"
+ testssh "github.com/metacubex/tailscale/tempfork/sshtest/ssh"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/cibuild"
+ "github.com/metacubex/tailscale/util/lineiter"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/version/distro"
+ "github.com/metacubex/tailscale/wgengine"
gliderssh "github.com/tailscale/gliderssh"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
- "tailscale.com/cmd/testwrapper/flakytest"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/net/memnet"
- "tailscale.com/net/tsdial"
- "tailscale.com/sessionrecording"
- "tailscale.com/tailcfg"
- testssh "tailscale.com/tempfork/sshtest/ssh"
- "tailscale.com/tsd"
- "tailscale.com/tstest"
- "tailscale.com/types/key"
- "tailscale.com/types/logid"
- "tailscale.com/types/netmap"
- "tailscale.com/util/cibuild"
- "tailscale.com/util/lineiter"
- "tailscale.com/util/must"
- "tailscale.com/version/distro"
- "tailscale.com/wgengine"
)
func TestMatchRule(t *testing.T) {
diff --git a/ssh/tailssh/user.go b/ssh/tailssh/user.go
index 0d2bf31e7f0d5..76ce63a98ad6b 100644
--- a/ssh/tailssh/user.go
+++ b/ssh/tailssh/user.go
@@ -14,12 +14,12 @@ import (
"strconv"
"strings"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/util/lineiter"
+ "github.com/metacubex/tailscale/util/osuser"
+ "github.com/metacubex/tailscale/version/distro"
"go4.org/mem"
- "tailscale.com/envknob"
- "tailscale.com/hostinfo"
- "tailscale.com/util/lineiter"
- "tailscale.com/util/osuser"
- "tailscale.com/version/distro"
)
// userMeta is a wrapper around *user.User with extra fields.
diff --git a/syncs/locked_test.go b/syncs/locked_test.go
index 94481f9cb2205..e70af4ad144fd 100644
--- a/syncs/locked_test.go
+++ b/syncs/locked_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build go1.13 && !go1.19
-
package syncs
import (
diff --git a/syncs/oncevalue_go120.go b/syncs/oncevalue_go120.go
new file mode 100644
index 0000000000000..8ddd91c201891
--- /dev/null
+++ b/syncs/oncevalue_go120.go
@@ -0,0 +1,12 @@
+package syncs
+
+import "sync"
+
+func OnceValue[T any](f func() T) func() T {
+ var once sync.Once
+ var v T
+ return func() T {
+ once.Do(func() { v = f() })
+ return v
+ }
+}
diff --git a/syncs/pool_test.go b/syncs/pool_test.go
index 34ca9973ff334..cb76be0a543e7 100644
--- a/syncs/pool_test.go
+++ b/syncs/pool_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/syncs/shardedint.go b/syncs/shardedint.go
index c0fda341fb564..3d86dc99786a3 100644
--- a/syncs/shardedint.go
+++ b/syncs/shardedint.go
@@ -41,9 +41,10 @@ type intShard struct {
// Value returns the current value.
func (m *ShardedInt) Value() int64 {
var v int64
- for s := range m.sv.All {
+ m.sv.All(func(s *intShard) bool {
v += s.Load()
- }
+ return true
+ })
return v
}
@@ -51,9 +52,10 @@ func (m *ShardedInt) Value() int64 {
// This is intended for observability/debugging only.
func (m *ShardedInt) GetDistribution() []int64 {
v := make([]int64, 0, m.sv.Len())
- for s := range m.sv.All {
+ m.sv.All(func(s *intShard) bool {
v = append(v, s.Load())
- }
+ return true
+ })
return v
}
diff --git a/syncs/shardedint_test.go b/syncs/shardedint_test.go
index c50e411d03f49..4948a26316bb6 100644
--- a/syncs/shardedint_test.go
+++ b/syncs/shardedint_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,8 +10,8 @@ import (
"sync"
"testing"
- . "tailscale.com/syncs"
- "tailscale.com/tstest"
+ . "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tstest"
)
var (
diff --git a/syncs/shardedmap_test.go b/syncs/shardedmap_test.go
index 0491bf3dd1fbf..36aa1316bb5ad 100644
--- a/syncs/shardedmap_test.go
+++ b/syncs/shardedmap_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/syncs/shardvalue_test.go b/syncs/shardvalue_test.go
index ab34527abd77f..05ab2cf79794c 100644
--- a/syncs/shardvalue_test.go
+++ b/syncs/shardvalue_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/syncs/syncs.go b/syncs/syncs.go
index d447b2e7bc4e0..16b61b03611e9 100644
--- a/syncs/syncs.go
+++ b/syncs/syncs.go
@@ -6,11 +6,11 @@ package syncs
import (
"context"
- "iter"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
"sync"
"sync/atomic"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/util/mak"
)
// ClosedChan returns a channel that's already closed.
@@ -396,7 +396,9 @@ func (m *Map[K, V]) Len() int {
func (m *Map[K, V]) Clear() {
m.mu.Lock()
defer m.mu.Unlock()
- clear(m.m)
+ for k := range m.m {
+ delete(m.m, k)
+ }
}
// Swap stores the value for the provided key, and returns the previous value
diff --git a/syncs/syncs_test.go b/syncs/syncs_test.go
index 1e79448ad961e..ab43f300ef727 100644
--- a/syncs/syncs_test.go
+++ b/syncs/syncs_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,8 +7,8 @@ package syncs
import (
"context"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"io"
- "maps"
"os"
"sync"
"testing"
diff --git a/tailcfg/derpmap.go b/tailcfg/derpmap.go
index c18b04ea11342..9b8440af4f319 100644
--- a/tailcfg/derpmap.go
+++ b/tailcfg/derpmap.go
@@ -7,7 +7,7 @@ import (
"net/netip"
"sort"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/types/key"
)
// DERPMap describes the set of DERP packet relay servers that are available.
diff --git a/tailcfg/proto_port_range.go b/tailcfg/proto_port_range.go
index 63012e93b2b8e..ebf9a90bb0420 100644
--- a/tailcfg/proto_port_range.go
+++ b/tailcfg/proto_port_range.go
@@ -8,8 +8,8 @@ import (
"strconv"
"strings"
- "tailscale.com/types/ipproto"
- "tailscale.com/util/vizerror"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/util/vizerror"
)
var (
diff --git a/tailcfg/proto_port_range_test.go b/tailcfg/proto_port_range_test.go
index 2fa6c0da0750d..d64925b8d0c2e 100644
--- a/tailcfg/proto_port_range_test.go
+++ b/tailcfg/proto_port_range_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,8 +9,8 @@ import (
"encoding"
"testing"
- "tailscale.com/types/ipproto"
- "tailscale.com/util/vizerror"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/util/vizerror"
)
var _ encoding.TextUnmarshaler = (*ProtoPortRange)(nil)
diff --git a/tailcfg/tailcfg.go b/tailcfg/tailcfg.go
index 0cb7597c345a1..73a182104e085 100644
--- a/tailcfg/tailcfg.go
+++ b/tailcfg/tailcfg.go
@@ -5,32 +5,32 @@
// the node and the coordination server.
package tailcfg
-//go:generate go run tailscale.com/cmd/viewer --type=User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,RegisterResponseAuth,RegisterRequest,DERPHomeParams,DERPRegion,DERPMap,DERPNode,SSHRule,SSHAction,SSHPrincipal,ControlDialPlan,Location,UserProfile,VIPService,SSHPolicy --clonefunc
+//go:generate go run github.com/metacubex/tailscale/cmd/viewer --type=User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,RegisterResponseAuth,RegisterRequest,DERPHomeParams,DERPRegion,DERPMap,DERPNode,SSHRule,SSHAction,SSHPrincipal,ControlDialPlan,Location,UserProfile,VIPService,SSHPolicy --clonefunc
import (
"bytes"
- "cmp"
"encoding/json"
"errors"
"fmt"
- "maps"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"reflect"
- "slices"
"strconv"
"strings"
"time"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/types/dnstype"
- "tailscale.com/types/key"
- "tailscale.com/types/opt"
- "tailscale.com/types/structs"
- "tailscale.com/types/tkatype"
- "tailscale.com/types/views"
- "tailscale.com/util/dnsname"
- "tailscale.com/util/slicesx"
- "tailscale.com/util/vizerror"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/structs"
+ "github.com/metacubex/tailscale/types/tkatype"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/util/vizerror"
)
// CapabilityVersion represents the client's capability level. That
@@ -435,8 +435,8 @@ type Node struct {
// Capabilities are capabilities that the node has.
// They're free-form strings, but should be in the form of URLs/URIs
// such as:
- // "https://tailscale.com/cap/is-admin"
- // "https://tailscale.com/cap/file-sharing"
+ // "https://github.com/metacubex/tailscale/cap/is-admin"
+ // "https://github.com/metacubex/tailscale/cap/file-sharing"
//
// Deprecated: use CapMap instead. See https://github.com/tailscale/tailscale/issues/11508
Capabilities []NodeCapability `json:",omitempty"`
@@ -1539,50 +1539,50 @@ type CapGrant struct {
// the peer communicates with the node that has this rule. Its meaning is
// application-defined.
//
-// It must be a URL like "https://tailscale.com/cap/file-send".
+// It must be a URL like "https://github.com/metacubex/tailscale/cap/file-send".
type PeerCapability string
const (
// PeerCapabilityFileSharingTarget grants the current node the ability to send
// files to the peer which has this capability.
- PeerCapabilityFileSharingTarget PeerCapability = "https://tailscale.com/cap/file-sharing-target"
+ PeerCapabilityFileSharingTarget PeerCapability = "https://github.com/metacubex/tailscale/cap/file-sharing-target"
// PeerCapabilityFileSharingSend grants the ability to receive files from a
// node that's owned by a different user.
- PeerCapabilityFileSharingSend PeerCapability = "https://tailscale.com/cap/file-send"
+ PeerCapabilityFileSharingSend PeerCapability = "https://github.com/metacubex/tailscale/cap/file-send"
// PeerCapabilityDebugPeer grants the ability for a peer to read this node's
// goroutines, metrics, magicsock internal state, etc.
- PeerCapabilityDebugPeer PeerCapability = "https://tailscale.com/cap/debug-peer"
+ PeerCapabilityDebugPeer PeerCapability = "https://github.com/metacubex/tailscale/cap/debug-peer"
// PeerCapabilityWakeOnLAN grants the ability to send a Wake-On-LAN packet.
- PeerCapabilityWakeOnLAN PeerCapability = "https://tailscale.com/cap/wake-on-lan"
+ PeerCapabilityWakeOnLAN PeerCapability = "https://github.com/metacubex/tailscale/cap/wake-on-lan"
// PeerCapabilityIngress grants the ability for a peer to send ingress traffic.
- PeerCapabilityIngress PeerCapability = "https://tailscale.com/cap/ingress"
+ PeerCapabilityIngress PeerCapability = "https://github.com/metacubex/tailscale/cap/ingress"
// PeerCapabilityWebUI grants the ability for a peer to edit features from the
// device Web UI.
- PeerCapabilityWebUI PeerCapability = "tailscale.com/cap/webui"
+ PeerCapabilityWebUI PeerCapability = "github.com/metacubex/tailscale/cap/webui"
// PeerCapabilityTaildrive grants the ability for a peer to access Taildrive
// shares.
- PeerCapabilityTaildrive PeerCapability = "tailscale.com/cap/drive"
+ PeerCapabilityTaildrive PeerCapability = "github.com/metacubex/tailscale/cap/drive"
// PeerCapabilityTaildriveSharer indicates that a peer has the ability to
// share folders with us.
- PeerCapabilityTaildriveSharer PeerCapability = "tailscale.com/cap/drive-sharer"
+ PeerCapabilityTaildriveSharer PeerCapability = "github.com/metacubex/tailscale/cap/drive-sharer"
// PeerCapabilityKubernetes grants a peer Kubernetes-specific
// capabilities, such as the ability to impersonate specific Tailscale
// user groups as Kubernetes user groups. This capability is read by
// peers that are Tailscale Kubernetes operator instances.
- PeerCapabilityKubernetes PeerCapability = "tailscale.com/cap/kubernetes"
+ PeerCapabilityKubernetes PeerCapability = "github.com/metacubex/tailscale/cap/kubernetes"
// PeerCapabilityRelay grants the ability for a peer to allocate relay
// endpoints.
- PeerCapabilityRelay PeerCapability = "tailscale.com/cap/relay"
+ PeerCapabilityRelay PeerCapability = "github.com/metacubex/tailscale/cap/relay"
// PeerCapabilityRelayTarget grants the current node the ability to allocate
// relay endpoints to the peer which has this capability.
- PeerCapabilityRelayTarget PeerCapability = "tailscale.com/cap/relay-target"
+ PeerCapabilityRelayTarget PeerCapability = "github.com/metacubex/tailscale/cap/relay-target"
// PeerCapabilityTsIDP grants a peer tsidp-specific
// capabilities, such as the ability to add user groups to the OIDC
// claim
- PeerCapabilityTsIDP PeerCapability = "tailscale.com/cap/tsidp"
+ PeerCapabilityTsIDP PeerCapability = "github.com/metacubex/tailscale/cap/tsidp"
)
// NodeCapMap is a map of capabilities to their optional values. It is valid for
@@ -1594,7 +1594,7 @@ type NodeCapMap map[NodeCapability][]RawMessage
// Equal reports whether c and c2 are equal.
func (c NodeCapMap) Equal(c2 NodeCapMap) bool {
- return maps.EqualFunc(c, c2, slices.Equal)
+ return maps.EqualFunc(c, c2, func(a, b []RawMessage) bool { return slices.Equal(a, b) })
}
// UnmarshalNodeCapJSON unmarshals each JSON value in cm[cap] as T.
@@ -1613,12 +1613,18 @@ func UnmarshalNodeCapViewJSON[T any](cm views.MapSlice[NodeCapability, RawMessag
return nil, nil
}
out := make([]T, 0, vals.Len())
- for _, v := range vals.All() {
+ var retErr error
+ vals.All()(func(_ int, v RawMessage) bool {
var t T
if err := json.Unmarshal([]byte(v), &t); err != nil {
- return nil, err
+ retErr = err
+ return false
}
out = append(out, t)
+ return true
+ })
+ if retErr != nil {
+ return nil, retErr
}
return out, nil
}
@@ -1655,12 +1661,18 @@ func UnmarshalCapViewJSON[T any](cm views.MapSlice[PeerCapability, RawMessage],
return nil, nil
}
out := make([]T, 0, vals.Len())
- for _, v := range vals.All() {
+ var retErr error
+ vals.All()(func(_ int, v RawMessage) bool {
var t T
if err := json.Unmarshal([]byte(v), &t); err != nil {
- return nil, err
+ retErr = err
+ return false
}
out = append(out, t)
+ return true
+ })
+ if retErr != nil {
+ return nil, retErr
}
return out, nil
}
@@ -2440,7 +2452,7 @@ type Oauth2Token struct {
// NodeCapability represents a capability granted to the self node as listed in
// MapResponse.Node.Capabilities.
//
-// It must be a URL like "https://tailscale.com/cap/file-sharing", or a
+// It must be a URL like "https://github.com/metacubex/tailscale/cap/file-sharing", or a
// well-known capability name like "funnel". The latter is only allowed for
// Tailscale-defined capabilities.
//
@@ -2463,26 +2475,26 @@ func (p NodeCapabilityPrefix) ToAttribute(value string) NodeCapability {
}
const (
- CapabilityFileSharing NodeCapability = "https://tailscale.com/cap/file-sharing"
- CapabilityAdmin NodeCapability = "https://tailscale.com/cap/is-admin"
- CapabilityOwner NodeCapability = "https://tailscale.com/cap/is-owner"
- CapabilitySSH NodeCapability = "https://tailscale.com/cap/ssh" // feature enabled/available
- CapabilitySSHRuleIn NodeCapability = "https://tailscale.com/cap/ssh-rule-in" // some SSH rule reach this node
- CapabilityDataPlaneAuditLogs NodeCapability = "https://tailscale.com/cap/data-plane-audit-logs" // feature enabled
- CapabilityDebug NodeCapability = "https://tailscale.com/cap/debug" // exposes debug endpoints over the PeerAPI
+ CapabilityFileSharing NodeCapability = "https://github.com/metacubex/tailscale/cap/file-sharing"
+ CapabilityAdmin NodeCapability = "https://github.com/metacubex/tailscale/cap/is-admin"
+ CapabilityOwner NodeCapability = "https://github.com/metacubex/tailscale/cap/is-owner"
+ CapabilitySSH NodeCapability = "https://github.com/metacubex/tailscale/cap/ssh" // feature enabled/available
+ CapabilitySSHRuleIn NodeCapability = "https://github.com/metacubex/tailscale/cap/ssh-rule-in" // some SSH rule reach this node
+ CapabilityDataPlaneAuditLogs NodeCapability = "https://github.com/metacubex/tailscale/cap/data-plane-audit-logs" // feature enabled
+ CapabilityDebug NodeCapability = "https://github.com/metacubex/tailscale/cap/debug" // exposes debug endpoints over the PeerAPI
CapabilityHTTPS NodeCapability = "https"
// CapabilityMacUIV2 makes the macOS GUI enable its v2 mode.
- CapabilityMacUIV2 NodeCapability = "https://tailscale.com/cap/mac-ui-v2"
+ CapabilityMacUIV2 NodeCapability = "https://github.com/metacubex/tailscale/cap/mac-ui-v2"
// CapabilityServicesInDesktopClients enables services list/menu/section in desktop clients.
// If this capability is not present, desktop clients should not show services.
- CapabilityServicesInDesktopClients NodeCapability = "https://tailscale.com/cap/services-in-desktop-clients"
+ CapabilityServicesInDesktopClients NodeCapability = "https://github.com/metacubex/tailscale/cap/services-in-desktop-clients"
// CapabilityBindToInterfaceByRoute changes how Darwin nodes create
// sockets (in the net/netns package). See that package for more
// details on the behaviour of this capability.
- CapabilityBindToInterfaceByRoute NodeCapability = "https://tailscale.com/cap/bind-to-interface-by-route"
+ CapabilityBindToInterfaceByRoute NodeCapability = "https://github.com/metacubex/tailscale/cap/bind-to-interface-by-route"
// NodeAttrDisableAndroidBindToActiveNetwork disables binding sockets to the
// currently active network on Android, which is enabled by default.
@@ -2495,41 +2507,41 @@ const (
// macOS and iOS clients) to override the default interface, this capability
// disables that and uses the default behavior (of parsing the routing
// table).
- CapabilityDebugDisableAlternateDefaultRouteInterface NodeCapability = "https://tailscale.com/cap/debug-disable-alternate-default-route-interface"
+ CapabilityDebugDisableAlternateDefaultRouteInterface NodeCapability = "https://github.com/metacubex/tailscale/cap/debug-disable-alternate-default-route-interface"
// CapabilityDebugDisableBindConnToInterface disables the automatic binding
// of connections to the default network interface on Darwin nodes.
- CapabilityDebugDisableBindConnToInterface NodeCapability = "https://tailscale.com/cap/debug-disable-bind-conn-to-interface"
+ CapabilityDebugDisableBindConnToInterface NodeCapability = "https://github.com/metacubex/tailscale/cap/debug-disable-bind-conn-to-interface"
// CapabilityDebugDisableBindConnToInterface disables the automatic binding
// of connections to the default network interface on Darwin nodes using network extensions
- CapabilityDebugDisableBindConnToInterfaceAppleExt NodeCapability = "https://tailscale.com/cap/debug-disable-bind-conn-to-interface-apple-ext"
+ CapabilityDebugDisableBindConnToInterfaceAppleExt NodeCapability = "https://github.com/metacubex/tailscale/cap/debug-disable-bind-conn-to-interface-apple-ext"
// CapabilityTailnetLock indicates the node may initialize tailnet lock.
- CapabilityTailnetLock NodeCapability = "https://tailscale.com/cap/tailnet-lock"
+ CapabilityTailnetLock NodeCapability = "https://github.com/metacubex/tailscale/cap/tailnet-lock"
// Funnel warning capabilities used for reporting errors to the user.
// CapabilityWarnFunnelNoInvite indicates whether Funnel is enabled for the tailnet.
// This cap is no longer used 2023-08-09 onwards.
- CapabilityWarnFunnelNoInvite NodeCapability = "https://tailscale.com/cap/warn-funnel-no-invite"
+ CapabilityWarnFunnelNoInvite NodeCapability = "https://github.com/metacubex/tailscale/cap/warn-funnel-no-invite"
// CapabilityWarnFunnelNoHTTPS indicates HTTPS has not been enabled for the tailnet.
// This cap is no longer used 2023-08-09 onwards.
- CapabilityWarnFunnelNoHTTPS NodeCapability = "https://tailscale.com/cap/warn-funnel-no-https"
+ CapabilityWarnFunnelNoHTTPS NodeCapability = "https://github.com/metacubex/tailscale/cap/warn-funnel-no-https"
// Debug logging capabilities
// CapabilityDebugTSDNSResolution enables verbose debug logging for DNS
// resolution for Tailscale-controlled domains (the control server, log
// server, DERP servers, etc.)
- CapabilityDebugTSDNSResolution NodeCapability = "https://tailscale.com/cap/debug-ts-dns-resolution"
+ CapabilityDebugTSDNSResolution NodeCapability = "https://github.com/metacubex/tailscale/cap/debug-ts-dns-resolution"
// CapabilityFunnelPorts specifies the ports that the Funnel is available on.
// The ports are specified as a comma-separated list of port numbers or port
// ranges (e.g. "80,443,8080-8090") in the ports query parameter.
- // e.g. https://tailscale.com/cap/funnel-ports?ports=80,443,8080-8090
- CapabilityFunnelPorts NodeCapability = "https://tailscale.com/cap/funnel-ports"
+ // e.g. https://github.com/metacubex/tailscale/cap/funnel-ports?ports=80,443,8080-8090
+ CapabilityFunnelPorts NodeCapability = "https://github.com/metacubex/tailscale/cap/funnel-ports"
// NodeAttrOnlyTCP443 specifies that the client should not attempt to generate
// any outbound traffic that isn't TCP on port 443 (HTTPS). This is used for
@@ -2879,7 +2891,7 @@ type SetDeviceAttributesRequest struct {
// Attributes not in the map are left unchanged.
// The value can be a string, float64, bool, or nil to delete.
//
-// See https://tailscale.com/s/api-device-posture-attrs.
+// See https://github.com/metacubex/tailscale/s/api-device-posture-attrs.
//
// TODO(bradfitz): add struct type for specifying optional associated data
// for each attribute value, like an expiry time?
diff --git a/tailcfg/tailcfg_clone.go b/tailcfg/tailcfg_clone.go
index f226563060b7f..064f32577e7de 100644
--- a/tailcfg/tailcfg_clone.go
+++ b/tailcfg/tailcfg_clone.go
@@ -1,22 +1,30 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-// Code generated by tailscale.com/cmd/cloner; DO NOT EDIT.
+// Code generated by github.com/metacubex/tailscale/cmd/cloner; DO NOT EDIT.
package tailcfg
import (
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"net/netip"
"time"
- "tailscale.com/types/dnstype"
- "tailscale.com/types/key"
- "tailscale.com/types/opt"
- "tailscale.com/types/structs"
- "tailscale.com/types/tkatype"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/structs"
+ "github.com/metacubex/tailscale/types/tkatype"
)
+func clonePtr[T any](p *T) *T {
+ if p == nil {
+ return nil
+ }
+ v := *p
+ return &v
+}
+
// Clone makes a deep copy of User.
// The result aliases no memory with the original.
func (src *User) Clone() *User {
@@ -52,10 +60,10 @@ func (src *Node) Clone() *Node {
dst.Tags = append(src.Tags[:0:0], src.Tags...)
dst.PrimaryRoutes = append(src.PrimaryRoutes[:0:0], src.PrimaryRoutes...)
if dst.LastSeen != nil {
- dst.LastSeen = new(*src.LastSeen)
+ dst.LastSeen = clonePtr(src.LastSeen)
}
if dst.Online != nil {
- dst.Online = new(*src.Online)
+ dst.Online = clonePtr(src.Online)
}
dst.Capabilities = append(src.Capabilities[:0:0], src.Capabilities...)
if dst.CapMap != nil {
@@ -65,10 +73,10 @@ func (src *Node) Clone() *Node {
}
}
if dst.SelfNodeV4MasqAddrForThisPeer != nil {
- dst.SelfNodeV4MasqAddrForThisPeer = new(*src.SelfNodeV4MasqAddrForThisPeer)
+ dst.SelfNodeV4MasqAddrForThisPeer = clonePtr(src.SelfNodeV4MasqAddrForThisPeer)
}
if dst.SelfNodeV6MasqAddrForThisPeer != nil {
- dst.SelfNodeV6MasqAddrForThisPeer = new(*src.SelfNodeV6MasqAddrForThisPeer)
+ dst.SelfNodeV6MasqAddrForThisPeer = clonePtr(src.SelfNodeV6MasqAddrForThisPeer)
}
if src.ExitNodeDNSResolvers != nil {
dst.ExitNodeDNSResolvers = make([]*dnstype.Resolver, len(src.ExitNodeDNSResolvers))
@@ -138,10 +146,10 @@ func (src *Hostinfo) Clone() *Hostinfo {
dst.NetInfo = src.NetInfo.Clone()
dst.SSH_HostKeys = append(src.SSH_HostKeys[:0:0], src.SSH_HostKeys...)
if dst.Location != nil {
- dst.Location = new(*src.Location)
+ dst.Location = clonePtr(src.Location)
}
if dst.TPM != nil {
- dst.TPM = new(*src.TPM)
+ dst.TPM = clonePtr(src.TPM)
}
return dst
}
@@ -340,7 +348,7 @@ func (src *RegisterResponseAuth) Clone() *RegisterResponseAuth {
dst := new(RegisterResponseAuth)
*dst = *src
if dst.Oauth2Token != nil {
- dst.Oauth2Token = new(*src.Oauth2Token)
+ dst.Oauth2Token = clonePtr(src.Oauth2Token)
}
return dst
}
@@ -364,7 +372,7 @@ func (src *RegisterRequest) Clone() *RegisterRequest {
dst.Hostinfo = src.Hostinfo.Clone()
dst.NodeKeySignature = append(src.NodeKeySignature[:0:0], src.NodeKeySignature...)
if dst.Timestamp != nil {
- dst.Timestamp = new(*src.Timestamp)
+ dst.Timestamp = clonePtr(src.Timestamp)
}
dst.DeviceCert = append(src.DeviceCert[:0:0], src.DeviceCert...)
dst.Signature = append(src.Signature[:0:0], src.Signature...)
@@ -422,7 +430,7 @@ func (src *DERPRegion) Clone() *DERPRegion {
if src.Nodes[i] == nil {
dst.Nodes[i] = nil
} else {
- dst.Nodes[i] = new(*src.Nodes[i])
+ dst.Nodes[i] = clonePtr(src.Nodes[i])
}
}
}
@@ -506,7 +514,7 @@ func (src *SSHRule) Clone() *SSHRule {
dst := new(SSHRule)
*dst = *src
if dst.RuleExpires != nil {
- dst.RuleExpires = new(*src.RuleExpires)
+ dst.RuleExpires = clonePtr(src.RuleExpires)
}
if src.Principals != nil {
dst.Principals = make([]*SSHPrincipal, len(src.Principals))
@@ -543,7 +551,7 @@ func (src *SSHAction) Clone() *SSHAction {
*dst = *src
dst.Recorders = append(src.Recorders[:0:0], src.Recorders...)
if dst.OnRecordingFailure != nil {
- dst.OnRecordingFailure = new(*src.OnRecordingFailure)
+ dst.OnRecordingFailure = clonePtr(src.OnRecordingFailure)
}
return dst
}
diff --git a/tailcfg/tailcfg_test.go b/tailcfg/tailcfg_test.go
index 8dd9191b63c84..90b35687236c0 100644
--- a/tailcfg/tailcfg_test.go
+++ b/tailcfg/tailcfg_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -13,11 +15,11 @@ import (
"testing"
"time"
- . "tailscale.com/tailcfg"
- "tailscale.com/tstest/deptest"
- "tailscale.com/types/key"
- "tailscale.com/types/opt"
- "tailscale.com/util/must"
+ . "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest/deptest"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/util/must"
)
func fieldsOf(t reflect.Type) (fields []string) {
@@ -874,9 +876,9 @@ func TestDeps(t *testing.T) {
BadDeps: map[string]string{
// Make sure we don't again accidentally bring in a dependency on
// drive or its transitive dependencies
- "testing": "do not use testing package in production code",
- "tailscale.com/drive/driveimpl": "https://github.com/tailscale/tailscale/pull/10631",
- "github.com/studio-b12/gowebdav": "https://github.com/tailscale/tailscale/pull/10631",
+ "testing": "do not use testing package in production code",
+ "github.com/metacubex/tailscale/drive/driveimpl": "https://github.com/tailscale/tailscale/pull/10631",
+ "github.com/studio-b12/gowebdav": "https://github.com/tailscale/tailscale/pull/10631",
},
}.Check(t)
}
diff --git a/tailcfg/tailcfg_view.go b/tailcfg/tailcfg_view.go
index 9900efbcc3d63..26a22004b4220 100644
--- a/tailcfg/tailcfg_view.go
+++ b/tailcfg/tailcfg_view.go
@@ -11,17 +11,17 @@ import (
"net/netip"
"time"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/types/dnstype"
- "tailscale.com/types/key"
- "tailscale.com/types/opt"
- "tailscale.com/types/structs"
- "tailscale.com/types/tkatype"
- "tailscale.com/types/views"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/structs"
+ "github.com/metacubex/tailscale/types/tkatype"
+ "github.com/metacubex/tailscale/types/views"
)
-//go:generate go run tailscale.com/cmd/cloner -clonefunc=true -type=User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,RegisterResponseAuth,RegisterRequest,DERPHomeParams,DERPRegion,DERPMap,DERPNode,SSHRule,SSHAction,SSHPrincipal,ControlDialPlan,Location,UserProfile,VIPService,SSHPolicy
+//go:generate go run github.com/metacubex/tailscale/cmd/cloner -clonefunc=true -type=User,Node,Hostinfo,NetInfo,Login,DNSConfig,RegisterResponse,RegisterResponseAuth,RegisterRequest,DERPHomeParams,DERPRegion,DERPMap,DERPNode,SSHRule,SSHAction,SSHPrincipal,ControlDialPlan,Location,UserProfile,VIPService,SSHPolicy
// View returns a read-only view of User.
func (p *User) View() UserView {
@@ -273,8 +273,8 @@ func (v NodeView) MachineAuthorized() bool { return v.ж.MachineAuthorized }
// They're free-form strings, but should be in the form of URLs/URIs
// such as:
//
-// "https://tailscale.com/cap/is-admin"
-// "https://tailscale.com/cap/file-sharing"
+// "https://github.com/metacubex/tailscale/cap/is-admin"
+// "https://github.com/metacubex/tailscale/cap/file-sharing"
//
// Deprecated: use CapMap instead. See https://github.com/tailscale/tailscale/issues/11508
func (v NodeView) Capabilities() views.Slice[NodeCapability] { return views.SliceOf(v.ж.Capabilities) }
diff --git a/tailcfg/tka.go b/tailcfg/tka.go
index 29c17b7567198..387ff593dfd96 100644
--- a/tailcfg/tka.go
+++ b/tailcfg/tka.go
@@ -4,8 +4,8 @@
package tailcfg
import (
- "tailscale.com/types/key"
- "tailscale.com/types/tkatype"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/tkatype"
)
// TKAInitBeginRequest submits a genesis AUM to seed the creation of the
diff --git a/tempfork/acme/acme_test.go b/tempfork/acme/acme_test.go
index f0c45aea9ab03..fc846427f254d 100644
--- a/tempfork/acme/acme_test.go
+++ b/tempfork/acme/acme_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/acme/http_test.go b/tempfork/acme/http_test.go
index d124e4e219abe..9bdf04e8ac90a 100644
--- a/tempfork/acme/http_test.go
+++ b/tempfork/acme/http_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/acme/jws_test.go b/tempfork/acme/jws_test.go
index d5f00ba2d3245..eba6ac1af949d 100644
--- a/tempfork/acme/jws_test.go
+++ b/tempfork/acme/jws_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/acme/rfc8555_test.go b/tempfork/acme/rfc8555_test.go
index ec51a7a5ed654..5cb1306917223 100644
--- a/tempfork/acme/rfc8555_test.go
+++ b/tempfork/acme/rfc8555_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/acme/sync_to_upstream_test.go b/tempfork/acme/sync_to_upstream_test.go
index e22c8c1a86d01..4bb7928011da1 100644
--- a/tempfork/acme/sync_to_upstream_test.go
+++ b/tempfork/acme/sync_to_upstream_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
package acme
import (
@@ -14,7 +16,7 @@ import (
// Verify that the files tempfork/acme/*.go (other than this test file) match the
// files in "github.com/tailscale/golang-x-crypto/acme" which is where we develop
// our fork of golang.org/x/crypto/acme and merge with upstream, but then we vendor
-// just its acme package into tailscale.com/tempfork/acme.
+// just its acme package into github.com/metacubex/tailscale/tempfork/acme.
//
// Development workflow:
//
diff --git a/tempfork/acme/types_test.go b/tempfork/acme/types_test.go
index 59ce7e7602ca3..0d2235ba022a8 100644
--- a/tempfork/acme/types_test.go
+++ b/tempfork/acme/types_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/heap/heap_test.go b/tempfork/heap/heap_test.go
index ddaf47a7f59e0..ae3e52efd0b50 100644
--- a/tempfork/heap/heap_test.go
+++ b/tempfork/heap/heap_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/pkgdoc/pkgdoc.go b/tempfork/pkgdoc/pkgdoc.go
index cab38dd48ec32..e3850d691232b 100644
--- a/tempfork/pkgdoc/pkgdoc.go
+++ b/tempfork/pkgdoc/pkgdoc.go
@@ -10,6 +10,7 @@ import (
"bytes"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"go/ast"
"go/build"
"go/doc"
@@ -19,7 +20,6 @@ import (
"io"
"io/fs"
"log"
- "slices"
)
const (
@@ -206,7 +206,7 @@ func (pkg *Package) bugs() {
// PackageDoc generates Markdown documentation for the package in the given
// directory. importPath is the full Go import path of that package (e.g.
-// "tailscale.com/tsnet"); it's used to render [Symbol] doc links to the
+// "github.com/metacubex/tailscale/tsnet"); it's used to render [Symbol] doc links to the
// right pkg.go.dev URL. If importPath is empty, build.ImportDir's guess
// is used (typically "." for module-based repos).
func PackageDoc(dir, importPath string) ([]byte, error) {
diff --git a/tempfork/sshtest/ssh/benchmark_test.go b/tempfork/sshtest/ssh/benchmark_test.go
index b356330b469d2..26570f3b5dc8d 100644
--- a/tempfork/sshtest/ssh/benchmark_test.go
+++ b/tempfork/sshtest/ssh/benchmark_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/buffer_test.go b/tempfork/sshtest/ssh/buffer_test.go
index d5781cb3da997..984e9faf5f8c5 100644
--- a/tempfork/sshtest/ssh/buffer_test.go
+++ b/tempfork/sshtest/ssh/buffer_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/certs_test.go b/tempfork/sshtest/ssh/certs_test.go
index 6208bb37a97e2..a553a5f79cd9e 100644
--- a/tempfork/sshtest/ssh/certs_test.go
+++ b/tempfork/sshtest/ssh/certs_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/cipher_test.go b/tempfork/sshtest/ssh/cipher_test.go
index fe339862c5a9d..57fd5b1226c06 100644
--- a/tempfork/sshtest/ssh/cipher_test.go
+++ b/tempfork/sshtest/ssh/cipher_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/client_auth_test.go b/tempfork/sshtest/ssh/client_auth_test.go
index ec27133a39b28..9f480e7f09ecf 100644
--- a/tempfork/sshtest/ssh/client_auth_test.go
+++ b/tempfork/sshtest/ssh/client_auth_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/client_test.go b/tempfork/sshtest/ssh/client_test.go
index 2621f0ea5276b..cfa9d8ffc2961 100644
--- a/tempfork/sshtest/ssh/client_test.go
+++ b/tempfork/sshtest/ssh/client_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/common_test.go b/tempfork/sshtest/ssh/common_test.go
index a7beee8e884e7..8edfd503391ac 100644
--- a/tempfork/sshtest/ssh/common_test.go
+++ b/tempfork/sshtest/ssh/common_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/example_test.go b/tempfork/sshtest/ssh/example_test.go
index 97b3b6aba6f8e..8a5c40e9f2be9 100644
--- a/tempfork/sshtest/ssh/example_test.go
+++ b/tempfork/sshtest/ssh/example_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/handshake_test.go b/tempfork/sshtest/ssh/handshake_test.go
index 2bc607b64938d..f44fea0149e7e 100644
--- a/tempfork/sshtest/ssh/handshake_test.go
+++ b/tempfork/sshtest/ssh/handshake_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/kex_test.go b/tempfork/sshtest/ssh/kex_test.go
index cb7f66a5092f6..e6723dac26f11 100644
--- a/tempfork/sshtest/ssh/kex_test.go
+++ b/tempfork/sshtest/ssh/kex_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/keys_test.go b/tempfork/sshtest/ssh/keys_test.go
index bf1f0be1b2de3..ee430d5e44bd9 100644
--- a/tempfork/sshtest/ssh/keys_test.go
+++ b/tempfork/sshtest/ssh/keys_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/mempipe_test.go b/tempfork/sshtest/ssh/mempipe_test.go
index f27339c51a1b4..da65840b184d5 100644
--- a/tempfork/sshtest/ssh/mempipe_test.go
+++ b/tempfork/sshtest/ssh/mempipe_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/messages_test.go b/tempfork/sshtest/ssh/messages_test.go
index e79076412ab49..4f5cc97371d7a 100644
--- a/tempfork/sshtest/ssh/messages_test.go
+++ b/tempfork/sshtest/ssh/messages_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/mux_test.go b/tempfork/sshtest/ssh/mux_test.go
index 21f0ac3e325a4..4e05c3c044342 100644
--- a/tempfork/sshtest/ssh/mux_test.go
+++ b/tempfork/sshtest/ssh/mux_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/server_multi_auth_test.go b/tempfork/sshtest/ssh/server_multi_auth_test.go
index 3b3980243763f..b512d7d4e2ded 100644
--- a/tempfork/sshtest/ssh/server_multi_auth_test.go
+++ b/tempfork/sshtest/ssh/server_multi_auth_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/server_test.go b/tempfork/sshtest/ssh/server_test.go
index c2b24f47ce878..9454df8d82758 100644
--- a/tempfork/sshtest/ssh/server_test.go
+++ b/tempfork/sshtest/ssh/server_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/session_test.go b/tempfork/sshtest/ssh/session_test.go
index 807a913e5ace7..b29d913b1de62 100644
--- a/tempfork/sshtest/ssh/session_test.go
+++ b/tempfork/sshtest/ssh/session_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/ssh_gss_test.go b/tempfork/sshtest/ssh/ssh_gss_test.go
index 39a111288af09..98f5c4866da2f 100644
--- a/tempfork/sshtest/ssh/ssh_gss_test.go
+++ b/tempfork/sshtest/ssh/ssh_gss_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
package ssh
import (
diff --git a/tempfork/sshtest/ssh/tcpip_test.go b/tempfork/sshtest/ssh/tcpip_test.go
index 4d8511472782d..d948c975d2b1a 100644
--- a/tempfork/sshtest/ssh/tcpip_test.go
+++ b/tempfork/sshtest/ssh/tcpip_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/testdata_test.go b/tempfork/sshtest/ssh/testdata_test.go
index 2da8c79dc64a4..c9799b2c4aec6 100644
--- a/tempfork/sshtest/ssh/testdata_test.go
+++ b/tempfork/sshtest/ssh/testdata_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tempfork/sshtest/ssh/transport_test.go b/tempfork/sshtest/ssh/transport_test.go
index 8445e1e561c15..1fb11f03bcd19 100644
--- a/tempfork/sshtest/ssh/transport_test.go
+++ b/tempfork/sshtest/ssh/transport_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/tka/aum.go b/tka/aum.go
index 44d289906566c..d117aa9d5d090 100644
--- a/tka/aum.go
+++ b/tka/aum.go
@@ -13,9 +13,9 @@ import (
"fmt"
"github.com/fxamacker/cbor/v2"
+ "github.com/metacubex/tailscale/types/tkatype"
+ "github.com/metacubex/tailscale/util/set"
"golang.org/x/crypto/blake2s"
- "tailscale.com/types/tkatype"
- "tailscale.com/util/set"
)
// AUMHash represents the BLAKE2s digest of an Authority Update Message (AUM).
@@ -42,7 +42,11 @@ func (h *AUMHash) UnmarshalText(text []byte) error {
// AppendText implements encoding.TextAppender.
func (h AUMHash) AppendText(b []byte) ([]byte, error) {
- return base32StdNoPad.AppendEncode(b, h[:]), nil
+ n := base32StdNoPad.EncodedLen(len(h))
+ off := len(b)
+ b = append(b, make([]byte, n)...)
+ base32StdNoPad.Encode(b[off:], h[:])
+ return b, nil
}
// MarshalText implements encoding.TextMarshaler.
diff --git a/tka/aum_test.go b/tka/aum_test.go
index 78966c76690ba..5ff189b8d1246 100644
--- a/tka/aum_test.go
+++ b/tka/aum_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,8 +12,8 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
+ "github.com/metacubex/tailscale/types/tkatype"
"golang.org/x/crypto/blake2s"
- "tailscale.com/types/tkatype"
)
func TestSerialization(t *testing.T) {
diff --git a/tka/builder.go b/tka/builder.go
index 131d54dde1318..bd39524ad09e3 100644
--- a/tka/builder.go
+++ b/tka/builder.go
@@ -9,7 +9,7 @@ import (
"fmt"
"os"
- "tailscale.com/types/tkatype"
+ "github.com/metacubex/tailscale/types/tkatype"
)
// Types implementing Signer can sign update messages.
diff --git a/tka/builder_test.go b/tka/builder_test.go
index 4e820e14d526d..5e625150a3c03 100644
--- a/tka/builder_test.go
+++ b/tka/builder_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,7 +11,7 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
- "tailscale.com/types/tkatype"
+ "github.com/metacubex/tailscale/types/tkatype"
)
type signer25519 ed25519.PrivateKey
diff --git a/tka/chaintest_test.go b/tka/chaintest_test.go
index 71210608b631f..2e8c9314fe6a3 100644
--- a/tka/chaintest_test.go
+++ b/tka/chaintest_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,7 +9,7 @@ import (
"bytes"
"crypto/ed25519"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"strconv"
"strings"
"testing"
@@ -15,7 +17,7 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/types/tkatype"
+ "github.com/metacubex/tailscale/types/tkatype"
)
// chaintest_test.go implements test helpers for concisely describing
diff --git a/tka/deeplink_test.go b/tka/deeplink_test.go
index 260ec9026ede9..03c57eb774019 100644
--- a/tka/deeplink_test.go
+++ b/tka/deeplink_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/tka/disabled_stub.go b/tka/disabled_stub.go
index f3cabd491dd12..21809df7da669 100644
--- a/tka/disabled_stub.go
+++ b/tka/disabled_stub.go
@@ -10,9 +10,9 @@ import (
"errors"
"time"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/tkatype"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/tkatype"
)
type Authority struct {
diff --git a/tka/key.go b/tka/key.go
index 08897d4095889..0ee33ddae6a38 100644
--- a/tka/key.go
+++ b/tka/key.go
@@ -7,9 +7,9 @@ import (
"crypto/ed25519"
"errors"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
- "tailscale.com/types/tkatype"
+ "github.com/metacubex/tailscale/types/tkatype"
)
// KeyKind describes the different varieties of a Key.
diff --git a/tka/key_test.go b/tka/key_test.go
index 1edeaf54f11d1..c72c35bff9f23 100644
--- a/tka/key_test.go
+++ b/tka/key_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,8 +12,8 @@ import (
"math/rand"
"testing"
- "tailscale.com/types/key"
- "tailscale.com/types/tkatype"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/tkatype"
)
// returns a random source based on the test name + extraSeed.
diff --git a/tka/scenario_test.go b/tka/scenario_test.go
index 61d9e25290ed8..d19d2c3c4e7e4 100644
--- a/tka/scenario_test.go
+++ b/tka/scenario_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,7 +7,7 @@ package tka
import (
"crypto/ed25519"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"sort"
"testing"
)
diff --git a/tka/sig.go b/tka/sig.go
index 9d107c98ff64c..473f6af925b29 100644
--- a/tka/sig.go
+++ b/tka/sig.go
@@ -14,14 +14,14 @@ import (
"strings"
"github.com/fxamacker/cbor/v2"
- "github.com/hdevalence/ed25519consensus"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/tkatype"
+ "github.com/metacubex/tailscale/util/ed25519consensus"
"golang.org/x/crypto/blake2s"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/tkatype"
)
-//go:generate go run tailscale.com/cmd/cloner -clonefunc=false -type=NodeKeySignature
+//go:generate go run github.com/metacubex/tailscale/cmd/cloner -clonefunc=false -type=NodeKeySignature
// SigKind describes valid NodeKeySignature types.
type SigKind uint8
diff --git a/tka/sig_test.go b/tka/sig_test.go
index 4581d4cc3ce9b..18b512adfff7d 100644
--- a/tka/sig_test.go
+++ b/tka/sig_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,8 +12,8 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/types/key"
- "tailscale.com/types/tkatype"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/tkatype"
)
func TestSigDirect(t *testing.T) {
diff --git a/tka/state.go b/tka/state.go
index ddf2d4ee01974..c0c26198c6ecc 100644
--- a/tka/state.go
+++ b/tka/state.go
@@ -11,9 +11,9 @@ import (
"errors"
"fmt"
+ "github.com/metacubex/tailscale/types/tkatype"
+ "github.com/metacubex/tailscale/util/testenv"
"golang.org/x/crypto/argon2"
- "tailscale.com/types/tkatype"
- "tailscale.com/util/testenv"
)
// ErrNoSuchKey is returned if the key referenced by a KeyID does not exist.
diff --git a/tka/state_test.go b/tka/state_test.go
index e5208e4e6e71d..7c490b526d8ab 100644
--- a/tka/state_test.go
+++ b/tka/state_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_tailnetlock
-
package tka
import (
diff --git a/tka/sync.go b/tka/sync.go
index 5cae9b45f9694..eebade523fa24 100644
--- a/tka/sync.go
+++ b/tka/sync.go
@@ -100,7 +100,7 @@ func (a *Authority) SyncOffer(storage Chonk) (SyncOffer, error) {
skipAmount uint64 = ancestorsSkipStart
curs AUMHash = a.Head()
)
- for i := range uint64(maxSyncHeadIntersectionIter) {
+ for i := uint64(0); i < uint64(maxSyncHeadIntersectionIter); i++ {
if i > 0 && (i%skipAmount) == 0 {
out.Ancestors = append(out.Ancestors, curs)
skipAmount = skipAmount << ancestorsSkipShift
@@ -172,7 +172,7 @@ func computeSyncIntersection(storage Chonk, localOffer, remoteOffer SyncOffer) (
if hasRemoteHead {
curs := localOffer.Head
- for range maxSyncHeadIntersectionIter {
+ for i := 0; i < maxSyncHeadIntersectionIter; i++ {
parent, err := storage.AUM(curs)
if err != nil {
if err != os.ErrNotExist {
diff --git a/tka/sync_test.go b/tka/sync_test.go
index 48f197e8c3a19..7007547fc94d0 100644
--- a/tka/sync_test.go
+++ b/tka/sync_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/tka/tailchonk.go b/tka/tailchonk.go
index 3b083f327f3e7..9f8b51c6e4ca0 100644
--- a/tka/tailchonk.go
+++ b/tka/tailchonk.go
@@ -9,18 +9,18 @@ import (
"bytes"
"errors"
"fmt"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
- "maps"
"os"
"path/filepath"
- "slices"
"sync"
"time"
"github.com/fxamacker/cbor/v2"
- "tailscale.com/atomicfile"
- "tailscale.com/tstime"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/atomicfile"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/testenv"
)
// Chonk implementations provide durable storage for AUMs and other
@@ -709,7 +709,7 @@ func markActiveChain(storage Chonk, verdict map[AUMHash]retainState, minChain in
return AUMHash{}, err
}
- for i := range minChain {
+ for i := 0; i < minChain; i++ {
h := next.Hash()
verdict[h] |= retainStateActive
diff --git a/tka/tailchonk_test.go b/tka/tailchonk_test.go
index 125fbecc0723b..104d2a76229df 100644
--- a/tka/tailchonk_test.go
+++ b/tka/tailchonk_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,18 +7,18 @@ package tka
import (
"bytes"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"os"
"path/filepath"
- "slices"
"sync"
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/util/must"
"golang.org/x/crypto/blake2s"
- "tailscale.com/types/key"
- "tailscale.com/util/must"
)
// This package has implementation-specific tests for Mem and FS.
diff --git a/tka/tka.go b/tka/tka.go
index 9b22edc2eb505..40402001bda12 100644
--- a/tka/tka.go
+++ b/tka/tka.go
@@ -14,9 +14,9 @@ import (
"sort"
"github.com/fxamacker/cbor/v2"
- "tailscale.com/types/key"
- "tailscale.com/types/tkatype"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/tkatype"
+ "github.com/metacubex/tailscale/util/set"
)
// Strict settings for the CBOR decoder.
@@ -212,7 +212,7 @@ func fastForwardWithAdvancer(
curs := nextAUM
state := startState
- for range maxIter {
+ for i := 0; i < maxIter; i++ {
if done != nil && done(curs, state) {
return curs, state, nil
}
diff --git a/tka/tka_clone.go b/tka/tka_clone.go
index 9c7a6eeb3350d..fd0a727531979 100644
--- a/tka/tka_clone.go
+++ b/tka/tka_clone.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-// Code generated by tailscale.com/cmd/cloner; DO NOT EDIT.
+// Code generated by github.com/metacubex/tailscale/cmd/cloner; DO NOT EDIT.
package tka
diff --git a/tka/tka_test.go b/tka/tka_test.go
index f0ec3ff6835e7..b464cba5410c0 100644
--- a/tka/tka_test.go
+++ b/tka/tka_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,8 +11,8 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
- "tailscale.com/types/key"
- "tailscale.com/types/tkatype"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/tkatype"
)
func TestComputeChainCandidates(t *testing.T) {
diff --git a/tka/verify.go b/tka/verify.go
index 1ef4fbbb19308..ced03198e329a 100644
--- a/tka/verify.go
+++ b/tka/verify.go
@@ -10,8 +10,8 @@ import (
"errors"
"fmt"
- "github.com/hdevalence/ed25519consensus"
- "tailscale.com/types/tkatype"
+ "github.com/metacubex/tailscale/types/tkatype"
+ "github.com/metacubex/tailscale/util/ed25519consensus"
)
// signatureVerify returns a nil error if the signature is valid over the
diff --git a/tka/verify_disabled.go b/tka/verify_disabled.go
index a4b3136d2ffea..310ebbef65852 100644
--- a/tka/verify_disabled.go
+++ b/tka/verify_disabled.go
@@ -8,7 +8,7 @@ package tka
import (
"errors"
- "tailscale.com/types/tkatype"
+ "github.com/metacubex/tailscale/types/tkatype"
)
// signatureVerify returns a nil error if the signature is valid over the
diff --git a/tool/gocross/autoflags.go b/tool/gocross/autoflags.go
index 405cad8b3b68e..acc2732b33f01 100644
--- a/tool/gocross/autoflags.go
+++ b/tool/gocross/autoflags.go
@@ -4,12 +4,12 @@
package main
import (
- "cmp"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"runtime"
"strings"
- "tailscale.com/version/mkversion"
+ "github.com/metacubex/tailscale/version/mkversion"
)
// Autoflags adjusts the commandline argv into a new commandline
@@ -59,10 +59,10 @@ func autoflagsForTest(argv []string, env *Environment, goroot, nativeGOOS, nativ
vi := getVersion()
ldflags = []string{
- "-X", "tailscale.com/version.longStamp=" + vi.Long,
- "-X", "tailscale.com/version.shortStamp=" + vi.Short,
- "-X", "tailscale.com/version.gitCommitStamp=" + vi.GitHash,
- "-X", "tailscale.com/version.extraGitCommitStamp=" + vi.OtherHash,
+ "-X", "github.com/metacubex/tailscale/version.longStamp=" + vi.Long,
+ "-X", "github.com/metacubex/tailscale/version.shortStamp=" + vi.Short,
+ "-X", "github.com/metacubex/tailscale/version.gitCommitStamp=" + vi.GitHash,
+ "-X", "github.com/metacubex/tailscale/version.extraGitCommitStamp=" + vi.OtherHash,
}
switch targetOS {
diff --git a/tool/gocross/autoflags_test.go b/tool/gocross/autoflags_test.go
index 7363e452ed635..e883f28bbe295 100644
--- a/tool/gocross/autoflags_test.go
+++ b/tool/gocross/autoflags_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,7 +9,7 @@ import (
"reflect"
"testing"
- "tailscale.com/version/mkversion"
+ "github.com/metacubex/tailscale/version/mkversion"
)
var fakeVersion = mkversion.VersionInfo{
@@ -55,7 +57,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
"gocross", "build",
"-trimpath",
"-tags=tailscale_go,osusergo,netgo",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg '-extldflags=-static'",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg '-extldflags=-static'",
"./cmd/tailcontrol",
},
},
@@ -81,7 +83,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
"gocross", "install",
"-trimpath",
"-tags=tailscale_go,osusergo,netgo",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg '-extldflags=-static'",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg '-extldflags=-static'",
"./cmd/tailcontrol",
},
},
@@ -110,7 +112,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
"gocross", "build",
"-trimpath",
"-tags=tailscale_go,osusergo,netgo",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg '-extldflags=-static'",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg '-extldflags=-static'",
"./cmd/tailcontrol",
},
},
@@ -139,7 +141,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
"gocross", "build",
"-trimpath",
"-tags=tailscale_go",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg",
"./cmd/tailcontrol",
},
},
@@ -164,7 +166,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
wantArgv: []string{
"gocross", "test",
"-tags=tailscale_go,osusergo,netgo",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg '-extldflags=-static'",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg '-extldflags=-static'",
"-race",
"./cmd/tailcontrol",
},
@@ -194,7 +196,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
"gocross", "build",
"-trimpath",
"-tags=tailscale_go",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg -H windows -s",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg -H windows -s",
"./cmd/tailcontrol",
},
},
@@ -223,7 +225,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
"gocross", "build",
"-trimpath",
"-tags=tailscale_go",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg",
"./cmd/tailcontrol",
},
},
@@ -253,7 +255,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
"gocross", "build",
"-trimpath",
"-tags=tailscale_go",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg",
"./cmd/tailcontrol",
},
},
@@ -279,7 +281,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
"gocross", "build",
"-trimpath",
"-tags=tailscale_go,omitidna,omitpemdecrypt",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg",
"./cmd/tailcontrol",
},
},
@@ -308,7 +310,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
"gocross", "build",
"-trimpath",
"-tags=tailscale_go,omitidna,omitpemdecrypt",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg",
"./cmd/tailcontrol",
},
},
@@ -337,7 +339,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
"gocross", "build",
"-trimpath",
"-tags=tailscale_go,omitidna,omitpemdecrypt",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg",
"./cmd/tailcontrol",
},
},
@@ -366,7 +368,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
"gocross", "build",
"-trimpath",
"-tags=tailscale_go,omitidna,omitpemdecrypt",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg",
"./cmd/tailcontrol",
},
},
@@ -395,7 +397,7 @@ TS_LINK_FAIL_REFLECT=1 (was )`,
"gocross", "build",
"-trimpath",
"-tags=tailscale_go,omitidna,omitpemdecrypt",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg",
"./cmd/tailcontrol",
},
},
@@ -428,7 +430,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
"gocross", "build",
"-trimpath",
"-tags=tailscale_go,omitidna,omitpemdecrypt,ts_macext",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg -w",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg -w",
"./cmd/tailcontrol",
},
},
@@ -461,7 +463,7 @@ TS_LINK_FAIL_REFLECT=1 (was )`,
"gocross", "build",
"-trimpath",
"-tags=tailscale_go,omitidna,omitpemdecrypt,ts_macext",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg -w",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg -w",
"./cmd/tailcontrol",
},
},
@@ -487,7 +489,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
"go", "build",
"-trimpath",
"-tags=tailscale_go,osusergo,netgo",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg '-extldflags=-static'",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg '-extldflags=-static'",
"./cmd/tailcontrol",
},
},
@@ -513,7 +515,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
"gocross", "list",
"-trimpath",
"-tags=tailscale_go,osusergo,netgo",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg '-extldflags=-static'",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg '-extldflags=-static'",
"./cmd/tailcontrol",
},
},
@@ -542,7 +544,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
"gocross", "build",
"-trimpath",
"-tags=tailscale_go,osusergo,netgo",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg '-extldflags=-static -L /my/glibc/path'",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg '-extldflags=-static -L /my/glibc/path'",
"./cmd/tailcontrol",
},
},
@@ -569,7 +571,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
"go", "run",
"-trimpath",
"-tags=tailscale_go,osusergo,netgo",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg '-extldflags=-static'",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg '-extldflags=-static'",
"./cmd/mkctr",
"--tags=foo",
},
@@ -599,7 +601,7 @@ TS_LINK_FAIL_REFLECT=0 (was )`,
"gocross", "build",
"-trimpath",
"-tags=tailscale_go,osusergo,netgo",
- "-ldflags", "-X tailscale.com/version.longStamp=1.2.3-long -X tailscale.com/version.shortStamp=1.2.3 -X tailscale.com/version.gitCommitStamp=abcd -X tailscale.com/version.extraGitCommitStamp=defg '-extldflags=-static'",
+ "-ldflags", "-X github.com/metacubex/tailscale/version.longStamp=1.2.3-long -X github.com/metacubex/tailscale/version.shortStamp=1.2.3 -X github.com/metacubex/tailscale/version.gitCommitStamp=abcd -X github.com/metacubex/tailscale/version.extraGitCommitStamp=defg '-extldflags=-static'",
"./cmd/tailcontrol",
},
},
diff --git a/tool/gocross/env_test.go b/tool/gocross/env_test.go
index 39af579eb15f1..afe786cb172ea 100644
--- a/tool/gocross/env_test.go
+++ b/tool/gocross/env_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/tool/gocross/gocross.go b/tool/gocross/gocross.go
index 67d4bfceee74f..139508389eccb 100644
--- a/tool/gocross/gocross.go
+++ b/tool/gocross/gocross.go
@@ -18,7 +18,7 @@ import (
"runtime/debug"
"strings"
- "tailscale.com/atomicfile"
+ "github.com/metacubex/tailscale/atomicfile"
)
func main() {
diff --git a/tool/gocross/gocross_test.go b/tool/gocross/gocross_test.go
index 2737432e2d0dc..aeabe15ed8c86 100644
--- a/tool/gocross/gocross_test.go
+++ b/tool/gocross/gocross_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,14 +8,14 @@ package main
import (
"testing"
- "tailscale.com/tstest/deptest"
+ "github.com/metacubex/tailscale/tstest/deptest"
)
func TestDeps(t *testing.T) {
deptest.DepChecker{
BadDeps: map[string]string{
- "tailscale.com/tailcfg": "circular dependency via go generate",
- "tailscale.com/version": "circular dependency via go generate",
+ "github.com/metacubex/tailscale/tailcfg": "circular dependency via go generate",
+ "github.com/metacubex/tailscale/version": "circular dependency via go generate",
},
}.Check(t)
}
diff --git a/tool/gocross/gocross_wrapper_test.go b/tool/gocross/gocross_wrapper_test.go
index 035b57c162b16..9b778cbdc9bb5 100644
--- a/tool/gocross/gocross_wrapper_test.go
+++ b/tool/gocross/gocross_wrapper_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux || darwin
-
package main
import (
@@ -14,7 +14,7 @@ import (
"strings"
"testing"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/util/must"
)
func TestGocrossWrapper(t *testing.T) {
diff --git a/tool/gocross/gocross_wrapper_windows_test.go b/tool/gocross/gocross_wrapper_windows_test.go
index 83f3e7b791f3e..d1660f2d00f3f 100644
--- a/tool/gocross/gocross_wrapper_windows_test.go
+++ b/tool/gocross/gocross_wrapper_windows_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,7 +14,7 @@ import (
"strings"
"testing"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/util/must"
)
func TestGocrossWrapper(t *testing.T) {
diff --git a/tool/gocross/toolchain.go b/tool/gocross/toolchain.go
index 8086d96976e92..c37973637d4be 100644
--- a/tool/gocross/toolchain.go
+++ b/tool/gocross/toolchain.go
@@ -82,7 +82,7 @@ func getToolchain() (toolchainDir, gorootDir string, err error) {
// A bunch of our tests and build processes involve re-invoking 'go build'
// or other build-ish commands (install, run, ...). These typically use
// runtime.GOROOT + "bin/go" to get at the Go binary. Even more edge case-y,
- // tailscale.com/cmd/tsconnect needs to fish a javascript glue file out of
+ // github.com/metacubex/tailscale/cmd/tsconnect needs to fish a javascript glue file out of
// GOROOT in order to build the javascript bundle for serving.
//
// Gocross always does a -trimpath on builds for reproducibility, which
diff --git a/tool/listpkgs/listpkgs.go b/tool/listpkgs/listpkgs.go
index b29db94b1f5c4..26e5c65aae1a0 100644
--- a/tool/listpkgs/listpkgs.go
+++ b/tool/listpkgs/listpkgs.go
@@ -9,12 +9,12 @@ import (
"bufio"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"go/build/constraint"
"io/fs"
"log"
"os"
"path/filepath"
- "slices"
"sort"
"strings"
"sync"
@@ -203,7 +203,7 @@ func computeAffected(pkgs []*packages.Package, tag string) map[string]bool {
}
func isThirdParty(pkg string) bool {
- return strings.HasPrefix(pkg, "tailscale.com/tempfork/")
+ return strings.HasPrefix(pkg, "github.com/metacubex/tailscale/tempfork/")
}
// hasBuildTag reports whether any source file in pkg mentions `tag`
diff --git a/tool/updateflakes/updateflakes.go b/tool/updateflakes/updateflakes.go
index e2a572d1278ba..7ddfc5473e755 100644
--- a/tool/updateflakes/updateflakes.go
+++ b/tool/updateflakes/updateflakes.go
@@ -32,8 +32,8 @@ import (
"path/filepath"
"strings"
+ "github.com/metacubex/tailscale/cmd/nardump/nardump"
"golang.org/x/sync/errgroup"
- "tailscale.com/cmd/nardump/nardump"
)
const (
diff --git a/tsconsensus/authorization.go b/tsconsensus/authorization.go
index 017c9e80721b9..6d2c10519cba6 100644
--- a/tsconsensus/authorization.go
+++ b/tsconsensus/authorization.go
@@ -10,11 +10,11 @@ import (
"sync"
"time"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tsnet"
- "tailscale.com/types/views"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/set"
)
// defaultStatusCacheTimeout is the duration after which cached status will be
diff --git a/tsconsensus/authorization_test.go b/tsconsensus/authorization_test.go
index 72c920972ebb5..d8c869d54463a 100644
--- a/tsconsensus/authorization_test.go
+++ b/tsconsensus/authorization_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,11 +11,11 @@ import (
"net/netip"
"testing"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/views"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/views"
)
type testStatusGetter struct {
diff --git a/tsconsensus/http.go b/tsconsensus/http.go
index a7e3af35d94f6..1e81fda3b3cab 100644
--- a/tsconsensus/http.go
+++ b/tsconsensus/http.go
@@ -14,7 +14,7 @@ import (
"net/http"
"time"
- "tailscale.com/util/httpm"
+ "github.com/metacubex/tailscale/util/httpm"
)
type joinRequest struct {
diff --git a/tsconsensus/monitor.go b/tsconsensus/monitor.go
index bf7410d0df332..d2d9e5e08fd62 100644
--- a/tsconsensus/monitor.go
+++ b/tsconsensus/monitor.go
@@ -7,14 +7,14 @@ import (
"context"
"encoding/json"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
"net/http"
- "slices"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tsnet"
- "tailscale.com/util/dnsname"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/util/dnsname"
)
type status struct {
diff --git a/tsconsensus/tsconsensus.go b/tsconsensus/tsconsensus.go
index 27cbf964e7207..271c11544b30d 100644
--- a/tsconsensus/tsconsensus.go
+++ b/tsconsensus/tsconsensus.go
@@ -37,9 +37,9 @@ import (
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/raft"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tsnet"
- "tailscale.com/types/views"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/types/views"
)
func raftAddr(host netip.Addr, cfg Config) string {
diff --git a/tsconsensus/tsconsensus_test.go b/tsconsensus/tsconsensus_test.go
index 3236ef680a8e9..cf03219457809 100644
--- a/tsconsensus/tsconsensus_test.go
+++ b/tsconsensus/tsconsensus_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -25,19 +27,19 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/raft"
- "tailscale.com/client/tailscale"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/net/netns"
- "tailscale.com/tailcfg"
- "tailscale.com/tsnet"
- "tailscale.com/tstest/integration"
- "tailscale.com/tstest/integration/testcontrol"
- "tailscale.com/tstest/nettest"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/views"
- "tailscale.com/util/cibuild"
- "tailscale.com/util/racebuild"
+ "github.com/metacubex/tailscale/client/tailscale"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/tstest/integration"
+ "github.com/metacubex/tailscale/tstest/integration/testcontrol"
+ "github.com/metacubex/tailscale/tstest/nettest"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/cibuild"
+ "github.com/metacubex/tailscale/util/racebuild"
)
type fsm struct {
diff --git a/tsd/tsd.go b/tsd/tsd.go
index 615c9c0e741c7..4d47438783b37 100644
--- a/tsd/tsd.go
+++ b/tsd/tsd.go
@@ -22,24 +22,24 @@ import (
"fmt"
"reflect"
- "tailscale.com/control/controlknobs"
- "tailscale.com/drive"
- "tailscale.com/health"
- "tailscale.com/ipn"
- "tailscale.com/ipn/conffile"
- "tailscale.com/net/dns"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsdial"
- "tailscale.com/net/tstun"
- "tailscale.com/proxymap"
- "tailscale.com/types/netmap"
- "tailscale.com/types/views"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/syspolicy/policyclient"
- "tailscale.com/util/usermetric"
- "tailscale.com/wgengine"
- "tailscale.com/wgengine/magicsock"
- "tailscale.com/wgengine/router"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/conffile"
+ "github.com/metacubex/tailscale/net/dns"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/proxymap"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/util/usermetric"
+ "github.com/metacubex/tailscale/wgengine"
+ "github.com/metacubex/tailscale/wgengine/magicsock"
+ "github.com/metacubex/tailscale/wgengine/router"
)
// System contains all the subsystems of a Tailscale node (tailscaled, etc.)
@@ -233,7 +233,7 @@ func (p *SubSystem[T]) Set(v T) {
return
}
- panic(fmt.Sprintf("%v is already set", reflect.TypeFor[T]().String()))
+ panic(fmt.Sprintf("%v is already set", reflect.TypeOf((*T)(nil)).Elem().String()))
}
p.v = v
p.set = true
@@ -242,7 +242,7 @@ func (p *SubSystem[T]) Set(v T) {
// Get returns the value of p, panicking if it hasn't been set.
func (p *SubSystem[T]) Get() T {
if !p.set {
- panic(fmt.Sprintf("%v is not set", reflect.TypeFor[T]().String()))
+ panic(fmt.Sprintf("%v is not set", reflect.TypeOf((*T)(nil)).Elem().String()))
}
return p.v
}
diff --git a/tsnet/depaware.txt b/tsnet/depaware.txt
index a4eed2a13a338..6ee3d905b057c 100644
--- a/tsnet/depaware.txt
+++ b/tsnet/depaware.txt
@@ -25,12 +25,12 @@ tailscale.com/tsnet dependencies: (generated by github.com/tailscale/depaware)
github.com/gaissmai/bart/internal/nodes from github.com/gaissmai/bart
github.com/gaissmai/bart/internal/sparse from github.com/gaissmai/bart/internal/nodes
github.com/gaissmai/bart/internal/value from github.com/gaissmai/bart+
- github.com/go-json-experiment/json from tailscale.com/types/opt+
- github.com/go-json-experiment/json/internal from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonflags from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonopts from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/internal/jsonwire from github.com/go-json-experiment/json+
- github.com/go-json-experiment/json/jsontext from github.com/go-json-experiment/json+
+ github.com/metacubex/jsonv2 from tailscale.com/types/opt+
+ github.com/metacubex/jsonv2/internal from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonflags from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonopts from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/internal/jsonwire from github.com/metacubex/jsonv2+
+ github.com/metacubex/jsonv2/jsontext from github.com/metacubex/jsonv2+
L 💣 github.com/godbus/dbus/v5 from tailscale.com/net/dns
github.com/golang/groupcache/lru from tailscale.com/net/dnscache
github.com/google/btree from gvisor.dev/gvisor/pkg/tcpip/transport/tcp
diff --git a/tsnet/example/tshello/tshello.go b/tsnet/example/tshello/tshello.go
index d45d209dc7abc..ddbcf35969ba1 100644
--- a/tsnet/example/tshello/tshello.go
+++ b/tsnet/example/tshello/tshello.go
@@ -13,7 +13,7 @@ import (
"net/http"
"strings"
- "tailscale.com/tsnet"
+ "github.com/metacubex/tailscale/tsnet"
)
var (
diff --git a/tsnet/example/tsnet-funnel/tsnet-funnel.go b/tsnet/example/tsnet-funnel/tsnet-funnel.go
index 27c3e1e5cdf2e..cd7529389836b 100644
--- a/tsnet/example/tsnet-funnel/tsnet-funnel.go
+++ b/tsnet/example/tsnet-funnel/tsnet-funnel.go
@@ -15,7 +15,7 @@ import (
"log"
"net/http"
- "tailscale.com/tsnet"
+ "github.com/metacubex/tailscale/tsnet"
)
func main() {
diff --git a/tsnet/example/tsnet-http-client/tsnet-http-client.go b/tsnet/example/tsnet-http-client/tsnet-http-client.go
index e61c512a0b085..010018aa448ec 100644
--- a/tsnet/example/tsnet-http-client/tsnet-http-client.go
+++ b/tsnet/example/tsnet-http-client/tsnet-http-client.go
@@ -11,7 +11,7 @@ import (
"os"
"path/filepath"
- "tailscale.com/tsnet"
+ "github.com/metacubex/tailscale/tsnet"
)
func main() {
diff --git a/tsnet/example/tsnet-services/tsnet-services.go b/tsnet/example/tsnet-services/tsnet-services.go
index 4604e8d3fbbce..721488813232d 100644
--- a/tsnet/example/tsnet-services/tsnet-services.go
+++ b/tsnet/example/tsnet-services/tsnet-services.go
@@ -35,8 +35,8 @@
// "ip": ["*"],
// ],
//
-// [Define a Service]: https://tailscale.com/kb/1552/tailscale-services#step-1-define-a-tailscale-service
-// [Generate an auth key]: https://tailscale.com/kb/1085/auth-keys#generate-an-auth-key
+// [Define a Service]: https://github.com/metacubex/tailscale/kb/1552/tailscale-services#step-1-define-a-tailscale-service
+// [Generate an auth key]: https://github.com/metacubex/tailscale/kb/1085/auth-keys#generate-an-auth-key
package main
import (
@@ -45,7 +45,7 @@ import (
"log"
"net/http"
- "tailscale.com/tsnet"
+ "github.com/metacubex/tailscale/tsnet"
)
var (
diff --git a/tsnet/example/web-client/web-client.go b/tsnet/example/web-client/web-client.go
index e64eb47e6e14f..9cfe92da660ce 100644
--- a/tsnet/example/web-client/web-client.go
+++ b/tsnet/example/web-client/web-client.go
@@ -9,8 +9,8 @@ import (
"log"
"net/http"
- "tailscale.com/client/web"
- "tailscale.com/tsnet"
+ "github.com/metacubex/tailscale/client/web"
+ "github.com/metacubex/tailscale/tsnet"
)
var (
diff --git a/tsnet/example_tshello_test.go b/tsnet/example_tshello_test.go
index 62b6737fd5245..5d0a62d37182d 100644
--- a/tsnet/example_tshello_test.go
+++ b/tsnet/example_tshello_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,7 +13,7 @@ import (
"net/http"
"strings"
- "tailscale.com/tsnet"
+ "github.com/metacubex/tailscale/tsnet"
)
func firstLabel(s string) string {
diff --git a/tsnet/example_tsnet_listen_service_multiple_ports_test.go b/tsnet/example_tsnet_listen_service_multiple_ports_test.go
index 5fe86a9ecf9fe..f026802e55cda 100644
--- a/tsnet/example_tsnet_listen_service_multiple_ports_test.go
+++ b/tsnet/example_tsnet_listen_service_multiple_ports_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,7 +12,7 @@ import (
_ "net/http/pprof"
"strings"
- "tailscale.com/tsnet"
+ "github.com/metacubex/tailscale/tsnet"
)
// This example function is in a separate file for the "net/http/pprof" import.
diff --git a/tsnet/example_tsnet_test.go b/tsnet/example_tsnet_test.go
index 2af31a76f787f..6403095791c20 100644
--- a/tsnet/example_tsnet_test.go
+++ b/tsnet/example_tsnet_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -13,7 +15,7 @@ import (
"os"
"path/filepath"
- "tailscale.com/tsnet"
+ "github.com/metacubex/tailscale/tsnet"
)
// ExampleServer shows you how to construct a ready-to-use tsnet instance.
diff --git a/tsnet/packet_filter_test.go b/tsnet/packet_filter_test.go
index ca776436e7085..0633d61282902 100644
--- a/tsnet/packet_filter_test.go
+++ b/tsnet/packet_filter_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,14 +12,14 @@ import (
"testing"
"time"
- "tailscale.com/ipn"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/key"
- "tailscale.com/types/netmap"
- "tailscale.com/util/must"
- "tailscale.com/wgengine/filter"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/wgengine/filter"
)
// waitFor blocks until a NetMap is seen on the IPN bus that satisfies the given
diff --git a/tsnet/tsnet.go b/tsnet/tsnet.go
index eb72d28d3f3e0..4bee804f7d9e6 100644
--- a/tsnet/tsnet.go
+++ b/tsnet/tsnet.go
@@ -28,7 +28,7 @@
//
// # Usage
//
-// import "tailscale.com/tsnet"
+// import "github.com/metacubex/tailscale/tsnet"
//
// s := &tsnet.Server{
// Hostname: "my-service",
@@ -63,7 +63,7 @@
// [Server.IDToken] or [Server.Audience]). Available only if the
// program imports the feature:
//
-// import _ "tailscale.com/feature/identityfederation"
+// import _ "github.com/metacubex/tailscale/feature/identityfederation"
//
// The feature is not linked by default to keep the AWS SDK and
// other cloud-provider dependencies out of programs that don't
@@ -131,18 +131,20 @@
// srv.Start()
// }
//
-// [Tailscale identity]: https://tailscale.com/docs/concepts/tailscale-identity
-// [Tailscale Funnel]: https://tailscale.com/docs/features/tailscale-funnel
-// [Tailscale Service]: https://tailscale.com/docs/features/tailscale-services
+// [Tailscale identity]: https://github.com/metacubex/tailscale/docs/concepts/tailscale-identity
+// [Tailscale Funnel]: https://github.com/metacubex/tailscale/docs/features/tailscale-funnel
+// [Tailscale Service]: https://github.com/metacubex/tailscale/docs/features/tailscale-services
package tsnet
import (
"context"
crand "crypto/rand"
"crypto/tls"
+ "crypto/x509"
"encoding/hex"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
"math"
@@ -152,51 +154,53 @@ import (
"os"
"path/filepath"
"runtime"
- "slices"
"strconv"
"strings"
"sync"
"time"
- "github.com/tailscale/wireguard-go/tun"
- "tailscale.com/client/local"
- "tailscale.com/control/controlclient"
- "tailscale.com/envknob"
- _ "tailscale.com/feature/c2n"
- _ "tailscale.com/feature/condregister/oauthkey"
- _ "tailscale.com/feature/condregister/portmapper"
- _ "tailscale.com/feature/condregister/useproxy"
- "tailscale.com/health"
- "tailscale.com/hostinfo"
- "tailscale.com/internal/client/tailscale"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnauth"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/ipn/localapi"
- "tailscale.com/ipn/store"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/logpolicy"
- "tailscale.com/logtail"
- "tailscale.com/logtail/filch"
- "tailscale.com/net/memnet"
- "tailscale.com/net/netmon"
- "tailscale.com/net/proxymux"
- "tailscale.com/net/socks5"
- "tailscale.com/net/tsdial"
- "tailscale.com/tailcfg"
- "tailscale.com/tsd"
- "tailscale.com/types/bools"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/types/nettype"
- "tailscale.com/types/views"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
- "tailscale.com/util/testenv"
- "tailscale.com/wgengine"
- "tailscale.com/wgengine/netstack"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/control/controlclient"
+ "github.com/metacubex/tailscale/envknob"
+ _ "github.com/metacubex/tailscale/feature/c2n"
+ _ "github.com/metacubex/tailscale/feature/condregister/oauthkey"
+ _ "github.com/metacubex/tailscale/feature/condregister/portmapper"
+ _ "github.com/metacubex/tailscale/feature/condregister/useproxy"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/internal/client/tailscale"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnauth"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/ipn/localapi"
+ "github.com/metacubex/tailscale/ipn/store"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/logpolicy"
+ "github.com/metacubex/tailscale/logtail"
+ "github.com/metacubex/tailscale/logtail/filch"
+ "github.com/metacubex/tailscale/net/dnscache"
+ "github.com/metacubex/tailscale/net/memnet"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/net/proxymux"
+ "github.com/metacubex/tailscale/net/socks5"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/types/bools"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/types/nettype"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/testenv"
+ "github.com/metacubex/tailscale/wgengine"
+ "github.com/metacubex/tailscale/wgengine/netstack"
)
// Server is an embedded Tailscale server.
@@ -218,7 +222,7 @@ type Server struct {
// Store specifies the state store to use.
//
// If nil, a new FileStore is initialized at `Dir/tailscaled.state`.
- // See tailscale.com/ipn/store for supported stores.
+ // See github.com/metacubex/tailscale/ipn/store for supported stores.
//
// Logs will automatically be uploaded to log.tailscale.com,
// where the configuration file for logging will be saved at
@@ -240,7 +244,7 @@ type Server struct {
Logf logger.Logf
// Ephemeral, if true, specifies that the instance should register
- // as an Ephemeral node (https://tailscale.com/s/ephemeral-nodes).
+ // as an Ephemeral node (https://github.com/metacubex/tailscale/s/ephemeral-nodes).
Ephemeral bool
// AuthKey, if non-empty, is the auth key to create the node
@@ -296,6 +300,22 @@ type Server struct {
// field at zero unless you know what you are doing.
Port uint16
+ // SystemDialer optionally specifies how tsnet dials non-Tailscale
+ // infrastructure such as control, DERP, STUN, and logtail.
+ SystemDialer netx.DialFunc
+
+ // SystemPacketListener optionally specifies how tsnet opens UDP sockets
+ // for non-Tailscale infrastructure such as STUN and peer paths.
+ SystemPacketListener netx.ListenPacketFunc
+
+ // ExtraRootCAs optionally specifies additional trusted root CAs for
+ // Tailscale control connections.
+ ExtraRootCAs *x509.CertPool
+
+ // LookupHook optionally specifies how tsnet resolves non-Tailscale
+ // infrastructure hostnames such as control and DERP.
+ LookupHook dnscache.LookupHookFunc
+
// AdvertiseTags specifies tags that should be applied to this node, for
// purposes of ACL enforcement. These can be referenced from the ACL policy
// document. Note that advertising a tag on the client doesn't guarantee
@@ -332,6 +352,7 @@ type Server struct {
listeners map[listenKey]*listener
nextEphemeralPort uint16 // next port to try in ephemeral range; 0 means use ephemeralPortFirst
fallbackTCPHandlers set.HandleSet[FallbackTCPHandler]
+ fallbackUDPHandlers set.HandleSet[FallbackUDPHandler]
dialer *tsdial.Dialer
advertisedServices map[tailcfg.ServiceName]int
closeOnce sync.Once
@@ -350,6 +371,19 @@ type Server struct {
// over the TCP conn.
type FallbackTCPHandler func(src, dst netip.AddrPort) (handler func(net.Conn), intercept bool)
+// FallbackUDPHandler describes the callback which
+// conditionally handles an incoming UDP flow for the
+// provided (src/port, dst/port) 4-tuple. These are registered
+// as handlers of last resort, and are called only if no
+// listener could handle the incoming flow.
+//
+// If the callback returns intercept=false, the flow is rejected.
+//
+// When intercept=true, the behavior depends on whether the returned handler
+// is non-nil: if nil, the connection is rejected. If non-nil, handler takes
+// over the TCP conn.
+type FallbackUDPHandler func(src, dst netip.AddrPort) (handler func(nettype.ConnPacketConn), intercept bool)
+
// Dial connects to the address on the tailnet.
// It will start the server if it has not been started yet.
func (s *Server) Dial(ctx context.Context, network, address string) (net.Conn, error) {
@@ -362,6 +396,30 @@ func (s *Server) Dial(ctx context.Context, network, address string) (net.Conn, e
return s.dialer.UserDial(ctx, network, address)
}
+// DialPlan resolves address and reports whether Dial would route it via
+// Tailscale instead of falling back to the system dialer.
+func (s *Server) DialPlan(ctx context.Context, network, address string) (ipp netip.AddrPort, viaTailscale bool, err error) {
+ if err := s.Start(); err != nil {
+ return netip.AddrPort{}, false, err
+ }
+ if err := s.awaitRunning(ctx); err != nil {
+ return netip.AddrPort{}, false, err
+ }
+ return s.dialer.UserDialPlan(ctx, network, address)
+}
+
+// Netstack returns the *netstack.Impl for the server.
+// It will start the server if it has not been started yet.
+func (s *Server) Netstack(ctx context.Context) (*netstack.Impl, error) {
+ if err := s.Start(); err != nil {
+ return nil, err
+ }
+ if err := s.awaitRunning(ctx); err != nil {
+ return nil, err
+ }
+ return s.netstack, nil
+}
+
// awaitRunning waits until the backend is in state Running.
// If the backend is in state Starting, it blocks until it reaches
// a terminal state (such as Stopped, NeedsMachineAuth)
@@ -626,7 +684,9 @@ func (s *Server) close() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
var wg sync.WaitGroup
- wg.Go(func() {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
// Perform a best-effort final flush.
if s.logtail != nil {
s.logtail.Shutdown(ctx)
@@ -634,12 +694,14 @@ func (s *Server) close() {
if s.logbuffer != nil {
s.logbuffer.Close()
}
- })
- wg.Go(func() {
+ }()
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
if s.localAPIServer != nil {
s.localAPIServer.Shutdown(ctx)
}
- })
+ }()
if s.shutdownCancel != nil {
s.shutdownCancel()
@@ -695,7 +757,7 @@ func (s *Server) TailscaleIPs() (ip4, ip6 netip.Addr) {
return
}
addrs := nm.GetAddresses()
- for _, addr := range addrs.All() {
+ addrs.All()(func(_ int, addr netip.Prefix) bool {
ip := addr.Addr()
if ip.Is6() {
ip6 = ip
@@ -703,7 +765,8 @@ func (s *Server) TailscaleIPs() (ip4, ip6 netip.Addr) {
if ip.Is4() {
ip4 = ip
}
- }
+ return true
+ })
return ip4, ip6
}
@@ -831,8 +894,9 @@ func (s *Server) start() (reterr error) {
s.Logf(format, a...)
}
- sys := tsd.NewSystem()
+ sys := tsd.NewSystemWithBus(eventbus.NewWithOptions(eventbus.BusOptions{Logf: tsLogf}))
s.sys = sys
+ sys.ExtraRootCAs = s.ExtraRootCAs
if err := s.startLogger(&closePool, sys.HealthTracker.Get(), tsLogf); err != nil {
return err
}
@@ -844,6 +908,9 @@ func (s *Server) start() (reterr error) {
closePool.add(s.netMon)
s.dialer = &tsdial.Dialer{Logf: tsLogf} // mutated below (before used)
+ s.dialer.SystemDialer = s.SystemDialer
+ s.dialer.SystemPacketListener = s.SystemPacketListener
+ s.dialer.LookupHook = s.LookupHook
s.dialer.SetBus(sys.Bus.Get())
eng, err := wgengine.NewUserspaceEngine(tsLogf, wgengine.Config{
Tun: s.Tun,
@@ -855,6 +922,7 @@ func (s *Server) start() (reterr error) {
ControlKnobs: sys.ControlKnobs(),
HealthTracker: sys.HealthTracker.Get(),
ExtraRootCAs: sys.ExtraRootCAs,
+ LookupHook: s.LookupHook,
Metrics: sys.UserMetricsRegistry(),
})
if err != nil {
@@ -927,13 +995,13 @@ func (s *Server) start() (reterr error) {
if s.Ephemeral {
loginFlags = controlclient.LoginEphemeral
}
- lb, err := ipnlocal.NewLocalBackend(tsLogf, s.logid, sys, loginFlags|controlclient.LocalBackendStartKeyOSNeutral)
+ lb, err := ipnlocal.NewLocalBackend(tsLogf, s.logid, sys, loginFlags|controlclient.LocalBackendStartKeyOSNeutral, s.LookupHook)
if err != nil {
return fmt.Errorf("NewLocalBackend: %v", err)
}
lb.SetTCPHandlerForFunnelFlow(s.getTCPHandlerForFunnelFlow)
lb.SetVarRoot(s.rootPath)
- s.logf("tsnet starting with hostname %q, varRoot %q", s.hostname, s.rootPath)
+ s.logf("tsnet starting with hostname: %s, varRoot: %s", s.hostname, s.rootPath)
s.lb = lb
if err := ns.Start(lb); err != nil {
return fmt.Errorf("failed to start netstack: %w", err)
@@ -1071,7 +1139,13 @@ func (s *Server) startLogger(closePool *closeOnErrorPool, health *health.Tracker
Buffer: s.logbuffer,
CompressLogs: true,
Bus: s.sys.Bus.Get(),
- HTTPC: &http.Client{Transport: logpolicy.NewLogtailTransport(logtail.DefaultHost, s.netMon, health, tsLogf)},
+ HTTPC: &http.Client{Transport: logpolicy.TransportOptions{
+ Host: logtail.DefaultHost,
+ NetMon: s.netMon,
+ Health: health,
+ Logf: tsLogf,
+ DialContext: s.SystemDialer,
+ }.New()},
MetricsDelta: clientmetric.EncodeLogTailMetricsDelta,
}
s.logtail = logtail.NewLogger(c, tsLogf)
@@ -1108,7 +1182,18 @@ func (s *Server) printAuthURLLoop() {
ctx, cancel := context.WithCancel(s.shutdownCtx)
defer cancel()
stateCh := make(chan struct{}, 1)
+ var lastAuthURL string
+ logAuthURL := func(authURL string) {
+ if authURL == "" || authURL == lastAuthURL {
+ return
+ }
+ lastAuthURL = authURL
+ s.logf("To start this tsnet server, restart with TS_AUTHKEY set, or go to: %s", authURL)
+ }
go s.lb.WatchNotifications(ctx, ipn.NotifyInitialState, nil, func(n *ipn.Notify) (keepGoing bool) {
+ if n.BrowseToURL != nil && *n.BrowseToURL != "" {
+ logAuthURL(*n.BrowseToURL)
+ }
if n.State == nil {
return true
}
@@ -1130,9 +1215,7 @@ func (s *Server) printAuthURLLoop() {
return
}
st := s.lb.StatusWithoutPeers()
- if st.AuthURL != "" {
- s.logf("To start this tsnet server, restart with TS_AUTHKEY set, or go to: %s", st.AuthURL)
- }
+ logAuthURL(st.AuthURL)
select {
case <-time.After(5 * time.Second):
case <-stateCh:
@@ -1247,6 +1330,14 @@ func (s *Server) getTCPHandlerForFlow(src, dst netip.AddrPort) (handler func(net
func (s *Server) getUDPHandlerForFlow(src, dst netip.AddrPort) (handler func(nettype.ConnPacketConn), intercept bool) {
ln, ok := s.listenerForDstAddr("udp", dst, false)
if !ok {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ for _, handler := range s.fallbackUDPHandlers {
+ connHandler, intercept := handler(src, dst)
+ if intercept {
+ return connHandler, intercept
+ }
+ }
return nil, true // don't handle, don't forward to localhost
}
return func(c nettype.ConnPacketConn) { ln.handle(c) }, true
@@ -1340,10 +1431,10 @@ func (s *Server) ListenTLS(network, addr string) (net.Listener, error) {
return nil, err
}
if !st.CurrentTailnet.MagicDNSEnabled {
- return nil, errors.New("tsnet: you must enable MagicDNS in the DNS page of the admin panel to proceed. See https://tailscale.com/s/https")
+ return nil, errors.New("tsnet: you must enable MagicDNS in the DNS page of the admin panel to proceed. See https://github.com/metacubex/tailscale/s/https")
}
if len(st.CertDomains) == 0 {
- return nil, errors.New("tsnet: you must enable HTTPS in the admin panel to proceed. See https://tailscale.com/s/https")
+ return nil, errors.New("tsnet: you must enable HTTPS in the admin panel to proceed. See https://github.com/metacubex/tailscale/s/https")
}
ln, err := s.listen(network, addr, listenOnTailnet)
@@ -1373,6 +1464,24 @@ func (s *Server) RegisterFallbackTCPHandler(cb FallbackTCPHandler) func() {
}
}
+// RegisterFallbackUDPHandler registers a callback which will be called
+// to handle a UDP flow to this tsnet node, for which no listeners will handle.
+//
+// If multiple fallback handlers are registered, they will be called in an
+// undefined order. See FallbackUDPHandler for details on handling a flow.
+//
+// The returned function can be used to deregister this callback.
+func (s *Server) RegisterFallbackUDPHandler(cb FallbackUDPHandler) func() {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ hnd := s.fallbackUDPHandlers.Add(cb)
+ return func() {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ delete(s.fallbackUDPHandlers, hnd)
+ }
+}
+
// getCert is the GetCertificate function used by ListenTLS.
//
// It calls GetCertificate on the localClient, passing in the ClientHelloInfo.
@@ -1493,7 +1602,7 @@ func (s *Server) ListenFunnel(network, addr string, opts ...FunnelOption) (net.L
srvConfig = &ipn.ServeConfig{}
}
if len(st.CertDomains) == 0 {
- return nil, errors.New("Funnel not available; HTTPS must be enabled. See https://tailscale.com/s/https")
+ return nil, errors.New("Funnel not available; HTTPS must be enabled. See https://github.com/metacubex/tailscale/s/https")
}
domain := st.CertDomains[0]
hp := ipn.HostPort(domain + ":" + portStr)
@@ -1596,7 +1705,7 @@ type ServiceModeHTTP struct {
// example.com/cap/foo only to paths beginning with /foo.
//
// For more information on app capabilities, see
- // https://tailscale.com/kb/1537/grants-app-capabilities
+ // https://github.com/metacubex/tailscale/kb/1537/grants-app-capabilities
AcceptAppCaps map[string][]string
// PROXYProtocolVersion indicates whether to send a PROXY protocol header
@@ -1626,7 +1735,7 @@ func (m ServiceModeHTTP) capsMap() map[string][]tailcfg.PeerCapability {
// A ServiceListener is a network listener for a Tailscale Service. For more
// information about Services, see
-// https://tailscale.com/kb/1552/tailscale-services
+// https://github.com/metacubex/tailscale/kb/1552/tailscale-services
type ServiceListener struct {
net.Listener
addr addr
@@ -1711,7 +1820,7 @@ func (sl *ServiceListener) Close() error {
// ErrUntaggedServiceHost is returned by ListenService when run on a node
// without any ACL tags. A node must use a tag-based identity to act as a
// Service host. For more information, see:
-// https://tailscale.com/kb/1552/tailscale-services#prerequisites
+// https://github.com/metacubex/tailscale/kb/1552/tailscale-services#prerequisites
var ErrUntaggedServiceHost = errors.New("service hosts must be tagged nodes")
// advertiseService ensures the Service is advertised by this node.
@@ -1750,12 +1859,13 @@ func (s *Server) decrementServiceAdvertisementLocked(name tailcfg.ServiceName) e
return nil
}
newAdvertised := make([]string, 0, advertised.Len()-1)
- for _, svc := range advertised.All() {
+ advertised.All()(func(_ int, svc string) bool {
if svc == name.String() {
- continue
+ return true
}
newAdvertised = append(newAdvertised, svc)
- }
+ return true
+ })
_, err := s.lb.EditPrefs(&ipn.MaskedPrefs{
AdvertiseServicesSet: true,
Prefs: ipn.Prefs{
@@ -1791,7 +1901,7 @@ func (s *Server) decrementServiceAdvertisementLocked(name tailcfg.ServiceName) e
//
// To advertise a Service with multiple ports, run ListenService multiple times.
// For more information about Services, see
-// https://tailscale.com/kb/1552/tailscale-services
+// https://github.com/metacubex/tailscale/kb/1552/tailscale-services
//
// This function will start the server if it is not already started.
func (s *Server) ListenService(name string, mode ServiceMode) (*ServiceListener, error) {
@@ -2181,7 +2291,7 @@ func (s *Server) GetRootPath() string {
// Packets will be written to the pcap until the process exits. The pcap needs a Lua dissector
// to be installed in Wireshark in order to decode properly: wgengine/capture/ts-dissector.lua
// in this repository.
-// https://tailscale.com/docs/reference/troubleshooting/network-configuration/inspect-unencrypted-packets
+// https://github.com/metacubex/tailscale/docs/reference/troubleshooting/network-configuration/inspect-unencrypted-packets
func (s *Server) CapturePcap(ctx context.Context, pcapFile string) error {
stream, err := s.localClient.StreamDebugCapture(ctx)
if err != nil {
diff --git a/tsnet/tsnet_test.go b/tsnet/tsnet_test.go
index 4ee0ab10cc1a0..518f0c804c9b9 100644
--- a/tsnet/tsnet_test.go
+++ b/tsnet/tsnet_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -18,6 +20,7 @@ import (
"errors"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
"math/big"
@@ -29,7 +32,6 @@ import (
"path/filepath"
"reflect"
"runtime"
- "slices"
"strconv"
"strings"
"sync"
@@ -38,31 +40,31 @@ import (
"time"
"github.com/google/go-cmp/cmp"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
dto "github.com/prometheus/client_model/go"
"github.com/prometheus/common/expfmt"
- "github.com/tailscale/wireguard-go/tun"
"golang.org/x/net/proxy"
- "tailscale.com/client/local"
- "tailscale.com/cmd/testwrapper/flakytest"
- "tailscale.com/internal/client/tailscale"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/net/netns"
- "tailscale.com/net/packet"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/tstest/deptest"
- "tailscale.com/tstest/integration"
- "tailscale.com/tstest/integration/testcontrol"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/types/views"
- "tailscale.com/util/mak"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/cmd/testwrapper/flakytest"
+ "github.com/metacubex/tailscale/internal/client/tailscale"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstest/deptest"
+ "github.com/metacubex/tailscale/tstest/integration"
+ "github.com/metacubex/tailscale/tstest/integration/testcontrol"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/must"
)
// TestListener_Server ensures that the listener type always keeps the Server
@@ -2905,11 +2907,11 @@ func TestDeps(t *testing.T) {
GOOS: "linux",
GOARCH: "amd64",
BadDeps: map[string]string{
- "golang.org/x/crypto/ssh": "tsnet should not depend on SSH",
- "golang.org/x/crypto/ssh/internal/bcrypt_pbkdf": "tsnet should not depend on SSH",
- "tailscale.com/ipn/store/awsstore": "tsnet callers wanting AWS state storage should import awsstore themselves",
- "tailscale.com/ipn/store/kubestore": "tsnet callers wanting Kubernetes state storage should import kubestore themselves",
- "tailscale.com/wif": "tsnet callers wanting workload identity federation should import tailscale.com/feature/identityfederation themselves",
+ "golang.org/x/crypto/ssh": "tsnet should not depend on SSH",
+ "golang.org/x/crypto/ssh/internal/bcrypt_pbkdf": "tsnet should not depend on SSH",
+ "github.com/metacubex/tailscale/ipn/store/awsstore": "tsnet callers wanting AWS state storage should import awsstore themselves",
+ "github.com/metacubex/tailscale/ipn/store/kubestore": "tsnet callers wanting Kubernetes state storage should import kubestore themselves",
+ "github.com/metacubex/tailscale/wif": "tsnet callers wanting workload identity federation should import github.com/metacubex/tailscale/feature/identityfederation themselves",
},
OnDep: func(dep string) {
if strings.Contains(dep, "portlist") ||
diff --git a/tstest/archtest/archtest_test.go b/tstest/archtest/archtest_test.go
index 1523baf7b2044..c6f6028f99385 100644
--- a/tstest/archtest/archtest_test.go
+++ b/tstest/archtest/archtest_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,7 +9,7 @@ import (
"runtime"
"testing"
- "gvisor.dev/gvisor/pkg/atomicbitops"
+ "github.com/metacubex/gvisor/pkg/atomicbitops"
)
// tests netstack's AlignedAtomicInt64.
diff --git a/tstest/archtest/qemu_test.go b/tstest/archtest/qemu_test.go
index 400f8bc4f9ea0..08b267a318289 100644
--- a/tstest/archtest/qemu_test.go
+++ b/tstest/archtest/qemu_test.go
@@ -1,7 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux && amd64 && !race
package archtest
@@ -13,7 +14,7 @@ import (
"strings"
"testing"
- "tailscale.com/util/cibuild"
+ "github.com/metacubex/tailscale/util/cibuild"
)
func TestInQemu(t *testing.T) {
@@ -53,7 +54,7 @@ func TestInQemu(t *testing.T) {
"test",
"--exec="+execVia,
"-v",
- "tailscale.com/tstest/archtest",
+ "github.com/metacubex/tailscale/tstest/archtest",
)
cmd.Env = append(os.Environ(), "GOARCH="+arch.Goarch)
out, err := cmd.CombinedOutput()
diff --git a/tstest/chonktest/chonktest.go b/tstest/chonktest/chonktest.go
index b0b32e6151c82..90130045dbe9e 100644
--- a/tstest/chonktest/chonktest.go
+++ b/tstest/chonktest/chonktest.go
@@ -16,9 +16,9 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/util/must"
"golang.org/x/crypto/blake2s"
- "tailscale.com/tka"
- "tailscale.com/util/must"
)
// returns a random source based on the test name + extraSeed.
diff --git a/tstest/chonktest/tailchonk_test.go b/tstest/chonktest/tailchonk_test.go
index 99b57f54f5900..be0f34d3680a2 100644
--- a/tstest/chonktest/tailchonk_test.go
+++ b/tstest/chonktest/tailchonk_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,8 +8,8 @@ package chonktest
import (
"testing"
- "tailscale.com/tka"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/util/must"
)
func TestImplementsChonk(t *testing.T) {
diff --git a/tstest/clock.go b/tstest/clock.go
index 1f88fb0a28611..db462ddd41bb5 100644
--- a/tstest/clock.go
+++ b/tstest/clock.go
@@ -8,8 +8,8 @@ import (
"sync"
"time"
- "tailscale.com/tstime"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/util/mak"
)
// ClockOpts is used to configure the initial settings for a Clock. Once the
diff --git a/tstest/clock_test.go b/tstest/clock_test.go
index 5a05d57bbee71..132801df7929a 100644
--- a/tstest/clock_test.go
+++ b/tstest/clock_test.go
@@ -1,15 +1,17 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package tstest
import (
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"sync/atomic"
"testing"
"time"
- "tailscale.com/tstime"
+ "github.com/metacubex/tailscale/tstime"
)
func TestClockWithDefinedStartTime(t *testing.T) {
diff --git a/tstest/deptest/deptest.go b/tstest/deptest/deptest.go
index 59672761ef06b..f19aed5307bd2 100644
--- a/tstest/deptest/deptest.go
+++ b/tstest/deptest/deptest.go
@@ -8,17 +8,17 @@ package deptest
import (
"encoding/json"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
- "slices"
"strings"
"sync"
"testing"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/util/set"
)
type DepChecker struct {
@@ -61,7 +61,7 @@ func (c DepChecker) Check(t *testing.T) {
}
tsRoot := sync.OnceValue(func() string {
- out, err := exec.Command("go", "list", "-f", "{{.Dir}}", "tailscale.com").Output()
+ out, err := exec.Command("go", "list", "-f", "{{.Dir}}", "github.com/metacubex/tailscale").Output()
if err != nil {
t.Fatalf("failed to find tailscale.com root: %v", err)
}
@@ -87,11 +87,11 @@ func (c DepChecker) Check(t *testing.T) {
// Doing this in the general case requires network access at runtime
// (resolving a package path to its module, possibly doing the ?go-get=1
// meta tag dance), so we just check the common case of
- // "tailscale.com/*" packages for now, with the assumption that all
- // "tailscale.com/*" packages are in the same module, which isn't
+ // "github.com/metacubex/tailscale/*" packages for now, with the assumption that all
+ // "github.com/metacubex/tailscale/*" packages are in the same module, which isn't
// necessarily true in the general case.
for dep := range c.BadDeps {
- if suf, ok := strings.CutPrefix(dep, "tailscale.com/"); ok {
+ if suf, ok := strings.CutPrefix(dep, "github.com/metacubex/tailscale/"); ok {
pkgDir := filepath.Join(tsRoot(), suf)
if _, err := os.Stat(pkgDir); err != nil {
t.Errorf("listed BadDep %q doesn't seem to exist anymore: %v", dep, err)
diff --git a/tstest/deptest/deptest_test.go b/tstest/deptest/deptest_test.go
index 1b83d46d3cc31..bbe91ed3fc3f4 100644
--- a/tstest/deptest/deptest_test.go
+++ b/tstest/deptest/deptest_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/tstest/integration/capmap_test.go b/tstest/integration/capmap_test.go
index aea4a210b44e1..644853cabbace 100644
--- a/tstest/integration/capmap_test.go
+++ b/tstest/integration/capmap_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,8 +10,8 @@ import (
"testing"
"time"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
)
// TestPeerCapMap tests that the node capability map (CapMap) is included in peer information.
diff --git a/tstest/integration/gen_deps.go b/tstest/integration/gen_deps.go
index 7e668266bbb78..178145322329d 100644
--- a/tstest/integration/gen_deps.go
+++ b/tstest/integration/gen_deps.go
@@ -25,7 +25,7 @@ func generate(goos string) {
var x struct {
Imports []string
}
- cmd := exec.Command("go", "list", "-json", "tailscale.com/cmd/tailscaled")
+ cmd := exec.Command("go", "list", "-json", "github.com/metacubex/tailscale/cmd/tailscaled")
cmd.Env = append(os.Environ(), "GOOS="+goos, "GOARCH=amd64")
j, err := cmd.Output()
if err != nil {
diff --git a/tstest/integration/integration.go b/tstest/integration/integration.go
index 861ec808d0206..fc7b753503ba1 100644
--- a/tstest/integration/integration.go
+++ b/tstest/integration/integration.go
@@ -32,26 +32,26 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/derp/derpserver"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/ipn/store"
+ "github.com/metacubex/tailscale/net/stun/stuntest"
+ "github.com/metacubex/tailscale/safesocket"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstest/integration/testcontrol"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/types/nettype"
+ "github.com/metacubex/tailscale/util/rands"
+ "github.com/metacubex/tailscale/util/zstdframe"
+ "github.com/metacubex/tailscale/version"
"go4.org/mem"
- "tailscale.com/client/local"
- "tailscale.com/derp/derpserver"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/ipn/store"
- "tailscale.com/net/stun/stuntest"
- "tailscale.com/safesocket"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/tstest/integration/testcontrol"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/types/nettype"
- "tailscale.com/util/rands"
- "tailscale.com/util/zstdframe"
- "tailscale.com/version"
)
var (
@@ -204,7 +204,7 @@ func buildTestBinaries(dir string) error {
}
return bi, nil
}
- err := build(dir, "tailscale.com/cmd/tailscaled", "tailscale.com/cmd/tailscale")
+ err := build(dir, "github.com/metacubex/tailscale/cmd/tailscaled", "github.com/metacubex/tailscale/cmd/tailscale")
if err != nil {
return err
}
diff --git a/tstest/integration/integration_linkat_linux_test.go b/tstest/integration/integration_linkat_linux_test.go
index fc0a2873f68bd..a2a9eb5a5de39 100644
--- a/tstest/integration/integration_linkat_linux_test.go
+++ b/tstest/integration/integration_linkat_linux_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/tstest/integration/integration_test.go b/tstest/integration/integration_test.go
index 3064d6a26f96d..5ea0083ee758c 100644
--- a/tstest/integration/integration_test.go
+++ b/tstest/integration/integration_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,6 +14,7 @@ import (
"errors"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net"
"net/http"
@@ -22,7 +25,6 @@ import (
"path/filepath"
"regexp"
"runtime"
- "slices"
"strconv"
"strings"
"sync"
@@ -31,27 +33,27 @@ import (
"time"
"github.com/google/go-cmp/cmp"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/client/tailscale"
+ "github.com/metacubex/tailscale/cmd/testwrapper/flakytest"
+ "github.com/metacubex/tailscale/feature"
+ _ "github.com/metacubex/tailscale/feature/clientupdate"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/net/udprelay/status"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstest/integration/testcontrol"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/set"
"github.com/miekg/dns"
"go4.org/mem"
- "tailscale.com/client/local"
- "tailscale.com/client/tailscale"
- "tailscale.com/cmd/testwrapper/flakytest"
- "tailscale.com/feature"
- _ "tailscale.com/feature/clientupdate"
- "tailscale.com/health"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn"
- "tailscale.com/net/tsaddr"
- "tailscale.com/net/tstun"
- "tailscale.com/net/udprelay/status"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/tstest/integration/testcontrol"
- "tailscale.com/types/key"
- "tailscale.com/types/netmap"
- "tailscale.com/types/opt"
- "tailscale.com/util/must"
- "tailscale.com/util/set"
)
func TestMain(m *testing.M) {
diff --git a/tstest/integration/nat/nat_test.go b/tstest/integration/nat/nat_test.go
index 8eca5742f28d8..005400f7b23f8 100644
--- a/tstest/integration/nat/nat_test.go
+++ b/tstest/integration/nat/nat_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,12 +7,12 @@ package nat
import (
"bytes"
- "cmp"
"context"
"encoding/json"
"errors"
"flag"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"io"
"net"
"net/http"
@@ -25,13 +27,13 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/client/tailscale"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest/natlab/vnet"
"golang.org/x/mod/modfile"
"golang.org/x/sync/errgroup"
- "tailscale.com/client/tailscale"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest/natlab/vnet"
)
var (
diff --git a/tstest/integration/tailscaled_deps_test_darwin.go b/tstest/integration/tailscaled_deps_test_darwin.go
index 70e0d75faf3eb..b7b7cf717cbb3 100644
--- a/tstest/integration/tailscaled_deps_test_darwin.go
+++ b/tstest/integration/tailscaled_deps_test_darwin.go
@@ -10,53 +10,53 @@ import (
// Otherwise cmd/go never sees that we depend on these packages'
// transitive deps when we run "go install tailscaled" in a child
// process and can cache a prior success when a dependency changes.
- _ "tailscale.com/chirp"
- _ "tailscale.com/client/local"
- _ "tailscale.com/cmd/tailscaled/childproc"
- _ "tailscale.com/control/controlclient"
- _ "tailscale.com/derp/derphttp"
- _ "tailscale.com/drive/driveimpl"
- _ "tailscale.com/envknob"
- _ "tailscale.com/feature"
- _ "tailscale.com/feature/buildfeatures"
- _ "tailscale.com/feature/condregister"
- _ "tailscale.com/feature/ssh"
- _ "tailscale.com/health"
- _ "tailscale.com/hostinfo"
- _ "tailscale.com/ipn"
- _ "tailscale.com/ipn/conffile"
- _ "tailscale.com/ipn/ipnlocal"
- _ "tailscale.com/ipn/ipnserver"
- _ "tailscale.com/ipn/store"
- _ "tailscale.com/ipn/store/mem"
- _ "tailscale.com/logpolicy"
- _ "tailscale.com/logtail"
- _ "tailscale.com/net/dns"
- _ "tailscale.com/net/dnsfallback"
- _ "tailscale.com/net/netmon"
- _ "tailscale.com/net/netns"
- _ "tailscale.com/net/proxymux"
- _ "tailscale.com/net/socks5"
- _ "tailscale.com/net/tsdial"
- _ "tailscale.com/net/tstun"
- _ "tailscale.com/paths"
- _ "tailscale.com/safesocket"
- _ "tailscale.com/syncs"
- _ "tailscale.com/tailcfg"
- _ "tailscale.com/tsd"
- _ "tailscale.com/tsweb/varz"
- _ "tailscale.com/types/flagtype"
- _ "tailscale.com/types/key"
- _ "tailscale.com/types/logger"
- _ "tailscale.com/types/logid"
- _ "tailscale.com/util/clientmetric"
- _ "tailscale.com/util/eventbus"
- _ "tailscale.com/util/osshare"
- _ "tailscale.com/util/syspolicy/pkey"
- _ "tailscale.com/util/syspolicy/policyclient"
- _ "tailscale.com/version"
- _ "tailscale.com/version/distro"
- _ "tailscale.com/wgengine"
- _ "tailscale.com/wgengine/netstack"
- _ "tailscale.com/wgengine/router"
+ _ "github.com/metacubex/tailscale/chirp"
+ _ "github.com/metacubex/tailscale/client/local"
+ _ "github.com/metacubex/tailscale/cmd/tailscaled/childproc"
+ _ "github.com/metacubex/tailscale/control/controlclient"
+ _ "github.com/metacubex/tailscale/derp/derphttp"
+ _ "github.com/metacubex/tailscale/drive/driveimpl"
+ _ "github.com/metacubex/tailscale/envknob"
+ _ "github.com/metacubex/tailscale/feature"
+ _ "github.com/metacubex/tailscale/feature/buildfeatures"
+ _ "github.com/metacubex/tailscale/feature/condregister"
+ _ "github.com/metacubex/tailscale/feature/ssh"
+ _ "github.com/metacubex/tailscale/health"
+ _ "github.com/metacubex/tailscale/hostinfo"
+ _ "github.com/metacubex/tailscale/ipn"
+ _ "github.com/metacubex/tailscale/ipn/conffile"
+ _ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ _ "github.com/metacubex/tailscale/ipn/ipnserver"
+ _ "github.com/metacubex/tailscale/ipn/store"
+ _ "github.com/metacubex/tailscale/ipn/store/mem"
+ _ "github.com/metacubex/tailscale/logpolicy"
+ _ "github.com/metacubex/tailscale/logtail"
+ _ "github.com/metacubex/tailscale/net/dns"
+ _ "github.com/metacubex/tailscale/net/dnsfallback"
+ _ "github.com/metacubex/tailscale/net/netmon"
+ _ "github.com/metacubex/tailscale/net/netns"
+ _ "github.com/metacubex/tailscale/net/proxymux"
+ _ "github.com/metacubex/tailscale/net/socks5"
+ _ "github.com/metacubex/tailscale/net/tsdial"
+ _ "github.com/metacubex/tailscale/net/tstun"
+ _ "github.com/metacubex/tailscale/paths"
+ _ "github.com/metacubex/tailscale/safesocket"
+ _ "github.com/metacubex/tailscale/syncs"
+ _ "github.com/metacubex/tailscale/tailcfg"
+ _ "github.com/metacubex/tailscale/tsd"
+ _ "github.com/metacubex/tailscale/tsweb/varz"
+ _ "github.com/metacubex/tailscale/types/flagtype"
+ _ "github.com/metacubex/tailscale/types/key"
+ _ "github.com/metacubex/tailscale/types/logger"
+ _ "github.com/metacubex/tailscale/types/logid"
+ _ "github.com/metacubex/tailscale/util/clientmetric"
+ _ "github.com/metacubex/tailscale/util/eventbus"
+ _ "github.com/metacubex/tailscale/util/osshare"
+ _ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ _ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ _ "github.com/metacubex/tailscale/version"
+ _ "github.com/metacubex/tailscale/version/distro"
+ _ "github.com/metacubex/tailscale/wgengine"
+ _ "github.com/metacubex/tailscale/wgengine/netstack"
+ _ "github.com/metacubex/tailscale/wgengine/router"
)
diff --git a/tstest/integration/tailscaled_deps_test_freebsd.go b/tstest/integration/tailscaled_deps_test_freebsd.go
index 70e0d75faf3eb..b7b7cf717cbb3 100644
--- a/tstest/integration/tailscaled_deps_test_freebsd.go
+++ b/tstest/integration/tailscaled_deps_test_freebsd.go
@@ -10,53 +10,53 @@ import (
// Otherwise cmd/go never sees that we depend on these packages'
// transitive deps when we run "go install tailscaled" in a child
// process and can cache a prior success when a dependency changes.
- _ "tailscale.com/chirp"
- _ "tailscale.com/client/local"
- _ "tailscale.com/cmd/tailscaled/childproc"
- _ "tailscale.com/control/controlclient"
- _ "tailscale.com/derp/derphttp"
- _ "tailscale.com/drive/driveimpl"
- _ "tailscale.com/envknob"
- _ "tailscale.com/feature"
- _ "tailscale.com/feature/buildfeatures"
- _ "tailscale.com/feature/condregister"
- _ "tailscale.com/feature/ssh"
- _ "tailscale.com/health"
- _ "tailscale.com/hostinfo"
- _ "tailscale.com/ipn"
- _ "tailscale.com/ipn/conffile"
- _ "tailscale.com/ipn/ipnlocal"
- _ "tailscale.com/ipn/ipnserver"
- _ "tailscale.com/ipn/store"
- _ "tailscale.com/ipn/store/mem"
- _ "tailscale.com/logpolicy"
- _ "tailscale.com/logtail"
- _ "tailscale.com/net/dns"
- _ "tailscale.com/net/dnsfallback"
- _ "tailscale.com/net/netmon"
- _ "tailscale.com/net/netns"
- _ "tailscale.com/net/proxymux"
- _ "tailscale.com/net/socks5"
- _ "tailscale.com/net/tsdial"
- _ "tailscale.com/net/tstun"
- _ "tailscale.com/paths"
- _ "tailscale.com/safesocket"
- _ "tailscale.com/syncs"
- _ "tailscale.com/tailcfg"
- _ "tailscale.com/tsd"
- _ "tailscale.com/tsweb/varz"
- _ "tailscale.com/types/flagtype"
- _ "tailscale.com/types/key"
- _ "tailscale.com/types/logger"
- _ "tailscale.com/types/logid"
- _ "tailscale.com/util/clientmetric"
- _ "tailscale.com/util/eventbus"
- _ "tailscale.com/util/osshare"
- _ "tailscale.com/util/syspolicy/pkey"
- _ "tailscale.com/util/syspolicy/policyclient"
- _ "tailscale.com/version"
- _ "tailscale.com/version/distro"
- _ "tailscale.com/wgengine"
- _ "tailscale.com/wgengine/netstack"
- _ "tailscale.com/wgengine/router"
+ _ "github.com/metacubex/tailscale/chirp"
+ _ "github.com/metacubex/tailscale/client/local"
+ _ "github.com/metacubex/tailscale/cmd/tailscaled/childproc"
+ _ "github.com/metacubex/tailscale/control/controlclient"
+ _ "github.com/metacubex/tailscale/derp/derphttp"
+ _ "github.com/metacubex/tailscale/drive/driveimpl"
+ _ "github.com/metacubex/tailscale/envknob"
+ _ "github.com/metacubex/tailscale/feature"
+ _ "github.com/metacubex/tailscale/feature/buildfeatures"
+ _ "github.com/metacubex/tailscale/feature/condregister"
+ _ "github.com/metacubex/tailscale/feature/ssh"
+ _ "github.com/metacubex/tailscale/health"
+ _ "github.com/metacubex/tailscale/hostinfo"
+ _ "github.com/metacubex/tailscale/ipn"
+ _ "github.com/metacubex/tailscale/ipn/conffile"
+ _ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ _ "github.com/metacubex/tailscale/ipn/ipnserver"
+ _ "github.com/metacubex/tailscale/ipn/store"
+ _ "github.com/metacubex/tailscale/ipn/store/mem"
+ _ "github.com/metacubex/tailscale/logpolicy"
+ _ "github.com/metacubex/tailscale/logtail"
+ _ "github.com/metacubex/tailscale/net/dns"
+ _ "github.com/metacubex/tailscale/net/dnsfallback"
+ _ "github.com/metacubex/tailscale/net/netmon"
+ _ "github.com/metacubex/tailscale/net/netns"
+ _ "github.com/metacubex/tailscale/net/proxymux"
+ _ "github.com/metacubex/tailscale/net/socks5"
+ _ "github.com/metacubex/tailscale/net/tsdial"
+ _ "github.com/metacubex/tailscale/net/tstun"
+ _ "github.com/metacubex/tailscale/paths"
+ _ "github.com/metacubex/tailscale/safesocket"
+ _ "github.com/metacubex/tailscale/syncs"
+ _ "github.com/metacubex/tailscale/tailcfg"
+ _ "github.com/metacubex/tailscale/tsd"
+ _ "github.com/metacubex/tailscale/tsweb/varz"
+ _ "github.com/metacubex/tailscale/types/flagtype"
+ _ "github.com/metacubex/tailscale/types/key"
+ _ "github.com/metacubex/tailscale/types/logger"
+ _ "github.com/metacubex/tailscale/types/logid"
+ _ "github.com/metacubex/tailscale/util/clientmetric"
+ _ "github.com/metacubex/tailscale/util/eventbus"
+ _ "github.com/metacubex/tailscale/util/osshare"
+ _ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ _ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ _ "github.com/metacubex/tailscale/version"
+ _ "github.com/metacubex/tailscale/version/distro"
+ _ "github.com/metacubex/tailscale/wgengine"
+ _ "github.com/metacubex/tailscale/wgengine/netstack"
+ _ "github.com/metacubex/tailscale/wgengine/router"
)
diff --git a/tstest/integration/tailscaled_deps_test_linux.go b/tstest/integration/tailscaled_deps_test_linux.go
index 70e0d75faf3eb..b7b7cf717cbb3 100644
--- a/tstest/integration/tailscaled_deps_test_linux.go
+++ b/tstest/integration/tailscaled_deps_test_linux.go
@@ -10,53 +10,53 @@ import (
// Otherwise cmd/go never sees that we depend on these packages'
// transitive deps when we run "go install tailscaled" in a child
// process and can cache a prior success when a dependency changes.
- _ "tailscale.com/chirp"
- _ "tailscale.com/client/local"
- _ "tailscale.com/cmd/tailscaled/childproc"
- _ "tailscale.com/control/controlclient"
- _ "tailscale.com/derp/derphttp"
- _ "tailscale.com/drive/driveimpl"
- _ "tailscale.com/envknob"
- _ "tailscale.com/feature"
- _ "tailscale.com/feature/buildfeatures"
- _ "tailscale.com/feature/condregister"
- _ "tailscale.com/feature/ssh"
- _ "tailscale.com/health"
- _ "tailscale.com/hostinfo"
- _ "tailscale.com/ipn"
- _ "tailscale.com/ipn/conffile"
- _ "tailscale.com/ipn/ipnlocal"
- _ "tailscale.com/ipn/ipnserver"
- _ "tailscale.com/ipn/store"
- _ "tailscale.com/ipn/store/mem"
- _ "tailscale.com/logpolicy"
- _ "tailscale.com/logtail"
- _ "tailscale.com/net/dns"
- _ "tailscale.com/net/dnsfallback"
- _ "tailscale.com/net/netmon"
- _ "tailscale.com/net/netns"
- _ "tailscale.com/net/proxymux"
- _ "tailscale.com/net/socks5"
- _ "tailscale.com/net/tsdial"
- _ "tailscale.com/net/tstun"
- _ "tailscale.com/paths"
- _ "tailscale.com/safesocket"
- _ "tailscale.com/syncs"
- _ "tailscale.com/tailcfg"
- _ "tailscale.com/tsd"
- _ "tailscale.com/tsweb/varz"
- _ "tailscale.com/types/flagtype"
- _ "tailscale.com/types/key"
- _ "tailscale.com/types/logger"
- _ "tailscale.com/types/logid"
- _ "tailscale.com/util/clientmetric"
- _ "tailscale.com/util/eventbus"
- _ "tailscale.com/util/osshare"
- _ "tailscale.com/util/syspolicy/pkey"
- _ "tailscale.com/util/syspolicy/policyclient"
- _ "tailscale.com/version"
- _ "tailscale.com/version/distro"
- _ "tailscale.com/wgengine"
- _ "tailscale.com/wgengine/netstack"
- _ "tailscale.com/wgengine/router"
+ _ "github.com/metacubex/tailscale/chirp"
+ _ "github.com/metacubex/tailscale/client/local"
+ _ "github.com/metacubex/tailscale/cmd/tailscaled/childproc"
+ _ "github.com/metacubex/tailscale/control/controlclient"
+ _ "github.com/metacubex/tailscale/derp/derphttp"
+ _ "github.com/metacubex/tailscale/drive/driveimpl"
+ _ "github.com/metacubex/tailscale/envknob"
+ _ "github.com/metacubex/tailscale/feature"
+ _ "github.com/metacubex/tailscale/feature/buildfeatures"
+ _ "github.com/metacubex/tailscale/feature/condregister"
+ _ "github.com/metacubex/tailscale/feature/ssh"
+ _ "github.com/metacubex/tailscale/health"
+ _ "github.com/metacubex/tailscale/hostinfo"
+ _ "github.com/metacubex/tailscale/ipn"
+ _ "github.com/metacubex/tailscale/ipn/conffile"
+ _ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ _ "github.com/metacubex/tailscale/ipn/ipnserver"
+ _ "github.com/metacubex/tailscale/ipn/store"
+ _ "github.com/metacubex/tailscale/ipn/store/mem"
+ _ "github.com/metacubex/tailscale/logpolicy"
+ _ "github.com/metacubex/tailscale/logtail"
+ _ "github.com/metacubex/tailscale/net/dns"
+ _ "github.com/metacubex/tailscale/net/dnsfallback"
+ _ "github.com/metacubex/tailscale/net/netmon"
+ _ "github.com/metacubex/tailscale/net/netns"
+ _ "github.com/metacubex/tailscale/net/proxymux"
+ _ "github.com/metacubex/tailscale/net/socks5"
+ _ "github.com/metacubex/tailscale/net/tsdial"
+ _ "github.com/metacubex/tailscale/net/tstun"
+ _ "github.com/metacubex/tailscale/paths"
+ _ "github.com/metacubex/tailscale/safesocket"
+ _ "github.com/metacubex/tailscale/syncs"
+ _ "github.com/metacubex/tailscale/tailcfg"
+ _ "github.com/metacubex/tailscale/tsd"
+ _ "github.com/metacubex/tailscale/tsweb/varz"
+ _ "github.com/metacubex/tailscale/types/flagtype"
+ _ "github.com/metacubex/tailscale/types/key"
+ _ "github.com/metacubex/tailscale/types/logger"
+ _ "github.com/metacubex/tailscale/types/logid"
+ _ "github.com/metacubex/tailscale/util/clientmetric"
+ _ "github.com/metacubex/tailscale/util/eventbus"
+ _ "github.com/metacubex/tailscale/util/osshare"
+ _ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ _ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ _ "github.com/metacubex/tailscale/version"
+ _ "github.com/metacubex/tailscale/version/distro"
+ _ "github.com/metacubex/tailscale/wgengine"
+ _ "github.com/metacubex/tailscale/wgengine/netstack"
+ _ "github.com/metacubex/tailscale/wgengine/router"
)
diff --git a/tstest/integration/tailscaled_deps_test_openbsd.go b/tstest/integration/tailscaled_deps_test_openbsd.go
index 70e0d75faf3eb..b7b7cf717cbb3 100644
--- a/tstest/integration/tailscaled_deps_test_openbsd.go
+++ b/tstest/integration/tailscaled_deps_test_openbsd.go
@@ -10,53 +10,53 @@ import (
// Otherwise cmd/go never sees that we depend on these packages'
// transitive deps when we run "go install tailscaled" in a child
// process and can cache a prior success when a dependency changes.
- _ "tailscale.com/chirp"
- _ "tailscale.com/client/local"
- _ "tailscale.com/cmd/tailscaled/childproc"
- _ "tailscale.com/control/controlclient"
- _ "tailscale.com/derp/derphttp"
- _ "tailscale.com/drive/driveimpl"
- _ "tailscale.com/envknob"
- _ "tailscale.com/feature"
- _ "tailscale.com/feature/buildfeatures"
- _ "tailscale.com/feature/condregister"
- _ "tailscale.com/feature/ssh"
- _ "tailscale.com/health"
- _ "tailscale.com/hostinfo"
- _ "tailscale.com/ipn"
- _ "tailscale.com/ipn/conffile"
- _ "tailscale.com/ipn/ipnlocal"
- _ "tailscale.com/ipn/ipnserver"
- _ "tailscale.com/ipn/store"
- _ "tailscale.com/ipn/store/mem"
- _ "tailscale.com/logpolicy"
- _ "tailscale.com/logtail"
- _ "tailscale.com/net/dns"
- _ "tailscale.com/net/dnsfallback"
- _ "tailscale.com/net/netmon"
- _ "tailscale.com/net/netns"
- _ "tailscale.com/net/proxymux"
- _ "tailscale.com/net/socks5"
- _ "tailscale.com/net/tsdial"
- _ "tailscale.com/net/tstun"
- _ "tailscale.com/paths"
- _ "tailscale.com/safesocket"
- _ "tailscale.com/syncs"
- _ "tailscale.com/tailcfg"
- _ "tailscale.com/tsd"
- _ "tailscale.com/tsweb/varz"
- _ "tailscale.com/types/flagtype"
- _ "tailscale.com/types/key"
- _ "tailscale.com/types/logger"
- _ "tailscale.com/types/logid"
- _ "tailscale.com/util/clientmetric"
- _ "tailscale.com/util/eventbus"
- _ "tailscale.com/util/osshare"
- _ "tailscale.com/util/syspolicy/pkey"
- _ "tailscale.com/util/syspolicy/policyclient"
- _ "tailscale.com/version"
- _ "tailscale.com/version/distro"
- _ "tailscale.com/wgengine"
- _ "tailscale.com/wgengine/netstack"
- _ "tailscale.com/wgengine/router"
+ _ "github.com/metacubex/tailscale/chirp"
+ _ "github.com/metacubex/tailscale/client/local"
+ _ "github.com/metacubex/tailscale/cmd/tailscaled/childproc"
+ _ "github.com/metacubex/tailscale/control/controlclient"
+ _ "github.com/metacubex/tailscale/derp/derphttp"
+ _ "github.com/metacubex/tailscale/drive/driveimpl"
+ _ "github.com/metacubex/tailscale/envknob"
+ _ "github.com/metacubex/tailscale/feature"
+ _ "github.com/metacubex/tailscale/feature/buildfeatures"
+ _ "github.com/metacubex/tailscale/feature/condregister"
+ _ "github.com/metacubex/tailscale/feature/ssh"
+ _ "github.com/metacubex/tailscale/health"
+ _ "github.com/metacubex/tailscale/hostinfo"
+ _ "github.com/metacubex/tailscale/ipn"
+ _ "github.com/metacubex/tailscale/ipn/conffile"
+ _ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ _ "github.com/metacubex/tailscale/ipn/ipnserver"
+ _ "github.com/metacubex/tailscale/ipn/store"
+ _ "github.com/metacubex/tailscale/ipn/store/mem"
+ _ "github.com/metacubex/tailscale/logpolicy"
+ _ "github.com/metacubex/tailscale/logtail"
+ _ "github.com/metacubex/tailscale/net/dns"
+ _ "github.com/metacubex/tailscale/net/dnsfallback"
+ _ "github.com/metacubex/tailscale/net/netmon"
+ _ "github.com/metacubex/tailscale/net/netns"
+ _ "github.com/metacubex/tailscale/net/proxymux"
+ _ "github.com/metacubex/tailscale/net/socks5"
+ _ "github.com/metacubex/tailscale/net/tsdial"
+ _ "github.com/metacubex/tailscale/net/tstun"
+ _ "github.com/metacubex/tailscale/paths"
+ _ "github.com/metacubex/tailscale/safesocket"
+ _ "github.com/metacubex/tailscale/syncs"
+ _ "github.com/metacubex/tailscale/tailcfg"
+ _ "github.com/metacubex/tailscale/tsd"
+ _ "github.com/metacubex/tailscale/tsweb/varz"
+ _ "github.com/metacubex/tailscale/types/flagtype"
+ _ "github.com/metacubex/tailscale/types/key"
+ _ "github.com/metacubex/tailscale/types/logger"
+ _ "github.com/metacubex/tailscale/types/logid"
+ _ "github.com/metacubex/tailscale/util/clientmetric"
+ _ "github.com/metacubex/tailscale/util/eventbus"
+ _ "github.com/metacubex/tailscale/util/osshare"
+ _ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ _ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ _ "github.com/metacubex/tailscale/version"
+ _ "github.com/metacubex/tailscale/version/distro"
+ _ "github.com/metacubex/tailscale/wgengine"
+ _ "github.com/metacubex/tailscale/wgengine/netstack"
+ _ "github.com/metacubex/tailscale/wgengine/router"
)
diff --git a/tstest/integration/tailscaled_deps_test_windows.go b/tstest/integration/tailscaled_deps_test_windows.go
index 00768c99e79c1..7a7976e045621 100644
--- a/tstest/integration/tailscaled_deps_test_windows.go
+++ b/tstest/integration/tailscaled_deps_test_windows.go
@@ -10,66 +10,66 @@ import (
// Otherwise cmd/go never sees that we depend on these packages'
// transitive deps when we run "go install tailscaled" in a child
// process and can cache a prior success when a dependency changes.
- _ "github.com/dblohm7/wingoes/com"
- _ "github.com/tailscale/wireguard-go/tun"
+ _ "github.com/metacubex/tailscale-wireguard-go/tun"
+ _ "github.com/metacubex/tailscale/client/local"
+ _ "github.com/metacubex/tailscale/cmd/tailscaled/childproc"
+ _ "github.com/metacubex/tailscale/cmd/tailscaled/tailscaledhooks"
+ _ "github.com/metacubex/tailscale/control/controlclient"
+ _ "github.com/metacubex/tailscale/derp/derphttp"
+ _ "github.com/metacubex/tailscale/drive/driveimpl"
+ _ "github.com/metacubex/tailscale/envknob"
+ _ "github.com/metacubex/tailscale/feature"
+ _ "github.com/metacubex/tailscale/feature/buildfeatures"
+ _ "github.com/metacubex/tailscale/feature/condregister"
+ _ "github.com/metacubex/tailscale/health"
+ _ "github.com/metacubex/tailscale/hostinfo"
+ _ "github.com/metacubex/tailscale/ipn"
+ _ "github.com/metacubex/tailscale/ipn/auditlog"
+ _ "github.com/metacubex/tailscale/ipn/conffile"
+ _ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ _ "github.com/metacubex/tailscale/ipn/ipnserver"
+ _ "github.com/metacubex/tailscale/ipn/store"
+ _ "github.com/metacubex/tailscale/ipn/store/mem"
+ _ "github.com/metacubex/tailscale/logpolicy"
+ _ "github.com/metacubex/tailscale/logtail"
+ _ "github.com/metacubex/tailscale/net/dns"
+ _ "github.com/metacubex/tailscale/net/dnsfallback"
+ _ "github.com/metacubex/tailscale/net/netmon"
+ _ "github.com/metacubex/tailscale/net/netns"
+ _ "github.com/metacubex/tailscale/net/proxymux"
+ _ "github.com/metacubex/tailscale/net/socks5"
+ _ "github.com/metacubex/tailscale/net/tsdial"
+ _ "github.com/metacubex/tailscale/net/tstun"
+ _ "github.com/metacubex/tailscale/paths"
+ _ "github.com/metacubex/tailscale/safesocket"
+ _ "github.com/metacubex/tailscale/syncs"
+ _ "github.com/metacubex/tailscale/tailcfg"
+ _ "github.com/metacubex/tailscale/tsd"
+ _ "github.com/metacubex/tailscale/tsweb/varz"
+ _ "github.com/metacubex/tailscale/types/flagtype"
+ _ "github.com/metacubex/tailscale/types/key"
+ _ "github.com/metacubex/tailscale/types/logger"
+ _ "github.com/metacubex/tailscale/types/logid"
+ _ "github.com/metacubex/tailscale/util/backoff"
+ _ "github.com/metacubex/tailscale/util/clientmetric"
+ _ "github.com/metacubex/tailscale/util/eventbus"
+ _ "github.com/metacubex/tailscale/util/osdiag"
+ _ "github.com/metacubex/tailscale/util/osshare"
+ _ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ _ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ _ "github.com/metacubex/tailscale/util/wingoes/com"
+ _ "github.com/metacubex/tailscale/util/winipcfg"
+ _ "github.com/metacubex/tailscale/util/winutil"
+ _ "github.com/metacubex/tailscale/util/winutil/gp"
+ _ "github.com/metacubex/tailscale/version"
+ _ "github.com/metacubex/tailscale/version/distro"
+ _ "github.com/metacubex/tailscale/wf"
+ _ "github.com/metacubex/tailscale/wgengine"
+ _ "github.com/metacubex/tailscale/wgengine/netstack"
+ _ "github.com/metacubex/tailscale/wgengine/router"
_ "golang.org/x/sys/windows"
_ "golang.org/x/sys/windows/svc"
_ "golang.org/x/sys/windows/svc/eventlog"
_ "golang.org/x/sys/windows/svc/mgr"
_ "golang.zx2c4.com/wintun"
- _ "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
- _ "tailscale.com/client/local"
- _ "tailscale.com/cmd/tailscaled/childproc"
- _ "tailscale.com/cmd/tailscaled/tailscaledhooks"
- _ "tailscale.com/control/controlclient"
- _ "tailscale.com/derp/derphttp"
- _ "tailscale.com/drive/driveimpl"
- _ "tailscale.com/envknob"
- _ "tailscale.com/feature"
- _ "tailscale.com/feature/buildfeatures"
- _ "tailscale.com/feature/condregister"
- _ "tailscale.com/health"
- _ "tailscale.com/hostinfo"
- _ "tailscale.com/ipn"
- _ "tailscale.com/ipn/auditlog"
- _ "tailscale.com/ipn/conffile"
- _ "tailscale.com/ipn/ipnlocal"
- _ "tailscale.com/ipn/ipnserver"
- _ "tailscale.com/ipn/store"
- _ "tailscale.com/ipn/store/mem"
- _ "tailscale.com/logpolicy"
- _ "tailscale.com/logtail"
- _ "tailscale.com/net/dns"
- _ "tailscale.com/net/dnsfallback"
- _ "tailscale.com/net/netmon"
- _ "tailscale.com/net/netns"
- _ "tailscale.com/net/proxymux"
- _ "tailscale.com/net/socks5"
- _ "tailscale.com/net/tsdial"
- _ "tailscale.com/net/tstun"
- _ "tailscale.com/paths"
- _ "tailscale.com/safesocket"
- _ "tailscale.com/syncs"
- _ "tailscale.com/tailcfg"
- _ "tailscale.com/tsd"
- _ "tailscale.com/tsweb/varz"
- _ "tailscale.com/types/flagtype"
- _ "tailscale.com/types/key"
- _ "tailscale.com/types/logger"
- _ "tailscale.com/types/logid"
- _ "tailscale.com/util/backoff"
- _ "tailscale.com/util/clientmetric"
- _ "tailscale.com/util/eventbus"
- _ "tailscale.com/util/osdiag"
- _ "tailscale.com/util/osshare"
- _ "tailscale.com/util/syspolicy/pkey"
- _ "tailscale.com/util/syspolicy/policyclient"
- _ "tailscale.com/util/winutil"
- _ "tailscale.com/util/winutil/gp"
- _ "tailscale.com/version"
- _ "tailscale.com/version/distro"
- _ "tailscale.com/wf"
- _ "tailscale.com/wgengine"
- _ "tailscale.com/wgengine/netstack"
- _ "tailscale.com/wgengine/router"
)
diff --git a/tstest/integration/testcontrol/testcontrol.go b/tstest/integration/testcontrol/testcontrol.go
index c96b1ed33a126..519806fe42a37 100644
--- a/tstest/integration/testcontrol/testcontrol.go
+++ b/tstest/integration/testcontrol/testcontrol.go
@@ -7,43 +7,43 @@ package testcontrol
import (
"bufio"
"bytes"
- "cmp"
"context"
"encoding/binary"
"encoding/json"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ "github.com/metacubex/tailscale/util/go120/randv2"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
- "maps"
- "math/rand/v2"
"net/http"
"net/http/httptest"
"net/netip"
"net/url"
- "slices"
"sort"
"strings"
"sync"
"time"
+ "github.com/metacubex/tailscale/control/controlhttp/controlhttpserver"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/tstest/tkatest"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/util/httpm"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/rands"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/zstdframe"
"golang.org/x/net/http2"
- "tailscale.com/control/controlhttp/controlhttpserver"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/tsaddr"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tka"
- "tailscale.com/tstest/tkatest"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/opt"
- "tailscale.com/util/httpm"
- "tailscale.com/util/mak"
- "tailscale.com/util/must"
- "tailscale.com/util/rands"
- "tailscale.com/util/set"
- "tailscale.com/util/zstdframe"
)
const msgLimit = 1 << 20 // encrypted message length limit
@@ -73,11 +73,11 @@ type Server struct {
// Online=true. This is a coarse stand-in for the per-node
// online/offline tracking that production control servers do based
// on streaming map sessions: certain disco-key handling fast paths
- // in [tailscale.com/control/controlclient] and
- // [tailscale.com/wgengine/userspace] only fire when the peer is
+ // in [github.com/metacubex/tailscale/control/controlclient] and
+ // [github.com/metacubex/tailscale/wgengine/userspace] only fire when the peer is
// reported online, so without this flag they are silently skipped
// in tests, which can mask bugs and slow down recovery from disco
- // rotations. See [tailscale.com/control/controlclient/map.go]
+ // rotations. See [github.com/metacubex/tailscale/control/controlclient/map.go]
// removeUnwantedDiscoUpdates and
// removeUnwantedDiscoUpdatesFromFullNetmapUpdate for callers that
// branch on Online.
@@ -719,7 +719,7 @@ func (s *Server) getUser(nodeKey key.NodePublic) (*tailcfg.User, *tailcfg.Login)
Provider: "testcontrol",
LoginName: loginName,
DisplayName: displayName,
- ProfilePicURL: "https://tailscale.com/static/images/marketing/team-carney.jpg",
+ ProfilePicURL: "https://github.com/metacubex/tailscale/static/images/marketing/team-carney.jpg",
}
user := &tailcfg.User{
ID: id,
diff --git a/tstest/integration/testcontrol/testcontrol_test.go b/tstest/integration/testcontrol/testcontrol_test.go
index d3008cdb7f43b..cf6b3214ea863 100644
--- a/tstest/integration/testcontrol/testcontrol_test.go
+++ b/tstest/integration/testcontrol/testcontrol_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -15,13 +17,13 @@ import (
"testing"
"time"
- "tailscale.com/control/ts2021"
- "tailscale.com/control/tsp"
- "tailscale.com/net/tsdial"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest/integration/testcontrol"
- "tailscale.com/types/key"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/control/ts2021"
+ "github.com/metacubex/tailscale/control/tsp"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest/integration/testcontrol"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/util/must"
)
// TestStreamingMapReqReadOnlyByVersion verifies that testcontrol matches
diff --git a/tstest/integration/vms/derive_bindhost_test.go b/tstest/integration/vms/derive_bindhost_test.go
index 079308055da3a..40a48ea45657e 100644
--- a/tstest/integration/vms/derive_bindhost_test.go
+++ b/tstest/integration/vms/derive_bindhost_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,7 +10,7 @@ import (
"runtime"
"testing"
- "tailscale.com/net/netmon"
+ "github.com/metacubex/tailscale/net/netmon"
)
func deriveBindhost(t *testing.T) string {
diff --git a/tstest/integration/vms/distros_test.go b/tstest/integration/vms/distros_test.go
index 8cc15aa7297fc..ee956b2ef6311 100644
--- a/tstest/integration/vms/distros_test.go
+++ b/tstest/integration/vms/distros_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/tstest/integration/vms/harness_test.go b/tstest/integration/vms/harness_test.go
index ccff6e81e0f33..a57bfe2a2491e 100644
--- a/tstest/integration/vms/harness_test.go
+++ b/tstest/integration/vms/harness_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !windows && !plan9
-
package vms
import (
@@ -22,12 +22,12 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest/integration"
+ "github.com/metacubex/tailscale/tstest/integration/testcontrol"
+ "github.com/metacubex/tailscale/types/dnstype"
"golang.org/x/crypto/ssh"
"golang.org/x/net/proxy"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest/integration"
- "tailscale.com/tstest/integration/testcontrol"
- "tailscale.com/types/dnstype"
)
type Harness struct {
diff --git a/tstest/integration/vms/nixos_test.go b/tstest/integration/vms/nixos_test.go
index 7d7a104363761..b952c6eceb050 100644
--- a/tstest/integration/vms/nixos_test.go
+++ b/tstest/integration/vms/nixos_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !windows && !plan9
-
package vms
import (
@@ -15,7 +15,7 @@ import (
"testing"
"text/template"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
var (
diff --git a/tstest/integration/vms/top_level_test.go b/tstest/integration/vms/top_level_test.go
index 849abfd2469ed..9d35d7f62afab 100644
--- a/tstest/integration/vms/top_level_test.go
+++ b/tstest/integration/vms/top_level_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !windows && !plan9
-
package vms
import (
diff --git a/tstest/integration/vms/vm_setup_test.go b/tstest/integration/vms/vm_setup_test.go
index 690c89dcf487b..1a5e3ec3ababa 100644
--- a/tstest/integration/vms/vm_setup_test.go
+++ b/tstest/integration/vms/vm_setup_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !windows && !plan9
-
package vms
import (
@@ -27,9 +27,9 @@ import (
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
"github.com/aws/aws-sdk-go-v2/service/s3"
+ "github.com/metacubex/tailscale/types/logger"
"github.com/pkg/sftp"
"golang.org/x/crypto/ssh"
- "tailscale.com/types/logger"
)
type vmInstance struct {
diff --git a/tstest/integration/vms/vms_steps_test.go b/tstest/integration/vms/vms_steps_test.go
index 940c92ddac63c..58666123bb0fa 100644
--- a/tstest/integration/vms/vms_steps_test.go
+++ b/tstest/integration/vms/vms_steps_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !windows && !plan9
-
package vms
import (
diff --git a/tstest/integration/vms/vms_test.go b/tstest/integration/vms/vms_test.go
index ed64acb91f4eb..e7aa4937461bc 100644
--- a/tstest/integration/vms/vms_test.go
+++ b/tstest/integration/vms/vms_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !windows && !plan9
-
package vms
import (
@@ -22,12 +22,12 @@ import (
"text/template"
"time"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/logger"
"github.com/pkg/sftp"
expect "github.com/tailscale/goexpect"
"golang.org/x/crypto/ssh"
"golang.org/x/sync/semaphore"
- "tailscale.com/tstest"
- "tailscale.com/types/logger"
)
const (
diff --git a/tstest/integration/whois_test.go b/tstest/integration/whois_test.go
index b4e99a547028b..4c17773db2de0 100644
--- a/tstest/integration/whois_test.go
+++ b/tstest/integration/whois_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,7 +13,7 @@ import (
"testing"
"time"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/tstest"
)
// TestUserspaceWhoIsProxyMap verifies that WhoIs lookups work via the
diff --git a/tstest/iosdeps/iosdeps.go b/tstest/iosdeps/iosdeps.go
index a1279e20baa15..bb708d512c835 100644
--- a/tstest/iosdeps/iosdeps.go
+++ b/tstest/iosdeps/iosdeps.go
@@ -41,50 +41,50 @@ import (
_ "time"
_ "unsafe"
- _ "github.com/tailscale/wireguard-go/device"
- _ "github.com/tailscale/wireguard-go/tun"
+ _ "github.com/metacubex/tailscale-wireguard-go/device"
+ _ "github.com/metacubex/tailscale-wireguard-go/tun"
+ _ "github.com/metacubex/tailscale/client/tailscale/apitype"
+ _ "github.com/metacubex/tailscale/drive/driveimpl"
+ _ "github.com/metacubex/tailscale/envknob"
+ _ "github.com/metacubex/tailscale/feature/condregister"
+ _ "github.com/metacubex/tailscale/feature/syspolicy"
+ _ "github.com/metacubex/tailscale/feature/taildrop"
+ _ "github.com/metacubex/tailscale/hostinfo"
+ _ "github.com/metacubex/tailscale/ipn"
+ _ "github.com/metacubex/tailscale/ipn/ipnauth"
+ _ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ _ "github.com/metacubex/tailscale/ipn/localapi"
+ _ "github.com/metacubex/tailscale/logpolicy"
+ _ "github.com/metacubex/tailscale/logtail"
+ _ "github.com/metacubex/tailscale/logtail/filch"
+ _ "github.com/metacubex/tailscale/net/dns"
+ _ "github.com/metacubex/tailscale/net/netmon"
+ _ "github.com/metacubex/tailscale/net/netutil"
+ _ "github.com/metacubex/tailscale/net/tsaddr"
+ _ "github.com/metacubex/tailscale/net/tsdial"
+ _ "github.com/metacubex/tailscale/net/tshttpproxy"
+ _ "github.com/metacubex/tailscale/net/tstun"
+ _ "github.com/metacubex/tailscale/paths"
+ _ "github.com/metacubex/tailscale/safesocket"
+ _ "github.com/metacubex/tailscale/tsd"
+ _ "github.com/metacubex/tailscale/types/empty"
+ _ "github.com/metacubex/tailscale/types/key"
+ _ "github.com/metacubex/tailscale/types/lazy"
+ _ "github.com/metacubex/tailscale/types/logger"
+ _ "github.com/metacubex/tailscale/types/logid"
+ _ "github.com/metacubex/tailscale/types/netmap"
+ _ "github.com/metacubex/tailscale/util/clientmetric"
+ _ "github.com/metacubex/tailscale/util/dnsname"
+ _ "github.com/metacubex/tailscale/util/eventbus"
+ _ "github.com/metacubex/tailscale/util/must"
+ _ "github.com/metacubex/tailscale/util/set"
+ _ "github.com/metacubex/tailscale/util/syspolicy"
+ _ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ _ "github.com/metacubex/tailscale/util/syspolicy/setting"
+ _ "github.com/metacubex/tailscale/util/syspolicy/source"
+ _ "github.com/metacubex/tailscale/version"
+ _ "github.com/metacubex/tailscale/wgengine"
+ _ "github.com/metacubex/tailscale/wgengine/netstack"
+ _ "github.com/metacubex/tailscale/wgengine/router"
_ "golang.org/x/sys/unix"
- _ "tailscale.com/client/tailscale/apitype"
- _ "tailscale.com/drive/driveimpl"
- _ "tailscale.com/envknob"
- _ "tailscale.com/feature/condregister"
- _ "tailscale.com/feature/syspolicy"
- _ "tailscale.com/feature/taildrop"
- _ "tailscale.com/hostinfo"
- _ "tailscale.com/ipn"
- _ "tailscale.com/ipn/ipnauth"
- _ "tailscale.com/ipn/ipnlocal"
- _ "tailscale.com/ipn/localapi"
- _ "tailscale.com/logpolicy"
- _ "tailscale.com/logtail"
- _ "tailscale.com/logtail/filch"
- _ "tailscale.com/net/dns"
- _ "tailscale.com/net/netmon"
- _ "tailscale.com/net/netutil"
- _ "tailscale.com/net/tsaddr"
- _ "tailscale.com/net/tsdial"
- _ "tailscale.com/net/tshttpproxy"
- _ "tailscale.com/net/tstun"
- _ "tailscale.com/paths"
- _ "tailscale.com/safesocket"
- _ "tailscale.com/tsd"
- _ "tailscale.com/types/empty"
- _ "tailscale.com/types/key"
- _ "tailscale.com/types/lazy"
- _ "tailscale.com/types/logger"
- _ "tailscale.com/types/logid"
- _ "tailscale.com/types/netmap"
- _ "tailscale.com/util/clientmetric"
- _ "tailscale.com/util/dnsname"
- _ "tailscale.com/util/eventbus"
- _ "tailscale.com/util/must"
- _ "tailscale.com/util/set"
- _ "tailscale.com/util/syspolicy"
- _ "tailscale.com/util/syspolicy/pkey"
- _ "tailscale.com/util/syspolicy/setting"
- _ "tailscale.com/util/syspolicy/source"
- _ "tailscale.com/version"
- _ "tailscale.com/wgengine"
- _ "tailscale.com/wgengine/netstack"
- _ "tailscale.com/wgengine/router"
)
diff --git a/tstest/iosdeps/iosdeps_test.go b/tstest/iosdeps/iosdeps_test.go
index 870088e38db9a..97bf63567882f 100644
--- a/tstest/iosdeps/iosdeps_test.go
+++ b/tstest/iosdeps/iosdeps_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,7 +8,7 @@ package iosdeps
import (
"testing"
- "tailscale.com/tstest/deptest"
+ "github.com/metacubex/tailscale/tstest/deptest"
)
func TestDeps(t *testing.T) {
@@ -14,17 +16,17 @@ func TestDeps(t *testing.T) {
GOOS: "ios",
GOARCH: "arm64",
BadDeps: map[string]string{
- "testing": "do not use testing package in production code",
- "text/template": "linker bloat (MethodByName)",
- "html/template": "linker bloat (MethodByName)",
- "tailscale.com/net/wsconn": "https://github.com/tailscale/tailscale/issues/13762",
- "github.com/coder/websocket": "https://github.com/tailscale/tailscale/issues/13762",
- "github.com/mitchellh/go-ps": "https://github.com/tailscale/tailscale/pull/13759",
- "database/sql/driver": "iOS doesn't use an SQL database",
- "github.com/google/uuid": "see tailscale/tailscale#13760",
- "tailscale.com/clientupdate/distsign": "downloads via AppStore, not distsign",
- "github.com/tailscale/hujson": "no config file support on iOS",
- "tailscale.com/feature/capture": "no debug packet capture on iOS",
+ "testing": "do not use testing package in production code",
+ "text/template": "linker bloat (MethodByName)",
+ "html/template": "linker bloat (MethodByName)",
+ "github.com/metacubex/tailscale/net/wsconn": "https://github.com/tailscale/tailscale/issues/13762",
+ "github.com/coder/websocket": "https://github.com/tailscale/tailscale/issues/13762",
+ "github.com/mitchellh/go-ps": "https://github.com/tailscale/tailscale/pull/13759",
+ "database/sql/driver": "iOS doesn't use an SQL database",
+ "github.com/google/uuid": "see tailscale/tailscale#13760",
+ "github.com/metacubex/tailscale/clientupdate/distsign": "downloads via AppStore, not distsign",
+ "github.com/tailscale/hujson": "no config file support on iOS",
+ "github.com/metacubex/tailscale/feature/capture": "no debug packet capture on iOS",
},
}.Check(t)
}
diff --git a/tstest/jsdeps/jsdeps.go b/tstest/jsdeps/jsdeps.go
index 964ca51e10fb6..133b0c62f0d1c 100644
--- a/tstest/jsdeps/jsdeps.go
+++ b/tstest/jsdeps/jsdeps.go
@@ -13,23 +13,23 @@ import (
_ "encoding/hex"
_ "encoding/json"
_ "fmt"
+ _ "github.com/metacubex/tailscale/util/go120/randv2"
_ "log"
- _ "math/rand/v2"
_ "net"
_ "strings"
_ "time"
+ _ "github.com/metacubex/tailscale/control/controlclient"
+ _ "github.com/metacubex/tailscale/ipn"
+ _ "github.com/metacubex/tailscale/ipn/ipnserver"
+ _ "github.com/metacubex/tailscale/net/netaddr"
+ _ "github.com/metacubex/tailscale/net/netns"
+ _ "github.com/metacubex/tailscale/net/tsdial"
+ _ "github.com/metacubex/tailscale/safesocket"
+ _ "github.com/metacubex/tailscale/tailcfg"
+ _ "github.com/metacubex/tailscale/types/logger"
+ _ "github.com/metacubex/tailscale/wgengine"
+ _ "github.com/metacubex/tailscale/wgengine/netstack"
+ _ "github.com/metacubex/tailscale/words"
_ "golang.org/x/crypto/ssh"
- _ "tailscale.com/control/controlclient"
- _ "tailscale.com/ipn"
- _ "tailscale.com/ipn/ipnserver"
- _ "tailscale.com/net/netaddr"
- _ "tailscale.com/net/netns"
- _ "tailscale.com/net/tsdial"
- _ "tailscale.com/safesocket"
- _ "tailscale.com/tailcfg"
- _ "tailscale.com/types/logger"
- _ "tailscale.com/wgengine"
- _ "tailscale.com/wgengine/netstack"
- _ "tailscale.com/words"
)
diff --git a/tstest/jsdeps/jsdeps_test.go b/tstest/jsdeps/jsdeps_test.go
index ba6dad6badf3d..1b8606dd94dbe 100644
--- a/tstest/jsdeps/jsdeps_test.go
+++ b/tstest/jsdeps/jsdeps_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,7 +8,7 @@ package jsdeps
import (
"testing"
- "tailscale.com/tstest/deptest"
+ "github.com/metacubex/tailscale/tstest/deptest"
)
func TestDeps(t *testing.T) {
diff --git a/tstest/kernel_linux_test.go b/tstest/kernel_linux_test.go
index 9445ebe2c3866..3c89d936910ee 100644
--- a/tstest/kernel_linux_test.go
+++ b/tstest/kernel_linux_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux
-
package tstest
import "testing"
diff --git a/tstest/largetailnet/largetailnet.go b/tstest/largetailnet/largetailnet.go
index 73ec2da805051..57ead1491d9e1 100644
--- a/tstest/largetailnet/largetailnet.go
+++ b/tstest/largetailnet/largetailnet.go
@@ -29,11 +29,11 @@ import (
"sync/atomic"
"time"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest/integration/testcontrol"
+ "github.com/metacubex/tailscale/types/key"
"go4.org/mem"
- "tailscale.com/net/tsaddr"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest/integration/testcontrol"
- "tailscale.com/types/key"
)
// SelfUserID is the synthetic [tailcfg.UserID] assigned to the self node and
diff --git a/tstest/largetailnet/largetailnet_test.go b/tstest/largetailnet/largetailnet_test.go
index 07f67df820014..df1e09387f9d7 100644
--- a/tstest/largetailnet/largetailnet_test.go
+++ b/tstest/largetailnet/largetailnet_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -13,13 +15,13 @@ import (
"testing"
"time"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/tailcfg"
- "tailscale.com/tsnet"
- "tailscale.com/tstest/integration"
- "tailscale.com/tstest/integration/testcontrol"
- "tailscale.com/tstest/largetailnet"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsnet"
+ "github.com/metacubex/tailscale/tstest/integration"
+ "github.com/metacubex/tailscale/tstest/integration/testcontrol"
+ "github.com/metacubex/tailscale/tstest/largetailnet"
+ "github.com/metacubex/tailscale/types/logger"
)
// tsnet.Server.Up handles the wait-for-ipn.Running step itself: it
diff --git a/tstest/log.go b/tstest/log.go
index 73e973d238d66..e094b137afa69 100644
--- a/tstest/log.go
+++ b/tstest/log.go
@@ -11,9 +11,9 @@ import (
"sync"
"testing"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/testenv"
"go4.org/mem"
- "tailscale.com/types/logger"
- "tailscale.com/util/testenv"
)
type testLogWriter struct {
@@ -49,12 +49,12 @@ func (panicLogWriter) Write(b []byte) (int, error) {
os.Stderr.Write(b)
return len(b), nil
}
- panic(fmt.Sprintf("please use tailscale.com/logger.Logf instead of the log package (tried to log: %q)", b))
+ panic(fmt.Sprintf("please use github.com/metacubex/tailscale/logger.Logf instead of the log package (tried to log: %q)", b))
}
// PanicOnLog modifies the standard library log package's default output to
// an io.Writer that panics, to root out code that's not plumbing their logging
-// through explicit tailscale.com/logger.Logf paths.
+// through explicit github.com/metacubex/tailscale/logger.Logf paths.
func PanicOnLog() {
log.SetOutput(panicLogWriter{})
}
diff --git a/tstest/log_test.go b/tstest/log_test.go
index 34aab000d4ad3..94a8e0130504b 100644
--- a/tstest/log_test.go
+++ b/tstest/log_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/tstest/mts/mts.go b/tstest/mts/mts.go
index c91e0ce996f44..4f34644a26086 100644
--- a/tstest/mts/mts.go
+++ b/tstest/mts/mts.go
@@ -14,9 +14,10 @@ import (
"encoding/json"
"flag"
"fmt"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"log"
- "maps"
"net"
"net/http"
"net/url"
@@ -24,16 +25,15 @@ import (
"os/exec"
"path/filepath"
"regexp"
- "slices"
"strings"
"sync"
"syscall"
"time"
- "tailscale.com/client/local"
- "tailscale.com/types/bools"
- "tailscale.com/types/lazy"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/types/bools"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/util/mak"
)
func usage(args ...any) {
@@ -292,7 +292,7 @@ func (c *Client) RunCommand(name string, args []string) {
if _, err := lc.StatusWithoutPeers(probeCtx); err != nil {
log.Fatalf("instance %q not running? start with 'mts server start %q'; got error: %v", name, name, err)
}
- args = append([]string{"run", "tailscale.com/cmd/tailscale", "--socket=" + sock}, args...)
+ args = append([]string{"run", "github.com/metacubex/tailscale/cmd/tailscale", "--socket=" + sock}, args...)
cmd := exec.Command("go", args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
@@ -316,7 +316,7 @@ type Server struct {
func (s *Server) tailscaled() string {
v, err := s.lazyTailscaled.GetErr(func() (string, error) {
- out, err := exec.Command("go", "list", "-f", "{{.Target}}", "tailscale.com/cmd/tailscaled").CombinedOutput()
+ out, err := exec.Command("go", "list", "-f", "{{.Target}}", "github.com/metacubex/tailscale/cmd/tailscaled").CombinedOutput()
if err != nil {
return "", err
}
diff --git a/tstest/natlab/firewall.go b/tstest/natlab/firewall.go
index e9192cfbd8ab7..aebea1d58c06f 100644
--- a/tstest/natlab/firewall.go
+++ b/tstest/natlab/firewall.go
@@ -9,7 +9,7 @@ import (
"sync"
"time"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/util/mak"
)
// FirewallType is the type of filtering a stateful firewall
diff --git a/tstest/natlab/natlab.go b/tstest/natlab/natlab.go
index b66779eebe7a3..358241897040a 100644
--- a/tstest/natlab/natlab.go
+++ b/tstest/natlab/natlab.go
@@ -14,17 +14,17 @@ import (
"encoding/base64"
"errors"
"fmt"
- "math/rand/v2"
+ "github.com/metacubex/tailscale/util/go120/randv2"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net"
"net/netip"
"os"
- "slices"
"sort"
"strconv"
"sync"
"time"
- "tailscale.com/net/netaddr"
+ "github.com/metacubex/tailscale/net/netaddr"
)
var traceOn, _ = strconv.ParseBool(os.Getenv("NATLAB_TRACE"))
diff --git a/tstest/natlab/natlab_test.go b/tstest/natlab/natlab_test.go
index d604907017a84..81a66caae571a 100644
--- a/tstest/natlab/natlab_test.go
+++ b/tstest/natlab/natlab_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,7 +13,7 @@ import (
"testing"
"time"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/tstest"
)
func TestAllocIPs(t *testing.T) {
diff --git a/tstest/natlab/vmtest/cmd/natlabprep/natlabprep.go b/tstest/natlab/vmtest/cmd/natlabprep/natlabprep.go
index d60b878e397a1..c7086ffcdc5e2 100644
--- a/tstest/natlab/vmtest/cmd/natlabprep/natlabprep.go
+++ b/tstest/natlab/vmtest/cmd/natlabprep/natlabprep.go
@@ -10,7 +10,7 @@ import (
"context"
"log"
- "tailscale.com/tstest/natlab/vmtest"
+ "github.com/metacubex/tailscale/tstest/natlab/vmtest"
)
func main() {
diff --git a/tstest/natlab/vmtest/qemu.go b/tstest/natlab/vmtest/qemu.go
index fbf31adb3518c..9638b7a56f63a 100644
--- a/tstest/natlab/vmtest/qemu.go
+++ b/tstest/natlab/vmtest/qemu.go
@@ -19,7 +19,7 @@ import (
"testing"
"time"
- "tailscale.com/tstest/natlab/vnet"
+ "github.com/metacubex/tailscale/tstest/natlab/vnet"
)
// qemuAccelArgs returns QEMU command-line flags for hardware-accelerated
diff --git a/tstest/natlab/vmtest/version.go b/tstest/natlab/vmtest/version.go
index 7e76716e4016f..1e0aec49bbc3c 100644
--- a/tstest/natlab/vmtest/version.go
+++ b/tstest/natlab/vmtest/version.go
@@ -18,7 +18,7 @@ import (
"strconv"
"strings"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
// versionRE matches a concrete X.Y.Z release version.
@@ -35,7 +35,7 @@ func resolveTestVersion(ctx context.Context, v string) (string, error) {
}
return v, nil
}
- url := "https://pkgs.tailscale.com/" + v + "/?mode=json"
+ url := "https://pkgs.github.com/metacubex/tailscale/" + v + "/?mode=json"
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return "", err
@@ -113,7 +113,7 @@ func ensureVersionBinaries(ctx context.Context, version, arch string, logf logge
if err != nil {
return "", err
}
- url := fmt.Sprintf("https://pkgs.tailscale.com/%s/tailscale_%s_%s.tgz", track, version, arch)
+ url := fmt.Sprintf("https://pkgs.github.com/metacubex/tailscale/%s/tailscale_%s_%s.tgz", track, version, arch)
logf("downloading %s", url)
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
diff --git a/tstest/natlab/vmtest/version_test.go b/tstest/natlab/vmtest/version_test.go
index 3750562905fe7..d82fc0878bcc9 100644
--- a/tstest/natlab/vmtest/version_test.go
+++ b/tstest/natlab/vmtest/version_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/tstest/natlab/vmtest/vmtest.go b/tstest/natlab/vmtest/vmtest.go
index 206ffde785949..db7ea0e2f2efe 100644
--- a/tstest/natlab/vmtest/vmtest.go
+++ b/tstest/natlab/vmtest/vmtest.go
@@ -38,19 +38,19 @@ import (
"time"
"github.com/google/gopacket/layers"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstest/integration/testcontrol"
+ "github.com/metacubex/tailscale/tstest/natlab/vnet"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/util/mak"
dto "github.com/prometheus/client_model/go"
"github.com/prometheus/common/expfmt"
"go4.org/mem"
"golang.org/x/sync/errgroup"
- "tailscale.com/client/local"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/tstest/integration/testcontrol"
- "tailscale.com/tstest/natlab/vnet"
- "tailscale.com/types/key"
- "tailscale.com/util/mak"
)
var (
diff --git a/tstest/natlab/vmtest/vmtest_test.go b/tstest/natlab/vmtest/vmtest_test.go
index c317ed712623d..3cc2f7b3b8ea1 100644
--- a/tstest/natlab/vmtest/vmtest_test.go
+++ b/tstest/natlab/vmtest/vmtest_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,14 +14,14 @@ import (
"testing"
"time"
- "tailscale.com/client/local"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/tstest/integration/testcontrol"
- "tailscale.com/tstest/natlab/vmtest"
- "tailscale.com/tstest/natlab/vnet"
- "tailscale.com/types/key"
- "tailscale.com/types/netmap"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstest/integration/testcontrol"
+ "github.com/metacubex/tailscale/tstest/natlab/vmtest"
+ "github.com/metacubex/tailscale/tstest/natlab/vnet"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/netmap"
)
// skipIfNotMacOSArm64 skips the test when the host isn't a macOS arm64 host.
diff --git a/tstest/natlab/vnet/conf.go b/tstest/natlab/vnet/conf.go
index 191de9e1839ec..a1672ff1fb441 100644
--- a/tstest/natlab/vnet/conf.go
+++ b/tstest/natlab/vnet/conf.go
@@ -4,21 +4,21 @@
package vnet
import (
- "cmp"
"context"
"fmt"
- "iter"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"os"
- "slices"
"time"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcapgo"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
- "tailscale.com/util/must"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/set"
)
// Note: the exported Node and Network are the configuration types;
diff --git a/tstest/natlab/vnet/conf_test.go b/tstest/natlab/vnet/conf_test.go
index 5716a503e4007..726f80d3a0394 100644
--- a/tstest/natlab/vnet/conf_test.go
+++ b/tstest/natlab/vnet/conf_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/tstest/natlab/vnet/easyaf.go b/tstest/natlab/vnet/easyaf.go
index 1edc9b3cd16b2..0a37f20addf95 100644
--- a/tstest/natlab/vnet/easyaf.go
+++ b/tstest/natlab/vnet/easyaf.go
@@ -4,12 +4,12 @@
package vnet
import (
+ "github.com/metacubex/tailscale/util/go120/randv2"
"log"
- "math/rand/v2"
"net/netip"
"time"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/util/mak"
)
// easyAFNAT is an "Endpoint Independent" NAT, like Linux and most home routers
diff --git a/tstest/natlab/vnet/nat.go b/tstest/natlab/vnet/nat.go
index 172e19767b179..8423b290b84a7 100644
--- a/tstest/natlab/vnet/nat.go
+++ b/tstest/natlab/vnet/nat.go
@@ -5,12 +5,12 @@ package vnet
import (
"errors"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"log"
- "math/rand/v2"
"net/netip"
"time"
- "tailscale.com/util/mak"
+ "github.com/metacubex/tailscale/util/mak"
)
const (
diff --git a/tstest/natlab/vnet/vnet.go b/tstest/natlab/vnet/vnet.go
index 958da04de3afe..bd812935ab3da 100644
--- a/tstest/natlab/vnet/vnet.go
+++ b/tstest/natlab/vnet/vnet.go
@@ -19,11 +19,11 @@ import (
"encoding/json"
"errors"
"fmt"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"io"
- "iter"
"log"
- "maps"
- "math/rand/v2"
"net"
"net/http"
"net/http/httptest"
@@ -35,36 +35,36 @@ import (
"sync/atomic"
"time"
- "github.com/gaissmai/bart"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
+ "github.com/metacubex/bart"
+ "github.com/metacubex/gvisor/pkg/buffer"
+ "github.com/metacubex/gvisor/pkg/tcpip"
+ "github.com/metacubex/gvisor/pkg/tcpip/adapters/gonet"
+ "github.com/metacubex/gvisor/pkg/tcpip/header"
+ "github.com/metacubex/gvisor/pkg/tcpip/link/channel"
+ "github.com/metacubex/gvisor/pkg/tcpip/network/arp"
+ "github.com/metacubex/gvisor/pkg/tcpip/network/ipv4"
+ "github.com/metacubex/gvisor/pkg/tcpip/network/ipv6"
+ "github.com/metacubex/gvisor/pkg/tcpip/stack"
+ "github.com/metacubex/gvisor/pkg/tcpip/transport/icmp"
+ "github.com/metacubex/gvisor/pkg/tcpip/transport/tcp"
+ "github.com/metacubex/gvisor/pkg/waiter"
+ "github.com/metacubex/tailscale/client/local"
+ "github.com/metacubex/tailscale/derp/derpserver"
+ "github.com/metacubex/tailscale/net/netutil"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/net/stun"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest/integration/testcontrol"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/zstdframe"
"go4.org/mem"
- "gvisor.dev/gvisor/pkg/buffer"
- "gvisor.dev/gvisor/pkg/tcpip"
- "gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
- "gvisor.dev/gvisor/pkg/tcpip/header"
- "gvisor.dev/gvisor/pkg/tcpip/link/channel"
- "gvisor.dev/gvisor/pkg/tcpip/network/arp"
- "gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
- "gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
- "gvisor.dev/gvisor/pkg/tcpip/stack"
- "gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
- "gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
- "gvisor.dev/gvisor/pkg/waiter"
- "tailscale.com/client/local"
- "tailscale.com/derp/derpserver"
- "tailscale.com/net/netutil"
- "tailscale.com/net/netx"
- "tailscale.com/net/stun"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest/integration/testcontrol"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/util/mak"
- "tailscale.com/util/must"
- "tailscale.com/util/set"
- "tailscale.com/util/zstdframe"
)
const nicID = 1
diff --git a/tstest/natlab/vnet/vnet_test.go b/tstest/natlab/vnet/vnet_test.go
index 9d7c78c453b11..5215c1d33c684 100644
--- a/tstest/natlab/vnet/vnet_test.go
+++ b/tstest/natlab/vnet/vnet_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -18,7 +20,7 @@ import (
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/util/must"
)
const (
diff --git a/tstest/nettest/nettest.go b/tstest/nettest/nettest.go
index cfb0a921904eb..1535e48e06405 100644
--- a/tstest/nettest/nettest.go
+++ b/tstest/nettest/nettest.go
@@ -14,10 +14,10 @@ import (
"sync"
"testing"
- "tailscale.com/net/memnet"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netx"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/net/memnet"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/util/testenv"
)
var useMemNet = flag.Bool("use-test-memnet", false, "prefer using in-memory network for tests")
diff --git a/tstest/resource.go b/tstest/resource.go
index 867925b7ddeb1..ec2d5207cfbd0 100644
--- a/tstest/resource.go
+++ b/tstest/resource.go
@@ -5,9 +5,9 @@ package tstest
import (
"bytes"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"runtime"
"runtime/pprof"
- "slices"
"strings"
"testing"
"time"
@@ -54,7 +54,9 @@ func ResourceCheck(tb testing.TB) {
}
// Print goroutine diff, omitting tstest.ResourceCheck goroutines.
- self := func(g goroutine) bool { return bytes.Contains(g.stack, []byte("\ttailscale.com/tstest.goroutines+")) }
+ self := func(g goroutine) bool {
+ return bytes.Contains(g.stack, []byte("\tgithub.com/metacubex/tailscale/tstest.goroutines+"))
+ }
start.goroutines = slices.DeleteFunc(start.goroutines, self)
end.goroutines = slices.DeleteFunc(end.goroutines, self)
tb.Logf("goroutine diff (-start +end):\n%s", diffGoroutines(start, end))
@@ -80,20 +82,20 @@ func goroutines() (int, []byte) {
//
// goroutine profile: total 408
// 48 @ 0x47bc0e 0x136c6b9 0x136c69e 0x136c7ab 0x1379809 0x13797fa 0x483da1
-// # 0x136c6b8 gvisor.dev/gvisor/pkg/sync.Gopark+0x78 gvisor.dev/gvisor@v0.0.0-20250205023644-9414b50a5633/pkg/sync/runtime_unsafe.go:33
-// # 0x136c69d gvisor.dev/gvisor/pkg/sleep.(*Sleeper).nextWaker+0x5d gvisor.dev/gvisor@v0.0.0-20250205023644-9414b50a5633/pkg/sleep/sleep_unsafe.go:210
-// # 0x136c7aa gvisor.dev/gvisor/pkg/sleep.(*Sleeper).fetch+0x2a gvisor.dev/gvisor@v0.0.0-20250205023644-9414b50a5633/pkg/sleep/sleep_unsafe.go:257
-// # 0x1379808 gvisor.dev/gvisor/pkg/sleep.(*Sleeper).Fetch+0xa8 gvisor.dev/gvisor@v0.0.0-20250205023644-9414b50a5633/pkg/sleep/sleep_unsafe.go:280
-// # 0x13797f9 gvisor.dev/gvisor/pkg/tcpip/transport/tcp.(*processor).start+0x99 gvisor.dev/gvisor@v0.0.0-20250205023644-9414b50a5633/pkg/tcpip/transport/tcp/dispatcher.go:291
+// # 0x136c6b8 github.com/metacubex/gvisor/pkg/sync.Gopark+0x78 github.com/metacubex/gvisor@v0.0.0-20250205023644-9414b50a5633/pkg/sync/runtime_unsafe.go:33
+// # 0x136c69d github.com/metacubex/gvisor/pkg/sleep.(*Sleeper).nextWaker+0x5d github.com/metacubex/gvisor@v0.0.0-20250205023644-9414b50a5633/pkg/sleep/sleep_unsafe.go:210
+// # 0x136c7aa github.com/metacubex/gvisor/pkg/sleep.(*Sleeper).fetch+0x2a github.com/metacubex/gvisor@v0.0.0-20250205023644-9414b50a5633/pkg/sleep/sleep_unsafe.go:257
+// # 0x1379808 github.com/metacubex/gvisor/pkg/sleep.(*Sleeper).Fetch+0xa8 github.com/metacubex/gvisor@v0.0.0-20250205023644-9414b50a5633/pkg/sleep/sleep_unsafe.go:280
+// # 0x13797f9 github.com/metacubex/gvisor/pkg/tcpip/transport/tcp.(*processor).start+0x99 github.com/metacubex/gvisor@v0.0.0-20250205023644-9414b50a5633/pkg/tcpip/transport/tcp/dispatcher.go:291
//
// 48 @ 0x47bc0e 0x413705 0x4132b2 0x10fc905 0x483da1
-// # 0x10fc904 github.com/tailscale/wireguard-go/device.(*Device).RoutineDecryption+0x184 github.com/tailscale/wireguard-go@v0.0.0-20250107165329-0b8b35511f19/device/receive.go:245
+// # 0x10fc904 github.com/metacubex/tailscale-wireguard-go/device.(*Device).RoutineDecryption+0x184 github.com/metacubex/tailscale-wireguard-go@v0.0.0-20250107165329-0b8b35511f19/device/receive.go:245
//
// 48 @ 0x47bc0e 0x413705 0x4132b2 0x10fcd2a 0x483da1
-// # 0x10fcd29 github.com/tailscale/wireguard-go/device.(*Device).RoutineHandshake+0x169 github.com/tailscale/wireguard-go@v0.0.0-20250107165329-0b8b35511f19/device/receive.go:279
+// # 0x10fcd29 github.com/metacubex/tailscale-wireguard-go/device.(*Device).RoutineHandshake+0x169 github.com/metacubex/tailscale-wireguard-go@v0.0.0-20250107165329-0b8b35511f19/device/receive.go:279
//
// 48 @ 0x47bc0e 0x413705 0x4132b2 0x1100ba7 0x483da1
-// # 0x1100ba6 github.com/tailscale/wireguard-go/device.(*Device).RoutineEncryption+0x186 github.com/tailscale/wireguard-go@v0.0.0-20250107165329-0b8b35511f19/device/send.go:451
+// # 0x1100ba6 github.com/metacubex/tailscale-wireguard-go/device.(*Device).RoutineEncryption+0x186 github.com/metacubex/tailscale-wireguard-go@v0.0.0-20250107165329-0b8b35511f19/device/send.go:451
//
// 26 @ 0x47bc0e 0x458e57 0x847587 0x483da1
// # 0x847586 database/sql.(*DB).connectionOpener+0x86 database/sql/sql.go:1261
@@ -102,7 +104,7 @@ func goroutines() (int, []byte) {
// # 0x754926 net/http.(*persistConn).writeLoop+0xe6 net/http/transport.go:2596
//
// 7 @ 0x47bc0e 0x413705 0x4132b2 0x10fda4d 0x483da1
-// # 0x10fda4c github.com/tailscale/wireguard-go/device.(*Peer).RoutineSequentialReceiver+0x16c github.com/tailscale/wireguard-go@v0.0.0-20250107165329-0b8b35511f19/device/receive.go:443
+// # 0x10fda4c github.com/metacubex/tailscale-wireguard-go/device.(*Peer).RoutineSequentialReceiver+0x16c github.com/metacubex/tailscale-wireguard-go@v0.0.0-20250107165329-0b8b35511f19/device/receive.go:443
func parseGoroutines(g []byte) goroutineDump {
head, tail, ok := bytes.Cut(g, []byte("\n"))
if !ok {
diff --git a/tstest/resource_test.go b/tstest/resource_test.go
index 4c3b68eeb4d80..e27e0c3d54bd0 100644
--- a/tstest/resource_test.go
+++ b/tstest/resource_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/tstest/tkatest/tkatest.go b/tstest/tkatest/tkatest.go
index 2726b4deca249..80278d4827ead 100644
--- a/tstest/tkatest/tkatest.go
+++ b/tstest/tkatest/tkatest.go
@@ -9,14 +9,14 @@ import (
"encoding/json"
"errors"
"fmt"
- "iter"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
"log"
"net/http"
- "tailscale.com/tailcfg"
- "tailscale.com/tka"
- "tailscale.com/types/key"
- "tailscale.com/types/tkatype"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/tkatype"
)
func serverError(w http.ResponseWriter, format string, a ...any) error {
diff --git a/tstest/tlstest/tlstest_test.go b/tstest/tlstest/tlstest_test.go
index 7f3583c8af15a..d830dbb870294 100644
--- a/tstest/tlstest/tlstest_test.go
+++ b/tstest/tlstest/tlstest_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/tstest/tstest.go b/tstest/tstest.go
index 7e25ce8a03f35..0a32b78ae585e 100644
--- a/tstest/tstest.go
+++ b/tstest/tstest.go
@@ -14,10 +14,10 @@ import (
"testing"
"time"
- "tailscale.com/envknob"
- "tailscale.com/types/logger"
- "tailscale.com/util/backoff"
- "tailscale.com/util/cibuild"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/backoff"
+ "github.com/metacubex/tailscale/util/cibuild"
)
// AssertNotParallel asserts that t has not been marked as parallel.
diff --git a/tstest/tstest_test.go b/tstest/tstest_test.go
index 0c281d2352f7b..6f5a358e3584d 100644
--- a/tstest/tstest_test.go
+++ b/tstest/tstest_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/tstest/typewalk/typewalk.go b/tstest/typewalk/typewalk.go
index dea87a8e927fc..4aac3abe39141 100644
--- a/tstest/typewalk/typewalk.go
+++ b/tstest/typewalk/typewalk.go
@@ -5,7 +5,7 @@
package typewalk
import (
- "iter"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
"reflect"
"strings"
)
diff --git a/tstime/jitter.go b/tstime/jitter.go
index 987680f3c0ba7..27e0cb790a395 100644
--- a/tstime/jitter.go
+++ b/tstime/jitter.go
@@ -4,7 +4,7 @@
package tstime
import (
- "math/rand/v2"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"time"
)
diff --git a/tstime/jitter_test.go b/tstime/jitter_test.go
index 149ed3fa5d6d8..e03593c5eec6d 100644
--- a/tstime/jitter_test.go
+++ b/tstime/jitter_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/tstime/mono/mono_test.go b/tstime/mono/mono_test.go
index dfa6fe1f078a3..30ff36e19b9b0 100644
--- a/tstime/mono/mono_test.go
+++ b/tstime/mono/mono_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/tstime/rate/rate.go b/tstime/rate/rate.go
index 3f2f5c9be55f5..643dffded2732 100644
--- a/tstime/rate/rate.go
+++ b/tstime/rate/rate.go
@@ -14,7 +14,7 @@ import (
"sync"
"time"
- "tailscale.com/tstime/mono"
+ "github.com/metacubex/tailscale/tstime/mono"
)
// Limit defines the maximum frequency of some events.
diff --git a/tstime/rate/rate_test.go b/tstime/rate/rate_test.go
index 3486371be565a..d76b9e8aec970 100644
--- a/tstime/rate/rate_test.go
+++ b/tstime/rate/rate_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -16,7 +18,7 @@ import (
"testing"
"time"
- "tailscale.com/tstime/mono"
+ "github.com/metacubex/tailscale/tstime/mono"
)
func closeEnough(a, b Limit) bool {
diff --git a/tstime/rate/value.go b/tstime/rate/value.go
index 8a627ff36119e..a5694ca0e26b2 100644
--- a/tstime/rate/value.go
+++ b/tstime/rate/value.go
@@ -10,7 +10,7 @@ import (
"sync"
"time"
- "tailscale.com/tstime/mono"
+ "github.com/metacubex/tailscale/tstime/mono"
)
// Value measures the rate at which events occur,
diff --git a/tstime/rate/value_test.go b/tstime/rate/value_test.go
index e6d60798407f1..f22fdcded2a61 100644
--- a/tstime/rate/value_test.go
+++ b/tstime/rate/value_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,8 +14,8 @@ import (
qt "github.com/frankban/quicktest"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/tstime/mono"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/tstime/mono"
+ "github.com/metacubex/tailscale/util/must"
)
const (
diff --git a/tstime/tstime.go b/tstime/tstime.go
index 8c52a4652beca..7ebd0f8e03b70 100644
--- a/tstime/tstime.go
+++ b/tstime/tstime.go
@@ -198,7 +198,6 @@ func (StdClock) Since(t time.Time) time.Duration {
type GoDuration struct{ time.Duration }
var (
- _ encoding.TextAppender = (*GoDuration)(nil)
_ encoding.TextMarshaler = (*GoDuration)(nil)
_ encoding.TextUnmarshaler = (*GoDuration)(nil)
)
diff --git a/tstime/tstime_test.go b/tstime/tstime_test.go
index 80d4e318e66bc..0c6ab4b1bdd6c 100644
--- a/tstime/tstime_test.go
+++ b/tstime/tstime_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,7 +10,7 @@ import (
"testing"
"time"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/util/must"
)
func TestParseDuration(t *testing.T) {
diff --git a/tsweb/debug.go b/tsweb/debug.go
index e4ac7a55909dd..82cd241b4a1d4 100644
--- a/tsweb/debug.go
+++ b/tsweb/debug.go
@@ -13,9 +13,9 @@ import (
"os"
"runtime"
- "tailscale.com/feature"
- "tailscale.com/tsweb/varz"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/tsweb/varz"
+ "github.com/metacubex/tailscale/version"
)
// DebugHandler is an http.Handler that serves a debugging "homepage",
@@ -38,7 +38,7 @@ type DebugHandler struct {
// PrometheusHandler is an optional hook to enable native Prometheus
// support in the debug handler. It is disabled by default. Import the
-// tailscale.com/tsweb/promvarz package to enable this feature.
+// github.com/metacubex/tailscale/tsweb/promvarz package to enable this feature.
var PrometheusHandler feature.Hook[func(*DebugHandler)]
// Debugger returns the DebugHandler registered on mux at /debug/,
diff --git a/tsweb/debug_test.go b/tsweb/debug_test.go
index 79c686b6b95d9..c62aa81cd967d 100644
--- a/tsweb/debug_test.go
+++ b/tsweb/debug_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,12 +7,12 @@ package tsweb
import (
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net/http"
"net/http/httptest"
"net/netip"
"runtime"
- "slices"
"strings"
"testing"
)
diff --git a/tsweb/promvarz/promvarz.go b/tsweb/promvarz/promvarz.go
index 4fdf394d0891b..1d4bacca66621 100644
--- a/tsweb/promvarz/promvarz.go
+++ b/tsweb/promvarz/promvarz.go
@@ -9,10 +9,10 @@ import (
"fmt"
"net/http"
+ "github.com/metacubex/tailscale/tsweb"
+ "github.com/metacubex/tailscale/tsweb/varz"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/expfmt"
- "tailscale.com/tsweb"
- "tailscale.com/tsweb/varz"
)
func init() {
diff --git a/tsweb/promvarz/promvarz_test.go b/tsweb/promvarz/promvarz_test.go
index 123330d6e5831..225d6fbeb15dc 100644
--- a/tsweb/promvarz/promvarz_test.go
+++ b/tsweb/promvarz/promvarz_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/tsweb/request_id.go b/tsweb/request_id.go
index 351ed1710802b..0985c0fde1f28 100644
--- a/tsweb/request_id.go
+++ b/tsweb/request_id.go
@@ -8,8 +8,8 @@ import (
"net/http"
"time"
- "tailscale.com/util/ctxkey"
- "tailscale.com/util/rands"
+ "github.com/metacubex/tailscale/util/ctxkey"
+ "github.com/metacubex/tailscale/util/rands"
)
// RequestID is an opaque identifier for a HTTP request, used to correlate
diff --git a/tsweb/tsweb.go b/tsweb/tsweb.go
index 101512b89b7f8..310d197de7783 100644
--- a/tsweb/tsweb.go
+++ b/tsweb/tsweb.go
@@ -7,14 +7,14 @@ package tsweb
import (
"bufio"
"bytes"
- "cmp"
"context"
"errors"
"expvar"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"io"
"log"
- "maps"
"net"
"net/http"
"net/netip"
@@ -28,14 +28,15 @@ import (
"sync"
"time"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/metrics"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tsweb/varz"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/ctxkey"
+ "github.com/metacubex/tailscale/util/vizerror"
"go4.org/mem"
- "tailscale.com/envknob"
- "tailscale.com/metrics"
- "tailscale.com/net/tsaddr"
- "tailscale.com/tsweb/varz"
- "tailscale.com/types/logger"
- "tailscale.com/util/ctxkey"
- "tailscale.com/util/vizerror"
)
// DevMode controls whether extra output in shown, for when the binary is being run in dev mode.
@@ -63,7 +64,7 @@ func IsProd443(addr string) bool {
var debugTrustedCIDRs = envknob.RegisterString("TS_DEBUG_TRUSTED_CIDRS")
// trustedCIDRs returns the parsed CIDR prefixes from TS_DEBUG_TRUSTED_CIDRS.
-var trustedCIDRs = sync.OnceValue(func() []netip.Prefix {
+var trustedCIDRs = syncs.OnceValue(func() []netip.Prefix {
return parseTrustedCIDRs(debugTrustedCIDRs())
})
@@ -485,7 +486,7 @@ func ErrorHandler(h ReturnHandler, opts ErrorOptions) http.Handler {
// errCallback is added to logHandler's request context so that errorHandler can
// pass errors back up the stack to logHandler.
-var errCallback = ctxkey.New[func(HTTPError)]("tailscale.com/tsweb.errCallback", nil)
+var errCallback = ctxkey.New[func(HTTPError)]("github.com/metacubex/tailscale/tsweb.errCallback", nil)
// logHandler is a http.Handler which logs the HTTP request.
// It injects an errCallback for errorHandler to augment the log message with
@@ -783,7 +784,8 @@ func (h errorHandler) handleError(w http.ResponseWriter, r *http.Request, lw *lo
// Extract a presentable, loggable error.
var hOK bool
- hErr, hAsOK := errors.AsType[HTTPError](err)
+ var hErr HTTPError
+ hAsOK := errors.As(err, &hErr)
if hAsOK {
hOK = true
if hErr.Code == 0 {
diff --git a/tsweb/tsweb_test.go b/tsweb/tsweb_test.go
index 4e09bfffb2ae7..f9a44adbdf3f5 100644
--- a/tsweb/tsweb_test.go
+++ b/tsweb/tsweb_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -22,11 +24,11 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/metrics"
- "tailscale.com/tstest"
- "tailscale.com/util/httpm"
- "tailscale.com/util/must"
- "tailscale.com/util/vizerror"
+ "github.com/metacubex/tailscale/metrics"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/util/httpm"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/vizerror"
)
type noopHijacker struct {
@@ -694,7 +696,7 @@ func TestStdHandler_Panic(t *testing.T) {
t.Errorf("got Err prefix %q, want %q", r.Err[:min(len(r.Err), len(p))], p)
logerr = true
}
- if s := "\ntailscale.com/tsweb.panicElsewhere("; !strings.Contains(r.Err, s) {
+ if s := "\ngithub.com/metacubex/tailscale/tsweb.panicElsewhere("; !strings.Contains(r.Err, s) {
t.Errorf("want Err substr %q, not found", s)
logerr = true
}
@@ -1003,7 +1005,7 @@ func TestStdHandler_OnErrorPanic(t *testing.T) {
t.Errorf("got Err prefix %q, want %q", r.Err[:min(len(r.Err), len(p))], p)
logerr = true
}
- if s := "\ntailscale.com/tsweb.panicElsewhere("; !strings.Contains(r.Err, s) {
+ if s := "\ngithub.com/metacubex/tailscale/tsweb.panicElsewhere("; !strings.Contains(r.Err, s) {
t.Errorf("want Err substr %q, not found", s)
logerr = true
}
@@ -1222,12 +1224,12 @@ func TestCleanRedirectURL(t *testing.T) {
want string
wantErr bool
}{
- {"http://tailscale.com/foo", tailscaleHost, "http://tailscale.com/foo", false},
- {"http://tailscale.com/foo", tailscaleAndOtherHost, "http://tailscale.com/foo", false},
+ {"http://github.com/metacubex/tailscale/foo", tailscaleHost, "http://github.com/metacubex/tailscale/foo", false},
+ {"http://github.com/metacubex/tailscale/foo", tailscaleAndOtherHost, "http://github.com/metacubex/tailscale/foo", false},
{"http://microsoft.com/foo", tailscaleAndOtherHost, "http://microsoft.com/foo", false},
- {"https://tailscale.com/foo", tailscaleHost, "https://tailscale.com/foo", false},
+ {"https://github.com/metacubex/tailscale/foo", tailscaleHost, "https://github.com/metacubex/tailscale/foo", false},
{"/foo", tailscaleHost, "/foo", false},
- {"//tailscale.com/foo", tailscaleHost, "//tailscale.com/foo", false},
+ {"//github.com/metacubex/tailscale/foo", tailscaleHost, "//github.com/metacubex/tailscale/foo", false},
{"/a/foobar", tailscaleHost, "/a/foobar", false},
{"http://127.0.0.1/a/foobar", localHost, "http://127.0.0.1/a/foobar", false},
{"http://127.0.0.1:123/a/foobar", localHost, "http://127.0.0.1:123/a/foobar", false},
diff --git a/tsweb/varz/varz.go b/tsweb/varz/varz.go
index 0df6e57751a7e..ff77543e33074 100644
--- a/tsweb/varz/varz.go
+++ b/tsweb/varz/varz.go
@@ -6,9 +6,9 @@ package varz
import (
"bufio"
- "cmp"
"expvar"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"io"
"net/http"
"os"
@@ -23,11 +23,11 @@ import (
"unicode"
"unicode/utf8"
+ "github.com/metacubex/tailscale/metrics"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/version"
"golang.org/x/exp/constraints"
- "tailscale.com/metrics"
- "tailscale.com/syncs"
- "tailscale.com/types/logger"
- "tailscale.com/version"
)
// StaticStringVar returns a new expvar.Var that always returns s.
@@ -328,7 +328,7 @@ func ExpvarDoHandler(expvarDoFunc func(f func(expvar.KeyValue))) func(http.Respo
}
}
-var binaryName = sync.OnceValue(func() string {
+var binaryName = syncs.OnceValue(func() string {
exe, err := os.Executable()
if err != nil {
return ""
@@ -370,19 +370,19 @@ func writeMemstat[V constraints.Integer | constraints.Float](bw *bufio.Writer, t
bw.WriteByte(' ')
rt := reflect.TypeOf(v)
switch {
- case rt == reflect.TypeFor[int]() ||
- rt == reflect.TypeFor[uint]() ||
- rt == reflect.TypeFor[int8]() ||
- rt == reflect.TypeFor[uint8]() ||
- rt == reflect.TypeFor[int16]() ||
- rt == reflect.TypeFor[uint16]() ||
- rt == reflect.TypeFor[int32]() ||
- rt == reflect.TypeFor[uint32]() ||
- rt == reflect.TypeFor[int64]() ||
- rt == reflect.TypeFor[uint64]() ||
- rt == reflect.TypeFor[uintptr]():
+ case rt == reflect.TypeOf((*int)(nil)).Elem() ||
+ rt == reflect.TypeOf((*uint)(nil)).Elem() ||
+ rt == reflect.TypeOf((*int8)(nil)).Elem() ||
+ rt == reflect.TypeOf((*uint8)(nil)).Elem() ||
+ rt == reflect.TypeOf((*int16)(nil)).Elem() ||
+ rt == reflect.TypeOf((*uint16)(nil)).Elem() ||
+ rt == reflect.TypeOf((*int32)(nil)).Elem() ||
+ rt == reflect.TypeOf((*uint32)(nil)).Elem() ||
+ rt == reflect.TypeOf((*int64)(nil)).Elem() ||
+ rt == reflect.TypeOf((*uint64)(nil)).Elem() ||
+ rt == reflect.TypeOf((*uintptr)(nil)).Elem():
bw.Write(strconv.AppendInt(bw.AvailableBuffer(), int64(v), 10))
- case rt == reflect.TypeFor[float32]() || rt == reflect.TypeFor[float64]():
+ case rt == reflect.TypeOf((*float32)(nil)).Elem() || rt == reflect.TypeOf((*float64)(nil)).Elem():
bw.Write(strconv.AppendFloat(bw.AvailableBuffer(), float64(v), 'f', -1, 64))
}
bw.WriteByte('\n')
@@ -419,7 +419,8 @@ func structTypeSortedFields(t reflect.Type) []sortedStructField {
return v.([]sortedStructField)
}
fields := make([]sortedStructField, 0, t.NumField())
- for sf := range t.Fields() {
+ for i := 0; i < t.NumField(); i++ {
+ sf := t.Field(i)
name := sf.Name
if v := sf.Tag.Get("json"); v != "" {
v, _, _ = strings.Cut(v, ",")
diff --git a/tsweb/varz/varz_test.go b/tsweb/varz/varz_test.go
index 27094e77bf01d..d056424fd05c6 100644
--- a/tsweb/varz/varz_test.go
+++ b/tsweb/varz/varz_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,11 +14,11 @@ import (
"strings"
"testing"
- "tailscale.com/metrics"
- "tailscale.com/syncs"
- "tailscale.com/tstest"
- "tailscale.com/util/racebuild"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/metrics"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/util/racebuild"
+ "github.com/metacubex/tailscale/version"
)
func TestVarzHandler(t *testing.T) {
diff --git a/types/appctype/appconnector.go b/types/appctype/appconnector.go
index b0fd5e65ab6c2..c7d7af5566088 100644
--- a/types/appctype/appconnector.go
+++ b/types/appctype/appconnector.go
@@ -2,14 +2,14 @@
// SPDX-License-Identifier: BSD-3-Clause
// Package appcfg contains an experimental configuration structure for
-// "tailscale.com/app-connectors" capmap extensions.
+// "github.com/metacubex/tailscale/app-connectors" capmap extensions.
package appctype
import (
"net/netip"
+ "github.com/metacubex/tailscale/tailcfg"
"go4.org/netipx"
- "tailscale.com/tailcfg"
)
// ConfigID is an opaque identifier for a configuration.
diff --git a/types/appctype/appconnector_test.go b/types/appctype/appconnector_test.go
index f411faec5bef0..8e6c1b9c6b88d 100644
--- a/types/appctype/appconnector_test.go
+++ b/types/appctype/appconnector_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,8 +12,8 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
- "tailscale.com/tailcfg"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/util/must"
)
var golden = `{
diff --git a/types/bools/bools_test.go b/types/bools/bools_test.go
index 70fcd0fbcb1a2..d407cd217ae3d 100644
--- a/types/bools/bools_test.go
+++ b/types/bools/bools_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/types/dnstype/dnstype.go b/types/dnstype/dnstype.go
index 1cd38d38385ba..434b4fbd0ff1f 100644
--- a/types/dnstype/dnstype.go
+++ b/types/dnstype/dnstype.go
@@ -4,11 +4,11 @@
// Package dnstype defines types for working with DNS.
package dnstype
-//go:generate go run tailscale.com/cmd/viewer --type=Resolver --clonefunc=true
+//go:generate go run github.com/metacubex/tailscale/cmd/viewer --type=Resolver --clonefunc=true
import (
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
)
// Resolver is the configuration for one DNS resolver.
diff --git a/types/dnstype/dnstype_clone.go b/types/dnstype/dnstype_clone.go
index e690ebaec3865..f9fc6500881cc 100644
--- a/types/dnstype/dnstype_clone.go
+++ b/types/dnstype/dnstype_clone.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-// Code generated by tailscale.com/cmd/cloner; DO NOT EDIT.
+// Code generated by github.com/metacubex/tailscale/cmd/cloner; DO NOT EDIT.
package dnstype
diff --git a/types/dnstype/dnstype_test.go b/types/dnstype/dnstype_test.go
index 8f746ab76bec7..f475c3ba002b1 100644
--- a/types/dnstype/dnstype_test.go
+++ b/types/dnstype/dnstype_test.go
@@ -1,12 +1,14 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package dnstype
import (
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"reflect"
- "slices"
"sort"
"testing"
)
diff --git a/types/dnstype/dnstype_view.go b/types/dnstype/dnstype_view.go
index c91feb6b8aa38..3e3b1850f2787 100644
--- a/types/dnstype/dnstype_view.go
+++ b/types/dnstype/dnstype_view.go
@@ -10,12 +10,12 @@ import (
"errors"
"net/netip"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/types/views"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/types/views"
)
-//go:generate go run tailscale.com/cmd/cloner -clonefunc=true -type=Resolver
+//go:generate go run github.com/metacubex/tailscale/cmd/cloner -clonefunc=true -type=Resolver
// View returns a read-only view of Resolver.
func (p *Resolver) View() ResolverView {
diff --git a/types/events/disco_update.go b/types/events/disco_update.go
index 206c554a1d7f0..e920ffc5bb7ab 100644
--- a/types/events/disco_update.go
+++ b/types/events/disco_update.go
@@ -7,7 +7,7 @@ package events
import (
"net/netip"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/types/key"
)
// DiscoKeyAdvertisement is an event sent on the [eventbus.Bus] when a disco
diff --git a/types/geo/point_test.go b/types/geo/point_test.go
index 32a73180add34..aae0047b67d5b 100644
--- a/types/geo/point_test.go
+++ b/types/geo/point_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,7 +11,7 @@ import (
"testing"
"testing/quick"
- "tailscale.com/types/geo"
+ "github.com/metacubex/tailscale/types/geo"
)
func TestPointZero(t *testing.T) {
diff --git a/types/geo/quantize_test.go b/types/geo/quantize_test.go
index 59d5587e565dc..22b4bcf5256e2 100644
--- a/types/geo/quantize_test.go
+++ b/types/geo/quantize_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,7 +9,7 @@ import (
"testing"
"testing/quick"
- "tailscale.com/types/geo"
+ "github.com/metacubex/tailscale/types/geo"
)
func TestPointAnonymize(t *testing.T) {
diff --git a/types/geo/units_test.go b/types/geo/units_test.go
index cfbb7ae6a6685..b53b5796a257e 100644
--- a/types/geo/units_test.go
+++ b/types/geo/units_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,7 +10,7 @@ import (
"strings"
"testing"
- "tailscale.com/types/geo"
+ "github.com/metacubex/tailscale/types/geo"
)
func TestDegrees(t *testing.T) {
diff --git a/types/iox/io_test.go b/types/iox/io_test.go
index 7a902841b75fe..e53ddd782c1fa 100644
--- a/types/iox/io_test.go
+++ b/types/iox/io_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,7 +11,7 @@ import (
"testing"
"testing/iotest"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/util/must"
)
func TestCopy(t *testing.T) {
diff --git a/types/ipproto/ipproto.go b/types/ipproto/ipproto.go
index a08985b3aba26..ba1cb30be762e 100644
--- a/types/ipproto/ipproto.go
+++ b/types/ipproto/ipproto.go
@@ -8,8 +8,8 @@ import (
"fmt"
"strconv"
- "tailscale.com/util/nocasemaps"
- "tailscale.com/util/vizerror"
+ "github.com/metacubex/tailscale/util/nocasemaps"
+ "github.com/metacubex/tailscale/util/vizerror"
)
// Version describes the IP address version.
diff --git a/types/ipproto/ipproto_test.go b/types/ipproto/ipproto_test.go
index 6d8be47a9046c..8edf0f9b6ecf1 100644
--- a/types/ipproto/ipproto_test.go
+++ b/types/ipproto/ipproto_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,7 +11,7 @@ import (
"fmt"
"testing"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/util/must"
)
// Ensure that the Proto type implements encoding.TextMarshaler and
diff --git a/types/jsonx/json.go b/types/jsonx/json.go
index 36516f495380b..a06e6650e93fb 100644
--- a/types/jsonx/json.go
+++ b/types/jsonx/json.go
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: BSD-3-Clause
// Package jsonx contains helper types and functionality to use with
-// [github.com/go-json-experiment/json], which is positioned to be
+// [github.com/metacubex/jsonv2], which is positioned to be
// merged into the Go standard library as [encoding/json/v2].
//
// See https://go.dev/issues/71497
@@ -13,8 +13,8 @@ import (
"fmt"
"reflect"
- "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
+ "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
)
var (
diff --git a/types/jsonx/json_test.go b/types/jsonx/json_test.go
index 8b0abbab64686..dd828cb26bbbb 100644
--- a/types/jsonx/json_test.go
+++ b/types/jsonx/json_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,9 +9,9 @@ import (
"errors"
"testing"
- "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
"github.com/google/go-cmp/cmp"
+ "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
)
type Interface interface {
diff --git a/types/key/chal.go b/types/key/chal.go
index 50827d28ed0fe..d08a3bea19991 100644
--- a/types/key/chal.go
+++ b/types/key/chal.go
@@ -6,8 +6,8 @@ package key
import (
"errors"
+ "github.com/metacubex/tailscale/types/structs"
"go4.org/mem"
- "tailscale.com/types/structs"
)
const (
diff --git a/types/key/control_test.go b/types/key/control_test.go
index 928be4283bc3a..e3462db08e226 100644
--- a/types/key/control_test.go
+++ b/types/key/control_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/types/key/derp.go b/types/key/derp.go
index a85611d241765..8f8287bf6abf7 100644
--- a/types/key/derp.go
+++ b/types/key/derp.go
@@ -11,8 +11,8 @@ import (
"fmt"
"strings"
+ "github.com/metacubex/tailscale/types/structs"
"go4.org/mem"
- "tailscale.com/types/structs"
)
var ErrInvalidMeshKey = errors.New("invalid mesh key")
diff --git a/types/key/derp_test.go b/types/key/derp_test.go
index ab98671e5bd29..421907985fe44 100644
--- a/types/key/derp_test.go
+++ b/types/key/derp_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/types/key/disco.go b/types/key/disco.go
index 7fa476dc35ec0..8b5b1513f9240 100644
--- a/types/key/disco.go
+++ b/types/key/disco.go
@@ -8,10 +8,10 @@ import (
"crypto/subtle"
"fmt"
+ "github.com/metacubex/tailscale/types/structs"
"go4.org/mem"
"golang.org/x/crypto/curve25519"
"golang.org/x/crypto/nacl/box"
- "tailscale.com/types/structs"
)
const (
diff --git a/types/key/disco_test.go b/types/key/disco_test.go
index fb22fa82f5400..5e7c83732e5d8 100644
--- a/types/key/disco_test.go
+++ b/types/key/disco_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/types/key/hardware_attestation.go b/types/key/hardware_attestation.go
index 5ca7e936b3d72..aa792057f10f9 100644
--- a/types/key/hardware_attestation.go
+++ b/types/key/hardware_attestation.go
@@ -9,6 +9,7 @@ import (
"crypto/elliptic"
"crypto/subtle"
"encoding/json"
+ "errors"
"fmt"
"io"
@@ -47,10 +48,7 @@ func HardwareAttestationPublicFromPlatformKey(k HardwareAttestationKey) Hardware
if !ok {
panic("hardware attestation key is not ECDSA")
}
- bytes, err := ecdsaPub.Bytes()
- if err != nil {
- panic(err)
- }
+ bytes := elliptic.Marshal(elliptic.P256(), ecdsaPub.X, ecdsaPub.Y)
if len(bytes) != pubkeyLength {
panic("hardware attestation key is not uncompressed ECDSA P-256")
}
@@ -114,9 +112,8 @@ func (k *HardwareAttestationPublic) UnmarshalText(b []byte) error {
return err
}
- _, err := ecdsa.ParseUncompressedPublicKey(elliptic.P256(), kb)
- if err != nil {
- return err
+ if x, y := elliptic.Unmarshal(elliptic.P256(), kb); x == nil || y == nil {
+ return errors.New("invalid uncompressed ECDSA P-256 public key")
}
copy(k.k[:], kb)
return nil
@@ -128,11 +125,11 @@ func (k HardwareAttestationPublic) AppendText(dst []byte) ([]byte, error) {
// Verifier returns the ECDSA public key for verifying signatures made by k.
func (k HardwareAttestationPublic) Verifier() *ecdsa.PublicKey {
- pk, err := ecdsa.ParseUncompressedPublicKey(elliptic.P256(), k.k[:])
- if err != nil {
- panic(err)
+ x, y := elliptic.Unmarshal(elliptic.P256(), k.k[:])
+ if x == nil || y == nil {
+ panic("invalid uncompressed ECDSA P-256 public key")
}
- return pk
+ return &ecdsa.PublicKey{Curve: elliptic.P256(), X: x, Y: y}
}
// emptyHardwareAttestationKey is a function that returns an empty
diff --git a/types/key/machine.go b/types/key/machine.go
index 9ad73bec1a434..7b45e34a3e0e5 100644
--- a/types/key/machine.go
+++ b/types/key/machine.go
@@ -8,10 +8,10 @@ import (
"crypto/subtle"
"encoding/hex"
+ "github.com/metacubex/tailscale/types/structs"
"go4.org/mem"
"golang.org/x/crypto/curve25519"
"golang.org/x/crypto/nacl/box"
- "tailscale.com/types/structs"
)
const (
diff --git a/types/key/machine_test.go b/types/key/machine_test.go
index 3db92ed406bd6..da2fda29c0fd3 100644
--- a/types/key/machine_test.go
+++ b/types/key/machine_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/types/key/nl.go b/types/key/nl.go
index 0e8c5ed966260..c69d2b35e7970 100644
--- a/types/key/nl.go
+++ b/types/key/nl.go
@@ -7,9 +7,9 @@ import (
"crypto/ed25519"
"crypto/subtle"
+ "github.com/metacubex/tailscale/types/structs"
+ "github.com/metacubex/tailscale/types/tkatype"
"go4.org/mem"
- "tailscale.com/types/structs"
- "tailscale.com/types/tkatype"
)
const (
diff --git a/types/key/nl_test.go b/types/key/nl_test.go
index 84fa920569f08..3a91b9890b4fc 100644
--- a/types/key/nl_test.go
+++ b/types/key/nl_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/types/key/node.go b/types/key/node.go
index a1d8e47bafce1..1565f384f56ae 100644
--- a/types/key/node.go
+++ b/types/key/node.go
@@ -11,11 +11,11 @@ import (
"errors"
"fmt"
+ "github.com/metacubex/tailscale/types/structs"
+ "github.com/metacubex/tailscale/util/bufiox"
"go4.org/mem"
"golang.org/x/crypto/curve25519"
"golang.org/x/crypto/nacl/box"
- "tailscale.com/types/structs"
- "tailscale.com/util/bufiox"
)
const (
diff --git a/types/key/node_test.go b/types/key/node_test.go
index 020ddd1f1ff6d..89d8333aee36a 100644
--- a/types/key/node_test.go
+++ b/types/key/node_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/types/key/util.go b/types/key/util.go
index c336d38792a25..4eff2b638c20d 100644
--- a/types/key/util.go
+++ b/types/key/util.go
@@ -9,13 +9,13 @@ import (
"encoding/hex"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"reflect"
- "slices"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/testenv"
"go4.org/mem"
- "tailscale.com/util/set"
- "tailscale.com/util/testenv"
)
// rand fills b with cryptographically strong random bytes. Panics if
@@ -56,7 +56,15 @@ func clamp25519Private(b []byte) {
func appendHexKey(dst []byte, prefix string, key []byte) []byte {
dst = slices.Grow(dst, len(prefix)+hex.EncodedLen(len(key)))
dst = append(dst, prefix...)
- dst = hex.AppendEncode(dst, key)
+ var enc [512]byte
+ if len(key)*2 <= len(enc) {
+ hex.Encode(enc[:len(key)*2], key)
+ dst = append(dst, enc[:len(key)*2]...)
+ } else {
+ buf := make([]byte, len(key)*2)
+ hex.Encode(buf, key)
+ dst = append(dst, buf...)
+ }
return dst
}
@@ -124,12 +132,12 @@ func debug32(k [32]byte) string {
func PrivateTypesForTest() set.Set[reflect.Type] {
testenv.AssertInTest()
return set.Of(
- reflect.TypeFor[ChallengePrivate](),
- reflect.TypeFor[ControlPrivate](),
- reflect.TypeFor[DiscoPrivate](),
- reflect.TypeFor[MachinePrivate](),
- reflect.TypeFor[NodePrivate](),
- reflect.TypeFor[NLPrivate](),
- reflect.TypeFor[HardwareAttestationKey](),
+ reflect.TypeOf((*ChallengePrivate)(nil)).Elem(),
+ reflect.TypeOf((*ControlPrivate)(nil)).Elem(),
+ reflect.TypeOf((*DiscoPrivate)(nil)).Elem(),
+ reflect.TypeOf((*MachinePrivate)(nil)).Elem(),
+ reflect.TypeOf((*NodePrivate)(nil)).Elem(),
+ reflect.TypeOf((*NLPrivate)(nil)).Elem(),
+ reflect.TypeOf((*HardwareAttestationKey)(nil)).Elem(),
)
}
diff --git a/types/key/util_test.go b/types/key/util_test.go
index 3323e0e574684..ecbb74a6869e1 100644
--- a/types/key/util_test.go
+++ b/types/key/util_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/types/lazy/deferred.go b/types/lazy/deferred.go
index 6e96f61e7af04..0528de1b513e7 100644
--- a/types/lazy/deferred.go
+++ b/types/lazy/deferred.go
@@ -89,7 +89,7 @@ func (d *DeferredInit) doSlow() (err *error) {
}()
for _, f := range d.funcs {
if err := f(); err != nil {
- return new(err)
+ return newError(err)
}
}
return nilErrPtr
diff --git a/types/lazy/deferred_test.go b/types/lazy/deferred_test.go
index 4b2bb07ee2fbd..c3f6da4ce676f 100644
--- a/types/lazy/deferred_test.go
+++ b/types/lazy/deferred_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/types/lazy/lazy.go b/types/lazy/lazy.go
index a24139fe1ab07..9af92a57d6397 100644
--- a/types/lazy/lazy.go
+++ b/types/lazy/lazy.go
@@ -11,7 +11,11 @@ import (
// nilErrPtr is a sentinel *error value for SyncValue.err to signal
// that SyncValue.v is valid.
-var nilErrPtr = new(error(nil))
+var nilErrPtr = newError(nil)
+
+func newError(err error) *error {
+ return &err
+}
// SyncValue is a lazily computed value.
//
@@ -78,7 +82,7 @@ func (z *SyncValue[T]) GetErr(fill func() (T, error)) (T, error) {
// Update z.err after z.v; see field docs.
if err != nil {
- z.err.Store(new(err))
+ z.err.Store(newError(err))
} else {
z.err.Store(nilErrPtr)
}
@@ -143,7 +147,7 @@ func (z *SyncValue[T]) SetForTest(tb testing_TB, val T, err error) {
z.v = val
if err != nil {
- z.err.Store(new(err))
+ z.err.Store(newError(err))
} else {
z.err.Store(nilErrPtr)
}
diff --git a/types/lazy/map.go b/types/lazy/map.go
index 4718c5b873c4b..2cc5553ebf838 100644
--- a/types/lazy/map.go
+++ b/types/lazy/map.go
@@ -3,7 +3,7 @@
package lazy
-import "tailscale.com/util/mak"
+import "github.com/metacubex/tailscale/util/mak"
// GMap is a map of lazily computed [GValue] pointers, keyed by a comparable
// type.
diff --git a/types/lazy/map_test.go b/types/lazy/map_test.go
index 5f09da5aea1f1..d2829e06d9bf6 100644
--- a/types/lazy/map_test.go
+++ b/types/lazy/map_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/types/lazy/sync_test.go b/types/lazy/sync_test.go
index b517594d0a8e3..47e65d9ae2675 100644
--- a/types/lazy/sync_test.go
+++ b/types/lazy/sync_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,7 +11,7 @@ import (
"sync"
"testing"
- "tailscale.com/types/opt"
+ "github.com/metacubex/tailscale/types/opt"
)
func TestSyncValue(t *testing.T) {
diff --git a/types/lazy/unsync_test.go b/types/lazy/unsync_test.go
index c3fcf27acad65..0d069cec54193 100644
--- a/types/lazy/unsync_test.go
+++ b/types/lazy/unsync_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/types/logger/logger.go b/types/logger/logger.go
index 71086e87dbd83..a64b3c593e162 100644
--- a/types/logger/logger.go
+++ b/types/logger/logger.go
@@ -21,10 +21,10 @@ import (
"context"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/util/ctxkey"
+ "github.com/metacubex/tailscale/util/testenv"
"go4.org/mem"
- "tailscale.com/envknob"
- "tailscale.com/util/ctxkey"
- "tailscale.com/util/testenv"
)
// Logf is the basic Tailscale logger type: a printf-like func.
diff --git a/types/logger/logger_test.go b/types/logger/logger_test.go
index f55a9484d344e..4ae80b7609d82 100644
--- a/types/logger/logger_test.go
+++ b/types/logger/logger_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -14,8 +16,8 @@ import (
"time"
qt "github.com/frankban/quicktest"
- "tailscale.com/tailcfg"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/version"
)
func TestFuncWriter(t *testing.T) {
diff --git a/types/logid/id.go b/types/logid/id.go
index 94e363879d324..62f76eeeb658b 100644
--- a/types/logid/id.go
+++ b/types/logid/id.go
@@ -11,8 +11,8 @@ import (
"encoding/binary"
"encoding/hex"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"math/bits"
- "slices"
"unicode/utf8"
)
@@ -46,7 +46,7 @@ func (id PrivateID) Add(i int64) PrivateID {
}
func (id PrivateID) AppendText(b []byte) ([]byte, error) {
- return hex.AppendEncode(b, id[:]), nil
+ return appendHex(b, id[:]), nil
}
func (id PrivateID) MarshalText() ([]byte, error) {
@@ -58,7 +58,7 @@ func (id *PrivateID) UnmarshalText(in []byte) error {
}
func (id PrivateID) String() string {
- return string(hex.AppendEncode(nil, id[:]))
+ return string(appendHex(nil, id[:]))
}
func (id1 PrivateID) Less(id2 PrivateID) bool {
@@ -96,7 +96,7 @@ func (id PublicID) Add(i int64) PublicID {
}
func (id PublicID) AppendText(b []byte) ([]byte, error) {
- return hex.AppendEncode(b, id[:]), nil
+ return appendHex(b, id[:]), nil
}
func (id PublicID) MarshalText() ([]byte, error) {
@@ -108,7 +108,7 @@ func (id *PublicID) UnmarshalText(in []byte) error {
}
func (id PublicID) String() string {
- return string(hex.AppendEncode(nil, id[:]))
+ return string(appendHex(nil, id[:]))
}
func (id1 PublicID) Less(id2 PublicID) bool {
@@ -140,6 +140,13 @@ func parseID[Bytes []byte | string](funcName string, out *[32]byte, in Bytes) (e
return nil
}
+func appendHex(dst []byte, src []byte) []byte {
+ n := len(dst)
+ dst = append(dst, make([]byte, hex.EncodedLen(len(src)))...)
+ hex.Encode(dst[n:], src)
+ return dst
+}
+
func add(id [32]byte, i int64) [32]byte {
var out uint64
switch {
diff --git a/types/logid/id_test.go b/types/logid/id_test.go
index 86a736bd877e6..9519d16919f8a 100644
--- a/types/logid/id_test.go
+++ b/types/logid/id_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,8 +9,8 @@ import (
"math"
"testing"
- "tailscale.com/tstest"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/util/must"
)
func TestIDs(t *testing.T) {
diff --git a/types/mapx/ordered.go b/types/mapx/ordered.go
index caaa4d098f8fb..9d6794d03dcf5 100644
--- a/types/mapx/ordered.go
+++ b/types/mapx/ordered.go
@@ -5,8 +5,8 @@
package mapx
import (
- "iter"
- "slices"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
)
// OrderedMap is a map that maintains the order of its keys.
diff --git a/types/mapx/ordered_test.go b/types/mapx/ordered_test.go
index 9bf0be6410e80..51607de1fc497 100644
--- a/types/mapx/ordered_test.go
+++ b/types/mapx/ordered_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,7 +7,7 @@ package mapx
import (
"fmt"
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"testing"
)
diff --git a/types/netlogfunc/netlogfunc.go b/types/netlogfunc/netlogfunc.go
index db856f0cf49f1..b678f615b60c2 100644
--- a/types/netlogfunc/netlogfunc.go
+++ b/types/netlogfunc/netlogfunc.go
@@ -7,7 +7,7 @@ package netlogfunc
import (
"net/netip"
- "tailscale.com/types/ipproto"
+ "github.com/metacubex/tailscale/types/ipproto"
)
// ConnectionCounter is a function for counting packets and bytes
diff --git a/types/netlogtype/netlogtype.go b/types/netlogtype/netlogtype.go
index 24fb32ab0bb5f..37b8682f51622 100644
--- a/types/netlogtype/netlogtype.go
+++ b/types/netlogtype/netlogtype.go
@@ -5,13 +5,13 @@
package netlogtype
import (
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"net/netip"
"sync"
"time"
- "tailscale.com/tailcfg"
- "tailscale.com/types/ipproto"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/ipproto"
)
// Message is the log message that captures network traffic.
@@ -153,5 +153,7 @@ func (c *CountsByConnection) Clone() map[Connection]Counts {
func (c *CountsByConnection) Reset() {
c.mu.Lock()
defer c.mu.Unlock()
- clear(c.m)
+ for k := range c.m {
+ delete(c.m, k)
+ }
}
diff --git a/types/netlogtype/netlogtype_test.go b/types/netlogtype/netlogtype_test.go
index 8271f0ae04144..c43f3f26b7f8e 100644
--- a/types/netlogtype/netlogtype_test.go
+++ b/types/netlogtype/netlogtype_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_tailnetlock
-
package netlogtype
import (
@@ -12,7 +12,7 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/util/must"
)
func TestMaxSize(t *testing.T) {
diff --git a/types/netmap/netmap.go b/types/netmap/netmap.go
index fbf415be0a95b..ed0326cff9f3e 100644
--- a/types/netmap/netmap.go
+++ b/types/netmap/netmap.go
@@ -5,21 +5,21 @@
package netmap
import (
- "cmp"
"encoding/json"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"net/netip"
"sort"
"strings"
"time"
- "tailscale.com/net/tsaddr"
- "tailscale.com/tailcfg"
- "tailscale.com/tka"
- "tailscale.com/types/key"
- "tailscale.com/types/views"
- "tailscale.com/util/set"
- "tailscale.com/wgengine/filter/filtertype"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tka"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/wgengine/filter/filtertype"
)
// NetworkMap is the current state of the world.
@@ -159,18 +159,19 @@ func (nm *NetworkMap) Services() map[tailcfg.ServiceName]tailcfg.ServiceDetails
return nil
}
result := make(map[tailcfg.ServiceName]tailcfg.ServiceDetails)
- for cap := range nm.SelfNode.CapMap().All() {
+ nm.SelfNode.CapMap().All()(func(cap tailcfg.NodeCapability, _ views.Slice[tailcfg.RawMessage]) bool {
if !strings.HasPrefix(string(cap), string(tailcfg.NodeAttrPrefixServices)) {
- continue
+ return true
}
svcs, err := tailcfg.UnmarshalNodeCapViewJSON[tailcfg.ServiceDetails](nm.SelfNode.CapMap(), cap)
if err != nil || len(svcs) < 1 {
- continue
+ return true
}
// NOTE(adrianosela): the NodeCapMap key suffix is opaque and MUST not
// be parsed or relied upon (so we extract name from the inner field).
result[svcs[0].Name] = svcs[0]
- }
+ return true
+ })
return result
}
@@ -186,10 +187,16 @@ func (nm *NetworkMap) SelfNodeOrZero() tailcfg.NodeView {
func (nm *NetworkMap) AnyPeersAdvertiseRoutes() bool {
for _, p := range nm.Peers {
// NOTE: (ChaosInTheCRD) if the peer being advertised is a tailscale ip, we ignore it in this check
- for _, r := range p.PrimaryRoutes().All() {
+ found := false
+ p.PrimaryRoutes().All()(func(_ int, r netip.Prefix) bool {
if !tsaddr.IsTailscaleIP(r.Addr()) || !r.IsSingleIP() {
- return true
+ found = true
+ return false
}
+ return true
+ })
+ if found {
+ return true
}
}
return false
@@ -221,7 +228,7 @@ func (nm *NetworkMap) PeerByTailscaleIP(ip netip.Addr) (peer tailcfg.NodeView, o
}
for _, n := range nm.Peers {
ad := n.Addresses()
- for i := range ad.Len() {
+ for i := 0; i < ad.Len(); i++ {
a := ad.At(i)
if a.Addr() == ip {
return n, true
@@ -382,13 +389,14 @@ func (a *NetworkMap) equalConciseHeader(b *NetworkMap) bool {
// in nodeConciseEqual in sync.
func printPeerConcise(buf *strings.Builder, p tailcfg.NodeView) {
aip := make([]string, p.AllowedIPs().Len())
- for i, a := range p.AllowedIPs().All() {
+ p.AllowedIPs().All()(func(i int, a netip.Prefix) bool {
s := strings.TrimSuffix(a.String(), "/32")
aip[i] = s
- }
+ return true
+ })
epStrs := make([]string, p.Endpoints().Len())
- for i, ep := range p.Endpoints().All() {
+ p.Endpoints().All()(func(i int, ep netip.AddrPort) bool {
e := ep.String()
// Align vertically on the ':' between IP and port
colon := strings.IndexByte(e, ':')
@@ -398,7 +406,8 @@ func printPeerConcise(buf *strings.Builder, p tailcfg.NodeView) {
colon--
}
epStrs[i] = fmt.Sprintf("%21v", e+strings.Repeat(" ", spaces))
- }
+ return true
+ })
derp := fmt.Sprintf("D%d", p.HomeDERP())
diff --git a/types/netmap/netmap_test.go b/types/netmap/netmap_test.go
index e68b243b37f42..c8b2b24189b2b 100644
--- a/types/netmap/netmap_test.go
+++ b/types/netmap/netmap_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,11 +11,11 @@ import (
"reflect"
"testing"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest/typewalk"
+ "github.com/metacubex/tailscale/types/key"
"go4.org/mem"
- "tailscale.com/net/netaddr"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest/typewalk"
- "tailscale.com/types/key"
)
func testNodeKey(b byte) (ret key.NodePublic) {
diff --git a/types/netmap/nodemut.go b/types/netmap/nodemut.go
index 901296b1fc337..87b335990dac1 100644
--- a/types/netmap/nodemut.go
+++ b/types/netmap/nodemut.go
@@ -4,14 +4,14 @@
package netmap
import (
- "cmp"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"reflect"
- "slices"
- "sync"
"time"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
)
// NodeMutation is the common interface for types that describe
@@ -54,7 +54,8 @@ type NodeMutationOnline struct {
}
func (m NodeMutationOnline) Apply(n *tailcfg.Node) {
- n.Online = new(m.Online)
+ online := m.Online
+ n.Online = &online
}
// NodeMutationLastSeen is a NodeMutation that says a node's LastSeen
@@ -65,14 +66,15 @@ type NodeMutationLastSeen struct {
}
func (m NodeMutationLastSeen) Apply(n *tailcfg.Node) {
- n.LastSeen = new(m.LastSeen)
+ lastSeen := m.LastSeen
+ n.LastSeen = &lastSeen
}
-var peerChangeFields = sync.OnceValue(func() []reflect.StructField {
+var peerChangeFields = syncs.OnceValue(func() []reflect.StructField {
var fields []reflect.StructField
- rt := reflect.TypeFor[tailcfg.PeerChange]()
- for field := range rt.Fields() {
- fields = append(fields, field)
+ rt := reflect.TypeOf((*tailcfg.PeerChange)(nil)).Elem()
+ for i := 0; i < rt.NumField(); i++ {
+ fields = append(fields, rt.Field(i))
}
return fields
})
diff --git a/types/netmap/nodemut_test.go b/types/netmap/nodemut_test.go
index 1ae2ab1f98bdd..f06761e6c7abd 100644
--- a/types/netmap/nodemut_test.go
+++ b/types/netmap/nodemut_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,9 +13,9 @@ import (
"time"
"github.com/google/go-cmp/cmp"
- "tailscale.com/tailcfg"
- "tailscale.com/types/logger"
- "tailscale.com/types/opt"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/opt"
)
// tests mapResponseContainsNonPatchFields
diff --git a/types/nettype/nettype.go b/types/nettype/nettype.go
index e44daa0c709f3..464a3f2b3c7fd 100644
--- a/types/nettype/nettype.go
+++ b/types/nettype/nettype.go
@@ -42,6 +42,32 @@ type PacketConn interface {
SetWriteDeadline(time.Time) error
}
+func MakePacketConn(pc net.PacketConn) PacketConn {
+ if pc, ok := pc.(PacketConn); ok {
+ return pc
+ }
+ return packetConnAdapter{pc}
+}
+
+type packetConnAdapter struct {
+ net.PacketConn
+}
+
+func (pc packetConnAdapter) WriteToUDPAddrPort(p []byte, addr netip.AddrPort) (int, error) {
+ return pc.PacketConn.WriteTo(p, net.UDPAddrFromAddrPort(addr))
+}
+
+func (pc packetConnAdapter) ReadFromUDPAddrPort(p []byte) (int, netip.AddrPort, error) {
+ n, addr, err := pc.PacketConn.ReadFrom(p)
+ type addrPort interface {
+ AddrPort() netip.AddrPort
+ }
+ if ap, _ := addr.(addrPort); ap != nil {
+ return n, ap.AddrPort(), err
+ }
+ return n, netip.AddrPort{}, err
+}
+
func MakePacketListenerWithNetIP(ln PacketListener) PacketListenerWithNetIP {
return packetListenerAdapter{ln}
}
@@ -55,7 +81,7 @@ func (a packetListenerAdapter) ListenPacket(ctx context.Context, network, addres
if err != nil {
return nil, err
}
- return pc.(PacketConn), nil
+ return MakePacketConn(pc), nil
}
// ConnPacketConn is the interface that's a superset of net.Conn and net.PacketConn.
diff --git a/types/opt/bool_test.go b/types/opt/bool_test.go
index de4da3788d1e7..4644a022fdcd2 100644
--- a/types/opt/bool_test.go
+++ b/types/opt/bool_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/types/opt/value.go b/types/opt/value.go
index 1ccdd75a47c72..41bad04203c82 100644
--- a/types/opt/value.go
+++ b/types/opt/value.go
@@ -7,13 +7,13 @@ import (
"fmt"
"reflect"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
)
// Value is an optional value to be JSON-encoded.
// With [encoding/json], a zero Value is marshaled as a JSON null.
-// With [github.com/go-json-experiment/json], a zero Value is omitted from the
+// With [github.com/metacubex/jsonv2], a zero Value is omitted from the
// JSON object if the Go struct field specified with omitzero.
// The omitempty tag option should never be used with Value fields.
type Value[T any] struct {
@@ -94,7 +94,7 @@ func (o Value[T]) Equal(v Value[T]) bool {
if eq, ok := ov.(equatable[T]); ok {
return eq.Equal(v.value)
}
- if reflect.TypeFor[T]().Comparable() {
+ if reflect.TypeOf((*T)(nil)).Elem().Comparable() {
return ov == any(v.value)
}
return false
diff --git a/types/opt/value_test.go b/types/opt/value_test.go
index 0b73182996ad2..0788db2f30ad5 100644
--- a/types/opt/value_test.go
+++ b/types/opt/value_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,9 +10,9 @@ import (
"reflect"
"testing"
- jsonv2 "github.com/go-json-experiment/json"
- "tailscale.com/types/bools"
- "tailscale.com/util/must"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/tailscale/types/bools"
+ "github.com/metacubex/tailscale/util/must"
)
var (
diff --git a/types/persist/persist.go b/types/persist/persist.go
index 2a8c2fb824d36..46deba852e786 100644
--- a/types/persist/persist.go
+++ b/types/persist/persist.go
@@ -8,12 +8,12 @@ import (
"fmt"
"reflect"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/structs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/structs"
)
-//go:generate go run tailscale.com/cmd/viewer -type=Persist
+//go:generate go run github.com/metacubex/tailscale/cmd/viewer -type=Persist
// Persist is the JSON type stored on disk on nodes to remember their
// settings between runs. This is stored as part of ipn.Prefs and is
diff --git a/types/persist/persist_clone.go b/types/persist/persist_clone.go
index b43dcc7fd979e..8d32608955b26 100644
--- a/types/persist/persist_clone.go
+++ b/types/persist/persist_clone.go
@@ -1,14 +1,14 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-// Code generated by tailscale.com/cmd/cloner; DO NOT EDIT.
+// Code generated by github.com/metacubex/tailscale/cmd/cloner; DO NOT EDIT.
package persist
import (
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/structs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/structs"
)
// Clone makes a deep copy of Persist.
diff --git a/types/persist/persist_test.go b/types/persist/persist_test.go
index 33773013d667f..0623f34b9a206 100644
--- a/types/persist/persist_test.go
+++ b/types/persist/persist_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,8 +9,8 @@ import (
"reflect"
"testing"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
)
func fieldsOf(t reflect.Type) (fields []string) {
diff --git a/types/persist/persist_view.go b/types/persist/persist_view.go
index f33d222c6fb8d..621975ee3cb85 100644
--- a/types/persist/persist_view.go
+++ b/types/persist/persist_view.go
@@ -9,15 +9,15 @@ import (
jsonv1 "encoding/json"
"errors"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/structs"
- "tailscale.com/types/views"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/structs"
+ "github.com/metacubex/tailscale/types/views"
)
-//go:generate go run tailscale.com/cmd/cloner -clonefunc=false -type=Persist
+//go:generate go run github.com/metacubex/tailscale/cmd/cloner -clonefunc=false -type=Persist
// View returns a read-only view of Persist.
func (p *Persist) View() PersistView {
diff --git a/types/prefs/item.go b/types/prefs/item.go
index 564e8ffde7d0f..ec203dd41fb6d 100644
--- a/types/prefs/item.go
+++ b/types/prefs/item.go
@@ -6,11 +6,11 @@ package prefs
import (
"fmt"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/types/opt"
- "tailscale.com/types/views"
- "tailscale.com/util/must"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/must"
)
// Item is a single preference item that can be configured.
@@ -86,7 +86,7 @@ type ItemView[T views.ViewCloner[T, V], V views.StructView[T]] struct {
}
// ItemViewOf returns a read-only view of i.
-// It is used by [tailscale.com/cmd/viewer].
+// It is used by [github.com/metacubex/tailscale/cmd/viewer].
func ItemViewOf[T views.ViewCloner[T, V], V views.StructView[T]](i *Item[T]) ItemView[T, V] {
return ItemView[T, V]{i}
}
diff --git a/types/prefs/list.go b/types/prefs/list.go
index c6881991ad769..4ecfb624e2c29 100644
--- a/types/prefs/list.go
+++ b/types/prefs/list.go
@@ -4,15 +4,15 @@
package prefs
import (
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
"time"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/views"
"golang.org/x/exp/constraints"
- "tailscale.com/types/opt"
- "tailscale.com/types/views"
)
// BasicType is a constraint that allows types whose underlying type is a predeclared
diff --git a/types/prefs/map.go b/types/prefs/map.go
index 07cb84f0da56a..f25188679a7d8 100644
--- a/types/prefs/map.go
+++ b/types/prefs/map.go
@@ -4,14 +4,14 @@
package prefs
import (
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"net/netip"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/views"
"golang.org/x/exp/constraints"
- "tailscale.com/types/opt"
- "tailscale.com/types/views"
)
// MapKeyType is a constraint allowing types that can be used as [Map] and [StructMap] keys.
diff --git a/types/prefs/prefs.go b/types/prefs/prefs.go
index 3f18886a724bc..eede80bb964d9 100644
--- a/types/prefs/prefs.go
+++ b/types/prefs/prefs.go
@@ -12,8 +12,8 @@
// non-preference fields that will be marshalled and unmarshalled but are
// otherwise ignored by the prefs package.
//
-// The preference types are compatible with the [tailscale.com/cmd/viewer] and
-// [tailscale.com/cmd/cloner] utilities. It is recommended to generate a read-only view
+// The preference types are compatible with the [github.com/metacubex/tailscale/cmd/viewer] and
+// [github.com/metacubex/tailscale/cmd/cloner] utilities. It is recommended to generate a read-only view
// of the user-defined prefs structure and use it in place of prefs whenever the prefs
// should not be modified.
package prefs
@@ -21,9 +21,9 @@ package prefs
import (
"errors"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/types/opt"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/types/opt"
)
var (
diff --git a/types/prefs/prefs_clone_test.go b/types/prefs/prefs_clone_test.go
index 1914a0c2551f6..a9621a20eadb4 100644
--- a/types/prefs/prefs_clone_test.go
+++ b/types/prefs/prefs_clone_test.go
@@ -1,7 +1,9 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-// Code generated by tailscale.com/cmd/cloner; DO NOT EDIT.
+// Code generated by github.com/metacubex/tailscale/cmd/cloner; DO NOT EDIT.
package prefs
@@ -65,7 +67,7 @@ func (src *TestBundle) Clone() *TestBundle {
dst := new(TestBundle)
*dst = *src
if dst.Nested != nil {
- dst.Nested = new(*src.Nested)
+ dst.Nested = func() *Nested { v := *src.Nested; return &v }()
}
return dst
}
diff --git a/types/prefs/prefs_example/prefs_example_clone.go b/types/prefs/prefs_example/prefs_example_clone.go
index c5fdc49fc3b9b..9f684a25ddd28 100644
--- a/types/prefs/prefs_example/prefs_example_clone.go
+++ b/types/prefs/prefs_example/prefs_example_clone.go
@@ -1,19 +1,19 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-// Code generated by tailscale.com/cmd/cloner; DO NOT EDIT.
+// Code generated by github.com/metacubex/tailscale/cmd/cloner; DO NOT EDIT.
package prefs_example
import (
"net/netip"
- "tailscale.com/drive"
- "tailscale.com/tailcfg"
- "tailscale.com/types/opt"
- "tailscale.com/types/persist"
- "tailscale.com/types/prefs"
- "tailscale.com/types/preftype"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/types/prefs"
+ "github.com/metacubex/tailscale/types/preftype"
)
// Clone makes a deep copy of Prefs.
diff --git a/types/prefs/prefs_example/prefs_example_view.go b/types/prefs/prefs_example/prefs_example_view.go
index 67a284bb5b4bb..ac41939dad243 100644
--- a/types/prefs/prefs_example/prefs_example_view.go
+++ b/types/prefs/prefs_example/prefs_example_view.go
@@ -10,17 +10,17 @@ import (
"errors"
"net/netip"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/drive"
- "tailscale.com/tailcfg"
- "tailscale.com/types/opt"
- "tailscale.com/types/persist"
- "tailscale.com/types/prefs"
- "tailscale.com/types/preftype"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/types/prefs"
+ "github.com/metacubex/tailscale/types/preftype"
)
-//go:generate go run tailscale.com/cmd/cloner -clonefunc=false -type=Prefs,AutoUpdatePrefs,AppConnectorPrefs
+//go:generate go run github.com/metacubex/tailscale/cmd/cloner -clonefunc=false -type=Prefs,AutoUpdatePrefs,AppConnectorPrefs
// View returns a read-only view of Prefs.
func (p *Prefs) View() PrefsView {
diff --git a/types/prefs/prefs_example/prefs_test.go b/types/prefs/prefs_example/prefs_test.go
index 93ed5b4fea27b..b3fc02cc70f9a 100644
--- a/types/prefs/prefs_example/prefs_test.go
+++ b/types/prefs/prefs_example/prefs_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,8 +9,8 @@ import (
"fmt"
"net/netip"
- "tailscale.com/ipn"
- "tailscale.com/types/prefs"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/types/prefs"
)
func ExamplePrefs_AdvertiseRoutes_setValue() {
@@ -50,7 +52,7 @@ func ExamplePrefs_AdvertiseRoutes_setValue() {
// In most contexts, preferences should only be read and never mutated.
// To make it easier to enforce this guarantee, a view type generated with
- // [tailscale.com/cmd/viewer] can be used instead of the mutable Prefs struct.
+ // [github.com/metacubex/tailscale/cmd/viewer] can be used instead of the mutable Prefs struct.
// Preferences accessed via a view have the same set of non-mutating
// methods as the underlying preferences but do not expose [prefs.Item.SetValue] or
// other methods that modify the preference's value or state.
diff --git a/types/prefs/prefs_example/prefs_types.go b/types/prefs/prefs_example/prefs_types.go
index d0764c64b6efc..7d8426fb5e7a3 100644
--- a/types/prefs/prefs_example/prefs_types.go
+++ b/types/prefs/prefs_example/prefs_types.go
@@ -1,31 +1,31 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-// Package prefs_example contains a [Prefs] type, which is like [tailscale.com/ipn.Prefs],
+// Package prefs_example contains a [Prefs] type, which is like [github.com/metacubex/tailscale/ipn.Prefs],
// but uses the [prefs] package to enhance individual preferences with state and metadata.
//
// It also includes testable examples utilizing the [Prefs] type.
// We made it a separate package to avoid circular dependencies
-// and due to limitations in [tailscale.com/cmd/viewer] when
+// and due to limitations in [github.com/metacubex/tailscale/cmd/viewer] when
// generating code for test packages.
package prefs_example
import (
"net/netip"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/drive"
- "tailscale.com/tailcfg"
- "tailscale.com/types/opt"
- "tailscale.com/types/persist"
- "tailscale.com/types/prefs"
- "tailscale.com/types/preftype"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/persist"
+ "github.com/metacubex/tailscale/types/prefs"
+ "github.com/metacubex/tailscale/types/preftype"
)
-//go:generate go run tailscale.com/cmd/viewer --type=Prefs,AutoUpdatePrefs,AppConnectorPrefs
+//go:generate go run github.com/metacubex/tailscale/cmd/viewer --type=Prefs,AutoUpdatePrefs,AppConnectorPrefs
-// Prefs is like [tailscale.com/ipn.Prefs], but with individual preferences wrapped in
+// Prefs is like [github.com/metacubex/tailscale/ipn.Prefs], but with individual preferences wrapped in
// [prefs.Item], [prefs.List], and [prefs.StructList] to include preference
// state and metadata. Related preferences can be grouped together in a nested
// struct (e.g., [AutoUpdatePrefs] or [AppConnectorPrefs]), whereas each
@@ -34,7 +34,7 @@ import (
//
// Non-preference fields, such as ExitNodePrior and Persist, can be included as-is.
//
-// Just like [tailscale.com/ipn.Prefs], [Prefs] is a mutable struct. It should
+// Just like [github.com/metacubex/tailscale/ipn.Prefs], [Prefs] is a mutable struct. It should
// only be used in well-defined contexts where mutability is expected and desired,
// such as when the LocalBackend receives a request from the GUI/CLI to change a
// preference, when a preference is managed via syspolicy and needs to be
diff --git a/types/prefs/prefs_test.go b/types/prefs/prefs_test.go
index ccc37b0a74df7..b3f1fd34a49b1 100644
--- a/types/prefs/prefs_test.go
+++ b/types/prefs/prefs_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,13 +13,13 @@ import (
"reflect"
"testing"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
"github.com/google/go-cmp/cmp"
- "tailscale.com/types/views"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/types/views"
)
-//go:generate go run tailscale.com/cmd/viewer --tags=test --type=TestPrefs,TestBundle,TestValueStruct,TestGenericStruct,TestPrefsGroup
+//go:generate go run github.com/metacubex/tailscale/cmd/viewer --tags=test --type=TestPrefs,TestBundle,TestValueStruct,TestGenericStruct,TestPrefsGroup
var (
_ jsonv2.MarshalerTo = (*ItemView[*TestBundle, TestBundleView])(nil)
diff --git a/types/prefs/prefs_view_test.go b/types/prefs/prefs_view_test.go
index ce4dee726badc..92ca73ac2ee3c 100644
--- a/types/prefs/prefs_view_test.go
+++ b/types/prefs/prefs_view_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,11 +12,11 @@ import (
"errors"
"net/netip"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
)
-//go:generate go run tailscale.com/cmd/cloner -clonefunc=false -type=TestPrefs,TestBundle,TestValueStruct,TestGenericStruct,TestPrefsGroup -tags=test
+//go:generate go run github.com/metacubex/tailscale/cmd/cloner -clonefunc=false -type=TestPrefs,TestBundle,TestValueStruct,TestGenericStruct,TestPrefsGroup -tags=test
// View returns a read-only view of TestPrefs.
func (p *TestPrefs) View() TestPrefsView {
diff --git a/types/prefs/struct_list.go b/types/prefs/struct_list.go
index e1c1863fc5dc1..b52c695f8a00a 100644
--- a/types/prefs/struct_list.go
+++ b/types/prefs/struct_list.go
@@ -5,13 +5,13 @@ package prefs
import (
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"reflect"
- "slices"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/types/opt"
- "tailscale.com/types/views"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/views"
)
// StructList is a preference type that holds zero or more potentially mutable struct values.
@@ -103,7 +103,7 @@ type StructListView[T views.ViewCloner[T, V], V views.StructView[T]] struct {
}
// StructListViewOf returns a read-only view of l.
-// It is used by [tailscale.com/cmd/viewer].
+// It is used by [github.com/metacubex/tailscale/cmd/viewer].
func StructListViewOf[T views.ViewCloner[T, V], V views.StructView[T]](ls *StructList[T]) StructListView[T, V] {
return StructListView[T, V]{ls}
}
diff --git a/types/prefs/struct_map.go b/types/prefs/struct_map.go
index 374d8a92ee925..a785642b3dd10 100644
--- a/types/prefs/struct_map.go
+++ b/types/prefs/struct_map.go
@@ -4,12 +4,12 @@
package prefs
import (
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/types/opt"
- "tailscale.com/types/views"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/views"
)
// StructMap is a preference type that holds potentially mutable key-value pairs.
@@ -83,7 +83,7 @@ type StructMapView[K MapKeyType, T views.ViewCloner[T, V], V views.StructView[T]
}
// StructMapViewOf returns a read-only view of m.
-// It is used by [tailscale.com/cmd/viewer].
+// It is used by [github.com/metacubex/tailscale/cmd/viewer].
func StructMapViewOf[K MapKeyType, T views.ViewCloner[T, V], V views.StructView[T]](m *StructMap[K, T]) StructMapView[K, T, V] {
return StructMapView[K, T, V]{m}
}
diff --git a/types/tkatype/tkatype_test.go b/types/tkatype/tkatype_test.go
index 337167a7d3bd8..ff5db2776fbcc 100644
--- a/types/tkatype/tkatype_test.go
+++ b/types/tkatype/tkatype_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/types/views/views.go b/types/views/views.go
index fe70e227fc64c..078136595b5ee 100644
--- a/types/views/views.go
+++ b/types/views/views.go
@@ -7,17 +7,17 @@ package views
import (
"bytes"
- "cmp"
jsonv1 "encoding/json"
"errors"
"fmt"
- "iter"
- "maps"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"reflect"
- "slices"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
"go4.org/mem"
)
@@ -114,7 +114,7 @@ func (v *ByteSlice[T]) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
}
// StructView represents the corresponding StructView of a Viewable. The concrete types are
-// typically generated by tailscale.com/cmd/viewer.
+// typically generated by github.com/metacubex/tailscale/cmd/viewer.
type StructView[T any] interface {
// Valid reports whether the underlying Viewable is nil.
Valid() bool
@@ -131,7 +131,7 @@ type Cloner[T any] interface {
}
// ViewCloner is any type that has had View and Clone funcs generated using
-// tailscale.com/cmd/viewer.
+// github.com/metacubex/tailscale/cmd/viewer.
type ViewCloner[T any, V StructView[T]] interface {
// View returns a read-only view of Viewable.
// If Viewable is nil, View().Valid() reports false.
@@ -348,7 +348,7 @@ func (v Slice[T]) AsSlice() []T {
//
// As it runs in O(n) time, use with care.
func (v Slice[T]) IndexFunc(f func(T) bool) int {
- for i := range v.Len() {
+ for i := 0; i < v.Len(); i++ {
if f(v.At(i)) {
return i
}
@@ -486,7 +486,7 @@ func unorderedSliceEqualAnyOrder[T any, V comparable](a, b Slice[T], cmp func(T)
return true
}
m := make(map[V]int)
- for i := range a.Len() {
+ for i := 0; i < a.Len(); i++ {
m[cmp(a.At(i))]++
m[cmp(b.At(i))]--
}
@@ -515,10 +515,10 @@ func unorderedSliceEqualAnyOrderSmall[T any, V comparable](a, b Slice[T], cmp fu
var aMatched, bMatched [shortOOOLen]bool
// Compare each element in a to each element in b
- for i := range a.Len() {
+ for i := 0; i < a.Len(); i++ {
av := cmp(a.At(i))
found := false
- for j := range a.Len() {
+ for j := 0; j < a.Len(); j++ {
// Skip elements in b that have already been
// used to match an item in a.
if bMatched[j] {
@@ -543,7 +543,7 @@ func unorderedSliceEqualAnyOrderSmall[T any, V comparable](a, b Slice[T], cmp fu
}
// Verify all elements were matched exactly once.
- for i := range a.Len() {
+ for i := 0; i < a.Len(); i++ {
if !aMatched[i] || !bMatched[i] {
return false
}
@@ -746,13 +746,16 @@ func MapViewsEqual[K, V comparable](a, b Map[K, V]) bool {
return true // both nil; can exit early
}
- for k, v := range a.All() {
+ okAll := true
+ a.All()(func(k K, v V) bool {
bv, ok := b.GetOk(k)
if !ok || v != bv {
+ okAll = false
return false
}
- }
- return true
+ return true
+ })
+ return okAll
}
// MapViewsEqualFunc returns whether the two given [Map]s are equal, using the
@@ -765,13 +768,16 @@ func MapViewsEqualFunc[K comparable, V1, V2 any](a Map[K, V1], b Map[K, V2], eq
return true // both nil; can exit early
}
- for k, v := range a.All() {
+ okAll := true
+ a.All()(func(k K, v V1) bool {
bv, ok := b.GetOk(k)
if !ok || !eq(v, bv) {
+ okAll = false
return false
}
- }
- return true
+ return true
+ })
+ return okAll
}
// MapRangeFn is the func called from a Map.Range call.
@@ -900,7 +906,8 @@ func (p ValuePointer[T]) Clone() *T {
if p.ж == nil {
return nil
}
- return new(*p.ж)
+ v := *p.ж
+ return &v
}
// String implements [fmt.Stringer].
@@ -951,7 +958,7 @@ func (p *ValuePointer[T]) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
// It has special handling for some types that contain pointers
// that we know are free from memory aliasing/mutation concerns.
func ContainsPointers[T any]() bool {
- return containsPointers(reflect.TypeFor[T]())
+ return containsPointers(reflect.TypeOf((*T)(nil)).Elem())
}
func containsPointers(typ reflect.Type) bool {
@@ -968,8 +975,8 @@ func containsPointers(typ reflect.Type) bool {
if isWellKnownImmutableStruct(typ) {
return false
}
- for field := range typ.Fields() {
- if containsPointers(field.Type) {
+ for i := 0; i < typ.NumField(); i++ {
+ if containsPointers(typ.Field(i).Type) {
return true
}
}
diff --git a/types/views/views_test.go b/types/views/views_test.go
index 7cdd1ab020312..6a3d6bf409d90 100644
--- a/types/views/views_test.go
+++ b/types/views/views_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,18 +8,18 @@ package views
import (
jsonv1 "encoding/json"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"reflect"
- "slices"
"strings"
"testing"
"unsafe"
qt "github.com/frankban/quicktest"
- jsonv2 "github.com/go-json-experiment/json"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/types/structs"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/tailscale/types/structs"
)
// Statically verify that each type implements the following interfaces.
diff --git a/util/backoff/backoff.go b/util/backoff/backoff.go
index 2edb1e7712e65..b2037ef4439b5 100644
--- a/util/backoff/backoff.go
+++ b/util/backoff/backoff.go
@@ -6,11 +6,11 @@ package backoff
import (
"context"
- "math/rand/v2"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"time"
- "tailscale.com/tstime"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/logger"
)
// Backoff tracks state the history of consecutive failures and sleeps
diff --git a/util/bufiox/bufiox_test.go b/util/bufiox/bufiox_test.go
index 727bb36997a6d..f1add0432fd30 100644
--- a/util/bufiox/bufiox_test.go
+++ b/util/bufiox/bufiox_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/clientmetric/clientmetric.go b/util/clientmetric/clientmetric.go
index 98068b9faf693..2dfc368566eec 100644
--- a/util/clientmetric/clientmetric.go
+++ b/util/clientmetric/clientmetric.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_clientmetrics
+//go:build ts_enable_clientmetrics
// Package clientmetric provides client-side metrics whose values
// get occasionally logged.
@@ -20,9 +20,9 @@ import (
"sync/atomic"
"time"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/util/set"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/testenv"
)
var (
diff --git a/util/clientmetric/clientmetric_test.go b/util/clientmetric/clientmetric_test.go
index db1cfe1893512..f51963a8b3ed9 100644
--- a/util/clientmetric/clientmetric_test.go
+++ b/util/clientmetric/clientmetric_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/clientmetric/omit.go b/util/clientmetric/omit.go
index 74018f12ac154..d489d85e5a21d 100644
--- a/util/clientmetric/omit.go
+++ b/util/clientmetric/omit.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build ts_omit_clientmetrics
+//go:build !ts_enable_clientmetrics
package clientmetric
diff --git a/util/cloudenv/cloudenv.go b/util/cloudenv/cloudenv.go
index aee4bac723f2d..92c66cf8351c4 100644
--- a/util/cloudenv/cloudenv.go
+++ b/util/cloudenv/cloudenv.go
@@ -7,8 +7,8 @@ package cloudenv
import (
"context"
"encoding/json"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"log"
- "math/rand/v2"
"net"
"net/http"
"os"
@@ -16,9 +16,9 @@ import (
"strings"
"time"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/syncs"
- "tailscale.com/types/lazy"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/lazy"
)
// CommonNonRoutableMetadataIP is the IP address of the metadata server
diff --git a/util/cloudenv/cloudenv_test.go b/util/cloudenv/cloudenv_test.go
index c928fe660ee72..f851e16c59542 100644
--- a/util/cloudenv/cloudenv_test.go
+++ b/util/cloudenv/cloudenv_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/cloudinfo/cloudinfo.go b/util/cloudinfo/cloudinfo.go
index 5f6a54ebdcb95..9d2c664a1a981 100644
--- a/util/cloudinfo/cloudinfo.go
+++ b/util/cloudinfo/cloudinfo.go
@@ -10,17 +10,17 @@ import (
"context"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net"
"net/http"
"net/netip"
- "slices"
"strings"
"time"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/types/logger"
- "tailscale.com/util/cloudenv"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/cloudenv"
)
const maxCloudInfoWait = 2 * time.Second
diff --git a/util/cloudinfo/cloudinfo_nocloud.go b/util/cloudinfo/cloudinfo_nocloud.go
index b7ea210c15c6f..2257e401af8c1 100644
--- a/util/cloudinfo/cloudinfo_nocloud.go
+++ b/util/cloudinfo/cloudinfo_nocloud.go
@@ -9,7 +9,7 @@ import (
"context"
"net/netip"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
// CloudInfo is not available in mobile and JS targets.
diff --git a/util/cloudinfo/cloudinfo_test.go b/util/cloudinfo/cloudinfo_test.go
index 721eca25f960d..58b4a8c207892 100644
--- a/util/cloudinfo/cloudinfo_test.go
+++ b/util/cloudinfo/cloudinfo_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,13 +7,13 @@ package cloudinfo
import (
"context"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/http"
"net/http/httptest"
"net/netip"
- "slices"
"testing"
- "tailscale.com/util/cloudenv"
+ "github.com/metacubex/tailscale/util/cloudenv"
)
func TestCloudInfo_AWS(t *testing.T) {
diff --git a/util/cmpver/version_test.go b/util/cmpver/version_test.go
index b3ab1b0289211..ff3adebb710ed 100644
--- a/util/cmpver/version_test.go
+++ b/util/cmpver/version_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,7 +8,7 @@ package cmpver_test
import (
"testing"
- "tailscale.com/util/cmpver"
+ "github.com/metacubex/tailscale/util/cmpver"
)
func TestCompare(t *testing.T) {
diff --git a/util/codegen/codegen.go b/util/codegen/codegen.go
index 2023c8d9b1e08..0fe231641fb50 100644
--- a/util/codegen/codegen.go
+++ b/util/codegen/codegen.go
@@ -16,9 +16,9 @@ import (
"reflect"
"strings"
+ "github.com/metacubex/tailscale/util/mak"
"golang.org/x/tools/go/packages"
"golang.org/x/tools/imports"
- "tailscale.com/util/mak"
)
var flagCopyright = flag.Bool("copyright", true, "add Tailscale copyright to generated file headers")
diff --git a/util/codegen/codegen_test.go b/util/codegen/codegen_test.go
index 49656401a9b18..f4bdd4991b7f9 100644
--- a/util/codegen/codegen_test.go
+++ b/util/codegen/codegen_test.go
@@ -1,10 +1,12 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package codegen
import (
- "cmp"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"go/types"
"net/netip"
"strings"
diff --git a/util/ctxkey/key.go b/util/ctxkey/key.go
index 982c65f04c8d7..ca0de69093a51 100644
--- a/util/ctxkey/key.go
+++ b/util/ctxkey/key.go
@@ -60,7 +60,7 @@ func New[Value any](name string, defaultValue Value) Key[Value] {
// since newly allocated pointers are globally unique within a process.
key := Key[Value]{name: new(stringer[string])}
if name == "" {
- name = reflect.TypeFor[Value]().String()
+ name = typeFor[Value]().String()
}
key.name.v = name
if v := reflect.ValueOf(defaultValue); v.IsValid() && !v.IsZero() {
@@ -73,7 +73,7 @@ func New[Value any](name string, defaultValue Value) Key[Value] {
func (key Key[Value]) contextKey() any {
if key.name == nil {
// Use the reflect.Type of the Value (implies key not created by New).
- return reflect.TypeFor[Value]()
+ return typeFor[Value]()
} else {
// Use the name pointer directly (implies key created by New).
return key.name
@@ -114,11 +114,16 @@ func (key Key[Value]) Has(ctx context.Context) (ok bool) {
// String returns the name of the key.
func (key Key[Value]) String() string {
if key.name == nil {
- return reflect.TypeFor[Value]().String()
+ return typeFor[Value]().String()
}
return key.name.String()
}
+func typeFor[T any]() reflect.Type {
+ var zero *T
+ return reflect.TypeOf(zero).Elem()
+}
+
// stringer implements [fmt.Stringer] on a generic T.
//
// This assists in debugging such that printing a context prints key and value.
diff --git a/util/ctxkey/key_test.go b/util/ctxkey/key_test.go
index 413c3eacdd847..ec6674aab6996 100644
--- a/util/ctxkey/key_test.go
+++ b/util/ctxkey/key_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/deephash/deephash.go b/util/deephash/deephash.go
index ae082ef35e019..29d27e821222b 100644
--- a/util/deephash/deephash.go
+++ b/util/deephash/deephash.go
@@ -71,8 +71,8 @@ import (
"sync"
"time"
- "tailscale.com/util/hashx"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/util/hashx"
+ "github.com/metacubex/tailscale/util/set"
)
// There is much overlap between the theory of serialization and hashing.
@@ -208,7 +208,7 @@ type Sum struct {
}
func (s1 *Sum) xor(s2 Sum) {
- for i := range sha256.Size {
+ for i := 0; i < sha256.Size; i++ {
s1.sum[i] ^= s2.sum[i]
}
}
@@ -248,7 +248,7 @@ func Hash[T any](v *T) Sum {
// Always treat the Hash input as if it were an interface by including
// a hash of the type. This ensures that hashing of two different types
// but with the same value structure produces different hashes.
- t := reflect.TypeFor[T]()
+ t := reflect.TypeOf((*T)(nil)).Elem()
h.hashType(t)
if v == nil {
h.HashUint8(0) // indicates nil
@@ -300,7 +300,7 @@ func ExcludeFields[T any](fields ...string) Option {
}
func newFieldFilter[T any](include bool, fields []string) Option {
- t := reflect.TypeFor[T]()
+ t := reflect.TypeOf((*T)(nil)).Elem()
fieldSet := set.Set[string]{}
for _, f := range fields {
if _, ok := t.FieldByName(f); !ok {
@@ -324,7 +324,7 @@ func HasherForType[T any](opts ...Option) func(*T) Sum {
if len(opts) > 1 {
panic("HasherForType only accepts one optional argument") // for now
}
- t := reflect.TypeFor[T]()
+ t := reflect.TypeOf((*T)(nil)).Elem()
var hash typeHasherFunc
for _, o := range opts {
switch o := o.(type) {
@@ -492,7 +492,7 @@ func makeArrayHasher(t reflect.Type) typeHasherFunc {
nb := t.Elem().Size() // byte size of each array element
return func(h *hasher, p pointer) {
once.Do(init)
- for i := range n {
+ for i := 0; i < n; i++ {
hashElem(h, p.arrayIndex(i, nb))
}
}
@@ -545,7 +545,7 @@ func makeSliceHasher(t reflect.Type) typeHasherFunc {
h.HashUint8(1) // indicates visiting slice
n := p.sliceLen()
h.HashUint64(uint64(n))
- for i := range n {
+ for i := 0; i < n; i++ {
pe := pa.arrayIndex(i, nb)
hashElem(h, pe)
}
diff --git a/util/deephash/deephash_test.go b/util/deephash/deephash_test.go
index a82203d503591..90804a0d25ca0 100644
--- a/util/deephash/deephash_test.go
+++ b/util/deephash/deephash_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -20,13 +22,13 @@ import (
"time"
qt "github.com/frankban/quicktest"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/util/deephash/testtype"
+ "github.com/metacubex/tailscale/util/hashx"
+ "github.com/metacubex/tailscale/version"
"go4.org/mem"
"go4.org/netipx"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/util/deephash/testtype"
- "tailscale.com/util/hashx"
- "tailscale.com/version"
)
type appendBytes []byte
diff --git a/util/deephash/tailscale_types_test.go b/util/deephash/tailscale_types_test.go
index 7e803c841c1f5..63c90fa650a1a 100644
--- a/util/deephash/tailscale_types_test.go
+++ b/util/deephash/tailscale_types_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,18 +13,18 @@ import (
"net/netip"
"testing"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/dnsname"
+ "github.com/metacubex/tailscale/wgengine/filter"
+ "github.com/metacubex/tailscale/wgengine/router"
+ "github.com/metacubex/tailscale/wgengine/wgcfg"
"go4.org/mem"
- "tailscale.com/tailcfg"
- "tailscale.com/types/dnstype"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/key"
- "tailscale.com/types/views"
- "tailscale.com/util/dnsname"
- "tailscale.com/wgengine/filter"
- "tailscale.com/wgengine/router"
- "tailscale.com/wgengine/wgcfg"
- . "tailscale.com/util/deephash"
+ . "github.com/metacubex/tailscale/util/deephash"
)
var sink Sum
diff --git a/util/deephash/types.go b/util/deephash/types.go
index ef19207bf68b8..79b1621195847 100644
--- a/util/deephash/types.go
+++ b/util/deephash/types.go
@@ -10,9 +10,9 @@ import (
)
var (
- timeTimeType = reflect.TypeFor[time.Time]()
- netipAddrType = reflect.TypeFor[netip.Addr]()
- selfHasherType = reflect.TypeFor[SelfHasher]()
+ timeTimeType = reflect.TypeOf((*time.Time)(nil)).Elem()
+ netipAddrType = reflect.TypeOf((*netip.Addr)(nil)).Elem()
+ selfHasherType = reflect.TypeOf((*SelfHasher)(nil)).Elem()
)
// typeIsSpecialized reports whether this type has specialized hashing.
diff --git a/util/deephash/types_test.go b/util/deephash/types_test.go
index 7a0a43b27e6d3..6687efd6c8473 100644
--- a/util/deephash/types_test.go
+++ b/util/deephash/types_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,8 +12,8 @@ import (
"time"
"unsafe"
- "tailscale.com/tailcfg"
- "tailscale.com/types/structs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/structs"
)
func TestTypeIsMemHashable(t *testing.T) {
diff --git a/util/dirwalk/dirwalk_test.go b/util/dirwalk/dirwalk_test.go
index f9ba842977d6b..413e891f0cb90 100644
--- a/util/dirwalk/dirwalk_test.go
+++ b/util/dirwalk/dirwalk_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,8 +14,8 @@ import (
"sort"
"testing"
+ "github.com/metacubex/tailscale/tstest"
"go4.org/mem"
- "tailscale.com/tstest"
)
func TestWalkShallowOSSpecific(t *testing.T) {
diff --git a/util/dnsname/dnsname.go b/util/dnsname/dnsname.go
index cf1ae62000956..fc62cd013a9bf 100644
--- a/util/dnsname/dnsname.go
+++ b/util/dnsname/dnsname.go
@@ -7,7 +7,7 @@ package dnsname
import (
"strings"
- "tailscale.com/util/vizerror"
+ "github.com/metacubex/tailscale/util/vizerror"
)
const (
@@ -40,7 +40,7 @@ func ToFQDN(s string) (FQDN, error) {
}
st := 0
- for i := range len(s) {
+ for i := 0; i < len(s); i++ {
if s[i] != '.' {
continue
}
@@ -234,7 +234,7 @@ func ValidHostname(hostname string) error {
return err
}
- for label := range strings.SplitSeq(fqdn.WithoutTrailingDot(), ".") {
+ for _, label := range strings.Split(fqdn.WithoutTrailingDot(), ".") {
if err := ValidLabel(label); err != nil {
return err
}
diff --git a/util/dnsname/dnsname_test.go b/util/dnsname/dnsname_test.go
index e349e51c7ad99..4c4f7d8ad99c7 100644
--- a/util/dnsname/dnsname_test.go
+++ b/util/dnsname/dnsname_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/ed25519consensus/ed25519.go b/util/ed25519consensus/ed25519.go
new file mode 100644
index 0000000000000..b32075aee65e1
--- /dev/null
+++ b/util/ed25519consensus/ed25519.go
@@ -0,0 +1,60 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Copyright 2016 Henry de Valence. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package ed25519consensus implements Ed25519 verification according to ZIP215.
+package ed25519consensus
+
+import (
+ "crypto/ed25519"
+ "crypto/sha512"
+
+ "github.com/metacubex/edwards25519"
+)
+
+// Verify reports whether sig is a valid signature of message by publicKey,
+// using precisely-specified validation criteria (ZIP 215) suitable for use in
+// consensus-critical contexts.
+func Verify(publicKey ed25519.PublicKey, message, sig []byte) bool {
+ if l := len(publicKey); l != ed25519.PublicKeySize {
+ return false
+ }
+
+ if len(sig) != ed25519.SignatureSize || sig[63]&224 != 0 {
+ return false
+ }
+
+ A, err := new(edwards25519.Point).SetBytes(publicKey)
+ if err != nil {
+ return false
+ }
+ A.Negate(A)
+
+ h := sha512.New()
+ h.Write(sig[:32])
+ h.Write(publicKey[:])
+ h.Write(message)
+ var digest [64]byte
+ h.Sum(digest[:0])
+
+ hReduced, err := new(edwards25519.Scalar).SetUniformBytes(digest[:])
+ if err != nil {
+ return false
+ }
+
+ checkR, err := new(edwards25519.Point).SetBytes(sig[:32])
+ if err != nil {
+ return false
+ }
+
+ s, err := new(edwards25519.Scalar).SetCanonicalBytes(sig[32:])
+ if err != nil {
+ return false
+ }
+
+ R := new(edwards25519.Point).VarTimeDoubleScalarBaseMult(hReduced, A, s)
+ p := new(edwards25519.Point).Subtract(R, checkR)
+ p.MultByCofactor(p)
+ return p.Equal(edwards25519.NewIdentityPoint()) == 1
+}
diff --git a/util/eventbus/bench_test.go b/util/eventbus/bench_test.go
index 9657c4e6f77b6..f7d5e29e092e8 100644
--- a/util/eventbus/bench_test.go
+++ b/util/eventbus/bench_test.go
@@ -1,13 +1,15 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package eventbus_test
import (
- "math/rand/v2"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"testing"
- "tailscale.com/util/eventbus"
+ "github.com/metacubex/tailscale/util/eventbus"
)
func BenchmarkBasicThroughput(b *testing.B) {
diff --git a/util/eventbus/bus.go b/util/eventbus/bus.go
index 1bc8aaed63dfc..7c69a39723987 100644
--- a/util/eventbus/bus.go
+++ b/util/eventbus/bus.go
@@ -5,13 +5,13 @@ package eventbus
import (
"context"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
"reflect"
- "slices"
- "tailscale.com/syncs"
- "tailscale.com/types/logger"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/set"
)
type PublishedEvent struct {
@@ -145,7 +145,7 @@ func (b *Bus) pump(ctx context.Context) {
if b.routeDebug.active() {
clients := make([]*Client, len(dests))
- for i := range len(dests) {
+ for i := 0; i < len(dests); i++ {
clients[i] = dests[i].client
}
b.routeDebug.run(RoutedEvent{
diff --git a/util/eventbus/bus_test.go b/util/eventbus/bus_test.go
index e7fa7577f2bdd..6b05dafff4914 100644
--- a/util/eventbus/bus_test.go
+++ b/util/eventbus/bus_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -16,7 +18,7 @@ import (
"github.com/creachadair/taskgroup"
"github.com/google/go-cmp/cmp"
- "tailscale.com/util/eventbus"
+ "github.com/metacubex/tailscale/util/eventbus"
)
type EventA struct {
@@ -134,7 +136,7 @@ func TestSubscriberFunc(t *testing.T) {
c.Close()
// Verify that the logger recorded that Close gave up on the slowpoke.
- want := regexp.MustCompile(`^.* tailscale.com/util/eventbus_test bus_test.go:\d+: ` +
+ want := regexp.MustCompile(`^.* github.com/metacubex/tailscale/util/eventbus_test bus_test.go:\d+: ` +
`giving up on subscriber for eventbus_test.EventA after \d+s at close.*`)
if got := buf.String(); !want.MatchString(got) {
t.Errorf("Wrong log output\ngot: %q\nwant %s", got, want)
@@ -519,7 +521,7 @@ func TestSlowSubs(t *testing.T) {
time.Sleep(7 * time.Second) // advance time...
synctest.Wait() // subscriber is done
- want := regexp.MustCompile(`^.* tailscale.com/util/eventbus_test bus_test.go:\d+: ` +
+ want := regexp.MustCompile(`^.* github.com/metacubex/tailscale/util/eventbus_test bus_test.go:\d+: ` +
`subscriber for eventbus_test.EventA is slow.*`)
if got := buf.String(); !want.MatchString(got) {
t.Errorf("Wrong log output\ngot: %q\nwant: %s", got, want)
@@ -548,7 +550,7 @@ func TestSlowSubs(t *testing.T) {
time.Sleep(7 * time.Second) // advance time...
synctest.Wait() // subscriber is done
- want := regexp.MustCompile(`^.* tailscale.com/util/eventbus_test bus_test.go:\d+: ` +
+ want := regexp.MustCompile(`^.* github.com/metacubex/tailscale/util/eventbus_test bus_test.go:\d+: ` +
`subscriber for eventbus_test.EventB is slow.*`)
if got := buf.String(); !want.MatchString(got) {
t.Errorf("Wrong log output\ngot: %q\nwant: %s", got, want)
diff --git a/util/eventbus/client.go b/util/eventbus/client.go
index 0168acdd4a2c4..34ccad8f04693 100644
--- a/util/eventbus/client.go
+++ b/util/eventbus/client.go
@@ -6,9 +6,9 @@ package eventbus
import (
"reflect"
- "tailscale.com/syncs"
- "tailscale.com/types/logger"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/set"
)
// A Client can publish and subscribe to events on its attached
diff --git a/util/eventbus/debug-demo/main.go b/util/eventbus/debug-demo/main.go
index 64b51a0fa4fac..e9e1c874416d7 100644
--- a/util/eventbus/debug-demo/main.go
+++ b/util/eventbus/debug-demo/main.go
@@ -8,16 +8,16 @@
package main
import (
+ "github.com/metacubex/tailscale/util/go120/randv2"
"log"
- "math/rand/v2"
"net/http"
"net/netip"
"time"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/tsweb"
- "tailscale.com/types/key"
- "tailscale.com/util/eventbus"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/tsweb"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/util/eventbus"
)
func main() {
diff --git a/util/eventbus/debug.go b/util/eventbus/debug.go
index 7a37aeac8b6f3..640d03150bb3b 100644
--- a/util/eventbus/debug.go
+++ b/util/eventbus/debug.go
@@ -4,18 +4,18 @@
package eventbus
import (
- "cmp"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"path/filepath"
"reflect"
"runtime"
- "slices"
"strings"
"sync/atomic"
"time"
- "tailscale.com/syncs"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/logger"
)
// slowSubscriberTimeout is a timeout after which a subscriber that does not
@@ -231,7 +231,7 @@ func logfForCaller(logf logger.Logf) logger.Logf {
}
func funcPackageName(funcName string) string {
- ls := max(strings.LastIndex(funcName, "/"), 0)
+ ls := maxInt(strings.LastIndex(funcName, "/"), 0)
for {
i := strings.LastIndex(funcName, ".")
if i <= ls {
@@ -240,3 +240,10 @@ func funcPackageName(funcName string) string {
funcName = funcName[:i]
}
}
+
+func maxInt(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
diff --git a/util/eventbus/debughttp.go b/util/eventbus/debughttp.go
index 1c5a64074e441..e12588d2124fa 100644
--- a/util/eventbus/debughttp.go
+++ b/util/eventbus/debughttp.go
@@ -1,15 +1,16 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ios && !android && !ts_omit_debugeventbus
+//go:build !ios && !android && ts_enable_debugeventbus
package eventbus
import (
"bytes"
- "cmp"
"embed"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"html/template"
"io"
"io/fs"
@@ -17,12 +18,11 @@ import (
"net/http"
"path/filepath"
"reflect"
- "slices"
"strings"
- "sync"
"github.com/coder/websocket"
- "tailscale.com/tsweb"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tsweb"
)
type httpDebugger struct {
@@ -41,7 +41,7 @@ func (d *Debugger) RegisterHTTP(td *tsweb.DebugHandler) {
//go:embed assets/*.html
var templatesSrc embed.FS
-var templates = sync.OnceValue(func() *template.Template {
+var templates = syncs.OnceValue(func() *template.Template {
d, err := fs.Sub(templatesSrc, "assets")
if err != nil {
panic(fmt.Errorf("getting eventbus debughttp templates subdir: %w", err))
diff --git a/util/eventbus/debughttp_off.go b/util/eventbus/debughttp_off.go
index 4b31bd6b78a79..ed487ff8c5b04 100644
--- a/util/eventbus/debughttp_off.go
+++ b/util/eventbus/debughttp_off.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build ios || android || ts_omit_debugeventbus
+//go:build ios || android || !ts_enable_debugeventbus
package eventbus
diff --git a/util/eventbus/eventbustest/eventbustest.go b/util/eventbus/eventbustest/eventbustest.go
index b3ef6c884d89f..2bdd3905eb009 100644
--- a/util/eventbus/eventbustest/eventbustest.go
+++ b/util/eventbus/eventbustest/eventbustest.go
@@ -11,7 +11,7 @@ import (
"time"
"github.com/google/go-cmp/cmp"
- "tailscale.com/util/eventbus"
+ "github.com/metacubex/tailscale/util/eventbus"
)
// NewBus constructs an [eventbus.Bus] that will be shut automatically when
diff --git a/util/eventbus/eventbustest/eventbustest_test.go b/util/eventbus/eventbustest/eventbustest_test.go
index 3c8b5aee86d8f..2787d3a9788d7 100644
--- a/util/eventbus/eventbustest/eventbustest_test.go
+++ b/util/eventbus/eventbustest/eventbustest_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,8 +12,8 @@ import (
"testing"
"testing/synctest"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
)
var doDebug = flag.Bool("debug", false, "Enable debug logging")
diff --git a/util/eventbus/eventbustest/examples_test.go b/util/eventbus/eventbustest/examples_test.go
index 87a0efe31c6e9..66b2f57f95625 100644
--- a/util/eventbus/eventbustest/examples_test.go
+++ b/util/eventbus/eventbustest/examples_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,8 +10,8 @@ import (
"testing/synctest"
"time"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
)
func TestExample_Expect(t *testing.T) {
diff --git a/util/eventbus/monitor.go b/util/eventbus/monitor.go
index 0d3056e206664..1985adb7b44ef 100644
--- a/util/eventbus/monitor.go
+++ b/util/eventbus/monitor.go
@@ -3,7 +3,7 @@
package eventbus
-import "tailscale.com/syncs"
+import "github.com/metacubex/tailscale/syncs"
// A Monitor monitors the execution of a goroutine processing events from a
// [Client], allowing the caller to block until it is complete. The zero value
diff --git a/util/eventbus/publish.go b/util/eventbus/publish.go
index fd037ac3444aa..0bd39a3a5561b 100644
--- a/util/eventbus/publish.go
+++ b/util/eventbus/publish.go
@@ -40,14 +40,14 @@ type Publisher[T any] struct {
type publisherCore struct {
client *Client
stop stopFlag
- typ reflect.Type // cached reflect.TypeFor[T]()
+ typ reflect.Type // cached reflect.TypeOf((*T)(nil)).Elem()
}
func newPublisher[T any](c *Client) *Publisher[T] {
return &Publisher[T]{
core: &publisherCore{
client: c,
- typ: reflect.TypeFor[T](),
+ typ: reflect.TypeOf((*T)(nil)).Elem(),
},
}
}
diff --git a/util/eventbus/queue.go b/util/eventbus/queue.go
index 0483a05a68d5c..8e05499e330bb 100644
--- a/util/eventbus/queue.go
+++ b/util/eventbus/queue.go
@@ -4,7 +4,7 @@
package eventbus
import (
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
)
// queue is an ordered queue of length up to capacity,
@@ -44,7 +44,10 @@ func (q *queue[T]) Add(v T) {
// Slide remaining values back to the start of the array.
n := copy(q.vals, q.vals[q.start:])
toClear := len(q.vals) - n
- clear(q.vals[len(q.vals)-toClear:])
+ for i := len(q.vals) - toClear; i < len(q.vals); i++ {
+ var zero T
+ q.vals[i] = zero
+ }
q.vals = q.vals[:n]
q.start = 0
}
diff --git a/util/eventbus/subscribe.go b/util/eventbus/subscribe.go
index ef380b7ac6839..dae4097b09262 100644
--- a/util/eventbus/subscribe.go
+++ b/util/eventbus/subscribe.go
@@ -10,9 +10,9 @@ import (
"runtime"
"time"
- "tailscale.com/syncs"
- "tailscale.com/types/logger"
- "tailscale.com/util/cibuild"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/cibuild"
)
type DeliveredEvent struct {
@@ -196,7 +196,7 @@ func newSubscriber[T any](r *subscribeState, logf logger.Logf) *Subscriber[T] {
slow.Stop() // reset in dispatch
return &Subscriber[T]{
read: make(chan T),
- unregister: func() { r.deleteSubscriber(reflect.TypeFor[T]()) },
+ unregister: func() { r.deleteSubscriber(reflect.TypeOf((*T)(nil)).Elem()) },
logf: logf,
slow: slow,
}
@@ -211,7 +211,7 @@ func newMonitor[T any](attach func(fn func(T)) (cancel func())) *Subscriber[T] {
}
func (s *Subscriber[T]) subscribeType() reflect.Type {
- return reflect.TypeFor[T]()
+ return reflect.TypeOf((*T)(nil)).Elem()
}
func (s *Subscriber[T]) monitor(debugEvent T) {
@@ -299,7 +299,7 @@ type subscriberFuncCore struct {
// subscribeType() and used by the dispatch closure to format
// slow-subscriber log messages.
typ reflect.Type
- // typeName is the cached reflect.TypeFor[T]().String() result.
+ // typeName is the cached reflect.TypeOf((*T)(nil)).Elem().String() result.
// Computed once at construction time so the dispatch closure
// (which runs once per delivered event) doesn't allocate a
// fresh string on every call. The string is also independent
@@ -322,7 +322,7 @@ type subscriberFuncCore struct {
}
func newSubscriberFunc[T any](r *subscribeState, f func(T), logf logger.Logf) *SubscriberFunc[T] {
- core := newSubscriberFuncCore(r, logf, reflect.TypeFor[T]())
+ core := newSubscriberFuncCore(r, logf, reflect.TypeOf((*T)(nil)).Elem())
// The dispatch closure is the only piece that intrinsically
// needs T: it performs the type assertion on the head queue
// value and forwards the unboxed value to the user callback.
@@ -356,7 +356,7 @@ func newSubscriberFunc[T any](r *subscribeState, f func(T), logf logger.Logf) *S
// Hoisting this out of newSubscriberFunc[T] eliminates the bulk of
// the constructor body's per-T stencil cost; the only T-typed
// instructions left in the generic constructor are the
-// reflect.TypeFor[T]() call (whose body is shared via the
+// reflect.TypeOf((*T)(nil)).Elem() call (whose body is shared via the
// internal/abi.TypeFor[T] dictionary) and the construction of the
// dispatch closure itself.
func newSubscriberFuncCore(r *subscribeState, logf logger.Logf, typ reflect.Type) *subscriberFuncCore {
diff --git a/util/execqueue/execqueue.go b/util/execqueue/execqueue.go
index b2c7014377e13..0e44470a4a176 100644
--- a/util/execqueue/execqueue.go
+++ b/util/execqueue/execqueue.go
@@ -8,7 +8,7 @@ import (
"context"
"errors"
- "tailscale.com/syncs"
+ "github.com/metacubex/tailscale/syncs"
)
type ExecQueue struct {
diff --git a/util/execqueue/execqueue_test.go b/util/execqueue/execqueue_test.go
index c9f3a449ef67e..a008eb3dc1807 100644
--- a/util/execqueue/execqueue_test.go
+++ b/util/execqueue/execqueue_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/go120/cmp/cmp.go b/util/go120/cmp/cmp.go
new file mode 100644
index 0000000000000..b43053dc1c1ab
--- /dev/null
+++ b/util/go120/cmp/cmp.go
@@ -0,0 +1,29 @@
+// Copyright (c) Tailscale Inc & contributors
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Package cmp backports the small subset of Go's cmp package used by Tailscale.
+package cmp
+
+import "golang.org/x/exp/constraints"
+
+type Ordered = constraints.Ordered
+
+func Compare[T constraints.Ordered](x, y T) int {
+ if x < y {
+ return -1
+ }
+ if x > y {
+ return 1
+ }
+ return 0
+}
+
+func Or[T comparable](vals ...T) T {
+ var zero T
+ for _, v := range vals {
+ if v != zero {
+ return v
+ }
+ }
+ return zero
+}
diff --git a/util/go120/iter/iter.go b/util/go120/iter/iter.go
new file mode 100644
index 0000000000000..5257610b080f8
--- /dev/null
+++ b/util/go120/iter/iter.go
@@ -0,0 +1,9 @@
+// Copyright (c) Tailscale Inc & contributors
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Package iter defines Go 1.23 iterator function types for Go 1.20 builds.
+package iter
+
+type Seq[V any] func(yield func(V) bool)
+
+type Seq2[K, V any] func(yield func(K, V) bool)
diff --git a/util/go120/maps/maps.go b/util/go120/maps/maps.go
new file mode 100644
index 0000000000000..8bcff5cf63571
--- /dev/null
+++ b/util/go120/maps/maps.go
@@ -0,0 +1,96 @@
+// Copyright (c) Tailscale Inc & contributors
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Package maps backports the subset of Go's maps package used by Tailscale.
+package maps
+
+import "github.com/metacubex/tailscale/util/go120/iter"
+
+func All[M ~map[K]V, K comparable, V any](m M) iter.Seq2[K, V] {
+ return func(yield func(K, V) bool) {
+ for k, v := range m {
+ if !yield(k, v) {
+ return
+ }
+ }
+ }
+}
+
+func Keys[M ~map[K]V, K comparable, V any](m M) iter.Seq[K] {
+ return func(yield func(K) bool) {
+ for k := range m {
+ if !yield(k) {
+ return
+ }
+ }
+ }
+}
+
+func Values[M ~map[K]V, K comparable, V any](m M) iter.Seq[V] {
+ return func(yield func(V) bool) {
+ for _, v := range m {
+ if !yield(v) {
+ return
+ }
+ }
+ }
+}
+
+func Collect[K comparable, V any](seq iter.Seq2[K, V]) map[K]V {
+ m := map[K]V{}
+ seq(func(k K, v V) bool {
+ m[k] = v
+ return true
+ })
+ return m
+}
+
+func Clone[M ~map[K]V, K comparable, V any](m M) M {
+ if m == nil {
+ return nil
+ }
+ clone := make(M, len(m))
+ for k, v := range m {
+ clone[k] = v
+ }
+ return clone
+}
+
+func Copy[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2) {
+ for k, v := range src {
+ dst[k] = v
+ }
+}
+
+func DeleteFunc[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool) {
+ for k, v := range m {
+ if del(k, v) {
+ delete(m, k)
+ }
+ }
+}
+
+func Equal[M1 ~map[K]V, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool {
+ if len(m1) != len(m2) {
+ return false
+ }
+ for k, v1 := range m1 {
+ if v2, ok := m2[k]; !ok || v1 != v2 {
+ return false
+ }
+ }
+ return true
+}
+
+func EqualFunc[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any](m1 M1, m2 M2, eq func(V1, V2) bool) bool {
+ if len(m1) != len(m2) {
+ return false
+ }
+ for k, v1 := range m1 {
+ v2, ok := m2[k]
+ if !ok || !eq(v1, v2) {
+ return false
+ }
+ }
+ return true
+}
diff --git a/util/go120/randv2/randv2.go b/util/go120/randv2/randv2.go
new file mode 100644
index 0000000000000..f65d9a51f65c7
--- /dev/null
+++ b/util/go120/randv2/randv2.go
@@ -0,0 +1,54 @@
+// Copyright (c) Tailscale Inc & contributors
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Package rand backports the subset of math/rand/v2 used by Tailscale.
+package rand
+
+import (
+ mrand "math/rand"
+ "time"
+
+ "golang.org/x/exp/constraints"
+)
+
+type PCG struct {
+ r *mrand.Rand
+}
+
+func (p *PCG) Seed(seed1, seed2 uint64) {
+ p.r = mrand.New(mrand.NewSource(int64(seed1 ^ (seed2 << 1))))
+}
+
+func (p *PCG) Uint64() uint64 {
+ if p.r == nil {
+ p.Seed(Uint64(), Uint64())
+ }
+ return uint64(p.r.Uint32())<<32 | uint64(p.r.Uint32())
+}
+
+func init() {
+ mrand.Seed(time.Now().UnixNano())
+}
+
+func Uint64() uint64 {
+ return uint64(mrand.Uint32())<<32 | uint64(mrand.Uint32())
+}
+
+func Float64() float64 {
+ return mrand.Float64()
+}
+
+func IntN(n int) int {
+ return mrand.Intn(n)
+}
+
+func N[T constraints.Integer](n T) T {
+ if n <= 0 {
+ panic("invalid argument to N")
+ }
+ return T(mrand.Int63n(int64(n)))
+}
+
+func Shuffle(n int, swap func(i, j int)) {
+ mrand.Shuffle(n, swap)
+}
diff --git a/util/go120/slices/slices.go b/util/go120/slices/slices.go
new file mode 100644
index 0000000000000..982225eb497e6
--- /dev/null
+++ b/util/go120/slices/slices.go
@@ -0,0 +1,152 @@
+// Copyright (c) Tailscale Inc & contributors
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Package slices backports the subset of Go's slices package used by Tailscale.
+package slices
+
+import (
+ "sort"
+
+ "github.com/metacubex/tailscale/util/go120/cmp"
+ "github.com/metacubex/tailscale/util/go120/iter"
+ "golang.org/x/exp/constraints"
+ xslices "golang.org/x/exp/slices"
+)
+
+func All[S ~[]E, E any](s S) iter.Seq2[int, E] {
+ return func(yield func(int, E) bool) {
+ for i, v := range s {
+ if !yield(i, v) {
+ return
+ }
+ }
+ }
+}
+
+func Values[S ~[]E, E any](s S) iter.Seq[E] {
+ return func(yield func(E) bool) {
+ for _, v := range s {
+ if !yield(v) {
+ return
+ }
+ }
+ }
+}
+
+func Backward[S ~[]E, E any](s S) iter.Seq2[int, E] {
+ return func(yield func(int, E) bool) {
+ for i := len(s) - 1; i >= 0; i-- {
+ if !yield(i, s[i]) {
+ return
+ }
+ }
+ }
+}
+
+func Collect[E any](seq iter.Seq[E]) []E {
+ var s []E
+ seq(func(v E) bool {
+ s = append(s, v)
+ return true
+ })
+ return s
+}
+
+func Sorted[E constraints.Ordered](seq iter.Seq[E]) []E {
+ s := Collect(seq)
+ Sort(s)
+ return s
+}
+
+func AppendSeq[S ~[]E, E any](s S, seq iter.Seq[E]) S {
+ seq(func(v E) bool {
+ s = append(s, v)
+ return true
+ })
+ return s
+}
+
+func Equal[S ~[]E, E comparable](s1, s2 S) bool { return xslices.Equal(s1, s2) }
+
+func EqualFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) bool {
+ return xslices.EqualFunc(s1, s2, eq)
+}
+
+func Clone[S ~[]E, E any](s S) S { return xslices.Clone(s) }
+
+func Compact[S ~[]E, E comparable](s S) S { return xslices.Compact(s) }
+
+func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S { return xslices.CompactFunc(s, eq) }
+
+func Contains[S ~[]E, E comparable](s S, v E) bool { return xslices.Contains(s, v) }
+
+func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool { return xslices.ContainsFunc(s, f) }
+
+func Delete[S ~[]E, E any](s S, i, j int) S { return xslices.Delete(s, i, j) }
+
+func DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S { return xslices.DeleteFunc(s, del) }
+
+func Grow[S ~[]E, E any](s S, n int) S { return xslices.Grow(s, n) }
+
+func Index[S ~[]E, E comparable](s S, v E) int { return xslices.Index(s, v) }
+
+func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int { return xslices.IndexFunc(s, f) }
+
+func Insert[S ~[]E, E any](s S, i int, v ...E) S { return xslices.Insert(s, i, v...) }
+
+func Sort[S ~[]E, E constraints.Ordered](s S) { xslices.Sort(s) }
+
+func SortFunc[S ~[]E, E any](s S, f func(a, b E) int) { xslices.SortFunc(s, f) }
+
+func SortStableFunc[S ~[]E, E any](s S, f func(a, b E) int) {
+ sort.SliceStable(s, func(i, j int) bool { return f(s[i], s[j]) < 0 })
+}
+
+func MinFunc[S ~[]E, E any](s S, f func(a, b E) int) E { return xslices.MinFunc(s, f) }
+
+func MaxFunc[S ~[]E, E any](s S, f func(a, b E) int) E { return xslices.MaxFunc(s, f) }
+
+func BinarySearch[S ~[]E, E constraints.Ordered](s S, target E) (int, bool) {
+ return xslices.BinarySearch(s, target)
+}
+
+func BinarySearchFunc[S ~[]E, E, T any](s S, target T, f func(E, T) int) (int, bool) {
+ return xslices.BinarySearchFunc(s, target, f)
+}
+
+func Concat[S ~[]E, E any](slices ...S) S {
+ var size int
+ for _, s := range slices {
+ size += len(s)
+ }
+ out := make(S, 0, size)
+ for _, s := range slices {
+ out = append(out, s...)
+ }
+ return out
+}
+
+func CompareFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, f func(E1, E2) int) int {
+ n := len(s1)
+ if len(s2) < n {
+ n = len(s2)
+ }
+ for i := 0; i < n; i++ {
+ if c := f(s1[i], s2[i]); c != 0 {
+ return c
+ }
+ }
+ return cmp.Compare(len(s1), len(s2))
+}
+
+func Compare[S1 ~[]E, S2 ~[]E, E constraints.Ordered](s1 S1, s2 S2) int {
+ return CompareFunc(s1, s2, cmp.Compare[E])
+}
+
+func IsSorted[S ~[]E, E constraints.Ordered](s S) bool {
+ return xslices.IsSorted(s)
+}
+
+func Max[S ~[]E, E constraints.Ordered](s S) E { return xslices.Max(s) }
+
+func Min[S ~[]E, E constraints.Ordered](s S) E { return xslices.Min(s) }
diff --git a/util/go120/trigger/trigger.go b/util/go120/trigger/trigger.go
new file mode 100644
index 0000000000000..b2b751c77b7b3
--- /dev/null
+++ b/util/go120/trigger/trigger.go
@@ -0,0 +1,44 @@
+// Copyright (c) Tailscale Inc & contributors
+// SPDX-License-Identifier: BSD-3-Clause
+
+package trigger
+
+import "sync"
+
+type Cond struct {
+ mu sync.Mutex
+ ch chan struct{}
+ on bool
+}
+
+func (c *Cond) Ready() <-chan struct{} {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ if c.ch == nil {
+ c.ch = make(chan struct{})
+ }
+ return c.ch
+}
+
+func (c *Cond) Set() {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ if c.on {
+ return
+ }
+ c.on = true
+ if c.ch == nil {
+ c.ch = make(chan struct{})
+ }
+ close(c.ch)
+}
+
+func (c *Cond) Reset() {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ if !c.on {
+ return
+ }
+ c.on = false
+ c.ch = make(chan struct{})
+}
diff --git a/util/goroutines/goroutines_test.go b/util/goroutines/goroutines_test.go
index 97adccf1c2ab1..a330fd64a3d05 100644
--- a/util/goroutines/goroutines_test.go
+++ b/util/goroutines/goroutines_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/goroutines/tracker.go b/util/goroutines/tracker.go
index b0513ef4efa3f..fe024381d4c27 100644
--- a/util/goroutines/tracker.go
+++ b/util/goroutines/tracker.go
@@ -6,8 +6,8 @@ package goroutines
import (
"sync/atomic"
- "tailscale.com/syncs"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/util/set"
)
// Tracker tracks a set of goroutines.
diff --git a/util/groupmember/groupmember.go b/util/groupmember/groupmember.go
index 090e1561dcded..235fc2df8c871 100644
--- a/util/groupmember/groupmember.go
+++ b/util/groupmember/groupmember.go
@@ -6,8 +6,8 @@
package groupmember
import (
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"os/user"
- "slices"
)
// IsMemberOfGroup reports whether the provided user is a member of
diff --git a/util/hashx/block512_test.go b/util/hashx/block512_test.go
index 03c77eabbecc3..554e33836af3b 100644
--- a/util/hashx/block512_test.go
+++ b/util/hashx/block512_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,7 +13,7 @@ import (
"testing"
qt "github.com/frankban/quicktest"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/util/must"
)
// naiveHash is an obviously correct implementation of Hash.
diff --git a/util/httphdr/httphdr_test.go b/util/httphdr/httphdr_test.go
index 37906a5bf6603..603987849c3e4 100644
--- a/util/httphdr/httphdr_test.go
+++ b/util/httphdr/httphdr_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/httpm/httpm_test.go b/util/httpm/httpm_test.go
index e8342a74f26b6..b50209c8bf5ae 100644
--- a/util/httpm/httpm_test.go
+++ b/util/httpm/httpm_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/limiter/limiter.go b/util/limiter/limiter.go
index f48114d531fa4..d00a2e9381e9a 100644
--- a/util/limiter/limiter.go
+++ b/util/limiter/limiter.go
@@ -10,8 +10,8 @@ import (
"io"
"time"
- "tailscale.com/syncs"
- "tailscale.com/util/lru"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/util/lru"
)
// Limiter is a keyed token bucket rate limiter.
diff --git a/util/limiter/limiter_test.go b/util/limiter/limiter_test.go
index 5210322bbd3b0..da819a929f3ea 100644
--- a/util/limiter/limiter_test.go
+++ b/util/limiter/limiter_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/lineiter/lineiter.go b/util/lineiter/lineiter.go
index 06d35909022b8..7d29d5c242683 100644
--- a/util/lineiter/lineiter.go
+++ b/util/lineiter/lineiter.go
@@ -7,11 +7,11 @@ package lineiter
import (
"bufio"
"bytes"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
"io"
- "iter"
"os"
- "tailscale.com/types/result"
+ "github.com/metacubex/tailscale/types/result"
)
// File returns an iterator that reads lines from the named file.
diff --git a/util/lineiter/lineiter_test.go b/util/lineiter/lineiter_test.go
index 6e9e285501fab..893c41722cd4e 100644
--- a/util/lineiter/lineiter_test.go
+++ b/util/lineiter/lineiter_test.go
@@ -1,10 +1,12 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package lineiter
import (
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
"testing"
)
diff --git a/util/linuxfw/detector.go b/util/linuxfw/detector.go
index a3a1c1ddaa547..86c4a1ba54d56 100644
--- a/util/linuxfw/detector.go
+++ b/util/linuxfw/detector.go
@@ -9,12 +9,12 @@ import (
"errors"
"os/exec"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/hostinfo"
- "tailscale.com/types/logger"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/version/distro"
)
func detectFirewallMode(logf logger.Logf, prefHint string) FirewallMode {
diff --git a/util/linuxfw/fake.go b/util/linuxfw/fake.go
index b902b93c1a66b..9580aee645279 100644
--- a/util/linuxfw/fake.go
+++ b/util/linuxfw/fake.go
@@ -8,8 +8,8 @@ package linuxfw
import (
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"os"
- "slices"
"strconv"
"strings"
)
diff --git a/util/linuxfw/fake_netfilter.go b/util/linuxfw/fake_netfilter.go
index e9d853508481d..58b8aa3ab3aae 100644
--- a/util/linuxfw/fake_netfilter.go
+++ b/util/linuxfw/fake_netfilter.go
@@ -8,7 +8,7 @@ package linuxfw
import (
"net/netip"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
// FakeNetfilterRunner is a fake netfilter runner for tests.
diff --git a/util/linuxfw/helpers.go b/util/linuxfw/helpers.go
index a369b6a8841b3..bd9a6985ac4d7 100644
--- a/util/linuxfw/helpers.go
+++ b/util/linuxfw/helpers.go
@@ -11,7 +11,7 @@ import (
"strings"
"unicode"
- "tailscale.com/util/slicesx"
+ "github.com/metacubex/tailscale/util/slicesx"
)
func formatMaybePrintable(b []byte) string {
diff --git a/util/linuxfw/iptables.go b/util/linuxfw/iptables.go
index 3bd2c288699e4..4c05bfe6b520d 100644
--- a/util/linuxfw/iptables.go
+++ b/util/linuxfw/iptables.go
@@ -14,9 +14,9 @@ import (
"strings"
"unicode"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/version/distro"
"github.com/coreos/go-iptables/iptables"
- "tailscale.com/types/logger"
- "tailscale.com/version/distro"
)
func init() {
diff --git a/util/linuxfw/iptables_disabled.go b/util/linuxfw/iptables_disabled.go
index c986fe7c206ea..1d0f0a4805b2f 100644
--- a/util/linuxfw/iptables_disabled.go
+++ b/util/linuxfw/iptables_disabled.go
@@ -8,7 +8,7 @@ package linuxfw
import (
"errors"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
func detectIptables() (int, error) {
diff --git a/util/linuxfw/iptables_for_svcs_test.go b/util/linuxfw/iptables_for_svcs_test.go
index b4dfe19c84c14..307a8be4acdc2 100644
--- a/util/linuxfw/iptables_for_svcs_test.go
+++ b/util/linuxfw/iptables_for_svcs_test.go
@@ -1,7 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux
package linuxfw
diff --git a/util/linuxfw/iptables_runner.go b/util/linuxfw/iptables_runner.go
index ace23a2353803..3f19f6faf703a 100644
--- a/util/linuxfw/iptables_runner.go
+++ b/util/linuxfw/iptables_runner.go
@@ -7,15 +7,15 @@ package linuxfw
import (
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
"net/netip"
"os/exec"
- "slices"
"strconv"
"strings"
- "tailscale.com/net/tsaddr"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/types/logger"
)
// isNotExistError needs to be overridden in tests that rely on distinguishing
diff --git a/util/linuxfw/iptables_runner_test.go b/util/linuxfw/iptables_runner_test.go
index b5a13fdba1bca..51dc2bc667582 100644
--- a/util/linuxfw/iptables_runner_test.go
+++ b/util/linuxfw/iptables_runner_test.go
@@ -1,7 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux
package linuxfw
@@ -10,8 +11,8 @@ import (
"strings"
"testing"
- "tailscale.com/net/tsaddr"
- "tailscale.com/tsconst"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/tsconst"
)
var testIsNotExistErr = "exitcode:1"
diff --git a/util/linuxfw/linuxfw.go b/util/linuxfw/linuxfw.go
index ed130a2b1416b..4be86eb9d5c2b 100644
--- a/util/linuxfw/linuxfw.go
+++ b/util/linuxfw/linuxfw.go
@@ -13,10 +13,10 @@ import (
"strconv"
"strings"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/tsconst"
+ "github.com/metacubex/tailscale/types/logger"
"github.com/tailscale/netlink"
- "tailscale.com/feature"
- "tailscale.com/tsconst"
- "tailscale.com/types/logger"
)
// MatchDecision is the decision made by the firewall for a packet matched by a rule.
diff --git a/util/linuxfw/nftables.go b/util/linuxfw/nftables.go
index 6059128a97c2f..8911d05799f0c 100644
--- a/util/linuxfw/nftables.go
+++ b/util/linuxfw/nftables.go
@@ -7,17 +7,17 @@
package linuxfw
import (
- "cmp"
"encoding/binary"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"sort"
"strings"
+ "github.com/metacubex/tailscale/types/logger"
"github.com/google/nftables"
"github.com/google/nftables/expr"
"github.com/google/nftables/xt"
"golang.org/x/sys/unix"
- "tailscale.com/types/logger"
)
// DebugNetfilter prints debug information about netfilter rules to the
diff --git a/util/linuxfw/nftables_for_svcs_test.go b/util/linuxfw/nftables_for_svcs_test.go
index c3be3fc3b7bee..0524ec568cea1 100644
--- a/util/linuxfw/nftables_for_svcs_test.go
+++ b/util/linuxfw/nftables_for_svcs_test.go
@@ -1,7 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux
package linuxfw
diff --git a/util/linuxfw/nftables_runner.go b/util/linuxfw/nftables_runner.go
index b31be8bae7bc8..9ce62ca73145c 100644
--- a/util/linuxfw/nftables_runner.go
+++ b/util/linuxfw/nftables_runner.go
@@ -15,11 +15,11 @@ import (
"reflect"
"strings"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/types/logger"
"github.com/google/nftables"
"github.com/google/nftables/expr"
"golang.org/x/sys/unix"
- "tailscale.com/net/tsaddr"
- "tailscale.com/types/logger"
)
const (
diff --git a/util/linuxfw/nftables_runner_test.go b/util/linuxfw/nftables_runner_test.go
index 65df7718e10e8..1e1617b384630 100644
--- a/util/linuxfw/nftables_runner_test.go
+++ b/util/linuxfw/nftables_runner_test.go
@@ -1,7 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build linux
package linuxfw
@@ -9,19 +10,19 @@ import (
"bytes"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"runtime"
- "slices"
"strings"
"testing"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/logger"
"github.com/google/nftables"
"github.com/google/nftables/expr"
"github.com/mdlayher/netlink"
"github.com/vishvananda/netns"
- "tailscale.com/net/tsaddr"
- "tailscale.com/tstest"
- "tailscale.com/types/logger"
)
func toAnySlice[T any](s []T) []any {
diff --git a/util/lru/lru_test.go b/util/lru/lru_test.go
index 5fbc718b1decd..22bb159177970 100644
--- a/util/lru/lru_test.go
+++ b/util/lru/lru_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,7 +12,7 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
- "tailscale.com/util/slicesx"
+ "github.com/metacubex/tailscale/util/slicesx"
)
func TestLRU(t *testing.T) {
diff --git a/util/mak/mak_test.go b/util/mak/mak_test.go
index 7a4090c20292c..566aada8af60e 100644
--- a/util/mak/mak_test.go
+++ b/util/mak/mak_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/multierr/multierr.go b/util/multierr/multierr.go
index 3acdb7d773222..d966e8b38d2fe 100644
--- a/util/multierr/multierr.go
+++ b/util/multierr/multierr.go
@@ -7,7 +7,7 @@ package multierr
import (
"errors"
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
)
diff --git a/util/multierr/multierr_test.go b/util/multierr/multierr_test.go
index 35195b3770db1..ce3bb2e79f58d 100644
--- a/util/multierr/multierr_test.go
+++ b/util/multierr/multierr_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -12,7 +14,7 @@ import (
qt "github.com/frankban/quicktest"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/util/multierr"
+ "github.com/metacubex/tailscale/util/multierr"
)
func TestAll(t *testing.T) {
diff --git a/util/nocasemaps/nocase.go b/util/nocasemaps/nocase.go
index 737ab5de7c3bb..c4820375fe811 100644
--- a/util/nocasemaps/nocase.go
+++ b/util/nocasemaps/nocase.go
@@ -57,7 +57,7 @@ func Set[K ~string, V any](m map[K]V, k K, v V) {
//
// Alternatively, we could use string interning.
// See an example intern data structure, see:
- // https://github.com/go-json-experiment/json/blob/master/intern.go
+ // https://github.com/metacubex/jsonv2/blob/master/intern.go
var a [stackArraySize]byte
m[K(appendToLower(a[:0], string(k)))] = v
}
@@ -91,7 +91,7 @@ func AppendSliceElem[K ~string, S []E, E any](m map[K]S, k K, vs ...E) {
}
func isLowerASCII(s string) bool {
- for i := range len(s) {
+ for i := 0; i < len(s); i++ {
if c := s[i]; c >= utf8.RuneSelf || ('A' <= c && c <= 'Z') {
return false
}
diff --git a/util/nocasemaps/nocase_test.go b/util/nocasemaps/nocase_test.go
index cae36242c3040..6a785aa1bc02f 100644
--- a/util/nocasemaps/nocase_test.go
+++ b/util/nocasemaps/nocase_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/osdiag/internal/wsc/wsc_windows.go b/util/osdiag/internal/wsc/wsc_windows.go
index 8bc43ac54bbb9..53422776a496a 100644
--- a/util/osdiag/internal/wsc/wsc_windows.go
+++ b/util/osdiag/internal/wsc/wsc_windows.go
@@ -11,9 +11,9 @@ import (
"syscall"
"unsafe"
- "github.com/dblohm7/wingoes"
- "github.com/dblohm7/wingoes/com"
- "github.com/dblohm7/wingoes/com/automation"
+ "github.com/metacubex/tailscale/util/wingoes"
+ "github.com/metacubex/tailscale/util/wingoes/com"
+ "github.com/metacubex/tailscale/util/wingoes/com/automation"
)
var (
diff --git a/util/osdiag/osdiag_windows.go b/util/osdiag/osdiag_windows.go
index ff489989c1dbd..b41cda308626d 100644
--- a/util/osdiag/osdiag_windows.go
+++ b/util/osdiag/osdiag_windows.go
@@ -12,13 +12,13 @@ import (
"unicode/utf16"
"unsafe"
- "github.com/dblohm7/wingoes/com"
- "github.com/dblohm7/wingoes/pe"
+ "github.com/metacubex/tailscale/util/osdiag/internal/wsc"
+ "github.com/metacubex/tailscale/util/wingoes/com"
+ "github.com/metacubex/tailscale/util/wingoes/pe"
+ "github.com/metacubex/tailscale/util/winutil"
+ "github.com/metacubex/tailscale/util/winutil/authenticode"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
- "tailscale.com/util/osdiag/internal/wsc"
- "tailscale.com/util/winutil"
- "tailscale.com/util/winutil/authenticode"
)
var (
@@ -541,7 +541,7 @@ func getSecurityInfo() map[string]any {
continue
}
- n = min(n, maxProvCount)
+ n = minInt32(n, maxProvCount)
values := make([]any, 0, n)
for i := int32(0); i < n; i++ {
@@ -653,3 +653,10 @@ func getEffectivePageFileValue() ([]string, error) {
entries, _, err := key.GetStringsValue("PagingFiles")
return entries, err
}
+
+func minInt32(a, b int32) int32 {
+ if a < b {
+ return a
+ }
+ return b
+}
diff --git a/util/osdiag/osdiag_windows_test.go b/util/osdiag/osdiag_windows_test.go
index f285f80feac43..fca914c7c7d7e 100644
--- a/util/osdiag/osdiag_windows_test.go
+++ b/util/osdiag/osdiag_windows_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,7 +8,7 @@ package osdiag
import (
"errors"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"strings"
"testing"
diff --git a/util/osshare/filesharingstatus_noop.go b/util/osshare/filesharingstatus_noop.go
index 22f0a33785131..b26a523609c8b 100644
--- a/util/osshare/filesharingstatus_noop.go
+++ b/util/osshare/filesharingstatus_noop.go
@@ -6,7 +6,7 @@
package osshare
import (
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
func SetFileSharingEnabled(enabled bool, logf logger.Logf) {}
diff --git a/util/osshare/filesharingstatus_windows.go b/util/osshare/filesharingstatus_windows.go
index d21c394d0a27c..b9e15087617d6 100644
--- a/util/osshare/filesharingstatus_windows.go
+++ b/util/osshare/filesharingstatus_windows.go
@@ -11,10 +11,10 @@ import (
"path/filepath"
"runtime"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/winutil"
"golang.org/x/sys/windows/registry"
- "tailscale.com/types/lazy"
- "tailscale.com/types/logger"
- "tailscale.com/util/winutil"
)
const (
diff --git a/util/osuser/group_ids.go b/util/osuser/group_ids.go
index 34d15c926ae98..889a940386173 100644
--- a/util/osuser/group_ids.go
+++ b/util/osuser/group_ids.go
@@ -12,7 +12,7 @@ import (
"strings"
"time"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/version/distro"
)
// GetGroupIds returns the list of group IDs that the user is a member of, or
diff --git a/util/osuser/group_ids_test.go b/util/osuser/group_ids_test.go
index fee86029bf4dc..6f8efa43b8242 100644
--- a/util/osuser/group_ids_test.go
+++ b/util/osuser/group_ids_test.go
@@ -1,10 +1,12 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package osuser
import (
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"testing"
)
diff --git a/util/osuser/user.go b/util/osuser/user.go
index 2de3da762739d..8e839ed3fe947 100644
--- a/util/osuser/user.go
+++ b/util/osuser/user.go
@@ -16,7 +16,7 @@ import (
"time"
"unicode/utf8"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/version/distro"
)
// LookupByUIDWithShell is like os/user.LookupId but handles a few edge cases
diff --git a/util/precompress/precompress.go b/util/precompress/precompress.go
index 80aed36821b2e..d89d1242b903f 100644
--- a/util/precompress/precompress.go
+++ b/util/precompress/precompress.go
@@ -17,8 +17,8 @@ import (
"path/filepath"
"github.com/andybalholm/brotli"
+ "github.com/metacubex/tailscale/tsweb"
"golang.org/x/sync/errgroup"
- "tailscale.com/tsweb"
)
// PrecompressDir compresses static assets in dirPath using Gzip and Brotli, so
diff --git a/util/race/race.go b/util/race/race.go
index 8e339dad2fd03..cd8721939562e 100644
--- a/util/race/race.go
+++ b/util/race/race.go
@@ -87,7 +87,7 @@ func (rh *Race[T]) Start(ctx context.Context) (T, error) {
// For each possible result, get it off the channel.
var errs []error
- for range 2 {
+ for i := 0; i < 2; i++ {
res := <-rh.results
// If this was an error, store it and hope that the other
diff --git a/util/race/race_test.go b/util/race/race_test.go
index 90b049909ce3c..7668faed12dcf 100644
--- a/util/race/race_test.go
+++ b/util/race/race_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,7 +11,7 @@ import (
"testing"
"time"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/tstest"
)
func TestRaceSuccess1(t *testing.T) {
diff --git a/util/rands/cheap.go b/util/rands/cheap.go
index f3b931d34662b..a82f8b4f62444 100644
--- a/util/rands/cheap.go
+++ b/util/rands/cheap.go
@@ -10,7 +10,7 @@ package rands
import (
"math/bits"
- randv2 "math/rand/v2"
+ randv2 "github.com/metacubex/tailscale/util/go120/randv2"
)
// Shuffle is like rand.Shuffle, but it does not allocate or lock any RNG state.
diff --git a/util/rands/cheap_test.go b/util/rands/cheap_test.go
index 874592a1b647e..1577a3a7ea1e3 100644
--- a/util/rands/cheap_test.go
+++ b/util/rands/cheap_test.go
@@ -1,13 +1,15 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package rands
import (
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"testing"
- randv2 "math/rand/v2"
+ randv2 "github.com/metacubex/tailscale/util/go120/randv2"
)
func TestShuffleNoAllocs(t *testing.T) {
diff --git a/util/rands/rands_test.go b/util/rands/rands_test.go
index 81cdf3bec02e0..a3b8d4d3b6132 100644
--- a/util/rands/rands_test.go
+++ b/util/rands/rands_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/reload/reload.go b/util/reload/reload.go
index edcb90c12a3f2..26764f931d14c 100644
--- a/util/reload/reload.go
+++ b/util/reload/reload.go
@@ -9,13 +9,13 @@ import (
"context"
"encoding/json"
"fmt"
- "math/rand/v2"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"os"
"reflect"
"time"
- "tailscale.com/syncs"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/logger"
)
// DefaultInterval is the default value for ReloadOpts.Interval if none is
diff --git a/util/reload/reload_test.go b/util/reload/reload_test.go
index 7e7963c3f7a9e..d363f74d2ca31 100644
--- a/util/reload/reload_test.go
+++ b/util/reload/reload_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -14,7 +16,7 @@ import (
"testing"
"time"
- "tailscale.com/tstest"
+ "github.com/metacubex/tailscale/tstest"
)
func TestReloader(t *testing.T) {
diff --git a/util/ringlog/ringlog.go b/util/ringlog/ringlog.go
index d8197dda84deb..e094e43946df8 100644
--- a/util/ringlog/ringlog.go
+++ b/util/ringlog/ringlog.go
@@ -4,7 +4,7 @@
// Package ringlog contains a limited-size concurrency-safe generic ring log.
package ringlog
-import "tailscale.com/syncs"
+import "github.com/metacubex/tailscale/syncs"
// New creates a new [RingLog] containing at most max items.
func New[T any](max int) *RingLog[T] {
@@ -50,7 +50,7 @@ func (rb *RingLog[T]) GetAll() []T {
rb.mu.Lock()
defer rb.mu.Unlock()
out := make([]T, len(rb.buf))
- for i := range len(rb.buf) {
+ for i := 0; i < len(rb.buf); i++ {
x := (rb.pos + i) % rb.max
out[i] = rb.buf[x]
}
diff --git a/util/ringlog/ringlog_test.go b/util/ringlog/ringlog_test.go
index 8ecf99cd0f3f1..6b3c6fd9f372e 100644
--- a/util/ringlog/ringlog_test.go
+++ b/util/ringlog/ringlog_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/safediff/diff_test.go b/util/safediff/diff_test.go
index 4251d788b10fe..986582f2f48c1 100644
--- a/util/safediff/diff_test.go
+++ b/util/safediff/diff_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/set/intset.go b/util/set/intset.go
index 29a634516a510..f9f1905bdeadd 100644
--- a/util/set/intset.go
+++ b/util/set/intset.go
@@ -4,13 +4,13 @@
package set
import (
- "iter"
- "maps"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"math/bits"
- "math/rand/v2"
+ "github.com/metacubex/tailscale/util/mak"
"golang.org/x/exp/constraints"
- "tailscale.com/util/mak"
)
// IntSet is a set optimized for integer values close to zero
@@ -42,19 +42,15 @@ func IntsOf[T constraints.Integer](slice ...T) IntSet[T] {
func (s IntSet[T]) Values() iter.Seq[T] {
return func(yield func(T) bool) {
if s.bits != 0 {
- for i := range s.bits.values() {
- if !yield(decodeZigZag[T](i)) {
- return
- }
- }
+ s.bits.values()(func(i uint64) bool {
+ return yield(decodeZigZag[T](i))
+ })
}
if s.extra != nil {
for hi, bs := range s.extra {
- for lo := range bs.values() {
- if !yield(decodeZigZag[T](hi*bits.UintSize + lo)) {
- return
- }
- }
+ bs.values()(func(lo uint64) bool {
+ return yield(decodeZigZag[T](hi*bits.UintSize + lo))
+ })
}
}
}
@@ -91,9 +87,10 @@ func (s *IntSet[T]) Add(e T) {
// AddSeq adds the values from seq to the set.
func (s *IntSet[T]) AddSeq(seq iter.Seq[T]) {
- for e := range seq {
+ seq(func(e T) bool {
s.Add(e)
- }
+ return true
+ })
}
// Len reports the number of elements in the set.
@@ -122,9 +119,10 @@ func (s *IntSet[T]) Delete(e T) {
// DeleteSeq deletes the values in seq from the set.
func (s *IntSet[T]) DeleteSeq(seq iter.Seq[T]) {
- for e := range seq {
+ seq(func(e T) bool {
s.Delete(e)
- }
+ return true
+ })
}
// Equal reports whether s is equal to other.
@@ -152,13 +150,13 @@ func (s bitSet) values() iter.Seq[uint64] {
return func(yield func(uint64) bool) {
// Hyrum-proofing: randomly iterate in forwards or reverse.
if rand.Uint64()%2 == 0 {
- for i := range bits.UintSize {
+ for i := 0; i < bits.UintSize; i++ {
if s.contains(uint64(i)) && !yield(uint64(i)) {
return
}
}
} else {
- for i := bits.UintSize; i >= 0; i-- {
+ for i := bits.UintSize - 1; i >= 0; i-- {
if s.contains(uint64(i)) && !yield(uint64(i)) {
return
}
diff --git a/util/set/intset_test.go b/util/set/intset_test.go
index 6cbf5a0bb472b..8e4403c53bbe0 100644
--- a/util/set/intset_test.go
+++ b/util/set/intset_test.go
@@ -1,12 +1,14 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package set
import (
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"math"
- "slices"
"testing"
"golang.org/x/exp/constraints"
diff --git a/util/set/set.go b/util/set/set.go
index c3d2350a7e6ba..ebceb88087634 100644
--- a/util/set/set.go
+++ b/util/set/set.go
@@ -6,7 +6,7 @@ package set
import (
"encoding/json"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"reflect"
"sort"
)
@@ -63,7 +63,7 @@ func (s Set[T]) Slice() []T {
for k := range s {
es = append(es, k)
}
- if f := genOrderedSwapper(reflect.TypeFor[T]()); f != nil {
+ if f := genOrderedSwapper(reflect.TypeOf((*T)(nil)).Elem()); f != nil {
sort.Slice(es, f(reflect.ValueOf(es)))
}
return es
diff --git a/util/set/set_test.go b/util/set/set_test.go
index 2188cbb4ddff7..f22544f5bb374 100644
--- a/util/set/set_test.go
+++ b/util/set/set_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,7 +7,7 @@ package set
import (
"encoding/json"
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"testing"
)
diff --git a/util/set/slice.go b/util/set/slice.go
index 921da4fa21622..9d83d2a4bc90d 100644
--- a/util/set/slice.go
+++ b/util/set/slice.go
@@ -4,9 +4,9 @@
package set
import (
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
- "tailscale.com/types/views"
+ "github.com/metacubex/tailscale/types/views"
)
// Slice is a set of elements tracked in a slice of unique elements.
@@ -67,7 +67,8 @@ func (ss *Slice[T]) Add(vs ...T) {
// AddSlice adds all elements in vs to the set.
func (ss *Slice[T]) AddSlice(vs views.Slice[T]) {
- for _, v := range vs.All() {
+ vs.All()(func(_ int, v T) bool {
ss.Add(v)
- }
+ return true
+ })
}
diff --git a/util/set/slice_test.go b/util/set/slice_test.go
index 468ba686c5772..a48c1a9921df5 100644
--- a/util/set/slice_test.go
+++ b/util/set/slice_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/set/smallset.go b/util/set/smallset.go
index da52dd265a939..d790bc028f7c9 100644
--- a/util/set/smallset.go
+++ b/util/set/smallset.go
@@ -4,10 +4,10 @@
package set
import (
- "iter"
- "maps"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
- "tailscale.com/types/structs"
+ "github.com/metacubex/tailscale/types/structs"
)
// SmallSet is a set that is optimized for reducing memory overhead when the
diff --git a/util/set/smallset_test.go b/util/set/smallset_test.go
index 019a9d24d1f5c..64834d1e38267 100644
--- a/util/set/smallset_test.go
+++ b/util/set/smallset_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,10 +7,10 @@ package set
import (
"fmt"
- "iter"
- "maps"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"reflect"
- "slices"
"testing"
)
diff --git a/util/singleflight/singleflight.go b/util/singleflight/singleflight.go
index e6d859178140b..5d34aeef82504 100644
--- a/util/singleflight/singleflight.go
+++ b/util/singleflight/singleflight.go
@@ -16,7 +16,7 @@
// - https://pkg.go.dev/golang.org/x/sync/singleflight
//
// This fork adds generics.
-package singleflight // import "tailscale.com/util/singleflight"
+package singleflight // import "github.com/metacubex/tailscale/util/singleflight"
import (
"bytes"
diff --git a/util/singleflight/singleflight_test.go b/util/singleflight/singleflight_test.go
index 4e8500cc3c3d6..c7ebbace7a7a5 100644
--- a/util/singleflight/singleflight_test.go
+++ b/util/singleflight/singleflight_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/slicesx/slicesx.go b/util/slicesx/slicesx.go
index 660110a3c4f28..14d9c904c8afc 100644
--- a/util/slicesx/slicesx.go
+++ b/util/slicesx/slicesx.go
@@ -5,8 +5,8 @@
package slicesx
import (
- "math/rand/v2"
- "slices"
+ "github.com/metacubex/tailscale/util/go120/randv2"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
)
// Interleave combines two slices of the form [a, b, c] and [x, y, z] into a
diff --git a/util/slicesx/slicesx_test.go b/util/slicesx/slicesx_test.go
index 6b28c29b47382..7de4e57265bf2 100644
--- a/util/slicesx/slicesx_test.go
+++ b/util/slicesx/slicesx_test.go
@@ -1,11 +1,13 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package slicesx
import (
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"reflect"
- "slices"
"testing"
qt "github.com/frankban/quicktest"
diff --git a/util/stringsx/stringsx_test.go b/util/stringsx/stringsx_test.go
index afce987c08a53..759d2200843fd 100644
--- a/util/stringsx/stringsx_test.go
+++ b/util/stringsx/stringsx_test.go
@@ -1,10 +1,12 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package stringsx
import (
- "cmp"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"strings"
"testing"
)
diff --git a/util/syspolicy/internal/internal.go b/util/syspolicy/internal/internal.go
index 4179f26c82cb2..85d2e51e98169 100644
--- a/util/syspolicy/internal/internal.go
+++ b/util/syspolicy/internal/internal.go
@@ -8,10 +8,10 @@ package internal
import (
"bytes"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/types/lazy"
- "tailscale.com/util/testenv"
- "tailscale.com/version"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/util/testenv"
+ "github.com/metacubex/tailscale/version"
)
// Init facilitates deferred invocation of initializers.
@@ -45,10 +45,10 @@ func EqualJSONForTest(tb testenv.TB, j1, j2 jsontext.Value) (s1, s2 string, equa
return "", "", true
}
// Otherwise, format the values for display and return false.
- if err := j1.Indent(); err != nil {
+ if err := j1.Indent(jsontext.WithIndent(" ")); err != nil {
tb.Fatal(err)
}
- if err := j2.Indent(); err != nil {
+ if err := j2.Indent(jsontext.WithIndent(" ")); err != nil {
tb.Fatal(err)
}
return j1.String(), j2.String(), false
diff --git a/util/syspolicy/internal/loggerx/logger.go b/util/syspolicy/internal/loggerx/logger.go
index 412616cb132cd..ffebac7c0c33d 100644
--- a/util/syspolicy/internal/loggerx/logger.go
+++ b/util/syspolicy/internal/loggerx/logger.go
@@ -8,9 +8,9 @@ import (
"log"
"sync/atomic"
- "tailscale.com/types/lazy"
- "tailscale.com/types/logger"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/testenv"
)
const (
diff --git a/util/syspolicy/internal/loggerx/logger_test.go b/util/syspolicy/internal/loggerx/logger_test.go
index 5c8fb7e2860d5..04569c55ab8ba 100644
--- a/util/syspolicy/internal/loggerx/logger_test.go
+++ b/util/syspolicy/internal/loggerx/logger_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,7 +11,7 @@ import (
"strings"
"testing"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
func TestDebugLogging(t *testing.T) {
diff --git a/util/syspolicy/internal/metrics/metrics.go b/util/syspolicy/internal/metrics/metrics.go
index 8a3b5327fbab8..d765cb2138ae3 100644
--- a/util/syspolicy/internal/metrics/metrics.go
+++ b/util/syspolicy/internal/metrics/metrics.go
@@ -10,16 +10,16 @@ import (
xmaps "golang.org/x/exp/maps"
- "tailscale.com/syncs"
- "tailscale.com/types/lazy"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/mak"
- "tailscale.com/util/slicesx"
- "tailscale.com/util/syspolicy/internal"
- "tailscale.com/util/syspolicy/internal/loggerx"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/setting"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/util/syspolicy/internal"
+ "github.com/metacubex/tailscale/util/syspolicy/internal/loggerx"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/testenv"
)
var lazyReportMetrics lazy.SyncValue[bool] // used as a test hook
@@ -270,7 +270,9 @@ func SetHooksForTest(tb testenv.TB, addMetric, setMetric metricFn) {
settingMetricsMu.Lock()
oldSettingMetricsMap := xmaps.Clone(settingMetricsMap)
- clear(settingMetricsMap)
+ for k := range settingMetricsMap {
+ delete(settingMetricsMap, k)
+ }
settingMetricsMu.Unlock()
tb.Cleanup(func() {
settingMetricsMu.Lock()
diff --git a/util/syspolicy/internal/metrics/metrics_test.go b/util/syspolicy/internal/metrics/metrics_test.go
index ce9dea98b86d7..f536c2054b5ee 100644
--- a/util/syspolicy/internal/metrics/metrics_test.go
+++ b/util/syspolicy/internal/metrics/metrics_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,11 +9,11 @@ import (
"errors"
"testing"
- "tailscale.com/types/lazy"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/syspolicy/internal"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/syspolicy/internal"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
)
func TestSettingMetricNames(t *testing.T) {
diff --git a/util/syspolicy/internal/metrics/test_handler.go b/util/syspolicy/internal/metrics/test_handler.go
index 1ec0c9f4c3015..0f2254a40cfa3 100644
--- a/util/syspolicy/internal/metrics/test_handler.go
+++ b/util/syspolicy/internal/metrics/test_handler.go
@@ -6,10 +6,10 @@ package metrics
import (
"strings"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/set"
- "tailscale.com/util/syspolicy/internal"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/syspolicy/internal"
+ "github.com/metacubex/tailscale/util/testenv"
)
// TestState represents a metric name and its expected value.
diff --git a/util/syspolicy/policy_keys.go b/util/syspolicy/policy_keys.go
index 2a4599cb85869..34fe27cbeb4e9 100644
--- a/util/syspolicy/policy_keys.go
+++ b/util/syspolicy/policy_keys.go
@@ -4,10 +4,10 @@
package syspolicy
import (
- "tailscale.com/util/syspolicy/internal"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/setting"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/util/syspolicy/internal"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/testenv"
)
// implicitDefinitions is a list of [setting.Definition] that will be registered
diff --git a/util/syspolicy/policy_keys_test.go b/util/syspolicy/policy_keys_test.go
index 17e2e7a9b8f92..c818f3a8b1243 100644
--- a/util/syspolicy/policy_keys_test.go
+++ b/util/syspolicy/policy_keys_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -14,8 +16,8 @@ import (
"strconv"
"testing"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
)
func TestKnownKeysRegistered(t *testing.T) {
diff --git a/util/syspolicy/policyclient/policyclient.go b/util/syspolicy/policyclient/policyclient.go
index e6ad208b02f65..024b7ae8723c3 100644
--- a/util/syspolicy/policyclient/policyclient.go
+++ b/util/syspolicy/policyclient/policyclient.go
@@ -9,9 +9,9 @@ package policyclient
import (
"time"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/ptype"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/ptype"
+ "github.com/metacubex/tailscale/util/testenv"
)
// Client is the interface between code making questions about the system policy
diff --git a/util/syspolicy/policytest/policytest.go b/util/syspolicy/policytest/policytest.go
index 9879a0fd3c69c..98eaf507550b4 100644
--- a/util/syspolicy/policytest/policytest.go
+++ b/util/syspolicy/policytest/policytest.go
@@ -6,15 +6,15 @@ package policytest
import (
"fmt"
- "maps"
- "slices"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"sync"
"time"
- "tailscale.com/util/set"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/policyclient"
- "tailscale.com/util/syspolicy/ptype"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/util/syspolicy/ptype"
)
// Config is a [policyclient.Client] implementation with a static mapping of
diff --git a/util/syspolicy/ptype/ptype_test.go b/util/syspolicy/ptype/ptype_test.go
index ba7eab471b5ea..a6325f56ff95e 100644
--- a/util/syspolicy/ptype/ptype_test.go
+++ b/util/syspolicy/ptype/ptype_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,7 +9,7 @@ import (
"encoding"
"testing"
- "tailscale.com/tstest/deptest"
+ "github.com/metacubex/tailscale/tstest/deptest"
)
var (
diff --git a/util/syspolicy/rsop/change_callbacks.go b/util/syspolicy/rsop/change_callbacks.go
index 0b6cd10c4cc1a..5b2aeb75b5c1a 100644
--- a/util/syspolicy/rsop/change_callbacks.go
+++ b/util/syspolicy/rsop/change_callbacks.go
@@ -4,18 +4,18 @@
package rsop
import (
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"reflect"
- "slices"
"sync"
"time"
- "tailscale.com/syncs"
- "tailscale.com/util/set"
- "tailscale.com/util/syspolicy/internal/loggerx"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/policyclient"
- "tailscale.com/util/syspolicy/ptype"
- "tailscale.com/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/syspolicy/internal/loggerx"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/util/syspolicy/ptype"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
)
// Change represents a change from the Old to the New value of type T.
@@ -110,7 +110,9 @@ func (c *policyChangeCallbacks) Close() {
c.mu.Lock()
defer c.mu.Unlock()
if c.cbs != nil {
- clear(c.cbs)
+ for h := range c.cbs {
+ delete(c.cbs, h)
+ }
c.cbs = nil
}
}
diff --git a/util/syspolicy/rsop/resultant_policy.go b/util/syspolicy/rsop/resultant_policy.go
index 5f8081a677a79..c91da66672953 100644
--- a/util/syspolicy/rsop/resultant_policy.go
+++ b/util/syspolicy/rsop/resultant_policy.go
@@ -6,16 +6,16 @@ package rsop
import (
"errors"
"fmt"
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"sync/atomic"
"time"
- "tailscale.com/syncs"
- "tailscale.com/util/syspolicy/internal/loggerx"
- "tailscale.com/util/syspolicy/setting"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/util/syspolicy/internal/loggerx"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/testenv"
- "tailscale.com/util/syspolicy/source"
+ "github.com/metacubex/tailscale/util/syspolicy/source"
)
// ErrPolicyClosed is returned by [Policy.Reload], [Policy.addSource],
diff --git a/util/syspolicy/rsop/resultant_policy_test.go b/util/syspolicy/rsop/resultant_policy_test.go
index 60132eae7a1d8..41610a569828f 100644
--- a/util/syspolicy/rsop/resultant_policy_test.go
+++ b/util/syspolicy/rsop/resultant_policy_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,7 +7,7 @@ package rsop
import (
"errors"
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"sort"
"strconv"
"sync"
@@ -14,12 +16,12 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/tstest"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/policyclient"
- "tailscale.com/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
- "tailscale.com/util/syspolicy/source"
+ "github.com/metacubex/tailscale/util/syspolicy/source"
)
func TestGetEffectivePolicyNoSource(t *testing.T) {
diff --git a/util/syspolicy/rsop/rsop.go b/util/syspolicy/rsop/rsop.go
index a57a4b34825ac..be6086dbc120d 100644
--- a/util/syspolicy/rsop/rsop.go
+++ b/util/syspolicy/rsop/rsop.go
@@ -9,13 +9,13 @@ package rsop
import (
"errors"
"fmt"
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
- "tailscale.com/syncs"
- "tailscale.com/util/slicesx"
- "tailscale.com/util/syspolicy/internal"
- "tailscale.com/util/syspolicy/setting"
- "tailscale.com/util/syspolicy/source"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/util/syspolicy/internal"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/syspolicy/source"
)
var (
diff --git a/util/syspolicy/rsop/store_registration.go b/util/syspolicy/rsop/store_registration.go
index 99dbc7096fc56..f79a8e602fec7 100644
--- a/util/syspolicy/rsop/store_registration.go
+++ b/util/syspolicy/rsop/store_registration.go
@@ -9,9 +9,9 @@ import (
"sync/atomic"
"time"
- "tailscale.com/util/syspolicy/setting"
- "tailscale.com/util/syspolicy/source"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/syspolicy/source"
+ "github.com/metacubex/tailscale/util/testenv"
)
// ErrAlreadyConsumed is the error returned when [StoreRegistration.ReplaceStore]
diff --git a/util/syspolicy/setting/errors.go b/util/syspolicy/setting/errors.go
index c8e0d8121ec2a..2a88aecc44cc8 100644
--- a/util/syspolicy/setting/errors.go
+++ b/util/syspolicy/setting/errors.go
@@ -37,7 +37,8 @@ type ErrorText string
// NewErrorText returns a [ErrorText] with the specified error message.
func NewErrorText(text string) *ErrorText {
- return new(ErrorText(text))
+ e := ErrorText(text)
+ return &e
}
// MaybeErrorText returns an [ErrorText] with the text of the specified error,
@@ -49,7 +50,8 @@ func MaybeErrorText(err error) *ErrorText {
if err, ok := err.(*ErrorText); ok {
return err
}
- return new(ErrorText(err.Error()))
+ e := ErrorText(err.Error())
+ return &e
}
// Error implements error.
diff --git a/util/syspolicy/setting/origin.go b/util/syspolicy/setting/origin.go
index 8ed629e72a322..11d1cf3de0041 100644
--- a/util/syspolicy/setting/origin.go
+++ b/util/syspolicy/setting/origin.go
@@ -6,8 +6,8 @@ package setting
import (
"fmt"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
)
// Origin describes where a policy or a policy setting is configured.
diff --git a/util/syspolicy/setting/policy_scope.go b/util/syspolicy/setting/policy_scope.go
index 4162614929dd2..663effca60ba2 100644
--- a/util/syspolicy/setting/policy_scope.go
+++ b/util/syspolicy/setting/policy_scope.go
@@ -7,8 +7,8 @@ import (
"fmt"
"strings"
- "tailscale.com/types/lazy"
- "tailscale.com/util/syspolicy/internal"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/util/syspolicy/internal"
)
var (
diff --git a/util/syspolicy/setting/policy_scope_test.go b/util/syspolicy/setting/policy_scope_test.go
index 9cdbbe7ab5df4..3798da1851e35 100644
--- a/util/syspolicy/setting/policy_scope_test.go
+++ b/util/syspolicy/setting/policy_scope_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,7 +9,7 @@ import (
"reflect"
"testing"
- jsonv2 "github.com/go-json-experiment/json"
+ jsonv2 "github.com/metacubex/jsonv2"
)
func TestPolicyScopeIsApplicableSetting(t *testing.T) {
diff --git a/util/syspolicy/setting/raw_item.go b/util/syspolicy/setting/raw_item.go
index 4bfb50faa1b62..22dbf3ced1c8c 100644
--- a/util/syspolicy/setting/raw_item.go
+++ b/util/syspolicy/setting/raw_item.go
@@ -7,11 +7,11 @@ import (
"fmt"
"reflect"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/types/opt"
- "tailscale.com/types/structs"
- "tailscale.com/util/syspolicy/pkey"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/structs"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
)
// RawItem contains a raw policy setting value as read from a policy store, or an
diff --git a/util/syspolicy/setting/raw_item_test.go b/util/syspolicy/setting/raw_item_test.go
index 1a40bc829c351..9b480df5a4224 100644
--- a/util/syspolicy/setting/raw_item_test.go
+++ b/util/syspolicy/setting/raw_item_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,7 +11,7 @@ import (
"strconv"
"testing"
- jsonv2 "github.com/go-json-experiment/json"
+ jsonv2 "github.com/metacubex/jsonv2"
)
func TestMarshalUnmarshalRawValue(t *testing.T) {
diff --git a/util/syspolicy/setting/setting.go b/util/syspolicy/setting/setting.go
index 4384e64c234f9..2219d89b1cf1d 100644
--- a/util/syspolicy/setting/setting.go
+++ b/util/syspolicy/setting/setting.go
@@ -9,16 +9,16 @@ package setting
import (
"fmt"
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
"time"
- "tailscale.com/syncs"
- "tailscale.com/types/lazy"
- "tailscale.com/util/syspolicy/internal"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/ptype"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/util/syspolicy/internal"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/ptype"
+ "github.com/metacubex/tailscale/util/testenv"
)
// Scope indicates the broadest scope at which a policy setting may apply,
diff --git a/util/syspolicy/setting/setting_test.go b/util/syspolicy/setting/setting_test.go
index 885491b679ba8..097e55739b56e 100644
--- a/util/syspolicy/setting/setting_test.go
+++ b/util/syspolicy/setting/setting_test.go
@@ -1,16 +1,18 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package setting
import (
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
"testing"
- "tailscale.com/types/lazy"
- "tailscale.com/util/syspolicy/internal"
- "tailscale.com/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/util/syspolicy/internal"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
)
func TestSettingDefinition(t *testing.T) {
diff --git a/util/syspolicy/setting/snapshot.go b/util/syspolicy/setting/snapshot.go
index 74cadd0be7296..30168a98042dd 100644
--- a/util/syspolicy/setting/snapshot.go
+++ b/util/syspolicy/setting/snapshot.go
@@ -5,17 +5,17 @@ package setting
import (
"errors"
- "iter"
- "maps"
- "slices"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"strings"
"time"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/util/deephash"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
xmaps "golang.org/x/exp/maps"
- "tailscale.com/util/deephash"
- "tailscale.com/util/syspolicy/pkey"
)
// Snapshot is an immutable collection of ([Key], [RawItem]) pairs, representing
diff --git a/util/syspolicy/setting/snapshot_test.go b/util/syspolicy/setting/snapshot_test.go
index 0385e4aefc8b4..7d6627c7a5e27 100644
--- a/util/syspolicy/setting/snapshot_test.go
+++ b/util/syspolicy/setting/snapshot_test.go
@@ -1,18 +1,20 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package setting
import (
- "cmp"
"encoding/json"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"testing"
"time"
- jsonv2 "github.com/go-json-experiment/json"
- "tailscale.com/util/syspolicy/internal"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/ptype"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/tailscale/util/syspolicy/internal"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/ptype"
)
const (
diff --git a/util/syspolicy/setting/summary.go b/util/syspolicy/setting/summary.go
index 4cb15c7c4d078..88b2fcc3df0c5 100644
--- a/util/syspolicy/setting/summary.go
+++ b/util/syspolicy/setting/summary.go
@@ -4,9 +4,9 @@
package setting
import (
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
- "tailscale.com/types/opt"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/types/opt"
)
// Summary is an immutable [PolicyScope] and [Origin].
diff --git a/util/syspolicy/source/env_policy_store.go b/util/syspolicy/source/env_policy_store.go
index 9b7cebfbf19e5..0d05e8f8a247a 100644
--- a/util/syspolicy/source/env_policy_store.go
+++ b/util/syspolicy/source/env_policy_store.go
@@ -11,8 +11,8 @@ import (
"strings"
"unicode/utf8"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
)
var lookupEnv = os.LookupEnv // test hook
diff --git a/util/syspolicy/source/env_policy_store_test.go b/util/syspolicy/source/env_policy_store_test.go
index 5cda0f32a2984..9e3fb7427ab05 100644
--- a/util/syspolicy/source/env_policy_store_test.go
+++ b/util/syspolicy/source/env_policy_store_test.go
@@ -1,18 +1,20 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package source
import (
- "cmp"
"errors"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"math"
"reflect"
"strconv"
"testing"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
)
func TestKeyToEnvVarName(t *testing.T) {
diff --git a/util/syspolicy/source/policy_reader.go b/util/syspolicy/source/policy_reader.go
index 177985322d318..ca36a1f57a9a0 100644
--- a/util/syspolicy/source/policy_reader.go
+++ b/util/syspolicy/source/policy_reader.go
@@ -6,19 +6,19 @@ package source
import (
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
- "slices"
"sort"
"sync"
"time"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
- "tailscale.com/util/syspolicy/internal/loggerx"
- "tailscale.com/util/syspolicy/internal/metrics"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/ptype"
- "tailscale.com/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/syspolicy/internal/loggerx"
+ "github.com/metacubex/tailscale/util/syspolicy/internal/metrics"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/ptype"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
)
// Reader reads all configured policy settings from a given [Store].
@@ -113,8 +113,8 @@ func (r *Reader) GetSettings() *setting.Snapshot {
}
// ReadSettings reads policy settings from the underlying [Store] even if no
-// changes were detected. It returns the new [*setting.Snapshot],nil on
-// success or an undefined snapshot (possibly `nil`) along with a non-`nil`
+// changes were detected. It returns the new [*setting.Snapshot], nil on
+// success or an undefined snapshot (possibly nil) along with a non-nil
// error in case of failure.
func (r *Reader) ReadSettings() (*setting.Snapshot, error) {
return r.reload(true)
@@ -195,7 +195,8 @@ func (r *Reader) OpenSession() (*ReadingSession, error) {
reader: r,
policyChangedCh: make(chan struct{}, 1),
}
- session.closeInternal = sync.OnceFunc(func() { close(session.policyChangedCh) })
+ var closeOnce sync.Once
+ session.closeInternal = func() { closeOnce.Do(func() { close(session.policyChangedCh) }) }
r.mu.Lock()
defer r.mu.Unlock()
if r.closing {
diff --git a/util/syspolicy/source/policy_reader_test.go b/util/syspolicy/source/policy_reader_test.go
index e5a893f56877a..5062fbe7bf85c 100644
--- a/util/syspolicy/source/policy_reader_test.go
+++ b/util/syspolicy/source/policy_reader_test.go
@@ -1,17 +1,19 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package source
import (
- "cmp"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"testing"
"time"
- "tailscale.com/util/must"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/ptype"
- "tailscale.com/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/ptype"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
)
func TestReaderLifecycle(t *testing.T) {
diff --git a/util/syspolicy/source/policy_source.go b/util/syspolicy/source/policy_source.go
index 3dfa83fd17a30..6e0a8ac91fec2 100644
--- a/util/syspolicy/source/policy_source.go
+++ b/util/syspolicy/source/policy_source.go
@@ -7,14 +7,14 @@
package source
import (
- "cmp"
"errors"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"io"
- "tailscale.com/types/lazy"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
)
// ErrStoreClosed is an error returned when attempting to use a [Store] after it
diff --git a/util/syspolicy/source/policy_store_windows.go b/util/syspolicy/source/policy_store_windows.go
index edcdcae69b408..d6ab5ade9fa61 100644
--- a/util/syspolicy/source/policy_store_windows.go
+++ b/util/syspolicy/source/policy_store_windows.go
@@ -9,13 +9,13 @@ import (
"strings"
"sync"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/syspolicy/internal/loggerx"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/winutil/gp"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
- "tailscale.com/util/set"
- "tailscale.com/util/syspolicy/internal/loggerx"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/setting"
- "tailscale.com/util/winutil/gp"
)
const (
diff --git a/util/syspolicy/source/policy_store_windows_test.go b/util/syspolicy/source/policy_store_windows_test.go
index b3ca5083d2a05..e20805b81fac1 100644
--- a/util/syspolicy/source/policy_store_windows_test.go
+++ b/util/syspolicy/source/policy_store_windows_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -14,15 +16,15 @@ import (
"testing"
"time"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/util/cibuild"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/winutil"
+ "github.com/metacubex/tailscale/util/winutil/gp"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
- "tailscale.com/tstest"
- "tailscale.com/util/cibuild"
- "tailscale.com/util/mak"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/setting"
- "tailscale.com/util/winutil"
- "tailscale.com/util/winutil/gp"
)
// subkeyStrings is a test type indicating that a string slice should be written
diff --git a/util/syspolicy/source/test_store.go b/util/syspolicy/source/test_store.go
index 1baa138319337..1e3e7d90c9363 100644
--- a/util/syspolicy/source/test_store.go
+++ b/util/syspolicy/source/test_store.go
@@ -8,13 +8,13 @@ import (
"sync"
"sync/atomic"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/testenv"
xmaps "golang.org/x/exp/maps"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
- "tailscale.com/util/slicesx"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/setting"
- "tailscale.com/util/testenv"
)
var (
@@ -249,7 +249,9 @@ func (s *TestStore) recordRead(key pkey.Key, typ setting.Type) {
func (s *TestStore) ResetCounters() {
s.readsMu.Lock()
- clear(s.reads)
+ for k := range s.reads {
+ delete(s.reads, k)
+ }
s.readsMu.Unlock()
}
@@ -415,7 +417,9 @@ func (s *TestStore) Delete(keys ...pkey.Key) {
func (s *TestStore) Clear() {
s.storeLock.Lock()
s.mu.Lock()
- clear(s.mw)
+ for k := range s.mw {
+ delete(s.mw, k)
+ }
s.mu.Unlock()
s.storeLock.Unlock()
s.NotifyPolicyChanged()
diff --git a/util/syspolicy/syspolicy.go b/util/syspolicy/syspolicy.go
index 7451bde758d4f..b87c7e2fc8e63 100644
--- a/util/syspolicy/syspolicy.go
+++ b/util/syspolicy/syspolicy.go
@@ -3,7 +3,7 @@
// Package syspolicy contains the implementation of system policy management.
// Calling code should use the client interface in
-// tailscale.com/util/syspolicy/policyclient.
+// github.com/metacubex/tailscale/util/syspolicy/policyclient.
package syspolicy
import (
@@ -12,13 +12,13 @@ import (
"reflect"
"time"
- "tailscale.com/util/syspolicy/internal/loggerx"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/policyclient"
- "tailscale.com/util/syspolicy/ptype"
- "tailscale.com/util/syspolicy/rsop"
- "tailscale.com/util/syspolicy/setting"
- "tailscale.com/util/syspolicy/source"
+ "github.com/metacubex/tailscale/util/syspolicy/internal/loggerx"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/policyclient"
+ "github.com/metacubex/tailscale/util/syspolicy/ptype"
+ "github.com/metacubex/tailscale/util/syspolicy/rsop"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/syspolicy/source"
)
var (
@@ -163,7 +163,7 @@ func convertPolicySettingValueTo[T setting.ValueType](value any, def T) (T, erro
// Convert [PreferenceOption], [Visibility], or [time.Duration] back to a string
// if someone requests a string instead of the actual setting's value.
// TODO(nickkhyl): check if this behavior is relied upon anywhere besides the old tests.
- if reflect.TypeFor[T]().Kind() == reflect.String {
+ if reflect.TypeOf((*T)(nil)).Elem().Kind() == reflect.String {
if str, ok := value.(fmt.Stringer); ok {
return any(str.String()).(T), nil
}
diff --git a/util/syspolicy/syspolicy_test.go b/util/syspolicy/syspolicy_test.go
index c62c90dddfb33..3511835f35b52 100644
--- a/util/syspolicy/syspolicy_test.go
+++ b/util/syspolicy/syspolicy_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -5,19 +7,19 @@ package syspolicy
import (
"errors"
- "slices"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"testing"
"time"
- "tailscale.com/types/logger"
- "tailscale.com/util/syspolicy/internal/loggerx"
- "tailscale.com/util/syspolicy/internal/metrics"
- "tailscale.com/util/syspolicy/pkey"
- "tailscale.com/util/syspolicy/ptype"
- "tailscale.com/util/syspolicy/rsop"
- "tailscale.com/util/syspolicy/setting"
- "tailscale.com/util/syspolicy/source"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/syspolicy/internal/loggerx"
+ "github.com/metacubex/tailscale/util/syspolicy/internal/metrics"
+ "github.com/metacubex/tailscale/util/syspolicy/pkey"
+ "github.com/metacubex/tailscale/util/syspolicy/ptype"
+ "github.com/metacubex/tailscale/util/syspolicy/rsop"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/syspolicy/source"
+ "github.com/metacubex/tailscale/util/testenv"
)
var someOtherError = errors.New("error other than not found")
diff --git a/util/syspolicy/syspolicy_windows.go b/util/syspolicy/syspolicy_windows.go
index 80c84b4570b9f..23da8418c07a7 100644
--- a/util/syspolicy/syspolicy_windows.go
+++ b/util/syspolicy/syspolicy_windows.go
@@ -8,11 +8,11 @@ import (
"fmt"
"os/user"
- "tailscale.com/util/syspolicy/internal"
- "tailscale.com/util/syspolicy/rsop"
- "tailscale.com/util/syspolicy/setting"
- "tailscale.com/util/syspolicy/source"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale/util/syspolicy/internal"
+ "github.com/metacubex/tailscale/util/syspolicy/rsop"
+ "github.com/metacubex/tailscale/util/syspolicy/setting"
+ "github.com/metacubex/tailscale/util/syspolicy/source"
+ "github.com/metacubex/tailscale/util/testenv"
)
func init() {
diff --git a/util/testenv/testenv.go b/util/testenv/testenv.go
index 1ae1fe8a8a0f1..49f7fbd612ae7 100644
--- a/util/testenv/testenv.go
+++ b/util/testenv/testenv.go
@@ -9,7 +9,7 @@ import (
"context"
"flag"
- "tailscale.com/types/lazy"
+ "github.com/metacubex/tailscale/types/lazy"
)
var lazyInTest lazy.SyncValue[bool]
diff --git a/util/testenv/testenv_test.go b/util/testenv/testenv_test.go
index 3001d19eb2722..296c9928a19fd 100644
--- a/util/testenv/testenv_test.go
+++ b/util/testenv/testenv_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,7 +8,7 @@ package testenv
import (
"testing"
- "tailscale.com/tstest/deptest"
+ "github.com/metacubex/tailscale/tstest/deptest"
)
func TestDeps(t *testing.T) {
diff --git a/util/truncate/truncate_test.go b/util/truncate/truncate_test.go
index 6a99a0efc4706..f36a050361449 100644
--- a/util/truncate/truncate_test.go
+++ b/util/truncate/truncate_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,7 +8,7 @@ package truncate_test
import (
"testing"
- "tailscale.com/util/truncate"
+ "github.com/metacubex/tailscale/util/truncate"
)
func TestString(t *testing.T) {
diff --git a/util/usermetric/metrics.go b/util/usermetric/metrics.go
index 14c2fabbec1f5..0b945e09260b1 100644
--- a/util/usermetric/metrics.go
+++ b/util/usermetric/metrics.go
@@ -10,7 +10,7 @@ package usermetric
import (
"sync"
- "tailscale.com/feature/buildfeatures"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
)
// Metrics contains user-facing metrics that are used by multiple packages.
diff --git a/util/usermetric/omit.go b/util/usermetric/omit.go
index c2681ebdaa3b4..108f0bce6697c 100644
--- a/util/usermetric/omit.go
+++ b/util/usermetric/omit.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build ts_omit_usermetrics
+//go:build !ts_enable_usermetrics
package usermetric
@@ -11,9 +11,7 @@ type Registry struct {
func (*Registry) NewGauge(name, help string) *Gauge { return nil }
-type MultiLabelMap[T comparable] = noopMap[T]
-
-type noopMap[T comparable] struct{}
+type MultiLabelMap[T comparable] struct{}
type Gauge struct{}
@@ -23,7 +21,7 @@ func NewMultiLabelMapWithRegistry[T comparable](m *Registry, name string, promTy
return nil
}
-func (*noopMap[T]) Add(T, int64) {}
-func (*noopMap[T]) Set(T, any) {}
+func (*MultiLabelMap[T]) Add(T, int64) {}
+func (*MultiLabelMap[T]) Set(T, any) {}
func (r *Registry) Handler(any, any) {} // no-op HTTP handler
diff --git a/util/usermetric/usermetric.go b/util/usermetric/usermetric.go
index f435f3ec23da3..8d7f9bb81dc88 100644
--- a/util/usermetric/usermetric.go
+++ b/util/usermetric/usermetric.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_usermetrics
+//go:build ts_enable_usermetrics
// Package usermetric provides a container and handler
// for user-facing metrics.
@@ -14,9 +14,9 @@ import (
"net/http"
"strings"
- "tailscale.com/metrics"
- "tailscale.com/tsweb/varz"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/metrics"
+ "github.com/metacubex/tailscale/tsweb/varz"
+ "github.com/metacubex/tailscale/util/set"
)
// Registry tracks user-facing metrics of various Tailscale subsystems.
@@ -29,7 +29,9 @@ type Registry struct {
// MultiLabelMap is an alias for metrics.MultiLabelMap in the common case,
// or an alias to a lighter type when usermetrics are omitted from the build.
-type MultiLabelMap[T comparable] = metrics.MultiLabelMap[T]
+type MultiLabelMap[T comparable] struct {
+ metrics.MultiLabelMap[T]
+}
// NewMultiLabelMapWithRegistry creates and register a new
// MultiLabelMap[T] variable with the given name and returns it.
@@ -38,11 +40,11 @@ type MultiLabelMap[T comparable] = metrics.MultiLabelMap[T]
// Note that usermetric are not protected against duplicate
// metrics name. It is the caller's responsibility to ensure that
// the name is unique.
-func NewMultiLabelMapWithRegistry[T comparable](m *Registry, name string, promType, helpText string) *metrics.MultiLabelMap[T] {
- ml := &metrics.MultiLabelMap[T]{
+func NewMultiLabelMapWithRegistry[T comparable](m *Registry, name string, promType, helpText string) *MultiLabelMap[T] {
+ ml := &MultiLabelMap[T]{MultiLabelMap: metrics.MultiLabelMap[T]{
Type: promType,
Help: helpText,
- }
+ }}
var zero T
_ = metrics.LabelString(zero) // panic early if T is invalid
m.vars.Set(name, ml)
diff --git a/util/usermetric/usermetric_test.go b/util/usermetric/usermetric_test.go
index cdbb44ec057bc..63bb92b42f43a 100644
--- a/util/usermetric/usermetric_test.go
+++ b/util/usermetric/usermetric_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/vizerror/vizerror.go b/util/vizerror/vizerror.go
index e0abe8f97d15e..8486dcf47a41b 100644
--- a/util/vizerror/vizerror.go
+++ b/util/vizerror/vizerror.go
@@ -77,5 +77,6 @@ func WrapWithMessage(wrapped error, publicMsg string) error {
// As returns the first vizerror.Error in err's chain.
func As(err error) (e Error, ok bool) {
- return errors.AsType[Error](err)
+ ok = errors.As(err, &e)
+ return e, ok
}
diff --git a/util/vizerror/vizerror_test.go b/util/vizerror/vizerror_test.go
index 10e8376030beb..c15b4fcda4c4c 100644
--- a/util/vizerror/vizerror_test.go
+++ b/util/vizerror/vizerror_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/wingoes/com/api.go b/util/wingoes/com/api.go
new file mode 100644
index 0000000000000..f86cde70a44d8
--- /dev/null
+++ b/util/wingoes/com/api.go
@@ -0,0 +1,140 @@
+// 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 windows
+
+package com
+
+import (
+ "unsafe"
+
+ "github.com/metacubex/tailscale/util/wingoes"
+)
+
+// MustGetAppID parses s, a string containing an app ID and returns a pointer to the
+// parsed AppID. s must be specified in the format "{XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}".
+// If there is an error parsing s, MustGetAppID panics.
+func MustGetAppID(s string) *AppID {
+ return (*AppID)(unsafe.Pointer(wingoes.MustGetGUID(s)))
+}
+
+// MustGetCLSID parses s, a string containing a CLSID and returns a pointer to the
+// parsed CLSID. s must be specified in the format "{XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}".
+// If there is an error parsing s, MustGetCLSID panics.
+func MustGetCLSID(s string) *CLSID {
+ return (*CLSID)(unsafe.Pointer(wingoes.MustGetGUID(s)))
+}
+
+// MustGetIID parses s, a string containing an IID and returns a pointer to the
+// parsed IID. s must be specified in the format "{XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}".
+// If there is an error parsing s, MustGetIID panics.
+func MustGetIID(s string) *IID {
+ return (*IID)(unsafe.Pointer(wingoes.MustGetGUID(s)))
+}
+
+// MustGetServiceID parses s, a string containing a service ID and returns a pointer to the
+// parsed ServiceID. s must be specified in the format "{XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}".
+// If there is an error parsing s, MustGetServiceID panics.
+func MustGetServiceID(s string) *ServiceID {
+ return (*ServiceID)(unsafe.Pointer(wingoes.MustGetGUID(s)))
+}
+
+func getCurrentApartmentInfo() (aptInfo, error) {
+ var info aptInfo
+ hr := coGetApartmentType(&info.apt, &info.qualifier)
+ if err := wingoes.ErrorFromHRESULT(hr); err.Failed() {
+ return info, err
+ }
+
+ return info, nil
+}
+
+// aptChecker is a function that applies an arbitrary predicate to an OS thread's
+// apartment information, returning true if the input satisifes that predicate.
+type aptChecker func(*aptInfo) bool
+
+// checkCurrentApartment obtains information about the COM apartment that the
+// current OS thread resides in, and then passes that information to chk,
+// which evaluates that information and determines the return value.
+func checkCurrentApartment(chk aptChecker) bool {
+ info, err := getCurrentApartmentInfo()
+ if err != nil {
+ return false
+ }
+
+ return chk(&info)
+}
+
+// AssertCurrentOSThreadSTA checks if the current OS thread resides in a
+// single-threaded apartment, and if not, panics.
+func AssertCurrentOSThreadSTA() {
+ if IsCurrentOSThreadSTA() {
+ return
+ }
+ panic("current OS thread does not reside in a single-threaded apartment")
+}
+
+// IsCurrentOSThreadSTA checks if the current OS thread resides in a
+// single-threaded apartment and returns true if so.
+func IsCurrentOSThreadSTA() bool {
+ chk := func(i *aptInfo) bool {
+ return i.apt == coAPTTYPE_STA || i.apt == coAPTTYPE_MAINSTA
+ }
+
+ return checkCurrentApartment(chk)
+}
+
+// AssertCurrentOSThreadMTA checks if the current OS thread resides in the
+// multi-threaded apartment, and if not, panics.
+func AssertCurrentOSThreadMTA() {
+ if IsCurrentOSThreadMTA() {
+ return
+ }
+ panic("current OS thread does not reside in the multi-threaded apartment")
+}
+
+// IsCurrentOSThreadMTA checks if the current OS thread resides in the
+// multi-threaded apartment and returns true if so.
+func IsCurrentOSThreadMTA() bool {
+ chk := func(i *aptInfo) bool {
+ return i.apt == coAPTTYPE_MTA
+ }
+
+ return checkCurrentApartment(chk)
+}
+
+// createInstanceWithCLSCTX creates a new garbage-collected COM object of type T
+// using class clsid. clsctx determines the acceptable location for hosting the
+// COM object (in-process, local but out-of-process, or remote).
+func createInstanceWithCLSCTX[T Object](clsid *CLSID, clsctx coCLSCTX) (T, error) {
+ var t T
+
+ iid := t.IID()
+ ppunk := NewABIReceiver()
+
+ hr := coCreateInstance(
+ clsid,
+ nil,
+ clsctx,
+ iid,
+ ppunk,
+ )
+ if err := wingoes.ErrorFromHRESULT(hr); err.Failed() {
+ return t, err
+ }
+
+ return t.Make(ppunk).(T), nil
+}
+
+// CreateInstance instantiates a new in-process COM object of type T
+// using class clsid.
+func CreateInstance[T Object](clsid *CLSID) (T, error) {
+ return createInstanceWithCLSCTX[T](clsid, coCLSCTX_INPROC_SERVER)
+}
+
+// CreateInstance instantiates a new local, out-of-process COM object of type T
+// using class clsid.
+func CreateOutOfProcessInstance[T Object](clsid *CLSID) (T, error) {
+ return createInstanceWithCLSCTX[T](clsid, coCLSCTX_LOCAL_SERVER)
+}
diff --git a/util/wingoes/com/automation/automation.go b/util/wingoes/com/automation/automation.go
new file mode 100644
index 0000000000000..3689155af34d2
--- /dev/null
+++ b/util/wingoes/com/automation/automation.go
@@ -0,0 +1,7 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+//go:build windows
+
+// Package automation provides essential types for interacting with COM Automation (IDispatch).
+package automation
diff --git a/util/wingoes/com/automation/mksyscall.go b/util/wingoes/com/automation/mksyscall.go
new file mode 100644
index 0000000000000..38c3091aff1c4
--- /dev/null
+++ b/util/wingoes/com/automation/mksyscall.go
@@ -0,0 +1,14 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+//go:build windows
+
+package automation
+
+//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go mksyscall.go
+//go:generate go run golang.org/x/tools/cmd/goimports -w zsyscall_windows.go
+
+//sys sysAllocString(str *uint16) (ret BSTR) = oleaut32.SysAllocString
+//sys sysAllocStringLen(str *uint16, strLen uint32) (ret BSTR) = oleaut32.SysAllocStringLen
+//sys sysFreeString(bstr BSTR) = oleaut32.SysFreeString
+//sys sysStringLen(bstr BSTR) (ret uint32) = oleaut32.SysStringLen
diff --git a/util/wingoes/com/automation/types.go b/util/wingoes/com/automation/types.go
new file mode 100644
index 0000000000000..5c94fa74d8498
--- /dev/null
+++ b/util/wingoes/com/automation/types.go
@@ -0,0 +1,93 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+//go:build windows
+
+package automation
+
+import (
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+// BSTR is the string format used by COM Automation. They are not garbage
+// collected and must be explicitly closed when no longer needed.
+type BSTR uintptr
+
+// NewBSTR creates a new BSTR from string s.
+func NewBSTR(s string) BSTR {
+ buf, err := windows.UTF16FromString(s)
+ if err != nil {
+ return 0
+ }
+ return NewBSTRFromUTF16(buf)
+}
+
+// NewBSTR creates a new BSTR from slice us, which contains UTF-16 code units.
+func NewBSTRFromUTF16(us []uint16) BSTR {
+ if len(us) == 0 {
+ return 0
+ }
+ return sysAllocStringLen(unsafe.SliceData(us), uint32(len(us)))
+}
+
+// NewBSTR creates a new BSTR from up, a C-style string pointer to UTF-16 code units.
+func NewBSTRFromUTF16Ptr(up *uint16) BSTR {
+ if up == nil {
+ return 0
+ }
+ return sysAllocString(up)
+}
+
+// Len returns the length of bs in code units.
+func (bs *BSTR) Len() uint32 {
+ return sysStringLen(*bs)
+}
+
+// String returns the contents of bs as a Go string.
+func (bs *BSTR) String() string {
+ return windows.UTF16ToString(bs.toUTF16())
+}
+
+// toUTF16 is unsafe for general use because it returns a pointer that is
+// not managed by the Go GC.
+func (bs *BSTR) toUTF16() []uint16 {
+ return unsafe.Slice(bs.toUTF16Ptr(), bs.Len())
+}
+
+// ToUTF16 returns the contents of bs as a slice of UTF-16 code units.
+func (bs *BSTR) ToUTF16() []uint16 {
+ return append([]uint16{}, bs.toUTF16()...)
+}
+
+// toUTF16Ptr is unsafe for general use because it returns a pointer that is
+// not managed by the Go GC.
+func (bs *BSTR) toUTF16Ptr() *uint16 {
+ return (*uint16)(unsafe.Pointer(*bs))
+}
+
+// ToUTF16 returns the contents of bs as C-style string pointer to UTF-16 code units.
+func (bs *BSTR) ToUTF16Ptr() *uint16 {
+ return unsafe.SliceData(bs.ToUTF16())
+}
+
+// Clone creates a clone of bs whose lifetime becomes independent of the original.
+// It must be explicitly closed when no longer needed.
+func (bs *BSTR) Clone() BSTR {
+ return sysAllocStringLen(bs.toUTF16Ptr(), bs.Len())
+}
+
+// IsNil returns true if bs holds a nil value.
+func (bs *BSTR) IsNil() bool {
+ return *bs == 0
+}
+
+// Close frees bs.
+func (bs *BSTR) Close() error {
+ if *bs != 0 {
+ sysFreeString(*bs)
+ *bs = 0
+ }
+ return nil
+}
diff --git a/util/wingoes/com/automation/zsyscall_windows.go b/util/wingoes/com/automation/zsyscall_windows.go
new file mode 100644
index 0000000000000..266f58d1b4dfe
--- /dev/null
+++ b/util/wingoes/com/automation/zsyscall_windows.go
@@ -0,0 +1,70 @@
+// Code generated by 'go generate'; DO NOT EDIT.
+
+package automation
+
+import (
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+ errnoERROR_IO_PENDING = 997
+)
+
+var (
+ errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+ errERROR_EINVAL error = syscall.EINVAL
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+ switch e {
+ case 0:
+ return errERROR_EINVAL
+ case errnoERROR_IO_PENDING:
+ return errERROR_IO_PENDING
+ }
+ // TODO: add more here, after collecting data on the common
+ // error values see on Windows. (perhaps when running
+ // all.bat?)
+ return e
+}
+
+var (
+ modoleaut32 = windows.NewLazySystemDLL("oleaut32.dll")
+
+ procSysAllocString = modoleaut32.NewProc("SysAllocString")
+ procSysAllocStringLen = modoleaut32.NewProc("SysAllocStringLen")
+ procSysFreeString = modoleaut32.NewProc("SysFreeString")
+ procSysStringLen = modoleaut32.NewProc("SysStringLen")
+)
+
+func sysAllocString(str *uint16) (ret BSTR) {
+ r0, _, _ := syscall.Syscall(procSysAllocString.Addr(), 1, uintptr(unsafe.Pointer(str)), 0, 0)
+ ret = BSTR(r0)
+ return
+}
+
+func sysAllocStringLen(str *uint16, strLen uint32) (ret BSTR) {
+ r0, _, _ := syscall.Syscall(procSysAllocStringLen.Addr(), 2, uintptr(unsafe.Pointer(str)), uintptr(strLen), 0)
+ ret = BSTR(r0)
+ return
+}
+
+func sysFreeString(bstr BSTR) {
+ syscall.Syscall(procSysFreeString.Addr(), 1, uintptr(bstr), 0, 0)
+ return
+}
+
+func sysStringLen(bstr BSTR) (ret uint32) {
+ r0, _, _ := syscall.Syscall(procSysStringLen.Addr(), 1, uintptr(bstr), 0, 0)
+ ret = uint32(r0)
+ return
+}
diff --git a/util/wingoes/com/com.go b/util/wingoes/com/com.go
new file mode 100644
index 0000000000000..33f1071d7ca5e
--- /dev/null
+++ b/util/wingoes/com/com.go
@@ -0,0 +1,9 @@
+// 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 windows
+
+// Package com provides an idiomatic foundation for instantiating and invoking
+// COM objects.
+package com
diff --git a/util/wingoes/com/globalopts.go b/util/wingoes/com/globalopts.go
new file mode 100644
index 0000000000000..9dcdbe4bdafea
--- /dev/null
+++ b/util/wingoes/com/globalopts.go
@@ -0,0 +1,120 @@
+// 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 windows
+
+package com
+
+import (
+ "runtime"
+ "syscall"
+ "unsafe"
+
+ "github.com/metacubex/tailscale/util/wingoes"
+)
+
+var (
+ CLSID_GlobalOptions = &CLSID{0x0000034B, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}
+)
+
+var (
+ IID_IGlobalOptions = &IID{0x0000015B, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}
+)
+
+type GLOBALOPT_PROPERTIES int32
+
+const (
+ COMGLB_EXCEPTION_HANDLING = GLOBALOPT_PROPERTIES(1)
+ COMGLB_APPID = GLOBALOPT_PROPERTIES(2)
+ COMGLB_RPC_THREADPOOL_SETTING = GLOBALOPT_PROPERTIES(3)
+ COMGLB_RO_SETTINGS = GLOBALOPT_PROPERTIES(4)
+ COMGLB_UNMARSHALING_POLICY = GLOBALOPT_PROPERTIES(5)
+)
+
+const (
+ COMGLB_EXCEPTION_HANDLE = 0
+ COMGLB_EXCEPTION_DONOT_HANDLE_FATAL = 1
+ COMGLB_EXCEPTION_DONOT_HANDLE = 1
+ COMGLB_EXCEPTION_DONOT_HANDLE_ANY = 2
+)
+
+// IGlobalOptionsABI represents the COM ABI for the IGlobalOptions interface.
+type IGlobalOptionsABI struct {
+ IUnknownABI
+}
+
+// GlobalOptions is the COM object used for setting global configuration settings
+// on the COM runtime. It must be called after COM runtime security has been
+// initialized, but before anything else "significant" is done using COM.
+type GlobalOptions struct {
+ GenericObject[IGlobalOptionsABI]
+}
+
+func (abi *IGlobalOptionsABI) Set(prop GLOBALOPT_PROPERTIES, value uintptr) error {
+ method := unsafe.Slice(abi.Vtbl, 5)[3]
+
+ rc, _, _ := syscall.Syscall(
+ method,
+ 3,
+ uintptr(unsafe.Pointer(abi)),
+ uintptr(prop),
+ value,
+ )
+ if e := wingoes.ErrorFromHRESULT(wingoes.HRESULT(rc)); e.Failed() {
+ return e
+ }
+
+ return nil
+}
+
+func (abi *IGlobalOptionsABI) Query(prop GLOBALOPT_PROPERTIES) (uintptr, error) {
+ var result uintptr
+ method := unsafe.Slice(abi.Vtbl, 5)[4]
+
+ rc, _, _ := syscall.Syscall(
+ method,
+ 3,
+ uintptr(unsafe.Pointer(abi)),
+ uintptr(prop),
+ uintptr(unsafe.Pointer(&result)),
+ )
+ if e := wingoes.ErrorFromHRESULT(wingoes.HRESULT(rc)); e.Failed() {
+ return 0, e
+ }
+
+ return result, nil
+}
+
+func (o GlobalOptions) IID() *IID {
+ return IID_IGlobalOptions
+}
+
+func (o GlobalOptions) Make(r ABIReceiver) any {
+ if r == nil {
+ return GlobalOptions{}
+ }
+
+ runtime.SetFinalizer(r, ReleaseABI)
+
+ pp := (**IGlobalOptionsABI)(unsafe.Pointer(r))
+ return GlobalOptions{GenericObject[IGlobalOptionsABI]{Pp: pp}}
+}
+
+// UnsafeUnwrap returns the underlying IGlobalOptionsABI of the object. As the
+// name implies, this is unsafe -- you had better know what you are doing!
+func (o GlobalOptions) UnsafeUnwrap() *IGlobalOptionsABI {
+ return *(o.Pp)
+}
+
+// Set sets the global property prop to value.
+func (o GlobalOptions) Set(prop GLOBALOPT_PROPERTIES, value uintptr) error {
+ p := *(o.Pp)
+ return p.Set(prop, value)
+}
+
+// Query returns the value of global property prop.
+func (o GlobalOptions) Query(prop GLOBALOPT_PROPERTIES) (uintptr, error) {
+ p := *(o.Pp)
+ return p.Query(prop)
+}
diff --git a/util/wingoes/com/guid.go b/util/wingoes/com/guid.go
new file mode 100644
index 0000000000000..6cac4345b9448
--- /dev/null
+++ b/util/wingoes/com/guid.go
@@ -0,0 +1,22 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+package com
+
+import (
+ "github.com/metacubex/tailscale/util/wingoes"
+)
+
+// We intentionally export these types across all GOOSes
+
+// IID is a GUID that represents an interface ID.
+type IID wingoes.GUID
+
+// CLSID is a GUID that represents a class ID.
+type CLSID wingoes.GUID
+
+// AppID is a GUID that represents an application ID.
+type AppID wingoes.GUID
+
+// ServiceID is a GUID that represents a service ID.
+type ServiceID wingoes.GUID
diff --git a/util/wingoes/com/interface.go b/util/wingoes/com/interface.go
new file mode 100644
index 0000000000000..c63c4e7be4a9c
--- /dev/null
+++ b/util/wingoes/com/interface.go
@@ -0,0 +1,112 @@
+// 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 windows
+
+package com
+
+import (
+ "syscall"
+ "unsafe"
+
+ "github.com/metacubex/tailscale/util/wingoes"
+)
+
+// IUnknown is the base COM interface.
+type IUnknown interface {
+ QueryInterface(iid *IID) (IUnknown, error)
+ AddRef() int32
+ Release() int32
+}
+
+// This is a sentinel that indicates that a struct implements the COM ABI.
+// Only IUnknownABI should implement this.
+type hasVTable interface {
+ vtable() *uintptr
+}
+
+// IUnknownABI describes the ABI of the IUnknown interface (ie, a vtable).
+type IUnknownABI struct {
+ Vtbl *uintptr
+}
+
+func (abi IUnknownABI) vtable() *uintptr {
+ return abi.Vtbl
+}
+
+// ABI is a type constraint allowing the COM ABI, or any struct that embeds it.
+type ABI interface {
+ hasVTable
+}
+
+// PUnknown is a type constraint for types that both implement IUnknown and
+// are also pointers to a COM ABI.
+type PUnknown[A ABI] interface {
+ IUnknown
+ *A
+}
+
+// ABIReceiver is the type that receives COM interface pointers from COM
+// method outparams.
+type ABIReceiver **IUnknownABI
+
+// NewABIReceiver instantiates a new ABIReceiver.
+func NewABIReceiver() ABIReceiver {
+ return ABIReceiver(new(*IUnknownABI))
+}
+
+// ReleaseABI releases a COM object. Finalizers must always invoke this function
+// when destroying COM interfaces.
+func ReleaseABI(p **IUnknownABI) {
+ (*p).Release()
+}
+
+// QueryInterface implements the QueryInterface call for a COM interface pointer.
+// iid is the desired interface ID.
+func (abi *IUnknownABI) QueryInterface(iid *IID) (IUnknown, error) {
+ var punk *IUnknownABI
+
+ r, _, _ := syscall.Syscall(
+ *(abi.Vtbl),
+ 3,
+ uintptr(unsafe.Pointer(abi)),
+ uintptr(unsafe.Pointer(iid)),
+ uintptr(unsafe.Pointer(&punk)),
+ )
+ if e := wingoes.ErrorFromHRESULT(wingoes.HRESULT(r)); e.Failed() {
+ return nil, e
+ }
+
+ return punk, nil
+}
+
+// AddRef implements the AddRef call for a COM interface pointer.
+func (abi *IUnknownABI) AddRef() int32 {
+ method := unsafe.Slice(abi.Vtbl, 3)[1]
+
+ r, _, _ := syscall.Syscall(
+ method,
+ 1,
+ uintptr(unsafe.Pointer(abi)),
+ 0,
+ 0,
+ )
+
+ return int32(r)
+}
+
+// Release implements the Release call for a COM interface pointer.
+func (abi *IUnknownABI) Release() int32 {
+ method := unsafe.Slice(abi.Vtbl, 3)[2]
+
+ r, _, _ := syscall.Syscall(
+ method,
+ 1,
+ uintptr(unsafe.Pointer(abi)),
+ 0,
+ 0,
+ )
+
+ return int32(r)
+}
diff --git a/util/wingoes/com/mksyscall.go b/util/wingoes/com/mksyscall.go
new file mode 100644
index 0000000000000..f26be9687a95c
--- /dev/null
+++ b/util/wingoes/com/mksyscall.go
@@ -0,0 +1,25 @@
+// 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 windows
+
+package com
+
+//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go mksyscall.go
+//go:generate go run golang.org/x/tools/cmd/goimports -w zsyscall_windows.go
+
+//sys coCreateInstance(clsid *CLSID, unkOuter *IUnknownABI, clsctx coCLSCTX, iid *IID, ppv **IUnknownABI) (hr wingoes.HRESULT) = ole32.CoCreateInstance
+//sys coGetApartmentType(aptType *coAPTTYPE, qual *coAPTTYPEQUALIFIER) (hr wingoes.HRESULT) = ole32.CoGetApartmentType
+//sys coInitializeEx(reserved uintptr, flags uint32) (hr wingoes.HRESULT) = ole32.CoInitializeEx
+//sys coInitializeSecurity(sd *windows.SECURITY_DESCRIPTOR, authSvcLen int32, authSvc *soleAuthenticationService, reserved1 uintptr, authnLevel rpcAuthnLevel, impLevel rpcImpersonationLevel, authList *soleAuthenticationList, capabilities authCapabilities, reserved2 uintptr) (hr wingoes.HRESULT) = ole32.CoInitializeSecurity
+
+// We don't use '?' on coIncrementMTAUsage because that doesn't play nicely with HRESULTs. We manually check for its presence in process.go
+//sys coIncrementMTAUsage(cookie *coMTAUsageCookie) (hr wingoes.HRESULT) = ole32.CoIncrementMTAUsage
+
+// Technically this proc is __cdecl, but since it has 0 args this doesn't matter
+//sys setOaNoCache() = oleaut32.SetOaNoCache
+
+// For the following two functions we use IUnknownABI instead of IStreamABI because it makes the callsites cleaner.
+//sys shCreateMemStream(pInit *byte, cbInit uint32) (stream *IUnknownABI) = shlwapi.SHCreateMemStream
+//sys createStreamOnHGlobal(hglobal internal.HGLOBAL, deleteOnRelease bool, stream **IUnknownABI) (hr wingoes.HRESULT) = ole32.CreateStreamOnHGlobal
diff --git a/util/wingoes/com/object.go b/util/wingoes/com/object.go
new file mode 100644
index 0000000000000..3f18d31512886
--- /dev/null
+++ b/util/wingoes/com/object.go
@@ -0,0 +1,89 @@
+// 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 windows
+
+package com
+
+import (
+ "fmt"
+ "unsafe"
+)
+
+// GenericObject is a struct that wraps any interface that implements the COM ABI.
+type GenericObject[A ABI] struct {
+ Pp **A
+}
+
+func (o GenericObject[A]) pp() **A {
+ return o.Pp
+}
+
+// Object is the interface that all garbage-collected instances of COM interfaces
+// must implement.
+type Object interface {
+ // IID returns the interface ID for the object. This method may be called
+ // on Objects containing the zero value, so its return value must not depend
+ // on the value of the method's receiver.
+ IID() *IID
+
+ // Make converts r to an instance of a garbage-collected COM object. The type
+ // of its return value must always match the type of the method's receiver.
+ Make(r ABIReceiver) any
+}
+
+// EmbedsGenericObject is a type constraint matching any struct that embeds
+// a GenericObject[A].
+type EmbedsGenericObject[A ABI] interface {
+ Object
+ ~struct{ GenericObject[A] }
+ pp() **A
+}
+
+// As casts obj to an object of type O, or panics if obj cannot be converted to O.
+func As[O Object, A ABI, PU PUnknown[A], E EmbedsGenericObject[A]](obj E) O {
+ o, err := TryAs[O, A, PU](obj)
+ if err != nil {
+ panic(fmt.Sprintf("wingoes.com.As error: %v", err))
+ }
+ return o
+}
+
+// TryAs casts obj to an object of type O, or returns an error if obj cannot be
+// converted to O.
+func TryAs[O Object, A ABI, PU PUnknown[A], E EmbedsGenericObject[A]](obj E) (O, error) {
+ var o O
+
+ iid := o.IID()
+ p := (PU)(unsafe.Pointer(*(obj.pp())))
+
+ i, err := p.QueryInterface(iid)
+ if err != nil {
+ return o, err
+ }
+
+ r := NewABIReceiver()
+ *r = i.(*IUnknownABI)
+
+ return o.Make(r).(O), nil
+}
+
+// IsSameObject returns true when both l and r refer to the same underlying object.
+func IsSameObject[AL, AR ABI, PL PUnknown[AL], PR PUnknown[AR], EL EmbedsGenericObject[AL], ER EmbedsGenericObject[AR]](l EL, r ER) bool {
+ pl := (PL)(unsafe.Pointer(*(l.pp())))
+ ul, err := pl.QueryInterface(IID_IUnknown)
+ if err != nil {
+ return false
+ }
+ defer ul.Release()
+
+ pr := (PR)(unsafe.Pointer(*(r.pp())))
+ ur, err := pr.QueryInterface(IID_IUnknown)
+ if err != nil {
+ return false
+ }
+ defer ur.Release()
+
+ return ul.(*IUnknownABI) == ur.(*IUnknownABI)
+}
diff --git a/util/wingoes/com/object_test.go b/util/wingoes/com/object_test.go
new file mode 100644
index 0000000000000..c964d0bd4ccdf
--- /dev/null
+++ b/util/wingoes/com/object_test.go
@@ -0,0 +1,32 @@
+//go:build ignore
+
+// Copyright (c) 2022 Aaron Klotz & AUTHORS. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package com
+
+import (
+ "testing"
+)
+
+func TestTryAs(t *testing.T) {
+ globalOpts, err := CreateInstance[GlobalOptions](CLSID_GlobalOptions)
+ if err != nil {
+ t.Fatalf("CreateInstance(CLSID_GlobalOptions) error: %v", err)
+ }
+
+ unk, err := TryAs[ObjectBase](globalOpts)
+ if err != nil {
+ t.Fatalf("TryAs(ObjectBase) error: %v", err)
+ }
+
+ globalOpts2, err := TryAs[GlobalOptions](unk)
+ if err != nil {
+ t.Fatalf("TryAs(GlobalOptions) error: %v", err)
+ }
+
+ if globalOpts.UnsafeUnwrap() != globalOpts2.UnsafeUnwrap() {
+ t.Errorf("globalOpts ABI != globalOpts2 ABI")
+ }
+}
diff --git a/util/wingoes/com/process.go b/util/wingoes/com/process.go
new file mode 100644
index 0000000000000..4429fa2650015
--- /dev/null
+++ b/util/wingoes/com/process.go
@@ -0,0 +1,268 @@
+// 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 windows
+
+package com
+
+import (
+ "os"
+ "runtime"
+
+ "github.com/metacubex/tailscale/util/wingoes"
+ "golang.org/x/sys/windows"
+)
+
+// ProcessType is an enumeration that specifies the type of the current process
+// when calling StartRuntime.
+type ProcessType uint
+
+const (
+ // ConsoleApp is a text-mode Windows program.
+ ConsoleApp = ProcessType(iota)
+ // Service is a Windows service.
+ Service
+ // GUIApp is a GUI-mode Windows program.
+ GUIApp
+
+ // Note: Even though this implementation is not yet internally distinguishing
+ // between console apps and services, this distinction may be useful in the
+ // future. For example, a service could receive more restrictive default
+ // security settings than a console app.
+ // Having this as part of the API now avoids future breakage.
+)
+
+// StartRuntime permanently initializes COM for the remaining lifetime of the
+// current process. To avoid errors, it should be called as early as possible
+// during program initialization. When processType == GUIApp, the current
+// OS thread becomes permanently locked to the current goroutine; any subsequent
+// GUI *must* be created on the same OS thread.
+// An excellent location to call StartRuntime is in the init function of the
+// main package.
+func StartRuntime(processType ProcessType) error {
+ return StartRuntimeWithDACL(processType, nil)
+}
+
+// StartRuntimeWithDACL permanently initializes COM for the remaining lifetime
+// of the current process. To avoid errors, it should be called as early as
+// possible during program initialization. When processType == GUIApp, the
+// current OS thread becomes permanently locked to the current goroutine; any
+// subsequent GUI *must* be created on the same OS thread. dacl is an ACL that
+// controls access of other processes connecting to the current process over COM.
+// For further information about COM access control, look up the COM_RIGHTS_*
+// access flags in the Windows developer documentation.
+// An excellent location to call StartRuntimeWithDACL is in the init function of
+// the main package.
+func StartRuntimeWithDACL(processType ProcessType, dacl *windows.ACL) error {
+ runtime.LockOSThread()
+
+ defer func() {
+ // When initializing for non-GUI processes, the OS thread may be unlocked
+ // upon return from this function.
+ if processType != GUIApp {
+ runtime.UnlockOSThread()
+ }
+ }()
+
+ switch processType {
+ case ConsoleApp, Service:
+ // Just start the MTA implicitly.
+ if err := startMTAImplicitly(); err != nil {
+ return err
+ }
+ case GUIApp:
+ // For GUIApp, we want the current OS thread to enter a single-threaded
+ // apartment (STA). However, we want all other OS threads to reside inside
+ // a multi-threaded apartment (MTA). The way to so this is to first start
+ // the MTA implicitly, affecting all OS threads who have not yet explicitly
+ // entered a COM apartment...
+ if err := startMTAImplicitly(); err != nil {
+ runtime.UnlockOSThread()
+ return err
+ }
+ // ...and then subsequently explicitly enter a STA on this OS thread, which
+ // automatically removes this OS thread from the MTA.
+ if err := enterSTA(); err != nil {
+ runtime.UnlockOSThread()
+ return err
+ }
+ // From this point forward, we must never unlock the OS thread.
+ default:
+ return os.ErrInvalid
+ }
+
+ // Order is extremely important here: initSecurity must be called immediately
+ // after apartments are set up, but before doing anything else.
+ if err := initSecurity(dacl); err != nil {
+ return err
+ }
+
+ // By default, for compatibility reasons, COM internally sets a catch-all
+ // exception handler at its API boundary. This is dangerous, so we override it.
+ // This work must happen after security settings are initialized, but before
+ // anything "significant" is done with COM.
+ globalOpts, err := CreateInstance[GlobalOptions](CLSID_GlobalOptions)
+ if err != nil {
+ return err
+ }
+
+ err = globalOpts.Set(COMGLB_EXCEPTION_HANDLING, COMGLB_EXCEPTION_DONOT_HANDLE_ANY)
+
+ // The BSTR cache never invalidates itself, so we disable it unconditionally.
+ // We do this here to ensure that the BSTR cache is off before anything
+ // can possibly start using oleaut32.dll.
+ setOaNoCache()
+
+ return err
+}
+
+// startMTAImplicitly creates an implicit multi-threaded apartment (MTA) for
+// all threads in a process that do not otherwise explicitly enter a COM apartment.
+func startMTAImplicitly() error {
+ // CoIncrementMTAUsage is the modern API to use for creating the MTA implicitly,
+ // however we may fall back to a legacy mechanism when the former API is unavailable.
+ if err := procCoIncrementMTAUsage.Find(); err != nil {
+ return startMTAImplicitlyLegacy()
+ }
+
+ // We do not retain cookie beyond this function, as we have no intention of
+ // tearing any of this back down.
+ var cookie coMTAUsageCookie
+ hr := coIncrementMTAUsage(&cookie)
+ if e := wingoes.ErrorFromHRESULT(hr); e.Failed() {
+ return e
+ }
+
+ return nil
+}
+
+// startMTAImplicitlyLegacy works by having a background OS thread explicitly enter
+// the multi-threaded apartment. All other OS threads that have not explicitly
+// entered an apartment will become implicit members of that MTA. This function is
+// written assuming that the current OS thread has already been locked.
+func startMTAImplicitlyLegacy() error {
+ // We need to start the MTA on a background OS thread, HOWEVER we also want this
+ // to happen synchronously, so we wait on c for MTA initialization to complete.
+ c := make(chan error)
+ go bgMTASustainer(c)
+ return <-c
+}
+
+// bgMTASustainer locks the current goroutine to the current OS thread, enters
+// the COM multi-threaded apartment, and then blocks for the remainder of the
+// process's lifetime. It sends its result to c so that startMTAImplicitlyLegacy
+// can wait for the MTA to be ready before proceeding.
+func bgMTASustainer(c chan error) {
+ runtime.LockOSThread()
+ err := enterMTA()
+ c <- err
+ if err != nil {
+ // We didn't enter the MTA, so just unlock and bail.
+ runtime.UnlockOSThread()
+ return
+ }
+ select {}
+}
+
+// enterMTA causes the current OS thread to explicitly declare itself to be a
+// member of COM's multi-threaded apartment. Note that this function affects
+// thread-local state, so use carefully!
+func enterMTA() error {
+ return coInit(windows.COINIT_MULTITHREADED)
+}
+
+// enterSTA causes the current OS thread to create and enter a single-threaded
+// apartment. The current OS thread must be locked and remain locked for the
+// duration of the thread's time in the apartment. For our purposes, the calling
+// OS thread never leaves the STA, so it must effectively remain locked for
+// the remaining lifetime of the process. A single-threaded apartment should be
+// used if and only if an OS thread is going to be creating windows and pumping
+// messages; STAs are NOT generic containers for single-threaded COM code,
+// contrary to popular belief. Note that this function affects thread-local
+// state, so use carefully!
+func enterSTA() error {
+ return coInit(windows.COINIT_APARTMENTTHREADED)
+}
+
+// coInit is a wrapper for CoInitializeEx that properly handles the S_FALSE
+// error code (x/sys/windows.CoInitializeEx does not).
+func coInit(apartment uint32) error {
+ hr := coInitializeEx(0, apartment)
+ if e := wingoes.ErrorFromHRESULT(hr); e.Failed() {
+ return e
+ }
+
+ return nil
+}
+
+const (
+ authSvcCOMChooses = -1
+)
+
+// initSecurity initializes COM security using the ACL specified by dacl.
+// A nil dacl implies that a default ACL should be used instead.
+func initSecurity(dacl *windows.ACL) error {
+ sd, err := buildSecurityDescriptor(dacl)
+ if err != nil {
+ return err
+ }
+
+ caps := authCapNone
+ if sd == nil {
+ // For COM to fall back to system-wide defaults, we need to set this bit.
+ caps |= authCapAppID
+ }
+
+ hr := coInitializeSecurity(
+ sd,
+ authSvcCOMChooses,
+ nil, // authSvc (not used because previous arg is authSvcCOMChooses)
+ 0, // Reserved, must be 0
+ rpcAuthnLevelDefault,
+ rpcImpLevelIdentify,
+ nil, // authlist: use defaults
+ caps,
+ 0, // Reserved, must be 0
+ )
+ if e := wingoes.ErrorFromHRESULT(hr); e.Failed() {
+ return e
+ }
+
+ return nil
+}
+
+// buildSecurityDescriptor inserts dacl into a valid security descriptor for use
+// with CoInitializeSecurity. A nil dacl results in a nil security descriptor,
+// which we consider to be a valid "use defaults" sentinel.
+func buildSecurityDescriptor(dacl *windows.ACL) (*windows.SECURITY_DESCRIPTOR, error) {
+ if dacl == nil {
+ // Not an error, just use defaults.
+ return nil, nil
+ }
+
+ sd, err := windows.NewSecurityDescriptor()
+ if err != nil {
+ return nil, err
+ }
+
+ if err := sd.SetDACL(dacl, true, false); err != nil {
+ return nil, err
+ }
+
+ // CoInitializeSecurity will fail unless the SD's owner and group are both set.
+ userSIDs, err := wingoes.CurrentProcessUserSIDs()
+ if err != nil {
+ return nil, err
+ }
+
+ if err := sd.SetOwner(userSIDs.User, false); err != nil {
+ return nil, err
+ }
+
+ if err := sd.SetGroup(userSIDs.PrimaryGroup, false); err != nil {
+ return nil, err
+ }
+
+ return sd, nil
+}
diff --git a/util/wingoes/com/process_test.go b/util/wingoes/com/process_test.go
new file mode 100644
index 0000000000000..2c1f7214a1acc
--- /dev/null
+++ b/util/wingoes/com/process_test.go
@@ -0,0 +1,40 @@
+//go:build ignore
+
+// 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.
+
+package com
+
+import (
+ "strings"
+ "testing"
+)
+
+// Each of these tests needs to run as their own process, since StartRuntime
+// performs process-wide initialization that is permanent for the remaining
+// life of the process.
+
+func TestGUI(t *testing.T) {
+ output := strings.TrimSpace(runTestProg(t, "testprocessruntime", "GUIApp"))
+ want := "OK"
+ if output != want {
+ t.Errorf("%s\n", strings.TrimPrefix(output, "error: "))
+ }
+}
+
+func TestGUIDACL(t *testing.T) {
+ output := strings.TrimSpace(runTestProg(t, "testprocessruntime", "GUIAppDACL"))
+ want := "OK"
+ if output != want {
+ t.Errorf("%s\n", strings.TrimPrefix(output, "error: "))
+ }
+}
+
+func TestNonGUI(t *testing.T) {
+ output := strings.TrimSpace(runTestProg(t, "testprocessruntime", "NonGUIApp"))
+ want := "OK"
+ if output != want {
+ t.Errorf("%s\n", strings.TrimPrefix(output, "error: "))
+ }
+}
diff --git a/util/wingoes/com/stream.go b/util/wingoes/com/stream.go
new file mode 100644
index 0000000000000..c3cafcabfaf00
--- /dev/null
+++ b/util/wingoes/com/stream.go
@@ -0,0 +1,389 @@
+// Copyright (c) 2023 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 windows
+
+package com
+
+import (
+ "io"
+ "runtime"
+ "syscall"
+ "unsafe"
+
+ "github.com/metacubex/tailscale/util/wingoes"
+ "github.com/metacubex/tailscale/util/wingoes/internal"
+ "golang.org/x/sys/windows"
+)
+
+var (
+ IID_ISequentialStream = &IID{0x0C733A30, 0x2A1C, 0x11CE, [8]byte{0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D}}
+ IID_IStream = &IID{0x0000000C, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}
+)
+
+type STGC uint32
+
+const (
+ STGC_DEFAULT = STGC(0)
+ STGC_OVERWRITE = STGC(1)
+ STGC_ONLYIFCURRENT = STGC(2)
+ STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE = STGC(4)
+ STGC_CONSOLIDATE = STGC(8)
+)
+
+type LOCKTYPE uint32
+
+const (
+ LOCK_WRITE = LOCKTYPE(1)
+ LOCK_EXCLUSIVE = LOCKTYPE(2)
+ LOCK_ONLYONCE = LOCKTYPE(4)
+)
+
+type STGTY uint32
+
+const (
+ STGTY_STORAGE = STGTY(1)
+ STGTY_STREAM = STGTY(2)
+ STGTY_LOCKBYTES = STGTY(3)
+ STGTY_PROPERTY = STGTY(4)
+)
+
+type STATFLAG uint32
+
+const (
+ STATFLAG_DEFAULT = STATFLAG(0)
+ STATFLAG_NONAME = STATFLAG(1)
+ STATFLAG_NOOPEN = STATFLAG(2)
+)
+
+type STATSTG struct {
+ Name COMAllocatedString
+ Type STGTY
+ Size uint64
+ MTime windows.Filetime
+ CTime windows.Filetime
+ ATime windows.Filetime
+ Mode uint32
+ LocksSupported LOCKTYPE
+ ClsID CLSID
+ _ uint32 // StateBits
+ _ uint32 // reserved
+}
+
+func (st *STATSTG) Close() error {
+ return st.Name.Close()
+}
+
+type ISequentialStreamABI struct {
+ IUnknownABI
+}
+
+type IStreamABI struct {
+ ISequentialStreamABI
+}
+
+type SequentialStream struct {
+ GenericObject[ISequentialStreamABI]
+}
+
+type Stream struct {
+ GenericObject[IStreamABI]
+}
+
+func (abi *ISequentialStreamABI) Read(p []byte) (int, error) {
+ if len(p) > maxStreamRWLen {
+ p = p[:maxStreamRWLen]
+ }
+
+ var cbRead uint32
+ method := unsafe.Slice(abi.Vtbl, 5)[3]
+
+ rc, _, _ := syscall.SyscallN(
+ method,
+ uintptr(unsafe.Pointer(abi)),
+ uintptr(unsafe.Pointer(unsafe.SliceData(p))),
+ uintptr(uint32(len(p))),
+ uintptr(unsafe.Pointer(&cbRead)),
+ )
+ n := int(cbRead)
+ e := wingoes.ErrorFromHRESULT(wingoes.HRESULT(rc))
+ if e.Failed() {
+ return n, e
+ }
+
+ // Various implementations of IStream handle EOF differently. We need to
+ // deal with both.
+ if e.AsHRESULT() == wingoes.S_FALSE || (n == 0 && len(p) > 0) {
+ return n, io.EOF
+ }
+
+ return n, nil
+}
+
+func (abi *ISequentialStreamABI) Write(p []byte) (int, error) {
+ w := p
+ if len(w) > maxStreamRWLen {
+ w = w[:maxStreamRWLen]
+ }
+
+ var cbWritten uint32
+ method := unsafe.Slice(abi.Vtbl, 5)[4]
+
+ rc, _, _ := syscall.SyscallN(
+ method,
+ uintptr(unsafe.Pointer(abi)),
+ uintptr(unsafe.Pointer(unsafe.SliceData(w))),
+ uintptr(uint32(len(w))),
+ uintptr(unsafe.Pointer(&cbWritten)),
+ )
+ n := int(cbWritten)
+ if e := wingoes.ErrorFromHRESULT(wingoes.HRESULT(rc)); e.Failed() {
+ return n, e
+ }
+
+ // Need this to satisfy Writer.
+ if n < len(p) {
+ return n, io.ErrShortWrite
+ }
+
+ return n, nil
+}
+
+func (o SequentialStream) IID() *IID {
+ return IID_ISequentialStream
+}
+
+func (o SequentialStream) Make(r ABIReceiver) any {
+ if r == nil {
+ return SequentialStream{}
+ }
+
+ runtime.SetFinalizer(r, ReleaseABI)
+
+ pp := (**ISequentialStreamABI)(unsafe.Pointer(r))
+ return SequentialStream{GenericObject[ISequentialStreamABI]{Pp: pp}}
+}
+
+func (o SequentialStream) UnsafeUnwrap() *ISequentialStreamABI {
+ return *(o.Pp)
+}
+
+func (o SequentialStream) Read(b []byte) (n int, err error) {
+ p := *(o.Pp)
+ return p.Read(b)
+}
+
+func (o SequentialStream) Write(b []byte) (int, error) {
+ p := *(o.Pp)
+ return p.Write(b)
+}
+
+func (abi *IStreamABI) Commit(flags STGC) error {
+ method := unsafe.Slice(abi.Vtbl, 14)[8]
+
+ rc, _, _ := syscall.SyscallN(
+ method,
+ uintptr(unsafe.Pointer(abi)),
+ uintptr(flags),
+ )
+ if e := wingoes.ErrorFromHRESULT(wingoes.HRESULT(rc)); e.Failed() {
+ return e
+ }
+
+ return nil
+}
+
+func (abi *IStreamABI) Revert() error {
+ method := unsafe.Slice(abi.Vtbl, 14)[9]
+
+ rc, _, _ := syscall.SyscallN(
+ method,
+ uintptr(unsafe.Pointer(abi)),
+ )
+
+ if e := wingoes.ErrorFromHRESULT(wingoes.HRESULT(rc)); e.Failed() {
+ return e
+ }
+
+ return nil
+}
+
+func (abi *IStreamABI) Stat(flags STATFLAG) (*STATSTG, error) {
+ result := new(STATSTG)
+ method := unsafe.Slice(abi.Vtbl, 14)[12]
+
+ rc, _, _ := syscall.SyscallN(
+ method,
+ uintptr(unsafe.Pointer(abi)),
+ uintptr(unsafe.Pointer(result)),
+ uintptr(flags),
+ )
+ if e := wingoes.ErrorFromHRESULT(wingoes.HRESULT(rc)); e.Failed() {
+ return nil, e
+ }
+
+ return result, nil
+}
+
+func (abi *IStreamABI) Clone() (result *IUnknownABI, _ error) {
+ method := unsafe.Slice(abi.Vtbl, 14)[13]
+
+ rc, _, _ := syscall.SyscallN(
+ method,
+ uintptr(unsafe.Pointer(abi)),
+ uintptr(unsafe.Pointer(&result)),
+ )
+ if e := wingoes.ErrorFromHRESULT(wingoes.HRESULT(rc)); e.Failed() {
+ return nil, e
+ }
+
+ return result, nil
+}
+
+func (o Stream) IID() *IID {
+ return IID_IStream
+}
+
+func (o Stream) Make(r ABIReceiver) any {
+ if r == nil {
+ return Stream{}
+ }
+
+ runtime.SetFinalizer(r, ReleaseABI)
+
+ pp := (**IStreamABI)(unsafe.Pointer(r))
+ return Stream{GenericObject[IStreamABI]{Pp: pp}}
+}
+
+func (o Stream) UnsafeUnwrap() *IStreamABI {
+ return *(o.Pp)
+}
+
+func (o Stream) Read(buf []byte) (int, error) {
+ p := *(o.Pp)
+ return p.Read(buf)
+}
+
+func (o Stream) Write(buf []byte) (int, error) {
+ p := *(o.Pp)
+ return p.Write(buf)
+}
+
+func (o Stream) Seek(offset int64, whence int) (n int64, _ error) {
+ p := *(o.Pp)
+ return p.Seek(offset, whence)
+}
+
+func (o Stream) SetSize(newSize uint64) error {
+ p := *(o.Pp)
+ return p.SetSize(newSize)
+}
+
+func (o Stream) CopyTo(dest Stream, numBytesToCopy uint64) (bytesRead, bytesWritten uint64, _ error) {
+ p := *(o.Pp)
+ return p.CopyTo(dest.UnsafeUnwrap(), numBytesToCopy)
+}
+
+func (o Stream) Commit(flags STGC) error {
+ p := *(o.Pp)
+ return p.Commit(flags)
+}
+
+func (o Stream) Revert() error {
+ p := *(o.Pp)
+ return p.Revert()
+}
+
+func (o Stream) LockRegion(offset, numBytes uint64, lockType LOCKTYPE) error {
+ p := *(o.Pp)
+ return p.LockRegion(offset, numBytes, lockType)
+}
+
+func (o Stream) UnlockRegion(offset, numBytes uint64, lockType LOCKTYPE) error {
+ p := *(o.Pp)
+ return p.UnlockRegion(offset, numBytes, lockType)
+}
+
+func (o Stream) Stat(flags STATFLAG) (*STATSTG, error) {
+ p := *(o.Pp)
+ return p.Stat(flags)
+}
+
+func (o Stream) Clone() (result Stream, _ error) {
+ p := *(o.Pp)
+ punk, err := p.Clone()
+ if err != nil {
+ return result, err
+ }
+
+ return result.Make(&punk).(Stream), nil
+}
+
+const hrE_OUTOFMEMORY = wingoes.HRESULT(-((0x8007000E ^ 0xFFFFFFFF) + 1))
+
+// NewMemoryStream creates a new in-memory Stream object initially containing a
+// copy of initialBytes. Its seek pointer is guaranteed to reference the
+// beginning of the stream.
+func NewMemoryStream(initialBytes []byte) (result Stream, _ error) {
+ return newMemoryStreamInternal(initialBytes, false)
+}
+
+func newMemoryStreamInternal(initialBytes []byte, forceLegacy bool) (result Stream, _ error) {
+ if len(initialBytes) > maxStreamRWLen {
+ return result, wingoes.ErrorFromHRESULT(hrE_OUTOFMEMORY)
+ }
+
+ // SHCreateMemStream exists on Win7 but is not safe for us to use until Win8.
+ if forceLegacy || !wingoes.IsWin8OrGreater() {
+ return newMemoryStreamLegacy(initialBytes)
+ }
+
+ var base *byte
+ var length uint32
+ if l := uint32(len(initialBytes)); l > 0 {
+ base = unsafe.SliceData(initialBytes)
+ length = l
+ }
+
+ punk := shCreateMemStream(base, length)
+ if punk == nil {
+ return result, wingoes.ErrorFromHRESULT(hrE_OUTOFMEMORY)
+ }
+
+ obj := result.Make(&punk).(Stream)
+ if _, err := obj.Seek(0, io.SeekStart); err != nil {
+ return result, err
+ }
+
+ return obj, nil
+}
+
+func newMemoryStreamLegacy(initialBytes []byte) (result Stream, _ error) {
+ ppstream := NewABIReceiver()
+ hr := createStreamOnHGlobal(internal.HGLOBAL(0), true, ppstream)
+ if e := wingoes.ErrorFromHRESULT(hr); e.Failed() {
+ return result, e
+ }
+
+ obj := result.Make(ppstream).(Stream)
+
+ if err := obj.SetSize(uint64(len(initialBytes))); err != nil {
+ return result, err
+ }
+
+ if len(initialBytes) == 0 {
+ return obj, nil
+ }
+
+ _, err := obj.Write(initialBytes)
+ if err != nil {
+ return result, err
+ }
+
+ if _, err := obj.Seek(0, io.SeekStart); err != nil {
+ return result, err
+ }
+
+ return obj, nil
+}
diff --git a/util/wingoes/com/stream_386.go b/util/wingoes/com/stream_386.go
new file mode 100644
index 0000000000000..44d30adda462f
--- /dev/null
+++ b/util/wingoes/com/stream_386.go
@@ -0,0 +1,130 @@
+// Copyright (c) 2023 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 windows
+
+package com
+
+import (
+ "math"
+ "syscall"
+ "unsafe"
+
+ "github.com/metacubex/tailscale/util/wingoes"
+)
+
+const maxStreamRWLen = math.MaxInt32
+
+func (abi *IStreamABI) Seek(offset int64, whence int) (n int64, _ error) {
+ var hr wingoes.HRESULT
+ method := unsafe.Slice(abi.Vtbl, 14)[5]
+
+ words := (*[2]uintptr)(unsafe.Pointer(&offset))
+ rc, _, _ := syscall.SyscallN(
+ method,
+ uintptr(unsafe.Pointer(abi)),
+ words[0],
+ words[1],
+ uintptr(uint32(whence)),
+ uintptr(unsafe.Pointer(&n)),
+ )
+ hr = wingoes.HRESULT(rc)
+
+ if e := wingoes.ErrorFromHRESULT(hr); e.Failed() {
+ return 0, e
+ }
+
+ return n, nil
+}
+
+func (abi *IStreamABI) SetSize(newSize uint64) error {
+ var hr wingoes.HRESULT
+ method := unsafe.Slice(abi.Vtbl, 14)[6]
+
+ words := (*[2]uintptr)(unsafe.Pointer(&newSize))
+ rc, _, _ := syscall.SyscallN(
+ method,
+ uintptr(unsafe.Pointer(abi)),
+ words[0],
+ words[1],
+ )
+ hr = wingoes.HRESULT(rc)
+
+ if e := wingoes.ErrorFromHRESULT(hr); e.Failed() {
+ return e
+ }
+
+ return nil
+}
+
+func (abi *IStreamABI) CopyTo(dest *IStreamABI, numBytesToCopy uint64) (bytesRead, bytesWritten uint64, _ error) {
+ var hr wingoes.HRESULT
+ method := unsafe.Slice(abi.Vtbl, 14)[7]
+
+ words := (*[2]uintptr)(unsafe.Pointer(&numBytesToCopy))
+ rc, _, _ := syscall.SyscallN(
+ method,
+ uintptr(unsafe.Pointer(abi)),
+ uintptr(unsafe.Pointer(dest)),
+ words[0],
+ words[1],
+ uintptr(unsafe.Pointer(&bytesRead)),
+ uintptr(unsafe.Pointer(&bytesWritten)),
+ )
+ hr = wingoes.HRESULT(rc)
+
+ if e := wingoes.ErrorFromHRESULT(hr); e.Failed() {
+ return bytesRead, bytesWritten, e
+ }
+
+ return bytesRead, bytesWritten, nil
+}
+
+func (abi *IStreamABI) LockRegion(offset, numBytes uint64, lockType LOCKTYPE) error {
+ var hr wingoes.HRESULT
+ method := unsafe.Slice(abi.Vtbl, 14)[10]
+
+ oWords := (*[2]uintptr)(unsafe.Pointer(&offset))
+ nWords := (*[2]uintptr)(unsafe.Pointer(&numBytes))
+ rc, _, _ := syscall.SyscallN(
+ method,
+ uintptr(unsafe.Pointer(abi)),
+ oWords[0],
+ oWords[1],
+ nWords[0],
+ nWords[1],
+ uintptr(lockType),
+ )
+ hr = wingoes.HRESULT(rc)
+
+ if e := wingoes.ErrorFromHRESULT(hr); e.Failed() {
+ return e
+ }
+
+ return nil
+}
+
+func (abi *IStreamABI) UnlockRegion(offset, numBytes uint64, lockType LOCKTYPE) error {
+ var hr wingoes.HRESULT
+ method := unsafe.Slice(abi.Vtbl, 14)[11]
+
+ oWords := (*[2]uintptr)(unsafe.Pointer(&offset))
+ nWords := (*[2]uintptr)(unsafe.Pointer(&numBytes))
+ rc, _, _ := syscall.SyscallN(
+ method,
+ uintptr(unsafe.Pointer(abi)),
+ oWords[0],
+ oWords[1],
+ nWords[0],
+ nWords[1],
+ uintptr(lockType),
+ )
+ hr = wingoes.HRESULT(rc)
+
+ if e := wingoes.ErrorFromHRESULT(hr); e.Failed() {
+ return e
+ }
+
+ return nil
+}
diff --git a/util/wingoes/com/stream_not386.go b/util/wingoes/com/stream_not386.go
new file mode 100644
index 0000000000000..be5b6f6369df7
--- /dev/null
+++ b/util/wingoes/com/stream_not386.go
@@ -0,0 +1,116 @@
+// Copyright (c) 2023 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 windows && !386
+
+package com
+
+import (
+ "math"
+ "syscall"
+ "unsafe"
+
+ "github.com/metacubex/tailscale/util/wingoes"
+)
+
+const maxStreamRWLen = math.MaxUint32
+
+func (abi *IStreamABI) Seek(offset int64, whence int) (n int64, _ error) {
+ var hr wingoes.HRESULT
+ method := unsafe.Slice(abi.Vtbl, 14)[5]
+
+ rc, _, _ := syscall.SyscallN(
+ method,
+ uintptr(unsafe.Pointer(abi)),
+ uintptr(offset),
+ uintptr(uint32(whence)),
+ uintptr(unsafe.Pointer(&n)),
+ )
+ hr = wingoes.HRESULT(rc)
+
+ if e := wingoes.ErrorFromHRESULT(hr); e.Failed() {
+ return 0, e
+ }
+
+ return n, nil
+}
+
+func (abi *IStreamABI) SetSize(newSize uint64) error {
+ var hr wingoes.HRESULT
+ method := unsafe.Slice(abi.Vtbl, 14)[6]
+
+ rc, _, _ := syscall.SyscallN(
+ method,
+ uintptr(unsafe.Pointer(abi)),
+ uintptr(newSize),
+ )
+ hr = wingoes.HRESULT(rc)
+
+ if e := wingoes.ErrorFromHRESULT(hr); e.Failed() {
+ return e
+ }
+
+ return nil
+}
+
+func (abi *IStreamABI) CopyTo(dest *IStreamABI, numBytesToCopy uint64) (bytesRead, bytesWritten uint64, _ error) {
+ var hr wingoes.HRESULT
+ method := unsafe.Slice(abi.Vtbl, 14)[7]
+
+ rc, _, _ := syscall.SyscallN(
+ method,
+ uintptr(unsafe.Pointer(abi)),
+ uintptr(unsafe.Pointer(dest)),
+ uintptr(numBytesToCopy),
+ uintptr(unsafe.Pointer(&bytesRead)),
+ uintptr(unsafe.Pointer(&bytesWritten)),
+ )
+ hr = wingoes.HRESULT(rc)
+
+ if e := wingoes.ErrorFromHRESULT(hr); e.Failed() {
+ return bytesRead, bytesWritten, e
+ }
+
+ return bytesRead, bytesWritten, nil
+}
+
+func (abi *IStreamABI) LockRegion(offset, numBytes uint64, lockType LOCKTYPE) error {
+ var hr wingoes.HRESULT
+ method := unsafe.Slice(abi.Vtbl, 14)[10]
+
+ rc, _, _ := syscall.SyscallN(
+ method,
+ uintptr(unsafe.Pointer(abi)),
+ uintptr(offset),
+ uintptr(numBytes),
+ uintptr(lockType),
+ )
+ hr = wingoes.HRESULT(rc)
+
+ if e := wingoes.ErrorFromHRESULT(hr); e.Failed() {
+ return e
+ }
+
+ return nil
+}
+
+func (abi *IStreamABI) UnlockRegion(offset, numBytes uint64, lockType LOCKTYPE) error {
+ var hr wingoes.HRESULT
+ method := unsafe.Slice(abi.Vtbl, 14)[11]
+
+ rc, _, _ := syscall.SyscallN(
+ method,
+ uintptr(unsafe.Pointer(abi)),
+ uintptr(offset),
+ uintptr(numBytes),
+ uintptr(lockType),
+ )
+ hr = wingoes.HRESULT(rc)
+
+ if e := wingoes.ErrorFromHRESULT(hr); e.Failed() {
+ return e
+ }
+
+ return nil
+}
diff --git a/util/wingoes/com/stream_test.go b/util/wingoes/com/stream_test.go
new file mode 100644
index 0000000000000..9f13fa79932d6
--- /dev/null
+++ b/util/wingoes/com/stream_test.go
@@ -0,0 +1,249 @@
+//go:build ignore
+
+// Copyright (c) 2023 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.
+
+package com
+
+import (
+ "io"
+ "runtime"
+ "testing"
+
+ "golang.org/x/exp/slices"
+)
+
+func TestStream(t *testing.T) {
+ t.Run("Default", func(t *testing.T) { memoryStream(t, false) })
+ t.Run("Legacy", func(t *testing.T) { memoryStream(t, true) })
+}
+
+func memoryStream(t *testing.T, useLegacy bool) {
+ empty1, err := newMemoryStreamInternal(nil, useLegacy)
+ if err != nil {
+ t.Fatalf("Error calling NewMemoryStream(nil): %v", err)
+ }
+ size, err := getSize(empty1)
+ if err != nil {
+ t.Fatalf("Error calling getSize: %v", err)
+ }
+ if size != 0 {
+ t.Errorf("Unexpected size, got %d, want 0", size)
+ }
+
+ empty2, err := newMemoryStreamInternal([]byte{}, useLegacy)
+ if err != nil {
+ t.Fatalf("Error calling NewMemoryStream(nil): %v", err)
+ }
+ size, err = getSize(empty2)
+ if err != nil {
+ t.Fatalf("Error calling getSize: %v", err)
+ }
+ if size != 0 {
+ t.Errorf("Unexpected size, got %d, want 0", size)
+ }
+
+ // Only try this on supported 64-bit archs so that the test doesn't run the
+ // risk of crashing due to OOM.
+ if runtime.GOARCH != "386" {
+ tooBig := getTooBigSlice()
+ _, err = newMemoryStreamInternal(tooBig, useLegacy)
+ if err == nil {
+ t.Errorf("Unexpected success creating too-large memory stream")
+ }
+ }
+
+ values := makeTestBuf(16)
+ stream, err := newMemoryStreamInternal(values, useLegacy)
+ if err != nil {
+ t.Fatalf("Error calling NewMemoryStream(%d): %v", len(values), err)
+ }
+ size, err = getSize(stream)
+ if err != nil {
+ t.Fatalf("Error calling getSize: %v", err)
+ }
+ if size != uint64(len(values)) {
+ t.Errorf("Unexpected size, got %d, want %d", size, len(values))
+ }
+ pos, err := getSeekPos(stream)
+ if err != nil {
+ t.Fatalf("Error calling getSeekPos: %v", err)
+ }
+ if pos != 0 {
+ t.Errorf("Unexpected seek pos, got %d, want 0", pos)
+ }
+
+ readBuf := make([]byte, len(values))
+ nRead, err := stream.Read(readBuf)
+ if err != nil {
+ t.Fatalf("Unexpected error calling Read, got %v, want nil", err)
+ }
+ if nRead != len(readBuf) {
+ t.Errorf("Unexpected number of bytes read, got %v, want %v", nRead, len(readBuf))
+ }
+ if !slices.Equal(values, readBuf) {
+ t.Errorf("Slices not equal")
+ }
+
+ pos, err = getSeekPos(stream)
+ if err != nil {
+ t.Fatalf("Error calling getSeekPos: %v", err)
+ }
+ if pos != int64(len(values)) {
+ t.Errorf("Unexpected seek pos, got %d, want %d", pos, len(values))
+ }
+
+ nRead, err = stream.Read(readBuf)
+ if err != io.EOF {
+ t.Errorf("Unexpected error calling Read, got %v, want %v", err, io.EOF)
+ }
+ if !slices.Equal(values, readBuf) {
+ t.Errorf("Slices not equal")
+ }
+
+ pos, err = stream.Seek(0, io.SeekStart)
+ if err != nil {
+ t.Fatalf("Error calling Seek: %v", err)
+ }
+ if pos != 0 {
+ t.Errorf("Unexpected seek pos, got %d, want 0", pos)
+ }
+
+ // Chunked read with EOF
+ chunk1 := make([]byte, 4)
+ chunk2 := make([]byte, len(values))
+
+ nRead, err = stream.Read(chunk1)
+ if err != nil {
+ t.Fatalf("Unexpected error calling Read, got %v, want nil", err)
+ }
+ if nRead != len(chunk1) {
+ t.Errorf("Unexpected number of bytes read, got %v, want %v", nRead, len(chunk1))
+ }
+ if !slices.Equal(chunk1, values[:nRead]) {
+ t.Errorf("Slices not equal")
+ }
+
+ nRead, err = stream.Read(chunk2)
+ if err != nil {
+ t.Fatalf("Unexpected error calling Read, got %v, want nil", err)
+ }
+ nDiff := len(values) - len(chunk1)
+ if nRead != nDiff {
+ t.Errorf("Unexpected number of bytes read, got %v, want %v", nRead, nDiff)
+ }
+ if !slices.Equal(chunk2[:nRead], values[len(chunk1):len(chunk1)+nRead]) {
+ t.Errorf("Slices not equal")
+ }
+
+ nRead, err = stream.Read(chunk2[nRead:])
+ if err != io.EOF {
+ t.Errorf("Unexpected error calling Read, got %v, want %v", err, io.EOF)
+ }
+
+ // Chunked write with EOF
+ wstream, err := newMemoryStreamInternal(nil, useLegacy)
+ if err != nil {
+ t.Fatalf("Error calling NewMemoryStream(nil): %v", err)
+ }
+
+ if err := wstream.SetSize(uint64(len(values))); err != nil {
+ t.Fatalf("Error calling SetSize(%d): %v", len(values), err)
+ }
+
+ pos, err = getSeekPos(wstream)
+ if err != nil {
+ t.Fatalf("Error calling getSeekPos: %v", err)
+ }
+ if pos != 0 {
+ t.Errorf("Unexpected seek pos, got %d, want 0", pos)
+ }
+
+ nWritten, err := wstream.Write(chunk1)
+ if err != nil {
+ t.Fatalf("Unexpected error calling Write, got %v, want nil", err)
+ }
+ if nWritten != len(chunk1) {
+ t.Errorf("Unexpected number of bytes written, got %v, want %v", nWritten, len(chunk1))
+ }
+
+ nWritten, err = wstream.Write(chunk2)
+ if err != nil {
+ t.Fatalf("Unexpected error calling Write, got %v, want nil", err)
+ }
+ if nWritten != len(chunk2) {
+ t.Errorf("Unexpected number of bytes written, got %v, want %v", nWritten, len(chunk2))
+ }
+
+ pos, err = wstream.Seek(0, io.SeekStart)
+ if err != nil {
+ t.Fatalf("Error calling Seek: %v", err)
+ }
+ if pos != 0 {
+ t.Errorf("Unexpected seek pos, got %d, want 0", pos)
+ }
+
+ readBuf2 := make([]byte, len(chunk1)+len(chunk2))
+ nRead, err = wstream.Read(readBuf2)
+ if err != nil {
+ t.Fatalf("Unexpected error calling Read, got %v, want nil", err)
+ }
+ if nRead != len(readBuf2) {
+ t.Errorf("Unexpected number of bytes read, got %v, want %v", nRead, len(readBuf2))
+ }
+ if !slices.Equal(append(chunk1, chunk2...), readBuf2) {
+ t.Errorf("Slices not equal")
+ }
+
+ // Clone, check same buffer contents but different interface pointers
+ stream2, err := stream.Clone()
+ if err != nil {
+ t.Fatalf("Unexpected error calling Clone, got %v, want nil", err)
+ }
+
+ pos, err = stream2.Seek(0, io.SeekStart)
+ if err != nil {
+ t.Fatalf("Error calling Seek: %v", err)
+ }
+ if pos != 0 {
+ t.Errorf("Unexpected seek pos, got %d, want 0", pos)
+ }
+
+ values2 := make([]byte, len(values))
+ nRead, err = stream2.Read(values2)
+ if err != nil {
+ t.Fatalf("Unexpected error calling Read, got %v, want nil", err)
+ }
+ if nRead != len(values2) {
+ t.Errorf("Unexpected number of bytes read, got %v, want %v", nRead, len(values2))
+ }
+ if !slices.Equal(values, values2) {
+ t.Errorf("Slices not equal")
+ }
+
+ if stream.UnsafeUnwrap() == stream2.UnsafeUnwrap() {
+ t.Errorf("Cloned streams wrap identical interface pointers")
+ }
+}
+
+func getSize(stream Stream) (uint64, error) {
+ statstg, err := stream.Stat(STATFLAG_NONAME)
+ if err != nil {
+ return 0, err
+ }
+
+ return statstg.Size, nil
+}
+
+func getSeekPos(stream Stream) (int64, error) {
+ return stream.Seek(0, io.SeekCurrent)
+}
+
+func makeTestBuf(size byte) []byte {
+ values := make([]byte, size)
+ for i, l := byte(0), byte(len(values)); i < l; i++ {
+ values[i] = i
+ }
+ return values
+}
diff --git a/util/wingoes/com/stream_test_386.go b/util/wingoes/com/stream_test_386.go
new file mode 100644
index 0000000000000..5dfaa8f64adbe
--- /dev/null
+++ b/util/wingoes/com/stream_test_386.go
@@ -0,0 +1,11 @@
+// Copyright (c) 2024 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 windows
+
+package com
+
+func getTooBigSlice() []byte {
+ return nil
+}
diff --git a/util/wingoes/com/stream_test_not386.go b/util/wingoes/com/stream_test_not386.go
new file mode 100644
index 0000000000000..9a3db1b2f0ddf
--- /dev/null
+++ b/util/wingoes/com/stream_test_not386.go
@@ -0,0 +1,11 @@
+// Copyright (c) 2024 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 windows && !386
+
+package com
+
+func getTooBigSlice() []byte {
+ return make([]byte, maxStreamRWLen+1)
+}
diff --git a/util/wingoes/com/subprocess_res_test.go b/util/wingoes/com/subprocess_res_test.go
new file mode 100644
index 0000000000000..be77f7db49aa3
--- /dev/null
+++ b/util/wingoes/com/subprocess_res_test.go
@@ -0,0 +1,51 @@
+//go:build ignore
+
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+package com
+
+import (
+ "os"
+
+ "github.com/tc-hib/winres"
+)
+
+const manifestContents = `
+
+
+
+
+
+
+
+
+
+
+`
+
+func addManifest(outPath, inPath string) (err error) {
+ inf, err := os.Open(inPath)
+ if err != nil {
+ return err
+ }
+ defer inf.Close()
+
+ outf, err := os.Create(outPath)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ outf.Close()
+ if err != nil {
+ os.Remove(outPath)
+ }
+ }()
+
+ var rs winres.ResourceSet
+ if err := rs.Set(winres.RT_MANIFEST, winres.ID(1), 0, []byte(manifestContents)); err != nil {
+ return err
+ }
+
+ return rs.WriteToEXE(outf, inf, winres.ForceCheckSum())
+}
diff --git a/util/wingoes/com/subprocess_test.go b/util/wingoes/com/subprocess_test.go
new file mode 100644
index 0000000000000..9e59bbe0c53a7
--- /dev/null
+++ b/util/wingoes/com/subprocess_test.go
@@ -0,0 +1,400 @@
+//go:build ignore
+
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package com
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "runtime"
+ "strconv"
+ "strings"
+ "sync"
+ "testing"
+ "time"
+)
+
+// The code in this file is adapted from internal/testenv in the Go source tree
+// and is used for writing tests that require spawning subprocesses.
+
+var toRemove []string
+
+func TestMain(m *testing.M) {
+ StartRuntime(ConsoleApp)
+ status := m.Run()
+ for _, file := range toRemove {
+ os.RemoveAll(file)
+ }
+ os.Exit(status)
+}
+
+var testprog struct {
+ sync.Mutex
+ dir string
+ target map[string]*buildexe
+}
+
+type buildexe struct {
+ once sync.Once
+ exe string
+ err error
+}
+
+func runTestProg(t *testing.T, binary, name string, env ...string) string {
+ exe, err := buildTestProg(t, binary)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ return runBuiltTestProg(t, exe, name, env...)
+}
+
+func runBuiltTestProg(t *testing.T, exe, name string, env ...string) string {
+ cmd := exec.Command(exe, name)
+ cmd.Env = append(cmd.Env, env...)
+ if testing.Short() {
+ cmd.Env = append(cmd.Env, "RUNTIME_TEST_SHORT=1")
+ }
+ out, _ := runWithTimeout(t, cmd)
+ return string(out)
+}
+
+var serializeBuild = make(chan bool, 2)
+
+func buildTestProg(t *testing.T, binary string, flags ...string) (string, error) {
+ testprog.Lock()
+ if testprog.dir == "" {
+ dir, err := os.MkdirTemp("", "go-build")
+ if err != nil {
+ t.Fatalf("failed to create temp directory: %v", err)
+ }
+ testprog.dir = dir
+ toRemove = append(toRemove, dir)
+ }
+
+ if testprog.target == nil {
+ testprog.target = make(map[string]*buildexe)
+ }
+ name := binary
+ if len(flags) > 0 {
+ name += "_" + strings.Join(flags, "_")
+ }
+ target, ok := testprog.target[name]
+ if !ok {
+ target = &buildexe{}
+ testprog.target[name] = target
+ }
+
+ dir := testprog.dir
+
+ // Unlock testprog while actually building, so that other
+ // tests can look up executables that were already built.
+ testprog.Unlock()
+
+ target.once.Do(func() {
+ // Only do two "go build"'s at a time,
+ // to keep load from getting too high.
+ serializeBuild <- true
+ defer func() { <-serializeBuild }()
+
+ // Don't get confused if goToolPath calls t.Skip.
+ target.err = errors.New("building test called t.Skip")
+
+ noresexe := filepath.Join(dir, name+"-nores.exe")
+
+ t.Logf("running go build -o %s %s", noresexe, strings.Join(flags, " "))
+ cmd := exec.Command(goToolPath(t), append([]string{"build", "-o", noresexe}, flags...)...)
+ cmd.Dir = "testdata/" + binary
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ target.err = fmt.Errorf("building %s %v: %v\n%s", binary, flags, err, out)
+ return
+ }
+
+ exe := filepath.Join(dir, name+".exe")
+
+ t.Logf("binding manifest to %s => %s", noresexe, exe)
+ if err := addManifest(exe, noresexe); err != nil {
+ target.err = fmt.Errorf("binding manifest %s %v: %v", binary, flags, err)
+ return
+ }
+
+ target.exe = exe
+ target.err = nil
+ })
+
+ return target.exe, target.err
+}
+
+// goTool reports the path to the Go tool.
+func goTool() (string, error) {
+ if !hasGoBuild() {
+ return "", errors.New("platform cannot run go tool")
+ }
+ exeSuffix := ".exe"
+ goroot, err := findGOROOT()
+ if err != nil {
+ return "", fmt.Errorf("cannot find go tool: %w", err)
+ }
+ path := filepath.Join(goroot, "bin", "go"+exeSuffix)
+ if _, err := os.Stat(path); err == nil {
+ return path, nil
+ }
+ goBin, err := exec.LookPath("go" + exeSuffix)
+ if err != nil {
+ return "", errors.New("cannot find go tool: " + err.Error())
+ }
+ return goBin, nil
+}
+
+// knownEnv is a list of environment variables that affect the operation
+// of the Go command.
+const knownEnv = `
+ AR
+ CC
+ CGO_CFLAGS
+ CGO_CFLAGS_ALLOW
+ CGO_CFLAGS_DISALLOW
+ CGO_CPPFLAGS
+ CGO_CPPFLAGS_ALLOW
+ CGO_CPPFLAGS_DISALLOW
+ CGO_CXXFLAGS
+ CGO_CXXFLAGS_ALLOW
+ CGO_CXXFLAGS_DISALLOW
+ CGO_ENABLED
+ CGO_FFLAGS
+ CGO_FFLAGS_ALLOW
+ CGO_FFLAGS_DISALLOW
+ CGO_LDFLAGS
+ CGO_LDFLAGS_ALLOW
+ CGO_LDFLAGS_DISALLOW
+ CXX
+ FC
+ GCCGO
+ GO111MODULE
+ GO386
+ GOAMD64
+ GOARCH
+ GOARM
+ GOBIN
+ GOCACHE
+ GOENV
+ GOEXE
+ GOEXPERIMENT
+ GOFLAGS
+ GOGCCFLAGS
+ GOHOSTARCH
+ GOHOSTOS
+ GOINSECURE
+ GOMIPS
+ GOMIPS64
+ GOMODCACHE
+ GONOPROXY
+ GONOSUMDB
+ GOOS
+ GOPATH
+ GOPPC64
+ GOPRIVATE
+ GOPROXY
+ GOROOT
+ GOSUMDB
+ GOTMPDIR
+ GOTOOLDIR
+ GOVCS
+ GOWASM
+ GOWORK
+ GO_EXTLINK_ENABLED
+ PKG_CONFIG
+`
+
+// goToolPath reports the path to the Go tool.
+// It is a convenience wrapper around goTool.
+// If the tool is unavailable goToolPath calls t.Skip.
+// If the tool should be available and isn't, goToolPath calls t.Fatal.
+func goToolPath(t testing.TB) string {
+ mustHaveGoBuild(t)
+ path, err := goTool()
+ if err != nil {
+ t.Fatal(err)
+ }
+ // Add all environment variables that affect the Go command to test metadata.
+ // Cached test results will be invalidate when these variables change.
+ // See golang.org/issue/32285.
+ for _, envVar := range strings.Fields(knownEnv) {
+ os.Getenv(envVar)
+ }
+ return path
+}
+
+// hasGoBuild reports whether the current system can build programs with “go build”
+// and then run them with os.StartProcess or exec.Command.
+func hasGoBuild() bool {
+ if os.Getenv("GO_GCFLAGS") != "" {
+ // It's too much work to require every caller of the go command
+ // to pass along "-gcflags="+os.Getenv("GO_GCFLAGS").
+ // For now, if $GO_GCFLAGS is set, report that we simply can't
+ // run go build.
+ return false
+ }
+ return true
+}
+
+// mustHaveGoBuild checks that the current system can build programs with “go build”
+// and then run them with os.StartProcess or exec.Command.
+// If not, mustHaveGoBuild calls t.Skip with an explanation.
+func mustHaveGoBuild(t testing.TB) {
+ if os.Getenv("GO_GCFLAGS") != "" {
+ t.Skipf("skipping test: 'go build' not compatible with setting $GO_GCFLAGS")
+ }
+ if !hasGoBuild() {
+ t.Skipf("skipping test: 'go build' not available on %s/%s", runtime.GOOS, runtime.GOARCH)
+ }
+}
+
+// hasGoRun reports whether the current system can run programs with “go run.”
+func hasGoRun() bool {
+ // For now, having go run and having go build are the same.
+ return hasGoBuild()
+}
+
+// mustHaveGoRun checks that the current system can run programs with “go run.”
+// If not, mustHaveGoRun calls t.Skip with an explanation.
+func mustHaveGoRun(t testing.TB) {
+ if !hasGoRun() {
+ t.Skipf("skipping test: 'go run' not available on %s/%s", runtime.GOOS, runtime.GOARCH)
+ }
+}
+
+var (
+ gorootOnce sync.Once
+ gorootPath string
+ gorootErr error
+)
+
+func findGOROOT() (string, error) {
+ gorootOnce.Do(func() {
+ gorootPath = runtime.GOROOT()
+ if gorootPath != "" {
+ // If runtime.GOROOT() is non-empty, assume that it is valid.
+ //
+ // (It might not be: for example, the user may have explicitly set GOROOT
+ // to the wrong directory, or explicitly set GOROOT_FINAL but not GOROOT
+ // and hasn't moved the tree to GOROOT_FINAL yet. But those cases are
+ // rare, and if that happens the user can fix what they broke.)
+ return
+ }
+
+ // runtime.GOROOT doesn't know where GOROOT is (perhaps because the test
+ // binary was built with -trimpath, or perhaps because GOROOT_FINAL was set
+ // without GOROOT and the tree hasn't been moved there yet).
+ //
+ // Since this is internal/testenv, we can cheat and assume that the caller
+ // is a test of some package in a subdirectory of GOROOT/src. ('go test'
+ // runs the test in the directory containing the packaged under test.) That
+ // means that if we start walking up the tree, we should eventually find
+ // GOROOT/src/go.mod, and we can report the parent directory of that.
+
+ cwd, err := os.Getwd()
+ if err != nil {
+ gorootErr = fmt.Errorf("finding GOROOT: %w", err)
+ return
+ }
+
+ dir := cwd
+ for {
+ parent := filepath.Dir(dir)
+ if parent == dir {
+ // dir is either "." or only a volume name.
+ gorootErr = fmt.Errorf("failed to locate GOROOT/src in any parent directory")
+ return
+ }
+
+ if base := filepath.Base(dir); base != "src" {
+ dir = parent
+ continue // dir cannot be GOROOT/src if it doesn't end in "src".
+ }
+
+ b, err := os.ReadFile(filepath.Join(dir, "go.mod"))
+ if err != nil {
+ if os.IsNotExist(err) {
+ dir = parent
+ continue
+ }
+ gorootErr = fmt.Errorf("finding GOROOT: %w", err)
+ return
+ }
+ goMod := string(b)
+
+ for goMod != "" {
+ var line string
+ line, goMod, _ = strings.Cut(goMod, "\n")
+ fields := strings.Fields(line)
+ if len(fields) >= 2 && fields[0] == "module" && fields[1] == "std" {
+ // Found "module std", which is the module declaration in GOROOT/src!
+ gorootPath = parent
+ return
+ }
+ }
+ }
+ })
+
+ return gorootPath, gorootErr
+}
+
+// runWithTimeout runs cmd and returns its combined output. If the
+// subprocess exits with a non-zero status, it will log that status
+// and return a non-nil error, but this is not considered fatal.
+func runWithTimeout(t testing.TB, cmd *exec.Cmd) ([]byte, error) {
+ args := cmd.Args
+ if args == nil {
+ args = []string{cmd.Path}
+ }
+
+ var b bytes.Buffer
+ cmd.Stdout = &b
+ cmd.Stderr = &b
+ if err := cmd.Start(); err != nil {
+ t.Fatalf("starting %s: %v", args, err)
+ }
+
+ // If the process doesn't complete within 1 minute,
+ // assume it is hanging and kill it to get a stack trace.
+ p := cmd.Process
+ done := make(chan bool)
+ go func() {
+ scale := 2
+ if s := os.Getenv("GO_TEST_TIMEOUT_SCALE"); s != "" {
+ if sc, err := strconv.Atoi(s); err == nil {
+ scale = sc
+ }
+ }
+
+ select {
+ case <-done:
+ case <-time.After(time.Duration(scale) * time.Minute):
+ p.Signal(os.Kill)
+ // If SIGQUIT doesn't do it after a little
+ // while, kill the process.
+ select {
+ case <-done:
+ case <-time.After(time.Duration(scale) * 30 * time.Second):
+ p.Signal(os.Kill)
+ }
+ }
+ }()
+
+ err := cmd.Wait()
+ if err != nil {
+ t.Logf("%s exit status: %v", args, err)
+ }
+ close(done)
+
+ return b.Bytes(), err
+}
diff --git a/util/wingoes/com/testdata/testprocessruntime/bgthread.go b/util/wingoes/com/testdata/testprocessruntime/bgthread.go
new file mode 100644
index 0000000000000..b9c2978be8c52
--- /dev/null
+++ b/util/wingoes/com/testdata/testprocessruntime/bgthread.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 windows
+
+package main
+
+import (
+ "runtime"
+
+ "github.com/metacubex/tailscale/util/wingoes/com"
+)
+
+func bgThreadCheckMTA(c chan bool) {
+ c <- com.IsCurrentOSThreadMTA()
+}
+
+func checkBackgroundThread(needLockOSThread bool) bool {
+ if needLockOSThread {
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+ }
+
+ c := make(chan bool)
+ go bgThreadCheckMTA(c)
+ return <-c
+}
diff --git a/util/wingoes/com/testdata/testprocessruntime/guiapp.go b/util/wingoes/com/testdata/testprocessruntime/guiapp.go
new file mode 100644
index 0000000000000..f1abfd7cae67c
--- /dev/null
+++ b/util/wingoes/com/testdata/testprocessruntime/guiapp.go
@@ -0,0 +1,62 @@
+// 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 windows
+
+package main
+
+import (
+ "fmt"
+ "runtime"
+
+ "github.com/metacubex/tailscale/util/wingoes/com"
+)
+
+func init() {
+ registerInit("GUIApp", GUIAppInit)
+ register("GUIApp", GUIApp)
+}
+
+func GUIAppInit() {
+ if err = com.StartRuntime(com.GUIApp); err != nil {
+ fmt.Println("error: ", err)
+ }
+}
+
+func GUIApp() {
+ if err != nil {
+ return
+ }
+
+ if !com.IsCurrentOSThreadSTA() {
+ fmt.Println("error: IsCurrentOSThreadSTA got false, want true")
+ return
+ }
+
+ globalOpts, err := com.CreateInstance[com.GlobalOptions](com.CLSID_GlobalOptions)
+ if err != nil {
+ fmt.Println("error: ", err)
+ return
+ }
+
+ val, err := globalOpts.Query(com.COMGLB_EXCEPTION_HANDLING)
+ if err != nil {
+ fmt.Println("error: ", err)
+ return
+ }
+ if val != com.COMGLB_EXCEPTION_DONOT_HANDLE_ANY {
+ fmt.Printf("error: COMGLB_EXCEPTION_HANDLING got %d, want %d\n", val, com.COMGLB_EXCEPTION_DONOT_HANDLE_ANY)
+ return
+ }
+
+ if !checkBackgroundThread(false) {
+ fmt.Println("error: background OS thread is not MTA")
+ return
+ }
+
+ // Force some COM objects to GC before we exit so that we catch any refcount bugs.
+ runtime.GC()
+
+ fmt.Println("OK")
+}
diff --git a/util/wingoes/com/testdata/testprocessruntime/guiapp_dacl.go b/util/wingoes/com/testdata/testprocessruntime/guiapp_dacl.go
new file mode 100644
index 0000000000000..8fb25a339a399
--- /dev/null
+++ b/util/wingoes/com/testdata/testprocessruntime/guiapp_dacl.go
@@ -0,0 +1,107 @@
+// 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 windows
+
+package main
+
+import (
+ "fmt"
+
+ "github.com/metacubex/tailscale/util/wingoes"
+ "github.com/metacubex/tailscale/util/wingoes/com"
+ "golang.org/x/sys/windows"
+)
+
+func init() {
+ registerInit("GUIAppDACL", GUIAppDACLInit)
+ register("GUIAppDACL", GUIApp) // We reuse GUIApp for this part of the test
+}
+
+func GUIAppDACLInit() {
+ var dacl *windows.ACL
+ dacl, err = makeDACL()
+ if err != nil {
+ fmt.Println("error: ", err)
+ return
+ }
+
+ if err = com.StartRuntimeWithDACL(com.GUIApp, dacl); err != nil {
+ fmt.Println("error: ", err)
+ }
+}
+
+const _COM_RIGHTS_EXECUTE = 1
+
+func makeDACL() (*windows.ACL, error) {
+ localSystem, err := windows.CreateWellKnownSid(windows.WinLocalSystemSid)
+ if err != nil {
+ return nil, err
+ }
+
+ administrators, err := windows.CreateWellKnownSid(windows.WinBuiltinAdministratorsSid)
+ if err != nil {
+ return nil, err
+ }
+
+ userSIDs, err := wingoes.CurrentProcessUserSIDs()
+ if err != nil {
+ return nil, err
+ }
+
+ var anyPackage *windows.SID
+ if wingoes.IsWin8OrGreater() {
+ anyPackage, err = windows.CreateWellKnownSid(windows.WinBuiltinAnyPackageSid)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ localSystemTrustee := windows.TRUSTEE{nil, windows.NO_MULTIPLE_TRUSTEE,
+ windows.TRUSTEE_IS_SID, windows.TRUSTEE_IS_USER,
+ windows.TrusteeValueFromSID(localSystem)}
+
+ adminTrustee := windows.TRUSTEE{nil, windows.NO_MULTIPLE_TRUSTEE,
+ windows.TRUSTEE_IS_SID, windows.TRUSTEE_IS_WELL_KNOWN_GROUP,
+ windows.TrusteeValueFromSID(administrators)}
+
+ userTrustee := windows.TRUSTEE{nil, windows.NO_MULTIPLE_TRUSTEE,
+ windows.TRUSTEE_IS_SID, windows.TRUSTEE_IS_USER,
+ windows.TrusteeValueFromSID(userSIDs.User)}
+
+ ea := []windows.EXPLICIT_ACCESS{
+ {
+ _COM_RIGHTS_EXECUTE,
+ windows.GRANT_ACCESS,
+ windows.NO_INHERITANCE,
+ localSystemTrustee,
+ },
+ {
+ _COM_RIGHTS_EXECUTE,
+ windows.GRANT_ACCESS,
+ windows.NO_INHERITANCE,
+ adminTrustee,
+ },
+ {
+ _COM_RIGHTS_EXECUTE,
+ windows.GRANT_ACCESS,
+ windows.NO_INHERITANCE,
+ userTrustee,
+ },
+ }
+
+ if anyPackage != nil {
+ anyPackageTrustee := windows.TRUSTEE{nil, windows.NO_MULTIPLE_TRUSTEE,
+ windows.TRUSTEE_IS_SID, windows.TRUSTEE_IS_WELL_KNOWN_GROUP,
+ windows.TrusteeValueFromSID(anyPackage)}
+
+ ea = append(ea, windows.EXPLICIT_ACCESS{
+ _COM_RIGHTS_EXECUTE,
+ windows.GRANT_ACCESS,
+ windows.NO_INHERITANCE,
+ anyPackageTrustee})
+ }
+
+ return windows.ACLFromEntries(ea, nil)
+}
diff --git a/util/wingoes/com/testdata/testprocessruntime/main.go b/util/wingoes/com/testdata/testprocessruntime/main.go
new file mode 100644
index 0000000000000..0a83af630d616
--- /dev/null
+++ b/util/wingoes/com/testdata/testprocessruntime/main.go
@@ -0,0 +1,40 @@
+// Copyright 2015 The Go 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 windows
+
+package main
+
+import "os"
+
+var (
+ cmds = map[string]func(){}
+ err error
+)
+
+func register(name string, f func()) {
+ if cmds[name] != nil {
+ panic("duplicate registration: " + name)
+ }
+ cmds[name] = f
+}
+
+func registerInit(name string, f func()) {
+ if len(os.Args) >= 2 && os.Args[1] == name {
+ f()
+ }
+}
+
+func main() {
+ if len(os.Args) < 2 {
+ println("usage: " + os.Args[0] + " name-of-test")
+ return
+ }
+ f := cmds[os.Args[1]]
+ if f == nil {
+ println("unknown function: " + os.Args[1])
+ return
+ }
+ f()
+}
diff --git a/util/wingoes/com/testdata/testprocessruntime/notguiapp.go b/util/wingoes/com/testdata/testprocessruntime/notguiapp.go
new file mode 100644
index 0000000000000..0dbce2ccfeb94
--- /dev/null
+++ b/util/wingoes/com/testdata/testprocessruntime/notguiapp.go
@@ -0,0 +1,62 @@
+// 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 windows
+
+package main
+
+import (
+ "fmt"
+ "runtime"
+
+ "github.com/metacubex/tailscale/util/wingoes/com"
+)
+
+func init() {
+ registerInit("NonGUIApp", NonGUIAppInit)
+ register("NonGUIApp", NonGUIApp)
+}
+
+func NonGUIAppInit() {
+ if err = com.StartRuntime(com.ConsoleApp); err != nil {
+ fmt.Printf("error: got %v, want nil\n", err)
+ }
+}
+
+func NonGUIApp() {
+ if err != nil {
+ return
+ }
+
+ if !com.IsCurrentOSThreadMTA() {
+ fmt.Println("error: IsCurrentOSThreadMTA got false, want true")
+ return
+ }
+
+ globalOpts, err := com.CreateInstance[com.GlobalOptions](com.CLSID_GlobalOptions)
+ if err != nil {
+ fmt.Printf("error: got %v, want nil\n", err)
+ return
+ }
+
+ val, err := globalOpts.Query(com.COMGLB_EXCEPTION_HANDLING)
+ if err != nil {
+ fmt.Printf("error: got %v, want nil\n", err)
+ return
+ }
+ if val != com.COMGLB_EXCEPTION_DONOT_HANDLE_ANY {
+ fmt.Printf("error: COMGLB_EXCEPTION_HANDLING got %d, want %d\n", val, com.COMGLB_EXCEPTION_DONOT_HANDLE_ANY)
+ return
+ }
+
+ if !checkBackgroundThread(true) {
+ fmt.Println("error: background OS thread is not MTA")
+ return
+ }
+
+ // Force some COM objects to GC before we exit so that we catch any refcount bugs.
+ runtime.GC()
+
+ fmt.Println("OK")
+}
diff --git a/util/wingoes/com/types.go b/util/wingoes/com/types.go
new file mode 100644
index 0000000000000..7de8dade8b6eb
--- /dev/null
+++ b/util/wingoes/com/types.go
@@ -0,0 +1,150 @@
+// 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 windows
+
+package com
+
+import (
+ "unsafe"
+
+ "github.com/metacubex/tailscale/util/wingoes"
+ "golang.org/x/sys/windows"
+)
+
+type coMTAUsageCookie windows.Handle
+
+type coCLSCTX uint32
+
+const (
+ // We intentionally do not define combinations of these values, as in my experience
+ // people don't realize what they're doing when they use those.
+ coCLSCTX_INPROC_SERVER = coCLSCTX(0x1)
+ coCLSCTX_LOCAL_SERVER = coCLSCTX(0x4)
+ coCLSCTX_REMOTE_SERVER = coCLSCTX(0x10)
+)
+
+type coAPTTYPE int32
+
+const (
+ coAPTTYPE_CURRENT = coAPTTYPE(-1)
+ coAPTTYPE_STA = coAPTTYPE(0)
+ coAPTTYPE_MTA = coAPTTYPE(1)
+ coAPTTYPE_NA = coAPTTYPE(2)
+ coAPTTYPE_MAINSTA = coAPTTYPE(3)
+)
+
+type coAPTTYPEQUALIFIER int32
+
+const (
+ coAPTTYPEQUALIFIER_NONE = coAPTTYPEQUALIFIER(0)
+ coAPTTYPEQUALIFIER_IMPLICIT_MTA = coAPTTYPEQUALIFIER(1)
+ coAPTTYPEQUALIFIER_NA_ON_MTA = coAPTTYPEQUALIFIER(2)
+ coAPTTYPEQUALIFIER_NA_ON_STA = coAPTTYPEQUALIFIER(3)
+ coAPTTYPEQUALIFIER_NA_ON_IMPLICIT_MTA = coAPTTYPEQUALIFIER(4)
+ coAPTTYPEQUALIFIER_NA_ON_MAINSTA = coAPTTYPEQUALIFIER(5)
+ coAPTTYPEQUALIFIER_APPLICATION_STA = coAPTTYPEQUALIFIER(6)
+)
+
+type aptInfo struct {
+ apt coAPTTYPE
+ qualifier coAPTTYPEQUALIFIER
+}
+
+type soleAuthenticationInfo struct {
+ authnSvc uint32
+ authzSvc uint32
+ authInfo uintptr
+}
+
+type soleAuthenticationList struct {
+ count uint32
+ authInfo *soleAuthenticationInfo
+}
+
+type soleAuthenticationService struct {
+ authnSvc uint32
+ authzSvc uint32
+ principalName *uint16
+ hr wingoes.HRESULT
+}
+
+type authCapabilities uint32
+
+const (
+ authCapNone = authCapabilities(0)
+ authCapMutualAuth = authCapabilities(1)
+ authCapSecureRefs = authCapabilities(2)
+ authCapAccessControl = authCapabilities(4)
+ authCapAppID = authCapabilities(8)
+ authCapDynamic = authCapabilities(0x10)
+ authCapStaticCloaking = authCapabilities(0x20)
+ authCapDynamicCloaking = authCapabilities(0x40)
+ authCapAnyAuthority = authCapabilities(0x80)
+ authCapMakeFullsic = authCapabilities(0x100)
+ authCapRequireFullsic = authCapabilities(0x200)
+ authCapAutoImpersonate = authCapabilities(0x400)
+ authCapDefault = authCapabilities(0x800)
+ authCapDisableAAA = authCapabilities(0x1000)
+ authCapNoCustomMarshal = authCapabilities(0x2000)
+)
+
+type rpcAuthnLevel uint32
+
+const (
+ rpcAuthnLevelDefault = rpcAuthnLevel(0)
+ rpcAuthnLevelNone = rpcAuthnLevel(1)
+ rpcAuthnLevelConnect = rpcAuthnLevel(2)
+ rpcAuthnLevelCall = rpcAuthnLevel(3)
+ rpcAuthnLevelPkt = rpcAuthnLevel(4)
+ rpcAuthnLevelPktIntegrity = rpcAuthnLevel(5)
+ rpcAuthnLevelPkgPrivacy = rpcAuthnLevel(6)
+)
+
+type rpcImpersonationLevel uint32
+
+const (
+ rpcImpLevelDefault = rpcImpersonationLevel(0)
+ rpcImpLevelAnonymous = rpcImpersonationLevel(1)
+ rpcImpLevelIdentify = rpcImpersonationLevel(2)
+ rpcImpLevelImpersonate = rpcImpersonationLevel(3)
+ rpcImpLevelDelegate = rpcImpersonationLevel(4)
+)
+
+// COMAllocatedString encapsulates a UTF-16 string that was allocated by COM
+// using its internal heap.
+type COMAllocatedString uintptr
+
+// Close frees the memory held by the string.
+func (s *COMAllocatedString) Close() error {
+ windows.CoTaskMemFree(unsafe.Pointer(*s))
+ *s = 0
+ return nil
+}
+
+func (s *COMAllocatedString) String() string {
+ return windows.UTF16PtrToString((*uint16)(unsafe.Pointer(*s)))
+}
+
+// UTF16 returns a slice containing a copy of the UTF-16 string, including a
+// NUL terminator.
+func (s *COMAllocatedString) UTF16() []uint16 {
+ p := (*uint16)(unsafe.Pointer(*s))
+ if p == nil {
+ return nil
+ }
+
+ n := 0
+ for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; n++ {
+ ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p))
+ }
+
+ // Make a copy, including the NUL terminator.
+ return append([]uint16{}, unsafe.Slice(p, n+1)...)
+}
+
+// UTF16Ptr returns a pointer to a NUL-terminated copy of the UTF-16 string.
+func (s *COMAllocatedString) UTF16Ptr() *uint16 {
+ return unsafe.SliceData(s.UTF16())
+}
diff --git a/util/wingoes/com/unknown.go b/util/wingoes/com/unknown.go
new file mode 100644
index 0000000000000..c1fb64c5f96dd
--- /dev/null
+++ b/util/wingoes/com/unknown.go
@@ -0,0 +1,44 @@
+// 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 windows
+
+package com
+
+import (
+ "runtime"
+)
+
+var (
+ IID_IUnknown = &IID{0x00000000, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}
+)
+
+// ObjectBase is a garbage-collected instance of any COM object's base interface.
+type ObjectBase struct {
+ GenericObject[IUnknownABI]
+}
+
+// IID always returns IID_IUnknown.
+func (o ObjectBase) IID() *IID {
+ return IID_IUnknown
+}
+
+// Make produces a new instance of ObjectBase that wraps r. Its return type is
+// always ObjectBase.
+func (o ObjectBase) Make(r ABIReceiver) any {
+ if r == nil {
+ return ObjectBase{}
+ }
+
+ runtime.SetFinalizer(r, ReleaseABI)
+
+ pp := (**IUnknownABI)(r)
+ return ObjectBase{GenericObject[IUnknownABI]{Pp: pp}}
+}
+
+// UnsafeUnwrap returns the underlying IUnknownABI of the object. As the name
+// implies, this is unsafe -- you had better know what you are doing!
+func (o ObjectBase) UnsafeUnwrap() *IUnknownABI {
+ return *(o.Pp)
+}
diff --git a/util/wingoes/com/zsyscall_windows.go b/util/wingoes/com/zsyscall_windows.go
new file mode 100644
index 0000000000000..a2e701270ffd9
--- /dev/null
+++ b/util/wingoes/com/zsyscall_windows.go
@@ -0,0 +1,106 @@
+// Code generated by 'go generate'; DO NOT EDIT.
+
+package com
+
+import (
+ "syscall"
+ "unsafe"
+
+ "github.com/metacubex/tailscale/util/wingoes"
+ "github.com/metacubex/tailscale/util/wingoes/internal"
+ "golang.org/x/sys/windows"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+ errnoERROR_IO_PENDING = 997
+)
+
+var (
+ errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+ errERROR_EINVAL error = syscall.EINVAL
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+ switch e {
+ case 0:
+ return errERROR_EINVAL
+ case errnoERROR_IO_PENDING:
+ return errERROR_IO_PENDING
+ }
+ // TODO: add more here, after collecting data on the common
+ // error values see on Windows. (perhaps when running
+ // all.bat?)
+ return e
+}
+
+var (
+ modole32 = windows.NewLazySystemDLL("ole32.dll")
+ modoleaut32 = windows.NewLazySystemDLL("oleaut32.dll")
+ modshlwapi = windows.NewLazySystemDLL("shlwapi.dll")
+
+ procCoCreateInstance = modole32.NewProc("CoCreateInstance")
+ procCoGetApartmentType = modole32.NewProc("CoGetApartmentType")
+ procCoIncrementMTAUsage = modole32.NewProc("CoIncrementMTAUsage")
+ procCoInitializeEx = modole32.NewProc("CoInitializeEx")
+ procCoInitializeSecurity = modole32.NewProc("CoInitializeSecurity")
+ procCreateStreamOnHGlobal = modole32.NewProc("CreateStreamOnHGlobal")
+ procSetOaNoCache = modoleaut32.NewProc("SetOaNoCache")
+ procSHCreateMemStream = modshlwapi.NewProc("SHCreateMemStream")
+)
+
+func coCreateInstance(clsid *CLSID, unkOuter *IUnknownABI, clsctx coCLSCTX, iid *IID, ppv **IUnknownABI) (hr wingoes.HRESULT) {
+ r0, _, _ := syscall.Syscall6(procCoCreateInstance.Addr(), 5, uintptr(unsafe.Pointer(clsid)), uintptr(unsafe.Pointer(unkOuter)), uintptr(clsctx), uintptr(unsafe.Pointer(iid)), uintptr(unsafe.Pointer(ppv)), 0)
+ hr = wingoes.HRESULT(r0)
+ return
+}
+
+func coGetApartmentType(aptType *coAPTTYPE, qual *coAPTTYPEQUALIFIER) (hr wingoes.HRESULT) {
+ r0, _, _ := syscall.Syscall(procCoGetApartmentType.Addr(), 2, uintptr(unsafe.Pointer(aptType)), uintptr(unsafe.Pointer(qual)), 0)
+ hr = wingoes.HRESULT(r0)
+ return
+}
+
+func coIncrementMTAUsage(cookie *coMTAUsageCookie) (hr wingoes.HRESULT) {
+ r0, _, _ := syscall.Syscall(procCoIncrementMTAUsage.Addr(), 1, uintptr(unsafe.Pointer(cookie)), 0, 0)
+ hr = wingoes.HRESULT(r0)
+ return
+}
+
+func coInitializeEx(reserved uintptr, flags uint32) (hr wingoes.HRESULT) {
+ r0, _, _ := syscall.Syscall(procCoInitializeEx.Addr(), 2, uintptr(reserved), uintptr(flags), 0)
+ hr = wingoes.HRESULT(r0)
+ return
+}
+
+func coInitializeSecurity(sd *windows.SECURITY_DESCRIPTOR, authSvcLen int32, authSvc *soleAuthenticationService, reserved1 uintptr, authnLevel rpcAuthnLevel, impLevel rpcImpersonationLevel, authList *soleAuthenticationList, capabilities authCapabilities, reserved2 uintptr) (hr wingoes.HRESULT) {
+ r0, _, _ := syscall.Syscall9(procCoInitializeSecurity.Addr(), 9, uintptr(unsafe.Pointer(sd)), uintptr(authSvcLen), uintptr(unsafe.Pointer(authSvc)), uintptr(reserved1), uintptr(authnLevel), uintptr(impLevel), uintptr(unsafe.Pointer(authList)), uintptr(capabilities), uintptr(reserved2))
+ hr = wingoes.HRESULT(r0)
+ return
+}
+
+func createStreamOnHGlobal(hglobal internal.HGLOBAL, deleteOnRelease bool, stream **IUnknownABI) (hr wingoes.HRESULT) {
+ var _p0 uint32
+ if deleteOnRelease {
+ _p0 = 1
+ }
+ r0, _, _ := syscall.Syscall(procCreateStreamOnHGlobal.Addr(), 3, uintptr(hglobal), uintptr(_p0), uintptr(unsafe.Pointer(stream)))
+ hr = wingoes.HRESULT(r0)
+ return
+}
+
+func setOaNoCache() {
+ syscall.Syscall(procSetOaNoCache.Addr(), 0, 0, 0, 0)
+ return
+}
+
+func shCreateMemStream(pInit *byte, cbInit uint32) (stream *IUnknownABI) {
+ r0, _, _ := syscall.Syscall(procSHCreateMemStream.Addr(), 2, uintptr(unsafe.Pointer(pInit)), uintptr(cbInit), 0)
+ stream = (*IUnknownABI)(unsafe.Pointer(r0))
+ return
+}
diff --git a/util/wingoes/error.go b/util/wingoes/error.go
new file mode 100644
index 0000000000000..baeacada38aab
--- /dev/null
+++ b/util/wingoes/error.go
@@ -0,0 +1,329 @@
+// 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 windows
+
+package wingoes
+
+import (
+ "fmt"
+
+ "golang.org/x/sys/windows"
+)
+
+// Error represents various error codes that may be encountered when coding
+// against Windows APIs, including HRESULTs, windows.NTStatus, and windows.Errno.
+type Error HRESULT
+
+// Errors are HRESULTs under the hood because the HRESULT encoding allows for
+// all the other common types of Windows errors to be encoded within them.
+
+const (
+ hrS_OK = HRESULT(0)
+ hrE_ABORT = HRESULT(-((0x80004004 ^ 0xFFFFFFFF) + 1))
+ hrE_FAIL = HRESULT(-((0x80004005 ^ 0xFFFFFFFF) + 1))
+ hrE_NOINTERFACE = HRESULT(-((0x80004002 ^ 0xFFFFFFFF) + 1))
+ hrE_NOTIMPL = HRESULT(-((0x80004001 ^ 0xFFFFFFFF) + 1))
+ hrE_POINTER = HRESULT(-((0x80004003 ^ 0xFFFFFFFF) + 1))
+ hrE_UNEXPECTED = HRESULT(-((0x8000FFFF ^ 0xFFFFFFFF) + 1))
+ hrTYPE_E_WRONGTYPEKIND = HRESULT(-((0x8002802A ^ 0xFFFFFFFF) + 1))
+)
+
+// S_FALSE is a peculiar HRESULT value which means that the call executed
+// successfully, but returned false as its result.
+const S_FALSE = HRESULT(1)
+
+var (
+ // genericError encodes an Error whose message string is very generic.
+ genericError = Error(hresultFromFacilityAndCode(hrFail, facilityWin32, hrCode(windows.ERROR_UNIDENTIFIED_ERROR)))
+)
+
+// Common HRESULT codes that don't use Win32 facilities, but have meanings that
+// we can manually translate to Win32 error codes.
+var commonHRESULTToErrno = map[HRESULT]windows.Errno{
+ hrE_ABORT: windows.ERROR_REQUEST_ABORTED,
+ hrE_FAIL: windows.ERROR_UNIDENTIFIED_ERROR,
+ hrE_NOINTERFACE: windows.ERROR_NOINTERFACE,
+ hrE_NOTIMPL: windows.ERROR_CALL_NOT_IMPLEMENTED,
+ hrE_UNEXPECTED: windows.ERROR_INTERNAL_ERROR,
+}
+
+type hrCode uint16
+type hrFacility uint16
+type failBit bool
+
+const (
+ hrFlagBitsMask = 0xF8000000
+ hrFacilityMax = 0x00001FFF
+ hrFacilityMask = hrFacilityMax << 16
+ hrCodeMax = 0x0000FFFF
+ hrCodeMask = hrCodeMax
+ hrFailBit = 0x80000000
+ hrCustomerBit = 0x20000000 // Also defined as syscall.APPLICATION_ERROR
+ hrFacilityNTBit = 0x10000000
+)
+
+const (
+ facilityWin32 = hrFacility(7)
+)
+
+// Succeeded returns true when hr is successful, but its actual error code
+// may include additional status information.
+func (hr HRESULT) Succeeded() bool {
+ return hr >= 0
+}
+
+// Failed returns true when hr contains a failure code.
+func (hr HRESULT) Failed() bool {
+ return hr < 0
+}
+
+func (hr HRESULT) String() string {
+ return fmt.Sprintf("0x%08X", uint32(hr))
+}
+
+func (hr HRESULT) isNT() bool {
+ return (hr & (hrCustomerBit | hrFacilityNTBit)) == hrFacilityNTBit
+}
+
+func (hr HRESULT) isCustomer() bool {
+ return (hr & hrCustomerBit) != 0
+}
+
+// isNormal returns true when the customer and NT bits are cleared, ie hr's
+// encoding contains valid facility and code fields.
+func (hr HRESULT) isNormal() bool {
+ return (hr & (hrCustomerBit | hrFacilityNTBit)) == 0
+}
+
+// facility returns the facility bits of hr. Only valid when isNormal is true.
+func (hr HRESULT) facility() hrFacility {
+ return hrFacility((uint32(hr) >> 16) & hrFacilityMax)
+}
+
+// facility returns the code bits of hr. Only valid when isNormal is true.
+func (hr HRESULT) code() hrCode {
+ return hrCode(uint32(hr) & hrCodeMask)
+}
+
+const (
+ hrFail = failBit(true)
+ hrSuccess = failBit(false)
+)
+
+func hresultFromFacilityAndCode(isFail failBit, f hrFacility, c hrCode) HRESULT {
+ var r uint32
+ if isFail {
+ r |= hrFailBit
+ }
+ r |= (uint32(f) << 16) & hrFacilityMask
+ r |= uint32(c) & hrCodeMask
+ return HRESULT(r)
+}
+
+// ErrorFromErrno creates an Error from e.
+func ErrorFromErrno(e windows.Errno) Error {
+ if e == windows.ERROR_SUCCESS {
+ return Error(hrS_OK)
+ }
+ if ue := uint32(e); (ue & hrFlagBitsMask) == hrCustomerBit {
+ // syscall.APPLICATION_ERROR == hrCustomerBit, so the only other thing
+ // we need to do to transform this into an HRESULT is add the fail flag
+ return Error(HRESULT(ue | hrFailBit))
+ }
+ if uint32(e) > hrCodeMax {
+ // Can't be encoded in HRESULT, return generic error instead
+ return genericError
+ }
+ return Error(hresultFromFacilityAndCode(hrFail, facilityWin32, hrCode(e)))
+}
+
+// ErrorFromNTStatus creates an Error from s.
+func ErrorFromNTStatus(s windows.NTStatus) Error {
+ if s == windows.STATUS_SUCCESS {
+ return Error(hrS_OK)
+ }
+ return Error(HRESULT(s) | hrFacilityNTBit)
+}
+
+// ErrorFromHRESULT creates an Error from hr.
+func ErrorFromHRESULT(hr HRESULT) Error {
+ return Error(hr)
+}
+
+// NewError converts e into an Error if e's type is supported. It returns
+// both the Error and a bool indicating whether the conversion was successful.
+func NewError(e any) (Error, bool) {
+ switch v := e.(type) {
+ case Error:
+ return v, true
+ case windows.NTStatus:
+ return ErrorFromNTStatus(v), true
+ case windows.Errno:
+ return ErrorFromErrno(v), true
+ case HRESULT:
+ return ErrorFromHRESULT(v), true
+ default:
+ return ErrorFromHRESULT(hrTYPE_E_WRONGTYPEKIND), false
+ }
+}
+
+// IsOK returns true when the Error is unconditionally successful.
+func (e Error) IsOK() bool {
+ return HRESULT(e) == hrS_OK
+}
+
+// Succeeded returns true when the Error is successful, but its error code
+// may include additional status information.
+func (e Error) Succeeded() bool {
+ return HRESULT(e).Succeeded()
+}
+
+// Failed returns true when the Error contains a failure code.
+func (e Error) Failed() bool {
+ return HRESULT(e).Failed()
+}
+
+// AsHRESULT converts the Error to a HRESULT.
+func (e Error) AsHRESULT() HRESULT {
+ return HRESULT(e)
+}
+
+type errnoFailHandler func(hr HRESULT) windows.Errno
+
+func (e Error) toErrno(f errnoFailHandler) windows.Errno {
+ hr := HRESULT(e)
+
+ if hr == hrS_OK {
+ return windows.ERROR_SUCCESS
+ }
+
+ if hr.isCustomer() {
+ return windows.Errno(uint32(e) ^ hrFailBit)
+ }
+
+ if hr.isNT() {
+ return e.AsNTStatus().Errno()
+ }
+
+ if hr.facility() == facilityWin32 {
+ return windows.Errno(hr.code())
+ }
+
+ if errno, ok := commonHRESULTToErrno[hr]; ok {
+ return errno
+ }
+
+ return f(hr)
+}
+
+// AsError converts the Error to a windows.Errno, but panics if not possible.
+func (e Error) AsErrno() windows.Errno {
+ handler := func(hr HRESULT) windows.Errno {
+ panic(fmt.Sprintf("wingoes.Error: Called AsErrno on a non-convertable HRESULT 0x%08X", uint32(hr)))
+ return windows.ERROR_UNIDENTIFIED_ERROR
+ }
+
+ return e.toErrno(handler)
+}
+
+type ntStatusFailHandler func(hr HRESULT) windows.NTStatus
+
+func (e Error) toNTStatus(f ntStatusFailHandler) windows.NTStatus {
+ hr := HRESULT(e)
+
+ if hr == hrS_OK {
+ return windows.STATUS_SUCCESS
+ }
+
+ if hr.isNT() {
+ return windows.NTStatus(hr ^ hrFacilityNTBit)
+ }
+
+ return f(hr)
+}
+
+// AsNTStatus converts the Error to a windows.NTStatus, but panics if not possible.
+func (e Error) AsNTStatus() windows.NTStatus {
+ handler := func(hr HRESULT) windows.NTStatus {
+ panic(fmt.Sprintf("windows.Error: Called AsNTStatus on a non-NTSTATUS HRESULT 0x%08X", uint32(hr)))
+ return windows.STATUS_UNSUCCESSFUL
+ }
+
+ return e.toNTStatus(handler)
+}
+
+// TryAsErrno converts the Error to a windows.Errno, or returns defval if
+// such a conversion is not possible.
+func (e Error) TryAsErrno(defval windows.Errno) windows.Errno {
+ handler := func(hr HRESULT) windows.Errno {
+ return defval
+ }
+
+ return e.toErrno(handler)
+}
+
+// TryAsNTStatus converts the Error to a windows.NTStatus, or returns defval if
+// such a conversion is not possible.
+func (e Error) TryAsNTStatus(defval windows.NTStatus) windows.NTStatus {
+ handler := func(hr HRESULT) windows.NTStatus {
+ return defval
+ }
+
+ return e.toNTStatus(handler)
+}
+
+// IsAvailableAsHRESULT returns true if e may be converted to an HRESULT.
+func (e Error) IsAvailableAsHRESULT() bool {
+ return true
+}
+
+// IsAvailableAsErrno returns true if e may be converted to a windows.Errno.
+func (e Error) IsAvailableAsErrno() bool {
+ hr := HRESULT(e)
+ if hr.isCustomer() || e.IsAvailableAsNTStatus() || (hr.facility() == facilityWin32) {
+ return true
+ }
+ _, convertable := commonHRESULTToErrno[hr]
+ return convertable
+}
+
+// IsAvailableAsNTStatus returns true if e may be converted to a windows.NTStatus.
+func (e Error) IsAvailableAsNTStatus() bool {
+ return HRESULT(e) == hrS_OK || HRESULT(e).isNT()
+}
+
+// Error produces a human-readable message describing Error e.
+func (e Error) Error() string {
+ if HRESULT(e).isCustomer() {
+ return windows.Errno(uint32(e) ^ hrFailBit).Error()
+ }
+
+ buf := make([]uint16, 300)
+ const flags = windows.FORMAT_MESSAGE_FROM_SYSTEM | windows.FORMAT_MESSAGE_IGNORE_INSERTS
+ lenExclNul, err := windows.FormatMessage(flags, 0, uint32(e), 0, buf, nil)
+ if err != nil {
+ return fmt.Sprintf("wingoes.Error 0x%08X", uint32(e))
+ }
+ for ; lenExclNul > 0 && (buf[lenExclNul-1] == '\n' || buf[lenExclNul-1] == '\r'); lenExclNul-- {
+ }
+ return windows.UTF16ToString(buf[:lenExclNul])
+}
+
+// Unwrap permits extraction of underlying windows.NTStatus or windows.Errno
+// errors that are encoded within e.
+func (e Error) Unwrap() error {
+ // Order is important! We need earlier checks to exclude certain things that
+ // would otherwise be (in this case) false positives in later checks!
+ switch {
+ case e.IsOK():
+ return nil
+ case e.IsAvailableAsNTStatus():
+ return e.AsNTStatus()
+ case e.IsAvailableAsErrno():
+ return e.AsErrno()
+ default:
+ return nil
+ }
+}
diff --git a/util/wingoes/guid.go b/util/wingoes/guid.go
new file mode 100644
index 0000000000000..da26361a273f9
--- /dev/null
+++ b/util/wingoes/guid.go
@@ -0,0 +1,15 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+package wingoes
+
+import (
+ "fmt"
+)
+
+func guidToString(guid GUID) string {
+ return fmt.Sprintf("{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
+ guid.Data1, guid.Data2, guid.Data3,
+ guid.Data4[0], guid.Data4[1],
+ guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7])
+}
diff --git a/util/wingoes/guid_notwindows.go b/util/wingoes/guid_notwindows.go
new file mode 100644
index 0000000000000..28d9da3385678
--- /dev/null
+++ b/util/wingoes/guid_notwindows.go
@@ -0,0 +1,17 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+//go:build !windows
+
+package wingoes
+
+type GUID struct {
+ Data1 uint32
+ Data2 uint16
+ Data3 uint16
+ Data4 [8]byte
+}
+
+func (guid GUID) String() string {
+ return guidToString(guid)
+}
diff --git a/util/wingoes/guid_windows.go b/util/wingoes/guid_windows.go
new file mode 100644
index 0000000000000..b05cf4c7382ed
--- /dev/null
+++ b/util/wingoes/guid_windows.go
@@ -0,0 +1,24 @@
+// 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.
+
+package wingoes
+
+import (
+ "fmt"
+
+ "golang.org/x/sys/windows"
+)
+
+type GUID = windows.GUID
+
+// MustGetGUID parses s, a string containing a GUID and returns a pointer to the
+// parsed GUID. s must be specified in the format "{XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}".
+// If there is an error parsing s, MustGetGUID panics.
+func MustGetGUID(s string) *windows.GUID {
+ guid, err := windows.GUIDFromString(s)
+ if err != nil {
+ panic(fmt.Sprintf("wingoes.MustGetGUID(%q) error %v", s, err))
+ }
+ return &guid
+}
diff --git a/util/wingoes/hresult.go b/util/wingoes/hresult.go
new file mode 100644
index 0000000000000..84f9caa11c730
--- /dev/null
+++ b/util/wingoes/hresult.go
@@ -0,0 +1,12 @@
+// 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.
+
+// Note this file is explicitly available on non-Windows platforms, in order to
+// aid `go generate` tooling on those platforms. It should not take a dependency
+// on x/sys/windows.
+
+package wingoes
+
+// HRESULT is equivalent to the HRESULT type in the Win32 SDK for C/C++.
+type HRESULT int32
diff --git a/util/wingoes/internal/types.go b/util/wingoes/internal/types.go
new file mode 100644
index 0000000000000..62fe249f1605e
--- /dev/null
+++ b/util/wingoes/internal/types.go
@@ -0,0 +1,13 @@
+// Copyright (c) 2023 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 windows
+
+package internal
+
+import (
+ "golang.org/x/sys/windows"
+)
+
+type HGLOBAL windows.Handle
diff --git a/util/wingoes/osversion.go b/util/wingoes/osversion.go
new file mode 100644
index 0000000000000..a9d679d56d82f
--- /dev/null
+++ b/util/wingoes/osversion.go
@@ -0,0 +1,204 @@
+// 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 windows
+
+package wingoes
+
+import (
+ "fmt"
+ "sync"
+
+ "golang.org/x/sys/windows"
+ "golang.org/x/sys/windows/registry"
+)
+
+var (
+ verOnce sync.Once
+ verInfo osVersionInfo // must access via getVersionInfo()
+)
+
+// osVersionInfo is more compact than windows.OsVersionInfoEx, which contains
+// extraneous information.
+type osVersionInfo struct {
+ major uint32
+ minor uint32
+ build uint32
+ servicePack uint16
+ str string
+ isDC bool
+ isServer bool
+}
+
+const (
+ _VER_NT_WORKSTATION = 1
+ _VER_NT_DOMAIN_CONTROLLER = 2
+ _VER_NT_SERVER = 3
+)
+
+func getVersionInfo() *osVersionInfo {
+ verOnce.Do(func() {
+ osv := windows.RtlGetVersion()
+ verInfo = osVersionInfo{
+ major: osv.MajorVersion,
+ minor: osv.MinorVersion,
+ build: osv.BuildNumber,
+ servicePack: osv.ServicePackMajor,
+ str: fmt.Sprintf("%d.%d.%d", osv.MajorVersion, osv.MinorVersion, osv.BuildNumber),
+ isDC: osv.ProductType == _VER_NT_DOMAIN_CONTROLLER,
+ // Domain Controllers are also implicitly servers.
+ isServer: osv.ProductType == _VER_NT_DOMAIN_CONTROLLER || osv.ProductType == _VER_NT_SERVER,
+ }
+ // UBR is only available on Windows 10 and 11 (MajorVersion == 10).
+ if osv.MajorVersion == 10 {
+ if ubr, err := getUBR(); err == nil {
+ verInfo.str = fmt.Sprintf("%s.%d", verInfo.str, ubr)
+ }
+ }
+ })
+ return &verInfo
+}
+
+// getUBR returns the "update build revision," ie. the fourth component of the
+// version string found on Windows 10 and Windows 11 systems.
+func getUBR() (uint32, error) {
+ key, err := registry.OpenKey(registry.LOCAL_MACHINE,
+ `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE|registry.WOW64_64KEY)
+ if err != nil {
+ return 0, err
+ }
+ defer key.Close()
+
+ val, valType, err := key.GetIntegerValue("UBR")
+ if err != nil {
+ return 0, err
+ }
+ if valType != registry.DWORD {
+ return 0, registry.ErrUnexpectedType
+ }
+
+ return uint32(val), nil
+}
+
+// GetOSVersionString returns the Windows version of the current machine in
+// dotted-decimal form. The version string contains 3 components on Windows 7
+// and 8.x, and 4 components on Windows 10 and 11.
+func GetOSVersionString() string {
+ return getVersionInfo().String()
+}
+
+// IsWinServer returns true if and only if this computer's version of Windows is
+// a server edition.
+func IsWinServer() bool {
+ return getVersionInfo().isServer
+}
+
+// IsWinDomainController returs true if this computer's version of Windows is
+// configured to act as a domain controller.
+func IsWinDomainController() bool {
+ return getVersionInfo().isDC
+}
+
+// IsWin7SP1OrGreater returns true when running on Windows 7 SP1 or newer.
+func IsWin7SP1OrGreater() bool {
+ if IsWin8OrGreater() {
+ return true
+ }
+
+ vi := getVersionInfo()
+ return vi.major == 6 && vi.minor == 1 && vi.servicePack > 0
+}
+
+// IsWin8OrGreater returns true when running on Windows 8.0 or newer.
+func IsWin8OrGreater() bool {
+ return getVersionInfo().isVersionOrGreater(6, 2, 0)
+}
+
+// IsWin8Point1OrGreater returns true when running on Windows 8.1 or newer.
+func IsWin8Point1OrGreater() bool {
+ return getVersionInfo().isVersionOrGreater(6, 3, 0)
+}
+
+// IsWin10OrGreater returns true when running on any build of Windows 10 or newer.
+func IsWin10OrGreater() bool {
+ return getVersionInfo().major >= 10
+}
+
+// Win10BuildConstant encodes build numbers for the various editions of Windows 10,
+// for use with IsWin10BuildOrGreater.
+type Win10BuildConstant uint32
+
+const (
+ Win10BuildRTM = Win10BuildConstant(10240)
+ Win10Build1511 = Win10BuildConstant(10586)
+ Win10Build1607 = Win10BuildConstant(14393)
+ WinServer2016 = Win10Build1607
+ Win10BuildAnniversary = Win10Build1607
+ Win10Build1703 = Win10BuildConstant(15063)
+ Win10BuildCreators = Win10Build1703
+ Win10Build1709 = Win10BuildConstant(16299)
+ Win10BuildFallCreators = Win10Build1709
+ Win10Build1803 = Win10BuildConstant(17134)
+ Win10Build1809 = Win10BuildConstant(17763)
+ WinServer2019 = Win10Build1809
+ Win10Build1903 = Win10BuildConstant(18362)
+ Win10Build1909 = Win10BuildConstant(18363)
+ Win10Build2004 = Win10BuildConstant(19041)
+ Win10Build20H2 = Win10BuildConstant(19042)
+ Win10Build21H1 = Win10BuildConstant(19043)
+ Win10Build21H2 = Win10BuildConstant(19044)
+ Win10Build22H2 = Win10BuildConstant(19045)
+ WinServer2022 = Win10BuildConstant(20348)
+)
+
+// IsWin10BuildOrGreater returns true when running on the specified Windows 10
+// build, or newer.
+func IsWin10BuildOrGreater(build Win10BuildConstant) bool {
+ return getVersionInfo().isWin10BuildOrGreater(uint32(build))
+}
+
+// Win11BuildConstant encodes build numbers for the various editions of Windows 11,
+// for use with IsWin11BuildOrGreater.
+type Win11BuildConstant uint32
+
+const (
+ Win11BuildRTM = Win11BuildConstant(22000)
+ Win11Build22H2 = Win11BuildConstant(22621)
+ Win11Build23H2 = Win11BuildConstant(22631)
+ Win11Build24H2 = Win11BuildConstant(26100)
+ WinServer2025 = Win11Build24H2
+)
+
+// IsWin11OrGreater returns true when running on any release of Windows 11,
+// or newer.
+func IsWin11OrGreater() bool {
+ return IsWin11BuildOrGreater(Win11BuildRTM)
+}
+
+// IsWin11BuildOrGreater returns true when running on the specified Windows 11
+// build, or newer.
+func IsWin11BuildOrGreater(build Win11BuildConstant) bool {
+ // Under the hood, Windows 11 is just Windows 10 with a sufficiently advanced
+ // build number.
+ return getVersionInfo().isWin10BuildOrGreater(uint32(build))
+}
+
+func (osv *osVersionInfo) String() string {
+ return osv.str
+}
+
+func (osv *osVersionInfo) isWin10BuildOrGreater(build uint32) bool {
+ return osv.isVersionOrGreater(10, 0, build)
+}
+
+func (osv *osVersionInfo) isVersionOrGreater(major, minor, build uint32) bool {
+ return isVerGE(osv.major, major, osv.minor, minor, osv.build, build)
+}
+
+func isVerGE(lmajor, rmajor, lminor, rminor, lbuild, rbuild uint32) bool {
+ return lmajor > rmajor ||
+ lmajor == rmajor &&
+ (lminor > rminor ||
+ lminor == rminor && lbuild >= rbuild)
+}
diff --git a/util/wingoes/pe/mksyscall_test.go b/util/wingoes/pe/mksyscall_test.go
new file mode 100644
index 0000000000000..a7225e035a928
--- /dev/null
+++ b/util/wingoes/pe/mksyscall_test.go
@@ -0,0 +1,47 @@
+//go:build ignore
+
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+package pe
+
+//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows_test.go mksyscall_test.go
+//go:generate go run golang.org/x/tools/cmd/goimports -w zsyscall_windows_test.go
+
+import (
+ "github.com/metacubex/tailscale/util/wingoes"
+ "golang.org/x/sys/windows"
+)
+
+const (
+ // This constant is only valid when used with imagehlp
+ _CERT_SECTION_TYPE_ANY WIN_CERT_TYPE = 0x00FF
+)
+
+type _SYMSRV_INDEX_INFO struct {
+ SizeOfStruct uint32
+ File [windows.MAX_PATH + 1]uint16
+ Stripped int32 // Win32 BOOL
+ Timestamp uint32
+ Size uint32
+ DBGFile [windows.MAX_PATH + 1]uint16
+ PDBFile [windows.MAX_PATH + 1]uint16
+ GUID wingoes.GUID
+ Sig uint32
+ Age uint32
+}
+
+// _IMAGE_NT_HEADERS_FIXED is IMAGE_NT_HEADERS sans OptionalHeader, whose
+// layout differs between 32 and 64 bit implementations.
+type _IMAGE_NT_HEADERS_FIXED struct {
+ Signature uint32
+ FileHeader FileHeader
+}
+
+//sys imageDirectoryEntryToDataEx(base uintptr, mappedAsImage byte, directoryEntry uint16, size *uint32, foundHeader *SectionHeader) (ret uintptr, err error) [failretval==0] = dbghelp.ImageDirectoryEntryToDataEx
+//sys imageEnumerateCertificates(fileHandle windows.Handle, typeFilter WIN_CERT_TYPE, certificateCount *uint32, indices *uint32, indexCount uint32) (err error) [int32(failretval)==0] = imagehlp.ImageEnumerateCertificates
+//sys imageGetCertificateData(fileHandle windows.Handle, certificateIndex uint32, certificate *byte, requiredLength *uint32) (err error) [int32(failretval)==0] = imagehlp.ImageGetCertificateData
+//sys imageNtHeader(base uintptr) (ret *_IMAGE_NT_HEADERS_FIXED, err error) [failretval==nil] = dbghelp.ImageNtHeader
+// TODO(aaron): Maybe use to test resolveRVA?
+// imageSectionHeader(ntHeaders *_IMAGE_NT_HEADERS_FIXED, base uintptr, rva uint32) (ret *SectionHeader, err error) [failretval==nil] = dbghelp.ImageRvaToSection
+//sys symSrvGetFileIndexInfo(file *uint16, info *_SYMSRV_INDEX_INFO, flags uint32) (err error) [int32(failretval)==0] = dbghelp.SymSrvGetFileIndexInfoW?
diff --git a/util/wingoes/pe/oh.go b/util/wingoes/pe/oh.go
new file mode 100644
index 0000000000000..336d00a171952
--- /dev/null
+++ b/util/wingoes/pe/oh.go
@@ -0,0 +1,262 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+package pe
+
+import (
+ dpe "debug/pe"
+ "unsafe"
+)
+
+// OptionalHeader provides the fields of a PE/COFF optional header. Since the
+// underlying format differs depending on whether the PE binary is 32-bit or
+// 64-bit, this type provides a unified interface.
+type OptionalHeader interface {
+ GetMagic() uint16
+ GetLinkerVersion() (major, minor uint8)
+ GetSizeOfCode() uint32
+ GetSizeOfInitializedData() uint32
+ GetSizeOfUninitializedData() uint32
+ GetAddressOfEntryPoint() uint32
+ GetBaseOfCode() uint32
+ GetImageBase() uint64
+ GetSectionAlignment() uint32
+ GetFileAlignment() uint32
+ GetOperatingSystemVersion() (major, minor uint16)
+ GetImageVersion() (major, minor uint16)
+ GetSubsystemVersion() (major, minor uint16)
+ GetWin32Version() uint32
+ GetSizeOfImage() uint32
+ GetSizeOfHeaders() uint32
+ GetCheckSum() uint32
+ GetSubsystem() uint16
+ GetDllCharacteristics() uint16
+ GetSizeOfStackReserve() uint64
+ GetSizeOfStackCommit() uint64
+ GetSizeOfHeapReserve() uint64
+ GetSizeOfHeapCommit() uint64
+ GetLoaderFlags() uint32
+ GetDataDirectory() []DataDirectoryEntry
+
+ SizeOf() uint16 // Size of the underlying struct, in bytes
+}
+
+type optionalHeader32 dpe.OptionalHeader32
+
+func (oh *optionalHeader32) GetMagic() uint16 {
+ return oh.Magic
+}
+
+func (oh *optionalHeader32) GetLinkerVersion() (major, minor uint8) {
+ return oh.MajorLinkerVersion, oh.MinorLinkerVersion
+}
+
+func (oh *optionalHeader32) GetSizeOfCode() uint32 {
+ return oh.SizeOfCode
+}
+
+func (oh *optionalHeader32) GetSizeOfInitializedData() uint32 {
+ return oh.SizeOfInitializedData
+}
+
+func (oh *optionalHeader32) GetSizeOfUninitializedData() uint32 {
+ return oh.SizeOfUninitializedData
+}
+
+func (oh *optionalHeader32) GetAddressOfEntryPoint() uint32 {
+ return oh.AddressOfEntryPoint
+}
+
+func (oh *optionalHeader32) GetBaseOfCode() uint32 {
+ return oh.BaseOfCode
+}
+
+func (oh *optionalHeader32) GetImageBase() uint64 {
+ return uint64(oh.ImageBase)
+}
+
+func (oh *optionalHeader32) GetSectionAlignment() uint32 {
+ return oh.SectionAlignment
+}
+
+func (oh *optionalHeader32) GetFileAlignment() uint32 {
+ return oh.FileAlignment
+}
+
+func (oh *optionalHeader32) GetOperatingSystemVersion() (major, minor uint16) {
+ return oh.MajorOperatingSystemVersion, oh.MinorOperatingSystemVersion
+}
+
+func (oh *optionalHeader32) GetImageVersion() (major, minor uint16) {
+ return oh.MajorImageVersion, oh.MinorImageVersion
+}
+
+func (oh *optionalHeader32) GetSubsystemVersion() (major, minor uint16) {
+ return oh.MajorSubsystemVersion, oh.MinorSubsystemVersion
+}
+
+func (oh *optionalHeader32) GetWin32Version() uint32 {
+ return oh.Win32VersionValue
+}
+
+func (oh *optionalHeader32) GetSizeOfImage() uint32 {
+ return oh.SizeOfImage
+}
+
+func (oh *optionalHeader32) GetSizeOfHeaders() uint32 {
+ return oh.SizeOfHeaders
+}
+
+func (oh *optionalHeader32) GetCheckSum() uint32 {
+ return oh.CheckSum
+}
+
+func (oh *optionalHeader32) GetSubsystem() uint16 {
+ return oh.Subsystem
+}
+
+func (oh *optionalHeader32) GetDllCharacteristics() uint16 {
+ return oh.DllCharacteristics
+}
+
+func (oh *optionalHeader32) GetSizeOfStackReserve() uint64 {
+ return uint64(oh.SizeOfStackReserve)
+}
+
+func (oh *optionalHeader32) GetSizeOfStackCommit() uint64 {
+ return uint64(oh.SizeOfStackCommit)
+}
+
+func (oh *optionalHeader32) GetSizeOfHeapReserve() uint64 {
+ return uint64(oh.SizeOfHeapReserve)
+}
+
+func (oh *optionalHeader32) GetSizeOfHeapCommit() uint64 {
+ return uint64(oh.SizeOfHeapCommit)
+}
+
+func (oh *optionalHeader32) GetLoaderFlags() uint32 {
+ return oh.LoaderFlags
+}
+
+func (oh *optionalHeader32) GetDataDirectory() []DataDirectoryEntry {
+ cnt := oh.NumberOfRvaAndSizes
+ if maxCnt := uint32(len(oh.DataDirectory)); cnt > maxCnt {
+ cnt = maxCnt
+ }
+ return oh.DataDirectory[:cnt]
+}
+
+func (oh *optionalHeader32) SizeOf() uint16 {
+ return uint16(unsafe.Sizeof(*oh))
+}
+
+type optionalHeader64 dpe.OptionalHeader64
+
+func (oh *optionalHeader64) GetMagic() uint16 {
+ return oh.Magic
+}
+
+func (oh *optionalHeader64) GetLinkerVersion() (major, minor uint8) {
+ return oh.MajorLinkerVersion, oh.MinorLinkerVersion
+}
+
+func (oh *optionalHeader64) GetSizeOfCode() uint32 {
+ return oh.SizeOfCode
+}
+
+func (oh *optionalHeader64) GetSizeOfInitializedData() uint32 {
+ return oh.SizeOfInitializedData
+}
+
+func (oh *optionalHeader64) GetSizeOfUninitializedData() uint32 {
+ return oh.SizeOfUninitializedData
+}
+
+func (oh *optionalHeader64) GetAddressOfEntryPoint() uint32 {
+ return oh.AddressOfEntryPoint
+}
+
+func (oh *optionalHeader64) GetBaseOfCode() uint32 {
+ return oh.BaseOfCode
+}
+
+func (oh *optionalHeader64) GetImageBase() uint64 {
+ return oh.ImageBase
+}
+
+func (oh *optionalHeader64) GetSectionAlignment() uint32 {
+ return oh.SectionAlignment
+}
+
+func (oh *optionalHeader64) GetFileAlignment() uint32 {
+ return oh.FileAlignment
+}
+
+func (oh *optionalHeader64) GetOperatingSystemVersion() (major, minor uint16) {
+ return oh.MajorOperatingSystemVersion, oh.MinorOperatingSystemVersion
+}
+
+func (oh *optionalHeader64) GetImageVersion() (major, minor uint16) {
+ return oh.MajorImageVersion, oh.MinorImageVersion
+}
+
+func (oh *optionalHeader64) GetSubsystemVersion() (major, minor uint16) {
+ return oh.MajorSubsystemVersion, oh.MinorSubsystemVersion
+}
+
+func (oh *optionalHeader64) GetWin32Version() uint32 {
+ return oh.Win32VersionValue
+}
+
+func (oh *optionalHeader64) GetSizeOfImage() uint32 {
+ return oh.SizeOfImage
+}
+
+func (oh *optionalHeader64) GetSizeOfHeaders() uint32 {
+ return oh.SizeOfHeaders
+}
+
+func (oh *optionalHeader64) GetCheckSum() uint32 {
+ return oh.CheckSum
+}
+
+func (oh *optionalHeader64) GetSubsystem() uint16 {
+ return oh.Subsystem
+}
+
+func (oh *optionalHeader64) GetDllCharacteristics() uint16 {
+ return oh.DllCharacteristics
+}
+
+func (oh *optionalHeader64) GetSizeOfStackReserve() uint64 {
+ return oh.SizeOfStackReserve
+}
+
+func (oh *optionalHeader64) GetSizeOfStackCommit() uint64 {
+ return oh.SizeOfStackCommit
+}
+
+func (oh *optionalHeader64) GetSizeOfHeapReserve() uint64 {
+ return oh.SizeOfHeapReserve
+}
+
+func (oh *optionalHeader64) GetSizeOfHeapCommit() uint64 {
+ return oh.SizeOfHeapCommit
+}
+
+func (oh *optionalHeader64) GetLoaderFlags() uint32 {
+ return oh.LoaderFlags
+}
+
+func (oh *optionalHeader64) GetDataDirectory() []DataDirectoryEntry {
+ cnt := oh.NumberOfRvaAndSizes
+ if maxCnt := uint32(len(oh.DataDirectory)); cnt > maxCnt {
+ cnt = maxCnt
+ }
+ return oh.DataDirectory[:cnt]
+}
+
+func (oh *optionalHeader64) SizeOf() uint16 {
+ return uint16(unsafe.Sizeof(*oh))
+}
diff --git a/util/wingoes/pe/pe.go b/util/wingoes/pe/pe.go
new file mode 100644
index 0000000000000..55caad66f2d2d
--- /dev/null
+++ b/util/wingoes/pe/pe.go
@@ -0,0 +1,785 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Package pe provides facilities for extracting information from PE binaries.
+// It only supports the same CPU architectures as the rest of wingoes.
+package pe
+
+import (
+ "bufio"
+ "bytes"
+ dpe "debug/pe"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+ "math"
+ "math/bits"
+ "os"
+ "reflect"
+ "strings"
+ "unsafe"
+
+ "github.com/metacubex/tailscale/util/wingoes"
+ "golang.org/x/exp/constraints"
+)
+
+// The following constants are from the PE spec
+const (
+ maxNumSections = 96
+ mzSignature = uint16(0x5A4D) // little-endian
+ offsetIMAGE_DOS_HEADERe_lfanew = 0x3C
+ peSignature = uint32(0x00004550) // little-endian
+)
+
+var (
+ // ErrBadLength is returned when the actual length of a data field in the
+ // binary is shorter than the expected length of that field.
+ ErrBadLength = errors.New("effective length did not match expected length")
+ // ErrBadCodeView is returned by (*PEHeaders).ExtractCodeViewInfo if the data
+ // at the requested address does not appear to contain valid CodeView information.
+ ErrBadCodeView = errors.New("invalid CodeView debug info")
+ // ErrIndexOutOfRange is returned by (*PEHeaders).DataDirectoryEntry if the
+ // specified index is greater than the maximum allowable index.
+ ErrIndexOutOfRange = errors.New("index out of range")
+ // ErrInvalidBinary is returned whenever the headers do not parse as expected,
+ // or reference locations outside the bounds of the PE file or module.
+ // The headers might be corrupt, malicious, or have been tampered with.
+ ErrInvalidBinary = errors.New("invalid PE binary")
+ // ErrBadCodeView is returned by (*PEHeaders).ExtractCodeViewInfo if the data
+ // at the requested address contains a non-CodeView debug info format.
+ ErrNotCodeView = errors.New("debug info is not CodeView")
+ // ErrIndexOutOfRange is returned by (*PEHeaders).DataDirectoryEntry if the
+ // corresponding entry is not populated in the PE image.
+ ErrNotPresent = errors.New("not present in this PE image")
+ // ErrResolvingFileRVA is returned when the result of arithmetic on a relative
+ // virtual address did not resolve to a valid RVA.
+ ErrResolvingFileRVA = errors.New("could not resolve file RVA")
+ // ErrUnavailableInModule is returned when requesting data from the binary
+ // that is not mapped into memory when loaded. The information must be
+ // loaded from a file-based PEHeaders.
+ ErrUnavailableInModule = errors.New("this information is unavailable from loaded modules; the PE file itself must be examined")
+ // ErrUnsupportedMachine is returned if the binary's CPU architecture is
+ // unsupported. This package currently implements support for x86, amd64,
+ // and arm64.
+ ErrUnsupportedMachine = errors.New("unsupported machine")
+)
+
+// FileHeader is the PE/COFF IMAGE_FILE_HEADER structure.
+type FileHeader dpe.FileHeader
+
+// SectionHeader is the PE/COFF IMAGE_SECTION_HEADER structure.
+type SectionHeader dpe.SectionHeader32
+
+// NameString returns the name of s as a Go string.
+func (s *SectionHeader) NameString() string {
+ // s.Name is UTF-8. When the string's length is < len(s.Name), the remaining
+ // bytes are padded with zeros.
+ for i, c := range s.Name {
+ if c == 0 {
+ return string(s.Name[:i])
+ }
+ }
+
+ return string(s.Name[:])
+}
+
+type peReaderBase interface {
+ io.ReaderAt
+ io.ReadSeeker
+}
+
+type peReader interface {
+ peReaderBase
+ io.Closer
+ Base() uintptr
+ Limit() uintptr
+}
+
+// PEHeaders represents the partially-parsed headers from a PE binary.
+type PEHeaders struct {
+ r peReader
+ fileHeader *FileHeader
+ optionalHeader OptionalHeader
+ sections []SectionHeader
+}
+
+// FileHeader returns the FileHeader that was parsed from peh.
+func (peh *PEHeaders) FileHeader() *FileHeader {
+ return peh.fileHeader
+}
+
+// FileHeader returns the OptionalHeader that was parsed from peh.
+func (peh *PEHeaders) OptionalHeader() OptionalHeader {
+ return peh.optionalHeader
+}
+
+// Sections returns a slice containing all section headers parsed from peh.
+func (peh *PEHeaders) Sections() []SectionHeader {
+ return peh.sections
+}
+
+// DataDirectoryEntry is a PE/COFF IMAGE_DATA_DIRECTORY structure.
+type DataDirectoryEntry = dpe.DataDirectory
+
+func resolveOptionalHeader(machine uint16, r peReader, offset uint32) (OptionalHeader, error) {
+ switch machine {
+ case dpe.IMAGE_FILE_MACHINE_I386:
+ return readStruct[optionalHeader32](r, offset)
+ case dpe.IMAGE_FILE_MACHINE_AMD64, dpe.IMAGE_FILE_MACHINE_ARM64:
+ return readStruct[optionalHeader64](r, offset)
+ default:
+ return nil, ErrUnsupportedMachine
+ }
+}
+
+func checkMagic(oh OptionalHeader, machine uint16) bool {
+ var expectedMagic uint16
+ switch machine {
+ case dpe.IMAGE_FILE_MACHINE_I386:
+ expectedMagic = 0x010B
+ case dpe.IMAGE_FILE_MACHINE_AMD64, dpe.IMAGE_FILE_MACHINE_ARM64:
+ expectedMagic = 0x020B
+ default:
+ panic(fmt.Sprintf("unsupported machine 0x%04X", machine))
+ }
+
+ return oh.GetMagic() == expectedMagic
+}
+
+type peBounds struct {
+ base uintptr
+ limit uintptr
+}
+
+type peFile struct {
+ peReaderBase
+ peBounds
+}
+
+func (pef *peFile) Close() error {
+ if cl, ok := pef.peReaderBase.(io.Closer); ok {
+ return cl.Close()
+ }
+ return nil
+}
+
+func (pef *peFile) Base() uintptr {
+ return pef.base
+}
+
+func (pef *peFile) Limit() uintptr {
+ return pef.limit
+}
+
+type peModule struct {
+ *bytes.Reader
+ peBounds
+ modLock uintptr
+}
+
+func (pei *peModule) Base() uintptr {
+ return pei.base
+}
+
+func (pei *peModule) Limit() uintptr {
+ return pei.limit
+}
+
+// NewPEFromFileName opens a PE binary located at filename and parses its PE
+// headers. Upon success it returns a non-nil *PEHeaders, otherwise it returns a
+// nil *PEHeaders and a non-nil error.
+// Call Close() on the returned *PEHeaders when it is no longer needed.
+func NewPEFromFileName(filename string) (*PEHeaders, error) {
+ f, err := os.Open(filename)
+ if err != nil {
+ return nil, err
+ }
+
+ return newPEFromFile(f)
+}
+
+func newPEFromFile(f *os.File) (*PEHeaders, error) {
+ fi, err := f.Stat()
+ if err != nil {
+ f.Close()
+ return nil, err
+ }
+
+ return newPEFromReaderBase(f, uintptr(fi.Size()))
+}
+
+func newPEFromReaderBase(rb peReaderBase, size uintptr) (*PEHeaders, error) {
+ // peBounds base is 0, limit is size
+ pef := &peFile{peReaderBase: rb, peBounds: peBounds{limit: size}}
+ peh, err := loadHeaders(pef)
+ if err != nil {
+ pef.Close()
+ return nil, err
+ }
+
+ return peh, nil
+}
+
+// NewPEFromBlob parses the PE headers in blob. Upon success it returns a
+// non-nil *PEHeaders, otherwise it returns a nil *PEHeaders and a non-nil error.
+// Call Close() on the returned *PEHeaders when it is no longer needed.
+func NewPEFromBlob(blob []byte) (*PEHeaders, error) {
+ return newPEFromReaderBase(bytes.NewReader(blob), uintptr(len(blob)))
+}
+
+// Close frees any resources that were opened when peh was created.
+func (peh *PEHeaders) Close() error {
+ return peh.r.Close()
+}
+
+type rvaType interface {
+ ~int8 | ~int16 | ~int32 | ~uint8 | ~uint16 | ~uint32
+}
+
+// addOffset ensures that off neither overflows nor underflows base.
+func addOffset[O rvaType](base uintptr, off O) (addr uintptr, ok bool) {
+ if off >= 0 {
+ if upoff := uintptr(off); upoff <= (math.MaxUint - base) {
+ return base + upoff, true
+ }
+ return 0, false
+ }
+
+ negation := uintptr(-off)
+ if negation >= base {
+ return 0, false
+ }
+ return base - negation, true
+}
+
+func binaryRead(r io.Reader, data any) (err error) {
+ // Supported Windows archs are now always LittleEndian
+ err = binary.Read(r, binary.LittleEndian, data)
+ if err == io.ErrUnexpectedEOF {
+ err = ErrBadLength
+ }
+ return err
+}
+
+// readStruct reads a T from offset rva. If r is a *peModule, the returned *T
+// points to the data in-place.
+// Note that currently this function will fail if rva references memory beyond
+// the bounds of the binary; in the case of modules, this may need to be relaxed
+// in some cases due to tampering by third-party crapware.
+func readStruct[T any, R rvaType](r peReader, rva R) (*T, error) {
+ switch v := r.(type) {
+ case *peFile:
+ if _, err := r.Seek(int64(rva), io.SeekStart); err != nil {
+ return nil, err
+ }
+
+ result := new(T)
+ if err := binaryRead(r, result); err != nil {
+ return nil, err
+ }
+
+ return result, nil
+ case *peModule:
+ addr, ok := addOffset(r.Base(), rva)
+ if !ok {
+ return nil, ErrInvalidBinary
+ }
+ szT := uint32(unsafe.Sizeof(*((*T)(nil))))
+ if addr2, ok := addOffset(addr, szT); !ok || addr2 >= v.Limit() {
+ return nil, ErrInvalidBinary
+ }
+
+ return (*T)(unsafe.Pointer(addr)), nil
+ default:
+ return nil, os.ErrInvalid
+ }
+}
+
+// readStructArray reads a []T with length count from offset rva. If r is a
+// *peModule, the returned []T references the data in-place.
+// Note that currently this function will fail if rva references memory beyond
+// the bounds of the binary; in the case of modules, this may need to be relaxed
+// in some cases due to tampering by third-party crapware.
+func readStructArray[T any, R rvaType](r peReader, rva R, count int) ([]T, error) {
+ switch v := r.(type) {
+ case *peFile:
+ if _, err := r.Seek(int64(rva), io.SeekStart); err != nil {
+ return nil, err
+ }
+
+ result := make([]T, count)
+ if err := binaryRead(r, result); err != nil {
+ return nil, err
+ }
+
+ return result, nil
+ case *peModule:
+ addr, ok := addOffset(r.Base(), rva)
+ if !ok {
+ return nil, ErrInvalidBinary
+ }
+ szT := uint32(reflect.ArrayOf(count, reflect.TypeOf((*T)(nil)).Elem()).Size())
+ if addr2, ok := addOffset(addr, szT); !ok || addr2 >= v.Limit() {
+ return nil, ErrInvalidBinary
+ }
+
+ return unsafe.Slice((*T)(unsafe.Pointer(addr)), count), nil
+ default:
+ return nil, os.ErrInvalid
+ }
+}
+
+func loadHeaders(r peReader) (*PEHeaders, error) {
+ // Check the signature of the DOS stub header
+ if _, err := r.Seek(0, io.SeekStart); err != nil {
+ return nil, err
+ }
+
+ var mz uint16
+ if err := binaryRead(r, &mz); err != nil {
+ if err == ErrBadLength {
+ err = ErrInvalidBinary
+ }
+ return nil, err
+ }
+ if mz != mzSignature {
+ return nil, ErrInvalidBinary
+ }
+
+ // Seek to the offset of the value that points to the beginning of the PE headers
+ if _, err := r.Seek(offsetIMAGE_DOS_HEADERe_lfanew, io.SeekStart); err != nil {
+ return nil, ErrInvalidBinary
+ }
+
+ // Load the offset to the beginning of the PE headers
+ var e_lfanew int32
+ if err := binaryRead(r, &e_lfanew); err != nil {
+ if err == ErrBadLength {
+ err = ErrInvalidBinary
+ }
+ return nil, err
+ }
+ if e_lfanew <= 0 {
+ return nil, ErrInvalidBinary
+ }
+ if addr, ok := addOffset(r.Base(), e_lfanew); !ok || addr >= r.Limit() {
+ return nil, ErrInvalidBinary
+ }
+
+ // Check the PE signature
+ if _, err := r.Seek(int64(e_lfanew), io.SeekStart); err != nil {
+ return nil, ErrInvalidBinary
+ }
+
+ var pe uint32
+ if err := binaryRead(r, &pe); err != nil {
+ if err == ErrBadLength {
+ err = ErrInvalidBinary
+ }
+ return nil, err
+ }
+ if pe != peSignature {
+ return nil, ErrInvalidBinary
+ }
+
+ // Read the file header
+ fileHeaderOffset := uint32(e_lfanew) + uint32(unsafe.Sizeof(pe))
+ if addr, ok := addOffset(r.Base(), fileHeaderOffset); !ok || addr >= r.Limit() {
+ return nil, ErrInvalidBinary
+ }
+
+ fileHeader, err := readStruct[FileHeader](r, fileHeaderOffset)
+ if err != nil {
+ return nil, err
+ }
+
+ machine := fileHeader.Machine
+ if !checkMachine(r, machine) {
+ return nil, ErrUnsupportedMachine
+ }
+
+ // Read the optional header
+ optionalHeaderOffset := uint32(fileHeaderOffset) + uint32(unsafe.Sizeof(*fileHeader))
+ if addr, ok := addOffset(r.Base(), optionalHeaderOffset); !ok || addr >= r.Limit() {
+ return nil, ErrInvalidBinary
+ }
+
+ optionalHeader, err := resolveOptionalHeader(machine, r, optionalHeaderOffset)
+ if err != nil {
+ return nil, err
+ }
+
+ if !checkMagic(optionalHeader, machine) {
+ return nil, ErrInvalidBinary
+ }
+
+ if fileHeader.SizeOfOptionalHeader < optionalHeader.SizeOf() {
+ return nil, ErrInvalidBinary
+ }
+
+ // Coarse-grained check that header sizes make sense
+ totalEssentialHeaderLen := uint32(offsetIMAGE_DOS_HEADERe_lfanew) +
+ uint32(unsafe.Sizeof(e_lfanew)) +
+ uint32(unsafe.Sizeof(*fileHeader)) +
+ uint32(fileHeader.SizeOfOptionalHeader)
+ if optionalHeader.GetSizeOfImage() < totalEssentialHeaderLen {
+ return nil, ErrInvalidBinary
+ }
+
+ numSections := fileHeader.NumberOfSections
+ if numSections > maxNumSections {
+ // More than 96 sections?! Really?!
+ return nil, ErrInvalidBinary
+ }
+
+ // Read in the section table
+ sectionTableOffset := optionalHeaderOffset + uint32(fileHeader.SizeOfOptionalHeader)
+ if addr, ok := addOffset(r.Base(), sectionTableOffset); !ok || addr >= r.Limit() {
+ return nil, ErrInvalidBinary
+ }
+
+ sections, err := readStructArray[SectionHeader](r, sectionTableOffset, int(numSections))
+ if err != nil {
+ return nil, err
+ }
+
+ return &PEHeaders{r: r, fileHeader: fileHeader, optionalHeader: optionalHeader, sections: sections}, nil
+}
+
+type rva32 interface {
+ ~int32 | ~uint32
+}
+
+// resolveRVA resolves rva, or returns 0 if unavailable.
+func resolveRVA[R rva32](nfo *PEHeaders, rva R) R {
+ if _, ok := nfo.r.(*peFile); !ok {
+ // Just the identity function in this case.
+ return rva
+ }
+
+ if rva <= 0 {
+ return 0
+ }
+
+ // We walk the section table, locating the section that would contain rva if
+ // we were mapped into memory. We then calculate the offset of rva from the
+ // starting virtual address of the section, and then add that offset to the
+ // section's starting file pointer.
+ urva := uint32(rva)
+ for _, s := range nfo.sections {
+ if urva < s.VirtualAddress {
+ continue
+ }
+ if urva >= (s.VirtualAddress + s.VirtualSize) {
+ continue
+ }
+ voff := urva - s.VirtualAddress
+ foff := s.PointerToRawData + voff
+ if foff >= s.PointerToRawData+s.SizeOfRawData {
+ return 0
+ }
+ return R(foff)
+ }
+
+ return 0
+}
+
+// DataDirectoryIndex is an enumeration specifying a particular entry in the
+// data directory.
+type DataDirectoryIndex int
+
+const (
+ IMAGE_DIRECTORY_ENTRY_EXPORT = DataDirectoryIndex(dpe.IMAGE_DIRECTORY_ENTRY_EXPORT)
+ IMAGE_DIRECTORY_ENTRY_IMPORT = DataDirectoryIndex(dpe.IMAGE_DIRECTORY_ENTRY_IMPORT)
+ IMAGE_DIRECTORY_ENTRY_RESOURCE = DataDirectoryIndex(dpe.IMAGE_DIRECTORY_ENTRY_RESOURCE)
+ IMAGE_DIRECTORY_ENTRY_EXCEPTION = DataDirectoryIndex(dpe.IMAGE_DIRECTORY_ENTRY_EXCEPTION)
+ IMAGE_DIRECTORY_ENTRY_SECURITY = DataDirectoryIndex(dpe.IMAGE_DIRECTORY_ENTRY_SECURITY)
+ IMAGE_DIRECTORY_ENTRY_BASERELOC = DataDirectoryIndex(dpe.IMAGE_DIRECTORY_ENTRY_BASERELOC)
+ IMAGE_DIRECTORY_ENTRY_DEBUG = DataDirectoryIndex(dpe.IMAGE_DIRECTORY_ENTRY_DEBUG)
+ IMAGE_DIRECTORY_ENTRY_ARCHITECTURE = DataDirectoryIndex(dpe.IMAGE_DIRECTORY_ENTRY_ARCHITECTURE)
+ IMAGE_DIRECTORY_ENTRY_GLOBALPTR = DataDirectoryIndex(dpe.IMAGE_DIRECTORY_ENTRY_GLOBALPTR)
+ IMAGE_DIRECTORY_ENTRY_TLS = DataDirectoryIndex(dpe.IMAGE_DIRECTORY_ENTRY_TLS)
+ IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = DataDirectoryIndex(dpe.IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG)
+ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = DataDirectoryIndex(dpe.IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT)
+ IMAGE_DIRECTORY_ENTRY_IAT = DataDirectoryIndex(dpe.IMAGE_DIRECTORY_ENTRY_IAT)
+ IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT = DataDirectoryIndex(dpe.IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT)
+ IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = DataDirectoryIndex(dpe.IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR)
+)
+
+const _IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16
+
+// DataDirectoryEntry returns information from nfo's data directory at index idx.
+// The type of the return value depends on the value of idx. Most values for idx
+// currently return the DataDirectoryEntry itself, however it will return more
+// sophisticated information for the following values of idx:
+//
+// * IMAGE_DIRECTORY_ENTRY_SECURITY returns []AuthenticodeCert
+// * IMAGE_DIRECTORY_ENTRY_DEBUG returns []IMAGE_DEBUG_DIRECTORY
+//
+// Note that other idx values _will_ be modified in the future to support more
+// sophisticated return values, so be careful to structure your type assertions
+// accordingly.
+func (nfo *PEHeaders) DataDirectoryEntry(idx DataDirectoryIndex) (any, error) {
+ if int(idx) >= _IMAGE_NUMBEROF_DIRECTORY_ENTRIES {
+ return nil, ErrIndexOutOfRange
+ }
+
+ dd := nfo.optionalHeader.GetDataDirectory()
+ if int(idx) >= len(dd) {
+ return nil, ErrNotPresent
+ }
+
+ dde := dd[idx]
+ if dde.VirtualAddress == 0 || dde.Size == 0 {
+ return nil, ErrNotPresent
+ }
+
+ switch idx {
+ /* TODO(aaron): (don't forget to sync tests!)
+ case IMAGE_DIRECTORY_ENTRY_EXPORT:
+ case IMAGE_DIRECTORY_ENTRY_IMPORT:
+ case IMAGE_DIRECTORY_ENTRY_RESOURCE:
+ */
+ case IMAGE_DIRECTORY_ENTRY_SECURITY:
+ return nfo.extractAuthenticode(dde)
+ case IMAGE_DIRECTORY_ENTRY_DEBUG:
+ return nfo.extractDebugInfo(dde)
+ // case IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR:
+ default:
+ return dde, nil
+ }
+}
+
+// WIN_CERT_REVISION is an enumeration from the Windows SDK.
+type WIN_CERT_REVISION uint16
+
+const (
+ WIN_CERT_REVISION_1_0 WIN_CERT_REVISION = 0x0100
+ WIN_CERT_REVISION_2_0 WIN_CERT_REVISION = 0x0200
+)
+
+// WIN_CERT_TYPE is an enumeration from the Windows SDK.
+type WIN_CERT_TYPE uint16
+
+const (
+ WIN_CERT_TYPE_X509 WIN_CERT_TYPE = 0x0001
+ WIN_CERT_TYPE_PKCS_SIGNED_DATA WIN_CERT_TYPE = 0x0002
+ WIN_CERT_TYPE_TS_STACK_SIGNED WIN_CERT_TYPE = 0x0004
+)
+
+type _WIN_CERTIFICATE_HEADER struct {
+ Length uint32
+ Revision WIN_CERT_REVISION
+ CertificateType WIN_CERT_TYPE
+}
+
+// AuthenticodeCert represents an authenticode signature that has been extracted
+// from a signed PE binary but not fully parsed.
+type AuthenticodeCert struct {
+ header _WIN_CERTIFICATE_HEADER
+ data []byte
+}
+
+// Revision returns the revision of ac.
+func (ac *AuthenticodeCert) Revision() WIN_CERT_REVISION {
+ return ac.header.Revision
+}
+
+// Type returns the type of ac.
+func (ac *AuthenticodeCert) Type() WIN_CERT_TYPE {
+ return ac.header.CertificateType
+}
+
+// Data returns the raw bytes of ac's cert.
+func (ac *AuthenticodeCert) Data() []byte {
+ return ac.data
+}
+
+func alignUp[V constraints.Integer](v V, powerOfTwo uint8) V {
+ if bits.OnesCount8(powerOfTwo) != 1 {
+ panic("invalid powerOfTwo argument to alignUp")
+ }
+ return v + ((-v) & (V(powerOfTwo) - 1))
+}
+
+// IMAGE_DEBUG_TYPE is an enumeration for indicating the type of debug
+// information referenced by a particular [IMAGE_DEBUG_DIRECTORY].
+type IMAGE_DEBUG_TYPE uint32
+
+const (
+ IMAGE_DEBUG_TYPE_UNKNOWN IMAGE_DEBUG_TYPE = 0
+ IMAGE_DEBUG_TYPE_COFF IMAGE_DEBUG_TYPE = 1
+ IMAGE_DEBUG_TYPE_CODEVIEW IMAGE_DEBUG_TYPE = 2
+ IMAGE_DEBUG_TYPE_FPO IMAGE_DEBUG_TYPE = 3
+ IMAGE_DEBUG_TYPE_MISC IMAGE_DEBUG_TYPE = 4
+ IMAGE_DEBUG_TYPE_EXCEPTION IMAGE_DEBUG_TYPE = 5
+ IMAGE_DEBUG_TYPE_FIXUP IMAGE_DEBUG_TYPE = 6
+ IMAGE_DEBUG_TYPE_OMAP_TO_SRC IMAGE_DEBUG_TYPE = 7
+ IMAGE_DEBUG_TYPE_OMAP_FROM_SRC IMAGE_DEBUG_TYPE = 8
+ IMAGE_DEBUG_TYPE_BORLAND IMAGE_DEBUG_TYPE = 9
+ IMAGE_DEBUG_TYPE_RESERVED10 IMAGE_DEBUG_TYPE = 10
+ IMAGE_DEBUG_TYPE_BBT IMAGE_DEBUG_TYPE = IMAGE_DEBUG_TYPE_RESERVED10
+ IMAGE_DEBUG_TYPE_CLSID IMAGE_DEBUG_TYPE = 11
+ IMAGE_DEBUG_TYPE_VC_FEATURE IMAGE_DEBUG_TYPE = 12
+ IMAGE_DEBUG_TYPE_POGO IMAGE_DEBUG_TYPE = 13
+ IMAGE_DEBUG_TYPE_ILTCG IMAGE_DEBUG_TYPE = 14
+ IMAGE_DEBUG_TYPE_MPX IMAGE_DEBUG_TYPE = 15
+ IMAGE_DEBUG_TYPE_REPRO IMAGE_DEBUG_TYPE = 16
+ IMAGE_DEBUG_TYPE_SPGO IMAGE_DEBUG_TYPE = 18
+ IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS IMAGE_DEBUG_TYPE = 20
+)
+
+// IMAGE_DEBUG_DIRECTORY describes debug information embedded in the binary.
+type IMAGE_DEBUG_DIRECTORY struct {
+ Characteristics uint32
+ TimeDateStamp uint32
+ MajorVersion uint16
+ MinorVersion uint16
+ Type IMAGE_DEBUG_TYPE
+ SizeOfData uint32
+ AddressOfRawData uint32
+ PointerToRawData uint32
+}
+
+func (nfo *PEHeaders) extractDebugInfo(dde DataDirectoryEntry) (any, error) {
+ rva := resolveRVA(nfo, dde.VirtualAddress)
+ if rva == 0 {
+ return nil, ErrResolvingFileRVA
+ }
+
+ count := dde.Size / uint32(unsafe.Sizeof(IMAGE_DEBUG_DIRECTORY{}))
+ return readStructArray[IMAGE_DEBUG_DIRECTORY](nfo.r, rva, int(count))
+}
+
+// IMAGE_DEBUG_INFO_CODEVIEW_UNPACKED contains CodeView debug information
+// embedded in the PE file. Note that this structure's ABI does not match its C
+// counterpart because the former uses a Go string and the latter is packed and
+// also includes a signature field.
+type IMAGE_DEBUG_INFO_CODEVIEW_UNPACKED struct {
+ GUID wingoes.GUID
+ Age uint32
+ PDBPath string
+}
+
+// String returns the data from u formatted in the same way that Microsoft
+// debugging tools and symbol servers use to identify PDB files corresponding
+// to a specific binary.
+func (u *IMAGE_DEBUG_INFO_CODEVIEW_UNPACKED) String() string {
+ var b strings.Builder
+ fmt.Fprintf(&b, "%08X%04X%04X", u.GUID.Data1, u.GUID.Data2, u.GUID.Data3)
+ for _, v := range u.GUID.Data4 {
+ fmt.Fprintf(&b, "%02X", v)
+ }
+ fmt.Fprintf(&b, "%X", u.Age)
+ return b.String()
+}
+
+const codeViewSignature = 0x53445352
+
+func (u *IMAGE_DEBUG_INFO_CODEVIEW_UNPACKED) unpack(r *bufio.Reader) error {
+ var signature uint32
+ if err := binaryRead(r, &signature); err != nil {
+ return err
+ }
+ if signature != codeViewSignature {
+ return ErrBadCodeView
+ }
+
+ if err := binaryRead(r, &u.GUID); err != nil {
+ return err
+ }
+
+ if err := binaryRead(r, &u.Age); err != nil {
+ return err
+ }
+
+ var storage [16]byte
+ pdbBytes := storage[:0]
+ for b, err := r.ReadByte(); err == nil && b != 0; b, err = r.ReadByte() {
+ pdbBytes = append(pdbBytes, b)
+ }
+
+ u.PDBPath = string(pdbBytes)
+ return nil
+}
+
+// ExtractCodeViewInfo obtains CodeView debug information from de, assuming that
+// de represents CodeView debug info.
+func (nfo *PEHeaders) ExtractCodeViewInfo(de IMAGE_DEBUG_DIRECTORY) (*IMAGE_DEBUG_INFO_CODEVIEW_UNPACKED, error) {
+ if de.Type != IMAGE_DEBUG_TYPE_CODEVIEW {
+ return nil, ErrNotCodeView
+ }
+
+ var sr *io.SectionReader
+ switch v := nfo.r.(type) {
+ case *peFile:
+ sr = io.NewSectionReader(v, int64(de.PointerToRawData), int64(de.SizeOfData))
+ case *peModule:
+ sr = io.NewSectionReader(v, int64(de.AddressOfRawData), int64(de.SizeOfData))
+ default:
+ return nil, ErrInvalidBinary
+ }
+
+ cv := new(IMAGE_DEBUG_INFO_CODEVIEW_UNPACKED)
+ if err := cv.unpack(bufio.NewReader(sr)); err != nil {
+ return nil, err
+ }
+
+ return cv, nil
+}
+
+func readFull(r io.Reader, buf []byte) (n int, err error) {
+ n, err = io.ReadFull(r, buf)
+ if err == io.ErrUnexpectedEOF {
+ err = ErrBadLength
+ }
+ return n, err
+}
+
+func (nfo *PEHeaders) extractAuthenticode(dde DataDirectoryEntry) (any, error) {
+ if _, ok := nfo.r.(*peFile); !ok {
+ // Authenticode; only available in file, not loaded at runtime.
+ return nil, ErrUnavailableInModule
+ }
+
+ var result []AuthenticodeCert
+ // The VirtualAddress is a file offset.
+ sr := io.NewSectionReader(nfo.r, int64(dde.VirtualAddress), int64(dde.Size))
+ var curOffset int64
+ szEntry := unsafe.Sizeof(_WIN_CERTIFICATE_HEADER{})
+
+ for {
+ var entry AuthenticodeCert
+ if err := binaryRead(sr, &entry.header); err != nil {
+ if err == io.EOF {
+ break
+ }
+ return nil, err
+ }
+ curOffset += int64(szEntry)
+
+ if uintptr(entry.header.Length) < szEntry {
+ return nil, ErrInvalidBinary
+ }
+
+ entry.data = make([]byte, uintptr(entry.header.Length)-szEntry)
+ n, err := readFull(sr, entry.data)
+ if err != nil {
+ return nil, err
+ }
+ curOffset += int64(n)
+
+ result = append(result, entry)
+
+ curOffset = alignUp(curOffset, 8)
+ if _, err := sr.Seek(curOffset, io.SeekStart); err != nil {
+ if err == io.EOF {
+ break
+ }
+ return nil, err
+ }
+ }
+
+ return result, nil
+}
diff --git a/util/wingoes/pe/pe_386.go b/util/wingoes/pe/pe_386.go
new file mode 100644
index 0000000000000..4f56810d0aa08
--- /dev/null
+++ b/util/wingoes/pe/pe_386.go
@@ -0,0 +1,16 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+//go:build windows
+
+package pe
+
+import (
+ dpe "debug/pe"
+)
+
+type optionalHeaderForGOARCH = optionalHeader32
+
+const (
+ expectedMachineForGOARCH = dpe.IMAGE_FILE_MACHINE_I386
+)
diff --git a/util/wingoes/pe/pe_amd64.go b/util/wingoes/pe/pe_amd64.go
new file mode 100644
index 0000000000000..77f35f1c0367d
--- /dev/null
+++ b/util/wingoes/pe/pe_amd64.go
@@ -0,0 +1,16 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+//go:build windows
+
+package pe
+
+import (
+ dpe "debug/pe"
+)
+
+type optionalHeaderForGOARCH = optionalHeader64
+
+const (
+ expectedMachineForGOARCH = dpe.IMAGE_FILE_MACHINE_AMD64
+)
diff --git a/util/wingoes/pe/pe_arm64.go b/util/wingoes/pe/pe_arm64.go
new file mode 100644
index 0000000000000..35791e1933db0
--- /dev/null
+++ b/util/wingoes/pe/pe_arm64.go
@@ -0,0 +1,16 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+//go:build windows
+
+package pe
+
+import (
+ dpe "debug/pe"
+)
+
+type optionalHeaderForGOARCH = optionalHeader64
+
+const (
+ expectedMachineForGOARCH = dpe.IMAGE_FILE_MACHINE_ARM64
+)
diff --git a/util/wingoes/pe/pe_notwindows.go b/util/wingoes/pe/pe_notwindows.go
new file mode 100644
index 0000000000000..ca82f1475160b
--- /dev/null
+++ b/util/wingoes/pe/pe_notwindows.go
@@ -0,0 +1,14 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+//go:build !windows
+
+package pe
+
+func (pei *peModule) Close() error {
+ return nil
+}
+
+func checkMachine(pe peReader, machine uint16) bool {
+ return true
+}
diff --git a/util/wingoes/pe/pe_notwindows_test.go b/util/wingoes/pe/pe_notwindows_test.go
new file mode 100644
index 0000000000000..977f7de86a374
--- /dev/null
+++ b/util/wingoes/pe/pe_notwindows_test.go
@@ -0,0 +1,18 @@
+//go:build ignore
+
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+package pe
+
+import (
+ "testing"
+)
+
+func testAuthenticodeAgainstSystemAPI(t *testing.T, filename string, certs []AuthenticodeCert) {
+ t.Skipf("This test requires Windows")
+}
+
+func testDebugInfoAgainstSystemAPI(t *testing.T, filename string, cv *IMAGE_DEBUG_INFO_CODEVIEW_UNPACKED) {
+ t.Skipf("This test requires Windows")
+}
diff --git a/util/wingoes/pe/pe_test.go b/util/wingoes/pe/pe_test.go
new file mode 100644
index 0000000000000..46d91ec0820ca
--- /dev/null
+++ b/util/wingoes/pe/pe_test.go
@@ -0,0 +1,125 @@
+//go:build ignore
+
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+package pe
+
+import (
+ dpe "debug/pe"
+ "fmt"
+ "os"
+ "path/filepath"
+ "testing"
+)
+
+// TODO(aaron): separate into cross-platform and windows-specific bits
+// We'll need a sample PE binary to test with on non-Windows
+
+func TestPE(t *testing.T) {
+ // NOTE: file names should always match a module already loaded in our process.
+ // kernel32 is always implicitly loaded
+ files := []string{`C:\Windows\System32\kernel32.dll`, os.Args[0]}
+
+ for _, file := range files {
+ base := filepath.Base(file)
+ t.Run(fmt.Sprintf("File_%s", base), func(t *testing.T) { testFile(t, file) })
+ t.Run(fmt.Sprintf("FileVsModule_%s", base), func(t *testing.T) { testFileVsModule(t, file) })
+ t.Run(fmt.Sprintf("VersionInfo_%s", base), func(t *testing.T) { testVersionInfo(t, file) })
+ }
+
+ t.Run("FileFromBytes", func(t *testing.T) { testFileFromBytes(t, files[0]) })
+}
+
+func testFile(t *testing.T, fname string) {
+ pei, err := NewPEFromFileName(fname)
+ if err != nil {
+ t.Fatalf("NewPEFromFileName: %v", err)
+ }
+
+ testFileInternal(t, fname, pei)
+}
+
+func testFileFromBytes(t *testing.T, fname string) {
+ blob, err := os.ReadFile(fname)
+ if err != nil {
+ t.Fatalf("os.ReadFile: %v", err)
+ }
+
+ peh, err := NewPEFromBlob(blob)
+ if err != nil {
+ t.Fatalf("NewPEFromBlob: %v", err)
+ }
+
+ testFileInternal(t, fname, peh)
+}
+
+func testFileInternal(t *testing.T, fname string, pei *PEHeaders) {
+ defer pei.Close()
+
+ t.Logf("Limit: 0x%08X (%d)\n", pei.r.Limit(), pei.r.Limit())
+
+ dd := pei.optionalHeader.GetDataDirectory()
+ for i, e := range dd {
+ t.Logf("%02d: V: 0x%08X, FOff: 0x%08X", i, e.VirtualAddress, resolveRVA(pei, e.VirtualAddress))
+ }
+
+ t.Logf("\n")
+
+ for i, s := range pei.sections {
+ t.Logf("%02d: %q F: 0x%08X, FS: 0x%08X, V: 0x%08X, VS: 0x%08X", i, s.NameString(), s.PointerToRawData, s.SizeOfRawData, s.VirtualAddress, s.VirtualSize)
+ }
+
+ dbgDirAny, err := pei.DataDirectoryEntry(dpe.IMAGE_DIRECTORY_ENTRY_DEBUG)
+ if err != nil && err != ErrNotPresent {
+ t.Fatalf("(*PEInfo).DataDirectoryEntry(%d) error %v", dpe.IMAGE_DIRECTORY_ENTRY_DEBUG, err)
+ }
+
+ dbgDir, ok := dbgDirAny.([]IMAGE_DEBUG_DIRECTORY)
+ if dbgDirAny != nil && !ok {
+ t.Errorf("did not get []IMAGE_DEBUG_DIRECTORY")
+ }
+
+ t.Logf("\n")
+ if len(dbgDir) == 0 {
+ t.Logf("No debug directory entries")
+ } else {
+ t.Logf("Debug Info:")
+ }
+
+ var cv *IMAGE_DEBUG_INFO_CODEVIEW_UNPACKED
+ for _, de := range dbgDir {
+ t.Logf("Type: %d", de.Type)
+ if de.Type == IMAGE_DEBUG_TYPE_CODEVIEW {
+ cv, err = pei.ExtractCodeViewInfo(de)
+ if err != nil {
+ t.Errorf("ExtractCodeViewInfo: %v", err)
+ continue
+ }
+ t.Logf("CodeView %q: %q", cv.String(), cv.PDBPath)
+ break
+ }
+ }
+
+ t.Logf("\n")
+ certsAny, err := pei.DataDirectoryEntry(dpe.IMAGE_DIRECTORY_ENTRY_SECURITY)
+ if err != nil && err != ErrNotPresent {
+ t.Fatalf("(*PEInfo).DataDirectoryEntry(%d) error %v", dpe.IMAGE_DIRECTORY_ENTRY_SECURITY, err)
+ }
+
+ certs, ok := certsAny.([]AuthenticodeCert)
+ if certsAny != nil && !ok {
+ t.Errorf("did not get []AuthenticodeCert")
+ }
+
+ t.Logf("%d certs embedded in binary", len(certs))
+ for i, cert := range certs {
+ t.Logf("%02d: Rev 0x%04X, Type %d, %d bytes", i, cert.Revision(), cert.Type(), len(cert.Data()))
+ }
+
+ t.Run("SystemAuthenticode", func(t *testing.T) { testAuthenticodeAgainstSystemAPI(t, fname, certs) })
+
+ if cv != nil {
+ t.Run("SystemDebugInfo", func(t *testing.T) { testDebugInfoAgainstSystemAPI(t, fname, cv) })
+ }
+}
diff --git a/util/wingoes/pe/pe_windows.go b/util/wingoes/pe/pe_windows.go
new file mode 100644
index 0000000000000..ee0e9cc80cc96
--- /dev/null
+++ b/util/wingoes/pe/pe_windows.go
@@ -0,0 +1,148 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+package pe
+
+import (
+ "bytes"
+ "fmt"
+ "os"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+func (pei *peModule) Close() error {
+ return windows.FreeLibrary(windows.Handle(pei.modLock))
+}
+
+// NewPEFromBaseAddressAndSize parses the headers in a PE binary loaded
+// into the current process's address space at address baseAddr with known
+// size. If you do not have the size, use NewPEFromBaseAddress instead.
+// Upon success it returns a non-nil *PEHeaders, otherwise it returns a nil
+// *PEHeaders and a non-nil error.
+func NewPEFromBaseAddressAndSize(baseAddr uintptr, size uint32) (*PEHeaders, error) {
+ if baseAddr == 0 || size == 0 {
+ return nil, os.ErrInvalid
+ }
+
+ // Grab a strong reference to the module until we're done with it.
+ var modLock windows.Handle
+ if err := windows.GetModuleHandleEx(
+ windows.GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+ (*uint16)(unsafe.Pointer(baseAddr)),
+ &modLock,
+ ); err != nil {
+ return nil, err
+ }
+
+ slc := unsafe.Slice((*byte)(unsafe.Pointer(baseAddr)), size)
+ r := bytes.NewReader(slc)
+ peMod := &peModule{
+ Reader: r,
+ peBounds: peBounds{
+ base: baseAddr,
+ limit: baseAddr + uintptr(size),
+ },
+ modLock: uintptr(modLock),
+ }
+
+ peh, err := loadHeaders(peMod)
+ if err != nil {
+ peMod.Close()
+ return nil, err
+ }
+
+ return peh, nil
+}
+
+// NewPEFromBaseAddress parses the headers in a PE binary loaded into the
+// current process's address space at address baseAddr.
+// Upon success it returns a non-nil *PEHeaders, otherwise it returns a nil
+// *PEHeaders and a non-nil error.
+func NewPEFromBaseAddress(baseAddr uintptr) (*PEHeaders, error) {
+ var modInfo windows.ModuleInfo
+ if err := windows.GetModuleInformation(
+ windows.CurrentProcess(),
+ windows.Handle(baseAddr),
+ &modInfo,
+ uint32(unsafe.Sizeof(modInfo)),
+ ); err != nil {
+ return nil, fmt.Errorf("querying module handle: %w", err)
+ }
+
+ return NewPEFromBaseAddressAndSize(baseAddr, modInfo.SizeOfImage)
+}
+
+// NewPEFromHMODULE parses the headers in a PE binary identified by hmodule that
+// is currently loaded into the current process's address space.
+// Upon success it returns a non-nil *PEHeaders, otherwise it returns a nil
+// *PEHeaders and a non-nil error.
+func NewPEFromHMODULE(hmodule windows.Handle) (*PEHeaders, error) {
+ // HMODULEs are just a loaded module's base address with the lowest two
+ // bits used for flags (see docs for LoadLibraryExW).
+ return NewPEFromBaseAddress(uintptr(hmodule) & ^uintptr(3))
+}
+
+// NewPEFromDLL parses the headers in a PE binary identified by dll that
+// is currently loaded into the current process's address space.
+// Upon success it returns a non-nil *PEHeaders, otherwise it returns a nil
+// *PEHeaders and a non-nil error.
+func NewPEFromDLL(dll *windows.DLL) (*PEHeaders, error) {
+ if dll == nil || dll.Handle == 0 {
+ return nil, os.ErrInvalid
+ }
+
+ return NewPEFromHMODULE(dll.Handle)
+}
+
+// NewPEFromLazyDLL parses the headers in a PE binary identified by ldll that
+// is currently loaded into the current process's address space.
+// Upon success it returns a non-nil *PEHeaders, otherwise it returns a nil
+// *PEHeaders and a non-nil error.
+func NewPEFromLazyDLL(ldll *windows.LazyDLL) (*PEHeaders, error) {
+ if ldll == nil {
+ return nil, os.ErrInvalid
+ }
+ if err := ldll.Load(); err != nil {
+ return nil, err
+ }
+
+ return NewPEFromHMODULE(windows.Handle(ldll.Handle()))
+}
+
+// NewPEFromFileHandle parses the PE headers from hfile, an open Win32 file handle.
+// It does *not* consume hfile.
+// Upon success it returns a non-nil *PEHeaders, otherwise it returns a
+// nil *PEHeaders and a non-nil error.
+// Call Close() on the returned *PEHeaders when it is no longer needed.
+func NewPEFromFileHandle(hfile windows.Handle) (*PEHeaders, error) {
+ if hfile == 0 || hfile == windows.InvalidHandle {
+ return nil, os.ErrInvalid
+ }
+
+ // Duplicate hfile so that we don't consume it.
+ var hfileDup windows.Handle
+ cp := windows.CurrentProcess()
+ if err := windows.DuplicateHandle(
+ cp,
+ hfile,
+ cp,
+ &hfileDup,
+ 0,
+ false,
+ windows.DUPLICATE_SAME_ACCESS,
+ ); err != nil {
+ return nil, err
+ }
+
+ return newPEFromFile(os.NewFile(uintptr(hfileDup), "PEFromFileHandle"))
+}
+
+func checkMachine(r peReader, machine uint16) bool {
+ // In-memory modules should always have a machine type that matches our own.
+ // (okay, so that's kinda sorta untrue with respect to WOW64, but that's
+ // a _very_ obscure use case).
+ _, isModule := r.(*peModule)
+ return !isModule || machine == expectedMachineForGOARCH
+}
diff --git a/util/wingoes/pe/pe_windows_test.go b/util/wingoes/pe/pe_windows_test.go
new file mode 100644
index 0000000000000..6ba5b767216d0
--- /dev/null
+++ b/util/wingoes/pe/pe_windows_test.go
@@ -0,0 +1,306 @@
+//go:build ignore
+
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+package pe
+
+import (
+ "bytes"
+ "errors"
+ "reflect"
+ "testing"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+func testAuthenticodeAgainstSystemAPI(t *testing.T, filename string, certs []AuthenticodeCert) {
+ syscerts, err := getCertDataViaSystem(filename)
+ if err != nil {
+ t.Fatalf("getCertDataViaSystem(%q) error %v", filename, err)
+ }
+
+ if len(certs) != len(syscerts) {
+ t.Errorf("len mismatch")
+ }
+
+ var testCerts [2]*AuthenticodeCert
+ for i, slc := range [][]AuthenticodeCert{certs, syscerts} {
+ for j, cert := range slc {
+ if cert.Revision() != WIN_CERT_REVISION_2_0 || cert.Type() != WIN_CERT_TYPE_PKCS_SIGNED_DATA {
+ continue
+ }
+ testCerts[i] = &slc[j]
+ break
+ }
+ }
+
+ if !reflect.DeepEqual(testCerts[0], testCerts[1]) {
+ t.Errorf("DeepEqual failed")
+ }
+}
+
+func testDebugInfoAgainstSystemAPI(t *testing.T, filename string, cv *IMAGE_DEBUG_INFO_CODEVIEW_UNPACKED) {
+ syscv, err := getCodeViewInfoViaSystem(filename)
+ if err != nil {
+ var dllerr *windows.DLLError
+ if errors.As(err, &dllerr) {
+ t.Skipf("Test requires dbghelp.dll version 6.6 or later")
+ }
+ t.Fatalf("getCodeViewInfoViaSystem(%q) error %v", filename, err)
+ }
+
+ if !reflect.DeepEqual(cv, syscv) {
+ t.Errorf("DeepEqual failed")
+ }
+}
+
+func getCodeViewInfoViaSystem(filename string) (result *IMAGE_DEBUG_INFO_CODEVIEW_UNPACKED, err error) {
+ filename16, err := windows.UTF16PtrFromString(filename)
+ if err != nil {
+ return nil, err
+ }
+
+ info := _SYMSRV_INDEX_INFO{
+ SizeOfStruct: uint32(unsafe.Sizeof(_SYMSRV_INDEX_INFO{})),
+ }
+ if err := symSrvGetFileIndexInfo(filename16, &info, 0); err != nil {
+ return nil, err
+ }
+
+ result = &IMAGE_DEBUG_INFO_CODEVIEW_UNPACKED{
+ GUID: info.GUID,
+ Age: info.Age,
+ PDBPath: windows.UTF16ToString(info.PDBFile[:]),
+ }
+ return result, nil
+}
+
+func getCertDataViaSystem(filename string) (result []AuthenticodeCert, err error) {
+ h, err := windows.Open(filename, windows.O_RDONLY, 0)
+ if err != nil {
+ return nil, err
+ }
+ defer windows.CloseHandle(h)
+
+ var certCount uint32
+ if err := imageEnumerateCertificates(h, _CERT_SECTION_TYPE_ANY, &certCount, nil, 0); err != nil {
+ return nil, err
+ }
+ if certCount == 0 {
+ return nil, nil
+ }
+
+ result = make([]AuthenticodeCert, 0, certCount)
+ for i := uint32(0); i < certCount; i++ {
+ reqd := uint32(0)
+ if err := imageGetCertificateData(h, i, nil, &reqd); err != windows.ERROR_INSUFFICIENT_BUFFER {
+ return nil, err
+ }
+
+ buf := make([]byte, reqd)
+ if err := imageGetCertificateData(h, i, unsafe.SliceData(buf), &reqd); err != nil {
+ return nil, err
+ }
+ r := bytes.NewReader(buf)
+
+ var entry AuthenticodeCert
+ if err := binaryRead(r, &entry.header); err != nil {
+ return nil, err
+ }
+
+ entry.data = buf[unsafe.Sizeof(_WIN_CERTIFICATE_HEADER{}):]
+ result = append(result, entry)
+ }
+
+ return result, nil
+}
+
+func testFileVsModule(t *testing.T, fname string) {
+ pef, err := NewPEFromFileName(fname)
+ if err != nil {
+ t.Errorf("NewPEFromFile: %v", err)
+ }
+ defer pef.Close()
+
+ fname16, err := windows.UTF16PtrFromString(fname)
+ if err != nil {
+ t.Fatalf("converting %q to UTF-16: %v", fname, err)
+ }
+
+ var hmod windows.Handle
+ if err := windows.GetModuleHandleEx(
+ windows.GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+ fname16,
+ &hmod,
+ ); err != nil {
+ t.Fatalf("loading %q: %v", fname, err)
+ }
+
+ pem, err := NewPEFromHMODULE(hmod)
+ if err != nil {
+ t.Errorf("NewPEFromHMODULE: %v", err)
+ }
+ defer pem.Close()
+
+ if !reflect.DeepEqual(pef.fileHeader, pem.fileHeader) {
+ t.Errorf("DeepEqual failed on fileHeader")
+ }
+
+ // The optional header's DataDirectory will be modified by loader relocations,
+ // so we need to exclude that from the comparison.
+ pefOH := pef.optionalHeader.(*optionalHeaderForGOARCH)
+ pefOHBytes := unsafe.Slice((*byte)(unsafe.Pointer(pefOH)), unsafe.Sizeof(*pefOH)-unsafe.Sizeof(pefOH.DataDirectory))
+ // ImageBase is pretty much guaranteed to differ, so make a copy and set that the module's value to the file's value.
+ pemOH := pem.optionalHeader.(*optionalHeaderForGOARCH)
+ pemOHCopy := *pemOH
+ pemOHCopy.ImageBase = pefOH.ImageBase
+
+ pemOHBytes := unsafe.Slice((*byte)(unsafe.Pointer(&pemOHCopy)), unsafe.Sizeof(pemOHCopy)-unsafe.Sizeof(pemOHCopy.DataDirectory))
+
+ if !bytes.Equal(pefOHBytes, pemOHBytes) {
+ t.Errorf("bytes.Equal failed on optionalHeader:\n\n%#v\n\nvs\n\n%#v\n\n", pefOHBytes, pemOHBytes)
+ }
+
+ // TODO(aaron): flesh out this test as (*PEInfo).DataDirectoryEntry is fleshed out
+ // Compare some DataDirectory stuff between file and module. Note that
+ // IMAGE_DIRECTORY_ENTRY_SECURITY is unavailable in modules.
+ ddIdx := IMAGE_DIRECTORY_ENTRY_DEBUG
+ dbgInfoFileAny, err := pef.DataDirectoryEntry(ddIdx)
+ if err != nil {
+ if err != ErrNotPresent {
+ t.Errorf("obtaining DataDirectory[%d] from file: %v", ddIdx, err)
+ }
+ }
+
+ dbgInfoModuleAny, err := pem.DataDirectoryEntry(ddIdx)
+ if err != nil {
+ if err != ErrNotPresent {
+ t.Errorf("obtaining DataDirectory[%d] from module: %v", ddIdx, err)
+ }
+ }
+
+ if (dbgInfoFileAny == nil || dbgInfoModuleAny == nil) && dbgInfoFileAny != dbgInfoModuleAny {
+ t.Errorf("DataDirectoryEntry[%d] for file returned %v while module returned %v", ddIdx, dbgInfoFileAny, dbgInfoModuleAny)
+ }
+
+ if dbgInfoFileAny != nil && dbgInfoModuleAny != nil {
+ dbgInfoFile, ok := dbgInfoFileAny.([]IMAGE_DEBUG_DIRECTORY)
+ if !ok {
+ t.Errorf("type assertion failed for dbgInfoFileAny")
+ }
+
+ dbgInfoModule, ok := dbgInfoModuleAny.([]IMAGE_DEBUG_DIRECTORY)
+ if !ok {
+ t.Errorf("type assertion failed for dbgInfoFileModule")
+ }
+
+ if len(dbgInfoFile) != len(dbgInfoModule) {
+ t.Errorf("length mismatch between dbgInfoFile (%d) and dbgInfoModule (%d)", len(dbgInfoFile), len(dbgInfoModule))
+ } else {
+ for i, def := range dbgInfoFile {
+ dem := dbgInfoModule[i]
+ if def.Type != dem.Type {
+ t.Errorf("type mismatch between dbgInfoFile[%d] (%d) and dbgInfoModule[%d] (%d)", i, def.Type, i, dem.Type)
+ continue
+ }
+ if def.Type == IMAGE_DEBUG_TYPE_CODEVIEW {
+ cvf, err := pef.ExtractCodeViewInfo(def)
+ if err != nil {
+ t.Errorf("failed extracting CodeView info from dbgInfoFile[%d]: %v", i, err)
+ continue
+ }
+
+ cvm, err := pem.ExtractCodeViewInfo(dem)
+ if err != nil {
+ t.Errorf("failed extracting CodeView info from dbgInfoModule[%d]: %v", i, err)
+ continue
+ }
+
+ if !reflect.DeepEqual(*cvf, *cvm) {
+ t.Errorf("debug info mismatch")
+ }
+ }
+ }
+ }
+ }
+}
+
+func testVersionInfo(t *testing.T, fname string) {
+ vi, err := NewVersionInfo(fname)
+ if err != nil {
+ if err == ErrNotPresent {
+ t.Skipf("No version info present in %q", fname)
+ } else {
+ t.Fatalf("NewVersionInfo failed: %v", err)
+ }
+ }
+
+ verNum := vi.VersionNumber()
+ t.Logf("Version number: %q", verNum.String())
+
+ companyName, err := vi.Field("CompanyName")
+ if err != nil {
+ t.Errorf("CompanyName failed: %v", err)
+ } else {
+ t.Logf("CompanyName: %q", companyName)
+ }
+}
+
+func TestModuleVsSystem(t *testing.T) {
+ k32 := windows.MustLoadDLL("kernel32.dll")
+ pem, err := NewPEFromDLL(k32)
+ if err != nil {
+ t.Errorf("NewPEFromHMODULE error: %v", err)
+ }
+ defer pem.Close()
+
+ fh, err := getFileHeaderViaSystem(uintptr(k32.Handle))
+ if err != nil {
+ t.Fatalf("getFileHeaderViaSystem error: %v", err)
+ }
+
+ if uintptr(unsafe.Pointer(fh)) != uintptr(unsafe.Pointer(pem.fileHeader)) {
+ t.Errorf("FileHeader pointers do not match")
+ }
+
+ var ddeZero DataDirectoryEntry
+ dd := pem.optionalHeader.GetDataDirectory()
+ for i, dde := range dd {
+ ddeSys, err := getDataDirectoryEntryViaSystem(uintptr(k32.Handle), DataDirectoryIndex(i))
+ if err != nil {
+ if dde == ddeZero {
+ // Not present; not an error
+ continue
+ }
+ t.Fatalf("getDataDirectoryEntryViaSystem error: %v", err)
+ }
+
+ if !reflect.DeepEqual(dde, *ddeSys) {
+ t.Errorf("DeepEqual failed on DataDirectory[%d]", i)
+ }
+ }
+}
+
+func getFileHeaderViaSystem(hmodule uintptr) (*FileHeader, error) {
+ ntFixed, err := imageNtHeader(hmodule)
+ if err != nil {
+ return nil, err
+ }
+
+ return &ntFixed.FileHeader, nil
+}
+
+func getDataDirectoryEntryViaSystem(hmodule uintptr, ddIndex DataDirectoryIndex) (dde *DataDirectoryEntry, err error) {
+ var size uint32
+ address, err := imageDirectoryEntryToDataEx(hmodule, 1, uint16(ddIndex), &size, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ return &DataDirectoryEntry{
+ VirtualAddress: uint32(address - hmodule),
+ Size: size,
+ }, nil
+}
diff --git a/util/wingoes/pe/version.go b/util/wingoes/pe/version.go
new file mode 100644
index 0000000000000..f6c6982ad87c9
--- /dev/null
+++ b/util/wingoes/pe/version.go
@@ -0,0 +1,167 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+//go:build windows
+
+package pe
+
+import (
+ "errors"
+ "fmt"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+var (
+ errFixedFileInfoBadSig = errors.New("bad VS_FIXEDFILEINFO signature")
+ errFixedFileInfoTooShort = errors.New("buffer smaller than VS_FIXEDFILEINFO")
+)
+
+// VersionNumber encapsulates a four-component version number that is stored
+// in Windows VERSIONINFO resources.
+type VersionNumber struct {
+ Major uint16
+ Minor uint16
+ Patch uint16
+ Build uint16
+}
+
+func (vn VersionNumber) String() string {
+ return fmt.Sprintf("%d.%d.%d.%d", vn.Major, vn.Minor, vn.Patch, vn.Build)
+}
+
+type langAndCodePage struct {
+ language uint16
+ codePage uint16
+}
+
+// VersionInfo encapsulates a buffer containing the VERSIONINFO resources that
+// have been successfully extracted from a PE binary.
+type VersionInfo struct {
+ buf []byte
+ fixed *windows.VS_FIXEDFILEINFO
+ translationIDs []langAndCodePage
+}
+
+const (
+ langEnUS = 0x0409
+ codePageUTF16LE = 0x04B0
+ langNeutral = 0
+)
+
+// NewVersionInfo extracts any VERSIONINFO resource from filepath, parses its
+// fixed-size information, and returns a *VersionInfo for further querying.
+// It returns ErrNotPresent if no VERSIONINFO resources are found.
+func NewVersionInfo(filepath string) (*VersionInfo, error) {
+ bufSize, err := windows.GetFileVersionInfoSize(filepath, nil)
+ if err != nil {
+ if errors.Is(err, windows.ERROR_RESOURCE_TYPE_NOT_FOUND) {
+ err = ErrNotPresent
+ }
+ return nil, err
+ }
+
+ buf := make([]byte, bufSize)
+ if err := windows.GetFileVersionInfo(filepath, 0, bufSize, unsafe.Pointer(unsafe.SliceData(buf))); err != nil {
+ return nil, err
+ }
+
+ var fixed *windows.VS_FIXEDFILEINFO
+ var fixedLen uint32
+ if err := windows.VerQueryValue(unsafe.Pointer(unsafe.SliceData(buf)), `\`, unsafe.Pointer(&fixed), &fixedLen); err != nil {
+ return nil, err
+ }
+ if fixedLen < uint32(unsafe.Sizeof(windows.VS_FIXEDFILEINFO{})) {
+ return nil, errFixedFileInfoTooShort
+ }
+ if fixed.Signature != 0xFEEF04BD {
+ return nil, errFixedFileInfoBadSig
+ }
+
+ return &VersionInfo{
+ buf: buf,
+ fixed: fixed,
+ }, nil
+}
+
+func (vi *VersionInfo) VersionNumber() VersionNumber {
+ f := vi.fixed
+
+ return VersionNumber{
+ Major: uint16(f.FileVersionMS >> 16),
+ Minor: uint16(f.FileVersionMS & 0xFFFF),
+ Patch: uint16(f.FileVersionLS >> 16),
+ Build: uint16(f.FileVersionLS & 0xFFFF),
+ }
+}
+
+func (vi *VersionInfo) maybeLoadTranslationIDs() {
+ if vi.translationIDs != nil {
+ // Already loaded
+ return
+ }
+
+ // Preferred translations, in order of preference.
+ preferredTranslationIDs := []langAndCodePage{
+ langAndCodePage{
+ language: langEnUS,
+ codePage: codePageUTF16LE,
+ },
+ langAndCodePage{
+ language: langNeutral,
+ codePage: codePageUTF16LE,
+ },
+ }
+
+ var ids *langAndCodePage
+ var idsNumBytes uint32
+ if err := windows.VerQueryValue(
+ unsafe.Pointer(unsafe.SliceData(vi.buf)),
+ `\VarFileInfo\Translation`,
+ unsafe.Pointer(&ids),
+ &idsNumBytes,
+ ); err != nil {
+ // If nothing is listed, then just try to use our preferred translation IDs.
+ vi.translationIDs = preferredTranslationIDs
+ return
+ }
+
+ idsSlice := unsafe.Slice(ids, idsNumBytes/uint32(unsafe.Sizeof(*ids)))
+ vi.translationIDs = append(preferredTranslationIDs, idsSlice...)
+}
+
+func (vi *VersionInfo) queryWithLangAndCodePage(key string, lcp langAndCodePage) (string, error) {
+ fq := fmt.Sprintf("\\StringFileInfo\\%04x%04x\\%s", lcp.language, lcp.codePage, key)
+
+ var value *uint16
+ var valueLen uint32
+ if err := windows.VerQueryValue(unsafe.Pointer(unsafe.SliceData(vi.buf)), fq, unsafe.Pointer(&value), &valueLen); err != nil {
+ return "", err
+ }
+
+ return windows.UTF16ToString(unsafe.Slice(value, valueLen)), nil
+}
+
+// Field queries the version information for a field named key and either
+// returns the field's value, or an error. It attempts to resolve strings using
+// the following order of language preference: en-US, language-neutral, followed
+// by the first entry in version info's list of supported languages that
+// successfully resolves the key.
+// If the key cannot be resolved, it returns ErrNotPresent.
+func (vi *VersionInfo) Field(key string) (string, error) {
+ vi.maybeLoadTranslationIDs()
+
+ for _, lcp := range vi.translationIDs {
+ value, err := vi.queryWithLangAndCodePage(key, lcp)
+ if err == nil {
+ return value, nil
+ }
+ if !errors.Is(err, windows.ERROR_RESOURCE_TYPE_NOT_FOUND) {
+ return "", err
+ }
+ // Otherwise we continue looping and try the next language
+ }
+
+ return "", ErrNotPresent
+}
diff --git a/util/wingoes/pe/zsyscall_windows_test.go b/util/wingoes/pe/zsyscall_windows_test.go
new file mode 100644
index 0000000000000..9e4ac00ed6045
--- /dev/null
+++ b/util/wingoes/pe/zsyscall_windows_test.go
@@ -0,0 +1,97 @@
+//go:build ignore
+
+// Code generated by 'go generate'; DO NOT EDIT.
+
+package pe
+
+import (
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+ errnoERROR_IO_PENDING = 997
+)
+
+var (
+ errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+ errERROR_EINVAL error = syscall.EINVAL
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+ switch e {
+ case 0:
+ return errERROR_EINVAL
+ case errnoERROR_IO_PENDING:
+ return errERROR_IO_PENDING
+ }
+ // TODO: add more here, after collecting data on the common
+ // error values see on Windows. (perhaps when running
+ // all.bat?)
+ return e
+}
+
+var (
+ moddbghelp = windows.NewLazySystemDLL("dbghelp.dll")
+ modimagehlp = windows.NewLazySystemDLL("imagehlp.dll")
+
+ procImageDirectoryEntryToDataEx = moddbghelp.NewProc("ImageDirectoryEntryToDataEx")
+ procImageNtHeader = moddbghelp.NewProc("ImageNtHeader")
+ procSymSrvGetFileIndexInfoW = moddbghelp.NewProc("SymSrvGetFileIndexInfoW")
+ procImageEnumerateCertificates = modimagehlp.NewProc("ImageEnumerateCertificates")
+ procImageGetCertificateData = modimagehlp.NewProc("ImageGetCertificateData")
+)
+
+func imageDirectoryEntryToDataEx(base uintptr, mappedAsImage byte, directoryEntry uint16, size *uint32, foundHeader *SectionHeader) (ret uintptr, err error) {
+ r0, _, e1 := syscall.Syscall6(procImageDirectoryEntryToDataEx.Addr(), 5, uintptr(base), uintptr(mappedAsImage), uintptr(directoryEntry), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(foundHeader)), 0)
+ ret = uintptr(r0)
+ if ret == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func imageNtHeader(base uintptr) (ret *_IMAGE_NT_HEADERS_FIXED, err error) {
+ r0, _, e1 := syscall.Syscall(procImageNtHeader.Addr(), 1, uintptr(base), 0, 0)
+ ret = (*_IMAGE_NT_HEADERS_FIXED)(unsafe.Pointer(r0))
+ if ret == nil {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func symSrvGetFileIndexInfo(file *uint16, info *_SYMSRV_INDEX_INFO, flags uint32) (err error) {
+ err = procSymSrvGetFileIndexInfoW.Find()
+ if err != nil {
+ return
+ }
+ r1, _, e1 := syscall.Syscall(procSymSrvGetFileIndexInfoW.Addr(), 3, uintptr(unsafe.Pointer(file)), uintptr(unsafe.Pointer(info)), uintptr(flags))
+ if int32(r1) == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func imageEnumerateCertificates(fileHandle windows.Handle, typeFilter WIN_CERT_TYPE, certificateCount *uint32, indices *uint32, indexCount uint32) (err error) {
+ r1, _, e1 := syscall.Syscall6(procImageEnumerateCertificates.Addr(), 5, uintptr(fileHandle), uintptr(typeFilter), uintptr(unsafe.Pointer(certificateCount)), uintptr(unsafe.Pointer(indices)), uintptr(indexCount), 0)
+ if int32(r1) == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func imageGetCertificateData(fileHandle windows.Handle, certificateIndex uint32, certificate *byte, requiredLength *uint32) (err error) {
+ r1, _, e1 := syscall.Syscall6(procImageGetCertificateData.Addr(), 4, uintptr(fileHandle), uintptr(certificateIndex), uintptr(unsafe.Pointer(certificate)), uintptr(unsafe.Pointer(requiredLength)), 0, 0)
+ if int32(r1) == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
diff --git a/util/wingoes/time.go b/util/wingoes/time.go
new file mode 100644
index 0000000000000..5598aadd369b9
--- /dev/null
+++ b/util/wingoes/time.go
@@ -0,0 +1,37 @@
+// 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 windows
+
+package wingoes
+
+import (
+ "errors"
+ "math"
+ "time"
+
+ "golang.org/x/sys/windows"
+)
+
+// Infinite is the [time.Duration] equivalent of [windows.INFINITE].
+const Infinite = time.Duration(math.MaxInt64)
+
+var (
+ // ErrDurationOutOfRange means that a time.Duration is too large to be able
+ // to be specified as a valid Win32 timeout value.
+ ErrDurationOutOfRange = errors.New("duration is out of timeout range")
+)
+
+// DurationToTimeoutMilliseconds converts d into a timeout usable by Win32 APIs.
+func DurationToTimeoutMilliseconds(d time.Duration) (uint32, error) {
+ if d == Infinite {
+ return windows.INFINITE, nil
+ }
+
+ millis := d.Milliseconds()
+ if millis >= windows.INFINITE {
+ return 0, ErrDurationOutOfRange
+ }
+ return uint32(millis), nil
+}
diff --git a/util/wingoes/util.go b/util/wingoes/util.go
new file mode 100644
index 0000000000000..658f68aa23b4f
--- /dev/null
+++ b/util/wingoes/util.go
@@ -0,0 +1,80 @@
+// 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 windows
+
+package wingoes
+
+import (
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+// UserSIDs contains pointers to the SIDs for a user and their primary group.
+type UserSIDs struct {
+ User *windows.SID
+ PrimaryGroup *windows.SID
+}
+
+// CurrentProcessUserSIDs returns a UserSIDs containing the SIDs of the user
+// and primary group who own the current process.
+func CurrentProcessUserSIDs() (*UserSIDs, error) {
+ token, err := windows.OpenCurrentProcessToken()
+ if err != nil {
+ return nil, err
+ }
+ defer token.Close()
+
+ userInfo, err := token.GetTokenUser()
+ if err != nil {
+ return nil, err
+ }
+
+ primaryGroup, err := token.GetTokenPrimaryGroup()
+ if err != nil {
+ return nil, err
+ }
+
+ // We just want the SIDs, not the rest of the structs that were output.
+ userSid, err := userInfo.User.Sid.Copy()
+ if err != nil {
+ return nil, err
+ }
+
+ primaryGroupSid, err := primaryGroup.PrimaryGroup.Copy()
+ if err != nil {
+ return nil, err
+ }
+
+ return &UserSIDs{User: userSid, PrimaryGroup: primaryGroupSid}, nil
+}
+
+// getTokenInfoVariableLen obtains variable-length token information. Use
+// this function for information classes that output variable-length data.
+func getTokenInfoVariableLen[T any](token windows.Token, infoClass uint32) (*T, error) {
+ var buf []byte
+ var desiredLen uint32
+
+ err := windows.GetTokenInformation(token, infoClass, nil, 0, &desiredLen)
+
+ for err == windows.ERROR_INSUFFICIENT_BUFFER {
+ buf = make([]byte, desiredLen)
+ err = windows.GetTokenInformation(token, infoClass, unsafe.SliceData(buf), desiredLen, &desiredLen)
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ return (*T)(unsafe.Pointer(unsafe.SliceData(buf))), nil
+}
+
+// getTokenInfoFixedLen obtains known fixed-length token information. Use this
+// function for information classes that output enumerations, BOOLs, integers etc.
+func getTokenInfoFixedLen[T any](token windows.Token, infoClass uint32) (result T, _ error) {
+ var actualLen uint32
+ err := windows.GetTokenInformation(token, infoClass, (*byte)(unsafe.Pointer(&result)), uint32(unsafe.Sizeof(result)), &actualLen)
+ return result, err
+}
diff --git a/util/winipcfg/winipcfg_windows.go b/util/winipcfg/winipcfg_windows.go
new file mode 100644
index 0000000000000..ed5e1844dc5ce
--- /dev/null
+++ b/util/winipcfg/winipcfg_windows.go
@@ -0,0 +1,148 @@
+// Copyright (c) Tailscale Inc & contributors
+// SPDX-License-Identifier: BSD-3-Clause
+
+package winipcfg
+
+import (
+ "net/netip"
+
+ "golang.org/x/sys/windows"
+)
+
+type LUID uint64
+
+func LUIDFromGUID(*windows.GUID) (LUID, error) { return 0, nil }
+func LUIDFromIndex(uint32) (LUID, error) { return 0, nil }
+
+func (l LUID) GUID() (windows.GUID, error) { return windows.GUID{}, nil }
+func (l LUID) DNS() ([]netip.Addr, error) { return nil, nil }
+
+func (l LUID) IPInterface(AddressFamily) (*MibIPInterfaceRow, error) {
+ return &MibIPInterfaceRow{}, nil
+}
+
+func (l LUID) Interface() (*MibIfRow2, error) {
+ return &MibIfRow2{}, nil
+}
+
+type AddressFamily uint16
+type GAAFlags uint32
+type IfOperStatus uint32
+type MibNotificationType uint32
+
+const (
+ GAAFlagIncludeAllInterfaces GAAFlags = 1 << iota
+)
+
+const (
+ IfOperStatusUp IfOperStatus = 1
+)
+
+const (
+ IfTypeSoftwareLoopback = 24
+ IfTypePropVirtual = 53
+)
+
+const (
+ IPAAFlagIpv4Enabled = 1 << iota
+ IPAAFlagIpv6Enabled
+)
+
+const (
+ MibParameterNotification MibNotificationType = iota
+ MibAddInstance
+)
+
+type IPAdapterAddresses struct {
+ LUID LUID
+ MTU uint32
+ IfType uint32
+ IfIndex uint32
+ Ipv4Metric uint32
+ Ipv6Metric uint32
+ Flags uint32
+ OperStatus IfOperStatus
+}
+
+func (a *IPAdapterAddresses) FriendlyName() string { return "" }
+func (a *IPAdapterAddresses) Description() string { return "" }
+
+type MibIfRow2 struct {
+ Type uint32
+ OperStatus IfOperStatus
+}
+
+func (r *MibIfRow2) Description() string { return "" }
+
+type MibIPInterfaceRow struct {
+ Connected bool
+ InterfaceLUID LUID
+ Metric uint32
+ OperStatus IfOperStatus
+}
+
+type RawSockaddrInet struct {
+ addr netip.Addr
+}
+
+func (s *RawSockaddrInet) SetAddr(addr netip.Addr) error {
+ s.addr = addr
+ return nil
+}
+
+type IPAddress struct {
+ addr netip.Addr
+}
+
+func (a IPAddress) Addr() netip.Addr { return a.addr }
+
+type IPPrefix struct {
+ PrefixLength uint8
+ prefix netip.Prefix
+}
+
+func (p IPPrefix) Prefix() netip.Prefix { return p.prefix }
+
+type MibUnicastIPAddressRow struct {
+ Address IPAddress
+}
+
+type MibIPforwardRow2 struct {
+ Loopback bool
+ DestinationPrefix IPPrefix
+ InterfaceLUID LUID
+ Metric uint32
+ NextHop IPAddress
+}
+
+func GetIPForwardTable2(AddressFamily) ([]MibIPforwardRow2, error) {
+ return nil, nil
+}
+
+func GetAdaptersAddresses(AddressFamily, GAAFlags) ([]*IPAdapterAddresses, error) {
+ return nil, nil
+}
+
+func GetIPInterfaceTable(AddressFamily) ([]MibIPInterfaceRow, error) {
+ return nil, nil
+}
+
+type UnicastAddressChangeCallback struct{}
+type RouteChangeCallback struct{}
+type InterfaceChangeCallback struct{}
+
+func RegisterUnicastAddressChangeCallback(func(MibNotificationType, *MibUnicastIPAddressRow)) (*UnicastAddressChangeCallback, error) {
+ return &UnicastAddressChangeCallback{}, nil
+}
+
+func RegisterRouteChangeCallback(func(MibNotificationType, *MibIPforwardRow2)) (*RouteChangeCallback, error) {
+ return &RouteChangeCallback{}, nil
+}
+
+func RegisterInterfaceChangeCallback(func(MibNotificationType, *MibIPInterfaceRow)) (*InterfaceChangeCallback, error) {
+ return &InterfaceChangeCallback{}, nil
+}
+
+func (*UnicastAddressChangeCallback) Unregister() error { return nil }
+func (*RouteChangeCallback) Unregister() error { return nil }
+func (*InterfaceChangeCallback) Unregister() error { return nil }
diff --git a/util/winutil/authenticode/authenticode_windows.go b/util/winutil/authenticode/authenticode_windows.go
index 46f60caf76f79..bacf617286994 100644
--- a/util/winutil/authenticode/authenticode_windows.go
+++ b/util/winutil/authenticode/authenticode_windows.go
@@ -12,8 +12,8 @@ import (
"strings"
"unsafe"
- "github.com/dblohm7/wingoes"
- "github.com/dblohm7/wingoes/pe"
+ "github.com/metacubex/tailscale/util/wingoes"
+ "github.com/metacubex/tailscale/util/wingoes/pe"
"golang.org/x/sys/windows"
)
diff --git a/util/winutil/authenticode/zsyscall_windows.go b/util/winutil/authenticode/zsyscall_windows.go
index f1fba2828713c..b42cc42ab5aef 100644
--- a/util/winutil/authenticode/zsyscall_windows.go
+++ b/util/winutil/authenticode/zsyscall_windows.go
@@ -6,7 +6,7 @@ import (
"syscall"
"unsafe"
- "github.com/dblohm7/wingoes"
+ "github.com/metacubex/tailscale/util/wingoes"
"golang.org/x/sys/windows"
)
diff --git a/util/winutil/conpty/conpty_windows.go b/util/winutil/conpty/conpty_windows.go
index 1071493f529b0..ba16b6457f386 100644
--- a/util/winutil/conpty/conpty_windows.go
+++ b/util/winutil/conpty/conpty_windows.go
@@ -10,9 +10,9 @@ import (
"io"
"os"
- "github.com/dblohm7/wingoes"
+ "github.com/metacubex/tailscale/util/wingoes"
+ "github.com/metacubex/tailscale/util/winutil"
"golang.org/x/sys/windows"
- "tailscale.com/util/winutil"
)
var (
diff --git a/util/winutil/gp/gp_windows_test.go b/util/winutil/gp/gp_windows_test.go
index 1ce75871e0c72..c807552185df0 100644
--- a/util/winutil/gp/gp_windows_test.go
+++ b/util/winutil/gp/gp_windows_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,7 +11,7 @@ import (
"testing"
"time"
- "tailscale.com/util/cibuild"
+ "github.com/metacubex/tailscale/util/cibuild"
)
func TestWatchForPolicyChange(t *testing.T) {
diff --git a/util/winutil/gp/policylock_windows.go b/util/winutil/gp/policylock_windows.go
index 6e6f63f820489..adae3dd8e05f6 100644
--- a/util/winutil/gp/policylock_windows.go
+++ b/util/winutil/gp/policylock_windows.go
@@ -72,9 +72,12 @@ var policyLockRestricted atomic.Int32
// would result in a deadlock. See tailscale/tailscale#14416 for more information.
func RestrictPolicyLocks() (removeRestriction func()) {
policyLockRestricted.Add(1)
- return sync.OnceFunc(func() {
- policyLockRestricted.Add(-1)
- })
+ var once sync.Once
+ return func() {
+ once.Do(func() {
+ policyLockRestricted.Add(-1)
+ })
+ }
}
// NewMachinePolicyLock creates a PolicyLock that facilitates pausing the
diff --git a/util/winutil/policy/policy_windows.go b/util/winutil/policy/policy_windows.go
index c831066034608..8222f9fd2a1ef 100644
--- a/util/winutil/policy/policy_windows.go
+++ b/util/winutil/policy/policy_windows.go
@@ -7,7 +7,7 @@ package policy
import (
"time"
- "tailscale.com/util/winutil"
+ "github.com/metacubex/tailscale/util/winutil"
)
// PreferenceOptionPolicy is a policy that governs whether a boolean variable
diff --git a/util/winutil/policy/policy_windows_test.go b/util/winutil/policy/policy_windows_test.go
index 881c08356b99a..22b6f1d0708b0 100644
--- a/util/winutil/policy/policy_windows_test.go
+++ b/util/winutil/policy/policy_windows_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/winutil/restartmgr_windows.go b/util/winutil/restartmgr_windows.go
index 3ef8a0383b2ba..a8f3bc624c2bf 100644
--- a/util/winutil/restartmgr_windows.go
+++ b/util/winutil/restartmgr_windows.go
@@ -16,9 +16,9 @@ import (
"unicode/utf16"
"unsafe"
- "github.com/dblohm7/wingoes"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/wingoes"
"golang.org/x/sys/windows"
- "tailscale.com/types/logger"
)
var (
@@ -461,7 +461,9 @@ func (rps RestartableProcesses) Close() error {
for _, v := range rps {
v.Close()
}
- clear(rps)
+ for pid := range rps {
+ delete(rps, pid)
+ }
return nil
}
@@ -508,7 +510,7 @@ func (rps RestartableProcesses) Terminate(logf logger.Logf, exitCode uint32, tim
for len(handles) > 0 {
// WaitForMultipleObjects can only wait on _MAXIMUM_WAIT_OBJECTS handles per
// call, so we batch them as necessary.
- count := uint32(min(len(handles), _MAXIMUM_WAIT_OBJECTS))
+ count := uint32(minInt(len(handles), _MAXIMUM_WAIT_OBJECTS))
waitCode, err := windows.WaitForMultipleObjects(handles[:count], true, millis)
if err != nil {
errs = append(errs, fmt.Errorf("waiting on terminated process handles: %w", err))
@@ -842,3 +844,10 @@ func NewEnvBlock(env []string) *uint16 {
buf.WriteByte(0)
return unsafe.SliceData(utf16.Encode([]rune(string(buf.Bytes()))))
}
+
+func minInt(a, b int) int {
+ if a < b {
+ return a
+ }
+ return b
+}
diff --git a/util/winutil/restartmgr_windows_test.go b/util/winutil/restartmgr_windows_test.go
index eb11ffc9ce51f..5edeeada7d7f3 100644
--- a/util/winutil/restartmgr_windows_test.go
+++ b/util/winutil/restartmgr_windows_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/winutil/s4u/lsa_windows.go b/util/winutil/s4u/lsa_windows.go
index a26a7bcf094fa..f00da225dd19f 100644
--- a/util/winutil/s4u/lsa_windows.go
+++ b/util/winutil/s4u/lsa_windows.go
@@ -13,11 +13,11 @@ import (
"unicode"
"unsafe"
- "github.com/dblohm7/wingoes"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/util/wingoes"
+ "github.com/metacubex/tailscale/util/winutil"
+ "github.com/metacubex/tailscale/util/winutil/winenv"
"golang.org/x/sys/windows"
- "tailscale.com/types/lazy"
- "tailscale.com/util/winutil"
- "tailscale.com/util/winutil/winenv"
)
const (
diff --git a/util/winutil/s4u/s4u_windows.go b/util/winutil/s4u/s4u_windows.go
index a5b543cab5ea1..06528d956d167 100644
--- a/util/winutil/s4u/s4u_windows.go
+++ b/util/winutil/s4u/s4u_windows.go
@@ -9,23 +9,23 @@ import (
"errors"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"math"
"os"
"os/user"
"runtime"
- "slices"
"strconv"
"strings"
"sync"
"sync/atomic"
"unsafe"
+ "github.com/metacubex/tailscale/cmd/tailscaled/childproc"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/winutil"
+ "github.com/metacubex/tailscale/util/winutil/conpty"
"golang.org/x/sys/windows"
- "tailscale.com/cmd/tailscaled/childproc"
- "tailscale.com/types/logger"
- "tailscale.com/util/winutil"
- "tailscale.com/util/winutil/conpty"
)
func init() {
diff --git a/util/winutil/startupinfo_windows.go b/util/winutil/startupinfo_windows.go
index 5ded67c7c78e1..ac560d134901e 100644
--- a/util/winutil/startupinfo_windows.go
+++ b/util/winutil/startupinfo_windows.go
@@ -6,11 +6,11 @@ package winutil
import (
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"os"
- "slices"
"unsafe"
- "github.com/dblohm7/wingoes"
+ "github.com/metacubex/tailscale/util/wingoes"
"golang.org/x/sys/windows"
)
diff --git a/util/winutil/subprocess_windows_test.go b/util/winutil/subprocess_windows_test.go
index f7c205d61c393..f9532650a0a3c 100644
--- a/util/winutil/subprocess_windows_test.go
+++ b/util/winutil/subprocess_windows_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
diff --git a/util/winutil/svcdiag_windows.go b/util/winutil/svcdiag_windows.go
index e28f9b6af58d6..1b27206239bbd 100644
--- a/util/winutil/svcdiag_windows.go
+++ b/util/winutil/svcdiag_windows.go
@@ -10,11 +10,11 @@ import (
"strings"
"unsafe"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/set"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/mgr"
- "tailscale.com/types/logger"
- "tailscale.com/util/set"
)
// LogSvcState obtains the state of the Windows service named rootSvcName and
diff --git a/util/winutil/userprofile_windows.go b/util/winutil/userprofile_windows.go
index c7fb028966ba6..75dde7c50e284 100644
--- a/util/winutil/userprofile_windows.go
+++ b/util/winutil/userprofile_windows.go
@@ -8,10 +8,10 @@ import (
"strings"
"unsafe"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/winutil/winenv"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
- "tailscale.com/types/logger"
- "tailscale.com/util/winutil/winenv"
)
type _PROFILEINFO struct {
diff --git a/util/winutil/userprofile_windows_test.go b/util/winutil/userprofile_windows_test.go
index 0a21cea6ac10f..f6b63ce65a1aa 100644
--- a/util/winutil/userprofile_windows_test.go
+++ b/util/winutil/userprofile_windows_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/winutil/winutil_windows.go b/util/winutil/winutil_windows.go
index cab0dabdf3694..bdb8575700734 100644
--- a/util/winutil/winutil_windows.go
+++ b/util/winutil/winutil_windows.go
@@ -698,10 +698,10 @@ func AllocateContiguousBuffer[T any, BU BufUnit](values ...[]BU) (t *T, tLenByte
}
// Get the sizes of T and BU, then compute a preferred alignment for T.
- tT := reflect.TypeFor[T]()
+ tT := reflect.TypeOf((*T)(nil)).Elem()
szT := tT.Size()
szBU := int(unsafe.Sizeof(BU(0)))
- alignment := max(tT.Align(), szBU)
+ alignment := maxInt(tT.Align(), szBU)
// Our buffers for values will start at the next szBU boundary.
tLenBytes = alignUp(uint32(szT), szBU)
@@ -972,3 +972,10 @@ func GUIPathFromReg() (string, error) {
return regPath, nil
}
+
+func maxInt(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
diff --git a/util/winutil/winutil_windows_test.go b/util/winutil/winutil_windows_test.go
index 955006789bc43..309a876037d06 100644
--- a/util/winutil/winutil_windows_test.go
+++ b/util/winutil/winutil_windows_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/util/winutil/zsyscall_windows.go b/util/winutil/zsyscall_windows.go
index 56aedb4c7f59c..fa3590a55e706 100644
--- a/util/winutil/zsyscall_windows.go
+++ b/util/winutil/zsyscall_windows.go
@@ -6,7 +6,7 @@ import (
"syscall"
"unsafe"
- "github.com/dblohm7/wingoes"
+ "github.com/metacubex/tailscale/util/wingoes"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
)
diff --git a/util/zstdframe/options.go b/util/zstdframe/options.go
index 67ab27169166d..64cde6246a326 100644
--- a/util/zstdframe/options.go
+++ b/util/zstdframe/options.go
@@ -9,7 +9,7 @@ import (
"sync"
"github.com/klauspost/compress/zstd"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/util/must"
)
// Option is an option that can be passed to [AppendEncode] or [AppendDecode].
@@ -216,7 +216,7 @@ func getDecoder(opts ...Option) decoder {
zopts := [...]zstd.DOption{
// Set concurrency=1 to ensure synchronous operation.
zstd.WithDecoderConcurrency(1),
- zstd.WithDecoderMaxMemory(1 << min(max(10, dopts.maxSizeLog2), 63)),
+ zstd.WithDecoderMaxMemory(1 << minInt(maxInt(10, int(dopts.maxSizeLog2)), 63)),
zstd.IgnoreChecksum(!dopts.checksum),
zstd.WithDecoderLowmem(dopts.lowMemory),
nil, // reserved for zstd.WithDecoderMaxWindow
@@ -231,6 +231,20 @@ func getDecoder(opts ...Option) decoder {
return decoder{pool, dec, maxSize}
}
+func minInt(a, b int) int {
+ if a < b {
+ return a
+ }
+ return b
+}
+
+func maxInt(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+
func putDecoder(d decoder) { d.pool.Put(d.Decoder) }
func (d decoder) DecodeAll(src, dst []byte) ([]byte, error) {
diff --git a/util/zstdframe/zstd_test.go b/util/zstdframe/zstd_test.go
index c006a06fd9d39..44901c249281e 100644
--- a/util/zstdframe/zstd_test.go
+++ b/util/zstdframe/zstd_test.go
@@ -1,11 +1,13 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package zstdframe
import (
+ "github.com/metacubex/tailscale/util/go120/randv2"
"math/bits"
- "math/rand/v2"
"os"
"runtime"
"strings"
@@ -13,7 +15,7 @@ import (
"testing"
"github.com/klauspost/compress/zstd"
- "tailscale.com/util/must"
+ "github.com/metacubex/tailscale/util/must"
)
// Use the concatenation of all Go source files in zstdframe as testdata.
diff --git a/version/cmdname.go b/version/cmdname.go
index 8e6adb047c8cc..9808599474549 100644
--- a/version/cmdname.go
+++ b/version/cmdname.go
@@ -48,9 +48,9 @@ func cmdName(exe string) string {
return fallbackName
}
// v is like:
- // "path\ttailscale.com/cmd/tailscale\nmod\ttailscale.com\t(devel)\t\ndep\tgithub.com/apenwarr/fixconsole\tv0.0.0-20191012055117-5a9f6489cc29\th1:muXWUcay7DDy1/hEQWrYlBy+g0EuwT70sBHg65SeUc4=\ndep\tgithub....
- for line := range strings.SplitSeq(info, "\n") {
- if goPkg, ok := strings.CutPrefix(line, "path\t"); ok { // like "tailscale.com/cmd/tailscale"
+ // "path\tgithub.com/metacubex/tailscale/cmd/tailscale\nmod\ttailscale.com\t(devel)\t\ndep\tgithub.com/apenwarr/fixconsole\tv0.0.0-20191012055117-5a9f6489cc29\th1:muXWUcay7DDy1/hEQWrYlBy+g0EuwT70sBHg65SeUc4=\ndep\tgithub....
+ for _, line := range strings.Split(info, "\n") {
+ if goPkg, ok := strings.CutPrefix(line, "path\t"); ok { // like "github.com/metacubex/tailscale/cmd/tailscale"
ret = path.Base(goPkg) // goPkg is always forward slashes; use path, not filepath
break
}
diff --git a/version/cmp.go b/version/cmp.go
index 6d44475e75743..15c314a6df5cf 100644
--- a/version/cmp.go
+++ b/version/cmp.go
@@ -164,7 +164,7 @@ func atoi(s string) (int, bool) {
}
un := uint(0)
- for i := range len(s) {
+ for i := 0; i < len(s); i++ {
c := s[i]
if c < '0' || c > '9' {
return 0, false
diff --git a/version/cmp_test.go b/version/cmp_test.go
index c93df1a7cebe2..fc1e5351e7cd1 100644
--- a/version/cmp_test.go
+++ b/version/cmp_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,8 +9,8 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
- "tailscale.com/tstest"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/version"
)
func TestParse(t *testing.T) {
diff --git a/version/distro/distro.go b/version/distro/distro.go
index 03c02ccab91cf..0d8b081e290cf 100644
--- a/version/distro/distro.go
+++ b/version/distro/distro.go
@@ -11,8 +11,9 @@ import (
"strconv"
"strings"
- "tailscale.com/types/lazy"
- "tailscale.com/util/lineiter"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/types/result"
+ "github.com/metacubex/tailscale/util/lineiter"
)
type Distro string
@@ -150,18 +151,25 @@ func DSMVersion() int {
return v
}
// But when run from the command line, we have to read it from the file:
- for lr := range lineiter.File("/etc/VERSION") {
+ var found int
+ lineiter.File("/etc/VERSION")(func(lr result.Of[[]byte]) bool {
line, err := lr.Value()
if err != nil {
- break // but otherwise ignore
+ return false // but otherwise ignore
}
line = bytes.TrimSpace(line)
if string(line) == `majorversion="7"` {
- return 7
+ found = 7
+ return false
}
if string(line) == `majorversion="6"` {
- return 6
+ found = 6
+ return false
}
+ return true
+ })
+ if found != 0 {
+ return found
}
return 0
})
diff --git a/version/distro/distro_test.go b/version/distro/distro_test.go
index f3460a180edc2..aae112ceddb17 100644
--- a/version/distro/distro_test.go
+++ b/version/distro/distro_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/version/export_test.go b/version/export_test.go
index ec43ad33248a7..d9632854733b4 100644
--- a/version/export_test.go
+++ b/version/export_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/version/mkversion/mkversion.go b/version/mkversion/mkversion.go
index 45576e4c1161b..47aa59a090abd 100644
--- a/version/mkversion/mkversion.go
+++ b/version/mkversion/mkversion.go
@@ -35,7 +35,7 @@ type VersionInfo struct {
// Long is the long version string. See the documentation for version.Long
// for possible values.
Long string
- // GitHash is the git hash of the tailscale.com Go module.
+ // GitHash is the git hash of the github.com/metacubex/tailscale Go module.
GitHash string
// OtherHash is the git hash of a supplemental git repository, if any. For
// example, the commit of the tailscale-android repository.
@@ -132,8 +132,8 @@ func InfoFrom(dir string) (VersionInfo, error) {
if modPath == "" {
return VersionInfo{}, fmt.Errorf("no module path in go.mod")
}
- if modPath == "tailscale.com" {
- // Invoked in the tailscale.com repo directly, just no further info to
+ if modPath == "github.com/metacubex/tailscale" {
+ // Invoked in the github.com/metacubex/tailscale repo directly, just no further info to
// collect.
v, err := infoFromDir(gitRoot)
if err != nil {
@@ -142,8 +142,8 @@ func InfoFrom(dir string) (VersionInfo, error) {
return mkOutput(v)
}
- // We seem to be in a repo that imports tailscale.com. Find the
- // tailscale.com repo and collect additional info from it.
+ // We seem to be in a repo that imports github.com/metacubex/tailscale. Find the
+ // github.com/metacubex/tailscale repo and collect additional info from it.
otherHash, err := runner.output("git", "rev-parse", "HEAD")
if err != nil {
return VersionInfo{}, fmt.Errorf("getting git hash: %w", err)
@@ -175,7 +175,7 @@ func InfoFrom(dir string) (VersionInfo, error) {
return mkOutput(v)
}
-// tailscaleModuleRef returns the git ref of the 'require tailscale.com' line
+// tailscaleModuleRef returns the git ref of the 'require github.com/metacubex/tailscale' line
// in the given go.mod bytes. The ref is either a short commit hash, or a git
// tag.
func tailscaleModuleRef(modBs []byte) (string, error) {
@@ -184,7 +184,7 @@ func tailscaleModuleRef(modBs []byte) (string, error) {
return "", err
}
for _, req := range mod.Require {
- if req.Mod.Path != "tailscale.com" {
+ if req.Mod.Path != "github.com/metacubex/tailscale" {
continue
}
// Get the last - separated part of req.Mod.Version
@@ -195,7 +195,7 @@ func tailscaleModuleRef(modBs []byte) (string, error) {
// If there are no dashes, the version is a tag.
return req.Mod.Version, nil
}
- return "", fmt.Errorf("no require tailscale.com line in go.mod")
+ return "", fmt.Errorf("no require github.com/metacubex/tailscale line in go.mod")
}
func mkOutput(v verInfo) (VersionInfo, error) {
@@ -329,7 +329,7 @@ type verInfo struct {
otherDate string
}
-// unknownPatchVersion is the patch version used when the tailscale.com package
+// unknownPatchVersion is the patch version used when the github.com/metacubex/tailscale package
// doesn't contain enough version information to derive the correct version.
// Such builds only get used when generating bug reports in an ephemeral working
// environment, so will never be distributed. As such, we use a highly visible
@@ -348,8 +348,8 @@ func infoFromCache(ref string, runner dirRunner) (verInfo, error) {
r := dirRunner(tailscaleCache)
if _, err := os.Stat(tailscaleCache); err != nil {
- if !runner.ok("git", "clone", "https://github.com/tailscale/tailscale", tailscaleCache) {
- return verInfo{}, fmt.Errorf("cloning tailscale.com repo failed")
+ if !runner.ok("git", "clone", "https://github.com/metacubex/tailscale", tailscaleCache) {
+ return verInfo{}, fmt.Errorf("cloning github.com/metacubex/tailscale repo failed")
}
}
diff --git a/version/mkversion/mkversion_test.go b/version/mkversion/mkversion_test.go
index 2f1a922c98924..a624c74bd0a70 100644
--- a/version/mkversion/mkversion_test.go
+++ b/version/mkversion/mkversion_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/version/modinfo_test.go b/version/modinfo_test.go
index ef75ce0771a47..5cc0868b1aba3 100644
--- a/version/modinfo_test.go
+++ b/version/modinfo_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,7 +12,7 @@ import (
"strings"
"testing"
- "tailscale.com/version"
+ "github.com/metacubex/tailscale/version"
)
var (
@@ -21,7 +23,7 @@ var (
func TestFindModuleInfo(t *testing.T) {
dir := t.TempDir()
name := filepath.Join(dir, "tailscaled-version-test")
- out, err := exec.Command("go", "build", "-o", name, "tailscale.com/cmd/tailscaled").CombinedOutput()
+ out, err := exec.Command("go", "build", "-o", name, "github.com/metacubex/tailscale/cmd/tailscaled").CombinedOutput()
if err != nil {
t.Fatalf("failed to build tailscaled: %v\n%s", err, out)
}
@@ -29,7 +31,7 @@ func TestFindModuleInfo(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- prefix := "path\ttailscale.com/cmd/tailscaled\nmod\ttailscale.com"
+ prefix := "path\tgithub.com/metacubex/tailscale/cmd/tailscaled\nmod\ttailscale.com"
if !strings.HasPrefix(modinfo, prefix) {
t.Errorf("unexpected modinfo contents %q", modinfo)
}
diff --git a/version/print.go b/version/print.go
index 3b4a256cf8781..5162028741052 100644
--- a/version/print.go
+++ b/version/print.go
@@ -5,12 +5,12 @@ package version
import (
"fmt"
+ "github.com/metacubex/tailscale/syncs"
"runtime"
"strings"
- "sync"
)
-var stringLazy = sync.OnceValue(func() string {
+var stringLazy = syncs.OnceValue(func() string {
var ret strings.Builder
ret.WriteString(Short())
ret.WriteByte('\n')
diff --git a/version/prop.go b/version/prop.go
index 59ca74086bd01..508842028f8cb 100644
--- a/version/prop.go
+++ b/version/prop.go
@@ -4,15 +4,15 @@
package version
import (
+ "github.com/metacubex/tailscale/syncs"
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
- "sync"
- "tailscale.com/tailcfg"
- "tailscale.com/types/lazy"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/lazy"
)
// AppIdentifierFn, if non-nil, is a callback function that returns the
@@ -214,6 +214,7 @@ var isUnstableBuild lazy.SyncValue[bool]
// IsUnstableBuild reports whether this is an unstable build.
// That is, whether its minor version number is odd.
func IsUnstableBuild() bool {
+ return false
return isUnstableBuild.Get(func() bool {
_, rest, ok := strings.Cut(Short(), ".")
if !ok {
@@ -248,7 +249,7 @@ func osVariant() string {
return ""
}
-var isDev = sync.OnceValue(func() bool {
+var isDev = syncs.OnceValue(func() bool {
return strings.Contains(Short(), "-dev")
})
diff --git a/version/version.go b/version/version.go
index 8ffc218321357..8b910a8c25c61 100644
--- a/version/version.go
+++ b/version/version.go
@@ -6,13 +6,13 @@ package version
import (
"fmt"
+ "github.com/metacubex/tailscale/syncs"
"runtime/debug"
"strconv"
"strings"
- "sync"
- tailscaleroot "tailscale.com"
- "tailscale.com/types/lazy"
+ tailscaleroot "github.com/metacubex/tailscale"
+ "github.com/metacubex/tailscale/types/lazy"
)
// Stamp vars can have their value set at build time by linker flags (see
@@ -118,7 +118,7 @@ func (i embeddedInfo) commitAbbrev() string {
return i.commit
}
-var getEmbeddedInfo = sync.OnceValue(func() embeddedInfo {
+var getEmbeddedInfo = syncs.OnceValue(func() embeddedInfo {
bi, ok := debug.ReadBuildInfo()
if !ok {
return embeddedInfo{}
@@ -150,7 +150,7 @@ var getEmbeddedInfo = sync.OnceValue(func() embeddedInfo {
// used to build this binary, if any. It is read separately from getEmbeddedInfo
// because that function discards build info when VCS fields are missing (e.g.
// in test binaries), but the toolchain rev is still present.
-var tailscaleToolchainRev = sync.OnceValue(func() string {
+var tailscaleToolchainRev = syncs.OnceValue(func() string {
bi, ok := debug.ReadBuildInfo()
if !ok {
return ""
@@ -202,7 +202,7 @@ func isValidLongWithTwoRepos(v string) bool {
if len(s) < 6 {
return false
}
- for i := range len(s) {
+ for i := 0; i < len(s); i++ {
b := s[i]
if (b < '0' || b > '9') && (b < 'a' || b > 'f') {
return false
diff --git a/version/version_internal_test.go b/version/version_internal_test.go
index 72b2dcd5f1f5d..e21a1eb487622 100644
--- a/version/version_internal_test.go
+++ b/version/version_internal_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,7 +10,7 @@ import (
"strings"
"testing"
- "tailscale.com/util/cibuild"
+ "github.com/metacubex/tailscale/util/cibuild"
)
func TestIsValidLongWithTwoRepos(t *testing.T) {
diff --git a/version/version_test.go b/version/version_test.go
index 01fcd47ecc0b5..4480938936d08 100644
--- a/version/version_test.go
+++ b/version/version_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,8 +12,8 @@ import (
"runtime/debug"
"testing"
- ts "tailscale.com"
- "tailscale.com/version"
+ ts "github.com/metacubex/tailscale"
+ "github.com/metacubex/tailscale/version"
)
func TestAlpineTag(t *testing.T) {
diff --git a/version_tailscale_test.go b/version_tailscale_test.go
index 60a8d54f48093..caabc9103c401 100644
--- a/version_tailscale_test.go
+++ b/version_tailscale_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build tailscale_go
-
package tailscaleroot
import (
diff --git a/version_test.go b/version_test.go
index 6fb3ddef9d52b..de917cf222b87 100644
--- a/version_test.go
+++ b/version_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/wf/firewall.go b/wf/firewall.go
index 995a60c3e3356..490e65255d6e8 100644
--- a/wf/firewall.go
+++ b/wf/firewall.go
@@ -11,9 +11,9 @@ import (
"net/netip"
"os"
+ "github.com/metacubex/tailscale/net/netaddr"
"github.com/tailscale/wf"
"golang.org/x/sys/windows"
- "tailscale.com/net/netaddr"
)
// Known addresses.
diff --git a/wgengine/bench/bench.go b/wgengine/bench/bench.go
index 7ce673b488e4a..4cec5877552cf 100644
--- a/wgengine/bench/bench.go
+++ b/wgengine/bench/bench.go
@@ -18,7 +18,7 @@ import (
"sync"
"time"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
const PayloadSize = 1000
diff --git a/wgengine/bench/bench_test.go b/wgengine/bench/bench_test.go
index 8788f4721a0e0..55b9f782f6615 100644
--- a/wgengine/bench/bench_test.go
+++ b/wgengine/bench/bench_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -10,7 +12,7 @@ import (
"testing"
"time"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
func BenchmarkTrivialNoAlloc(b *testing.B) {
diff --git a/wgengine/bench/trafficgen.go b/wgengine/bench/trafficgen.go
index 3be398d5348d1..481aedb3148f8 100644
--- a/wgengine/bench/trafficgen.go
+++ b/wgengine/bench/trafficgen.go
@@ -11,8 +11,8 @@ import (
"sync"
"time"
- "tailscale.com/net/packet"
- "tailscale.com/types/ipproto"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/types/ipproto"
)
type Snapshot struct {
diff --git a/wgengine/bench/wg.go b/wgengine/bench/wg.go
index 7b35a089aebcc..ca9cf42b7f69b 100644
--- a/wgengine/bench/wg.go
+++ b/wgengine/bench/wg.go
@@ -12,18 +12,18 @@ import (
"sync"
"testing"
- "github.com/tailscale/wireguard-go/tun"
-
- "tailscale.com/net/dns"
- "tailscale.com/tailcfg"
- "tailscale.com/tsd"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/wgengine"
- "tailscale.com/wgengine/filter"
- "tailscale.com/wgengine/router"
- "tailscale.com/wgengine/wgcfg"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+
+ "github.com/metacubex/tailscale/net/dns"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/wgengine"
+ "github.com/metacubex/tailscale/wgengine/filter"
+ "github.com/metacubex/tailscale/wgengine/router"
+ "github.com/metacubex/tailscale/wgengine/wgcfg"
)
func epFromTyped(eps []tailcfg.Endpoint) (ret []netip.AddrPort) {
diff --git a/wgengine/filter/filter.go b/wgengine/filter/filter.go
index b2be836c73395..7f207b2be4c54 100644
--- a/wgengine/filter/filter.go
+++ b/wgengine/filter/filter.go
@@ -6,26 +6,26 @@ package filter
import (
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
"sync"
"time"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/net/flowtrack"
+ "github.com/metacubex/tailscale/net/ipset"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime/rate"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/util/usermetric"
+ "github.com/metacubex/tailscale/wgengine/filter/filtertype"
"go4.org/netipx"
- "tailscale.com/envknob"
- "tailscale.com/net/flowtrack"
- "tailscale.com/net/ipset"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/packet"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime/rate"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/logger"
- "tailscale.com/types/views"
- "tailscale.com/util/mak"
- "tailscale.com/util/slicesx"
- "tailscale.com/util/usermetric"
- "tailscale.com/wgengine/filter/filtertype"
)
// Filter is a stateful packet filter.
diff --git a/wgengine/filter/filter_test.go b/wgengine/filter/filter_test.go
index a3b9a8e001e60..9d1d934c235f7 100644
--- a/wgengine/filter/filter_test.go
+++ b/wgengine/filter/filter_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,30 +10,30 @@ import (
"encoding/json"
"flag"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"os"
- "slices"
"strconv"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
+ "github.com/metacubex/tailscale/net/flowtrack"
+ "github.com/metacubex/tailscale/net/ipset"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstime/rate"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/util/usermetric"
+ "github.com/metacubex/tailscale/wgengine/filter/filtertype"
"go4.org/netipx"
- "tailscale.com/net/flowtrack"
- "tailscale.com/net/ipset"
- "tailscale.com/net/packet"
- "tailscale.com/net/tsaddr"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/tstime/rate"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/logger"
- "tailscale.com/types/views"
- "tailscale.com/util/must"
- "tailscale.com/util/slicesx"
- "tailscale.com/util/usermetric"
- "tailscale.com/wgengine/filter/filtertype"
)
// testAllowedProto is an IP protocol number we treat as allowed for
diff --git a/wgengine/filter/filtertype/filtertype.go b/wgengine/filter/filtertype/filtertype.go
index aab5fe8eef046..6c340eeee85a0 100644
--- a/wgengine/filter/filtertype/filtertype.go
+++ b/wgengine/filter/filtertype/filtertype.go
@@ -9,12 +9,12 @@ import (
"net/netip"
"strings"
- "tailscale.com/tailcfg"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/views"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/views"
)
-//go:generate go run tailscale.com/cmd/cloner --type=Match,CapMatch
+//go:generate go run github.com/metacubex/tailscale/cmd/cloner --type=Match,CapMatch
// PortRange is a range of TCP and UDP ports.
type PortRange struct {
diff --git a/wgengine/filter/filtertype/filtertype_clone.go b/wgengine/filter/filtertype/filtertype_clone.go
index 094063a5d1305..1cd3157fd17b8 100644
--- a/wgengine/filter/filtertype/filtertype_clone.go
+++ b/wgengine/filter/filtertype/filtertype_clone.go
@@ -1,16 +1,16 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-// Code generated by tailscale.com/cmd/cloner; DO NOT EDIT.
+// Code generated by github.com/metacubex/tailscale/cmd/cloner; DO NOT EDIT.
package filtertype
import (
"net/netip"
- "tailscale.com/tailcfg"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/views"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/views"
)
// Clone makes a deep copy of Match.
diff --git a/wgengine/filter/match.go b/wgengine/filter/match.go
index eee6ddf258fa1..5668341d447f0 100644
--- a/wgengine/filter/match.go
+++ b/wgengine/filter/match.go
@@ -6,10 +6,10 @@ package filter
import (
"net/netip"
- "tailscale.com/net/packet"
- "tailscale.com/tailcfg"
- "tailscale.com/types/views"
- "tailscale.com/wgengine/filter/filtertype"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/wgengine/filter/filtertype"
)
type matches []filtertype.Match
diff --git a/wgengine/filter/tailcfg.go b/wgengine/filter/tailcfg.go
index e7e71526a43bc..4f4677f4db03c 100644
--- a/wgengine/filter/tailcfg.go
+++ b/wgengine/filter/tailcfg.go
@@ -8,12 +8,12 @@ import (
"net/netip"
"strings"
+ "github.com/metacubex/tailscale/net/ipset"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/views"
"go4.org/netipx"
- "tailscale.com/net/ipset"
- "tailscale.com/net/netaddr"
- "tailscale.com/tailcfg"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/views"
)
var defaultProtos = []ipproto.Proto{
diff --git a/wgengine/magicsock/blockforever_conn.go b/wgengine/magicsock/blockforever_conn.go
index a215826b751f7..25246aad0c8e7 100644
--- a/wgengine/magicsock/blockforever_conn.go
+++ b/wgengine/magicsock/blockforever_conn.go
@@ -11,7 +11,7 @@ import (
"syscall"
"time"
- "tailscale.com/syncs"
+ "github.com/metacubex/tailscale/syncs"
)
// blockForeverConn is a net.PacketConn whose reads block until it is closed.
diff --git a/wgengine/magicsock/debughttp.go b/wgengine/magicsock/debughttp.go
index a9f4734f9653e..19ae3d3f72f5d 100644
--- a/wgengine/magicsock/debughttp.go
+++ b/wgengine/magicsock/debughttp.go
@@ -13,11 +13,11 @@ import (
"strings"
"time"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime/mono"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime/mono"
+ "github.com/metacubex/tailscale/types/key"
)
// ServeHTTPDebug serves an HTML representation of the innards of c for debugging.
diff --git a/wgengine/magicsock/debugknobs.go b/wgengine/magicsock/debugknobs.go
index 580d954c0bc40..28b1b2148cd46 100644
--- a/wgengine/magicsock/debugknobs.go
+++ b/wgengine/magicsock/debugknobs.go
@@ -9,9 +9,9 @@ import (
"log"
"net/netip"
"strings"
- "sync"
- "tailscale.com/envknob"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/syncs"
)
// Various debugging and experimental tweakables, set by environment
@@ -83,7 +83,7 @@ func inTest() bool { return envknob.Bool("IN_TS_TEST") }
// https://github.com/tailscale/tailscale/pull/12735.
//
// It can be between 0 and 3 comma-separated AddrPorts.
-var pretendpoints = sync.OnceValue(func() (ret []netip.AddrPort) {
+var pretendpoints = syncs.OnceValue(func() (ret []netip.AddrPort) {
all := envknob.String("TS_DEBUG_PRETENDPOINT")
const max = 3
remain := all
diff --git a/wgengine/magicsock/debugknobs_stubs.go b/wgengine/magicsock/debugknobs_stubs.go
index c156ff8a7d92b..a66806533e9c1 100644
--- a/wgengine/magicsock/debugknobs_stubs.go
+++ b/wgengine/magicsock/debugknobs_stubs.go
@@ -8,7 +8,7 @@ package magicsock
import (
"net/netip"
- "tailscale.com/types/opt"
+ "github.com/metacubex/tailscale/types/opt"
)
// All knobs are disabled on iOS and Wasm.
diff --git a/wgengine/magicsock/derp.go b/wgengine/magicsock/derp.go
index 72c75db5a835a..d5b4bbc47ec75 100644
--- a/wgengine/magicsock/derp.go
+++ b/wgengine/magicsock/derp.go
@@ -8,30 +8,30 @@ import (
"context"
"crypto/tls"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net"
"net/netip"
"reflect"
- "slices"
"time"
"unsafe"
- "github.com/tailscale/wireguard-go/conn"
- "tailscale.com/derp"
- "tailscale.com/derp/derphttp"
- "tailscale.com/health"
- "tailscale.com/net/dnscache"
- "tailscale.com/net/netcheck"
- "tailscale.com/net/tsaddr"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime/mono"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/util/backoff"
- "tailscale.com/util/mak"
- "tailscale.com/util/rands"
- "tailscale.com/util/testenv"
+ "github.com/metacubex/tailscale-wireguard-go/conn"
+ "github.com/metacubex/tailscale/derp"
+ "github.com/metacubex/tailscale/derp/derphttp"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/dnscache"
+ "github.com/metacubex/tailscale/net/netcheck"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime/mono"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/backoff"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/rands"
+ "github.com/metacubex/tailscale/util/testenv"
)
// frameReceiveRecordRate is the minimum time between updates to last frame
@@ -413,6 +413,7 @@ func (c *Conn) derpWriteChanForRegion(regionID int, peer key.NodePublic) chan de
}
return derpMap.Regions[regionID]
})
+ dc.SetURLDialer(c.systemDialer)
dc.HealthTracker = c.health
if c.extraRootCAs != nil {
dc.TLSConfig = &tls.Config{RootCAs: c.extraRootCAs}
diff --git a/wgengine/magicsock/derp_test.go b/wgengine/magicsock/derp_test.go
index c79882d54c2e5..c9a21946c60dc 100644
--- a/wgengine/magicsock/derp_test.go
+++ b/wgengine/magicsock/derp_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,12 +9,12 @@ import (
"fmt"
"testing"
- "tailscale.com/health"
- "tailscale.com/net/netcheck"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/netcheck"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
)
func CheckDERPHeuristicTimes(t *testing.T) {
diff --git a/wgengine/magicsock/disco_atomic.go b/wgengine/magicsock/disco_atomic.go
index e17ce2f97eb30..909d90de7fed3 100644
--- a/wgengine/magicsock/disco_atomic.go
+++ b/wgengine/magicsock/disco_atomic.go
@@ -6,7 +6,7 @@ package magicsock
import (
"sync/atomic"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/types/key"
)
type discoKeyPair struct {
diff --git a/wgengine/magicsock/disco_atomic_test.go b/wgengine/magicsock/disco_atomic_test.go
index cec4b1133b274..d1a3338ce355f 100644
--- a/wgengine/magicsock/disco_atomic_test.go
+++ b/wgengine/magicsock/disco_atomic_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,7 +8,7 @@ package magicsock
import (
"testing"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/types/key"
)
func TestDiscoAtomic(t *testing.T) {
diff --git a/wgengine/magicsock/endpoint.go b/wgengine/magicsock/endpoint.go
index d831a903216fd..89e58f079eda8 100644
--- a/wgengine/magicsock/endpoint.go
+++ b/wgengine/magicsock/endpoint.go
@@ -9,32 +9,32 @@ import (
"encoding/binary"
"errors"
"fmt"
- "iter"
+ iter "github.com/metacubex/tailscale/util/go120/iter"
+ "github.com/metacubex/tailscale/util/go120/randv2"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"math"
- "math/rand/v2"
"net"
"net/netip"
"reflect"
"runtime"
- "slices"
"sync/atomic"
"time"
+ "github.com/metacubex/tailscale/disco"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/stun"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime/mono"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/ringlog"
+ "github.com/metacubex/tailscale/util/slicesx"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
- "tailscale.com/disco"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/net/packet"
- "tailscale.com/net/stun"
- "tailscale.com/net/tstun"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime/mono"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/util/mak"
- "tailscale.com/util/ringlog"
- "tailscale.com/util/slicesx"
)
var mtuProbePingSizesV4 []int
@@ -103,7 +103,7 @@ type endpoint struct {
expired bool // whether the node has expired
isWireguardOnly bool // whether the endpoint is WireGuard only
- relayCapable bool // whether the node is capable of speaking via a [tailscale.com/net/udprelay.Server]
+ relayCapable bool // whether the node is capable of speaking via a [github.com/metacubex/tailscale/net/udprelay.Server]
}
// udpRelayEndpointReady determines whether the given relay [addrQuality] should
@@ -298,7 +298,7 @@ func (p *ProbeUDPLifetimeConfig) Valid() bool {
return false
}
for i, c := range p.Cliffs {
- if c <= max(udpLifetimeProbeCliffSlack*2, heartbeatInterval) {
+ if c <= maxDuration(udpLifetimeProbeCliffSlack*2, heartbeatInterval) {
// A timeout cliff less than or equal to twice
// udpLifetimeProbeCliffSlack is invalid due to being effectively
// zero when the cliff slack is subtracted from the cliff value at
@@ -782,7 +782,7 @@ func (de *endpoint) heartbeatForLifetime() {
p.resetCycleEndpointLocked()
return
}
- inactiveFor := mono.Now().Sub(max(de.lastRecvUDPAny.LoadAtomic(), de.lastSendAny))
+ inactiveFor := mono.Now().Sub(maxMonoTime(de.lastRecvUDPAny.LoadAtomic(), de.lastSendAny))
delta := afterInactivityFor - inactiveFor
if delta.Abs() > udpLifetimeProbeSchedulingTolerance {
if delta < 0 {
@@ -850,7 +850,7 @@ func (de *endpoint) heartbeat() {
// a WireGuard keepalive may have fallen somewhere within the
// sessionActiveTimeout window. heartbeatForLifetime will also
// perform a similar check, and reschedule as necessary.
- inactiveFor := now.Sub(max(de.lastSendAny, de.lastRecvUDPAny.LoadAtomic()))
+ inactiveFor := now.Sub(maxMonoTime(de.lastSendAny, de.lastRecvUDPAny.LoadAtomic()))
after := afterInactivityFor - inactiveFor
if after < 0 {
// shouldn't happen
@@ -1243,8 +1243,8 @@ const discoPingSize = len(disco.Magic) + key.DiscoPublicRawLen + disco.NonceLen
// The caller should use de.discoKey as the discoKey argument.
// It is passed in so that sendDiscoPing doesn't need to lock de.mu.
func (de *endpoint) sendDiscoPing(ep epAddr, discoKey key.DiscoPublic, txid stun.TxID, size int, logLevel discoLogLevel) {
- size = min(size, MaxDiscoPingSize)
- padding := max(size-discoPingSize, 0)
+ size = minInt(size, MaxDiscoPingSize)
+ padding := maxInt(size-discoPingSize, 0)
sent, _ := de.c.sendDiscoMessage(ep, de.publicKey, discoKey, &disco.Ping{
TxID: [12]byte(txid),
@@ -1265,7 +1265,7 @@ func (de *endpoint) sendDiscoPing(ep epAddr, discoKey key.DiscoPublic, txid stun
// discoPingPurpose is the reason why a discovery ping message was sent.
type discoPingPurpose int
-//go:generate go run tailscale.com/cmd/addlicense -file discopingpurpose_string.go go run golang.org/x/tools/cmd/stringer -type=discoPingPurpose -trimprefix=ping
+//go:generate go run github.com/metacubex/tailscale/cmd/addlicense -file discopingpurpose_string.go go run golang.org/x/tools/cmd/stringer -type=discoPingPurpose -trimprefix=ping
const (
// pingDiscovery means that purpose of a ping was to see if a
// path was valid.
@@ -1551,14 +1551,14 @@ func (de *endpoint) setEndpointsLocked(eps interface {
}
var newIpps []netip.AddrPort
- for i, ipp := range eps.All() {
+ eps.All()(func(i int, ipp netip.AddrPort) bool {
if i > math.MaxInt16 {
// Seems unlikely.
- break
+ return false
}
if !ipp.IsValid() {
de.c.logf("magicsock: bogus netmap endpoint from %v", eps)
- continue
+ return true
}
if st, ok := de.endpointState[ipp]; ok {
st.index = int16(i)
@@ -1566,7 +1566,8 @@ func (de *endpoint) setEndpointsLocked(eps interface {
de.endpointState[ipp] = &endpointState{index: int16(i)}
newIpps = append(newIpps, ipp)
}
- }
+ return true
+ })
if len(newIpps) > 0 {
de.debugUpdates.Add(EndpointChange{
When: time.Now(),
@@ -2099,3 +2100,31 @@ func (de *endpoint) setDERPHome(regionID uint16) {
de.c.relayManager.handleDERPHomeChange(de.publicKey, regionID)
}
}
+
+func minInt(a, b int) int {
+ if a < b {
+ return a
+ }
+ return b
+}
+
+func maxInt(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+
+func maxDuration(a, b time.Duration) time.Duration {
+ if a > b {
+ return a
+ }
+ return b
+}
+
+func maxMonoTime(a, b mono.Time) mono.Time {
+ if a.After(b) {
+ return a
+ }
+ return b
+}
diff --git a/wgengine/magicsock/endpoint_test.go b/wgengine/magicsock/endpoint_test.go
index 593cf1455b0c6..8503e609f83db 100644
--- a/wgengine/magicsock/endpoint_test.go
+++ b/wgengine/magicsock/endpoint_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,13 +11,13 @@ import (
"testing/synctest"
"time"
- "tailscale.com/disco"
- "tailscale.com/net/packet"
- "tailscale.com/net/stun"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime/mono"
- "tailscale.com/types/key"
- "tailscale.com/util/ringlog"
+ "github.com/metacubex/tailscale/disco"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/stun"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime/mono"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/util/ringlog"
)
func TestProbeUDPLifetimeConfig_Equals(t *testing.T) {
diff --git a/wgengine/magicsock/endpoint_tracker.go b/wgengine/magicsock/endpoint_tracker.go
index 372f346853723..277c3ee2f291c 100644
--- a/wgengine/magicsock/endpoint_tracker.go
+++ b/wgengine/magicsock/endpoint_tracker.go
@@ -4,15 +4,15 @@
package magicsock
import (
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
"time"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tempfork/heap"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tempfork/heap"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
)
const (
@@ -184,7 +184,7 @@ func (et *endpointTracker) extendLocked(ep tailcfg.Endpoint, until time.Time) {
for i, entry := range *epHeap {
if entry.endpoint == ep {
entry.until = until
- heap.Fix(epHeap, i)
+ heap.Fix[*endpointTrackerEntry](epHeap, i)
return
}
}
@@ -213,14 +213,14 @@ func (et *endpointTracker) addLocked(now time.Time, ep tailcfg.Endpoint, until t
if !found {
// Add address to heap; either the endpoint is new, or the heap
// was newly-created and thus empty.
- heap.Push(epHeap, &endpointTrackerEntry{endpoint: ep, until: until})
+ heap.Push[*endpointTrackerEntry](epHeap, &endpointTrackerEntry{endpoint: ep, until: until})
}
// Now that we've added everything, pop from our heap until we're below
// the limit. This is a min-heap, so popping removes the lowest (and
// thus oldest) endpoint.
for epHeap.Len() > endpointTrackerMaxPerAddr {
- heap.Pop(epHeap)
+ heap.Pop[*endpointTrackerEntry](epHeap)
}
}
@@ -234,7 +234,7 @@ func (et *endpointTracker) removeExpiredLocked(now time.Time) {
for epHeap.Len() > 0 {
minElem := epHeap.Min()
if now.After(minElem.until) {
- heap.Pop(epHeap)
+ heap.Pop[*endpointTrackerEntry](epHeap)
} else {
break
}
diff --git a/wgengine/magicsock/endpoint_tracker_test.go b/wgengine/magicsock/endpoint_tracker_test.go
index b3b1a63d94e29..5c5434ec48203 100644
--- a/wgengine/magicsock/endpoint_tracker_test.go
+++ b/wgengine/magicsock/endpoint_tracker_test.go
@@ -1,17 +1,19 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package magicsock
import (
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"reflect"
- "slices"
"strings"
"testing"
"time"
- "tailscale.com/tailcfg"
+ "github.com/metacubex/tailscale/tailcfg"
)
func TestEndpointTracker(t *testing.T) {
diff --git a/wgengine/magicsock/errors_go120.go b/wgengine/magicsock/errors_go120.go
new file mode 100644
index 0000000000000..4ef77482aea4a
--- /dev/null
+++ b/wgengine/magicsock/errors_go120.go
@@ -0,0 +1,7 @@
+//go:build !go1.21
+
+package magicsock
+
+import "errors"
+
+var ErrUnsupported = errors.New("unsupported operation")
diff --git a/wgengine/magicsock/errors_go121.go b/wgengine/magicsock/errors_go121.go
new file mode 100644
index 0000000000000..c9da7967ea8df
--- /dev/null
+++ b/wgengine/magicsock/errors_go121.go
@@ -0,0 +1,7 @@
+//go:build go1.21
+
+package magicsock
+
+import "errors"
+
+var ErrUnsupported = errors.ErrUnsupported
diff --git a/wgengine/magicsock/magicsock.go b/wgengine/magicsock/magicsock.go
index 6461c552ea951..4356f557919dd 100644
--- a/wgengine/magicsock/magicsock.go
+++ b/wgengine/magicsock/magicsock.go
@@ -13,64 +13,66 @@ import (
"encoding/binary"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net"
"net/netip"
"reflect"
"runtime"
- "slices"
"strconv"
"strings"
"sync"
"sync/atomic"
"time"
- "github.com/tailscale/wireguard-go/conn"
- "github.com/tailscale/wireguard-go/device"
+ "github.com/metacubex/tailscale-wireguard-go/conn"
+ "github.com/metacubex/tailscale-wireguard-go/device"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/disco"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/feature/condlite/expvar"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/hostinfo"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/net/batching"
+ "github.com/metacubex/tailscale/net/dnscache"
+ "github.com/metacubex/tailscale/net/netcheck"
+ "github.com/metacubex/tailscale/net/neterror"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/ping"
+ "github.com/metacubex/tailscale/net/portmapper/portmappertype"
+ "github.com/metacubex/tailscale/net/sockopts"
+ "github.com/metacubex/tailscale/net/sockstats"
+ "github.com/metacubex/tailscale/net/stun"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/tstime/mono"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/lazy"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netlogfunc"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/nettype"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/cloudinfo"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/ringlog"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/testenv"
+ "github.com/metacubex/tailscale/util/usermetric"
+ "github.com/metacubex/tailscale/wgengine/filter"
+ "github.com/metacubex/tailscale/wgengine/router"
+ "github.com/metacubex/tailscale/wgengine/wgint"
"go4.org/mem"
"golang.org/x/net/ipv6"
- "tailscale.com/control/controlknobs"
- "tailscale.com/disco"
- "tailscale.com/envknob"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/feature/condlite/expvar"
- "tailscale.com/health"
- "tailscale.com/hostinfo"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/net/batching"
- "tailscale.com/net/netcheck"
- "tailscale.com/net/neterror"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netns"
- "tailscale.com/net/packet"
- "tailscale.com/net/ping"
- "tailscale.com/net/portmapper/portmappertype"
- "tailscale.com/net/sockopts"
- "tailscale.com/net/sockstats"
- "tailscale.com/net/stun"
- "tailscale.com/net/tstun"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/tstime/mono"
- "tailscale.com/types/key"
- "tailscale.com/types/lazy"
- "tailscale.com/types/logger"
- "tailscale.com/types/netlogfunc"
- "tailscale.com/types/netmap"
- "tailscale.com/types/nettype"
- "tailscale.com/types/views"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/cloudinfo"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/mak"
- "tailscale.com/util/ringlog"
- "tailscale.com/util/set"
- "tailscale.com/util/testenv"
- "tailscale.com/util/usermetric"
- "tailscale.com/wgengine/filter"
- "tailscale.com/wgengine/router"
- "tailscale.com/wgengine/wgint"
)
const (
@@ -164,8 +166,10 @@ type Conn struct {
derpActiveFunc func()
idleFunc func() time.Duration // nil means unknown
testOnlyPacketListener nettype.PacketListener
+ packetListener netx.ListenPacketFunc
onDERPRecv func(int, key.NodePublic, []byte) bool // or nil, see Options.OnDERPRecv
netMon *netmon.Monitor // must be non-nil
+ systemDialer netx.DialFunc // or nil
health *health.Tracker // or nil
extraRootCAs *x509.CertPool // additional trusted root CAs; or nil
controlKnobs *controlknobs.Knobs // or nil
@@ -337,7 +341,7 @@ type Conn struct {
peerMap peerMap
// relayManager manages allocation and handshaking of
- // [tailscale.com/net/udprelay.Server] endpoints.
+ // [github.com/metacubex/tailscale/net/udprelay.Server] endpoints.
relayManager relayManager
// discoInfo is the state for an active peer DiscoKey.
@@ -464,6 +468,14 @@ type Options struct {
// It must be non-nil.
NetMon *netmon.Monitor
+ // SystemDialer optionally specifies how TCP probes and DERP connections
+ // dial non-Tailscale infrastructure.
+ SystemDialer netx.DialFunc
+
+ // PacketListener optionally specifies how UDP sockets are opened for
+ // non-Tailscale infrastructure.
+ PacketListener netx.ListenPacketFunc
+
// HealthTracker optionally specifies the health tracker to
// report errors and warnings to.
HealthTracker *health.Tracker
@@ -472,6 +484,10 @@ type Options struct {
// for TLS connections to DERP servers.
ExtraRootCAs *x509.CertPool
+ // LookupHook optionally specifies how tsnet resolves non-Tailscale
+ // infrastructure hostnames such as control and DERP.
+ LookupHook dnscache.LookupHookFunc
+
// Metrics specifies the metrics registry to record metrics to.
Metrics *usermetric.Registry
@@ -638,6 +654,7 @@ func NewConn(opts Options) (*Conn, error) {
c.derpActiveFunc = opts.derpActiveFunc()
c.idleFunc = opts.IdleFunc
c.testOnlyPacketListener = opts.TestOnlyPacketListener
+ c.packetListener = opts.PacketListener
c.onDERPRecv = opts.OnDERPRecv
// Set up publishers and subscribers. Subscribe calls must return before
@@ -676,6 +693,7 @@ func NewConn(opts Options) (*Conn, error) {
}
c.netMon = opts.NetMon
+ c.systemDialer = opts.SystemDialer
c.health = opts.HealthTracker
c.extraRootCAs = opts.ExtraRootCAs
c.getPeerByKey = opts.PeerByKeyFunc
@@ -687,10 +705,13 @@ func NewConn(opts Options) (*Conn, error) {
c.netChecker = &netcheck.Client{
Logf: logger.WithPrefix(c.logf, "netcheck: "),
NetMon: c.netMon,
+ Dialer: c.systemDialer,
+ PacketListener: c.packetListener,
SendPacket: c.sendUDPNetcheck,
SkipExternalNetwork: inTest(),
PortMapper: c.portMapper,
UseDNSCache: true,
+ LookupHook: opts.LookupHook,
}
c.metrics = registerMetrics(opts.Metrics)
@@ -701,13 +722,13 @@ func NewConn(opts Options) (*Conn, error) {
if d4, err := c.listenRawDisco("ip4"); err == nil {
c.logf("[v1] using BPF disco receiver for IPv4")
c.closeDisco4 = d4
- } else if !errors.Is(err, errors.ErrUnsupported) {
+ } else if !errors.Is(err, ErrUnsupported) {
c.logf("[v1] couldn't create raw v4 disco listener, using regular listener instead: %v", err)
}
if d6, err := c.listenRawDisco("ip6"); err == nil {
c.logf("[v1] using BPF disco receiver for IPv6")
c.closeDisco6 = d6
- } else if !errors.Is(err, errors.ErrUnsupported) {
+ } else if !errors.Is(err, ErrUnsupported) {
c.logf("[v1] couldn't create raw v6 disco listener, using regular listener instead: %v", err)
}
@@ -1345,9 +1366,10 @@ func (c *Conn) determineEndpoints(ctx context.Context) ([]tailcfg.Endpoint, erro
// re-run.
eps = c.endpointTracker.update(time.Now(), eps)
- for _, ep := range c.staticEndpoints.All() {
+ c.staticEndpoints.All()(func(_ int, ep netip.AddrPort) bool {
addAddr(ep, tailcfg.EndpointExplicitConf)
- }
+ return true
+ })
if localAddr := c.pconn4.LocalAddr(); localAddr.IP.IsUnspecified() {
ips, loopback, err := netmon.LocalAddresses()
@@ -1445,7 +1467,7 @@ func (c *Conn) networkDown() bool {
// Send implements conn.Bind.
//
-// See https://pkg.go.dev/github.com/tailscale/wireguard-go/conn#Bind.Send
+// See https://pkg.go.dev/github.com/metacubex/tailscale-wireguard-go/conn#Bind.Send
func (c *Conn) Send(buffs [][]byte, ep conn.Endpoint, offset int) (err error) {
n := int64(len(buffs))
defer func() {
@@ -1496,7 +1518,8 @@ func (c *Conn) sendUDPBatch(addr epAddr, buffs [][]byte, offset int) (sent bool,
err = c.pconn4.WriteWireGuardBatchTo(buffs, addr, offset)
}
if err != nil {
- if errGSO, ok := errors.AsType[neterror.ErrUDPGSODisabled](err); ok {
+ var errGSO neterror.ErrUDPGSODisabled
+ if ok := errors.As(err, &errGSO); ok {
c.logf("magicsock: %s", errGSO.Error())
err = errGSO.RetryErr
} else {
@@ -1565,11 +1588,11 @@ func (c *Conn) maybeRebindOnError(err error) {
// sendUDPNetcheck sends b via UDP to addr. It is used exclusively by netcheck.
// It returns the number of bytes sent along with any error encountered. It
-// returns errors.ErrUnsupported if the client is explicitly configured to only
+// returns ErrUnsupported if the client is explicitly configured to only
// send data over TCP port 443 and/or we're running on wasm.
func (c *Conn) sendUDPNetcheck(b []byte, addr netip.AddrPort) (int, error) {
if c.onlyTCP443.Load() || runtime.GOOS == "js" {
- return 0, errors.ErrUnsupported
+ return 0, ErrUnsupported
}
switch {
case addr.Addr().Is4():
@@ -1634,7 +1657,7 @@ func (c *Conn) sendAddr(addr netip.AddrPort, pubKey key.NodePublic, b []byte, is
pkt := bytes.Clone(b)
wr := derpWriteRequest{addr, pubKey, pkt, isDisco}
- for range 3 {
+ for i := 0; i < 3; i++ {
select {
case <-c.donec:
metricSendDERPErrorClosed.Add(1)
@@ -1831,7 +1854,7 @@ func (c *Conn) receiveIP(b []byte, ipp netip.AddrPort, cache *epAddrEndpointCach
// Strip away the Geneve header before returning the packet to
// wireguard-go.
//
- // TODO(jwhited): update [github.com/tailscale/wireguard-go/conn.ReceiveFunc]
+ // TODO(jwhited): update [github.com/metacubex/tailscale-wireguard-go/conn.ReceiveFunc]
// to support returning start offset in order to get rid of this memmove perf
// penalty.
size = copy(b, b[packet.GeneveFixedHeaderLength:])
@@ -2131,7 +2154,7 @@ func packetLooksLike(msg []byte) (t packetLooksLikeType, isGeneveEncap bool) {
// - magic [6]byte
// - senderDiscoPubKey [32]byte
// - nonce [24]byte
-// - naclbox of payload (see tailscale.com/disco package for inner payload format)
+// - naclbox of payload (see github.com/metacubex/tailscale/disco package for inner payload format)
//
// For messages received over DERP, the src.ap.Addr() will be derpMagicIP (with
// src.ap.Port() being the region ID) and the derpNodeSrc will be the node key
@@ -2787,7 +2810,7 @@ func debugRingBufferSize(numPeers int) int {
}
const averageRingBufferElemSize = 512
- return max(defaultVal, maxRingBufferSize/(averageRingBufferElemSize*numPeers))
+ return maxInt(defaultVal, maxRingBufferSize/(averageRingBufferElemSize*numPeers))
}
// debugFlags are the debug flags in use by the magicsock package.
@@ -2928,14 +2951,15 @@ func nodeHasCap(filt *filter.Filter, src, dst tailcfg.NodeView, cap tailcfg.Peer
!dst.Valid() {
return false
}
- for _, srcPrefix := range src.Addresses().All() {
+ var hasCap bool
+ src.Addresses().All()(func(_ int, srcPrefix netip.Prefix) bool {
if !srcPrefix.IsSingleIP() {
- continue
+ return true
}
srcAddr := srcPrefix.Addr()
- for _, dstPrefix := range dst.Addresses().All() {
+ dst.Addresses().All()(func(_ int, dstPrefix netip.Prefix) bool {
if !dstPrefix.IsSingleIP() {
- continue
+ return true
}
dstAddr := dstPrefix.Addr()
if dstAddr.BitLen() == srcAddr.BitLen() { // same address family
@@ -2946,11 +2970,14 @@ func nodeHasCap(filt *filter.Filter, src, dst tailcfg.NodeView, cap tailcfg.Peer
// same address family they either have the capability or not.
// We do not check against additional host addresses of the same
// address family.
- return filt.CapsWithValues(srcAddr, dstAddr).HasCapability(cap)
+ hasCap = filt.CapsWithValues(srcAddr, dstAddr).HasCapability(cap)
+ return false
}
- }
- }
- return false
+ return true
+ })
+ return !hasCap
+ })
+ return hasCap
}
// candidatePeerRelay represents the identifiers and DERP home region ID for a
@@ -3329,16 +3356,18 @@ func (c *Conn) logEndpointCreated(n tailcfg.NodeView) {
fmt.Fprintf(w, "derp=%v%s ", regionID, code)
}
- for _, a := range n.AllowedIPs().All() {
+ n.AllowedIPs().All()(func(_ int, a netip.Prefix) bool {
if a.IsSingleIP() {
fmt.Fprintf(w, "aip=%v ", a.Addr())
} else {
fmt.Fprintf(w, "aip=%v ", a)
}
- }
- for _, ep := range n.Endpoints().All() {
+ return true
+ })
+ n.Endpoints().All()(func(_ int, ep netip.AddrPort) bool {
fmt.Fprintf(w, "ep=%v ", ep)
- }
+ return true
+ })
}))
}
@@ -3611,6 +3640,13 @@ func (c *Conn) listenPacket(network string, port uint16) (nettype.PacketConn, er
if c.testOnlyPacketListener != nil {
return nettype.MakePacketListenerWithNetIP(c.testOnlyPacketListener).ListenPacket(ctx, network, addr)
}
+ if c.packetListener != nil {
+ pc, err := c.packetListener(ctx, network, addr)
+ if err != nil {
+ return nil, err
+ }
+ return nettype.MakePacketConn(pc), nil
+ }
return nettype.MakePacketListenerWithNetIP(netns.Listener(c.logf, c.netMon)).ListenPacket(ctx, network, addr)
}
@@ -3977,7 +4013,11 @@ const indexSentinelDeleted = -1
// already instantiated it returns the existing one.
func (c *Conn) getPinger() *ping.Pinger {
return c.wgPinger.Get(func() *ping.Pinger {
- return ping.New(c.connCtx, c.dlogf, netns.Listener(c.logf, c.netMon))
+ lp := c.packetListener
+ if lp == nil {
+ lp = netns.Listener(c.logf, c.netMon).ListenPacket
+ }
+ return ping.New(c.connCtx, c.dlogf, lp)
})
}
diff --git a/wgengine/magicsock/magicsock_default.go b/wgengine/magicsock/magicsock_default.go
index fc3e656b245f3..bb673f919ce1c 100644
--- a/wgengine/magicsock/magicsock_default.go
+++ b/wgengine/magicsock/magicsock_default.go
@@ -6,11 +6,10 @@
package magicsock
import (
- "errors"
"fmt"
"io"
)
func (c *Conn) listenRawDisco(family string) (io.Closer, error) {
- return nil, fmt.Errorf("raw disco listening not supported on this OS: %w", errors.ErrUnsupported)
+ return nil, fmt.Errorf("raw disco listening not supported on this OS: %w", ErrUnsupported)
}
diff --git a/wgengine/magicsock/magicsock_linux.go b/wgengine/magicsock/magicsock_linux.go
index 522341e721317..61f2265225ebe 100644
--- a/wgengine/magicsock/magicsock_linux.go
+++ b/wgengine/magicsock/magicsock_linux.go
@@ -18,17 +18,17 @@ import (
"time"
"github.com/mdlayher/socket"
+ "github.com/metacubex/tailscale/disco"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
"golang.org/x/net/bpf"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
"golang.org/x/sys/cpu"
"golang.org/x/sys/unix"
- "tailscale.com/disco"
- "tailscale.com/envknob"
- "tailscale.com/net/netns"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
)
const (
@@ -170,11 +170,11 @@ var (
// https://github.com/tailscale/tailscale/issues/3824
func (c *Conn) listenRawDisco(family string) (io.Closer, error) {
if !envknobEnableRawDisco() {
- // Return an 'errors.ErrUnsupported' to prevent the callee from
+ // Return an 'errUnsupported' to prevent the callee from
// logging; when we switch this to an opt-out (vs. an opt-in),
// drop the ErrUnsupported so that the callee logs that it was
// disabled.
- return nil, fmt.Errorf("raw disco not enabled: %w", errors.ErrUnsupported)
+ return nil, fmt.Errorf("raw disco not enabled: %w", ErrUnsupported)
}
// https://github.com/tailscale/tailscale/issues/5607
diff --git a/wgengine/magicsock/magicsock_linux_test.go b/wgengine/magicsock/magicsock_linux_test.go
index 200979f815ab0..c1d860f8edbc9 100644
--- a/wgengine/magicsock/magicsock_linux_test.go
+++ b/wgengine/magicsock/magicsock_linux_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,10 +11,10 @@ import (
"net/netip"
"testing"
+ "github.com/metacubex/tailscale/disco"
"golang.org/x/net/bpf"
"golang.org/x/sys/cpu"
"golang.org/x/sys/unix"
- "tailscale.com/disco"
)
func TestParseUDPPacket(t *testing.T) {
diff --git a/wgengine/magicsock/magicsock_notplan9.go b/wgengine/magicsock/magicsock_notplan9.go
index 6bb9db5d7f1d6..e0e669ae201b8 100644
--- a/wgengine/magicsock/magicsock_notplan9.go
+++ b/wgengine/magicsock/magicsock_notplan9.go
@@ -9,7 +9,7 @@ import (
"errors"
"syscall"
- "tailscale.com/net/neterror"
+ "github.com/metacubex/tailscale/net/neterror"
)
// shouldRebind returns if the error is one that is known to be healed by a
diff --git a/wgengine/magicsock/magicsock_test.go b/wgengine/magicsock/magicsock_test.go
index b3c21cb2469bd..e52a063e553d7 100644
--- a/wgengine/magicsock/magicsock_test.go
+++ b/wgengine/magicsock/magicsock_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -33,49 +35,49 @@ import (
qt "github.com/frankban/quicktest"
"github.com/google/go-cmp/cmp"
- wgconn "github.com/tailscale/wireguard-go/conn"
- "github.com/tailscale/wireguard-go/device"
- "github.com/tailscale/wireguard-go/tun/tuntest"
+ wgconn "github.com/metacubex/tailscale-wireguard-go/conn"
+ "github.com/metacubex/tailscale-wireguard-go/device"
+ "github.com/metacubex/tailscale-wireguard-go/tun/tuntest"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/derp/derpserver"
+ "github.com/metacubex/tailscale/disco"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/netcheck"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/ping"
+ "github.com/metacubex/tailscale/net/stun"
+ "github.com/metacubex/tailscale/net/stun/stuntest"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/tstest/natlab"
+ "github.com/metacubex/tailscale/tstime/mono"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netlogtype"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/nettype"
+ "github.com/metacubex/tailscale/util/cibuild"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/must"
+ "github.com/metacubex/tailscale/util/racebuild"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/slicesx"
+ "github.com/metacubex/tailscale/util/usermetric"
+ "github.com/metacubex/tailscale/wgengine/filter"
+ "github.com/metacubex/tailscale/wgengine/filter/filtertype"
+ "github.com/metacubex/tailscale/wgengine/wgcfg"
+ "github.com/metacubex/tailscale/wgengine/wgcfg/nmcfg"
+ "github.com/metacubex/tailscale/wgengine/wglog"
"go4.org/mem"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
- "tailscale.com/control/controlknobs"
- "tailscale.com/derp/derpserver"
- "tailscale.com/disco"
- "tailscale.com/envknob"
- "tailscale.com/health"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/netcheck"
- "tailscale.com/net/netmon"
- "tailscale.com/net/packet"
- "tailscale.com/net/ping"
- "tailscale.com/net/stun"
- "tailscale.com/net/stun/stuntest"
- "tailscale.com/net/tstun"
- "tailscale.com/tailcfg"
- "tailscale.com/tstest"
- "tailscale.com/tstest/natlab"
- "tailscale.com/tstime/mono"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/netlogtype"
- "tailscale.com/types/netmap"
- "tailscale.com/types/nettype"
- "tailscale.com/util/cibuild"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/must"
- "tailscale.com/util/racebuild"
- "tailscale.com/util/set"
- "tailscale.com/util/slicesx"
- "tailscale.com/util/usermetric"
- "tailscale.com/wgengine/filter"
- "tailscale.com/wgengine/filter/filtertype"
- "tailscale.com/wgengine/wgcfg"
- "tailscale.com/wgengine/wgcfg/nmcfg"
- "tailscale.com/wgengine/wglog"
)
func init() {
@@ -2701,7 +2703,7 @@ func mockPinger(t *testing.T, clock *tstest.Clock, dest net.Addr) (*ping.Pinger,
destPort: dIPP.Port(),
}
- p := ping.New(ctx, t.Logf, &mockListenPacketer{conn4: conn4, conn6: conn6})
+ p := ping.New(ctx, t.Logf, &mockListenPacketer{conn4: conn4, conn6: conn6}.ListenPacket)
done := func() {
if err := p.Close(); err != nil {
diff --git a/wgengine/magicsock/peermap.go b/wgengine/magicsock/peermap.go
index b6e9b08a360ed..0130dffb066ea 100644
--- a/wgengine/magicsock/peermap.go
+++ b/wgengine/magicsock/peermap.go
@@ -4,9 +4,9 @@
package magicsock
import (
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/util/set"
)
// peerInfo is all the information magicsock tracks about a particular
diff --git a/wgengine/magicsock/peermap_test.go b/wgengine/magicsock/peermap_test.go
index 7fcd09384e540..365be96e6f182 100644
--- a/wgengine/magicsock/peermap_test.go
+++ b/wgengine/magicsock/peermap_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,8 +9,8 @@ import (
"net/netip"
"testing"
- "tailscale.com/net/packet"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/types/key"
)
func Test_peerMap_oneRelayEpAddrPerNK(t *testing.T) {
diff --git a/wgengine/magicsock/peermtu.go b/wgengine/magicsock/peermtu.go
index 6f3df50a3c435..14770bf5b414c 100644
--- a/wgengine/magicsock/peermtu.go
+++ b/wgengine/magicsock/peermtu.go
@@ -8,9 +8,9 @@ package magicsock
import (
"errors"
+ "github.com/metacubex/tailscale/disco"
+ "github.com/metacubex/tailscale/net/tstun"
"golang.org/x/sys/unix"
- "tailscale.com/disco"
- "tailscale.com/net/tstun"
)
// Peer path MTU routines shared by platforms that implement it.
diff --git a/wgengine/magicsock/peermtu_stubs.go b/wgengine/magicsock/peermtu_stubs.go
index a7fc5c99ba869..d8aa0c60ba252 100644
--- a/wgengine/magicsock/peermtu_stubs.go
+++ b/wgengine/magicsock/peermtu_stubs.go
@@ -5,7 +5,7 @@
package magicsock
-import "tailscale.com/disco"
+import "github.com/metacubex/tailscale/disco"
func (c *Conn) DontFragSetting() (bool, error) {
return false, nil
diff --git a/wgengine/magicsock/rebinding_conn.go b/wgengine/magicsock/rebinding_conn.go
index 11398c5925617..c784fd3e68a24 100644
--- a/wgengine/magicsock/rebinding_conn.go
+++ b/wgengine/magicsock/rebinding_conn.go
@@ -11,12 +11,12 @@ import (
"sync/atomic"
"syscall"
+ "github.com/metacubex/tailscale/net/batching"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/nettype"
"golang.org/x/net/ipv6"
- "tailscale.com/net/batching"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/packet"
- "tailscale.com/syncs"
- "tailscale.com/types/nettype"
)
// RebindingUDPConn is a UDP socket that can be re-bound.
@@ -152,7 +152,7 @@ func (c *RebindingUDPConn) LocalAddr() *net.UDPAddr {
}
func (c *RebindingUDPConn) localAddrLocked() *net.UDPAddr {
- return c.pconn.LocalAddr().(*net.UDPAddr)
+ return net.UDPAddrFromAddrPort(netaddr.FromStdNetAddr(c.pconn.LocalAddr()))
}
// errNilPConn is returned by RebindingUDPConn.Close when there is no current pconn.
diff --git a/wgengine/magicsock/relaymanager.go b/wgengine/magicsock/relaymanager.go
index 8ea15bce30199..021a427fa2815 100644
--- a/wgengine/magicsock/relaymanager.go
+++ b/wgengine/magicsock/relaymanager.go
@@ -12,19 +12,19 @@ import (
"sync/atomic"
"time"
- "tailscale.com/disco"
- "tailscale.com/net/packet"
- "tailscale.com/net/stun"
- udprelay "tailscale.com/net/udprelay/endpoint"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime"
- "tailscale.com/types/key"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/disco"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/stun"
+ udprelay "github.com/metacubex/tailscale/net/udprelay/endpoint"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/util/set"
)
// relayManager manages allocation, handshaking, and initial probing (disco
-// ping/pong) of [tailscale.com/net/udprelay.Server] endpoints. The zero value
+// ping/pong) of [github.com/metacubex/tailscale/net/udprelay.Server] endpoints. The zero value
// is ready for use.
//
// [relayManager] methods can be called by [Conn] and [endpoint] while their .mu
@@ -79,7 +79,7 @@ type relayManager struct {
runLoopStoppedCh chan struct{}
}
-// serverDiscoVNI represents a [tailscale.com/net/udprelay.Server] disco key
+// serverDiscoVNI represents a [github.com/metacubex/tailscale/net/udprelay.Server] disco key
// and Geneve header VNI value for a given [udprelay.ServerEndpoint].
type serverDiscoVNI struct {
serverDisco key.DiscoPublic
@@ -916,7 +916,7 @@ func (r *relayManager) handshakeServerEndpoint(work *relayHandshakeWork) {
// detached and independent of 'BindLifetime' to prevent relay server
// (mis)configuration from negatively impacting client resource usage.
const maxHandshakeLifetime = time.Second * 30
- timer := time.NewTimer(min(work.se.BindLifetime.Duration, maxHandshakeLifetime))
+ timer := time.NewTimer(minDuration(work.se.BindLifetime.Duration, maxHandshakeLifetime))
defer timer.Stop()
// Limit the number of pings we will transmit. Inbound pings trigger
@@ -1054,7 +1054,7 @@ func (r *relayManager) allocateServerEndpoint(work *relayEndpointAllocWork) {
defer returnAfterTimer.Stop()
// While connections to DERP are over TCP, they can be lossy on the DERP
// server when data moves between the two independent streams. Also, the
- // peer relay server may not be "ready" (see [tailscale.com/net/udprelay.ErrServerNotReady]).
+ // peer relay server may not be "ready" (see [github.com/metacubex/tailscale/net/udprelay.ErrServerNotReady]).
// So, start a timer to retry once if needed.
retryAfterTimer := time.NewTimer(udprelay.ServerRetryAfter)
defer retryAfterTimer.Stop()
@@ -1135,3 +1135,10 @@ func (r *relayManager) allocateAllServersRunLoop(wlb endpointWithLastBest) {
go r.allocateServerEndpoint(started)
}
}
+
+func minDuration(a, b time.Duration) time.Duration {
+ if a < b {
+ return a
+ }
+ return b
+}
diff --git a/wgengine/magicsock/relaymanager_test.go b/wgengine/magicsock/relaymanager_test.go
index 47d935404b5fe..66953994fff3c 100644
--- a/wgengine/magicsock/relaymanager_test.go
+++ b/wgengine/magicsock/relaymanager_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,10 +8,10 @@ package magicsock
import (
"testing"
- "tailscale.com/disco"
- udprelay "tailscale.com/net/udprelay/endpoint"
- "tailscale.com/types/key"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/disco"
+ udprelay "github.com/metacubex/tailscale/net/udprelay/endpoint"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/util/set"
)
func TestRelayManagerInitAndIdle(t *testing.T) {
diff --git a/wgengine/mem_ios.go b/wgengine/mem_ios.go
index f278359a8809b..754fced35185c 100644
--- a/wgengine/mem_ios.go
+++ b/wgengine/mem_ios.go
@@ -4,7 +4,7 @@
package wgengine
import (
- "github.com/tailscale/wireguard-go/device"
+ "github.com/metacubex/tailscale-wireguard-go/device"
)
// iOS has a very restrictive memory limit on network extensions.
diff --git a/wgengine/netlog/netlog.go b/wgengine/netlog/netlog.go
index e03a520f29bce..ba010d064bd70 100644
--- a/wgengine/netlog/netlog.go
+++ b/wgengine/netlog/netlog.go
@@ -1,41 +1,41 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_netlog && !ts_omit_logtail
+//go:build !ts_omit_netlog && ts_enable_logtail
// Package netlog provides a logger that monitors a TUN device and
// periodically records any traffic into a log stream.
package netlog
import (
- "cmp"
"context"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"io"
"log"
"net/http"
"net/netip"
"time"
- "tailscale.com/health"
- "tailscale.com/logpolicy"
- "tailscale.com/logtail"
- "tailscale.com/net/netmon"
- "tailscale.com/net/sockstats"
- "tailscale.com/net/tsaddr"
- "tailscale.com/syncs"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/types/netlogfunc"
- "tailscale.com/types/netlogtype"
- "tailscale.com/types/netmap"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/set"
- "tailscale.com/wgengine/router"
-
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/logpolicy"
+ "github.com/metacubex/tailscale/logtail"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/sockstats"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/types/netlogfunc"
+ "github.com/metacubex/tailscale/types/netlogtype"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/wgengine/router"
+
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
)
// pollPeriod specifies how often to poll for network traffic.
@@ -413,19 +413,21 @@ func makeNodeMaps(nm *netmap.NetworkMap) (selfNode nodeUser, allNodes map[netip.
allNodes = make(map[netip.Addr]nodeUser)
if nm.SelfNode.Valid() {
selfNode = nodeUser{nm.SelfNode, nm.UserProfiles[nm.SelfNode.User()]}
- for _, addr := range nm.SelfNode.Addresses().All() {
+ nm.SelfNode.Addresses().All()(func(_ int, addr netip.Prefix) bool {
if addr.IsSingleIP() {
allNodes[addr.Addr()] = selfNode
}
- }
+ return true
+ })
}
for _, peer := range nm.Peers {
if peer.Valid() {
- for _, addr := range peer.Addresses().All() {
+ peer.Addresses().All()(func(_ int, addr netip.Prefix) bool {
if addr.IsSingleIP() {
allNodes[addr.Addr()] = nodeUser{peer, nm.UserProfiles[peer.User()]}
}
- }
+ return true
+ })
}
}
return selfNode, allNodes
diff --git a/wgengine/netlog/netlog_omit.go b/wgengine/netlog/netlog_omit.go
index 041a183769554..d4d8d003386e6 100644
--- a/wgengine/netlog/netlog_omit.go
+++ b/wgengine/netlog/netlog_omit.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build ts_omit_netlog || ts_omit_logtail
+//go:build ts_omit_netlog || !ts_enable_logtail
package netlog
diff --git a/wgengine/netlog/netlog_test.go b/wgengine/netlog/netlog_test.go
index cc6968547cdbf..84381c26580d4 100644
--- a/wgengine/netlog/netlog_test.go
+++ b/wgengine/netlog/netlog_test.go
@@ -1,28 +1,28 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_netlog && !ts_omit_logtail
-
package netlog
import (
"encoding/binary"
- "math/rand/v2"
+ "github.com/metacubex/tailscale/util/go120/randv2"
"net/netip"
"sync"
"testing"
"testing/synctest"
"time"
- jsonv2 "github.com/go-json-experiment/json"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/tailcfg"
- "tailscale.com/types/bools"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/netlogtype"
- "tailscale.com/types/netmap"
- "tailscale.com/wgengine/router"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/bools"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/netlogtype"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/wgengine/router"
)
func TestEmbedNodeInfo(t *testing.T) {
diff --git a/wgengine/netlog/record.go b/wgengine/netlog/record.go
index 62c3a6866da2a..0ca41aadc8947 100644
--- a/wgengine/netlog/record.go
+++ b/wgengine/netlog/record.go
@@ -1,22 +1,22 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_netlog && !ts_omit_logtail
+//go:build !ts_omit_netlog && ts_enable_logtail
package netlog
import (
- "cmp"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
"strings"
"time"
"unicode/utf8"
- "tailscale.com/tailcfg"
- "tailscale.com/types/bools"
- "tailscale.com/types/netlogtype"
- "tailscale.com/util/set"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/bools"
+ "github.com/metacubex/tailscale/types/netlogtype"
+ "github.com/metacubex/tailscale/util/set"
)
// maxLogSize is the maximum number of bytes for a log message.
@@ -130,8 +130,8 @@ func (r record) toMessage(excludeNodeInfo, anonymizeExitTraffic bool) netlogtype
func compareConnCnts(x, y netlogtype.ConnectionCounts) int {
return cmp.Or(
- netip.AddrPort.Compare(x.Src, y.Src),
- netip.AddrPort.Compare(x.Dst, y.Dst),
+ compareAddrPort(x.Src, y.Src),
+ compareAddrPort(x.Dst, y.Dst),
cmp.Compare(x.Proto, y.Proto))
}
@@ -147,18 +147,20 @@ func (nu nodeUser) jsonLen() (n int) {
}
if nu.Addresses().Len() > 0 {
n += len(`"addresses":[]`)
- for _, addr := range nu.Addresses().All() {
+ nu.Addresses().All()(func(_ int, addr netip.Prefix) bool {
n += bools.IfElse(addr.Addr().Is4(), len(`"255.255.255.255"`), len(`"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"`)) + len(",")
- }
+ return true
+ })
}
if nu.Hostinfo().Valid() && len(nu.Hostinfo().OS()) > 0 {
n += len(`"os":`) + jsonQuotedLen(nu.Hostinfo().OS()) + len(`,`)
}
if nu.Tags().Len() > 0 {
n += len(`"tags":[]`)
- for _, tag := range nu.Tags().All() {
+ nu.Tags().All()(func(_ int, tag string) bool {
n += jsonQuotedLen(tag) + len(",")
- }
+ return true
+ })
} else if nu.user.Valid() && nu.user.ID() == nu.User() && len(nu.user.LoginName()) > 0 {
n += len(`"user":`) + jsonQuotedLen(nu.user.LoginName()) + len(",")
}
@@ -175,14 +177,15 @@ func (nu nodeUser) toNode() netlogtype.Node {
Name: strings.TrimSuffix(nu.Name(), "."),
}
var ipv4, ipv6 netip.Addr
- for _, addr := range nu.Addresses().All() {
+ nu.Addresses().All()(func(_ int, addr netip.Prefix) bool {
switch {
case addr.IsSingleIP() && addr.Addr().Is4():
ipv4 = addr.Addr()
case addr.IsSingleIP() && addr.Addr().Is6():
ipv6 = addr.Addr()
}
- }
+ return true
+ })
n.Addresses = []netip.Addr{ipv4, ipv6}
n.Addresses = slices.DeleteFunc(n.Addresses, func(a netip.Addr) bool { return !a.IsValid() })
if nu.Hostinfo().Valid() {
@@ -216,3 +219,7 @@ func jsonQuotedLen(s string) int {
}
return n
}
+
+func compareAddrPort(a, b netip.AddrPort) int {
+ return cmp.Or(a.Addr().Compare(b.Addr()), cmp.Compare(a.Port(), b.Port()))
+}
diff --git a/wgengine/netlog/record_test.go b/wgengine/netlog/record_test.go
index 1edae7450c842..f54bb9951c7f0 100644
--- a/wgengine/netlog/record_test.go
+++ b/wgengine/netlog/record_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_netlog && !ts_omit_logtail
-
package netlog
import (
@@ -10,14 +10,14 @@ import (
"testing"
"time"
- jsonv2 "github.com/go-json-experiment/json"
- "github.com/go-json-experiment/json/jsontext"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
- "tailscale.com/tailcfg"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/netlogtype"
- "tailscale.com/util/must"
+ jsonv2 "github.com/metacubex/jsonv2"
+ "github.com/metacubex/jsonv2/jsontext"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/netlogtype"
+ "github.com/metacubex/tailscale/util/must"
)
func addr(s string) netip.Addr {
diff --git a/wgengine/netstack/gro/gro.go b/wgengine/netstack/gro/gro.go
index 152b252951c80..2a55401390112 100644
--- a/wgengine/netstack/gro/gro.go
+++ b/wgengine/netstack/gro/gro.go
@@ -9,14 +9,14 @@ package gro
import (
"bytes"
- "github.com/tailscale/wireguard-go/tun"
- "gvisor.dev/gvisor/pkg/buffer"
- "gvisor.dev/gvisor/pkg/tcpip"
- "gvisor.dev/gvisor/pkg/tcpip/header"
- "gvisor.dev/gvisor/pkg/tcpip/header/parse"
- "gvisor.dev/gvisor/pkg/tcpip/stack"
- "tailscale.com/net/packet"
- "tailscale.com/types/ipproto"
+ "github.com/metacubex/gvisor/pkg/buffer"
+ "github.com/metacubex/gvisor/pkg/tcpip"
+ "github.com/metacubex/gvisor/pkg/tcpip/checksum"
+ "github.com/metacubex/gvisor/pkg/tcpip/header"
+ "github.com/metacubex/gvisor/pkg/tcpip/header/parse"
+ "github.com/metacubex/gvisor/pkg/tcpip/stack"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/types/ipproto"
)
// RXChecksumOffload validates IPv4, TCP, and UDP header checksums in p,
@@ -42,7 +42,7 @@ func RXChecksumOffload(p *packet.Parsed) *stack.PacketBuffer {
if csumStart < header.IPv4MinimumSize || csumStart > header.IPv4MaximumHeaderSize || len(buf) < csumStart {
return nil
}
- if ^tun.Checksum(buf[:csumStart], 0) != 0 {
+ if ^checksum.Checksum(buf[:csumStart], 0) != 0 {
return nil
}
pn = header.IPv4ProtocolNumber
@@ -82,12 +82,8 @@ func RXChecksumOffload(p *packet.Parsed) *stack.PacketBuffer {
if p.IPProto == ipproto.TCP || p.IPProto == ipproto.UDP {
lenForPseudo := len(buf) - csumStart
- csum := tun.PseudoHeaderChecksum(
- uint8(p.IPProto),
- p.Src.Addr().AsSlice(),
- p.Dst.Addr().AsSlice(),
- uint16(lenForPseudo))
- csum = tun.Checksum(buf[csumStart:], csum)
+ csum := header.PseudoHeaderChecksum(tcpip.TransportProtocolNumber(p.IPProto), tcpip.AddrFromSlice(p.Src.Addr().AsSlice()), tcpip.AddrFromSlice(p.Dst.Addr().AsSlice()), uint16(lenForPseudo))
+ csum = checksum.Checksum(buf[csumStart:], csum)
if ^csum != 0 {
return nil
}
diff --git a/wgengine/netstack/gro/gro_default.go b/wgengine/netstack/gro/gro_default.go
index ac9d672ab8a6e..54612ee484edb 100644
--- a/wgengine/netstack/gro/gro_default.go
+++ b/wgengine/netstack/gro/gro_default.go
@@ -8,9 +8,9 @@ package gro
import (
"sync"
- "gvisor.dev/gvisor/pkg/tcpip/stack"
- nsgro "gvisor.dev/gvisor/pkg/tcpip/stack/gro"
- "tailscale.com/net/packet"
+ "github.com/metacubex/gvisor/pkg/tcpip/stack"
+ nsgro "github.com/metacubex/gvisor/pkg/tcpip/stack/gro"
+ "github.com/metacubex/tailscale/net/packet"
)
var (
diff --git a/wgengine/netstack/gro/gro_disabled.go b/wgengine/netstack/gro/gro_disabled.go
index 9b2ae69955c97..d5cefb50d0018 100644
--- a/wgengine/netstack/gro/gro_disabled.go
+++ b/wgengine/netstack/gro/gro_disabled.go
@@ -8,7 +8,7 @@ package gro
import (
"runtime"
- "tailscale.com/net/packet"
+ "github.com/metacubex/tailscale/net/packet"
)
type GRO struct{}
diff --git a/wgengine/netstack/gro/gro_test.go b/wgengine/netstack/gro/gro_test.go
index 49171b78c97aa..5132f77f5361b 100644
--- a/wgengine/netstack/gro/gro_test.go
+++ b/wgengine/netstack/gro/gro_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,9 +10,9 @@ import (
"net/netip"
"testing"
- "gvisor.dev/gvisor/pkg/tcpip"
- "gvisor.dev/gvisor/pkg/tcpip/header"
- "tailscale.com/net/packet"
+ "github.com/metacubex/gvisor/pkg/tcpip"
+ "github.com/metacubex/gvisor/pkg/tcpip/header"
+ "github.com/metacubex/tailscale/net/packet"
)
func Test_RXChecksumOffload(t *testing.T) {
diff --git a/wgengine/netstack/link_endpoint.go b/wgengine/netstack/link_endpoint.go
index 82b5446ac8789..02c8ae63db6ae 100644
--- a/wgengine/netstack/link_endpoint.go
+++ b/wgengine/netstack/link_endpoint.go
@@ -7,14 +7,14 @@ import (
"context"
"sync"
- "gvisor.dev/gvisor/pkg/buffer"
- "gvisor.dev/gvisor/pkg/tcpip"
- "gvisor.dev/gvisor/pkg/tcpip/header"
- "gvisor.dev/gvisor/pkg/tcpip/stack"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/net/packet"
- "tailscale.com/types/ipproto"
- "tailscale.com/wgengine/netstack/gro"
+ "github.com/metacubex/gvisor/pkg/buffer"
+ "github.com/metacubex/gvisor/pkg/tcpip"
+ "github.com/metacubex/gvisor/pkg/tcpip/header"
+ "github.com/metacubex/gvisor/pkg/tcpip/stack"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/wgengine/netstack/gro"
)
type queue struct {
diff --git a/wgengine/netstack/netstack.go b/wgengine/netstack/netstack.go
index 659e079246171..699ff6f668af5 100644
--- a/wgengine/netstack/netstack.go
+++ b/wgengine/netstack/netstack.go
@@ -20,45 +20,45 @@ import (
"sync/atomic"
"time"
- "github.com/tailscale/wireguard-go/conn"
- "gvisor.dev/gvisor/pkg/refs"
- "gvisor.dev/gvisor/pkg/tcpip"
- "gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
- "gvisor.dev/gvisor/pkg/tcpip/header"
- "gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
- "gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
- "gvisor.dev/gvisor/pkg/tcpip/stack"
- "gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
- "gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
- "gvisor.dev/gvisor/pkg/tcpip/transport/udp"
- "gvisor.dev/gvisor/pkg/waiter"
- "tailscale.com/envknob"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/metrics"
- "tailscale.com/net/dns"
- "tailscale.com/net/ipset"
- "tailscale.com/net/netaddr"
- "tailscale.com/net/netx"
- "tailscale.com/net/packet"
- "tailscale.com/net/tsaddr"
- "tailscale.com/net/tsdial"
- "tailscale.com/net/tstun"
- "tailscale.com/proxymap"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/types/nettype"
- "tailscale.com/types/views"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/set"
- "tailscale.com/version"
- "tailscale.com/wgengine"
- "tailscale.com/wgengine/filter"
- "tailscale.com/wgengine/magicsock"
- "tailscale.com/wgengine/netstack/gro"
+ "github.com/metacubex/gvisor/pkg/refs"
+ "github.com/metacubex/gvisor/pkg/tcpip"
+ "github.com/metacubex/gvisor/pkg/tcpip/adapters/gonet"
+ "github.com/metacubex/gvisor/pkg/tcpip/header"
+ "github.com/metacubex/gvisor/pkg/tcpip/network/ipv4"
+ "github.com/metacubex/gvisor/pkg/tcpip/network/ipv6"
+ "github.com/metacubex/gvisor/pkg/tcpip/stack"
+ "github.com/metacubex/gvisor/pkg/tcpip/transport/icmp"
+ "github.com/metacubex/gvisor/pkg/tcpip/transport/tcp"
+ "github.com/metacubex/gvisor/pkg/tcpip/transport/udp"
+ "github.com/metacubex/gvisor/pkg/waiter"
+ "github.com/metacubex/tailscale-wireguard-go/conn"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/metrics"
+ "github.com/metacubex/tailscale/net/dns"
+ "github.com/metacubex/tailscale/net/ipset"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/proxymap"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/nettype"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/version"
+ "github.com/metacubex/tailscale/wgengine"
+ "github.com/metacubex/tailscale/wgengine/filter"
+ "github.com/metacubex/tailscale/wgengine/magicsock"
+ "github.com/metacubex/tailscale/wgengine/netstack/gro"
)
const debugPackets = false
@@ -473,14 +473,15 @@ func init() {
// endpoint, and name collisions will result in Prometheus scraping errors.
clientmetric.NewCounterFunc("netstack_tcp_forward_dropped_attempts", func() int64 {
var total uint64
- for ns := range stacksForMetrics.Keys() {
+ stacksForMetrics.Keys()(func(ns *Impl) bool {
delta := ns.ipstack.Stats().TCP.ForwardMaxInFlightDrop.Value()
if total+delta > math.MaxInt64 {
total = math.MaxInt64
- break
+ return false
}
total += delta
- }
+ return true
+ })
return int64(total)
})
}
@@ -646,9 +647,11 @@ func (ns *Impl) Start(b LocalBackend) error {
udpFwd := udp.NewForwarder(ns.ipstack, ns.acceptUDPNoICMP)
ns.ipstack.SetTransportProtocolHandler(tcp.ProtocolNumber, ns.wrapTCPProtocolHandler(tcpFwd.HandlePacket))
ns.ipstack.SetTransportProtocolHandler(udp.ProtocolNumber, ns.wrapUDPProtocolHandler(udpFwd.HandlePacket))
- ns.injectWG.Go(func() {
+ ns.injectWG.Add(1)
+ go func() {
+ defer ns.injectWG.Done()
ns.inject()
- })
+ }()
if ns.ready.Swap(true) {
panic("already started")
}
@@ -737,13 +740,15 @@ func (ns *Impl) UpdateNetstackIPs(nm *netmap.NetworkMap) {
newPfx := make(map[netip.Prefix]bool)
if selfNode.Valid() {
- for _, p := range selfNode.Addresses().All() {
+ selfNode.Addresses().All()(func(_ int, p netip.Prefix) bool {
newPfx[p] = true
- }
+ return true
+ })
if ns.ProcessSubnets {
- for _, p := range selfNode.AllowedIPs().All() {
+ selfNode.AllowedIPs().All()(func(_ int, p netip.Prefix) bool {
newPfx[p] = true
- }
+ return true
+ })
}
}
@@ -822,9 +827,10 @@ func (ns *Impl) UpdateActiveVIPServices(activeServices views.Slice[string]) {
ns.mu.Lock()
defer ns.mu.Unlock()
activeServicesSet := make(set.Set[tailcfg.ServiceName], activeServices.Len())
- for _, s := range activeServices.All() {
+ activeServices.All()(func(_ int, s string) bool {
activeServicesSet.Add(tailcfg.AsServiceName(s))
- }
+ return true
+ })
ns.atomicActiveVIPServices.Store(activeServicesSet)
}
@@ -1732,8 +1738,7 @@ func (ns *Impl) forwardTCP(getClient func(...tcpip.SettableSocketOption) *gonet.
if ns.forwardDialFunc != nil {
dialFunc = ns.forwardDialFunc
} else {
- var stdDialer net.Dialer
- dialFunc = stdDialer.DialContext
+ dialFunc = ns.dialer.SystemDial
}
// TODO: this is racy, dialing before we register our local address. See
@@ -1805,7 +1810,7 @@ func (ns *Impl) forwardTCP(getClient func(...tcpip.SettableSocketOption) *gonet.
}
}()
// Wait for both ends of the connection to close.
- for range 2 {
+ for i := 0; i < 2; i++ {
err = <-connClosed
if err != nil {
ns.logf("proxy connection closed with error: %v", err)
@@ -2020,47 +2025,47 @@ func (ns *Impl) forwardUDP(client *gonet.UDPConn, clientAddr, dstAddr netip.Addr
ns.logf("[v2] netstack: forwarding incoming UDP connection on port %v", port)
}
- var backendListenAddr *net.UDPAddr
- var backendRemoteAddr *net.UDPAddr
+ var backendListenAddr netip.AddrPort
+ var backendRemoteAddr netip.AddrPort
isLocal := ns.isLocalIP(dstAddr.Addr())
isLoopback := dstAddr.Addr() == ipv4Loopback || dstAddr.Addr() == ipv6Loopback
if isLocal {
- backendRemoteAddr = &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: int(port)}
- backendListenAddr = &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: int(srcPort)}
+ backendRemoteAddr = netip.AddrPortFrom(netip.MustParseAddr("127.0.0.1"), port)
+ backendListenAddr = netip.AddrPortFrom(netip.MustParseAddr("127.0.0.1"), srcPort)
} else if isLoopback {
- ip := net.IP(ipv4Loopback.AsSlice())
+ ip := ipv4Loopback
if dstAddr.Addr() == ipv6Loopback {
- ip = ipv6Loopback.AsSlice()
+ ip = ipv6Loopback
}
- backendRemoteAddr = &net.UDPAddr{IP: ip, Port: int(port)}
- backendListenAddr = &net.UDPAddr{IP: ip, Port: int(srcPort)}
+ backendRemoteAddr = netip.AddrPortFrom(ip, port)
+ backendListenAddr = netip.AddrPortFrom(ip, srcPort)
} else {
if dstIP := dstAddr.Addr(); viaRange.Contains(dstIP) {
dstAddr = netip.AddrPortFrom(tsaddr.UnmapVia(dstIP), dstAddr.Port())
}
- backendRemoteAddr = net.UDPAddrFromAddrPort(dstAddr)
+ backendRemoteAddr = dstAddr
if dstAddr.Addr().Is4() {
- backendListenAddr = &net.UDPAddr{IP: net.ParseIP("0.0.0.0"), Port: int(srcPort)}
+ backendListenAddr = netip.AddrPortFrom(netip.IPv4Unspecified(), srcPort)
} else {
- backendListenAddr = &net.UDPAddr{IP: net.ParseIP("::"), Port: int(srcPort)}
+ backendListenAddr = netip.AddrPortFrom(netip.IPv4Unspecified(), srcPort)
}
}
- backendConn, err := net.ListenUDP("udp", backendListenAddr)
+ backendConn, err := ns.dialer.SystemPacketListen(context.Background(), "udp", backendListenAddr.String())
if err != nil {
ns.logf("netstack: could not bind local port %v: %v, trying again with random port", backendListenAddr.Port, err)
- backendListenAddr.Port = 0
- backendConn, err = net.ListenUDP("udp", backendListenAddr)
+ backendListenAddr = netip.AddrPortFrom(backendListenAddr.Addr(), 0)
+ backendConn, err = ns.dialer.SystemPacketListen(context.Background(), "udp", backendListenAddr.String())
if err != nil {
ns.logf("netstack: could not create UDP socket, preventing forwarding to %v: %v", dstAddr, err)
return
}
}
- backendLocalAddr := backendConn.LocalAddr().(*net.UDPAddr)
+ backendLocalIPPort := netaddr.FromStdNetAddr(backendConn.LocalAddr())
+ backendLocalIPPort = netaddr.Unmap(backendLocalIPPort)
- backendLocalIPPort := netip.AddrPortFrom(backendListenAddr.AddrPort().Addr().Unmap().WithZone(backendLocalAddr.Zone), backendLocalAddr.AddrPort().Port())
if !backendLocalIPPort.IsValid() {
- ns.logf("could not get backend local IP:port from %v:%v", backendLocalAddr.IP, backendLocalAddr.Port)
+ ns.logf("could not get backend local IP:port from %v:%v", backendLocalIPPort.Addr(), backendLocalIPPort.Port())
}
if isLocal {
if err := ns.pm.RegisterIPPortIdentity("udp", backendLocalIPPort, clientAddr.Addr()); err != nil {
@@ -2093,7 +2098,7 @@ func (ns *Impl) forwardUDP(client *gonet.UDPConn, clientAddr, dstAddr netip.Addr
timer.Reset(idleTimeout)
}
startPacketCopy(ctx, cancel, client, net.UDPAddrFromAddrPort(clientAddr), backendConn, ns.logf, extend)
- startPacketCopy(ctx, cancel, backendConn, backendRemoteAddr, client, ns.logf, extend)
+ startPacketCopy(ctx, cancel, backendConn, net.UDPAddrFromAddrPort(backendRemoteAddr), client, ns.logf, extend)
if isLocal {
// Wait for the copies to be done before decrementing the
// subnet address count to potentially remove the route.
diff --git a/wgengine/netstack/netstack_tcpbuf_default.go b/wgengine/netstack/netstack_tcpbuf_default.go
index ed93175c4fed1..d92435328d131 100644
--- a/wgengine/netstack/netstack_tcpbuf_default.go
+++ b/wgengine/netstack/netstack_tcpbuf_default.go
@@ -6,7 +6,7 @@
package netstack
import (
- "gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
+ "github.com/metacubex/gvisor/pkg/tcpip/transport/tcp"
)
const (
diff --git a/wgengine/netstack/netstack_tcpbuf_ios.go b/wgengine/netstack/netstack_tcpbuf_ios.go
index a5368da8633d7..2687927f1f2bc 100644
--- a/wgengine/netstack/netstack_tcpbuf_ios.go
+++ b/wgengine/netstack/netstack_tcpbuf_ios.go
@@ -6,7 +6,7 @@
package netstack
import (
- "gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
+ "github.com/metacubex/gvisor/pkg/tcpip/transport/tcp"
)
const (
diff --git a/wgengine/netstack/netstack_test.go b/wgengine/netstack/netstack_test.go
index 7f248cd44faae..db841a7fce55b 100644
--- a/wgengine/netstack/netstack_test.go
+++ b/wgengine/netstack/netstack_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,36 +8,36 @@ package netstack
import (
"context"
"fmt"
- "maps"
+ maps "github.com/metacubex/tailscale/util/go120/maps"
"net"
"net/netip"
"runtime"
"testing"
"time"
- "gvisor.dev/gvisor/pkg/buffer"
- "gvisor.dev/gvisor/pkg/tcpip"
- "gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
- "gvisor.dev/gvisor/pkg/tcpip/header"
- "gvisor.dev/gvisor/pkg/tcpip/stack"
- "tailscale.com/envknob"
- "tailscale.com/ipn"
- "tailscale.com/ipn/ipnlocal"
- "tailscale.com/ipn/store/mem"
- "tailscale.com/metrics"
- "tailscale.com/net/netx"
- "tailscale.com/net/packet"
- "tailscale.com/net/tsaddr"
- "tailscale.com/net/tsdial"
- "tailscale.com/net/tstun"
- "tailscale.com/tsd"
- "tailscale.com/tstest"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/logid"
- "tailscale.com/types/netmap"
- "tailscale.com/util/clientmetric"
- "tailscale.com/wgengine"
- "tailscale.com/wgengine/filter"
+ "github.com/metacubex/gvisor/pkg/buffer"
+ "github.com/metacubex/gvisor/pkg/tcpip"
+ "github.com/metacubex/gvisor/pkg/tcpip/adapters/gonet"
+ "github.com/metacubex/gvisor/pkg/tcpip/header"
+ "github.com/metacubex/gvisor/pkg/tcpip/stack"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/ipn"
+ "github.com/metacubex/tailscale/ipn/ipnlocal"
+ "github.com/metacubex/tailscale/ipn/store/mem"
+ "github.com/metacubex/tailscale/metrics"
+ "github.com/metacubex/tailscale/net/netx"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/wgengine"
+ "github.com/metacubex/tailscale/wgengine/filter"
)
// TestInjectInboundLeak tests that injectInbound doesn't leak memory.
diff --git a/wgengine/netstack/netstack_userping.go b/wgengine/netstack/netstack_userping.go
index d42c8fbe7c271..be57be7952316 100644
--- a/wgengine/netstack/netstack_userping.go
+++ b/wgengine/netstack/netstack_userping.go
@@ -13,8 +13,8 @@ import (
"runtime"
"time"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/version/distro"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/version/distro"
)
// setAmbientCapsRaw is non-nil on Linux for Synology, to run ping with
diff --git a/wgengine/netstack/netstack_userping_apple.go b/wgengine/netstack/netstack_userping_apple.go
index cb6926f0a9a4b..8e285e45b38ed 100644
--- a/wgengine/netstack/netstack_userping_apple.go
+++ b/wgengine/netstack/netstack_userping_apple.go
@@ -11,7 +11,7 @@ import (
"net/netip"
"time"
- "tailscale.com/net/ping"
+ "github.com/metacubex/tailscale/net/ping"
)
// sendOutboundUserPing sends a non-privileged ICMP (or ICMPv6) ping to dstIP with the given timeout.
diff --git a/wgengine/netstack/netstack_userping_test.go b/wgengine/netstack/netstack_userping_test.go
index cba298d453698..4730247d86269 100644
--- a/wgengine/netstack/netstack_userping_test.go
+++ b/wgengine/netstack/netstack_userping_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/wgengine/pendopen.go b/wgengine/pendopen.go
index e816506def871..0d5eb5f16df6e 100644
--- a/wgengine/pendopen.go
+++ b/wgengine/pendopen.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !ts_omit_debug
+//go:build ts_enable_debug
package wgengine
@@ -10,16 +10,16 @@ import (
"net/netip"
"runtime"
"strings"
- "sync"
"time"
- "github.com/gaissmai/bart"
- "tailscale.com/net/flowtrack"
- "tailscale.com/net/packet"
- "tailscale.com/net/tstun"
- "tailscale.com/types/ipproto"
- "tailscale.com/util/mak"
- "tailscale.com/wgengine/filter"
+ "github.com/metacubex/bart"
+ "github.com/metacubex/tailscale/net/flowtrack"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/wgengine/filter"
)
type flowtrackTuple = flowtrack.Tuple
@@ -99,10 +99,10 @@ func (e *userspaceEngine) trackOpenPreFilterIn(pp *packet.Parsed, t *tstun.Wrapp
var (
appleIPRange = netip.MustParsePrefix("17.0.0.0/8")
- canonicalIPs = sync.OnceValue(func() (checkIPFunc func(netip.Addr) bool) {
+ canonicalIPs = syncs.OnceValue(func() (checkIPFunc func(netip.Addr) bool) {
// https://bgp.he.net/AS41231#_prefixes
t := &bart.Lite{}
- for s := range strings.FieldsSeq(`
+ for _, s := range strings.Fields(`
91.189.89.0/24
91.189.91.0/24
91.189.92.0/24
@@ -212,12 +212,13 @@ func (e *userspaceEngine) onOpenTimeout(flow flowtrack.Tuple) {
ps, found := e.getPeerStatusLite(n.Key())
if !found {
onlyZeroRoute := true // whether peerForIP returned n only because its /0 route matched
- for _, r := range n.AllowedIPs().All() {
+ n.AllowedIPs().All()(func(_ int, r netip.Prefix) bool {
if r.Bits() != 0 && r.Contains(flow.DstAddr()) {
onlyZeroRoute = false
- break
+ return false
}
- }
+ return true
+ })
if onlyZeroRoute {
// This node was returned by peerForIP because
// its exit node /0 route(s) matched, but this
diff --git a/wgengine/pendopen_omit.go b/wgengine/pendopen_omit.go
index 01d33306b291e..9f47ec0b3a477 100644
--- a/wgengine/pendopen_omit.go
+++ b/wgengine/pendopen_omit.go
@@ -1,14 +1,14 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build ts_omit_debug
+//go:build !ts_enable_debug
package wgengine
import (
- "tailscale.com/net/packet"
- "tailscale.com/net/tstun"
- "tailscale.com/wgengine/filter"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/wgengine/filter"
)
type flowtrackTuple = struct{}
diff --git a/wgengine/router/callback.go b/wgengine/router/callback.go
index 11ce832f4f5e4..1a16d793faaf9 100644
--- a/wgengine/router/callback.go
+++ b/wgengine/router/callback.go
@@ -6,7 +6,7 @@ package router
import (
"sync"
- "tailscale.com/net/dns"
+ "github.com/metacubex/tailscale/net/dns"
)
// CallbackRouter is an implementation of both Router and dns.OSConfigurator.
diff --git a/wgengine/router/consolidating_router.go b/wgengine/router/consolidating_router.go
index 14283330b124c..589846d3b44b6 100644
--- a/wgengine/router/consolidating_router.go
+++ b/wgengine/router/consolidating_router.go
@@ -4,8 +4,8 @@
package router
import (
+ "github.com/metacubex/tailscale/types/logger"
"go4.org/netipx"
- "tailscale.com/types/logger"
)
// ConsolidatingRoutes wraps a Router with logic that consolidates Routes
diff --git a/wgengine/router/consolidating_router_test.go b/wgengine/router/consolidating_router_test.go
index 1bf79a29d614d..fe665cab7716c 100644
--- a/wgengine/router/consolidating_router_test.go
+++ b/wgengine/router/consolidating_router_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/wgengine/router/osrouter/ifconfig_windows.go b/wgengine/router/osrouter/ifconfig_windows.go
index cb87ad5f24114..933c0bf0fbc0e 100644
--- a/wgengine/router/osrouter/ifconfig_windows.go
+++ b/wgengine/router/osrouter/ifconfig_windows.go
@@ -8,24 +8,24 @@ package osrouter
import (
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"log"
"net/netip"
- "slices"
"sort"
"time"
- "tailscale.com/health"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsaddr"
- "tailscale.com/net/tstun"
- "tailscale.com/wgengine/router"
- "tailscale.com/wgengine/winnet"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/wgengine/router"
+ "github.com/metacubex/tailscale/wgengine/winnet"
ole "github.com/go-ole/go-ole"
- "github.com/tailscale/wireguard-go/tun"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/util/winipcfg"
"go4.org/netipx"
"golang.org/x/sys/windows"
- "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
)
// monitorDefaultRoutes subscribes to route change events and updates
diff --git a/wgengine/router/osrouter/ifconfig_windows_test.go b/wgengine/router/osrouter/ifconfig_windows_test.go
index f272a59f899f6..bfd90f029da1a 100644
--- a/wgengine/router/osrouter/ifconfig_windows_test.go
+++ b/wgengine/router/osrouter/ifconfig_windows_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,7 +13,7 @@ import (
"strings"
"testing"
- "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
+ "github.com/metacubex/tailscale/util/winipcfg"
)
func randIP() netip.Addr {
diff --git a/wgengine/router/osrouter/osrouter.go b/wgengine/router/osrouter/osrouter.go
index ac4e48c7268c7..a22538fb1f70d 100644
--- a/wgengine/router/osrouter/osrouter.go
+++ b/wgengine/router/osrouter/osrouter.go
@@ -7,7 +7,7 @@
// package.
package osrouter
-import "tailscale.com/wgengine/router"
+import "github.com/metacubex/tailscale/wgengine/router"
// shutdownConfig is a routing configuration that removes all router
// state from the OS. It's the config used when callers pass in a nil
diff --git a/wgengine/router/osrouter/osrouter_test.go b/wgengine/router/osrouter/osrouter_test.go
index 5e81d6297d035..1499f20532872 100644
--- a/wgengine/router/osrouter/osrouter_test.go
+++ b/wgengine/router/osrouter/osrouter_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/wgengine/router/osrouter/router_freebsd.go b/wgengine/router/osrouter/router_freebsd.go
index c1e1a389b8537..f006af605656d 100644
--- a/wgengine/router/osrouter/router_freebsd.go
+++ b/wgengine/router/osrouter/router_freebsd.go
@@ -4,9 +4,9 @@
package osrouter
import (
- "tailscale.com/net/netmon"
- "tailscale.com/types/logger"
- "tailscale.com/wgengine/router"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/wgengine/router"
)
func init() {
diff --git a/wgengine/router/osrouter/router_linux.go b/wgengine/router/osrouter/router_linux.go
index 41a2a7b90741e..5f901e9342a8a 100644
--- a/wgengine/router/osrouter/router_linux.go
+++ b/wgengine/router/osrouter/router_linux.go
@@ -19,22 +19,22 @@ import (
"syscall"
"time"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/tsconst"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/types/preftype"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/linuxfw"
+ "github.com/metacubex/tailscale/version/distro"
+ "github.com/metacubex/tailscale/wgengine/router"
"github.com/tailscale/netlink"
- "github.com/tailscale/wireguard-go/tun"
"go4.org/netipx"
"golang.org/x/sys/unix"
"golang.org/x/time/rate"
- "tailscale.com/envknob"
- "tailscale.com/health"
- "tailscale.com/net/netmon"
- "tailscale.com/tsconst"
- "tailscale.com/types/logger"
- "tailscale.com/types/opt"
- "tailscale.com/types/preftype"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/linuxfw"
- "tailscale.com/version/distro"
- "tailscale.com/wgengine/router"
)
func init() {
@@ -578,7 +578,7 @@ var dockerStatefulFilteringWarnable = health.Register(&health.Warnable{
Code: "docker-stateful-filtering",
Title: "Docker with stateful filtering",
Severity: health.SeverityMedium,
- Text: health.StaticMessage("Stateful filtering is enabled and Docker was detected; this may prevent Docker containers on this host from resolving DNS and connecting to Tailscale nodes. See https://tailscale.com/s/stateful-docker"),
+ Text: health.StaticMessage("Stateful filtering is enabled and Docker was detected; this may prevent Docker containers on this host from resolving DNS and connecting to Tailscale nodes. See https://github.com/metacubex/tailscale/s/stateful-docker"),
})
func (r *linuxRouter) updateStatefulFilteringWithDockerWarning(cfg *router.Config) {
diff --git a/wgengine/router/osrouter/router_linux_test.go b/wgengine/router/osrouter/router_linux_test.go
index 8830822e06346..96c21289cb0e2 100644
--- a/wgengine/router/osrouter/router_linux_test.go
+++ b/wgengine/router/osrouter/router_linux_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,12 +8,12 @@ package osrouter
import (
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"math/rand"
"net/netip"
"os"
"reflect"
"regexp"
- "slices"
"sort"
"strings"
"sync"
@@ -19,20 +21,20 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/tsconst"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/linuxfw"
+ "github.com/metacubex/tailscale/version/distro"
+ "github.com/metacubex/tailscale/wgengine/router"
"github.com/tailscale/netlink"
- "github.com/tailscale/wireguard-go/tun"
"go4.org/netipx"
- "tailscale.com/health"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsaddr"
- "tailscale.com/tsconst"
- "tailscale.com/tstest"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/linuxfw"
- "tailscale.com/version/distro"
- "tailscale.com/wgengine/router"
)
type Config = router.Config
diff --git a/wgengine/router/osrouter/router_openbsd.go b/wgengine/router/osrouter/router_openbsd.go
index 1c7eed52e2e76..491e4610bbf6b 100644
--- a/wgengine/router/osrouter/router_openbsd.go
+++ b/wgengine/router/osrouter/router_openbsd.go
@@ -10,15 +10,15 @@ import (
"net/netip"
"os/exec"
- "github.com/tailscale/wireguard-go/tun"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/netns"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/wgengine/router"
"go4.org/netipx"
- "tailscale.com/health"
- "tailscale.com/net/netmon"
- "tailscale.com/net/netns"
- "tailscale.com/types/logger"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/set"
- "tailscale.com/wgengine/router"
)
func init() {
diff --git a/wgengine/router/osrouter/router_plan9.go b/wgengine/router/osrouter/router_plan9.go
index 1436ee8a2191a..6e92a71e29a40 100644
--- a/wgengine/router/osrouter/router_plan9.go
+++ b/wgengine/router/osrouter/router_plan9.go
@@ -11,11 +11,11 @@ import (
"os"
"strings"
- "github.com/tailscale/wireguard-go/tun"
- "tailscale.com/health"
- "tailscale.com/net/netmon"
- "tailscale.com/types/logger"
- "tailscale.com/wgengine/router"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/wgengine/router"
)
func init() {
diff --git a/wgengine/router/osrouter/router_userspace_bsd.go b/wgengine/router/osrouter/router_userspace_bsd.go
index 272594d7c427b..535912f912f56 100644
--- a/wgengine/router/osrouter/router_userspace_bsd.go
+++ b/wgengine/router/osrouter/router_userspace_bsd.go
@@ -12,14 +12,14 @@ import (
"os/exec"
"runtime"
- "github.com/tailscale/wireguard-go/tun"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/version"
+ "github.com/metacubex/tailscale/wgengine/router"
"go4.org/netipx"
- "tailscale.com/health"
- "tailscale.com/net/netmon"
- "tailscale.com/net/tsaddr"
- "tailscale.com/types/logger"
- "tailscale.com/version"
- "tailscale.com/wgengine/router"
)
func init() {
diff --git a/wgengine/router/osrouter/router_windows.go b/wgengine/router/osrouter/router_windows.go
index ef9eb04a147a7..6669bfcf48aff 100644
--- a/wgengine/router/osrouter/router_windows.go
+++ b/wgengine/router/osrouter/router_windows.go
@@ -8,27 +8,27 @@ import (
"context"
"encoding/json"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"net/netip"
"os"
"os/exec"
"path/filepath"
- "slices"
"strings"
"sync"
"syscall"
"time"
- "github.com/tailscale/wireguard-go/tun"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/dns"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/util/backoff"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/winipcfg"
+ "github.com/metacubex/tailscale/wgengine/router"
"golang.org/x/sys/windows"
- "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
- "tailscale.com/health"
- "tailscale.com/net/dns"
- "tailscale.com/net/netmon"
- "tailscale.com/types/logger"
- "tailscale.com/util/backoff"
- "tailscale.com/util/eventbus"
- "tailscale.com/wgengine/router"
)
func init() {
diff --git a/wgengine/router/osrouter/router_windows_test.go b/wgengine/router/osrouter/router_windows_test.go
index abbbdf93b1fcb..fb3e0aaf645ca 100644
--- a/wgengine/router/osrouter/router_windows_test.go
+++ b/wgengine/router/osrouter/router_windows_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/wgengine/router/osrouter/runner.go b/wgengine/router/osrouter/runner.go
index 82b2680e67277..06930fdb960ef 100644
--- a/wgengine/router/osrouter/runner.go
+++ b/wgengine/router/osrouter/runner.go
@@ -8,9 +8,9 @@ package osrouter
import (
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"os"
"os/exec"
- "slices"
"strconv"
"strings"
"syscall"
diff --git a/wgengine/router/router.go b/wgengine/router/router.go
index f8d702d470527..f673bf4e04887 100644
--- a/wgengine/router/router.go
+++ b/wgengine/router/router.go
@@ -8,19 +8,19 @@ package router
import (
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
"reflect"
"runtime"
- "slices"
-
- "github.com/tailscale/wireguard-go/tun"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/health"
- "tailscale.com/net/netmon"
- "tailscale.com/types/logger"
- "tailscale.com/types/preftype"
- "tailscale.com/util/eventbus"
+
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/preftype"
+ "github.com/metacubex/tailscale/util/eventbus"
)
// Router is responsible for managing the system network stack.
diff --git a/wgengine/router/router_fake.go b/wgengine/router/router_fake.go
index 6b3bc044aea6d..989c76232b59b 100644
--- a/wgengine/router/router_fake.go
+++ b/wgengine/router/router_fake.go
@@ -4,7 +4,7 @@
package router
import (
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale/types/logger"
)
// NewFake returns a Router that does nothing when called and always
diff --git a/wgengine/router/router_test.go b/wgengine/router/router_test.go
index e6b41558622fe..fd2bd8f8f9504 100644
--- a/wgengine/router/router_test.go
+++ b/wgengine/router/router_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -8,7 +10,7 @@ import (
"reflect"
"testing"
- "tailscale.com/types/preftype"
+ "github.com/metacubex/tailscale/types/preftype"
)
func TestConfigEqual(t *testing.T) {
diff --git a/wgengine/userspace.go b/wgengine/userspace.go
index 23edf30b379de..58d9c315c741e 100644
--- a/wgengine/userspace.go
+++ b/wgengine/userspace.go
@@ -9,63 +9,64 @@ import (
"crypto/x509"
"errors"
"fmt"
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"io"
"math"
"net/netip"
"runtime"
- "slices"
"sync"
"sync/atomic"
"time"
- "github.com/gaissmai/bart"
- "github.com/tailscale/wireguard-go/device"
- "github.com/tailscale/wireguard-go/tun"
- "tailscale.com/control/controlknobs"
- "tailscale.com/drive"
- "tailscale.com/envknob"
- "tailscale.com/feature"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/health"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/net/dns"
- "tailscale.com/net/dns/resolver"
- "tailscale.com/net/ipset"
- "tailscale.com/net/netmon"
- "tailscale.com/net/packet"
- "tailscale.com/net/sockstats"
- "tailscale.com/net/tsaddr"
- "tailscale.com/net/tsdial"
- "tailscale.com/net/tstun"
- "tailscale.com/syncs"
- "tailscale.com/tailcfg"
- "tailscale.com/tstime/mono"
- "tailscale.com/types/dnstype"
- "tailscale.com/types/events"
- "tailscale.com/types/ipproto"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/netmap"
- "tailscale.com/types/views"
- "tailscale.com/util/backoff"
- "tailscale.com/util/checkchange"
- "tailscale.com/util/clientmetric"
- "tailscale.com/util/eventbus"
- "tailscale.com/util/execqueue"
- "tailscale.com/util/mak"
- "tailscale.com/util/set"
- "tailscale.com/util/singleflight"
- "tailscale.com/util/testenv"
- "tailscale.com/util/usermetric"
- "tailscale.com/version"
- "tailscale.com/wgengine/filter"
- "tailscale.com/wgengine/magicsock"
- "tailscale.com/wgengine/netlog"
- "tailscale.com/wgengine/netstack/gro"
- "tailscale.com/wgengine/router"
- "tailscale.com/wgengine/wgcfg"
- "tailscale.com/wgengine/wgint"
- "tailscale.com/wgengine/wglog"
+ "github.com/metacubex/bart"
+ "github.com/metacubex/tailscale-wireguard-go/device"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/drive"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/net/dns"
+ "github.com/metacubex/tailscale/net/dns/resolver"
+ "github.com/metacubex/tailscale/net/dnscache"
+ "github.com/metacubex/tailscale/net/ipset"
+ "github.com/metacubex/tailscale/net/netmon"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/net/sockstats"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/net/tsdial"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/tstime/mono"
+ "github.com/metacubex/tailscale/types/dnstype"
+ "github.com/metacubex/tailscale/types/events"
+ "github.com/metacubex/tailscale/types/ipproto"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/views"
+ "github.com/metacubex/tailscale/util/backoff"
+ "github.com/metacubex/tailscale/util/checkchange"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/util/eventbus"
+ "github.com/metacubex/tailscale/util/execqueue"
+ "github.com/metacubex/tailscale/util/mak"
+ "github.com/metacubex/tailscale/util/set"
+ "github.com/metacubex/tailscale/util/singleflight"
+ "github.com/metacubex/tailscale/util/testenv"
+ "github.com/metacubex/tailscale/util/usermetric"
+ "github.com/metacubex/tailscale/version"
+ "github.com/metacubex/tailscale/wgengine/filter"
+ "github.com/metacubex/tailscale/wgengine/magicsock"
+ "github.com/metacubex/tailscale/wgengine/netlog"
+ "github.com/metacubex/tailscale/wgengine/netstack/gro"
+ "github.com/metacubex/tailscale/wgengine/router"
+ "github.com/metacubex/tailscale/wgengine/wgcfg"
+ "github.com/metacubex/tailscale/wgengine/wgint"
+ "github.com/metacubex/tailscale/wgengine/wglog"
)
// networkLoggerUploadTimeout is the maximum timeout to wait when
@@ -222,6 +223,10 @@ type Config struct {
// connections (e.g. DERP). Passed through to magicsock.
ExtraRootCAs *x509.CertPool
+ // LookupHook optionally specifies how tsnet resolves non-Tailscale
+ // infrastructure hostnames such as control and DERP.
+ LookupHook dnscache.LookupHookFunc
+
// ControlKnobs is the set of control plane-provied knobs
// to use.
// If nil, defaults are used.
@@ -341,6 +346,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
}
if conf.Dialer == nil {
conf.Dialer = &tsdial.Dialer{Logf: logf}
+ conf.Dialer.LookupHook = conf.LookupHook
if conf.EventBus != nil {
conf.Dialer.SetBus(conf.EventBus)
}
@@ -435,8 +441,11 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
DERPActiveFunc: e.RequestStatus,
IdleFunc: e.tundev.IdleDuration,
NetMon: e.netMon,
+ SystemDialer: conf.Dialer.SystemDial,
+ PacketListener: conf.Dialer.SystemPacketListen,
HealthTracker: e.health,
ExtraRootCAs: conf.ExtraRootCAs,
+ LookupHook: conf.LookupHook,
Metrics: conf.Metrics,
ControlKnobs: conf.ControlKnobs,
PeerByKeyFunc: e.PeerByKey,
@@ -740,12 +749,15 @@ func (e *userspaceEngine) SetPeerByIPPacketFunc(fn func(netip.Addr) (_ key.NodeP
// hasOverlap checks if there is a IPPrefix which is common amongst the two
// provided slices.
func hasOverlap(aips, rips views.Slice[netip.Prefix]) bool {
- for _, aip := range aips.All() {
+ overlap := false
+ aips.All()(func(_ int, aip netip.Prefix) bool {
if views.SliceContains(rips, aip) {
- return true
+ overlap = true
+ return false
}
- }
- return false
+ return true
+ })
+ return overlap
}
// ResetAndStop resets the engine to a clean state (like calling Reconfig
@@ -1127,11 +1139,12 @@ func (e *userspaceEngine) getStatus() (*Status, error) {
}
peers := make([]ipnstate.PeerStatusLite, 0, peerKeys.Len())
- for _, key := range peerKeys.All() {
+ peerKeys.All()(func(_ int, key key.NodePublic) bool {
if status, ok := e.getPeerStatusLite(key); ok {
peers = append(peers, status)
}
- }
+ return true
+ })
return &Status{
AsOf: time.Now(),
@@ -1354,10 +1367,16 @@ func (e *userspaceEngine) mySelfIPMatchingFamily(dst netip.Addr) (src netip.Addr
if addrs.Len() == 0 {
return zero, errors.New("no self address in netmap")
}
- for _, p := range addrs.All() {
+ var retAddr netip.Addr
+ addrs.All()(func(_ int, p netip.Prefix) bool {
if p.IsSingleIP() && p.Addr().BitLen() == dst.BitLen() {
- return p.Addr(), nil
+ retAddr = p.Addr()
+ return false
}
+ return true
+ })
+ if retAddr.IsValid() {
+ return retAddr, nil
}
return zero, errors.New("no self address in netmap matching address family")
}
@@ -1523,7 +1542,7 @@ func (e *userspaceEngine) PeerForIP(ip netip.Addr) (ret PeerForIP, ok bool) {
// Check for exact matches before looking for subnet matches.
// TODO(bradfitz): add maps for these. on NetworkMap?
for _, p := range nm.Peers {
- for i := range p.Addresses().Len() {
+ for i := 0; i < p.Addresses().Len(); i++ {
a := p.Addresses().At(i)
if a.Addr() == ip && a.IsSingleIP() && tsaddr.IsTailscaleIP(ip) {
return PeerForIP{Node: p, Route: a}, true
@@ -1531,7 +1550,7 @@ func (e *userspaceEngine) PeerForIP(ip netip.Addr) (ret PeerForIP, ok bool) {
}
}
addrs := nm.GetAddresses()
- for i := range addrs.Len() {
+ for i := 0; i < addrs.Len(); i++ {
if a := addrs.At(i); a.Addr() == ip && a.IsSingleIP() && tsaddr.IsTailscaleIP(ip) {
return PeerForIP{Node: nm.SelfNode, IsSelf: true, Route: a}, true
}
diff --git a/wgengine/userspace_ext_test.go b/wgengine/userspace_ext_test.go
index 2d41a2df08dd2..c5d50b9a748a1 100644
--- a/wgengine/userspace_ext_test.go
+++ b/wgengine/userspace_ext_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,13 +8,13 @@ package wgengine_test
import (
"testing"
- "github.com/tailscale/wireguard-go/tun"
- "tailscale.com/net/tstun"
- "tailscale.com/tsd"
- "tailscale.com/tstest"
- "tailscale.com/types/logger"
- "tailscale.com/wgengine"
- "tailscale.com/wgengine/router"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/net/tstun"
+ "github.com/metacubex/tailscale/tsd"
+ "github.com/metacubex/tailscale/tstest"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/wgengine"
+ "github.com/metacubex/tailscale/wgengine/router"
)
func TestIsNetstack(t *testing.T) {
diff --git a/wgengine/userspace_test.go b/wgengine/userspace_test.go
index 918c466c1fbdc..5d9d888878792 100644
--- a/wgengine/userspace_test.go
+++ b/wgengine/userspace_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -11,21 +13,21 @@ import (
"runtime"
"testing"
+ "github.com/metacubex/tailscale/cmd/testwrapper/flakytest"
+ "github.com/metacubex/tailscale/control/controlknobs"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/net/dns"
+ "github.com/metacubex/tailscale/net/netaddr"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/types/opt"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/usermetric"
+ "github.com/metacubex/tailscale/wgengine/router"
+ "github.com/metacubex/tailscale/wgengine/wgcfg"
"go4.org/mem"
- "tailscale.com/cmd/testwrapper/flakytest"
- "tailscale.com/control/controlknobs"
- "tailscale.com/envknob"
- "tailscale.com/health"
- "tailscale.com/net/dns"
- "tailscale.com/net/netaddr"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/netmap"
- "tailscale.com/types/opt"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/usermetric"
- "tailscale.com/wgengine/router"
- "tailscale.com/wgengine/wgcfg"
)
func nodeViews(v []*tailcfg.Node) []tailcfg.NodeView {
diff --git a/wgengine/watchdog.go b/wgengine/watchdog.go
index 6aa1c1bd64cf0..0fe061340cc0e 100644
--- a/wgengine/watchdog.go
+++ b/wgengine/watchdog.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !js && !ts_omit_debug
+//go:build !js && ts_enable_debug
package wgengine
@@ -14,19 +14,19 @@ import (
"sync"
"time"
- "tailscale.com/envknob"
- "tailscale.com/feature/buildfeatures"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/net/dns"
- "tailscale.com/net/packet"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/netmap"
- "tailscale.com/util/clientmetric"
- "tailscale.com/wgengine/filter"
- "tailscale.com/wgengine/router"
- "tailscale.com/wgengine/wgcfg"
- "tailscale.com/wgengine/wgint"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/feature/buildfeatures"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/net/dns"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/util/clientmetric"
+ "github.com/metacubex/tailscale/wgengine/filter"
+ "github.com/metacubex/tailscale/wgengine/router"
+ "github.com/metacubex/tailscale/wgengine/wgcfg"
+ "github.com/metacubex/tailscale/wgengine/wgint"
)
type watchdogEvent string
diff --git a/wgengine/watchdog_omit.go b/wgengine/watchdog_omit.go
index b4ed4344292e6..783a53744d8ba 100644
--- a/wgengine/watchdog_omit.go
+++ b/wgengine/watchdog_omit.go
@@ -1,7 +1,7 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build js || ts_omit_debug
+//go:build js || !ts_enable_debug
package wgengine
diff --git a/wgengine/watchdog_test.go b/wgengine/watchdog_test.go
index a0ce9cf079652..42f0aed60266e 100644
--- a/wgengine/watchdog_test.go
+++ b/wgengine/watchdog_test.go
@@ -1,8 +1,8 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-//go:build !js
-
package wgengine
import (
@@ -11,9 +11,9 @@ import (
"testing"
"time"
- "tailscale.com/health"
- "tailscale.com/util/eventbus/eventbustest"
- "tailscale.com/util/usermetric"
+ "github.com/metacubex/tailscale/health"
+ "github.com/metacubex/tailscale/util/eventbus/eventbustest"
+ "github.com/metacubex/tailscale/util/usermetric"
)
func TestWatchdog(t *testing.T) {
diff --git a/wgengine/wgcfg/config.go b/wgengine/wgcfg/config.go
index 5510b65b2a199..4605a30715d8b 100644
--- a/wgengine/wgcfg/config.go
+++ b/wgengine/wgcfg/config.go
@@ -5,14 +5,14 @@
package wgcfg
import (
+ slices "github.com/metacubex/tailscale/util/go120/slices"
"net/netip"
- "slices"
- "tailscale.com/types/key"
- "tailscale.com/types/logid"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logid"
)
-//go:generate go run tailscale.com/cmd/cloner -type=Config,Peer
+//go:generate go run github.com/metacubex/tailscale/cmd/cloner -type=Config,Peer
// Config is a WireGuard configuration.
// It only supports the set of things Tailscale uses.
diff --git a/wgengine/wgcfg/config_test.go b/wgengine/wgcfg/config_test.go
index 013d3a4b49a6e..548072480cccc 100644
--- a/wgengine/wgcfg/config_test.go
+++ b/wgengine/wgcfg/config_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
diff --git a/wgengine/wgcfg/device.go b/wgengine/wgcfg/device.go
index ed32f8337e43e..e2c7a42a9f408 100644
--- a/wgengine/wgcfg/device.go
+++ b/wgengine/wgcfg/device.go
@@ -7,17 +7,15 @@ import (
"fmt"
"net/netip"
- "github.com/tailscale/wireguard-go/conn"
- "github.com/tailscale/wireguard-go/device"
- "github.com/tailscale/wireguard-go/tun"
- "tailscale.com/types/logger"
+ "github.com/metacubex/tailscale-wireguard-go/conn"
+ "github.com/metacubex/tailscale-wireguard-go/device"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/types/logger"
)
// NewDevice returns a wireguard-go Device configured for Tailscale use.
func NewDevice(tunDev tun.Device, bind conn.Bind, logger *device.Logger) *device.Device {
- ret := device.NewDevice(tunDev, bind, logger)
- ret.DisableSomeRoamingForBrokenMobileSemantics()
- return ret
+ return device.NewDevice(tunDev, bind, logger)
}
// ReconfigDevice replaces the existing device configuration with cfg.
@@ -28,7 +26,7 @@ func NewDevice(tunDev tun.Device, bind conn.Bind, logger *device.Logger) *device
// The caller is responsible for:
// - calling [device.Device.SetPrivateKey] when the key changes
// - installing a [device.PeerByIPPacketFunc] on the device for outbound
-// packet routing (e.g. via [tailscale.com/wgengine.Engine.SetPeerByIPPacketFunc])
+// packet routing (e.g. via [github.com/metacubex/tailscale/wgengine.Engine.SetPeerByIPPacketFunc])
func ReconfigDevice(d *device.Device, cfg *Config, logf logger.Logf) (err error) {
defer func() {
if err != nil {
diff --git a/wgengine/wgcfg/device_test.go b/wgengine/wgcfg/device_test.go
index 07eb41adbbdca..99a4778e758cc 100644
--- a/wgengine/wgcfg/device_test.go
+++ b/wgengine/wgcfg/device_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,10 +11,10 @@ import (
"os"
"testing"
- "github.com/tailscale/wireguard-go/conn"
- "github.com/tailscale/wireguard-go/device"
- "github.com/tailscale/wireguard-go/tun"
- "tailscale.com/types/key"
+ "github.com/metacubex/tailscale-wireguard-go/conn"
+ "github.com/metacubex/tailscale-wireguard-go/device"
+ "github.com/metacubex/tailscale-wireguard-go/tun"
+ "github.com/metacubex/tailscale/types/key"
)
func TestReconfigDevice(t *testing.T) {
diff --git a/wgengine/wgcfg/nmcfg/nmcfg.go b/wgengine/wgcfg/nmcfg/nmcfg.go
index f99b7b007a564..784e9ca79dcda 100644
--- a/wgengine/wgcfg/nmcfg/nmcfg.go
+++ b/wgengine/wgcfg/nmcfg/nmcfg.go
@@ -6,18 +6,18 @@ package nmcfg
import (
"bufio"
- "cmp"
"fmt"
+ cmp "github.com/metacubex/tailscale/util/go120/cmp"
"net/netip"
"strings"
- "tailscale.com/net/tsaddr"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/types/logid"
- "tailscale.com/types/netmap"
- "tailscale.com/wgengine/wgcfg"
+ "github.com/metacubex/tailscale/net/tsaddr"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/types/logid"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/wgengine/wgcfg"
)
func nodeDebugName(n tailcfg.NodeView) string {
@@ -37,12 +37,15 @@ func cidrIsSubnet(node tailcfg.NodeView, cidr netip.Prefix) bool {
if tsaddr.IsTailscaleIP(cidr.Addr()) {
return false
}
- for _, selfCIDR := range node.Addresses().All() {
+ isSubnet := true
+ node.Addresses().All()(func(_ int, selfCIDR netip.Prefix) bool {
if cidr == selfCIDR {
+ isSubnet = false
return false
}
- }
- return true
+ return true
+ })
+ return isSubnet
}
// WGCfg returns the NetworkMaps's WireGuard configuration.
@@ -101,23 +104,24 @@ func WGCfg(pk key.NodePrivate, nm *netmap.NetworkMap, logf logger.Logf, flags ne
cpeer.V4MasqAddr = peer.SelfNodeV4MasqAddrForThisPeer().Clone()
cpeer.V6MasqAddr = peer.SelfNodeV6MasqAddrForThisPeer().Clone()
cpeer.IsJailed = peer.IsJailed()
- for _, allowedIP := range peer.AllowedIPs().All() {
+ peer.AllowedIPs().All()(func(_ int, allowedIP netip.Prefix) bool {
if allowedIP.Bits() == 0 && peer.StableID() != exitNode {
if didExitNodeLog {
// Don't log about both the IPv4 /0 and IPv6 /0.
- continue
+ return true
}
didExitNodeLog = true
skippedExitNode = append(skippedExitNode, peer)
- continue
+ return true
} else if cidrIsSubnet(peer, allowedIP) {
if (flags & netmap.AllowSubnetRoutes) == 0 {
skippedSubnetRouter = append(skippedSubnetRouter, peer)
- continue
+ return true
}
}
cpeer.AllowedIPs = append(cpeer.AllowedIPs, allowedIP)
- }
+ return true
+ })
}
logList := func(title string, nodes []tailcfg.NodeView) {
diff --git a/wgengine/wgcfg/wgcfg_clone.go b/wgengine/wgcfg/wgcfg_clone.go
index a8a2122678b02..b33e2a93bd8d8 100644
--- a/wgengine/wgcfg/wgcfg_clone.go
+++ b/wgengine/wgcfg/wgcfg_clone.go
@@ -1,15 +1,15 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
-// Code generated by tailscale.com/cmd/cloner; DO NOT EDIT.
+// Code generated by github.com/metacubex/tailscale/cmd/cloner; DO NOT EDIT.
package wgcfg
import (
"net/netip"
- "tailscale.com/types/key"
- "tailscale.com/types/logid"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logid"
)
// Clone makes a deep copy of Config.
@@ -55,10 +55,10 @@ func (src *Peer) Clone() *Peer {
*dst = *src
dst.AllowedIPs = append(src.AllowedIPs[:0:0], src.AllowedIPs...)
if dst.V4MasqAddr != nil {
- dst.V4MasqAddr = new(*src.V4MasqAddr)
+ dst.V4MasqAddr = func() *netip.Addr { v := *src.V4MasqAddr; return &v }()
}
if dst.V6MasqAddr != nil {
- dst.V6MasqAddr = new(*src.V6MasqAddr)
+ dst.V6MasqAddr = func() *netip.Addr { v := *src.V6MasqAddr; return &v }()
}
return dst
}
diff --git a/wgengine/wgengine.go b/wgengine/wgengine.go
index 5ca4b75cfa110..ed138744703a8 100644
--- a/wgengine/wgengine.go
+++ b/wgengine/wgengine.go
@@ -9,16 +9,16 @@ import (
"net/netip"
"time"
- "tailscale.com/ipn/ipnstate"
- "tailscale.com/net/dns"
- "tailscale.com/net/packet"
- "tailscale.com/tailcfg"
- "tailscale.com/types/key"
- "tailscale.com/types/netmap"
- "tailscale.com/wgengine/filter"
- "tailscale.com/wgengine/router"
- "tailscale.com/wgengine/wgcfg"
- "tailscale.com/wgengine/wgint"
+ "github.com/metacubex/tailscale/ipn/ipnstate"
+ "github.com/metacubex/tailscale/net/dns"
+ "github.com/metacubex/tailscale/net/packet"
+ "github.com/metacubex/tailscale/tailcfg"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/netmap"
+ "github.com/metacubex/tailscale/wgengine/filter"
+ "github.com/metacubex/tailscale/wgengine/router"
+ "github.com/metacubex/tailscale/wgengine/wgcfg"
+ "github.com/metacubex/tailscale/wgengine/wgint"
)
// Status is the Engine status.
diff --git a/wgengine/wgint/wgint.go b/wgengine/wgint/wgint.go
index 88c48486e3fc6..76abd4633af6c 100644
--- a/wgengine/wgint/wgint.go
+++ b/wgengine/wgint/wgint.go
@@ -11,7 +11,7 @@ import (
"time"
"unsafe"
- "github.com/tailscale/wireguard-go/device"
+ "github.com/metacubex/tailscale-wireguard-go/device"
)
var (
@@ -23,7 +23,7 @@ var (
)
func getPeerStatsOffset(name string) uintptr {
- peerType := reflect.TypeFor[device.Peer]()
+ peerType := reflect.TypeOf((*device.Peer)(nil)).Elem()
field, ok := peerType.FieldByName(name)
if !ok {
panic("no " + name + " field in device.Peer")
@@ -35,7 +35,7 @@ func getPeerStatsOffset(name string) uintptr {
}
func getPeerHandshakeAttemptsOffset() uintptr {
- peerType := reflect.TypeFor[device.Peer]()
+ peerType := reflect.TypeOf((*device.Peer)(nil)).Elem()
field, ok := peerType.FieldByName("timers")
if !ok {
panic("no timers field in device.Peer")
diff --git a/wgengine/wgint/wgint_test.go b/wgengine/wgint/wgint_test.go
index 3409a7fde2d15..78f556c4a3186 100644
--- a/wgengine/wgint/wgint_test.go
+++ b/wgengine/wgint/wgint_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,7 +8,7 @@ package wgint
import (
"testing"
- "github.com/tailscale/wireguard-go/device"
+ "github.com/metacubex/tailscale-wireguard-go/device"
)
func TestInternalOffsets(t *testing.T) {
diff --git a/wgengine/wglog/wglog.go b/wgengine/wglog/wglog.go
index 174babb91a933..f6825d3859163 100644
--- a/wgengine/wglog/wglog.go
+++ b/wgengine/wglog/wglog.go
@@ -9,12 +9,12 @@ import (
"strings"
"sync"
- "github.com/tailscale/wireguard-go/device"
- "tailscale.com/envknob"
- "tailscale.com/syncs"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/wgengine/wgcfg"
+ "github.com/metacubex/tailscale-wireguard-go/device"
+ "github.com/metacubex/tailscale/envknob"
+ "github.com/metacubex/tailscale/syncs"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/wgengine/wgcfg"
)
// A Logger is a wireguard-go log wrapper that cleans up and rewrites log lines.
diff --git a/wgengine/wglog/wglog_test.go b/wgengine/wglog/wglog_test.go
index 2e82f9312a5dc..b5775cabd84a9 100644
--- a/wgengine/wglog/wglog_test.go
+++ b/wgengine/wglog/wglog_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
@@ -7,11 +9,11 @@ import (
"fmt"
"testing"
+ "github.com/metacubex/tailscale/types/key"
+ "github.com/metacubex/tailscale/types/logger"
+ "github.com/metacubex/tailscale/wgengine/wgcfg"
+ "github.com/metacubex/tailscale/wgengine/wglog"
"go4.org/mem"
- "tailscale.com/types/key"
- "tailscale.com/types/logger"
- "tailscale.com/wgengine/wgcfg"
- "tailscale.com/wgengine/wglog"
)
func TestLogger(t *testing.T) {
diff --git a/wif/wif.go b/wif/wif.go
index af36ea980ea5c..ba43cc677d42f 100644
--- a/wif/wif.go
+++ b/wif/wif.go
@@ -22,7 +22,7 @@ import (
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
"github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/aws/smithy-go"
- "tailscale.com/util/httpm"
+ "github.com/metacubex/tailscale/util/httpm"
)
type Environment string
diff --git a/words/words_test.go b/words/words_test.go
index 3547411a1e160..97cc91d6635bd 100644
--- a/words/words_test.go
+++ b/words/words_test.go
@@ -1,3 +1,5 @@
+//go:build ignore
+
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause