fix(descriptor): rebuild SDP that Firefox accepts; release v5.8.1
Live cross-browser testing found three defects in the SBQ2 SDP template, all
invisible to Chrome and all fatal to Firefox.
The candidate lines omitted raddr/rport on srflx and relay candidates. RFC 8839
section 5.1 makes rel-addr and rel-port mandatory for non-host candidates even
though ICE never reads them; Chrome tolerates the omission and Firefox drops the
candidate. Relay-only connections to Firefox failed 0/8 against 8/8 for the
browser's own SDP. The STUN and TURN profiles hid it because a host pair
connected instead -- the relay candidates were never actually needed there.
The template also advertised ice-options:trickle without ever closing the
candidate set, though a descriptor is a complete one-shot set with no channel to
trickle over, and hard-coded the m= port and c= line to the 9 / 0.0.0.0 null
default candidate, which is the trickle convention for "nothing gathered yet".
Both are now correct: no trickle, an explicit a=end-of-candidates, and the most
publicly reachable candidate as the default.
All three are serializer-side and cost zero descriptor bytes; sizes are
unchanged at 98-149 bytes, QR version 6-8. Verified 48/48 across all 16
combinations of {Chrome, Firefox} squared and four network profiles, with every
relay-only pair now connecting over the relay.
This commit is contained in:
+29
-3
@@ -83,9 +83,35 @@ Foundation and priority are **not** transmitted. Priority only orders
|
||||
connectivity checks, and each peer computes its own local priorities anyway; the
|
||||
serializer re-derives RFC 8445 §5.1.2.1 values with `localPref = 65535 - index`,
|
||||
so the sender's ordering intent survives at zero cost. Foundations are grouped by
|
||||
kind and transport, satisfying both halves of §5.1.1.3. `raddr`/`rport` are
|
||||
diagnostics that ICE does not consume, and `generation`/`network-cost` are Chrome
|
||||
extensions.
|
||||
kind and transport, satisfying both halves of §5.1.1.3. `generation` and
|
||||
`network-cost` are Chrome extensions and are dropped.
|
||||
|
||||
### What the serializer must emit anyway
|
||||
|
||||
Three things are not in the descriptor but must appear in the rebuilt SDP. All
|
||||
three are constants or derived from data already present, so none costs a byte —
|
||||
and each was found by a live cross-browser test rather than by reading the spec.
|
||||
|
||||
- **`raddr` / `rport` on every srflx, prflx and relay candidate.** RFC 8839 §5.1
|
||||
makes rel-addr and rel-port mandatory for non-host candidates even though ICE's
|
||||
own algorithm never reads them. An earlier draft left them out as
|
||||
"diagnostics". Chrome accepts such a line; **Firefox drops the candidate.**
|
||||
Measured: relay-only connections to Firefox went 0/8 while the browser's own
|
||||
SDP went 8/8, and the fault was invisible in the STUN and TURN profiles because
|
||||
a host pair connected instead. `0.0.0.0`/`0` (or `::`/`0`) is emitted — the
|
||||
same placeholder Chrome uses when it has no base address to disclose.
|
||||
|
||||
- **No `a=ice-options:trickle`, and an explicit `a=end-of-candidates`.** A
|
||||
descriptor is a complete one-shot candidate set; there is no channel to trickle
|
||||
over. Advertising trickle promises candidates that can never arrive and leaves
|
||||
the peer waiting for them.
|
||||
|
||||
- **A real default candidate on the `m=` port and `c=` line.** `m=application 9`
|
||||
with `c=IN IP4 0.0.0.0` is the trickle convention for "nothing gathered yet"
|
||||
(RFC 8840 §4.1) and is simply false here. The serializer advertises the most
|
||||
publicly reachable candidate — relay, then srflx, then host, which is the order
|
||||
Chrome uses and the reverse of ICE priority — falling back to the null form
|
||||
only when every candidate is mDNS, which is also what Chrome does.
|
||||
|
||||
### TLV extension area
|
||||
|
||||
|
||||
Reference in New Issue
Block a user