Skip to content

Commit e965cea

Browse files
committed
Merge branch 'master' into AGDNS-2862-math-rand-v2
2 parents 38e6527 + 1fdda9a commit e965cea

File tree

2 files changed

+155
-11
lines changed

2 files changed

+155
-11
lines changed

proxy/proxy.go

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -750,21 +750,20 @@ func (p *Proxy) Resolve(dctx *DNSContext) (err error) {
750750
func (p *Proxy) cacheWorks(dctx *DNSContext) (ok bool) {
751751
var reason string
752752
switch {
753-
case p.cache == nil:
754-
reason = "disabled"
755-
case dctx.RequestedPrivateRDNS != netip.Prefix{}:
756-
// Don't cache the requests intended for local upstream servers, those
757-
// should be fast enough as is.
758-
reason = "requested address is private"
759753
case dctx.CustomUpstreamConfig != nil && dctx.CustomUpstreamConfig.cache == nil:
760-
// In case of custom upstream cache is not configured, the global proxy
761-
// cache cannot be used because different upstreams can return different
762-
// results.
754+
// If custom upstreams are used but the custom upstream cache is
755+
// disabled, return false to prevent storing results in the global
756+
// cache.
763757
//
764758
// See https://github.com/AdguardTeam/dnsproxy/issues/169.
765-
//
766-
// TODO(e.burkov): It probably should be decided after resolve.
767759
reason = "custom upstreams cache is not configured"
760+
case p.cache == nil &&
761+
(dctx.CustomUpstreamConfig == nil || dctx.CustomUpstreamConfig.cache == nil):
762+
reason = "caching disabled: neither global cache nor custom upstreams cache is configured"
763+
case dctx.RequestedPrivateRDNS != netip.Prefix{}:
764+
// Don't cache the requests intended for local upstream servers, those
765+
// should be fast enough as is.
766+
reason = "requested address is private"
768767
case dctx.Req.CheckingDisabled:
769768
// Also don't lookup the cache for responses with DNSSEC checking
770769
// disabled since only validated responses are cached and those may be

proxy/proxy_test.go

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package proxy_test
2+
3+
import (
4+
"net"
5+
"testing"
6+
7+
"github.com/AdguardTeam/dnsproxy/internal/dnsproxytest"
8+
"github.com/AdguardTeam/dnsproxy/proxy"
9+
"github.com/AdguardTeam/dnsproxy/upstream"
10+
"github.com/AdguardTeam/golibs/testutil"
11+
"github.com/miekg/dns"
12+
"github.com/stretchr/testify/assert"
13+
"github.com/stretchr/testify/require"
14+
)
15+
16+
// newCustomUpstreamConfig is a helper function that returns an initialized
17+
// [*proxy.CustomUpstreamConfig].
18+
func newCustomUpstreamConfig(ups upstream.Upstream, enabled bool) (c *proxy.CustomUpstreamConfig) {
19+
return proxy.NewCustomUpstreamConfig(
20+
&proxy.UpstreamConfig{Upstreams: []upstream.Upstream{ups}},
21+
enabled,
22+
0,
23+
false,
24+
)
25+
}
26+
27+
// isCachedWithCustomConfig is a helper function that returns the caching
28+
// results of a constructed request using the provided custom upstream
29+
// configuration and FQDN.
30+
func isCachedWithCustomConfig(
31+
tb testing.TB,
32+
p *proxy.Proxy,
33+
conf *proxy.CustomUpstreamConfig,
34+
fqdn string,
35+
) (isCached bool) {
36+
tb.Helper()
37+
38+
d := &proxy.DNSContext{
39+
CustomUpstreamConfig: conf,
40+
Req: (&dns.Msg{}).SetQuestion(fqdn, dns.TypeA),
41+
}
42+
43+
err := p.Resolve(d)
44+
require.NoError(tb, err)
45+
46+
qs := d.QueryStatistics()
47+
require.NotNil(tb, qs)
48+
49+
s := qs.Main()
50+
require.Len(tb, s, 1)
51+
52+
return s[0].IsCached
53+
}
54+
55+
func TestProxy_Resolve_cache(t *testing.T) {
56+
const host = "example.test."
57+
58+
ups := &dnsproxytest.FakeUpstream{
59+
OnAddress: func() (addr string) { return "stub" },
60+
OnClose: func() (err error) { return nil },
61+
}
62+
ups.OnExchange = func(req *dns.Msg) (resp *dns.Msg, err error) {
63+
resp = (&dns.Msg{}).SetReply(req)
64+
resp.Answer = append(resp.Answer, &dns.A{
65+
Hdr: dns.RR_Header{
66+
Name: req.Question[0].Name,
67+
Rrtype: dns.TypeA,
68+
Class: dns.ClassINET,
69+
Ttl: 60,
70+
},
71+
A: net.IP{192, 0, 2, 0},
72+
})
73+
74+
return resp, nil
75+
}
76+
77+
upsConf := &proxy.UpstreamConfig{
78+
Upstreams: []upstream.Upstream{ups},
79+
}
80+
81+
testCases := []struct {
82+
customUpstreamConf *proxy.CustomUpstreamConfig
83+
wantCachedWithConf assert.BoolAssertionFunc
84+
wantCachedGlobal assert.BoolAssertionFunc
85+
name string
86+
prxCacheEnabled bool
87+
}{{
88+
customUpstreamConf: nil,
89+
wantCachedWithConf: assert.True,
90+
wantCachedGlobal: assert.True,
91+
name: "global_cache",
92+
prxCacheEnabled: true,
93+
}, {
94+
customUpstreamConf: newCustomUpstreamConfig(ups, true),
95+
wantCachedWithConf: assert.True,
96+
wantCachedGlobal: assert.False,
97+
name: "custom_cache",
98+
prxCacheEnabled: false,
99+
}, {
100+
customUpstreamConf: newCustomUpstreamConfig(ups, false),
101+
wantCachedWithConf: assert.False,
102+
wantCachedGlobal: assert.False,
103+
name: "custom_cache_only_upstreams",
104+
prxCacheEnabled: false,
105+
}, {
106+
customUpstreamConf: newCustomUpstreamConfig(ups, true),
107+
wantCachedWithConf: assert.True,
108+
wantCachedGlobal: assert.False,
109+
name: "two_caches_enabled",
110+
prxCacheEnabled: true,
111+
}, {
112+
customUpstreamConf: nil,
113+
wantCachedWithConf: assert.False,
114+
wantCachedGlobal: assert.False,
115+
name: "two_caches_disabled",
116+
prxCacheEnabled: false,
117+
}}
118+
119+
for _, tc := range testCases {
120+
t.Run(tc.name, func(t *testing.T) {
121+
p, err := proxy.New(&proxy.Config{
122+
UDPListenAddr: []*net.UDPAddr{net.UDPAddrFromAddrPort(localhostAnyPort)},
123+
UpstreamConfig: upsConf,
124+
CacheEnabled: tc.prxCacheEnabled,
125+
})
126+
require.NoError(t, err)
127+
require.NotNil(t, p)
128+
129+
ctx := testutil.ContextWithTimeout(t, testTimeout)
130+
err = p.Start(ctx)
131+
require.NoError(t, err)
132+
133+
testutil.CleanupAndRequireSuccess(t, func() (err error) { return p.Shutdown(ctx) })
134+
135+
res := isCachedWithCustomConfig(t, p, tc.customUpstreamConf, host)
136+
assert.False(t, res)
137+
138+
res = isCachedWithCustomConfig(t, p, tc.customUpstreamConf, host)
139+
tc.wantCachedWithConf(t, res)
140+
141+
res = isCachedWithCustomConfig(t, p, nil, host)
142+
tc.wantCachedGlobal(t, res)
143+
})
144+
}
145+
}

0 commit comments

Comments
 (0)