Files
worker/checks/cdns/soa_query.go
Gleb Tv 2c7a0236da feat: publish standalone worker
Separate worker packaging and service lifecycle from the control plane.
2026-07-13 17:55:14 +03:00

83 строки
2.0 KiB
Go

package cdns
import (
"fmt"
"net"
"github.com/miekg/dns"
)
func soaQuery(mychan chan SOAreply, zone string, name string, server string) {
var result SOAreply
var trials uint
result.retrieved = false
result.name = name
result.address = server
result.msg = "UNKNOWN"
m := new(dns.Msg)
if !noedns {
m.SetEdns0(bufsize, !nodnssec)
}
m.Id = dns.Id()
if recursion {
m.RecursionDesired = true
} else {
m.RecursionDesired = false
}
m.Question = make([]dns.Question, 1)
c := new(dns.Client)
c.ReadTimeout = timeout // Seems ignored for TCP?
if tcp {
c.Net = "tcp"
}
m.Question[0] = dns.Question{Name: zone, Qtype: dns.TypeSOA, Qclass: dns.ClassINET}
nsAddressPort := net.JoinHostPort(server, "53")
if debug {
fmt.Printf("DEBUG Querying SOA from %s\n", nsAddressPort)
}
for trials = 0; trials < uint(maxTrials); trials++ {
soa, rtt, err := c.Exchange(m, nsAddressPort)
if soa == nil {
result.rtt = 0
result.msg = err.Error()
} else {
result.rtt = rtt
if soa.Rcode != dns.RcodeSuccess {
result.msg = dns.RcodeToString[soa.Rcode]
break
}
if len(soa.Answer) == 0 { /* May happen if the server is a recursor, not authoritative, since we query with RD=0 */
result.msg = "0 answer"
break
} else { //nolint:revive // complex nested structure
gotSoa := false
for _, rsoa := range soa.Answer {
switch r := rsoa.(type) {
case *dns.SOA:
if noauthrequired || soa.Authoritative {
result.retrieved = true
result.serial = r.Serial
result.msg = "OK"
} else {
result.msg = "Not authoritative"
}
gotSoa = true
case *dns.CNAME: /* Bad practice but common */
result.msg = "Apparently not a zone but an alias"
case *dns.RRSIG:
/* Ignore them. See bug #8 */
default:
// TODO: a name server can send us other RR types.
result.msg = fmt.Sprintf("Internal error when processing %s, unexpected record type\n", rsoa)
}
}
if !gotSoa {
result.msg = "No SOA record in reply"
}
break
}
}
}
mychan <- result
}