From b3c7b631c267b75e17ac32cf1aa37aef4b12fb60 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Mon, 7 Dec 2020 09:13:26 -0800 Subject: [PATCH] tailcfg, control/controlclient: make nil PacketFilter mean unchanged (mapver 6) After mapver 5's incremental netmap updates & user profiles, much of the remaining bandwidth for streamed MapResponses were redundant, unchanged PacketFilters. So make MapRequest.Version 6 mean that nil means unchanged from the previous value. --- control/controlclient/direct.go | 10 ++++++++-- tailcfg/tailcfg.go | 21 ++++++++++++++++++--- version/version.go | 2 +- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/control/controlclient/direct.go b/control/controlclient/direct.go index 72ea0b4ba..36f5e45c9 100644 --- a/control/controlclient/direct.go +++ b/control/controlclient/direct.go @@ -45,6 +45,7 @@ "tailscale.com/types/opt" "tailscale.com/types/structs" "tailscale.com/version" + "tailscale.com/wgengine/filter" ) type Persist struct { @@ -541,7 +542,7 @@ func (c *Direct) PollNetMap(ctx context.Context, maxPolls int, cb func(*NetworkM } request := tailcfg.MapRequest{ - Version: 5, + Version: 6, KeepAlive: c.keepAlive, NodeKey: tailcfg.NodeKey(persist.PrivateNodeKey.Public()), DiscoKey: c.discoPubKey, @@ -636,6 +637,7 @@ func (c *Direct) PollNetMap(ctx context.Context, maxPolls int, cb func(*NetworkM var lastDERPMap *tailcfg.DERPMap var lastUserProfile = map[tailcfg.UserID]tailcfg.UserProfile{} + var lastParsedPacketFilter []filter.Match // If allowStream, then the server will use an HTTP long poll to // return incremental results. There is always one response right @@ -713,6 +715,10 @@ func (c *Direct) PollNetMap(ctx context.Context, maxPolls int, cb func(*NetworkM resp.Peers = filtered } + if pf := resp.PacketFilter; pf != nil { + lastParsedPacketFilter = c.parsePacketFilter(pf) + } + nm := &NetworkMap{ NodeKey: tailcfg.NodeKey(persist.PrivateNodeKey.Public()), PrivateKey: persist.PrivateNodeKey, @@ -727,7 +733,7 @@ func (c *Direct) PollNetMap(ctx context.Context, maxPolls int, cb func(*NetworkM Domain: resp.Domain, DNS: resp.DNSConfig, Hostinfo: resp.Node.Hostinfo, - PacketFilter: c.parsePacketFilter(resp.PacketFilter), + PacketFilter: lastParsedPacketFilter, DERPMap: lastDERPMap, Debug: resp.Debug, } diff --git a/tailcfg/tailcfg.go b/tailcfg/tailcfg.go index 1036b7517..191ec0615 100644 --- a/tailcfg/tailcfg.go +++ b/tailcfg/tailcfg.go @@ -476,6 +476,7 @@ type MapRequest struct { // 3: implicit compression, keep-alives // 4: opt-in keep-alives via KeepAlive field, opt-in compression via Compress // 5: 2020-10-19, implies IncludeIPv6, delta Peers/UserProfiles, supports MagicDNS + // 6: 2020-12-07: means MapResponse.PacketFilter nil means unchanged Version int Compress string // "zstd" or "" (no compression) KeepAlive bool // whether server should send keep-alives back to us @@ -620,11 +621,25 @@ type MapResponse struct { SearchPaths []string `json:",omitempty"` DNSConfig DNSConfig `json:",omitempty"` - // ACLs - Domain string + // Domain is the name of the network that this node is + // in. It's either of the form "example.com" (for user + // foo@example.com, for multi-user networks) or + // "foo@gmail.com" (for siloed users on shared email + // providers). Its exact form should not be depended on; new + // forms are coming later. + Domain string + + // PacketFilter are the firewall rules. + // + // For MapRequest.Version >= 6, a nil value means the most + // previously streamed non-nil MapResponse.PacketFilter within + // the same HTTP response. A non-nil but empty list always means + // no PacketFilter (that is, to block everything). PacketFilter []FilterRule - UserProfiles []UserProfile // as of 1.1.541: may be new or updated user profiles only + + UserProfiles []UserProfile // as of 1.1.541 (mapver 5): may be new or updated user profiles only Roles []Role // deprecated; clients should not rely on Roles + // TODO: Groups []Group // TODO: Capabilities []Capability diff --git a/version/version.go b/version/version.go index 87d6507fd..fbab0e6f4 100644 --- a/version/version.go +++ b/version/version.go @@ -10,7 +10,7 @@ // Long is a full version number for this build, of the form // "x.y.z-commithash", or "date.yyyymmdd" if no actual version was // provided. -const Long = "date.20201203" +const Long = "date.20201207" // Short is a short version number for this build, of the form // "x.y.z", or "date.yyyymmdd" if no actual version was provided.