diff options
Diffstat (limited to 'plugin/pkg/upstream/upstream.go')
-rw-r--r-- | plugin/pkg/upstream/upstream.go | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/plugin/pkg/upstream/upstream.go b/plugin/pkg/upstream/upstream.go new file mode 100644 index 000000000..fc85d3f5c --- /dev/null +++ b/plugin/pkg/upstream/upstream.go @@ -0,0 +1,55 @@ +// Package upstream abstracts a upstream lookups so that plugins +// can handle them in an unified way. +package upstream + +import ( + "github.com/miekg/dns" + + "github.com/coredns/coredns/core/dnsserver" + "github.com/coredns/coredns/plugin/pkg/dnsutil" + "github.com/coredns/coredns/plugin/pkg/nonwriter" + "github.com/coredns/coredns/plugin/proxy" + "github.com/coredns/coredns/request" +) + +// Upstream is used to resolve CNAME targets +type Upstream struct { + self bool + Forward *proxy.Proxy +} + +// NewUpstream creates a new Upstream for given destination(s) +func NewUpstream(dests []string) (Upstream, error) { + u := Upstream{} + if len(dests) == 0 { + u.self = true + return u, nil + } + u.self = false + ups, err := dnsutil.ParseHostPortOrFile(dests...) + if err != nil { + return u, err + } + p := proxy.NewLookup(ups) + u.Forward = &p + return u, nil +} + +// Lookup routes lookups to Self or Forward +func (u Upstream) Lookup(state request.Request, name string, typ uint16) (*dns.Msg, error) { + if u.self { + // lookup via self + req := new(dns.Msg) + req.SetQuestion(name, typ) + state.SizeAndDo(req) + nw := nonwriter.New(state.W) + state2 := request.Request{W: nw, Req: req} + server := state.Context.Value(dnsserver.Key{}).(*dnsserver.Server) + server.ServeDNS(state.Context, state2.W, req) + return nw.Msg, nil + } + if u.Forward != nil { + return u.Forward.Lookup(state, name, typ) + } + return &dns.Msg{}, nil +} |