Skip to content

0.12.1 — a dead STUN server, and a panel that shows its evidence

Latest

Choose a tag to compare

@NiKrause NiKrause released this 29 Aug 09:42
· 2 commits to main since this release
5f6d28d

0.12.1 — a dead STUN server, and a panel that shows its evidence

Upgrade for one reason that is not cosmetic: since 0.12.0 every consumer of
this library has been asking an endpoint that answers nothing.

2606:4700:4700::1111 sat in DEFAULT_RTC_CONFIGURATION as Cloudflare's IPv6
STUN server. It is their public resolver — the IPv6 twin of 1.1.1.1 — and
answers no binding request at all. Their STUN service is 2606:4700:49::.
Measured against each with a real peer connection: the old address returns no
candidate, the correct one answers immediately.

The failure cost no error, no delay and no log line, which is how it survived a
release. It only halved the evidence behind an IPv6 verdict — and a verdict that
is wrong in the quiet direction looks exactly like a verdict that is right. A
test now asserts that no address in the list is a resolver, and that there is one
IPv6 literal per named server, which is the whole reason the literals exist.

Everything else here came out of a single field report: a phone on mobile data
whose IPv6 chip said none while the panel below it listed two global IPv6
addresses.

The addresses behind the verdict

probeNetwork gathered every candidate and kept only a set of ports. It now
returns them, and <qr-status> and <qr-intro> show them in a <details> with
a Check again button.

A verdict answers will this work. The list answers what changed, which is the
question after switching a VPN on and one no summary can answer. A second probe
marks what is new and keeps what vanished, struck through — a row that disappears
between two probes is the most interesting thing the panel can show.

It is closed by default, and that is a safety property rather than a tidiness
one: a reflexive candidate carries the public IP of whoever is looking at the
screen.

Each row names the protocol as well as the origin. The same address is gathered
once over UDP and once over TCP, and the TCP one carries port 9 — the discard
port ICE uses as a placeholder for an active TCP candidate. Without the protocol
those read as one address duplicated with a nonsense port.

unproven — an address nobody reached is untested, not absent

The reported case: a device holding two global IPv6 prefixes, with no reflexive
IPv6 candidate. None was wrong — the address is there and is offered to a
peer. Usable would have been wrong too: WebRTC's data channel is DTLS over
UDP and the ICE checks are UDP, so if IPv6 UDP does not leave a network the host
candidate is unusable as well, and the TCP candidates a browser gathers are
active-only and cannot pair with another browser's.

What cannot be told apart from inside the browser is that case from those
particular STUN servers being unreachable over IPv6 while everything else is
fine
. Only one is fatal and they look identical. So the row is amber, states
both readings instead of picking one, and ranks with symmetric — an untested
IPv6 never turns the summary green.

The verdict has never filtered candidates. A global IPv6 address is packed
into the compact payload and carried in the full one whatever colour the row is.
The panel advises; ICE still offers everything it gathered.

Also

readIceCandidates(sdp) the candidates with their addresses — describeIce reduces them to counts, which is right for a status line and wrong for anybody asking which network was this
probeNetworkcandidates { type, protocol, address, port, family }, where family is v4, v6 or mdns
<qr-intro>.recheck() open() measures once and remembers, which is wrong for a button somebody presses after changing their network
new string keys the candidate list, shared by both elements from one table so a translation cannot drift between the two panels

The IPv6 verdict also distinguishes three cases where it previously named two
possibilities and helped with neither: a global IPv6 host candidate present (the
address is not the problem), host addresses hidden behind mDNS stand-ins (nothing
can be read, and the ambiguous sentence is the honest one), or neither — the only
case where "get IPv6" is the advice.

Upgrade cost

No breaking changes. unproven is a new state, and a consumer's own string table
will not have a label for it; mergeStrings falls back to the English default,
so that row reads untested in an otherwise translated panel until the key is
added. That is the whole of it.

157 unit tests, 178 demo specs across Chromium, Firefox and WebKit.