ipn: add IPCVersion override func

I've done this a handful of times in the past and again today.
Time to make it a supported thing for the future.

Used while debugging tailscale/corp#4559 (macsys CLI issues)

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2022-04-25 20:30:41 -07:00 committed by Brad Fitzpatrick
parent 928d1fddd2
commit 3601b43530
3 changed files with 23 additions and 10 deletions

View File

@ -36,7 +36,6 @@
"tailscale.com/paths" "tailscale.com/paths"
"tailscale.com/safesocket" "tailscale.com/safesocket"
"tailscale.com/tailcfg" "tailscale.com/tailcfg"
"tailscale.com/version"
) )
var ( var (
@ -106,8 +105,8 @@ func DoLocalRequest(req *http.Request) (*http.Response, error) {
func doLocalRequestNiceError(req *http.Request) (*http.Response, error) { func doLocalRequestNiceError(req *http.Request) (*http.Response, error) {
res, err := DoLocalRequest(req) res, err := DoLocalRequest(req)
if err == nil { if err == nil {
if server := res.Header.Get("Tailscale-Version"); server != "" && server != version.Long && onVersionMismatch != nil { if server := res.Header.Get("Tailscale-Version"); server != "" && server != ipn.IPCVersion() && onVersionMismatch != nil {
onVersionMismatch(version.Long, server) onVersionMismatch(ipn.IPCVersion(), server)
} }
if res.StatusCode == 403 { if res.StatusCode == 403 {
all, _ := ioutil.ReadAll(res.Body) all, _ := ioutil.ReadAll(res.Body)

View File

@ -274,7 +274,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
tailscale.com/util/uniq from tailscale.com/wgengine/magicsock tailscale.com/util/uniq from tailscale.com/wgengine/magicsock
tailscale.com/util/winutil from tailscale.com/cmd/tailscaled+ tailscale.com/util/winutil from tailscale.com/cmd/tailscaled+
W 💣 tailscale.com/util/winutil/vss from tailscale.com/util/winutil W 💣 tailscale.com/util/winutil/vss from tailscale.com/util/winutil
tailscale.com/version from tailscale.com/client/tailscale+ tailscale.com/version from tailscale.com/cmd/tailscaled+
tailscale.com/version/distro from tailscale.com/cmd/tailscaled+ tailscale.com/version/distro from tailscale.com/cmd/tailscaled+
W tailscale.com/wf from tailscale.com/cmd/tailscaled W tailscale.com/wf from tailscale.com/cmd/tailscaled
tailscale.com/wgengine from tailscale.com/cmd/tailscaled+ tailscale.com/wgengine from tailscale.com/cmd/tailscaled+

View File

@ -15,6 +15,7 @@
"log" "log"
"time" "time"
"tailscale.com/envknob"
"tailscale.com/tailcfg" "tailscale.com/tailcfg"
"tailscale.com/types/logger" "tailscale.com/types/logger"
"tailscale.com/types/structs" "tailscale.com/types/structs"
@ -116,7 +117,7 @@ func (bs *BackendServer) send(n Notify) {
if bs.sendNotifyMsg == nil { if bs.sendNotifyMsg == nil {
return return
} }
n.Version = version.Long n.Version = ipcVersion
bs.sendNotifyMsg(n) bs.sendNotifyMsg(n)
} }
@ -153,9 +154,9 @@ func (bs *BackendServer) GotCommandMsg(ctx context.Context, b []byte) error {
const ErrMsgPermissionDenied = "permission denied" const ErrMsgPermissionDenied = "permission denied"
func (bs *BackendServer) GotCommand(ctx context.Context, cmd *Command) error { func (bs *BackendServer) GotCommand(ctx context.Context, cmd *Command) error {
if cmd.Version != version.Long && !cmd.AllowVersionSkew { if cmd.Version != ipcVersion && !cmd.AllowVersionSkew {
vs := fmt.Sprintf("GotCommand: Version mismatch! frontend=%#v backend=%#v", vs := fmt.Sprintf("GotCommand: Version mismatch! frontend=%#v backend=%#v",
cmd.Version, version.Long) cmd.Version, ipcVersion)
bs.logf("%s", vs) bs.logf("%s", vs)
// ignore the command, but send a message back to the // ignore the command, but send a message back to the
// caller so it can realize the version mismatch too. // caller so it can realize the version mismatch too.
@ -228,6 +229,19 @@ func NewBackendClient(logf logger.Logf, sendCommandMsg func(jsonb []byte)) *Back
} }
} }
// IPCVersion returns version.Long usually, unless TS_DEBUG_FAKE_IPC_VERSION is
// set, in which it contains that value. This is only used for weird development
// cases when testing mismatched versions and you want the client to act like it's
// compatible with the server.
func IPCVersion() string {
if v := envknob.String("TS_DEBUG_FAKE_IPC_VERSION"); v != "" {
return v
}
return version.Long
}
var ipcVersion = IPCVersion()
func (bc *BackendClient) GotNotifyMsg(b []byte) { func (bc *BackendClient) GotNotifyMsg(b []byte) {
if len(b) == 0 { if len(b) == 0 {
// not interesting // not interesting
@ -240,9 +254,9 @@ func (bc *BackendClient) GotNotifyMsg(b []byte) {
if err := json.Unmarshal(b, &n); err != nil { if err := json.Unmarshal(b, &n); err != nil {
log.Fatalf("BackendClient.Notify: cannot decode message (length=%d, %#q): %v", len(b), b, err) log.Fatalf("BackendClient.Notify: cannot decode message (length=%d, %#q): %v", len(b), b, err)
} }
if n.Version != version.Long && !bc.AllowVersionSkew { if n.Version != ipcVersion && !bc.AllowVersionSkew {
vs := fmt.Sprintf("GotNotify: Version mismatch! frontend=%#v backend=%#v", vs := fmt.Sprintf("GotNotify: Version mismatch! frontend=%#v backend=%#v",
version.Long, n.Version) ipcVersion, n.Version)
bc.logf("%s", vs) bc.logf("%s", vs)
// delete anything in the notification except the version, // delete anything in the notification except the version,
// to prevent incorrect operation. // to prevent incorrect operation.
@ -257,7 +271,7 @@ func (bc *BackendClient) GotNotifyMsg(b []byte) {
} }
func (bc *BackendClient) send(cmd Command) { func (bc *BackendClient) send(cmd Command) {
cmd.Version = version.Long cmd.Version = ipcVersion
b, err := json.Marshal(cmd) b, err := json.Marshal(cmd)
if err != nil { if err != nil {
log.Fatalf("Failed json.Marshal(cmd): %v\n", err) log.Fatalf("Failed json.Marshal(cmd): %v\n", err)