diff --git a/main.go b/main.go index 9182b45fc..e8f3fb0a6 100644 --- a/main.go +++ b/main.go @@ -233,13 +233,16 @@ func run(options *Options) { func createProxyConfig(options *Options) proxy.Config { // Create the config config := proxy.Config{ - Ratelimit: options.Ratelimit, - CacheEnabled: options.Cache, - CacheSizeBytes: options.CacheSizeBytes, - CacheMinTTL: options.CacheMinTTL, - CacheMaxTTL: options.CacheMaxTTL, - CacheOptimistic: options.CacheOptimistic, - RefuseAny: options.RefuseAny, + Ratelimit: options.Ratelimit, + CacheEnabled: options.Cache, + CacheSizeBytes: options.CacheSizeBytes, + CacheMinTTL: options.CacheMinTTL, + CacheMaxTTL: options.CacheMaxTTL, + CacheOptimistic: options.CacheOptimistic, + RefuseAny: options.RefuseAny, + // TODO(e.burkov): The following CIDRs are aimed to match any + // address. This is not quite civil approach to be used by + // default so think about configuring it. TrustedProxies: []string{"0.0.0.0/0", "::0/0"}, EnableEDNSClientSubnet: options.EnableEDNSSubnet, UDPBufferSize: options.UDPBufferSize, diff --git a/proxy/proxy.go b/proxy/proxy.go index 17768ba21..ca87dd2ac 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -420,7 +420,7 @@ func (p *Proxy) replyFromUpstream(d *DNSContext) (ok bool, err error) { reply, u, err = p.checkDNS64(req, reply, upstreams) } else if p.isBogusNXDomain(reply) { log.Tracef("Received IP from the bogus-nxdomain list, replacing response") - reply = p.genNXDomain(reply) + reply = p.genWithRCode(reply, dns.RcodeNameError) } log.Tracef("RTT: %s", time.Since(start)) diff --git a/proxy/server.go b/proxy/server.go index f63cc838f..3a21c2213 100644 --- a/proxy/server.go +++ b/proxy/server.go @@ -1,9 +1,9 @@ package proxy import ( + "errors" "fmt" "net" - "strings" "time" "github.com/AdguardTeam/golibs/log" @@ -177,12 +177,7 @@ func (p *Proxy) respond(d *DNSContext) { } func isNonCriticalError(err error) (ok bool) { - // TODO(a.garipov): When Go 1.16 is released, replace the error string - // check with proper error handling. - // - // See https://github.com/golang/go/issues/4373. - return isEPIPE(err) || - strings.HasSuffix(err.Error(), "use of closed network connection") + return isEPIPE(err) || errors.Is(err, net.ErrClosed) } // Set TTL value of all records according to our settings @@ -199,32 +194,24 @@ func (p *Proxy) setMinMaxTTL(r *dns.Msg) { } func (p *Proxy) genServerFailure(request *dns.Msg) *dns.Msg { - resp := dns.Msg{} - resp.SetRcode(request, dns.RcodeServerFailure) - resp.RecursionAvailable = true - return &resp + return p.genWithRCode(request, dns.RcodeServerFailure) } -func (p *Proxy) genNotImpl(request *dns.Msg) *dns.Msg { - resp := dns.Msg{} - resp.SetRcode(request, dns.RcodeNotImplemented) - resp.RecursionAvailable = true - resp.SetEdns0(1452, false) // NOTIMPL without EDNS is treated as 'we don't support EDNS', so explicitly set it - return &resp -} +func (p *Proxy) genNotImpl(request *dns.Msg) (resp *dns.Msg) { + resp = p.genWithRCode(request, dns.RcodeNotImplemented) + // NOTIMPL without EDNS is treated as 'we don't support EDNS', so + // explicitly set it. + resp.SetEdns0(1452, false) -func (p *Proxy) genRefused(request *dns.Msg) *dns.Msg { - resp := dns.Msg{} - resp.SetRcode(request, dns.RcodeRefused) - resp.RecursionAvailable = true - return &resp + return resp } -func (p *Proxy) genNXDomain(req *dns.Msg) *dns.Msg { - resp := dns.Msg{} - resp.SetRcode(req, dns.RcodeNameError) +func (p *Proxy) genWithRCode(r *dns.Msg, code int) (resp *dns.Msg) { + resp = &dns.Msg{} + resp.SetRcode(r, code) resp.RecursionAvailable = true - return &resp + + return resp } func (p *Proxy) logDNSMessage(m *dns.Msg) { diff --git a/proxy/server_https.go b/proxy/server_https.go index 5014ee433..6c145600a 100644 --- a/proxy/server_https.go +++ b/proxy/server_https.go @@ -107,7 +107,7 @@ func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { log.Debug("request came from proxy server %s", prx) if !p.proxyVerifier.detect(prx) { log.Debug("the proxy server %s is not trusted", prx) - d.Res = p.genRefused(req) + d.Res = p.genWithRCode(req, dns.RcodeRefused) p.respond(d) return @@ -143,8 +143,18 @@ func (p *Proxy) respondHTTPS(d *DNSContext) error { return err } +// addrsFromRequest extracts the actual client's IP address and the latest proxy +// server's IP address from the first suitable r's header. The appropriate +// returning values are turning to nil if r doesn't contain any information +// about it. Current headers priority is: +// +// 1. CF-Connecting-IP +// 2. True-Client-IP +// 3. X-Real-IP +// 4. X-Forwarded-For +// func addrsFromRequest(r *http.Request) (realIP net.IP, prx net.IP) { - for _, h := range []string{ + for _, h := range [...]string{ // Headers set by CloudFlare proxy servers. "CF-Connecting-IP", "True-Client-IP", @@ -169,6 +179,8 @@ func addrsFromRequest(r *http.Request) (realIP net.IP, prx net.IP) { return realIP, net.ParseIP(xff[lastComma+1:]) } +// remoteAddr returns the real client's address and the IP address of the latest +// proxy server if any. func remoteAddr(r *http.Request) (addr net.Addr, prx net.IP, err error) { var hostStr, portStr string if hostStr, portStr, err = net.SplitHostPort(r.RemoteAddr); err != nil { diff --git a/proxy/subnetdetector.go b/proxy/subnetdetector.go index 95f9ff36e..ecf06b8e6 100644 --- a/proxy/subnetdetector.go +++ b/proxy/subnetdetector.go @@ -1,6 +1,7 @@ package proxy import ( + "fmt" "net" ) @@ -57,7 +58,7 @@ func newSubnetDetector(nets []string) (sd *subnetDetector, err error) { _, ipnet, err = net.ParseCIDR(ipnetStr) if err != nil { if ipnet = parseIPAsCIDR(ipnetStr); ipnet == nil { - return nil, err + return nil, fmt.Errorf("bad CIDR or IP at index %d: %w", i, err) } }