net/dnsfallback: add singleflight to recursive resolver

This prevents running more than one recursive resolution for the same
hostname in parallel, which can use excessive amounts of CPU when called
in a tight loop. Additionally, add tests that hit the network (when
run with a flag) to test the lookup behaviour.

Updates tailscale/corp#15261

Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I39351e1d2a8782dd4c52cb04b3bd982eb651c81e
This commit is contained in:
Andrew Dunham
2023-10-27 10:25:13 -04:00
parent a40e918d63
commit e33bc64cff
3 changed files with 181 additions and 60 deletions

View File

@ -4,13 +4,17 @@
package dnsfallback
import (
"context"
"encoding/json"
"flag"
"os"
"path/filepath"
"reflect"
"testing"
"tailscale.com/net/netmon"
"tailscale.com/tailcfg"
"tailscale.com/types/logger"
)
func TestGetDERPMap(t *testing.T) {
@ -170,3 +174,30 @@ func TestCacheUnchanged(t *testing.T) {
t.Fatalf("didn't find non-empty regular file; mode=%v size=%d", st.Mode(), st.Size())
}
}
var extNetwork = flag.Bool("use-external-network", false, "use the external network in tests")
func TestLookup(t *testing.T) {
if !*extNetwork {
t.Skip("skipping test without --use-external-network")
}
logf, closeLogf := logger.LogfCloser(t.Logf)
defer closeLogf()
netMon, err := netmon.New(logf)
if err != nil {
t.Fatal(err)
}
resolver := &fallbackResolver{
logf: logf,
netMon: netMon,
waitForCompare: true,
}
addrs, err := resolver.Lookup(context.Background(), "controlplane.tailscale.com")
if err != nil {
t.Fatal(err)
}
t.Logf("addrs: %+v", addrs)
}