// notify sends notifies to the configured remote servers. It will try up to three times // before giving up on a specific remote. We will sequentially loop through "to" // until they all have replied (or have 3 failed attempts). func notify(zone string, to []string) error { m := new(dns.Msg) m.SetNotify(zone) c := new(dns.Client) for _, t := range to { if t == "*" { continue } if err := notifyAddr(c, m, t); err != nil { log.Printf("[ERROR] " + err.Error()) } else { log.Printf("[INFO] Sent notify for zone %s to %s", zone, t) } } return nil }
func sendNotify(servers []string, domain string) []NotifyResponse { if !strings.HasSuffix(domain, ".") { domain = domain + "." } if len(servers) == 0 { fmt.Println("No servers") resp := NotifyResponse{Result: "No servers", Error: true} fmt.Println("No servers") return []NotifyResponse{resp} } c := new(dns.Client) c.ReadTimeout = time.Duration(*timeout) * time.Millisecond m := new(dns.Msg) m.SetNotify(domain) wg := new(sync.WaitGroup) responseChannel := make(chan NotifyResponse, len(servers)) for _, server := range servers { go func(server string) { result := NotifyResponse{Server: server} wg.Add(1) defer func() { wg.Done() if result.Error || !*quiet { fmt.Printf("%s: %s\n", result.Server, result.Result) } responseChannel <- result }() target, err := fixupHost(server) if err != nil { result.Result = fmt.Sprintf("%s: %s", server, err) fmt.Println(result.Result) result.Error = true return } result.Server = target if *verbose { fmt.Println("Sending notify to", target) } resp, rtt, err := c.Exchange(m, target) if err != nil { result.Error = true result.Result = err.Error() return } ok := "ok" if !resp.Authoritative { ok = fmt.Sprintf("not ok (%s)", dns.RcodeToString[resp.Rcode]) } result.Result = fmt.Sprintf("%s: %s (%s)", target, ok, rtt.String()) responseChannel <- result }(server) } responses := make([]NotifyResponse, len(servers)) for i := 0; i < len(servers); i++ { responses[i] = <-responseChannel } wg.Wait() return responses }