68 lines
1.5 KiB
Go
68 lines
1.5 KiB
Go
|
// 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 }
|