só atualiza se houver mudança no endereço

This commit is contained in:
2026-09-16 00:42:51 -03:00
parent 6c16f0da7a
commit 3b066755dd
2 changed files with 37 additions and 10 deletions
+33 -8
View File
@@ -1,4 +1,4 @@
// Package updater runs one dynamic DNS update pass across all configured entries. // Package updater runs dynamic DNS update passes across all configured entries.
package updater package updater
import ( import (
@@ -11,11 +11,28 @@ import (
"git.aehoo.net/alphard/he-dydns/internal/network" "git.aehoo.net/alphard/he-dydns/internal/network"
) )
// Run discovers the current address(es) and updates every configured entry. type cacheKey struct {
// It returns an error only when address discovery itself fails outright; hostname string
// per-entry update failures are logged and aggregated but do not stop other recordType config.RecordType
// entries from being attempted. }
func Run(cfg *config.Config) error {
// Updater runs update passes and remembers the last address successfully
// published for each entry, so unchanged addresses aren't re-sent upstream.
type Updater struct {
last map[cacheKey]net.IP
}
// New returns an Updater with no cached state; its first Run always
// publishes every entry that has a usable address.
func New() *Updater {
return &Updater{last: make(map[cacheKey]net.IP)}
}
// Run discovers the current address(es) and updates entries whose address
// changed since the last successful update. It returns an error only when
// address discovery itself fails outright; per-entry update failures are
// logged and aggregated but do not stop other entries from being attempted.
func (u *Updater) Run(cfg *config.Config) error {
addrs, err := network.Discover(cfg.Interface) addrs, err := network.Discover(cfg.Interface)
if err != nil { if err != nil {
return fmt.Errorf("discovering address: %w", err) return fmt.Errorf("discovering address: %w", err)
@@ -48,12 +65,20 @@ func Run(cfg *config.Config) error {
continue continue
} }
key := cacheKey{hostname: entry.Hostname, recordType: entry.RecordType}
if last, ok := u.last[key]; ok && last.Equal(ip) {
log.Printf("%s (%s) unchanged at %s; skipping update", entry.Hostname, entry.RecordType, ip)
continue
}
if err := hedns.Update(entry.Hostname, entry.Token, ip); err != nil { if err := hedns.Update(entry.Hostname, entry.Token, ip); err != nil {
log.Printf("error: %v", err) log.Printf("error: %v", err)
failures++ failures++
} else { continue
log.Printf("updated %s (%s) -> %s", entry.Hostname, entry.RecordType, ip)
} }
log.Printf("updated %s (%s) -> %s", entry.Hostname, entry.RecordType, ip)
u.last[key] = ip
} }
if failures > 0 { if failures > 0 {
+4 -2
View File
@@ -61,7 +61,9 @@ func main() {
log.Fatalf("fatal: %v", err) log.Fatalf("fatal: %v", err)
} }
runErr := updater.Run(cfg) u := updater.New()
runErr := u.Run(cfg)
if runErr != nil { if runErr != nil {
log.Printf("update pass completed with errors: %v", runErr) log.Printf("update pass completed with errors: %v", runErr)
} }
@@ -85,7 +87,7 @@ func main() {
for { for {
select { select {
case <-ticker.C: case <-ticker.C:
if err := updater.Run(cfg); err != nil { if err := u.Run(cfg); err != nil {
log.Printf("update pass completed with errors: %v", err) log.Printf("update pass completed with errors: %v", err)
} }
case sig := <-sigCh: case sig := <-sigCh: