net/netns, net/dns/resolver, etc: make netmon required in most places

The goal is to move more network state accessors to netmon.Monitor
where they can be cheaper/cached. But first (this change and others)
we need to make sure the one netmon.Monitor is plumbed everywhere.

Some notable bits:

* tsdial.NewDialer is added, taking a now-required netmon

* because a tsdial.Dialer always has a netmon, anything taking both
  a Dialer and a NetMon is now redundant; take only the Dialer and
  get the NetMon from that if/when needed.

* netmon.NewStatic is added, primarily for tests

Updates tailscale/corp#10910
Updates tailscale/corp#18960
Updates #7967
Updates #3299

Change-Id: I877f9cb87618c4eb037cee098241d18da9c01691
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2024-04-26 22:06:20 -07:00
committed by Brad Fitzpatrick
parent 4f73a26ea5
commit 3672f29a4e
34 changed files with 228 additions and 86 deletions

View File

@@ -71,7 +71,7 @@ type Client struct {
privateKey key.NodePrivate
logf logger.Logf
netMon *netmon.Monitor // optional; nil means interfaces will be looked up on-demand
netMon *netmon.Monitor // always non-nil
dialer func(ctx context.Context, network, addr string) (net.Conn, error)
// Either url or getRegion is non-nil:
@@ -116,9 +116,11 @@ func (c *Client) String() string {
// NewRegionClient returns a new DERP-over-HTTP client. It connects lazily.
// To trigger a connection, use Connect.
// The netMon parameter is optional; if non-nil it's used to do faster interface lookups.
// The healthTracker parameter is also optional.
func NewRegionClient(privateKey key.NodePrivate, logf logger.Logf, netMon *netmon.Monitor, getRegion func() *tailcfg.DERPRegion) *Client {
if netMon == nil {
panic("nil netMon")
}
ctx, cancel := context.WithCancel(context.Background())
c := &Client{
privateKey: privateKey,
@@ -140,7 +142,10 @@ func NewNetcheckClient(logf logger.Logf) *Client {
// NewClient returns a new DERP-over-HTTP client. It connects lazily.
// To trigger a connection, use Connect.
func NewClient(privateKey key.NodePrivate, serverURL string, logf logger.Logf) (*Client, error) {
func NewClient(privateKey key.NodePrivate, serverURL string, logf logger.Logf, netMon *netmon.Monitor) (*Client, error) {
if netMon == nil {
panic("nil netMon")
}
u, err := url.Parse(serverURL)
if err != nil {
return nil, fmt.Errorf("derphttp.NewClient: %v", err)
@@ -157,6 +162,7 @@ func NewClient(privateKey key.NodePrivate, serverURL string, logf logger.Logf) (
ctx: ctx,
cancelCtx: cancel,
clock: tstime.StdClock{},
netMon: netMon,
}
return c, nil
}

View File

@@ -16,12 +16,15 @@ import (
"time"
"tailscale.com/derp"
"tailscale.com/net/netmon"
"tailscale.com/types/key"
)
func TestSendRecv(t *testing.T) {
serverPrivateKey := key.NewNode()
netMon := netmon.NewStatic()
const numClients = 3
var clientPrivateKeys []key.NodePrivate
var clientKeys []key.NodePublic
@@ -68,7 +71,7 @@ func TestSendRecv(t *testing.T) {
}()
for i := range numClients {
key := clientPrivateKeys[i]
c, err := NewClient(key, serverURL, t.Logf)
c, err := NewClient(key, serverURL, t.Logf, netMon)
if err != nil {
t.Fatalf("client %d: %v", i, err)
}
@@ -183,7 +186,7 @@ func TestPing(t *testing.T) {
}
}()
c, err := NewClient(key.NewNode(), serverURL, t.Logf)
c, err := NewClient(key.NewNode(), serverURL, t.Logf, netmon.NewStatic())
if err != nil {
t.Fatalf("NewClient: %v", err)
}
@@ -236,7 +239,7 @@ func newTestServer(t *testing.T, k key.NodePrivate) (serverURL string, s *derp.S
}
func newWatcherClient(t *testing.T, watcherPrivateKey key.NodePrivate, serverToWatchURL string) (c *Client) {
c, err := NewClient(watcherPrivateKey, serverToWatchURL, t.Logf)
c, err := NewClient(watcherPrivateKey, serverToWatchURL, t.Logf, netmon.NewStatic())
if err != nil {
t.Fatal(err)
}