1
// Copyright (c) 2014 The SkyDNS Authors. All rights reserved.
2
// Use of this source code is governed by The MIT License (MIT) that can be
3
// found in the LICENSE file.
15
"github.com/miekg/dns"
19
SCacheCapacity = 10000
20
RCacheCapacity = 100000
24
// Config provides options to the SkyDNS resolver.
26
// The ip:port SkyDNS should be listening on for incoming DNS requests.
27
DnsAddr string `json:"dns_addr,omitempty"`
28
// bind to port(s) activated by systemd. If set to true, this overrides DnsAddr.
29
Systemd bool `json:"systemd,omitempty"`
30
// The domain SkyDNS is authoritative for, defaults to skydns.local.
31
Domain string `json:"domain,omitempty"`
32
// Domain pointing to a key where service info is stored when being queried
33
// for local.dns.skydns.local.
34
Local string `json:"local,omitempty"`
35
// The hostmaster responsible for this domain, defaults to hostmaster.<Domain>.
36
Hostmaster string `json:"hostmaster,omitempty"`
37
DNSSEC string `json:"dnssec,omitempty"`
38
// Round robin A/AAAA replies. Default is true.
39
RoundRobin bool `json:"round_robin,omitempty"`
40
// Round robin selection of nameservers from among those listed, rather than have all forwarded requests try the first listed server first every time.
41
NSRotate bool `json:"ns_rotate,omitempty"`
42
// List of ip:port, seperated by commas of recursive nameservers to forward queries to.
43
Nameservers []string `json:"nameservers,omitempty"`
44
// Never provide a recursive service.
45
NoRec bool `json:"no_rec,omitempty"`
46
ReadTimeout time.Duration `json:"read_timeout,omitempty"`
47
// Default priority on SRV records when none is given. Defaults to 10.
48
Priority uint16 `json:"priority"`
49
// Default TTL, in seconds, when none is given in etcd. Defaults to 3600.
50
Ttl uint32 `json:"ttl,omitempty"`
51
// Minimum TTL, in seconds, for NXDOMAIN responses. Defaults to 300.
52
MinTtl uint32 `json:"min_ttl,omitempty"`
53
// SCache, capacity of the signature cache in signatures stored.
54
SCache int `json:"scache,omitempty"`
55
// RCache, capacity of response cache in resource records stored.
56
RCache int `json:"rcache,omitempty"`
57
// RCacheTtl, how long to cache in seconds.
58
RCacheTtl int `json:"rcache_ttl,omitempty"`
59
// How many labels a name should have before we allow forwarding. Default to 2.
60
Ndots int `json:"ndot,omitempty"`
62
// DNSSEC key material
63
PubKey *dns.DNSKEY `json:"-"`
64
KeyTag uint16 `json:"-"`
65
PrivKey crypto.Signer `json:"-"`
67
Verbose bool `json:"-"`
69
// some predefined string "constants"
70
localDomain string // "local.dns." + config.Domain
71
dnsDomain string // "ns.dns". + config.Domain
73
// Stub zones support. Pointer to a map that we refresh when we see
74
// an update. Map contains domainname -> nameserver:port
75
stub *map[string][]string
78
func SetDefaults(config *Config) error {
79
if config.ReadTimeout == 0 {
80
config.ReadTimeout = 2 * time.Second
82
if config.DnsAddr == "" {
83
config.DnsAddr = "127.0.0.1:53"
85
if config.Domain == "" {
86
config.Domain = "skydns.local."
88
if config.Hostmaster == "" {
89
config.Hostmaster = appendDomain("hostmaster", config.Domain)
91
// People probably don't know that SOA's email addresses cannot
92
// contain @-signs, replace them with dots
93
config.Hostmaster = dns.Fqdn(strings.Replace(config.Hostmaster, "@", ".", -1))
94
if config.MinTtl == 0 {
100
if config.Priority == 0 {
103
if config.RCache < 0 {
106
if config.SCache < 0 {
109
if config.RCacheTtl == 0 {
110
config.RCacheTtl = RCacheTtl
112
if config.Ndots <= 0 {
116
if len(config.Nameservers) == 0 {
117
c, err := dns.ClientConfigFromFile("/etc/resolv.conf")
118
if !os.IsNotExist(err) {
122
for _, s := range c.Servers {
123
config.Nameservers = append(config.Nameservers, net.JoinHostPort(s, c.Port))
127
config.Domain = dns.Fqdn(strings.ToLower(config.Domain))
128
if config.DNSSEC != "" {
129
// For some reason the + are replaces by spaces in etcd. Re-replace them
130
keyfile := strings.Replace(config.DNSSEC, " ", "+", -1)
131
k, p, err := ParseKeyFile(keyfile)
135
if k.Header().Name != dns.Fqdn(config.Domain) {
136
return fmt.Errorf("ownername of DNSKEY must match SkyDNS domain")
138
k.Header().Ttl = config.Ttl
140
config.KeyTag = k.KeyTag()
143
config.localDomain = appendDomain("local.dns", config.Domain)
144
config.dnsDomain = appendDomain("ns.dns", config.Domain)
145
stubmap := make(map[string][]string)
146
config.stub = &stubmap
150
func appendDomain(s1, s2 string) string {
151
if len(s2) > 0 && s2[0] == '.' {