-
Notifications
You must be signed in to change notification settings - Fork 0
/
apex.go
108 lines (90 loc) · 2.73 KB
/
apex.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package gateway
import (
"github.com/coredns/coredns/plugin/pkg/dnsutil"
"github.com/coredns/coredns/request"
"github.com/miekg/dns"
)
// serveSubApex serves requests that hit the zones fake 'dns' subdomain where our nameservers live.
func (gw *Gateway) serveSubApex(state request.Request) (int, error) {
base, _ := dnsutil.TrimZone(state.Name(), state.Zone)
m := new(dns.Msg)
m.SetReply(state.Req)
m.Authoritative = true
// base is gw.apex, if it's longer return nxdomain
switch labels := dns.CountLabel(base); labels {
default:
m.SetRcode(m, dns.RcodeNameError)
m.Ns = []dns.RR{gw.soa(state)}
if err := state.W.WriteMsg(m); err != nil {
log.Errorf("Failed to send a response: %s", err)
}
return 0, nil
case 2:
if base != gw.apex {
// nxdomain
m.SetRcode(m, dns.RcodeNameError)
m.Ns = []dns.RR{gw.soa(state)}
if err := state.W.WriteMsg(m); err != nil {
log.Errorf("Failed to send a response: %s", err)
}
return 0, nil
}
addr := gw.ExternalAddrFunc(state)
for _, rr := range addr {
rr.Header().Ttl = gw.ttlSOA
rr.Header().Name = state.QName()
switch state.QType() {
case dns.TypeA:
if rr.Header().Rrtype == dns.TypeA {
m.Answer = append(m.Answer, rr)
}
case dns.TypeAAAA:
if rr.Header().Rrtype == dns.TypeAAAA {
m.Answer = append(m.Answer, rr)
}
}
}
if len(m.Answer) == 0 {
m.Ns = []dns.RR{gw.soa(state)}
}
if err := state.W.WriteMsg(m); err != nil {
log.Errorf("Failed to send a response: %s", err)
}
return 0, nil
}
}
func (gw *Gateway) soa(state request.Request) *dns.SOA {
header := dns.RR_Header{Name: state.Zone, Rrtype: dns.TypeSOA, Ttl: gw.ttlSOA, Class: dns.ClassINET}
soa := &dns.SOA{Hdr: header,
Mbox: dnsutil.Join(gw.hostmaster, gw.apex, state.Zone),
Ns: dnsutil.Join(gw.apex, state.Zone),
Serial: 12345, // Also dynamic?
Refresh: 7200,
Retry: 1800,
Expire: 86400,
Minttl: gw.ttlSOA,
}
return soa
}
func (gw *Gateway) nameservers(state request.Request) (result []dns.RR) {
primaryNS := gw.ns1(state)
result = append(result, primaryNS)
secondaryNS := gw.ns2(state)
if secondaryNS != nil {
result = append(result, secondaryNS)
}
return result
}
func (gw *Gateway) ns1(state request.Request) *dns.NS {
header := dns.RR_Header{Name: state.Zone, Rrtype: dns.TypeNS, Ttl: gw.ttlSOA, Class: dns.ClassINET}
ns := &dns.NS{Hdr: header, Ns: dnsutil.Join(gw.apex, state.Zone)}
return ns
}
func (gw *Gateway) ns2(state request.Request) *dns.NS {
if gw.secondNS == "" { // If second NS is undefined, return nothing
return nil
}
header := dns.RR_Header{Name: state.Zone, Rrtype: dns.TypeNS, Ttl: gw.ttlSOA, Class: dns.ClassINET}
ns := &dns.NS{Hdr: header, Ns: dnsutil.Join(gw.secondNS, state.Zone)}
return ns
}