mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-11-03 16:31:20 +00:00 
			
		
		
		
	ipn/ipnlocal: clear magicsock's netmap on logout
magicsock was hanging onto its netmap on logout, which caused tailscale status to display partial information about a bunch of zombie peers. After logout, there should be no peers. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This commit is contained in:
		
				
					committed by
					
						
						Josh Bleecher Snyder
					
				
			
			
				
	
			
			
			
						parent
						
							84a1106fa7
						
					
				
				
					commit
					93ae11105d
				
			@@ -536,6 +536,7 @@ func (b *LocalBackend) setClientStatus(st controlclient.Status) {
 | 
				
			|||||||
		// Since st.NetMap==nil means "netmap is unchanged", there is
 | 
							// Since st.NetMap==nil means "netmap is unchanged", there is
 | 
				
			||||||
		// no other way to represent this change.
 | 
							// no other way to represent this change.
 | 
				
			||||||
		b.setNetMapLocked(nil)
 | 
							b.setNetMapLocked(nil)
 | 
				
			||||||
 | 
							b.e.SetNetworkMap(new(netmap.NetworkMap))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	prefs := b.prefs
 | 
						prefs := b.prefs
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -409,6 +409,56 @@ func TestOneNodeUpWindowsStyle(t *testing.T) {
 | 
				
			|||||||
	d1.MustCleanShutdown(t)
 | 
						d1.MustCleanShutdown(t)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestLogoutRemovesAllPeers(t *testing.T) {
 | 
				
			||||||
 | 
						t.Parallel()
 | 
				
			||||||
 | 
						env := newTestEnv(t)
 | 
				
			||||||
 | 
						// Spin up some nodes.
 | 
				
			||||||
 | 
						nodes := make([]*testNode, 2)
 | 
				
			||||||
 | 
						for i := range nodes {
 | 
				
			||||||
 | 
							nodes[i] = newTestNode(t, env)
 | 
				
			||||||
 | 
							nodes[i].StartDaemon(t)
 | 
				
			||||||
 | 
							nodes[i].AwaitResponding(t)
 | 
				
			||||||
 | 
							nodes[i].MustUp()
 | 
				
			||||||
 | 
							nodes[i].AwaitIP(t)
 | 
				
			||||||
 | 
							nodes[i].AwaitRunning(t)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Make every node ping every other node.
 | 
				
			||||||
 | 
						// This makes sure magicsock is fully populated.
 | 
				
			||||||
 | 
						for i := range nodes {
 | 
				
			||||||
 | 
							for j := range nodes {
 | 
				
			||||||
 | 
								if i <= j {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if err := tstest.WaitFor(20*time.Second, func() error {
 | 
				
			||||||
 | 
									return nodes[i].Ping(nodes[j])
 | 
				
			||||||
 | 
								}); err != nil {
 | 
				
			||||||
 | 
									t.Fatalf("ping %v -> %v: %v", nodes[i].AwaitIP(t), nodes[j].AwaitIP(t), err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// wantNode0PeerCount waits until node[0] status includes exactly want peers.
 | 
				
			||||||
 | 
						wantNode0PeerCount := func(want int) {
 | 
				
			||||||
 | 
							if err := tstest.WaitFor(20*time.Second, func() error {
 | 
				
			||||||
 | 
								s := nodes[0].MustStatus(t)
 | 
				
			||||||
 | 
								if peers := s.Peers(); len(peers) != want {
 | 
				
			||||||
 | 
									return fmt.Errorf("want %d peer(s) in status, got %v", want, peers)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}); err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wantNode0PeerCount(len(nodes) - 1) // all other nodes are peers
 | 
				
			||||||
 | 
						nodes[0].MustLogOut()
 | 
				
			||||||
 | 
						wantNode0PeerCount(0) // node[0] is logged out, so it should not have any peers
 | 
				
			||||||
 | 
						nodes[0].MustUp()
 | 
				
			||||||
 | 
						nodes[0].AwaitIP(t)
 | 
				
			||||||
 | 
						wantNode0PeerCount(len(nodes) - 1) // all other nodes are peers again
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// testEnv contains the test environment (set of servers) used by one
 | 
					// testEnv contains the test environment (set of servers) used by one
 | 
				
			||||||
// or more nodes.
 | 
					// or more nodes.
 | 
				
			||||||
type testEnv struct {
 | 
					type testEnv struct {
 | 
				
			||||||
@@ -703,6 +753,21 @@ func (n *testNode) MustDown() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (n *testNode) MustLogOut() {
 | 
				
			||||||
 | 
						t := n.env.t
 | 
				
			||||||
 | 
						t.Logf("Running logout ...")
 | 
				
			||||||
 | 
						if err := n.Tailscale("logout").Run(); err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("logout: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (n *testNode) Ping(otherNode *testNode) error {
 | 
				
			||||||
 | 
						t := n.env.t
 | 
				
			||||||
 | 
						ip := otherNode.AwaitIP(t).String()
 | 
				
			||||||
 | 
						t.Logf("Running ping %v (from %v)...", ip, n.AwaitIP(t))
 | 
				
			||||||
 | 
						return n.Tailscale("ping", ip).Run()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AwaitListening waits for the tailscaled to be serving local clients
 | 
					// AwaitListening waits for the tailscaled to be serving local clients
 | 
				
			||||||
// over its localhost IPC mechanism. (Unix socket, etc)
 | 
					// over its localhost IPC mechanism. (Unix socket, etc)
 | 
				
			||||||
func (n *testNode) AwaitListening(t testing.TB) {
 | 
					func (n *testNode) AwaitListening(t testing.TB) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -239,6 +239,7 @@ func (ns *Impl) updateIPs(nm *netmap.NetworkMap) {
 | 
				
			|||||||
	newIPs := make(map[tcpip.AddressWithPrefix]bool)
 | 
						newIPs := make(map[tcpip.AddressWithPrefix]bool)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	isAddr := map[netaddr.IPPrefix]bool{}
 | 
						isAddr := map[netaddr.IPPrefix]bool{}
 | 
				
			||||||
 | 
						if nm.SelfNode != nil {
 | 
				
			||||||
		for _, ipp := range nm.SelfNode.Addresses {
 | 
							for _, ipp := range nm.SelfNode.Addresses {
 | 
				
			||||||
			isAddr[ipp] = true
 | 
								isAddr[ipp] = true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -248,6 +249,7 @@ func (ns *Impl) updateIPs(nm *netmap.NetworkMap) {
 | 
				
			|||||||
				newIPs[ipPrefixToAddressWithPrefix(ipp)] = true
 | 
									newIPs[ipPrefixToAddressWithPrefix(ipp)] = true
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ipsToBeAdded := make(map[tcpip.AddressWithPrefix]bool)
 | 
						ipsToBeAdded := make(map[tcpip.AddressWithPrefix]bool)
 | 
				
			||||||
	for ipp := range newIPs {
 | 
						for ipp := range newIPs {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user