MCPcopy
hub / github.com/AdguardTeam/dnsproxy / replyFromUpstream

Method replyFromUpstream

proxy/proxy.go:583–638  ·  view source on GitHub ↗

replyFromUpstream tries to resolve the request via configured upstream servers. It returns true if the response actually came from an upstream.

(d *DNSContext)

Source from the content-addressed store, hash-verified

581// replyFromUpstream tries to resolve the request via configured upstream
582// servers. It returns true if the response actually came from an upstream.
583func (p *Proxy) replyFromUpstream(d *DNSContext) (ok bool, err error) {
584 req := d.Req
585
586 upstreams, isPrivate := p.selectUpstreams(d)
587 if len(upstreams) == 0 {
588 d.Res = p.messages.NewMsgNXDOMAIN(req)
589
590 return false, fmt.Errorf("selecting upstream: %w", upstream.ErrNoUpstreams)
591 }
592
593 if isPrivate {
594 p.recDetector.add(d.Req)
595 }
596
597 src := "upstream"
598 wrapped := upstreamsWithStats(upstreams)
599
600 // Perform the DNS request.
601 resp, u, err := p.exchangeUpstreams(req, wrapped)
602 if dns64Ups := p.performDNS64(req, resp, wrapped); dns64Ups != nil {
603 u = dns64Ups
604 } else if p.isBogusNXDomain(resp) {
605 p.logger.Debug("response contains bogus-nxdomain ip")
606 resp = p.messages.NewMsgNXDOMAIN(req)
607 }
608
609 var wrappedFallbacks []upstream.Upstream
610 if err != nil && !isPrivate && p.Fallbacks != nil {
611 p.logger.Debug("using fallback", slogutil.KeyError, err)
612
613 src = "fallback"
614
615 // upstreams mustn't appear empty since they have been validated when
616 // creating proxy.
617 upstreams = p.Fallbacks.getUpstreamsForDomain(req.Question[0].Name)
618
619 wrappedFallbacks = upstreamsWithStats(upstreams)
620 resp, u, err = upstream.ExchangeParallel(wrappedFallbacks, req)
621 }
622
623 if err != nil {
624 p.logger.Debug("resolving err", "src", src, slogutil.KeyError, err)
625 }
626
627 if resp != nil {
628 p.logger.Debug("resolved", "upstream", u.Address(), "src", src)
629 }
630
631 unwrapped, stats := collectQueryStats(p.UpstreamMode, u, wrapped, wrappedFallbacks)
632 d.queryStatistics = stats
633
634 ctx := context.TODO()
635 p.handleExchangeResult(ctx, d, req, resp, unwrapped)
636
637 return resp != nil, err
638}
639
640// handleExchangeResult handles the result after the upstream exchange. It sets

Callers 1

ResolveMethod · 0.95

Calls 12

selectUpstreamsMethod · 0.95
exchangeUpstreamsMethod · 0.95
performDNS64Method · 0.95
isBogusNXDomainMethod · 0.95
handleExchangeResultMethod · 0.95
ExchangeParallelFunction · 0.92
upstreamsWithStatsFunction · 0.85
collectQueryStatsFunction · 0.85
addMethod · 0.80
getUpstreamsForDomainMethod · 0.80
NewMsgNXDOMAINMethod · 0.65
AddressMethod · 0.65

Tested by

no test coverage detected