Skip to content

Release packages - #1327

Merged
cloudwebrtc merged 1 commit into
mainfrom
knope/release
Aug 26, 2026
Merged

cloudwebrtc merged 1 commit into
mainfrom
knope/release

Conversation

@knope-bot

@knope-bot knope-bot Bot commented Aug 13, 2026 •

Copy link
Copy Markdown
Contributor

Important

Merging this pull request will create these releases

webrtc-sys-build 0.3.19 (2026-08-25)

Fixes

fix: bump libwebrtc to webrtc-b9233c3-2 so TURN/TLS can use the OS trust store

WebRTC validates TURN/TLS against a small set of anchors compiled into
rtc_base/ssl_roots.h, generated in 2023 from Google's own PKI list. It has no
Amazon, Starfield Services or ISRG roots, so a relay-only connection to a TURN
server fronted by AWS ACM or Let's Encrypt times out with unknown_ca even
though the host OS trusts the chain.

This build picks up webrtc-sdk/webrtc#277, which falls back to the operating
system's trust store when the built-in anchors yield no path. It sits in
rtc_base below every SDK, so the C++ API that webrtc-sys binds is covered
without any Rust-side change.

livekit-api 0.6.4 (2026-08-25)

Fixes

Moves access-token generation and verification into a new livekit-token crate.

livekit_api::access_token::* continues to resolve to the same types via a
re-export, so no consumer changes are needed.

Also fixes the services-tokio and services-async features, which used the
access-token types without declaring the access-token feature. Building with
--no-default-features --features services-tokio previously failed to compile.

yuv-sys 0.3.15 (2026-08-25)

Fixes

  • yuv-sys: fail with an actionable error when the libyuv submodule is not initialized

libwebrtc 0.3.46 (2026-08-25)

Features

feat: enable WARP (SPED + SNAP) by default, gated by the server

WARP is now always enabled on the client and negotiated with the SFU: SPED
(DTLS-in-STUN) via the WebRTC-IceHandshakeDtls field trial, and SNAP
(SCTP-INIT-in-SDP) via the RtcConfiguration.enable_sctp_snap field. When the
server does not enable WARP it is not advertised and the connection falls back to
plain DTLS/SCTP, so there is no client-side toggle.

BREAKING CHANGE: libwebrtc::RtcConfiguration is now #[non_exhaustive] and has a
new enable_sctp_snap field. Construct it from RtcConfiguration::default() and set
the fields you need instead of a struct literal.

Fixes

fix: bump libwebrtc to webrtc-b9233c3-2 so TURN/TLS can use the OS trust store

WebRTC validates TURN/TLS against a small set of anchors compiled into
rtc_base/ssl_roots.h, generated in 2023 from Google's own PKI list. It has no
Amazon, Starfield Services or ISRG roots, so a relay-only connection to a TURN
server fronted by AWS ACM or Let's Encrypt times out with unknown_ca even
though the host OS trusts the chain.

This build picks up webrtc-sdk/webrtc#277, which falls back to the operating
system's trust store when the built-in anchors yield no path. It sits in
rtc_base below every SDK, so the C++ API that webrtc-sys binds is covered
without any Rust-side change.

webrtc-sys 0.3.43 (2026-08-25)

Fixes

fix: bump libwebrtc to webrtc-b9233c3-2 so TURN/TLS can use the OS trust store

WebRTC validates TURN/TLS against a small set of anchors compiled into
rtc_base/ssl_roots.h, generated in 2023 from Google's own PKI list. It has no
Amazon, Starfield Services or ISRG roots, so a relay-only connection to a TURN
server fronted by AWS ACM or Let's Encrypt times out with unknown_ca even
though the host OS trusts the chain.

This build picks up webrtc-sdk/webrtc#277, which falls back to the operating
system's trust store when the built-in anchors yield no path. It sits in
rtc_base below every SDK, so the C++ API that webrtc-sys binds is covered
without any Rust-side change.

feat: enable WARP (SPED + SNAP) by default, gated by the server

