Commit Graph
1585 Commits
Author SHA1 Message Date
David Chen d269ac59dd Preserve FEC sender state and harden subscription updates
Carry repair sequence state through the existing DownTrack GetState/SeedState
handoff so cached transceiver reuse preserves SRTP sequence continuity. Close
the old encoder before saving its sequence, and allocate its media group only
when protection is first used.

Apply subscriber settings from one immutable snapshot and discard superseded
updates. Preserve upstream FEC on shared sendrecv codec lists when downstream
generation is disabled. Lock the source RTP stats while seeding a replacement
sender to avoid racing its final snapshot update.

Align field and import grouping with the surrounding implementation. Add
regressions for sequence wrap/rebind, SRTP sender reuse, concurrent settings,
superseded updates, and independent negotiation flags.

Validation: full race suites passed for pkg/sfu/flexfec, pkg/sfu/pacer,
pkg/sfu/rtpstats, pkg/sfu, and pkg/rtc. Encoder benchmarks remain approximately
1.9-2.5 us per five 1200-byte media packets at low/medium/high protection;
disabled encoding has zero allocations.
2026-09-12 11:44:49 -07:00
David Chen 38a675025d Generate downstream FlexFEC with per-track protection presets 2026-09-12 10:51:44 -07:00
David Chen 9553143469 remove the ability to configure payload type for FlexFEC 2026-09-09 16:39:11 -07:00
David Chen 478f6937c3 Fix FlexFEC negotiation with libwebrtc publishers 2026-08-30 17:43:57 -07:00
David Chen a8b35cc818 Harden upstream FlexFEC handling 2026-08-29 22:02:23 -07:00
David Chen 390d40e70a Lower FlexFEC repair window to two seconds 2026-08-29 15:48:31 -07:00
David Chen d1e39735e2 Validate FlexFEC payload type range 2026-08-28 20:27:11 -07:00
David Chen 6a879f4f48 Add upstream FlexFEC recovery support 2026-08-28 17:46:41 -07:00
cnderrauber d185224719 warp log (#4811) 2026-08-28 16:59:21 +08:00
Raja Subramanian c362e61d3c Set up track info properly for dummy receiver. (#4807)
In migration cases, dummy receiver trackInfo is used by relay tracks to
set up the receivers and those need the proper track info.

Also check for proper receiver when adding a migrated track.
2026-08-28 00:27:50 +05:30
Alex FeldgendlerandClaude Opus 5 dc2bd1d3b4 Wait for the callbacks these tests assert on. (#4803)
TestUnsubscribe checked that the changed-notifier observer was gone as
soon as the unsubscribe had settled, but setDesired leaves the
RemoveObserver call to a goroutine of its own and nothing the test waits
on orders against it, so CI caught the assertion running first.
TestSubscribe has the same defect on the unsubscribed callback, which
unmarkSubscribedTo delivers with a bare go while the subscribed one is
called inline.

Wait for both, each with a message of its own, so that a leak that is
real still says which of them broke.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-27 12:25:01 +05:30
Raja SubramanianandClaude Opus 5 bbdfd50d62 Fix simulcast RTX pairing broken by pion/webrtc#3470 (#4800)
pion no longer starts the repair stream reader when a custom BufferFactory
is set, so the mid/rid/rsid extensions were never observed and simulcast RTX
streams were never paired with their primary streams.

Extract the extensions on the buffer write path instead. Migrated publishers
send no extensions at all, so pair those from SimTracks.

Adds an integration test covering both paths, and moves the vnet setup it
shares with the downtrack test into pkg/testutils/vnettest.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 13:01:22 +05:30
Raja Subramanian b0710f7a6a Reduce locking in media track + telemetry listener on move participant. (#4790)
* Reduce locking in media track + telemetry listener on move participant.

Telemetry listener was not getting it from new room on room move.

* update comment

* fix signal bytes reporting

* room aware telemetry listener in media track

* data track telemetry listener
2026-08-25 02:45:40 +05:30
Raja Subramanian 26975ef057 Join failure is a canceled connection attempt. (#4788)
Could happen due to participant being already in room, exceeding max
participants, etc.
2026-08-24 10:56:17 +05:30
cnderrauber 803864dc7b Add bytes cap on migration data cache size (#4782) 2026-08-21 16:49:09 +08:00
Raja Subramanian 6a64df20df Add a small cache for data messages received via SendData API. (#4781)
SendData API messages do not have sender ID or sequence number. So, they
were not cached and hence excluded from the reliable caching feature
which is meant to provide reliability of data channel messages between
the time other participants see participant as ACTIVE (which happens on
ICE connected) and data channel being open (DTLS done + data channels
opened).

Add a small cache for that and flush those messages on data channel
establishment.
2026-08-20 13:51:10 +05:30
Raja Subramanian 972c64a29b Check for ICE connection before closing participant on signal close. (#4780)
* Check for ICE connection before closing participant on signal close.

Only close the participant if ICE has not connected by the time signal
source is closed. If ICE had connected, candidates have been exchanged
and link was established. So, it should be resumable.

Waiting for DTLS closed the participant sometimes in the windowa after
ICE connection, but before DTLS finishes and that unnecessarily closed
the participant forcing a full reconnect.

* variable name
2026-08-20 13:07:28 +05:30
Raja Subramanian 0ef7ee440c Fix deadlock in regress codec check. (#4775) 2026-08-19 20:17:53 +05:30
cnderrauber dbe06aa8d1 Experimental WARP (#4649)
* Experimental WARP

* fix panic

* go dep

* stats
2026-08-14 16:26:08 +08:00
Raja Subramanian 9d676e3a60 Limit number of pending tracks per participant. (#4750)
* Limit number of pending tracks per participant.

Prevents just a signalling connection adding tracks without actually
publishing them growing a large number.

* add to supervisor only if pending track is accepted
2026-08-13 16:48:49 +05:30
Raja Subramanian d51533e25c Make subscription limit log Debugw as it could spam in a large room. (#4748) 2026-08-13 13:33:32 +05:30
Raja Subramanian 2cd50a961f Record publish time on participant close for pending tracks. (#4738)
With https://github.com/livekit/livekit/pull/4706, there was a case of
some downstream component taking a long time while lock was held. While
the underlying cause of holding a lock while doing callback was removed
in that PR, to catch such cases, some publish side metric anomaly would
be useful to monitor and alert on.

Adding a publish time record for pending tracks on participant close.
That would inflate the publish time for participants not being able to
publish and can be alerted on as it will spike up the value at node
level and at cluster level if multiple nodes have the issue.
2026-08-12 21:41:52 +05:30
Raja SubramanianandClaude Opus 4.8 3c6e56232e Add configurable read-message size limit on signalling WebSockets (#4743)
* Add configurable read-message size limit on signalling WebSockets

Set a read limit on both the client-facing (/rtc) and agent worker
WebSocket connections so an oversized frame is rejected by the transport
before being buffered. The limits are operator-tunable via
signal_message_size_limit and agent_signal_message_size_limit, both
defaulting to 2 MiB (0 disables).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Add tests for signalling WebSocket read-message size limit

Cover the configurable signal_message_size_limit added in the prior
commit:
- config: assert both limits default to 2 MiB and that a YAML override
  (including 0 to disable) is parsed correctly.
- full-path integration: a real client connects to /rtc on a single-node
  server and an oversized frame is rejected by the transport with a 1009
  close; a 0 limit leaves the connection unbounded and signalling
  proceeds.

Adds setupSingleNodeTestWithConfig so a single-node server can be started
with config overrides.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Bound decompressed size of signalling WebSocket messages

conn.SetReadLimit only accounts for the compressed bytes read off the
wire, and the client-facing /rtc upgrader negotiates permessage-deflate,
so a small compressed frame could still expand into a much larger buffer
once inflated. Enforce the same limit on the decompressed message by
reading through NextReader + io.LimitReader in WSSignalConnection instead
of the unbounded ReadMessage.

The transport-level SetReadLimit is kept as the cheap wire-level guard;
the new check is the decompressed-size backstop.

Adds NextReader to the WebsocketClient interface (regenerated fake) and a
unit test plus permessage-deflate integration tests covering the
amplification case.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-12 12:07:26 +05:30
Raja SubramanianandClaude Opus 4.8 c4c356f6ca Cover a couple of more cases on data track runt packet handling. (#4741)
* Cover a couple of more cases on data track runt packet handling.

* Guard data track header parser against extensions-size integer wraparound.

Widen the extensions-size arithmetic to int so a 0xFFFF wire value no
longer wraps in uint16, and reject any packet whose computed hdrSize
exceeds the buffer before slicing the payload.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-11 18:25:10 +05:30
Raja Subramanian d279899b7c Fix publish track count on migration in. (#4740)
* Fix publish track count on migration in.

https://github.com/livekit/livekit/pull/4707 addressed the case of
publish tracks overcounting due to synthesised track publish on migrate
in. But, it introduced an issue where published tracks count could go
negative because unpublish subtracted the counter irrespective of the
track actually migrated in or not.

Fix it by keeping track of local publish.

Also, the older code was skipping publisher track count increase if the
synthesised publish was handled first. Address it by checking if the
track is actually new (i. e. fresh local publish) when the track was
already created in the migrate in path.

* fix pub time for tracks published after migration

* test

* prevent multiple track egresses
2026-08-11 16:13:57 +05:30
Kuba Podgórski 335990afa5 return psrpc.FailedPrecondition for "participant client version does not support moving" error (#4736) 2026-08-09 00:42:24 -07:00
Anunay MaheshwariandSimon Beeli 4e921aa1b6 Expand room details in webhook events (#4730)
* pass room proto directly to telemetry events

* Keep telemetry analytics events on a minimal room, gate full room in webhooks

---------

Co-authored-by: Simon Beeli <simon.beeli@gmx.ch>
2026-08-07 15:29:41 +05:30
Raja Subramanian 3f9cf6bfc2 Do not report end time for participant if the participant is migrating (#4728)
out.
2026-08-06 00:59:37 +05:30
Raja Subramanian 52ef3cd649 Include data track susbcriptions in WaitForSubscription. (#4727) 2026-08-05 13:28:48 +05:30
Nikita Davydov 2a9bb36ee0 Apply ICE preference when switching to TCP on unstable UDP (#4703)
onMediaLossUpdate notified the participant handler directly, which only
sends a leave request with resume action. handleConnectionFailed that
actually switches the ICE preference to TCP/TLS was never called on
this path, so the client reconnected over UDP again and the fallback
kept firing every 30-60s without ever migrating.

Fixes livekit/livekit#4702
2026-08-04 13:04:36 +05:30
cnderrauber 4d177cb01b Remove H.264 baseline (42001f) from default enabled codecs (#4723)
Users can explicitly enable this profile if they are certain that all device support it.
2026-08-04 11:12:42 +08:00
Raja Subramanian ced94b8645 log high stream start latency. (#4714)
* log high stream start latency.

There is something wrong in measurement as audio is showing high p99
latency. Must be misattributing samples. So, logging for high latency to
understand this better.

* use correct variable

* time since create
2026-07-30 17:10:59 +05:30
cnderrauber 436a0cc3d3 Support more h264 profiles (#4708)
* Register h264 main profile if enabled explicitly

We don't support the h264 main profile for compatibility,
user can enabled it by set fmtp explicitly in codec config
to enable it if want to use it in special scenario.

* go mod
2026-07-28 16:18:19 +08:00
Raja Subramanian b8a073cb68 A bit better counting for track publish. (#4707)
- Count a publish attempt on a migrating in tarck as there is no
  AddTrack for that.
- Add cancel publish only if the participant connection is canceled
- Do not add publish counter for synthetic publish attempts which
  happens for migrating in tracks. It will be counted on migrating in
  node when the track is actually published, i. e. negotiated/packets
  flowing.
2026-07-28 02:18:14 +05:30
Raja Subramanian 25e3774cbb Do not call telemetry listener under pending track lock. (#4706)
* Do not call telemetry listener under pending track lock.

Fix the TrackPublishRequested call of telemetry listener.

Audited other callbacks to ensure that it is not under lock.

* missed some paths of recording it, thanks Devin
2026-07-27 23:52:21 +05:30
Raja Subramanian 0aa296e126 Record subscribe stream start time in prometheus. (#4704)
* Record subscribe stream start time in prometheus.

Adjust for mutes, i. e. take the last unmute time as the start point and
calculate time till the first byte is sent.

* close the tiny window of race

* Prevent long tail sample when publisher glitches.

Thanks to @milos-lk for this.

Publisher restarting would have reset the layer and would have caused a
sample with very high stream start time. We only need to capture when we
do a dummy start or when the state is seeded to a different node upon
migration.

* reduce a diff

* test

* changed the wrong thing, thank you Devin
2026-07-27 20:37:44 +05:30
Raja Subramanian 1bbd4702b6 Spelling fixes (#4698) 2026-07-26 22:26:41 +05:30
Raja Subramanian c684997c4f Add country to participant closing log (#4693) 2026-07-20 15:32:42 +05:30
Benjamin PrachtandCopilot Autofix powered by AI 14aeeb3c56 Potential fix for code scanning alert no. 42: Incorrect conversion between integer types (#4684)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-07-17 09:56:26 +02:00
Erik HortschandClaude Opus 4.8 5407ee03ae rtc: guard against nil subscriber in TransportManager.HandleAnswer (#4680)
In single-PC and one-shot signalling modes the subscriber PCTransport is
never created, so t.subscriber is nil. Every other TransportManager method
that touches the subscriber nil-checks it first; HandleAnswer did not, so a
client sending an SDP answer in those modes crashed the process with a nil
pointer dereference. Guard it and log, matching AddICECandidate/Negotiate.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 13:36:03 -07:00
Raja Subramanian 8c14a617f5 Use proto logger to get named enums in the logs. (#4679) 2026-07-16 23:50:13 +05:30
Raja Subramanian 38d7efca83 Record rtc_success prom as soon as RTC connects. (#4677)
Was doing it on participant close. But, that misaligns `rtc_init`
(number of attempts) a bit if the participant sessions are long.
Record it as soon as RTC connects so that it is more time aligned with
`rtc_init`.
2026-07-16 12:49:27 +05:30
Florian Loretan 7818dd21b9 fix: bound data-track buffering under downlink congestion (targetLatency) (#4667)
* fix: bound data-track buffering under downlink congestion

The SFU data-track down-channel writer was constructed with targetLatency=0,
which disables the buffered-amount/latency-based drop in writeUnreliable. Under
subscriber downlink congestion, frames were queued unbounded and in order in the
per-subscriber SCTP send buffer instead of being dropped, so end-to-end latency
grew without limit and only drained once congestion cleared. This contradicts
data tracks being a low-latency, lossy transport.

Wire a dedicated `datachannel_data_track_target_latency` config through to both
data-track writer call sites (mirroring how `datachannel_lossy_target_latency`
controls the lossy publishData channel), reusing lossyDataChannelMinBufferedAmount
as the drop floor. Defaults to 100ms so data tracks are latency-bounded out of
the box; set to 0 to restore the previous unbounded behavior.

Fixes #4666

* fix: track drained bytes on successful unreliable data channel writes

writeUnreliable only called BitrateCalculator.AddBytes when a write failed,
so on the common success path the calculator never received samples. As a
result Bitrate() had no data and the latency-based drop threshold collapsed to
the static minBufferedAmount floor, making the per-subscriber latency control
(datachannel_lossy_target_latency and the new datachannel_data_track_target_latency)
effectively inert. Call AddBytes after every write, matching writeReliable.
2026-07-14 10:06:09 +08:00
Raja Subramanian 424c7a602a Record final RTC state as success/failure. (#4658)
Leave out canceled attempts. Should make it easier to do percentages.

Not putting these in node stats yet. Will observe in prom before using
it in node stats.
2026-07-11 00:09:16 +05:30
Raja Subramanian 19c3d00fc9 Add option to exclude local IPv6 candidates. (#4657)
Could be useful option to try in certain conditions where flakey IPv6
infrastructure is suspected for connection issues.
2026-07-10 15:56:58 +05:30
Raja Subramanian cb46452b5d Export migration to LocalParticipant interface. (#4652)
Can be used during delayed egress start.
2026-07-09 12:23:33 +05:30
Raja Subramanian bf777e6513 Make IsConnectionCanceled available at LocalParticipant interface. (#4643)
Can be used to keep track of pariticpants failing connection in a room
by checking this when room closes the participant.
2026-07-05 16:08:10 +05:30
Jacob Gelmanandboks1971 a47e21b6cb Data track schema metadata (#4622)
* Async attributes on participant.

How it is different from existing participant attributes?
1. Async attribute can be added one at a time.
2. These are not included in `ParticipantInfo`.
3. Get an attribute bt participant identity and async attribute ID as
   and when needed.

* clean up

* get full definitions, not just ids

* listener OnDataTrackSchema

* name length config

* data blob

* deps

* static check

* Add missing request ID

* Update protocol commit

* Wire up StoreDataBlobResponse

* Pass request ID through in GetDataBlobResponse

* Pin protocol for schema metadata

* Pass through schema and frame encoding

* Support custom encoding identifiers

* Rename config key

* Increase default length to 32

* Make log messages more generic

* Use getters with built-in null check

* Do not bump deps

* Rename function

* Use protocol v1.48.1 release

---------

Co-authored-by: boks1971 <raja.gobi@tutanota.com>
2026-06-29 10:44:08 -07:00
Raja Subramanian 23090163ce Configurable migration wait duration for longer waits in simulation. (#4624)
Only applies if it is more than the default 3 seconds.
2026-06-26 20:01:32 +05:30
Raja SubramanianandJacob Gelman 1faab0c48e Add support for data blob (a. k. a. async participant attributes) (#4619)
* Async attributes on participant.

How it is different from existing participant attributes?
1. Async attribute can be added one at a time.
2. These are not included in `ParticipantInfo`.
3. Get an attribute bt participant identity and async attribute ID as
   and when needed.

* clean up

* get full definitions, not just ids

* listener OnDataTrackSchema

* name length config

* data blob

* deps

* static check

* Add missing request ID

* Update protocol commit

* Wire up StoreDataBlobResponse

* Pass request ID through in GetDataBlobResponse

* deps

* atomic

* sctp at 1.9.5

* remove proto clone

---------

Co-authored-by: Jacob Gelman <3182119+ladvoc@users.noreply.github.com>
2026-06-24 14:42:37 +05:30