app: show what the server reports as facts, not as inputs

The settings card offered three editable boxes and said nothing about the
server itself — which addresses a test will actually use, on which ports,
what it can measure. That is the part a person checks before trusting a
result, and "which address did this come from" is precisely the question
a report leaves open.

The server now publishes it. The profile's targets carried one IPv4 and a
TODO; it reports both families and both alternates, derived from the UDP
listen spec rather than configured separately, so the list cannot drift
from what is actually bound. No reservation means no alternate is
claimed: announcing a second address as the RFC 5780 alternate when none
was set aside would promise a redirect the server will not send.

The app renders them read-only, in a panel visibly distinct from the
fields above. An editable box that changes nothing is worse than no box,
and these are facts to read rather than settings to apply.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
mrambossek
2026-08-02 08:14:42 +02:00
co-authored by Claude Opus 5
parent fe4ec23ba1
commit c4f2a10790
8 changed files with 207 additions and 8 deletions
+33 -7
View File
@@ -80,6 +80,10 @@ type Server struct {
CanaryQueries func(sessionPrefix string) any
// CanaryZone is surfaced in the profile so the app knows what to query.
CanaryZone string
// The addresses this server can be measured on. The "_alt" pair is the second address
// RFC 5780 behaviour discovery redirects to, and the one reserved from services so that
// nothing answering there is itself a measurement.
IP4, IP6, IP4Alt, IP6Alt string
// ProvenGood reports the server's self-test signal (may be nil). Surfaced
// in the profile so a client can trust — or skip — MTU tests: if the
// server's own egress isn't full-MTU, client MTU results measure the
@@ -614,13 +618,7 @@ func (s *Server) profile(w http.ResponseWriter, r *http.Request) {
// modified builds and gives clients provenance for the measurement.
"source_url": "", // TODO: stamp from build metadata
"capabilities": s.Capabilities,
"targets": []map[string]any{{
"id": s.Name,
"ip4": host, // TODO: explicit configured addresses, v6, second STUN addr
"udp_port": s.UDPPort,
"tcp_port": s.TCPPort,
"stun_port": s.StunPort,
}},
"targets": []map[string]any{s.target(host)},
"pins": []string{"pin-sha256:" + s.PinB64},
"next_pins": []string{},
"canary_zone": s.CanaryZone,
@@ -838,6 +836,34 @@ func EnrollmentURI(publicURL, pinB64, token string) string {
"&t=" + url.QueryEscape(token)
}
// target describes where this server can be measured, so a client can say which address a result
// came from instead of "the server".
//
// The alternates matter as much as the primaries: RFC 5780 behaviour discovery needs a second
// address to redirect to, and an operator reading a report needs to know which of their addresses
// a finding refers to. [fallback] is used only when nothing was configured explicitly, so a server
// that has not been told its own addresses still answers with something usable.
func (s *Server) target(fallback string) map[string]any {
t := map[string]any{
"id": s.Name,
"udp_port": s.UDPPort,
"tcp_port": s.TCPPort,
"stun_port": s.StunPort,
}
ip4 := s.IP4
if ip4 == "" {
ip4 = fallback
}
for k, v := range map[string]string{
"ip4": ip4, "ip6": s.IP6, "ip4_alt": s.IP4Alt, "ip6_alt": s.IP6Alt,
} {
if v != "" {
t[k] = v
}
}
return t
}
// upstreamJSON renders the upstream tally with the derived figures already computed, so every
// consumer does not have to repeat (and risk fumbling) the same arithmetic.
func upstreamJSON(sess *session.Session) map[string]any {