diff --git a/proxy/upstreams.go b/proxy/upstreams.go index dfb44e741..c44a25a88 100644 --- a/proxy/upstreams.go +++ b/proxy/upstreams.go @@ -29,6 +29,9 @@ type UpstreamConfig struct { // Upstreams is a list of default upstreams. Upstreams []upstream.Upstream + + // DomainSpecificUpstreams is a list of domain specific upstreams. + DomainSpecificUpstreams []upstream.Upstream } // type check @@ -110,7 +113,7 @@ type ParseError struct { // err is the original error. err error - // Idx is an index of the line of the upstream list. + // Idx is an index of the lines. See [ParseUpstreamsConfig]. Idx int } @@ -153,6 +156,9 @@ type configParser struct { // upstreams is a list of default upstreams. upstreams []upstream.Upstream + + // domainSpecificUpstreams is a list of domain specific upstreams. + domainSpecificUpstreams []upstream.Upstream } // parse returns UpstreamConfig and error if upstreams configuration is invalid. @@ -172,6 +178,7 @@ func (p *configParser) parse(conf []string) (c *UpstreamConfig, err error) { return &UpstreamConfig{ Upstreams: p.upstreams, + DomainSpecificUpstreams: p.domainSpecificUpstreams, DomainReservedUpstreams: p.domainReservedUpstreams, SpecifiedDomainUpstreams: p.specifiedDomainUpstreams, SubdomainExclusions: p.subdomainsOnlyExclusions, @@ -180,7 +187,7 @@ func (p *configParser) parse(conf []string) (c *UpstreamConfig, err error) { // parseLine returns an error if upstream configuration line is invalid. func (p *configParser) parseLine(idx int, confLine string) (err error) { - upstreams, domains, err := splitConfigLine(idx, confLine) + upstreams, domains, err := splitConfigLine(confLine) if err != nil { // Don't wrap the error since it's informative enough as is. return err @@ -197,7 +204,7 @@ func (p *configParser) parseLine(idx int, confLine string) (err error) { } for _, u := range upstreams { - err = p.specifyUpstream(domains, u, idx, confLine) + err = p.specifyUpstream(domains, u, idx) if err != nil { // Don't wrap the error since it's informative enough as is. return err @@ -210,14 +217,14 @@ func (p *configParser) parseLine(idx int, confLine string) (err error) { // splitConfigLine parses upstream configuration line and returns list upstream // addresses (one or many), list of domains for which this upstream is reserved // (may be nil) or error if something went wrong. -func splitConfigLine(idx int, confLine string) (upstreams, domains []string, err error) { +func splitConfigLine(confLine string) (upstreams, domains []string, err error) { if !strings.HasPrefix(confLine, "[/") { return []string{confLine}, nil, nil } domainsLine, upstreamsLine, found := strings.Cut(confLine[len("[/"):], "/]") if !found || upstreamsLine == "" { - return nil, nil, fmt.Errorf("wrong upstream specification %d %q", idx, confLine) + return nil, nil, fmt.Errorf("wrong upstream specification") } // split domains list @@ -241,19 +248,14 @@ func splitConfigLine(idx int, confLine string) (upstreams, domains []string, err } // specifyUpstream specifies the upstream for domains. -func (p *configParser) specifyUpstream( - domains []string, - u string, - idx int, - confLine string, -) (err error) { +func (p *configParser) specifyUpstream(domains []string, u string, idx int) (err error) { dnsUpstream, ok := p.upstreamsIndex[u] // TODO(e.burkov): Improve identifying duplicate upstreams. if !ok { // create an upstream dnsUpstream, err = upstream.AddressToUpstream(u, p.options.Clone()) if err != nil { - return fmt.Errorf("cannot prepare the upstream %d %q: %s", idx, confLine, err) + return fmt.Errorf("cannot prepare the upstream: %s", err) } // save to the index @@ -262,11 +264,18 @@ func (p *configParser) specifyUpstream( addr := dnsUpstream.Address() if len(domains) == 0 { - log.Debug("dnsproxy: upstream at index %d: %s", idx, addr) p.upstreams = append(p.upstreams, dnsUpstream) + + log.Debug("dnsproxy: upstream at index %d: %s", idx, addr) } else { - log.Debug("dnsproxy: upstream at index %d: %s is reserved for %s", idx, addr, domains) + p.domainSpecificUpstreams = append(p.domainSpecificUpstreams, dnsUpstream) p.includeToReserved(dnsUpstream, domains) + + log.Debug("dnsproxy: upstream at index %d: %s is reserved for %d domains", + idx, + addr, + len(domains), + ) } return nil