// 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 import ( "context" "fmt" "strings" sdk "git.happydns.org/checker-sdk-go/checker" ) type ruleTCPReachable struct{} func RuleTCPReachable() sdk.CheckRule { return &ruleTCPReachable{} } func (ruleTCPReachable) Name() string { return "srv_tcp_reachable" } func (ruleTCPReachable) Description() string { return "Every TCP SRV target:port accepts a TCP connection." } func (ruleTCPReachable) Evaluate(ctx context.Context, obs sdk.ObservationGetter, _ sdk.CheckerOptions) []sdk.CheckState { d, cs := getData(ctx, obs) if cs != nil { return []sdk.CheckState{*cs} } total, ok, failed := countProbeResults(d, protoTCP) if total == 0 { return []sdk.CheckState{{Status: sdk.StatusUnknown, Code: "srv_tcp_na", Message: "No TCP targets to test."}} } if ok == total { return []sdk.CheckState{{Status: sdk.StatusOK, Code: "srv_tcp_ok", Message: fmt.Sprintf("All %d TCP target(s) reachable.", total)}} } if ok == 0 { return []sdk.CheckState{{Status: sdk.StatusCrit, Code: "srv_tcp_all_down", Message: fmt.Sprintf("All %d TCP target(s) unreachable: %s", total, strings.Join(failed, "; "))}} } return []sdk.CheckState{{Status: sdk.StatusWarn, Code: "srv_tcp_partial", Message: fmt.Sprintf("%d/%d TCP target(s) unreachable: %s", total-ok, total, strings.Join(failed, "; "))}} } type ruleUDPReachable struct{} func RuleUDPReachable() sdk.CheckRule { return &ruleUDPReachable{} } func (ruleUDPReachable) Name() string { return "srv_udp_reachable" } func (ruleUDPReachable) Description() string { return "UDP SRV targets do not return ICMP port-unreachable." } func (ruleUDPReachable) Evaluate(ctx context.Context, obs sdk.ObservationGetter, _ sdk.CheckerOptions) []sdk.CheckState { d, cs := getData(ctx, obs) if cs != nil { return []sdk.CheckState{*cs} } total, ok, failed := countProbeResults(d, protoUDP) if total == 0 { return []sdk.CheckState{{Status: sdk.StatusUnknown, Code: "srv_udp_na", Message: "No UDP targets to test."}} } if ok == total { return []sdk.CheckState{{Status: sdk.StatusOK, Code: "srv_udp_ok", Message: fmt.Sprintf("All %d UDP target(s) reachable.", total)}} } return []sdk.CheckState{{Status: sdk.StatusWarn, Code: "srv_udp_issue", Message: fmt.Sprintf("%d/%d UDP target(s) reported port unreachable: %s", total-ok, total, strings.Join(failed, "; "))}} }