Conversation
…ransport Allocate derived REQUESTED-TRANSPORT from the transport used to reach the server, so a client talking to its server over TCP asked for an RFC 6062 TCP allocation. RFC 8656 §7.1 keeps the two apart: REQUESTED-TRANSPORT names what the allocation relays, and a client on TCP normally still wants a UDP relay. ClientConfig gains `requested_transport`, defaulting to UDP, used by the Allocate and by its authenticated retry. Callers that set nothing keep what they had; callers that build ClientConfig as a struct literal need the new field, which the in-tree examples and tests now set. Refs webrtc-rs/webrtc#848.
…ages Over TCP, TURN sends its messages back to back with no framing of its own (RFC 8656 §12.5): a STUN message is 20 bytes plus its length field, a ChannelData message 4 bytes plus its length rounded up to a multiple of 4. tcp_framing is RFC 4571's length prefix, which is ICE-TCP's framing and not TURN's, so a host reading a TURN stream had nothing to split it with. TurnStreamDecoder has TcpFrameDecoder's shape — push bytes, pop whole messages — so a host can hold either per stream. Messages come out as they were on the wire, padding included; a first byte that starts neither kind is an error, since a stream has nowhere to resynchronise. Refs webrtc-rs/webrtc#848.
Transactions retransmitted on every transport: 200 ms doubling to 1.6 s, seven requests, a timeout after about eight seconds. Over a reliable transport RFC 8489 §6.2.2 has the client send once and wait Ti, 39.5 s — TCP is already retransmitting underneath, and repeating the request on top only sends the server duplicates of it. A transaction over anything that is not UDP now has one deadline at Ti and no retransmission; passing it reports TransactionTimeout as before. UDP is unchanged. Kept as its own commit: it is not needed for TURN over TCP to work, only for it to behave as the RFC asks. Refs webrtc-rs/webrtc#848.
This was referenced Sep 22, 2026
mnaza
added a commit
to mnaza/relaysight
that referenced
this pull request
Sep 22, 2026
…, install gateways from signed releases Everything since the last sync, in one commit; this clone keeps its own history. A revoked gateway's cameras can be retired from the roster: a tombstone rather than a delete, so recordings still play and a gateway reporting the camera again brings it back with its history. The action refuses while the gateway is still in service. Each camera can have its own credentials, encrypted on the gateway under the same key as its identity and entered with `vms-gateway credentials`, which reads the password from stdin. The shared CAMERA_USERNAME and CAMERA_PASSWORD stay as the fallback. Gateways install on a site box from a signed release: install.sh verifies the Ed25519-signed manifest before touching anything and sets up a hardened systemd service with a daily self-update. An update keeps a new binary only once the API has accepted a heartbeat from it, and rolls back otherwise. make check-installer runs all of it on a real systemd. Retina now comes from a pinned fork carrying the fix for decimal SSRCs, until upstream releases it. docs/INSTALL-GATEWAY.md says what is checked and what is not; no release has been cut yet, because the release key does not exist yet. Plus the upstream design for TURN over TCP in webrtc-rs, which is open as webrtc-rs/rtc#254 and webrtc-rs/webrtc#907.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #254 +/- ##
==========================================
- Coverage 87.85% 87.81% -0.04%
==========================================
Files 499 500 +1
Lines 72540 72670 +130
==========================================
+ Hits 63728 63816 +88
- Misses 8812 8854 +42
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
rainliu
requested changes
Sep 26, 2026
rainliu
left a comment
Member
There was a problem hiding this comment.
don't add the public field
Adding requested_transport to ClientConfig, whose fields are all public, breaks anyone who builds it as a struct literal. The field doesn't earn that break:
- The only other value is useless. The field's own doc says asking for TCP "requests an RFC 6062 TCP allocation instead, which this client does not implement." I checked: rtc-turn has no Connect or ConnectionBind; only the constants exist in rtc-stun. So requested_transport: TCP just gets an allocation the client can't use.
- Hard-coding UDP gives the same fix with no API change. Both Allocate requests send PROTO_UDP, with a comment citing RFC 8656 §7.1 and noting that RFC 6062 isn't implemented. I applied that on top of the PR:
- rtc-turn passes 46 tests (the default-value test goes with the field);
- the examples build;
- ClientConfig, the examples and the doc example are unchanged from master.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of webrtc-rs/webrtc#848 — the
rtchalf. Thewebrtchalf (the relayer,RTCTcpTransport, the driver) follows as a draft PR that bumps this submodule.As agreed on the issue: TCP first, TLS as a follow-up.
What changes
feat(turn): request the relay transport independently of the server transport.allocate()and its authenticated retry derived REQUESTED-TRANSPORT fromtransport_protocol, so a client reaching its server over TCP asked for an RFC 6062 TCP allocation. RFC 8656 §7.1 keeps the two apart.ClientConfiggainsrequested_transport, defaulting to UDP.This is a break for callers that build
ClientConfigas a struct literal. The published baseline is 0.21.0 and master is 1.0.0-alpha.1, so the semver job allows it. The in-tree examples and tests set the new field. One question for you: shouldClientConfigbecome#[non_exhaustive]before 1.0? TLS will probably want a field of its own, and that would be the same break again.feat(shared):TurnStreamDecoder. Over a stream, TURN's STUN and ChannelData messages arrive back to back with no framing of their own (RFC 8656 §12.5).tcp_framingis RFC 4571, which is ICE-TCP's framing, so there was nothing to split a TURN stream with. The new decoder hasTcpFrameDecoder's shape — push bytes, pop whole messages — so a host can hold either one per stream.fix(turn): do not retransmit requests over TCP. Transactions retransmitted on every transport. RFC 8489 §6.2.2 says to send once over a reliable transport and wait Ti = 39.5 s; transactions over anything that is not UDP now do that. It's a separate commit, and TCP works without it, so drop it if you'd rather take it separately.Tests
rtc-turn: an Allocate over TCP carries REQUESTED-TRANSPORT UDP, and the default is unchanged. A request over TCP is sent once and times out at Ti, while UDP still retransmits.rtc-shared: the decoder handles STUN, ChannelData with and without padding, coalesced and byte-by-byte input, and invalid first bits. There is a doctest too.rtc-turnpasses 47 tests plus its doctest.One unrelated note:
rtc-sctp'stest_assoc_reset_close_one_wayfails for me under a fullcargo test --workspacerun, and passes on its own. It does the same on the untouched base (784e464), so it isn't this change — I mention it in case it's news.Refs webrtc-rs/webrtc#848.