WARP is now always enabled on the client and negotiated with the SFU: SPED
(DTLS-in-STUN) via the WebRTC-IceHandshakeDtls field trial, and SNAP
(SCTP-INIT-in-SDP) via the RtcConfiguration.enable_sctp_snap field. When the
server does not enable WARP it is not advertised and the connection falls back to
plain DTLS/SCTP, so there is no client-side toggle.

BREAKING CHANGE: libwebrtc::RtcConfiguration is now #[non_exhaustive] and has a
new enable_sctp_snap field. Construct it from RtcConfiguration::default() and set
the fields you need instead of a struct literal.

imgproc 0.3.20 (2026-08-25)

Fixes

  • yuv-sys: fail with an actionable error when the libyuv submodule is not initialized

livekit 0.8.4 (2026-08-25)

Features

feat: enable WARP (SPED + SNAP) by default, gated by the server

WARP is now always enabled on the client and negotiated with the SFU: SPED
(DTLS-in-STUN) via the WebRTC-IceHandshakeDtls field trial, and SNAP
(SCTP-INIT-in-SDP) via the RtcConfiguration.enable_sctp_snap field. When the
server does not enable WARP it is not advertised and the connection falls back to
plain DTLS/SCTP, so there is no client-side toggle.

BREAKING CHANGE: libwebrtc::RtcConfiguration is now #[non_exhaustive] and has a
new enable_sctp_snap field. Construct it from RtcConfiguration::default() and set
the fields you need instead of a struct literal.

Fixes

fix: bump libwebrtc to webrtc-b9233c3-2 so TURN/TLS can use the OS trust store

WebRTC validates TURN/TLS against a small set of anchors compiled into
rtc_base/ssl_roots.h, generated in 2023 from Google's own PKI list. It has no
Amazon, Starfield Services or ISRG roots, so a relay-only connection to a TURN
server fronted by AWS ACM or Let's Encrypt times out with unknown_ca even
though the host OS trusts the chain.

This build picks up webrtc-sdk/webrtc#277, which falls back to the operating
system's trust store when the built-in anchors yield no path. It sits in
rtc_base below every SDK, so the C++ API that webrtc-sys binds is covered
without any Rust-side change.

Moves access-token generation and verification into a new livekit-token crate.

livekit_api::access_token::* continues to resolve to the same types via a
re-export, so no consumer changes are needed.

Also fixes the services-tokio and services-async features, which used the
access-token types without declaring the access-token feature. Building with
--no-default-features --features services-tokio previously failed to compile.

livekit-common 0.1.2 (2026-08-25)

Fixes

  • Register the Bytes UniFFI custom type once in livekit-common and borrow it from each component with uniffi::use_remote_type!, so the converter is emitted once and the post-generation Swift workaround is no longer needed

livekit-token-source 0.1.2 (2026-08-25)

Features

  • Adds optional caching version of the token sources

livekit-token 0.1.1 (2026-08-25)

Fixes

Moves access-token generation and verification into a new livekit-token crate.

livekit_api::access_token::* continues to resolve to the same types via a
re-export, so no consumer changes are needed.

Also fixes the services-tokio and services-async features, which used the
access-token types without declaring the access-token feature. Building with
--no-default-features --features services-tokio previously failed to compile.

livekit-data-stream 0.1.3 (2026-08-25)

Fixes

livekit-datatrack 0.1.14 (2026-08-25)

Fixes

  • Register the Bytes UniFFI custom type once in livekit-common and borrow it from each component with uniffi::use_remote_type!, so the converter is emitted once and the post-generation Swift workaround is no longer needed

livekit-uniffi 0.1.9 (2026-08-25)

Fixes

  • differentiate signal connection errors correctly from timeouts - Add e2e signalling tests #1234 (@lukasIO)
  • Expose RemoteDataTrack.set_pipeline_options and RemoteDataTrackPipelineOptions (max_partial_frames) over UniFFI, matching the JS and Rust SDKs
  • Register the Bytes UniFFI custom type once in livekit-common and borrow it from each component with uniffi::use_remote_type!, so the converter is emitted once and the post-generation Swift workaround is no longer needed

Moves access-token generation and verification into a new livekit-token crate.

livekit_api::access_token::* continues to resolve to the same types via a
re-export, so no consumer changes are needed.

