diff --git a/cmd/cli/dns_proxy.go b/cmd/cli/dns_proxy.go index 6611975..f195f62 100644 --- a/cmd/cli/dns_proxy.go +++ b/cmd/cli/dns_proxy.go @@ -445,6 +445,10 @@ func (p *prog) proxy(ctx context.Context, req *proxyRequest) *proxyResponse { } } else { switch { + case isSrvLookup(req.msg): + upstreams = []string{upstreamOS} + upstreamConfigs = []*ctrld.UpstreamConfig{osUpstreamConfig} + ctrld.Log(ctx, mainLog.Load().Debug(), "SRV record lookup, using upstreams: %v", upstreams) case isPrivatePtrLookup(req.msg): isLanOrPtrQuery = true if answer := p.proxyPrivatePtrLookup(ctx, req.msg); answer != nil { @@ -1059,6 +1063,14 @@ func isLanHostnameQuery(m *dns.Msg) bool { strings.HasSuffix(name, ".lan") } +// isSrvLookup reports whether DNS message is a SRV query. +func isSrvLookup(m *dns.Msg) bool { + if m == nil || len(m.Question) == 0 { + return false + } + return m.Question[0].Qtype == dns.TypeSRV +} + // isWanClient reports whether the input is a WAN address. func isWanClient(na net.Addr) bool { var ip netip.Addr diff --git a/cmd/cli/dns_proxy_test.go b/cmd/cli/dns_proxy_test.go index 877fb71..6e7a431 100644 --- a/cmd/cli/dns_proxy_test.go +++ b/cmd/cli/dns_proxy_test.go @@ -414,6 +414,26 @@ func Test_isPrivatePtrLookup(t *testing.T) { } } +func Test_isSrvLookup(t *testing.T) { + tests := []struct { + name string + msg *dns.Msg + isSrvLookup bool + }{ + {"SRV", newDnsMsgWithHostname("foo", dns.TypeSRV), true}, + {"Not SRV", newDnsMsgWithHostname("foo", dns.TypeNone), false}, + } + for _, tc := range tests { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + if got := isSrvLookup(tc.msg); tc.isSrvLookup != got { + t.Errorf("unexpected result, want: %v, got: %v", tc.isSrvLookup, got) + } + }) + } +} + func Test_isWanClient(t *testing.T) { tests := []struct { name string