diff --git a/cmd/tailscale/cli/cli_test.go b/cmd/tailscale/cli/cli_test.go index 36cffa8ab..6ad7e0888 100644 --- a/cmd/tailscale/cli/cli_test.go +++ b/cmd/tailscale/cli/cli_test.go @@ -1016,9 +1016,6 @@ func TestPrefFlagMapping(t *testing.T) { continue } switch prefName { - case "AllowSingleHosts": - // Fake pref for downgrade compat. See #12058. - continue case "WantRunning", "Persist", "LoggedOut": // All explicitly handled (ignored) by checkForAccidentalSettingReverts. continue diff --git a/ipn/ipn_clone.go b/ipn/ipn_clone.go index e179438cd..773167a0d 100644 --- a/ipn/ipn_clone.go +++ b/ipn/ipn_clone.go @@ -104,7 +104,6 @@ func (src *Prefs) Clone() *Prefs { DriveShares []*drive.Share RelayServerPort *uint16 RelayServerStaticEndpoints []netip.AddrPort - AllowSingleHosts marshalAsTrueInJSON Persist *persist.Persist }{}) diff --git a/ipn/ipn_view.go b/ipn/ipn_view.go index 4e9d46bda..31c3dff2f 100644 --- a/ipn/ipn_view.go +++ b/ipn/ipn_view.go @@ -453,16 +453,6 @@ func (v PrefsView) RelayServerStaticEndpoints() views.Slice[netip.AddrPort] { return views.SliceOf(v.ж.RelayServerStaticEndpoints) } -// AllowSingleHosts was a legacy field that was always true -// for the past 4.5 years. It controlled whether Tailscale -// peers got /32 or /128 routes for each other. -// As of 2024-05-17 we're starting to ignore it, but to let -// people still downgrade Tailscale versions and not break -// all peer-to-peer networking we still write it to disk (as JSON) -// so it can be loaded back by old versions. -// TODO(bradfitz): delete this in 2025 sometime. See #12058. -func (v PrefsView) AllowSingleHosts() marshalAsTrueInJSON { return v.ж.AllowSingleHosts } - // The Persist field is named 'Config' in the file for backward // compatibility with earlier versions. // TODO(apenwarr): We should move this out of here, it's not a pref. @@ -506,7 +496,6 @@ func (v PrefsView) Persist() persist.PersistView { return v.ж.Persist.View() } DriveShares []*drive.Share RelayServerPort *uint16 RelayServerStaticEndpoints []netip.AddrPort - AllowSingleHosts marshalAsTrueInJSON Persist *persist.Persist }{}) diff --git a/ipn/prefs.go b/ipn/prefs.go index e54086b61..01c8bc5f8 100644 --- a/ipn/prefs.go +++ b/ipn/prefs.go @@ -291,16 +291,6 @@ type Prefs struct { // non-nil. RelayServerStaticEndpoints []netip.AddrPort `json:",omitempty"` - // AllowSingleHosts was a legacy field that was always true - // for the past 4.5 years. It controlled whether Tailscale - // peers got /32 or /128 routes for each other. - // As of 2024-05-17 we're starting to ignore it, but to let - // people still downgrade Tailscale versions and not break - // all peer-to-peer networking we still write it to disk (as JSON) - // so it can be loaded back by old versions. - // TODO(bradfitz): delete this in 2025 sometime. See #12058. - AllowSingleHosts marshalAsTrueInJSON - // The Persist field is named 'Config' in the file for backward // compatibility with earlier versions. // TODO(apenwarr): We should move this out of here, it's not a pref. @@ -331,13 +321,6 @@ func (au1 AutoUpdatePrefs) Equals(au2 AutoUpdatePrefs) bool { ok1 == ok2 } -type marshalAsTrueInJSON struct{} - -var trueJSON = []byte("true") - -func (marshalAsTrueInJSON) MarshalJSON() ([]byte, error) { return trueJSON, nil } -func (*marshalAsTrueInJSON) UnmarshalJSON([]byte) error { return nil } - // AppConnectorPrefs are the app connector settings for the node agent. type AppConnectorPrefs struct { // Advertise specifies whether the app connector subsystem is advertising diff --git a/ipn/prefs_test.go b/ipn/prefs_test.go index c20de0c00..97ed33c23 100644 --- a/ipn/prefs_test.go +++ b/ipn/prefs_test.go @@ -70,7 +70,6 @@ func TestPrefsEqual(t *testing.T) { "DriveShares", "RelayServerPort", "RelayServerStaticEndpoints", - "AllowSingleHosts", "Persist", } if have := fieldsOf(reflect.TypeFor[Prefs]()); !reflect.DeepEqual(have, prefsHandles) { @@ -714,7 +713,7 @@ func TestMaskedPrefsFields(t *testing.T) { have := map[string]bool{} for _, f := range fieldsOf(reflect.TypeFor[Prefs]()) { switch f { - case "Persist", "AllowSingleHosts": + case "Persist": // These can't be edited. continue } @@ -1222,27 +1221,6 @@ func TestNotifyPrefsJSONRoundtrip(t *testing.T) { } } -// Verify that our Prefs type writes out an AllowSingleHosts field so we can -// downgrade to older versions that require it. -func TestPrefsDowngrade(t *testing.T) { - var p Prefs - j, err := json.Marshal(p) - if err != nil { - t.Fatal(err) - } - - type oldPrefs struct { - AllowSingleHosts bool - } - var op oldPrefs - if err := json.Unmarshal(j, &op); err != nil { - t.Fatal(err) - } - if !op.AllowSingleHosts { - t.Fatal("AllowSingleHosts should be true") - } -} - func TestParseAutoExitNodeString(t *testing.T) { tests := []struct { name string diff --git a/types/prefs/prefs_example/prefs_example_clone.go b/types/prefs/prefs_example/prefs_example_clone.go index c5fdc49fc..9d43fb250 100644 --- a/types/prefs/prefs_example/prefs_example_clone.go +++ b/types/prefs/prefs_example/prefs_example_clone.go @@ -61,7 +61,6 @@ func (src *Prefs) Clone() *Prefs { PostureChecking prefs.Item[bool] NetfilterKind prefs.Item[string] DriveShares prefs.StructList[*drive.Share] - AllowSingleHosts prefs.Item[marshalAsTrueInJSON] Persist *persist.Persist }{}) diff --git a/types/prefs/prefs_example/prefs_example_view.go b/types/prefs/prefs_example/prefs_example_view.go index 67a284bb5..aa71c1a89 100644 --- a/types/prefs/prefs_example/prefs_example_view.go +++ b/types/prefs/prefs_example/prefs_example_view.go @@ -145,7 +145,6 @@ func (v PrefsView) NetfilterKind() prefs.Item[string] { return v.ж.NetfilterKin func (v PrefsView) DriveShares() prefs.StructListView[*drive.Share, drive.ShareView] { return prefs.StructListViewOf(&v.ж.DriveShares) } -func (v PrefsView) AllowSingleHosts() prefs.Item[marshalAsTrueInJSON] { return v.ж.AllowSingleHosts } // Persist is an internal state rather than a preference. // It can be kept in the Prefs structure but should not be wrapped @@ -182,7 +181,6 @@ func (v PrefsView) Persist() persist.PersistView { return v.ж.Persist.View() } PostureChecking prefs.Item[bool] NetfilterKind prefs.Item[string] DriveShares prefs.StructList[*drive.Share] - AllowSingleHosts prefs.Item[marshalAsTrueInJSON] Persist *persist.Persist }{}) diff --git a/types/prefs/prefs_example/prefs_types.go b/types/prefs/prefs_example/prefs_types.go index d0764c64b..e704e6bef 100644 --- a/types/prefs/prefs_example/prefs_types.go +++ b/types/prefs/prefs_example/prefs_types.go @@ -106,8 +106,7 @@ type Prefs struct { // not be modified after the preference is set. // Since the item type (*drive.Share) is mutable and implements [views.ViewCloner], // we need to use [prefs.StructList] instead of [prefs.List]. - DriveShares prefs.StructList[*drive.Share] `json:",omitzero"` - AllowSingleHosts prefs.Item[marshalAsTrueInJSON] `json:",omitzero"` + DriveShares prefs.StructList[*drive.Share] `json:",omitzero"` // Persist is an internal state rather than a preference. // It can be kept in the Prefs structure but should not be wrapped @@ -162,10 +161,3 @@ func (p Prefs) MarshalJSON() ([]byte, error) { func (p *Prefs) UnmarshalJSON(b []byte) error { return jsonv2.Unmarshal(b, p) // uses UnmarshalJSONFrom } - -type marshalAsTrueInJSON struct{} - -var trueJSON = []byte("true") - -func (marshalAsTrueInJSON) MarshalJSON() ([]byte, error) { return trueJSON, nil } -func (*marshalAsTrueInJSON) UnmarshalJSON([]byte) error { return nil }