Also fixes the services-tokio and services-async features, which used the
access-token types without declaring the access-token feature. Building with
--no-default-features --features services-tokio previously failed to compile.

livekit-ffi 0.12.76 (2026-08-25)

Fixes

fix: bump libwebrtc to webrtc-b9233c3-2 so TURN/TLS can use the OS trust store

WebRTC validates TURN/TLS against a small set of anchors compiled into
rtc_base/ssl_roots.h, generated in 2023 from Google's own PKI list. It has no
Amazon, Starfield Services or ISRG roots, so a relay-only connection to a TURN
server fronted by AWS ACM or Let's Encrypt times out with unknown_ca even
though the host OS trusts the chain.

This build picks up webrtc-sdk/webrtc#277, which falls back to the operating
system's trust store when the built-in anchors yield no path. It sits in
rtc_base below every SDK, so the C++ API that webrtc-sys binds is covered
without any Rust-side change.

feat: enable WARP (SPED + SNAP) by default, gated by the server

WARP is now always enabled on the client and negotiated with the SFU: SPED
(DTLS-in-STUN) via the WebRTC-IceHandshakeDtls field trial, and SNAP
(SCTP-INIT-in-SDP) via the RtcConfiguration.enable_sctp_snap field. When the
server does not enable WARP it is not advertised and the connection falls back to
plain DTLS/SCTP, so there is no client-side toggle.

BREAKING CHANGE: libwebrtc::RtcConfiguration is now #[non_exhaustive] and has a
new enable_sctp_snap field. Construct it from RtcConfiguration::default() and set
the fields you need instead of a struct literal.

Moves access-token generation and verification into a new livekit-token crate.

livekit_api::access_token::* continues to resolve to the same types via a
re-export, so no consumer changes are needed.

Also fixes the services-tokio and services-async features, which used the
access-token types without declaring the access-token feature. Building with
--no-default-features --features services-tokio previously failed to compile.

@knope-bot
knope-bot Bot requested review from cloudwebrtc and ladvoc as code owners August 13, 2026 16:27

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@knope-bot
knope-bot Bot requested a review from MaxHeimbrock as a code owner August 14, 2026 10:14
@knope-bot
knope-bot Bot force-pushed the knope/release branch 4 times, most recently from 201dd8a to 0c4b07b Compare August 20, 2026 00:57
@knope-bot
knope-bot Bot force-pushed the knope/release branch 2 times, most recently from d211d38 to 4db849c Compare August 24, 2026 08:08
@knope-bot
knope-bot Bot requested a review from 1egoman as a code owner August 24, 2026 08:08
@knope-bot
knope-bot Bot force-pushed the knope/release branch 3 times, most recently from d734f95 to 21b8d01 Compare August 25, 2026 15:36
@cloudwebrtc
cloudwebrtc merged commit 2d9f01a into main Aug 26, 2026
26 checks passed
@cloudwebrtc
cloudwebrtc deleted the knope/release branch August 26, 2026 06:48
xianshijing-lk added a commit that referenced this pull request Oct 19, 2026
## Summary

Fixes a regression introduced by #1376: an RPC call whose reply arrives
just after its recipient leaves the room is failed, even though the call
succeeded.

#1376 added `RpcClientManager::handle_participant_disconnected`, which
removes a call's pending ack and response the moment its recipient
disconnects. That was a real fix — before it, a recipient leaving
mid-call stranded the caller for the full 15s response timeout and
reported `ResponseTimeout` instead of the disconnect that actually ended
the call. But it assumed "participant left" implies "no reply is
coming", and that is not true: the departure is announced on the
**signalling connection** (`signal_response::Message::Update` →
`SessionEvent::ParticipantUpdate`), while the ack and response travel on
the **data channel**. Nothing orders the two against each other.

`lk.sip.EndCall` produces the losing order routinely, because the SIP
participant leaves the room as soon as it has ended the call it was just
asked to end. The reply then arrives to find its entry already gone, is
discarded with `Response received for unexpected RPC request`, and the
caller gets `RECIPIENT_DISCONNECTED` (1503) for a call that in fact
completed. A caller that retries goes on to address a participant no
longer in the room, nothing acks, and it spends the full
`max_round_trip_latency` — 7s by default — before failing with
`CONNECTION_TIMEOUT`.

