Commit Graph
3853 Commits
Author SHA1 Message Date
cnderrauberandGitHub fad2cc4afe Use request id to make api idempotence on sdk retry (#4694)
* Use request id to make api idempotence on sdk retry

Derive resource id from request id
2026-08-12 09:28:39 +08:00
223587e140 Add per-participant concurrent TURN allocation quota (#4744)
* Add per-participant concurrent TURN allocation quota

The embedded TURN server authenticated each Allocate request but placed
no cap on how many relay allocations a single participant credential
could hold. One participant could reuse its credential across many client
5-tuples and open one relay socket/port per request, exhausting the
shared relay-port range for everyone else.

Add a configurable per-participant limit (turn.per_user_relay_allocation_limit,
default 4) wired to Pion's QuotaHandler, keyed by the participant ID from
HandleAuth. Slots are reserved before allocation and released when the
allocation ends, under a single lock, so concurrent Allocate bursts cannot
race past the limit; reservations are keyed by source address so retransmits
are idempotent. Over-quota requests receive 486 (Allocation Quota Reached).

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

* Reclaim unconfirmed TURN allocation reservations

Allow reserved a quota slot before Pion built the relay, but the slot was
only released on the allocation-deleted event. An Allocate that passed the
quota check and then failed to create a relay (e.g. relay-port range
exhausted) emits no event, so the reservation leaked: after enough failures
a participant could lock itself out with 486, and the tracking map grew
without bound.

Reservations now start pending and are confirmed on allocation-created; each
pending reservation carries a reclaim timer that frees the slot after a TTL,
so a failed attempt cannot hold a slot forever while concurrent-burst safety
is preserved.

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

* Make TURN reservation reclaim identity-aware

The reclaim timer captured only userID+key. Because Timer.Stop cannot cancel
a callback that has already fired and is waiting on the lock, a stale timer
could delete a replacement reservation created for the same userID+key after
the original was released, leaving a live allocation untracked and letting the
participant exceed its cap.

reclaimPending now captures the slot pointer and only removes the entry when
the map still holds that exact slot, so a stale timer is a no-op.

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 23:12:07 +05:30
Raja SubramanianandGitHub 7167f91493 Validate TURN config to guard against invalid values (#4742) 2026-08-11 20:34:49 +05:30
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 SubramanianandGitHub 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
Raja SubramanianandGitHub 7f1c175a38 Check layer value in dependency descriptor and keep it in bounds. (#4739) 2026-08-11 12:04:19 +05:30
renovate[bot]GitHubrenovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
32368f79d2 Update actions/setup-go action to v7 (#4720)
Generated by renovateBot

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-09 00:44:18 -07:00
Kuba PodgórskiandGitHub 335990afa5 return psrpc.FailedPrecondition for "participant client version does not support moving" error (#4736) 2026-08-09 00:42:24 -07:00
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
cnderrauberandGitHub 8e6077221c Return incompatible in SetCodecWithState if the codec PT changed (#4729) 2026-08-06 15:42:06 +08:00
Raja SubramanianandGitHub 3f9cf6bfc2 Do not report end time for participant if the participant is migrating (#4728)
out.
2026-08-06 00:59:37 +05:30
Raja SubramanianandGitHub 52ef3cd649 Include data track susbcriptions in WaitForSubscription. (#4727) 2026-08-05 13:28:48 +05:30
Nikita DavydovandGitHub 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
cnderrauberandGitHub 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 SubramanianandGitHub 28468035d2 Check for pictureID existence in VP8 and VP9 (#4721)
* Check for pictureID existence in VP8 and VP9

* test
2026-08-03 15:22:59 +05:30
Felix-AyushandGitHub 4618b63eb7 Fix AgentHandler.DrainConnections deadlock on worker close. (#4710)
Snapshot workers and release h.mu before Close so HandleConnection can deregister without blocking drain.
2026-08-03 14:49:23 +05:30
3b9f118327 Release v1.13.5. (#4715)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v1.13.5
2026-07-31 12:28:21 +05:30
Raja SubramanianandGitHub 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
Felix-AyushandGitHub 0759280cd0 Fix getRefLayerRTPTimestamp off-by-one that can panic on max layer index (#4712)
* Fix getRefLayerRTPTimestamp off-by-one that can panic on max layer index.

Reject ref/target layers with >= len(refInfos) so layer==len is an error instead of an out-of-range index.

* Remove historical comment from ref-layer bounds test.

Keep the regression coverage without referencing the old bounds check in source.
2026-07-30 15:24:50 +05:30
cnderrauberandGitHub 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 SubramanianandGitHub 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 SubramanianandGitHub 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 SubramanianandGitHub 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 SubramanianandGitHub f1e2eee2fe protocol update with webhook status logging (#4700) 2026-07-27 01:57:10 +05:30
Raja SubramanianandGitHub dfd3a3c4a5 protocol deps for logging webhook status (#4699) 2026-07-27 01:00:51 +05:30
Raja SubramanianandGitHub 1bbd4702b6 Spelling fixes (#4698) 2026-07-26 22:26:41 +05:30
renovate[bot]GitHubrenovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
a0d6e72017 Update go deps (#4645)
Generated by renovateBot

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-07-25 23:23:56 -07:00
He ChenandGitHub 93422be0c5 TELCU-1: send resolved ringing timeout (#4697) 2026-07-23 15:29:24 -07:00
Raja SubramanianandGitHub fc2fe3faf5 Use simulcast constructor for VP9 if simulcasted. (#4696)
Not active path, but noticed it while reviewing a bug report. Just
fixing it for correctness in code.
2026-07-23 13:15:01 +05:30
Ninad PundalikandGitHub afb9142c1e Add status code for twirp request latency prometheus metric (#4621)
* Add status code for twirp request latency prometheus metric

* Drop the twirp error codes as that adds a lot of coardinality
2026-07-22 15:52:30 +05:30
Raja SubramanianandGitHub 13e4aaec2b Tests for down stream packet push. (#4692)
* Tests for down stream packet push.

A recent issue (padding bit in RTP header) surfaced a gap which slipped
through due to lack of tests. Changes in pion/rtp were not adopted
properly.

So, adding some tests (thank you Claude for the heavy lifting) to test
the down stream packet path using the whole pion chain.

Split out some interfaces so it is easier to have it all in one place
and create fakes.

Will help adding more tests, for example include the upstream path also
in the integration test. May have to create more interfaces and make
things testable, but this is a start.

* missed file

* rtx specific test
2026-07-20 20:15:07 +05:30
Raja SubramanianandGitHub c684997c4f Add country to participant closing log (#4693) 2026-07-20 15:32:42 +05:30
David ZhaoandGitHub 3f59d0dd9e add mock for testing region pins with API (#4691)
we'll ensure that clients support redirection when making an API
to an unpinned region
2026-07-19 21:12:35 -07:00
Raja SubramanianandGitHub 366cadcd96 Fix padding bit in forwarded packet. (#4690)
Addresses https://github.com/livekit/livekit/issues/4689

We were probably missing a couple of bits with this
1. Not affected for regular traffic like from browsers as it does not
   add padding, but special clients were affected.
2. Probe packets were probably using wrong last byte as pion/rtp would
   have overwrriten with 0 because the header.PaddingSize for the newer
   versions were not set. That could have affected bandwidth estimation
   catch up.
2026-07-19 20:53:28 +05:30
0b3fd288e3 Release v1.13.4. (#4688)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v1.13.4
2026-07-18 13:37:18 +05:30
Alex FishandGitHub a1033e4242 Bump protocol version to fix call to Validate. (#4686) 2026-07-17 12:19:33 -07:00
Chenghao MouandGitHub 28931e2f84 add redaction flag in Job (#4650)
* add redaction flag in Job

* update dependencies
2026-07-17 14:42:00 +01:00
Raja SubramanianandGitHub f0ac6ce200 Prefer QDisc.Stats till go-tc addresses QDisc.Stats2 parsing (#4685) 2026-07-17 16:39:25 +05:30
Benjamin PrachtGitHubCopilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
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
Raja SubramanianandGitHub 2c91395055 Propagate spreader threshold to RED receivers. (#4683)
Following up on this PR (https://github.com/livekit/livekit/pull/4678 -
great catch btw, thank you), propagating the spreader threshold to RED
receivers also.

Removing the test as it was a simple case and that would not have caught
the original issue.
2026-07-17 02:25:10 +05:30
HuangJieandGitHub 15a9542c99 Fix receiver load balance threshold initialization (#4678) 2026-07-17 02:08:32 +05:30
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 SubramanianandGitHub 8c14a617f5 Use proto logger to get named enums in the logs. (#4679) 2026-07-16 23:50:13 +05:30
Raja SubramanianandGitHub 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
cce14a6fec fix: don't undercount data channel bitrate over idle gaps (#4676)
* fix: don't undercount data channel bitrate over idle gaps

BitrateCalculator divided drained bytes by wall-clock time, including
idle gaps between sparse writes. A fast channel fed sparsely (e.g. 1 KB
every second, acked in a few ms) therefore reported its low offered load
(~8 kbps) instead of its drain capacity (~800 kbps). In the unreliable
writer that shrinks targetLatencyLimit and drops bursts on a channel
that is actually keeping up.

Measure the rate over backlogged ("busy") time only, so idle time no
longer dilutes the estimate. Backlog is detected from the buffer
occupancy just before a write (bufferedAmount - bytesWritten): since no
bytes are added between writes the buffer only drains, so a non-zero
pre-write level means it never emptied and the interval was genuinely
busy. Gating on the post-write buffered amount would be wrong -- it
always includes the just-enqueued (not yet SACKed) bytes and is ~never
zero, collapsing the estimate back to wall-clock. When no backlog is
ever observed the calculator reports no estimate (ok=false) instead of a
confidently-low number.

Introduce BitrateMode:
- BusyOnly (writer default): busy denominator, all drained bytes counted.
- ExcludeIdleDrain: also drops bytes drained across non-backlogged
  intervals for a clean drain-capacity estimate free of idle
  contamination.
- WallClock: elapsed-time denominator, all bytes; for the test-client
  reader which has no send buffer to observe.

Call sites keep the conservative behaviour (writers BusyOnly, reader
WallClock). Tests exercise both writer modes and the mixed idle-then-
backlog window where they diverge.

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

* Trim comments in data channel bitrate calculator

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

* Make BitrateMode.String a method on the enum

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-07-16 00:29:23 +05:30
Alex FishandGitHub cc87a83e1f TEL-730: Log soft validation errors. (#4671) 2026-07-15 09:06:01 -07:00
dcd08bec63 Fix goroutine leak from orphaned signal relay streams (#4674)
* Fix goroutine leak from orphaned signal relay streams

signalService.RelaySignal blocks on the first `<-stream.Channel()` waiting for the StartSession message. psrpc's streamHandler.handleOpenRequest only closes the stream after the handler returns, so if a stream is opened but the client goes away before sending StartSession, the channel is never fed and never closed, and this goroutine blocks forever. Under mass reconnects this leaks one goroutine (and its retained objects) per orphaned stream; they only clear on process restart.

Wrap the initial receive in a select that also returns when the stream context is cancelled or after config.SignalRelay.RetryTimeout, so an orphaned stream returns before Hijack() and psrpc closes it.

Signed-off-by: SKaterinenko <skaterinenko@gmail.com>

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Paul Wells <paulwe@gmail.com>
2026-07-15 05:41:16 -07:00
Raja SubramanianandGitHub 0c7b93d39a Add more details to unreliable data channel drop error. (#4673)
Some data track related tests are failing due to setting a target
latency of 100ms. Would be good to understand if taget latency or min
buffer is causing the drops.
2026-07-15 17:12:39 +05:30
Raja SubramanianandGitHub d4888f7d2a Update pion/ice to deal with hang on close. (#4672)
Potential cause of #4549, #4591
2026-07-15 14:14:49 +05:30
Florian LoretanandGitHub 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