forked from skynetservices/skydns
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
130 lines (115 loc) · 3.72 KB
/
main.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright (c) 2014 The SkyDNS Authors. All rights reserved.
// Use of this source code is governed by The MIT License (MIT) that can be
// found in the LICENSE file.
package main
import (
"flag"
"fmt"
"log"
"net"
"os"
"strconv"
"strings"
"time"
"github.com/coreos/go-etcd/etcd"
"github.com/miekg/dns"
)
const Version = "2.0.0c"
var (
tlskey = ""
tlspem = ""
cacert = ""
config = &Config{ReadTimeout: 0, Domain: "", DnsAddr: "", DNSSEC: ""}
nameserver = ""
machine = ""
discover = false
verbose = false
)
const (
SCacheCapacity = 10000
RCacheCapacity = 100000
RCacheTtl = 60
)
func env(key, def string) string {
if x := os.Getenv(key); x != "" {
return x
}
return def
}
func init() {
flag.StringVar(&config.Domain, "domain", env("SKYDNS_DOMAIN", "skydns.local."), "domain to anchor requests to (SKYDNS_DOMAIN)")
flag.StringVar(&config.DnsAddr, "addr", env("SKYDNS_ADDR", "127.0.0.1:53"), "ip:port to bind to (SKYDNS_ADDR)")
flag.StringVar(&nameserver, "nameservers", env("SKYDNS_NAMESERVERS", ""), "nameserver address(es) to forward (non-local) queries to e.g. 8.8.8.8:53,8.8.4.4:53")
flag.StringVar(&machine, "machines", env("ETCD_MACHINES", ""), "machine address(es) running etcd")
flag.StringVar(&config.DNSSEC, "dnssec", "", "basename of DNSSEC key file e.q. Kskydns.local.+005+38250")
flag.StringVar(&config.Local, "local", "", "optional unique value for this skydns instance")
flag.StringVar(&tlskey, "tls-key", env("ETCD_TLSKEY", ""), "TLS Private Key path")
flag.StringVar(&tlspem, "tls-pem", env("ETCD_TLSPEM", ""), "X509 Certificate")
flag.StringVar(&cacert, "ca-cert", env("ECTD_CACERT", ""), "CA Certificate")
flag.DurationVar(&config.ReadTimeout, "rtimeout", 2*time.Second, "read timeout")
flag.BoolVar(&config.RoundRobin, "round-robin", true, "round robin A/AAAA replies")
flag.BoolVar(&discover, "discover", false, "discover new machines by watching /v2/_etcd/machines")
flag.BoolVar(&verbose, "verbose", false, "log queries")
// TTl
// Minttl
flag.StringVar(&config.Hostmaster, "hostmaster", "hostmaster@skydns.local.", "hostmaster email address to use")
flag.IntVar(&config.SCache, "scache", SCacheCapacity, "capacity of the signature cache")
flag.IntVar(&config.RCache, "rcache", 0, "capacity of the response cache") // default to 0 for now
flag.IntVar(&config.RCacheTtl, "rcache-ttl", RCacheTtl, "TTL of the response cache")
}
func main() {
flag.Parse()
machines := strings.Split(machine, ",")
client := NewClient(machines)
if nameserver != "" {
for _, hostPort := range strings.Split(nameserver, ",") {
if err := validateHostPort(hostPort); err != nil {
log.Fatalf("nameserver is invalid: %s\n", err)
}
config.Nameservers = append(config.Nameservers, hostPort)
}
}
if err := validateHostPort(config.DnsAddr); err != nil {
log.Fatalf("addr is invalid: %s\n", err)
}
config, err := loadConfig(client, config)
if err != nil {
log.Fatal(err)
}
s := NewServer(config, client)
if s.config.Local != "" {
s.config.Local = dns.Fqdn(s.config.Local)
}
if discover {
go func() {
recv := make(chan *etcd.Response)
go s.client.Watch("/_etcd/machines/", 0, true, recv, nil)
for {
select {
case n := <-recv:
// we can see an n == nil, probably when we can't connect to etcd.
if n != nil {
s.UpdateClient(n)
}
}
}
}()
}
statsCollect()
if err := s.Run(); err != nil {
log.Fatal(err)
}
}
func validateHostPort(hostPort string) error {
host, port, err := net.SplitHostPort(hostPort)
if err != nil {
return err
}
if ip := net.ParseIP(host); ip == nil {
return fmt.Errorf("bad IP address: %s", host)
}
if p, _ := strconv.Atoi(port); p < 1 || p > 65535 {
return fmt.Errorf("bad port number %s", port)
}
return nil
}