Adds a happyDomain checker that probes STUN/TURN servers end-to-end:
DNS/SRV discovery, UDP/TCP/TLS/DTLS dial, STUN binding + reflexive-addr
sanity, open-relay detection, authenticated TURN Allocate (long-term
creds or REST-API HMAC), public-relay check, CreatePermission + Send
round-trip through the relay, and optional ChannelBind.
Failing sub-tests carry a remediation string (`Fix`) that the HTML
report surfaces as a yellow headline callout and inline next to each
row. Mapping covers the most common coturn misconfigurations
(external-ip, relay-ip, lt-cred-mech, min-port/max-port, cert issues,
401 nonce drift, 441/442/486/508 allocation errors).
Implements sdk.EndpointDiscoverer (checker/discovery.go): every
stuns:/turns:/DTLS endpoint observed during Collect is published as a
DiscoveredEndpoint{Type: "tls"|"dtls"} so a downstream TLS checker can
verify certificates without re-parsing the observation.
Backed by pion/stun/v3 + pion/turn/v4 + pion/dtls/v3; SDK pinned to a
local replace until the EndpointDiscoverer interface ships in a tagged
release.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
47 lines
1.3 KiB
Go
47 lines
1.3 KiB
Go
package checker
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
sdk "git.happydns.org/checker-sdk-go/checker"
|
|
)
|
|
|
|
// DiscoverEndpoints implements sdk.EndpointDiscoverer. It publishes every
|
|
// TLS/DTLS endpoint seen during collection so a downstream TLS checker can
|
|
// verify certificates without re-parsing the observation.
|
|
//
|
|
// stuns:/turns: speak TLS immediately after the TCP handshake (no STARTTLS),
|
|
// so we emit Type="tls". DTLS endpoints are published as Type="dtls" — an
|
|
// open-string convention, consumed by DTLS-aware probes.
|
|
func (p *stunTurnProvider) DiscoverEndpoints(data any) ([]sdk.DiscoveredEndpoint, error) {
|
|
d, ok := data.(*StunTurnData)
|
|
if !ok {
|
|
return nil, fmt.Errorf("unexpected data type %T", data)
|
|
}
|
|
seen := make(map[string]struct{})
|
|
var out []sdk.DiscoveredEndpoint
|
|
for _, ep := range d.Endpoints {
|
|
if !ep.Endpoint.Secure {
|
|
continue
|
|
}
|
|
epType := "tls"
|
|
if ep.Endpoint.Transport == TransportDTLS {
|
|
epType = "dtls"
|
|
}
|
|
key := fmt.Sprintf("%s|%s|%d", epType, ep.Endpoint.Host, ep.Endpoint.Port)
|
|
if _, dup := seen[key]; dup {
|
|
continue
|
|
}
|
|
seen[key] = struct{}{}
|
|
out = append(out, sdk.DiscoveredEndpoint{
|
|
Type: epType,
|
|
Host: ep.Endpoint.Host,
|
|
Port: ep.Endpoint.Port,
|
|
Meta: map[string]any{
|
|
"source": "stun-turn",
|
|
"uri": ep.Endpoint.URI,
|
|
},
|
|
})
|
|
}
|
|
return out, nil
|
|
}
|