Initial commit
This commit is contained in:
commit
f6f102079f
19 changed files with 2222 additions and 0 deletions
159
checker/types.go
Normal file
159
checker/types.go
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
// Package checker implements the SIP / VoIP server checker for
|
||||
// happyDomain.
|
||||
//
|
||||
// It probes a domain's SIP deployment end-to-end (NAPTR + SRV
|
||||
// resolution per RFC 3263, reachability on UDP / TCP / TLS, SIP
|
||||
// OPTIONS ping per RFC 3261) and reports actionable findings.
|
||||
//
|
||||
// TLS certificate chain / SAN / expiry / cipher posture is
|
||||
// intentionally out of scope — the forthcoming checker-tls covers
|
||||
// that. SIPS endpoints are published as "tls" discovery endpoints
|
||||
// so checker-tls can probe them; its findings are folded back into
|
||||
// this report via GetRelated("tls_probes"). See
|
||||
// happydomain3/docs/checker-discovery-endpoint.md.
|
||||
package checker
|
||||
|
||||
import (
|
||||
sdk "git.happydns.org/checker-sdk-go/checker"
|
||||
)
|
||||
|
||||
const ObservationKeySIP sdk.ObservationKey = "sip"
|
||||
|
||||
// Transport identifies one of the three SIP transports we probe.
|
||||
type Transport string
|
||||
|
||||
const (
|
||||
TransportUDP Transport = "udp"
|
||||
TransportTCP Transport = "tcp"
|
||||
TransportTLS Transport = "tls" // SIPS, direct TLS on connect
|
||||
)
|
||||
|
||||
// SIPData is the full observation stored per run.
|
||||
type SIPData struct {
|
||||
Domain string `json:"domain"`
|
||||
RunAt string `json:"run_at"`
|
||||
NAPTR []NAPTRRecord `json:"naptr,omitempty"`
|
||||
SRV SRVLookup `json:"srv"`
|
||||
Endpoints []EndpointProbe `json:"endpoints"`
|
||||
Coverage Coverage `json:"coverage"`
|
||||
Issues []Issue `json:"issues"`
|
||||
}
|
||||
|
||||
// NAPTRRecord is a subset of a NAPTR record enough to reason about
|
||||
// SIP service resolution.
|
||||
type NAPTRRecord struct {
|
||||
Service string `json:"service"` // e.g. "SIP+D2T"
|
||||
Regexp string `json:"regexp,omitempty"`
|
||||
Replacement string `json:"replacement,omitempty"`
|
||||
Flags string `json:"flags,omitempty"`
|
||||
Order uint16 `json:"order"`
|
||||
Preference uint16 `json:"preference"`
|
||||
}
|
||||
|
||||
// SRVLookup groups the SRV records found per transport plus per-prefix
|
||||
// lookup errors and a fallback marker when no SRV was published.
|
||||
type SRVLookup struct {
|
||||
UDP []SRVRecord `json:"udp,omitempty"`
|
||||
TCP []SRVRecord `json:"tcp,omitempty"`
|
||||
SIPS []SRVRecord `json:"sips,omitempty"`
|
||||
// Errors per-set, keyed by SRV prefix ("_sip._udp.", …).
|
||||
Errors map[string]string `json:"errors,omitempty"`
|
||||
// FallbackProbed is true when no SRV was published and we probed
|
||||
// the bare domain on 5060 / 5061.
|
||||
FallbackProbed bool `json:"fallback_probed,omitempty"`
|
||||
}
|
||||
|
||||
// SRVRecord captures one SRV plus the addresses it resolves to.
|
||||
type SRVRecord struct {
|
||||
Target string `json:"target"`
|
||||
Port uint16 `json:"port"`
|
||||
Priority uint16 `json:"priority"`
|
||||
Weight uint16 `json:"weight"`
|
||||
IPv4 []string `json:"ipv4,omitempty"`
|
||||
IPv6 []string `json:"ipv6,omitempty"`
|
||||
}
|
||||
|
||||
// EndpointProbe is the result of probing one (transport, target, address).
|
||||
type EndpointProbe struct {
|
||||
Transport Transport `json:"transport"`
|
||||
SRVPrefix string `json:"srv_prefix"`
|
||||
Target string `json:"target"`
|
||||
Port uint16 `json:"port"`
|
||||
Address string `json:"address"`
|
||||
IsIPv6 bool `json:"is_ipv6,omitempty"`
|
||||
|
||||
Reachable bool `json:"reachable"`
|
||||
ReachableErr string `json:"reachable_err,omitempty"`
|
||||
|
||||
TLSVersion string `json:"tls_version,omitempty"`
|
||||
TLSCipher string `json:"tls_cipher,omitempty"`
|
||||
|
||||
OptionsSent bool `json:"options_sent,omitempty"`
|
||||
OptionsStatus string `json:"options_status,omitempty"` // e.g. "200 OK"
|
||||
OptionsRawCode int `json:"options_raw_code,omitempty"`
|
||||
OptionsRTTMs int64 `json:"options_rtt_ms,omitempty"`
|
||||
ServerHeader string `json:"server_header,omitempty"`
|
||||
UserAgent string `json:"user_agent,omitempty"`
|
||||
AllowMethods []string `json:"allow_methods,omitempty"`
|
||||
ContactURI string `json:"contact_uri,omitempty"`
|
||||
|
||||
ElapsedMS int64 `json:"elapsed_ms"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// OK reports whether this probe counts as a working SIP endpoint
|
||||
// (reachable + 2xx answer to OPTIONS).
|
||||
func (e EndpointProbe) OK() bool {
|
||||
return e.Reachable && e.OptionsSent && e.OptionsRawCode >= 200 && e.OptionsRawCode < 300
|
||||
}
|
||||
|
||||
// Coverage is a roll-up of the per-endpoint results.
|
||||
type Coverage struct {
|
||||
HasIPv4 bool `json:"has_ipv4"`
|
||||
HasIPv6 bool `json:"has_ipv6"`
|
||||
WorkingUDP bool `json:"working_udp"`
|
||||
WorkingTCP bool `json:"working_tcp"`
|
||||
WorkingTLS bool `json:"working_tls"`
|
||||
AnyWorking bool `json:"any_working"`
|
||||
}
|
||||
|
||||
// Issue is a structured finding. The rule reduces issues to a worst
|
||||
// severity; the report renders them as an actionable fix list.
|
||||
type Issue struct {
|
||||
Code string `json:"code"`
|
||||
Severity string `json:"severity"` // "info" | "warn" | "crit"
|
||||
Message string `json:"message"`
|
||||
Fix string `json:"fix,omitempty"`
|
||||
Endpoint string `json:"endpoint,omitempty"`
|
||||
}
|
||||
|
||||
// Severities. Match checker-xmpp conventions for cross-checker
|
||||
// consistency.
|
||||
const (
|
||||
SeverityInfo = "info"
|
||||
SeverityWarn = "warn"
|
||||
SeverityCrit = "crit"
|
||||
)
|
||||
|
||||
// Issue codes. Keep short, stable, prefixed with "sip." so downstream
|
||||
// consumers can filter.
|
||||
const (
|
||||
CodeNoSRV = "sip.no_srv"
|
||||
CodeOnlyUDP = "sip.srv.only_udp"
|
||||
CodeNoTLS = "sip.srv.no_tls"
|
||||
CodeSRVServfail = "sip.srv.servfail"
|
||||
CodeSRVTargetUnresolved = "sip.srv.target_unresolvable"
|
||||
CodeNAPTRServfail = "sip.naptr.servfail"
|
||||
|
||||
CodeTCPUnreachable = "sip.tcp.unreachable"
|
||||
CodeUDPUnreachable = "sip.udp.unreachable"
|
||||
CodeTLSHandshake = "sip.tls.handshake_failed"
|
||||
CodeOptionsNoAnswer = "sip.options.no_response"
|
||||
CodeOptionsNon2xx = "sip.options.non_2xx"
|
||||
CodeOptionsNoAllow = "sip.options.no_allow"
|
||||
CodeOptionsNoInvite = "sip.options.no_invite"
|
||||
|
||||
CodeFallbackProbed = "sip.fallback_probed"
|
||||
CodeNoIPv6 = "sip.no_ipv6"
|
||||
CodeAllDown = "sip.all_endpoints_down"
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue