diff --git a/cmd/dnsupdater/main.go b/cmd/dnsupdater/main.go index 0ad387e..96c8e41 100644 --- a/cmd/dnsupdater/main.go +++ b/cmd/dnsupdater/main.go @@ -3,11 +3,13 @@ package main import ( "context" "encoding/json" + "errors" "fmt" "net/http" "os" "path" "strings" + "sync" "time" "github.com/rs/zerolog" @@ -107,39 +109,73 @@ func update(ctx context.Context, requester outboundip.IpRequester, manager dns.M } newIp := newIpResult.Ip + wg := sync.WaitGroup{} + updatedDomains := "" + updatedDomainsChannel := make(chan string) for _, domain := range configuration.Domains { - currentIp, err := manager.GetARecord(domain) - if err != nil { - return fmt.Errorf("getting current ip: %v", err) - } - - if currentIp == newIp { - continue - } - log. - Ctx(ctx). - Info(). - Str("domain", domain). - Str("current ip", currentIp). - Str("new ip", newIp). - Msg("ip has changed") - err = manager.SetARecord(domain, newIp) - if err != nil { - return fmt.Errorf("setting current ip: %v", err) - } - updatedDomains += fmt.Sprintf("\t- %s\n", domain) + domain := domain + wg.Add(1) + go func() { + defer wg.Done() + updated, err := checkDomain(manager, domain, newIp) + if err != nil { + log.Error().Err(err).Str("domain", domain).Msg("checking domain ip change") + } + if updated { + updatedDomainsChannel <- domain + } + }() + } + go func() { + wg.Wait() + close(updatedDomainsChannel) + }() + for { + select { + case <-ctx.Done(): + return errors.New("context canceled") + case d, ok := <-updatedDomainsChannel: + if !ok { + updatedDomainsChannel = nil + break + } + updatedDomains += fmt.Sprintf("\t- %s\n", d) + } + if updatedDomainsChannel == nil { + break + } } - if updatedDomains != "" { SendStatusMail(fmt.Sprintf(`Home IP has changed : %s Dns updated successfully for domains %s`, newIp, updatedDomains)) } - return nil } +func checkDomain(manager dns.Manager, domainname string, outboundip string) (bool, error) { + currentIp, err := manager.GetARecord(domainname) + if err != nil { + return false, fmt.Errorf("getting current ip: %v", err) + } + + if currentIp == outboundip { + return false, nil + } + log. + Info(). + Str("domain", domainname). + Str("current ip", currentIp). + Str("new ip", outboundip). + Msg("ip has changed") + err = manager.SetARecord(domainname, outboundip) + if err != nil { + return false, fmt.Errorf("setting current ip: %v", err) + } + return true, nil +} + func SendStatusMail(messageText string) { settings := configuration.MailSettings