This commit is contained in:
maxpetrusenkoagent 2026-07-03 08:00:41 -04:00 committed by GitHub
commit cbb7bb68b1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 70 additions and 12 deletions

View file

@ -0,0 +1,46 @@
package server
import (
"encoding/json"
"net"
"net/http"
"net/http/httptest"
"testing"
"tailscale.com/tailcfg"
)
func TestDERPBootstrapDNSIncludesControlHostQuery(t *testing.T) {
derpMap := (&tailcfg.DERPMap{
Regions: map[int]*tailcfg.DERPRegion{
999: {
RegionID: 999,
RegionCode: "headscale",
RegionName: "Headscale Embedded DERP",
Nodes: []*tailcfg.DERPNode{{
Name: "999a",
RegionID: 999,
HostName: "derp.invalid.",
}},
},
},
}).View()
req := httptest.NewRequest(http.MethodGet, "/bootstrap-dns?q=localhost", nil)
rec := httptest.NewRecorder()
DERPBootstrapDNSHandler(derpMap)(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("expected status %d, got %d", http.StatusOK, rec.Code)
}
var entries map[string][]net.IP
if err := json.NewDecoder(rec.Body).Decode(&entries); err != nil {
t.Fatalf("decoding bootstrap DNS response: %v", err)
}
if len(entries["localhost"]) == 0 {
t.Fatalf("expected bootstrap DNS response to include the control host query, got %#v", entries)
}
}

View file

@ -317,25 +317,37 @@ func DERPBootstrapDNSHandler(
resolvCtx, cancel := context.WithTimeout(req.Context(), time.Minute)
defer cancel()
var resolver net.Resolver
lookupNames := make([]string, 0)
if q := strings.TrimSpace(req.URL.Query().Get("q")); q != "" {
lookupNames = append(lookupNames, q)
}
for _, region := range derpMap.Regions().All() { //nolint:unqueryvet // not SQLBoiler, tailcfg iterator
for _, node := range region.Nodes().All() { //nolint:unqueryvet // not SQLBoiler, tailcfg iterator
addrs, err := resolver.LookupIP(resolvCtx, "ip", node.HostName())
if err != nil {
log.Trace().
Caller().
Err(err).
Msgf("bootstrap DNS lookup failed %q", node.HostName())
continue
}
dnsEntries[node.HostName()] = addrs
lookupNames = append(lookupNames, node.HostName())
}
}
for _, name := range lookupNames {
if _, ok := dnsEntries[name]; ok {
continue
}
addrs, err := resolver.LookupIP(resolvCtx, "ip", name)
if err != nil {
log.Trace().
Caller().
Err(err).
Msgf("bootstrap DNS lookup failed %q", name)
continue
}
dnsEntries[name] = addrs
}
writer.Header().Set("Content-Type", "application/json")
writer.WriteHeader(http.StatusOK)