dns-remap: rewrite dns answer handling
This commit is contained in:
parent
856dca3154
commit
7a8867433f
188
dns-remap.go
188
dns-remap.go
@ -18,117 +18,114 @@ type DnsAnswer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func dnsRemap(qname string, qtype uint16, orig *dns.Msg) ([]PowerDnsAnswer, error) {
|
func dnsRemap(qname string, qtype uint16, orig *dns.Msg) ([]PowerDnsAnswer, error) {
|
||||||
|
result := make([]PowerDnsAnswer, 0)
|
||||||
interim := make([]DnsAnswer, 0, len(orig.Answer))
|
interim := make([]DnsAnswer, 0, len(orig.Answer))
|
||||||
real_qnames := make([]string, 0)
|
|
||||||
|
|
||||||
for _, rr := range orig.Answer {
|
needle := qname
|
||||||
if rr.Header().Name != qname {
|
name_seen := map[string]bool{
|
||||||
|
needle: true,
|
||||||
|
}
|
||||||
|
cname_dive := true
|
||||||
|
for {
|
||||||
|
if !cname_dive {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
cname_dive = false
|
||||||
|
|
||||||
|
for _, rr := range orig.Answer {
|
||||||
|
if rr.Header().Name != needle {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if rr.Header().Rrtype != dns.TypeCNAME {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
cname_dive = true
|
||||||
|
cname := rr.(*dns.CNAME)
|
||||||
|
_, seen := name_seen[cname.Target]
|
||||||
|
if seen {
|
||||||
|
// CNAME loop?
|
||||||
|
return []PowerDnsAnswer{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
needle = cname.Target
|
||||||
|
name_seen[needle] = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if cname_dive {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
r := DnsAnswer{
|
for _, rr := range orig.Answer {
|
||||||
Qname: qname,
|
if rr.Header().Name != needle {
|
||||||
Qtype: rr.Header().Rrtype,
|
continue
|
||||||
Ttl: rr.Header().Ttl,
|
}
|
||||||
}
|
|
||||||
switch r.Qtype {
|
t := rr.Header().Rrtype
|
||||||
case dns.TypeA:
|
switch t {
|
||||||
r.Addr = rr.(*dns.A).A
|
case dns.TypeA, dns.TypeAAAA:
|
||||||
r.AddrLen = net.IPv4len
|
// continue below
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
r := DnsAnswer{
|
||||||
|
Qname: qname,
|
||||||
|
Qtype: t,
|
||||||
|
Ttl: rr.Header().Ttl,
|
||||||
|
}
|
||||||
|
switch r.Qtype {
|
||||||
|
case dns.TypeA:
|
||||||
|
r.Addr = rr.(*dns.A).A
|
||||||
|
r.AddrLen = net.IPv4len
|
||||||
|
case dns.TypeAAAA:
|
||||||
|
r.Addr = rr.(*dns.AAAA).AAAA
|
||||||
|
r.AddrLen = net.IPv6len
|
||||||
|
}
|
||||||
interim = append(interim, r)
|
interim = append(interim, r)
|
||||||
case dns.TypeAAAA:
|
|
||||||
r.Addr = rr.(*dns.AAAA).AAAA
|
|
||||||
r.AddrLen = net.IPv6len
|
|
||||||
interim = append(interim, r)
|
|
||||||
case dns.TypeCNAME:
|
|
||||||
cname := rr.(*dns.CNAME)
|
|
||||||
real_qnames = append(real_qnames, cname.Target)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
// fix missing A/AAAA records
|
||||||
var mtx_interim sync.Mutex
|
if (len(interim) == 0) && ((needle != qname) || (qtype == dns.TypeANY)) {
|
||||||
// reprocess answers due to CNAME
|
var wg sync.WaitGroup
|
||||||
for _, real_qname := range real_qnames {
|
var a, aaaa []PowerDnsAnswer
|
||||||
wg.Add(1)
|
|
||||||
go func(real_name string) {
|
|
||||||
defer wg.Done()
|
|
||||||
|
|
||||||
found_qname := false
|
if qtype != dns.TypeAAAA {
|
||||||
for _, rr := range orig.Answer {
|
wg.Add(1)
|
||||||
if rr.Header().Name != real_name {
|
go func() {
|
||||||
continue
|
defer wg.Done()
|
||||||
|
x, _ := dnsApi_lookup_int(needle, dns.TypeA)
|
||||||
|
if x != nil {
|
||||||
|
a = x.([]PowerDnsAnswer)
|
||||||
}
|
}
|
||||||
found_qname = true
|
}()
|
||||||
|
}
|
||||||
r := DnsAnswer{
|
if qtype != dns.TypeA {
|
||||||
Qname: qname,
|
wg.Add(1)
|
||||||
Qtype: rr.Header().Rrtype,
|
go func() {
|
||||||
Ttl: rr.Header().Ttl,
|
defer wg.Done()
|
||||||
|
x, _ := dnsApi_lookup_int(needle, dns.TypeAAAA)
|
||||||
|
if x != nil {
|
||||||
|
aaaa = x.([]PowerDnsAnswer)
|
||||||
}
|
}
|
||||||
switch r.Qtype {
|
}()
|
||||||
case dns.TypeA:
|
}
|
||||||
r.Addr = rr.(*dns.A).A
|
|
||||||
r.AddrLen = net.IPv4len
|
|
||||||
|
|
||||||
mtx_interim.Lock()
|
wg.Wait()
|
||||||
interim = append(interim, r)
|
|
||||||
mtx_interim.Unlock()
|
|
||||||
case dns.TypeAAAA:
|
|
||||||
r.Addr = rr.(*dns.AAAA).AAAA
|
|
||||||
r.AddrLen = net.IPv6len
|
|
||||||
|
|
||||||
mtx_interim.Lock()
|
if a != nil {
|
||||||
interim = append(interim, r)
|
result = append(result, a...)
|
||||||
mtx_interim.Unlock()
|
}
|
||||||
}
|
if aaaa != nil {
|
||||||
}
|
result = append(result, aaaa...)
|
||||||
if found_qname {
|
}
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := dnsCustomResolve(real_name, dns.TypeANY)
|
// HACK: replace qname
|
||||||
if err != nil {
|
for i := range result {
|
||||||
return
|
result[i].Qname = qname
|
||||||
}
|
}
|
||||||
if resp == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, rr := range resp.Answer {
|
|
||||||
if rr.Header().Name != real_name {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
r := DnsAnswer{
|
|
||||||
Qname: qname,
|
|
||||||
Qtype: rr.Header().Rrtype,
|
|
||||||
Ttl: rr.Header().Ttl,
|
|
||||||
}
|
|
||||||
switch r.Qtype {
|
|
||||||
case dns.TypeA:
|
|
||||||
r.Addr = rr.(*dns.A).A
|
|
||||||
r.AddrLen = net.IPv4len
|
|
||||||
|
|
||||||
mtx_interim.Lock()
|
|
||||||
interim = append(interim, r)
|
|
||||||
mtx_interim.Unlock()
|
|
||||||
case dns.TypeAAAA:
|
|
||||||
r.Addr = rr.(*dns.AAAA).AAAA
|
|
||||||
r.AddrLen = net.IPv6len
|
|
||||||
|
|
||||||
mtx_interim.Lock()
|
|
||||||
interim = append(interim, r)
|
|
||||||
mtx_interim.Unlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}(real_qname)
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
|
|
||||||
result := make([]PowerDnsAnswer, 0, len(interim))
|
|
||||||
// nothing to do
|
|
||||||
if len(interim) == 0 {
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +136,6 @@ func dnsRemap(qname string, qtype uint16, orig *dns.Msg) ([]PowerDnsAnswer, erro
|
|||||||
for _, r := range interim {
|
for _, r := range interim {
|
||||||
switch r.AddrLen {
|
switch r.AddrLen {
|
||||||
case net.IPv4len, net.IPv6len:
|
case net.IPv4len, net.IPv6len:
|
||||||
break
|
|
||||||
default:
|
default:
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user