package checker import ( "context" "fmt" "strings" sdk "git.happydns.org/checker-sdk-go/checker" ) // Rules returns the list of CheckRules exposed by the STUN/TURN checker. // Each concern is its own rule (SRV for STUN, SRV for TURN, STUN // binding, TURN open-relay probe, TURN authenticated allocation, relay // echo, TLS transport, IPv6 coverage, …) so the UI can show a granular // status instead of a single aggregated one. func Rules() []sdk.CheckRule { return []sdk.CheckRule{ &discoveryRule{}, &srvStunRule{}, &srvTurnRule{}, &dialRule{}, &stunBindingRule{}, &stunReflexivePublicRule{}, &stunLatencyRule{}, &turnOpenRelayRule{}, &turnAuthRule{}, &turnRelayPublicRule{}, &turnRelayEchoRule{}, &turnTLSTransportRule{}, &ipv6CoverageRule{}, } } // loadData fetches the observation; on error returns a CheckState that // callers should emit directly. func loadData(ctx context.Context, obs sdk.ObservationGetter) (*StunTurnData, *sdk.CheckState) { var data StunTurnData if err := obs.Get(ctx, ObservationKeyStunTurn, &data); err != nil { return nil, &sdk.CheckState{ Status: sdk.StatusError, Message: fmt.Sprintf("failed to get STUN/TURN observation: %v", err), Code: "stun_turn.observation_error", } } return &data, nil } func passState(code, msg string) sdk.CheckState { return sdk.CheckState{Status: sdk.StatusOK, Message: msg, Code: code} } func skippedState(code, msg string) sdk.CheckState { return sdk.CheckState{Status: sdk.StatusUnknown, Message: msg, Code: code} } func epSubject(ep Endpoint) string { if ep.URI != "" { return ep.URI } return fmt.Sprintf("%s:%d/%s", ep.Host, ep.Port, ep.Transport) } // hasTURNEndpoint reports whether the observation contains at least one // TURN endpoint (excluding STUN-only endpoints). func hasTURNEndpoint(data *StunTurnData) bool { for _, ep := range data.Endpoints { if ep.Endpoint.IsTURN { return true } } return false } // joinMsg concatenates non-empty parts with ": " between them. func joinMsg(parts ...string) string { out := make([]string, 0, len(parts)) for _, p := range parts { if strings.TrimSpace(p) != "" { out = append(out, p) } } return strings.Join(out, ": ") }