2020-05-19 19:32:23 -07:00
|
|
|
package dnsseed
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2020-05-21 16:07:37 -07:00
|
|
|
"net"
|
2020-05-19 19:32:23 -07:00
|
|
|
|
|
|
|
"github.com/coredns/coredns/plugin"
|
2020-05-20 19:16:41 -07:00
|
|
|
"github.com/coredns/coredns/request"
|
2020-05-19 19:32:23 -07:00
|
|
|
"github.com/miekg/dns"
|
|
|
|
"github.com/zcashfoundation/dnsseeder/zcash"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ZcashSeeder discovers IP addresses by asking Zcash peers for them.
|
|
|
|
type ZcashSeeder struct {
|
2020-05-20 19:16:41 -07:00
|
|
|
Next plugin.Handler
|
|
|
|
Zones []string
|
2020-05-19 19:32:23 -07:00
|
|
|
seeder *zcash.Seeder
|
2020-05-25 14:39:20 -07:00
|
|
|
opts *options
|
2020-05-19 19:32:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Name satisfies the Handler interface.
|
|
|
|
func (zs ZcashSeeder) Name() string { return "dnsseed" }
|
|
|
|
|
|
|
|
// Ready implements the ready.Readiness interface, once this flips to true CoreDNS
|
|
|
|
// assumes this plugin is ready for queries; it is not checked again.
|
|
|
|
func (zs ZcashSeeder) Ready() bool {
|
|
|
|
// setup() has attempted an initial connection to the backing peer already.
|
|
|
|
return zs.seeder.Ready()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (zs ZcashSeeder) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
|
2020-05-20 19:16:41 -07:00
|
|
|
// Check if it's a question for us
|
|
|
|
state := request.Request{W: w, Req: r}
|
|
|
|
zone := plugin.Zones(zs.Zones).Matches(state.Name())
|
|
|
|
if zone == "" {
|
|
|
|
return plugin.NextOrFailure(zs.Name(), zs.Next, ctx, w, r)
|
|
|
|
}
|
|
|
|
|
2020-05-21 16:07:37 -07:00
|
|
|
var peerIPs []net.IP
|
|
|
|
switch state.QType() {
|
|
|
|
case dns.TypeA:
|
|
|
|
peerIPs = zs.seeder.Addresses(25)
|
|
|
|
case dns.TypeAAAA:
|
|
|
|
peerIPs = zs.seeder.AddressesV6(25)
|
|
|
|
default:
|
|
|
|
return dns.RcodeNotImplemented, nil
|
|
|
|
}
|
2020-05-20 19:16:41 -07:00
|
|
|
|
|
|
|
a := new(dns.Msg)
|
|
|
|
a.SetReply(r)
|
|
|
|
a.Authoritative = true
|
2020-05-21 15:41:08 -07:00
|
|
|
a.Answer = make([]dns.RR, 0, 25)
|
2020-05-20 19:16:41 -07:00
|
|
|
|
|
|
|
for i := 0; i < len(peerIPs); i++ {
|
|
|
|
var rr dns.RR
|
|
|
|
|
2020-05-21 15:41:08 -07:00
|
|
|
if peerIPs[i].To4() == nil {
|
|
|
|
rr = new(dns.AAAA)
|
2020-05-25 14:39:20 -07:00
|
|
|
rr.(*dns.AAAA).Hdr = dns.RR_Header{Name: state.QName(), Rrtype: dns.TypeAAAA, Ttl: zs.opts.recordTTL, Class: state.QClass()}
|
2020-05-21 15:41:08 -07:00
|
|
|
rr.(*dns.AAAA).AAAA = peerIPs[i]
|
|
|
|
} else {
|
2020-05-20 19:16:41 -07:00
|
|
|
rr = new(dns.A)
|
2020-05-25 14:39:20 -07:00
|
|
|
rr.(*dns.A).Hdr = dns.RR_Header{Name: state.QName(), Rrtype: dns.TypeA, Ttl: zs.opts.recordTTL, Class: state.QClass()}
|
2020-05-21 15:41:08 -07:00
|
|
|
rr.(*dns.A).A = peerIPs[i]
|
2020-05-20 19:16:41 -07:00
|
|
|
}
|
|
|
|
|
2020-05-21 15:41:08 -07:00
|
|
|
a.Answer = append(a.Answer, rr)
|
2020-05-20 19:16:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
w.WriteMsg(a)
|
|
|
|
return dns.RcodeSuccess, nil
|
2020-05-19 19:32:23 -07:00
|
|
|
}
|