Commit Graph
1552 Commits
Author SHA1 Message Date
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 1bbd4702b6 Spelling fixes (#4698) 2026-07-26 22:26:41 +05:30
Raja SubramanianandGitHub c684997c4f Add country to participant closing log (#4693) 2026-07-20 15:32:42 +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
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
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
Raja SubramanianandGitHub 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 SubramanianandGitHub 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 SubramanianandGitHub cb46452b5d Export migration to LocalParticipant interface. (#4652)
Can be used during delayed egress start.
2026-07-09 12:23:33 +05:30
Raja SubramanianandGitHub 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
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 SubramanianandGitHub 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
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
6658dd5454 Echo offered audio payload types in single-PC subscriber answer (#4614)
In single peer connection mode, when the server answers a subscriber's
offer, configureSenderAudio set the sender codec preferences from the
server MediaEngine's payload types. The answer could therefore advertise
Opus on a payload type the offerer never offered (server PT 111 vs
offered PT 109). Chrome tolerates this; Firefox decodes 0 samples
(silence) -- packets are received but never decoded. The forwarded RTP
already uses the offered PT, so only the answer SDP was inconsistent.
This regressed in v1.12.0 once the single-PC MediaEngine became a union
of publish+subscribe codecs.

Parse the remote offer's audio rtpmap and remap the sender audio codec
preferences to echo the offered payload types (RFC 3264 6.1) before
SetCodecPreferences.

Fixes #4599

Co-authored-by: laosun <14806343+cnvipstar@users.noreply.github.com>
2026-06-23 10:36:41 +05:30
Raja SubramanianandGitHub 4facbc582a Move lock to addPendingTrack function. (#4617)
Wrapping the function with the lock outside in the only invocation was
not needed.
2026-06-23 10:30:59 +05:30
Ryan GausandGitHub 86a79f83fc fix: report participant capabilities in ParticipantInfo (#4606) 2026-06-22 09:23:33 -04:00
Raja SubramanianandGitHub f7085535da Tighten up publish latency stat. (#4615)
Previously it was anchored to participant transitioning to `ACTIVE` if
the add track request happened before that. But, that has a few issues
1.`ACTIVE` is for primary peer connection which could be subscriber peer
connection.
2. `ACTIVE` also include data channel establishment.

Switch to first connected time of publisher peer connection for that to
get a more accurate measure of track publish time.
2026-06-22 17:36:06 +05:30
cfedcc71d0 feat: acquire requested video layer directly at HIGH quality by default (#4595)
* feat: acquire requested video layer directly at HIGH quality by default

Two changes that together remove the visible low->high quality ramp for a new
subscriber (both publisher-first and subscriber-first join orders):

1. Default a subscriber's initial video quality to HIGH on bind instead of LOW
   for adaptive stream, so the subscribed max layer is the top layer. Adaptive
   stream clients can still scale down afterwards based on viewport.

2. On initial layer acquisition the forwarder/selector latch directly onto the
   allocator's target (the requested top layer) instead of opportunistically
   latching onto the first lower key frame that arrives. A short
   initial-acquisition grace aims the target at the requested layer; if it does
   not show up in time, the target falls back to the highest layer seen so
   acquisition never stalls.

Always on - no configuration flag.

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

* feat: gate start-at-desired-quality behind EnableStartAtDesiredQuality flag

Put the "acquire requested video layer directly at HIGH quality" behavior
behind a per-subscriber EnableStartAtDesiredQuality flag (default off, so
the original low->high ramp-up is restored unless enabled).

Plumbed from config.RTC.EnableStartAtDesiredQuality through ParticipantParams
-> SubscribedTrack/DownTrack -> Forwarder -> simulcast selector, gating all
three behavior changes: the HIGH default on bind, the forwarder's
initial-acquisition grace, and the selector's direct-latch-onto-target.

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

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* remove config.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-19 20:12:54 +08:00
Raja SubramanianandGitHub a011d995da Do not call nil callback (#4607) 2026-06-18 23:24:33 +05:30
Raja SubramanianandGitHub e7c63aa537 Log subscription limit breaches (#4603) 2026-06-18 00:08:39 +05:30
Raja SubramanianandGitHub 67ca7a12cf Record more RTC cancellation points. (#4600)
There are several places the participant can drop off after initiating a
connection attempt. Count those places as cancellation including when
participant is closed due to specific reasons.

Cancels should be discounted when determining RTC/ICE connectivity
success/failure percentage.
2026-06-17 20:43:29 +05:30
Paul WellsandGitHub 12a023ae45 agent: thread attributes map from dispatch to job (#4598)
* agent: thread simulation flag from dispatch to job

Reads simulation from AgentDispatch / RoomAgentDispatch and copies it
onto Job in agent.LaunchJob and the inline room-agent path so workers
see the flag.

Stacked on top of livekit/protocol#1629.

* agent: replace simulation bool with attributes map

Threads the renamed attributes map (was bool simulation) from dispatch
to job and bumps the protocol pseudo-version.

* deps
2026-06-16 01:53:01 -07:00
cnderrauberandGitHub 9746c9a9d6 Enforce subscriptio permission to data track (#4588)
* Enforce subscriptio permission to data track

* use revoke path as same as media track

* nil check
2026-06-12 16:02:12 +08:00
08ab361e8e [WIP] rtc: add RestartSessionTimer to re-anchor participant session duration (#4566)
* rtc: add RestartSessionTimer to re-anchor participant session duration

Exposes ParticipantImpl.RestartSessionTimer so the session timer can be
re-anchored to the actual join time. Duration is only ever emitted once
the participant becomes active, so re-anchoring at join keeps pre-join
wall-clock out of the reported/billed duration. Adds the method to the
LocalParticipant interface (fake regenerated) and a local protocol
replace to pick up SessionTimer.Reset.

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

* tidy

* update protocol

* report ended at for inactive sessions

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Paul Wells <paulwe@gmail.com>
2026-06-11 10:02:25 -07:00
cnderrauberandGitHub 7dc6877738 Preserve original expiry when refreshing token (#4580)
To avoid shortening the token expiration time during
refreshing cause client reconnect failed after network
down for a long time (>5min).
2026-06-10 14:51:10 +08:00
Raja SubramanianandGitHub 8d2b827f44 Add prom metrics for peer connectino state. (#4574)
* Add prom metrics for peer connectino state.

By direction (PUBLISHER vs SUBSCRIBER) and state ("started" ->
"connected"). This gives a way to track peer connections failing to
finish establishment.

The RTC active count can be useful for primary peer connection, but not
for non-primary. This counter can be used to track any and can generally
be used to understand success/failure rate of peer connection
establishment.

* add a couple of more states

* clean up and avoid duplicate reporting fully established

* staticcheck
2026-06-09 16:11:03 +05:30
Paul WellsandGitHub 77ecf920ff rtc: report participant session end time on room move (#4561)
MoveToRoom resets the participant reporter resolver to receive new
(room, participant_session) keys for the destination, but the source
room's participant_session row never gets an end_time — the periodic
duration scrape only emits one once disconnectedAt is set, and a move
doesn't transition the participant to DISCONNECTED. Report end_time
immediately before the reset so the row is closed out cleanly.
2026-06-03 21:35:39 -07:00
cnderrauberandGitHub 63be96f631 Prevent panic from nil(illegal) syncState.Subscriptions message (#4560) 2026-06-04 10:32:24 +08:00
cnderrauberandGitHub 356ae211a3 Config documentation for advertise_internal_ip and skip_external_ip_validation (#4552)
See https://github.com/livekit/mediatransportutil/pull/88
2026-06-01 14:37:08 +08:00
shishirngandGitHub 7c319a67d4 rtc: prevent duration reporting for inactive participants (#4550)
Added a check to ensure that duration is not published for participants
that never became active.
2026-05-27 14:39:04 -04:00
Paul WellsandGitHub cde8962709 rtc: emit per-data-track bytes via BytesTrackStats (#4540)
Data tracks (the new _data_track datachannel) previously only updated a
private dataTrackStats that logged a single summary at Close. Bytes never
reached the OnTrackStats -> TelemetryService.TrackStats pipeline that
media tracks and signal channels feed.

Wire DataTrack (UPSTREAM, publisher-home) and DataDownTrack (DOWNSTREAM,
per-subscriber) into BytesTrackStats on the same 5s cadence, mirroring
the media-track convention: subscriber's country and ID with publisher's
track ID for DOWNSTREAM. Cross-region proxy DataTracks leave the stats
pointer nil (no publisher reporter on that node, and relayed bytes would
double-count). Legacy dataTrackStats packet-loss/frame counters are
preserved.
2026-05-23 17:42:55 -07:00
Raja SubramanianandGitHub 062d12197f Use NACKQuueInterface type. (#4538)
And some extra logging for subscription permission when it fails.
2026-05-21 23:00:51 +05:30
Paul WellsandGitHub 7f08b04c1e Add IsIntentionalDisconnect helper (#4537)
Shared helper for callers that need to distinguish intentional/expected
participant closures (client leave, admin action, room teardown, migration)
from connection failures. Extracted from cloud's IsClosedIntentionally
switch so cloud-side code paths can share a single source of truth.
2026-05-20 11:42:51 -07:00
Raja SubramanianandGitHub 1ab2bf043b Clean up packet size logging (#4536)
Reverting
- https://github.com/livekit/livekit/pull/4521
- https://github.com/livekit/livekit/pull/4525

There are TWCC feedback packets that are larger than MTU. Seems to
happen under a couple of conditions
1. Bad client data, i. e. severely out-of-order packets, bad sequence
   numbers, etc.
2. On an ICE restart - this is rare, but it seemed to be flaky network
   with some packets arriving and some not and causing a lot of gaps.

Either case, not much to do. If fargmentation/re-assembly back to
publisher works, the feedback will make it through. If not, feedbacks
will be missed and clients have to work with some missing data which is
not unexpected and the protocol is designed to handle.

However, filed pion/interceptor issue just in case - https://github.com/pion/interceptor/issues/416
2026-05-20 23:58:05 +05:30
cnderrauberandGitHub 8ab92a80f6 Don't require media sections when joining (#4535)
* Don't require media sections when joining

Client except browser (rust/libwebrtc is known) could have problem
to fire ontrack event when reuses extra media section to subscribe
track, so disable this feature in server side and let client determine
if extra media sections are needed.

* lint
2026-05-20 13:28:51 +08:00
Paul WellsandGitHub 019a6640ae rtc: report participant kind code and details (#4534)
* rtc: report participant kind code and details

Plumb ParticipantKind and KindDetails through MediaTrack and
BytesTrackStats so track-level reporting can record the numeric kind
code plus details codes on every participant_session aggregation,
alongside the existing Kind string. Also picks up the new kind fields
on resolved BytesSignalStats participants.

Adds deployment/agentID/version to the agent worker logger.
2026-05-18 23:20:52 -07:00
Raja SubramanianandGitHub b32933b0d4 Log details of RTCP packets. (#4525)
* Log details of RTCP packets.

Seeing large (> MTU) packets on publisher peer connection RTCP. The
four types there are
- RTCP Receiver Reports
- NACK
- TWCC
- PLI

Can't think of what would be blowing up in size.

RTCP Receiver Report and PLI are fixed in size

NACKs vary, but the limit is 100 NACKs which should fit in 400 bytes
even if all of them are spread apart in the sequence number space.

TWCC varies, but a feedback packet is sent every 100ms or when it holds
100 packets. So, that also should not be too big.

Logging packet details to understand this better.

* revert debug
2026-05-14 18:55:00 +05:30
Raja SubramanianandGitHub ef2e5efe14 Log large packets receive/send. (#4521)
* Log large packets receive/send.

Seeing cases of servers reporting need for segmentation/re-assembly of
packets. So, logging packet receive/send for RTP/RTCP to check if
anything is seeing more than 1400 byte packets.

* log downtrack RTCP too
2026-05-13 16:04:53 +05:30
Raja SubramanianandGitHub 20d4a3a168 Populate data track loggers with context (#4514) 2026-05-09 10:14:48 +05:30
Paul WellsandGitHub 803999efad rename agent environment to deployment (#4506)
* rename agent environment to deployment

* deps
2026-05-05 14:19:40 -07:00
Paul WellsandGitHub 253f977d32 add duration seconds reporting (#4500)
* add duration seconds reporting

* deps

* deps
2026-05-02 06:19:23 -07:00
Paul WellsandGitHub ffab3bd308 add agent environment (#4498)
* add agent environment

* lint

* psrpc error

* deps
2026-05-01 19:30:06 -07:00
Raja SubramanianandGitHub ccdf23c8a6 Use mediatransportutil/codec package, no functional change (#4497) 2026-05-01 20:06:29 +05:30
olafal0andGitHub f51798bcf6 Fix publish-only limitations being incorrectly applied to receivers (#4495)
* Fix publish-only limitations being incorrectly applied receive-side in a single PC

* `StaticConfigurations` disabled some codecs for publish only, which worked in dual PC
* In single PC, the server incorrectly disabled these codecs in both directions
* Dual PC mode is unchanged; single PC handles per-direction filtering correctly

* Filter recv-side codecs to publish list in single-PC SDP answer

* Confirm H264 is present in offer in test
2026-04-30 18:49:34 +05:30
Raja SubramanianandGitHub a002337db1 Legacy TrackInfo.Simulcast flag. (#4493)
* Legacy TrackInfo.Simulcast flag.

When AddTrack did not send SimulcastCodecs, the legacy `Simulcast` flag
was not set. Fix it by setting the flag when a second layer is
published.

* staticcheck

* use the existing PrimaryReceiver function
2026-04-29 22:43:33 +05:30
Paul WellsandGitHub d7c2daf1ac report all simulcast layers (#4491) 2026-04-28 10:45:32 -07:00