## Reported impact

Surfaced by a customer upgrading `livekit-agents` 1.7.1 → 1.8.5, whose
E2E suite went from a historical <1% failure rate on `lk.sip.EndCall` to
**13 of ~44 calls**, each costing ~11s of extra session time (2s before
the retry + the 7s ack timeout). The version boundary matches this
change exactly:

| agents | pins | `rust-sdks` submodule | has #1376? |
|---|---|---|---|
| 1.8.3 | `livekit==1.1.18` | `2d9f01ab` (Release #1327) | no |
| 1.8.4 | `livekit==1.1.20` | `5a656c4b` (Release #1423) | **yes** |
| 1.8.5 | `livekit==1.1.20` | `5a656c4b` | **yes** |

which is consistent with their report of 260 clean scenarios after
downgrading to 1.8.3. (Note for anyone triaging the same report: the
break is 1.8.4, not 1.8.5 — both pin the same `livekit-rtc`.)

The `EndCall` itself always landed; nothing left calls up. The damage
was a false error plus the wasted retry.

## Change

A disconnect now **shortens** the wait instead of ending it.

`handle_participant_disconnected` no longer removes the pending entries
— dropping them is what turns an in-flight reply into an "unexpected RPC
request". It signals each affected caller over a per-leg `oneshot`, and
the caller then waits up to `DISCONNECT_GRACE_PERIOD` (2s), never past
its own timeout, for a reply already on the wire. Per-leg signals mean a
disconnect seen while waiting on the ack is still remembered once the
call moves on to the response.

A recipient that really did leave without replying still fails fast with
`RECIPIENT_DISCONNECTED` rather than running out the 15s response
timeout, so #1376's improvement is preserved. `fail_all_pending` (room
close) still fails immediately — the data channel is gone, nothing more
can arrive.

## Tests

`livekit-rpc/src/tests.rs` — three new tests on virtual time, driving
the exact event ordering that caused the bug:

- `test_response_after_disconnect_still_resolves_caller` — the repro:
ack, disconnect, then the response 50ms later (matching the ~45ms gap
seen in the field). **Fails on `main`** with `RpcError { code: 1503,
message: "Recipient disconnected" }` — the reported symptom — and passes
here.
- `test_ack_after_disconnect_still_resolves_caller` — same race on the
ack leg. Also fails on `main`.
- `test_disconnect_grace_period_does_not_wait_out_response_timeout` —
the grace period is a reprieve, not a second response timeout.

Reverting only `client.rs` to `main` and keeping the tests gives 25
passed / 2 failed; with the fix, 27 passed. The existing
`test_participant_disconnect_fails_pending_call` still passes and now
also asserts the call ends well inside its 30s response timeout.

`livekit/tests/rpc_test.rs` —
`test_rpc_recipient_leaving_without_replying_fails_promptly` covers the
same contract end-to-end against a live server: a handler that never
replies, the recipient closes its room, and the caller must fail with
`RECIPIENT_DISCONNECTED` inside 15s despite a 60s response timeout. This
guards the fast-fail behaviour from being reverted along with the race
fix.

Worth being explicit about the split: the race itself cannot be forced
end-to-end — it is a sub-50ms window owned by two independent
transports, and a client-side room close tears down the data channel, so
the reply would be genuinely lost rather than merely late. The
deterministic coverage therefore lives in the unit tests, at the seam
where the event ordering is actually decided. The e2e test is compiled
but not run locally (it needs a server); CI runs it under
`__lk-e2e-test`.

## Follow-up, not in this PR

`perform_rpc` to an identity that is not in the room does not fail fast:
it sends into the void and waits the full 7s ack timeout before
returning `CONNECTION_TIMEOUT`. `RpcTransport` already exposes
`remote_identities()`, so this could return `RECIPIENT_NOT_FOUND` (1401)
immediately. Left out because it changes an API-visible error code on an
existing path.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Ryan Gaus <ryan.gaus@livekit.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant