meshname/meshname.go

68 lines
1.5 KiB
Go
Raw Permalink Normal View History

2021-05-27 12:24:07 +00:00
// Package meshname implements a plugin that returns details about the resolving
// querying it.
package meshname
import (
"context"
_meshname "github.com/zhoreeq/meshname/pkg/meshname"
"github.com/miekg/dns"
)
const name = "meshname"
// Meshname is a plugin that resolves .meshname domains
type Meshname struct{
dnsClient *dns.Client
}
// ServeDNS implements the plugin.Handler interface.
func (mn Meshname) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
var remoteLookups = make(map[string][]dns.Question)
a := new(dns.Msg)
a.SetReply(r)
a.Authoritative = true
for _, q := range r.Question {
labels := dns.SplitDomainName(q.Name)
if len(labels) < 2 {
// s.log.Debugln("Error: invalid domain requested")
continue
}
subDomain := labels[len(labels)-2]
resolvedAddr, err := _meshname.IPFromDomain(&subDomain)
if err != nil {
// s.log.Debugln(err)
continue
}
remoteLookups[resolvedAddr.String()] = append(remoteLookups[resolvedAddr.String()], q)
}
for remoteServer, questions := range remoteLookups {
rm := new(dns.Msg)
rm.RecursionDesired = true
rm.Question = questions
resp, _, err := mn.dnsClient.Exchange(rm, "["+remoteServer+"]:53") // no retries
if err != nil {
// s.log.Debugln(err)
continue
}
// s.log.Debugln(resp.String())
a.Answer = append(a.Answer, resp.Answer...)
a.Ns = append(a.Ns, resp.Ns...)
a.Extra = append(a.Extra, resp.Extra...)
}
w.WriteMsg(a)
return 0, nil
}
// Name implements the Handler interface.
func (mn Meshname) Name() string { return name }