diff --git a/control/dns.go b/control/dns.go index b83cc73d75..1a3878036a 100644 --- a/control/dns.go +++ b/control/dns.go @@ -28,12 +28,7 @@ type DnsForwarder interface { Close() error } -var forwarderCache = make(map[string]DnsForwarder) - func newDnsForwarder(upstream *dns.Upstream, dialArgument dialArgument) (DnsForwarder, error) { - if forwarder, ok := forwarderCache[upstream.String()]; ok { - return forwarder, nil - } forwarder, err := func() (DnsForwarder, error) { switch dialArgument.l4proto { case consts.L4ProtoStr_TCP: @@ -65,7 +60,6 @@ func newDnsForwarder(upstream *dns.Upstream, dialArgument dialArgument) (DnsForw if err != nil { return nil, err } - forwarderCache[upstream.String()] = forwarder return forwarder, nil } diff --git a/control/dns_control.go b/control/dns_control.go index bf8f8729f2..5435814738 100644 --- a/control/dns_control.go +++ b/control/dns_control.go @@ -78,6 +78,8 @@ type DnsController struct { // mutex protects the dnsCache. dnsCacheMu sync.Mutex dnsCache map[string]*DnsCache + dnsForwarderCacheMu sync.Mutex + dnsForwarderCache map[string]DnsForwarder } func parseIpVersionPreference(prefer int) (uint16, error) { @@ -114,6 +116,8 @@ func NewDnsController(routing *dns.Dns, option *DnsControllerOption) (c *DnsCont fixedDomainTtl: option.FixedDomainTtl, dnsCacheMu: sync.Mutex{}, dnsCache: make(map[string]*DnsCache), + dnsForwarderCacheMu: sync.Mutex{}, + dnsForwarderCache: make(map[string]DnsForwarder), }, nil } @@ -556,7 +560,19 @@ func (c *DnsController) dialSend(invokingDepth int, req *udpRequest, data []byte ctxDial, cancel := context.WithTimeout(context.TODO(), consts.DefaultDialTimeout) defer cancel() - forwarder, err := newDnsForwarder(upstream, *dialArgument) + // get forwarder from cache + c.dnsForwarderCacheMu.Lock() + forwarder, ok := c.dnsForwarderCache[upstreamName] + if !ok { + forwarder, err = newDnsForwarder(upstream, *dialArgument) + if err != nil { + c.dnsForwarderCacheMu.Unlock() + return err + } + c.dnsForwarderCache[upstreamName] = forwarder + } + c.dnsForwarderCacheMu.Unlock() + defer func() { if !connClosed { forwarder.Close()