checker: implement ShareKey to mutualise TLS probes across targets
A TLS probe result depends only on the set of endpoints actually dialed and the probe knobs, never on which domain or service published them: the observation is a map keyed by each endpoint's contract Ref (host|port|effective SNI|STARTTLS|require). Implement sdk.ObservationSharer so the host dials a host:port once and serves every target that resolves to the same endpoint set, instead of re-handshaking per record. This is the highest-value case among the checkers, since dane, xmpp, srv, dav, … all funnel their endpoints into this single checker. The share key sorts the endpoint Refs and folds in the probe timeout and the cipher-enumeration flag, since both change what is collected (a tighter timeout can fail a slow handshake; enumeration adds the Enum block). An empty or unparseable entry set yields "" so the host falls back to per-target caching.
This commit is contained in:
parent
7c2f4bfbb5
commit
03af5615ae
4 changed files with 131 additions and 4 deletions
|
|
@ -2,8 +2,12 @@ package checker
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"log"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
|
@ -83,3 +87,43 @@ dispatch:
|
|||
CollectedAt: time.Now(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ShareKey implements sdk.ObservationSharer. A TLS probe result depends only on
|
||||
// the set of endpoints actually dialed and the probe knobs, never on which
|
||||
// domain or service published them: the observation is a map keyed by each
|
||||
// endpoint's contract Ref (host|port|effective SNI|STARTTLS|require), so two
|
||||
// targets that resolve to the same endpoint set produce identical probes. This
|
||||
// lets the host dial a host:port once and serve every target that points at it
|
||||
// instead of re-handshaking per record — the highest-value case here, since
|
||||
// dane, xmpp, srv, dav, … all funnel endpoints into this single checker.
|
||||
//
|
||||
// The probe timeout and cipher-enumeration flag are folded in because they
|
||||
// change what is collected (a tighter timeout can fail a slow handshake;
|
||||
// enumeration adds the Enum block). Inputs that yield no probable endpoint
|
||||
// return "" so the host falls back to the default per-target caching.
|
||||
func (p *tlsProvider) ShareKey(opts sdk.CheckerOptions) (string, error) {
|
||||
raw, ok := sdk.GetOption[[]sdk.DiscoveryEntry](opts, OptionEndpoints)
|
||||
if !ok {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
entries, _ := contract.ParseEntries(raw)
|
||||
if len(entries) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
refs := make([]string, 0, len(entries))
|
||||
for _, e := range entries {
|
||||
refs = append(refs, e.Ref)
|
||||
}
|
||||
sort.Strings(refs)
|
||||
|
||||
timeoutMs := sdk.GetIntOption(opts, OptionProbeTimeoutMs, DefaultProbeTimeoutMs)
|
||||
if timeoutMs <= 0 {
|
||||
timeoutMs = DefaultProbeTimeoutMs
|
||||
}
|
||||
enumerate := sdk.GetBoolOption(opts, OptionEnumerateCiphers, false)
|
||||
|
||||
h := sha256.Sum256(fmt.Appendf(nil, "%d|%t|%s", timeoutMs, enumerate, strings.Join(refs, ",")))
|
||||
return "tls:" + hex.EncodeToString(h[:8]), nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue