diff options
author | 2017-02-07 18:01:16 +0000 | |
---|---|---|
committer | 2017-02-07 18:01:16 +0000 | |
commit | dbe1b2510d609bf37b0874f0aafa91e982cdc5c2 (patch) | |
tree | 90762f068772ec41ca027c212227aa49a327f821 /middleware/proxy/proxy.go | |
parent | e8ebcd3cfddde935ba163e26cd035f902051044f (diff) | |
download | coredns-dbe1b2510d609bf37b0874f0aafa91e982cdc5c2.tar.gz coredns-dbe1b2510d609bf37b0874f0aafa91e982cdc5c2.tar.zst coredns-dbe1b2510d609bf37b0874f0aafa91e982cdc5c2.zip |
middleware/proxy: fix except keyword (#505)
Fix the except keyword usage - the config would allow it, but it was
not enforced in the code.
Turns out that **FROM** was also not enforced, fix both, by (basically)
copying the code from Caddy.
Update the README and tests.
Locally test as well, shows that this works:
~~~
.:1053 {
proxy miek.nl 8.8.8.8:53 {
except a.miek.nl
}
proxy a.miek.nl 8.8.4.4:53
errors stdout
log stdout
}
~~~
And gives the desired results, not having a proxy line for `a.miek.nl`
results in a SERVFAIL (as expected).
Fixes #502
Diffstat (limited to 'middleware/proxy/proxy.go')
-rw-r--r-- | middleware/proxy/proxy.go | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/middleware/proxy/proxy.go b/middleware/proxy/proxy.go index 3f870661c..b8b50adc6 100644 --- a/middleware/proxy/proxy.go +++ b/middleware/proxy/proxy.go @@ -17,6 +17,7 @@ import ( var ( errUnreachable = errors.New("unreachable backend") errInvalidProtocol = errors.New("invalid protocol") + errInvalidDomain = errors.New("invalid path for proxy") ) // Proxy represents a middleware instance that can proxy requests to another (DNS) server. @@ -37,7 +38,7 @@ type Upstream interface { // Selects an upstream host to be routed to. Select() *UpstreamHost // Checks if subpdomain is not an ignored. - IsAllowedPath(string) bool + IsAllowedDomain(string) bool // Exchanger returns the exchanger to be used for this upstream. Exchanger() Exchanger } @@ -73,12 +74,17 @@ func (uh *UpstreamHost) Down() bool { var tryDuration = 60 * time.Second // ServeDNS satisfies the middleware.Handler interface. - func (p Proxy) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { var span, child ot.Span span = ot.SpanFromContext(ctx) state := request.Request{W: w, Req: r} - for _, upstream := range *p.Upstreams { + + upstream := p.match(state) + if upstream == nil { + return middleware.NextOrFailure(p.Name(), p.Next, ctx, w, r) + } + + for { start := time.Now() // Since Select() should give us "up" hosts, keep retrying @@ -129,7 +135,24 @@ func (p Proxy) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) ( return dns.RcodeServerFailure, errUnreachable } - return middleware.NextOrFailure(p.Name(), p.Next, ctx, w, r) +} + +func (p Proxy) match(state request.Request) (u Upstream) { + longestMatch := 0 + for _, upstream := range *p.Upstreams { + from := upstream.From() + + if !middleware.Name(from).Matches(state.Name()) || !upstream.IsAllowedDomain(state.Name()) { + continue + } + + if lf := len(from); lf > longestMatch { + longestMatch = lf + u = upstream + } + } + return u + } // Name implements the Handler interface. |