diff --git a/internal/dnsinspect/dnsinspect.go b/internal/dnsinspect/dnsinspect.go index 4d1ab5b4..36debb94 100644 --- a/internal/dnsinspect/dnsinspect.go +++ b/internal/dnsinspect/dnsinspect.go @@ -391,6 +391,7 @@ func runFanOut(ctx context.Context, host string, target resolverTargetInfo, syst wg.Add(1) go func(i int, qt queryType) { defer wg.Done() + queryStart := time.Now() results[i].typ = qt switch { case systemPolicy != nil: @@ -410,6 +411,14 @@ func runFanOut(ctx context.Context, host string, target resolverTargetInfo, syst default: results[i].records, results[i].tcpFallback, results[i].err = lookupUDPRecordsWithFallback(ctx, target.udpAddr, host, qt) } + // System-nameserver queries expose resolver metadata that includes + // failover and retry time. The other backends do not, so measure + // their query operation here. This starts after shared resolver + // setup, which prevents bootstrap/connect time from being charged + // to every concurrently issued query. + if results[i].duration <= 0 { + results[i].duration = time.Since(queryStart) + } }(i, qt) } wg.Wait() diff --git a/internal/dnsinspect/dnsinspect_test.go b/internal/dnsinspect/dnsinspect_test.go index ab012e28..f06d87d2 100644 --- a/internal/dnsinspect/dnsinspect_test.go +++ b/internal/dnsinspect/dnsinspect_test.go @@ -347,7 +347,7 @@ func TestLookupQueriesRecordTypesConcurrently(t *testing.T) { })) defer server.Close() - _, err := lookup(context.Background(), &Config{ + res, err := lookup(context.Background(), &Config{ DNSServer: mustURL(t, server.URL+"/dns-query"), }, "example.com", time.Now()) if err != nil { @@ -360,6 +360,14 @@ func TestLookupQueriesRecordTypesConcurrently(t *testing.T) { if got < 2 { t.Fatalf("max concurrent requests = %d, want at least 2", got) } + if got, want := len(res.queries), len(inspectTypes); got != want { + t.Fatalf("query results = %d, want %d", got, want) + } + for _, query := range res.queries { + if query.duration <= 0 { + t.Errorf("%s query duration = %s, want positive duration", query.typ.label, query.duration) + } + } } func TestInspectKeepsRecordsAndFailsOnPartialQueryError(t *testing.T) {