// This file is part of the happyDomain (R) project. // Copyright (c) 2020-2026 happyDomain // Authors: Pierre-Olivier Mercier, et al. // // This program is offered under a commercial and under the AGPL license. // For commercial licensing, contact us at . // // For AGPL licensing: // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // Package checker implements the generic SRV records checker for happyDomain. // // TLS/certificate testing is intentionally out of scope: it is handled by a // dedicated TLS checker. package checker import ( sdk "git.happydns.org/checker-sdk-go/checker" ) const ObservationKeySRV sdk.ObservationKey = "srv_records" const ( protoTCP = "tcp" protoUDP = "udp" ) type SRVRecord struct { Service string `json:"service"` Proto string `json:"proto"` Owner string `json:"owner"` Target string `json:"target"` Port uint16 `json:"port"` Priority uint16 `json:"priority"` Weight uint16 `json:"weight"` IsNullTarget bool `json:"isNullTarget,omitempty"` // target == "." means "no service" IsCNAME bool `json:"isCNAME,omitempty"` // RFC 2782: MUST NOT be CNAME CNAMEChain []string `json:"cnameChain,omitempty"` Addresses []string `json:"addresses,omitempty"` ResolveError string `json:"resolveError,omitempty"` Probes []ProbeResult `json:"probes,omitempty"` } type ProbeResult struct { Address string `json:"address"` Proto string `json:"proto"` // Connected reports whether the probe should be treated as reachable. // For TCP this is a true handshake. For UDP, where silent drops are // indistinguishable from a working service, a timeout also sets // Connected=true and populates Error with an explanatory note: the // rule treats "no ICMP unreachable" as best-effort reachable. Connected bool `json:"connected"` LatencyMs float64 `json:"latencyMs,omitempty"` Error string `json:"error,omitempty"` } type SRVData struct { ServiceDomain string `json:"serviceDomain"` Records []SRVRecord `json:"records"` }