diff options
author | Mike Crute <mike@crute.us> | 2020-08-11 05:11:29 +0000 |
---|---|---|
committer | Mike Crute <mike@crute.us> | 2020-08-11 05:30:28 +0000 |
commit | 52eb9dc9fc1e0472aea4fd5bd0bb7ea259431d41 (patch) | |
tree | 98dd05b7aaee29e692bd42d4873c84d6d53abe6e | |
parent | d7fec42036b331a8966efcc85e59b8dafea725ae (diff) | |
download | go_ddns_manager-52eb9dc9fc1e0472aea4fd5bd0bb7ea259431d41.tar.bz2 go_ddns_manager-52eb9dc9fc1e0472aea4fd5bd0bb7ea259431d41.tar.xz go_ddns_manager-52eb9dc9fc1e0472aea4fd5bd0bb7ea259431d41.zip |
Do not do ddns update if ip is same
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | dns/client.go (renamed from dns/cilent.go) | 63 | ||||
-rw-r--r-- | go.sum | 1 | ||||
-rw-r--r-- | web/controllers/ddns.go | 13 |
4 files changed, 77 insertions, 2 deletions
@@ -1,4 +1,4 @@ | |||
1 | ./dns-service | 1 | /dns-service |
2 | 2 | ||
3 | # Generated files have a zzz_ prefix | 3 | # Generated files have a zzz_ prefix |
4 | **/zzz_*.go | 4 | **/zzz_*.go |
diff --git a/dns/cilent.go b/dns/client.go index 6efe1b5..f322b45 100644 --- a/dns/cilent.go +++ b/dns/client.go | |||
@@ -49,6 +49,37 @@ func (c *DNSClient) AXFR(zone *bind.Zone) (chan *dns.Envelope, error) { | |||
49 | return t.In(m, fmt.Sprintf("%s:53", c.Server)) | 49 | return t.In(m, fmt.Sprintf("%s:53", c.Server)) |
50 | } | 50 | } |
51 | 51 | ||
52 | func (c *DNSClient) ReadRemoteZone(zone *bind.Zone) ([]RR, error) { | ||
53 | rrs := []RR{} | ||
54 | seenSoa := false | ||
55 | |||
56 | data, err := c.AXFR(zone) | ||
57 | if err != nil { | ||
58 | return nil, err | ||
59 | } | ||
60 | |||
61 | for rd := range data { | ||
62 | for _, r := range rd.RR { | ||
63 | switch dr := FromDNS(r).(type) { | ||
64 | case *SOA: | ||
65 | // Transfers have 2 SOA records, exclude the last one | ||
66 | if !seenSoa { | ||
67 | rrs = append(rrs, dr) | ||
68 | seenSoa = true | ||
69 | } | ||
70 | case RR: | ||
71 | rrs = append(rrs, dr) | ||
72 | default: | ||
73 | // This should only be possible if we somehow are | ||
74 | // missing generated DNS data types. | ||
75 | return nil, fmt.Errorf("Invalid return type") | ||
76 | } | ||
77 | } | ||
78 | } | ||
79 | |||
80 | return rrs, nil | ||
81 | } | ||
82 | |||
52 | func (c *DNSClient) StartUpdate(zone *bind.Zone) *DNSTransaction { | 83 | func (c *DNSClient) StartUpdate(zone *bind.Zone) *DNSTransaction { |
53 | m := &dns.Msg{} | 84 | m := &dns.Msg{} |
54 | m.SetUpdate(zone.Name) | 85 | m.SetUpdate(zone.Name) |
@@ -60,6 +91,18 @@ func (c *DNSClient) StartUpdate(zone *bind.Zone) *DNSTransaction { | |||
60 | } | 91 | } |
61 | } | 92 | } |
62 | 93 | ||
94 | func (c *DNSClient) QueryRecursive(zone *bind.Zone, fqdn string, rtype uint16) *DNSTransaction { | ||
95 | m := &dns.Msg{} | ||
96 | m.RecursionDesired = true | ||
97 | m.SetQuestion(fqdn, rtype) | ||
98 | |||
99 | return &DNSTransaction{ | ||
100 | zone: zone, | ||
101 | key: zone.Keys()[0], | ||
102 | msg: m, | ||
103 | } | ||
104 | } | ||
105 | |||
63 | func (c *DNSClient) SendUpdate(t *DNSTransaction) error { | 106 | func (c *DNSClient) SendUpdate(t *DNSTransaction) error { |
64 | udp := &dns.Client{Net: "udp", TsigSecret: t.key.AsMap()} | 107 | udp := &dns.Client{Net: "udp", TsigSecret: t.key.AsMap()} |
65 | tcp := &dns.Client{Net: "tcp", TsigSecret: t.key.AsMap()} | 108 | tcp := &dns.Client{Net: "tcp", TsigSecret: t.key.AsMap()} |
@@ -79,3 +122,23 @@ func (c *DNSClient) SendUpdate(t *DNSTransaction) error { | |||
79 | 122 | ||
80 | return nil | 123 | return nil |
81 | } | 124 | } |
125 | |||
126 | func (c *DNSClient) SendQuery(t *DNSTransaction) ([]dns.RR, error) { | ||
127 | udp := &dns.Client{Net: "udp", TsigSecret: t.key.AsMap()} | ||
128 | tcp := &dns.Client{Net: "tcp", TsigSecret: t.key.AsMap()} | ||
129 | |||
130 | t.msg.SetEdns0(4096, false) | ||
131 | t.key.Sign(t.msg) | ||
132 | |||
133 | in, _, err := udp.Exchange(t.msg, c.Server) | ||
134 | if in != nil && in.Truncated { | ||
135 | // If the TCP request succeeds, the err will reset to nil | ||
136 | in, _, err = tcp.Exchange(t.msg, c.Server) | ||
137 | } | ||
138 | |||
139 | if err != nil { | ||
140 | return nil, err | ||
141 | } | ||
142 | |||
143 | return in.Answer, nil | ||
144 | } | ||
@@ -70,6 +70,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn | |||
70 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | 70 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= |
71 | golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g= | 71 | golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g= |
72 | golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | 72 | golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= |
73 | golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= | ||
73 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | 74 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
74 | golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | 75 | golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
75 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | 76 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
diff --git a/web/controllers/ddns.go b/web/controllers/ddns.go index 692b59f..d476255 100644 --- a/web/controllers/ddns.go +++ b/web/controllers/ddns.go | |||
@@ -5,6 +5,7 @@ import ( | |||
5 | "net/http" | 5 | "net/http" |
6 | 6 | ||
7 | "github.com/gin-gonic/gin" | 7 | "github.com/gin-gonic/gin" |
8 | godns "github.com/miekg/dns" | ||
8 | 9 | ||
9 | "code.crute.me/mcrute/go_ddns_manager/dns" | 10 | "code.crute.me/mcrute/go_ddns_manager/dns" |
10 | "code.crute.me/mcrute/go_ddns_manager/util" | 11 | "code.crute.me/mcrute/go_ddns_manager/util" |
@@ -35,7 +36,17 @@ func UpdateDynamicDNS(c *gin.Context) { | |||
35 | return | 36 | return |
36 | } | 37 | } |
37 | 38 | ||
38 | txn := cfg.DNSClient.StartUpdate(zone).Upsert(&dns.A{ | 39 | txn := cfg.DNSClient.QueryRecursive(zone, res, godns.TypeA) |
40 | cur, err := cfg.DNSClient.SendQuery(txn) | ||
41 | if err == nil && len(cur) == 1 { | ||
42 | if cur[0].(*godns.A).A.Equal(inip) { | ||
43 | log.Printf("ddns: Update not required for '%s', IP %s", res, inip) | ||
44 | c.String(http.StatusNotModified, "") | ||
45 | return | ||
46 | } | ||
47 | } | ||
48 | |||
49 | txn = cfg.DNSClient.StartUpdate(zone).Upsert(&dns.A{ | ||
39 | Name: part, | 50 | Name: part, |
40 | Ttl: 60, | 51 | Ttl: 60, |
41 | A: inip, | 52 | A: inip, |