Before this change, if the SDP offer has paused rids,
SDP answer echoed it back. That causes issues where enabling/disabling
of layers is signalled via the signalling channel. The following
scenario breaks
1. PeerB signals PeerA to disable all simulcast layers.
2. PeerA sends an SDP offer with RIDs disabled.
a. NOTE: A renegotiation is not needed, but happens for a different
reason.
3. PeerB signals again to PeerA to re-enable layers.
4. PeerB sends answer for the offer in Step 2 with paused rids.
5. PeerA keeps layers paused.
Adding a setting engine option to not change existing behaviour. Pause
state of a rid will be ignored if setting is enabled.
As defined in [RFC8839], when an ICE restart occurs, a new SDP offer/answer exchange is triggered. However, as WHIP does not support renegotiation of non-ICE-related SDP information, a WHIP client will not send a new offer when an ICE restart occurs. Instead, the WHIP client and WHIP session will only exchange the relevant ICE information via an HTTP PATCH request as defined in Section 4.3.1 and MUST assume that the previously negotiated non-ICE-related SDP information still applies after the ICE restart.
When performing an ICE restart, the WHIP client MUST include the updated "ice-pwd" and "ice-ufrag" in the SDP fragment of the HTTP PATCH request body as well as the new set of gathered ICE candidates as defined in [RFC8840]. Similar to what is defined in Section 4.3.2, as per [RFC9429], only "m=" sections not marked as bundle-only can gather ICE candidates, so given that the "max-bundle" policy is being used, the SDP fragment will contain only the offerer-tagged "m=" line of the bundle group. A WHIP client sending a PATCH request for performing ICE restart MUST contain an If-Match header field with a field-value of "*" as per Section 13.1.1 of [RFC9110].
Co-authored-by: Joe Turki <git@joeturki.com>
This PR contains the following updates:
| Package | Change | Age | Confidence |
|---|---|---|---|
| [github.com/pion/ice/v4](https://redirect.github.com/pion/ice) |
`v4.0.10` -> `v4.0.11` |
[](https://docs.renovatebot.com/merge-confidence/)
|
[](https://docs.renovatebot.com/merge-confidence/)
|
---
### Release Notes
<details>
<summary>pion/ice (github.com/pion/ice/v4)</summary>
###
[`v4.0.11`](https://redirect.github.com/pion/ice/releases/tag/v4.0.11)
[Compare
Source](https://redirect.github.com/pion/ice/compare/v4.0.10...v4.0.11)
#### Changelog
-
[`4537cf7`](4537cf7b6c)
Fix a deadlock in TaskLoop
-
[`30c406b`](30c406b788)
Update module github.com/pion/mdns/v2 to v2.1.0
([#​839](https://redirect.github.com/pion/ice/issues/839))
-
[`32ca87a`](32ca87a218)
Update module github.com/pion/turn/v4 to v4.1.3
([#​838](https://redirect.github.com/pion/ice/issues/838))
-
[`43a7803`](43a7803ff3)
Always close/cleanup on runners
-
[`06dd638`](06dd6383d6)
Skip link-local-ipv6 on macos
-
[`1901fa6`](1901fa602a)
Update CI configs to v0.11.33
-
[`db55950`](db55950324)
Update module github.com/pion/transport/v3 to v3.1.1
-
[`e1b445c`](e1b445c641)
Wire rest of the options
-
[`65bb60d`](65bb60dec1)
Finish agent options
-
[`4c9f55e`](4c9f55e84f)
Update module github.com/pion/transport/v3 to v3.1.0
-
[`7336a27`](7336a27f8a)
Update module github.com/pion/turn/v4 to v4.1.2
-
[`f56f52c`](f56f52ca84)
Add automatic renomination
-
[`649e13a`](649e13aab5)
Remove unnecessary comments in agent.go
-
[`d1491ba`](d1491ba5ca)
Fix race condition in setSelectedPair
-
[`163dca5`](163dca56e4)
Update module github.com/pion/stun/v3 to v3.0.1
-
[`b5142e4`](b5142e4d36)
Deduplicated error messages for easier debugging
-
[`43dce03`](43dce03277)
Update CI configs to v0.11.31
-
[`8217b53`](8217b53fa6)
Update module github.com/pion/transport/v3 to v3.0.8
-
[`56839aa`](56839aaef5)
Add support for continual gathering
-
[`ed14a44`](ed14a44c7f)
Update default relay-only candidate wait
-
[`3897c30`](3897c30941)
Remove nolint, validate port
-
[`ee3a2e4`](ee3a2e4341)
Fix the tests on Windows
-
[`92565e1`](92565e1979)
Update CI configs to v0.11.29
-
[`965031e`](965031eb25)
Add IceCandidatePairStats
-
[`1ce9ff1`](1ce9ff1d8d)
Apply go modernize
-
[`f7437da`](f7437da850)
Improve code cov by adding various tests
-
[`14b3ccc`](14b3cccabf)
Replace verbose check with slices.Contains
-
[`0d56129`](0d561290f4)
Fix typo in FirstResponseReceivedAt
-
[`0227f4b`](0227f4ba5a)
Fix flakiness in tcp\_packet\_conn test
-
[`6fbde9f`](6fbde9fb03)
Improve code cov for tcp\_mux\_multi
-
[`1ac8975`](1ac89758a3)
Improve code cov for tcp\_packet\_conn
-
[`351ccd8`](351ccd8088)
Improve code cov for udp\_mux\_universal
-
[`1a61855`](1a618559fc)
Improve code cov for udp\_muxed\_conn
-
[`3deadbd`](3deadbd6f1)
Re-enable ipv6 UDP mux tests in i386
-
[`67dccba`](67dccba0a6)
Update CI configs to v0.11.26
-
[`850dec4`](850dec457f)
Update CI configs to v0.11.25
-
[`82b1ba3`](82b1ba3a48)
Update CI configs to v0.11.24
-
[`b717342`](b717342750)
Update module github.com/stretchr/testify to v1.11.1
-
[`71de7d2`](71de7d2b18)
Add more configuration to AgentOptions
-
[`4b50bc8`](4b50bc8078)
Add support for renomination
-
[`fb0107e`](fb0107e8ae)
Update module github.com/stretchr/testify to v1.11.0
-
[`3d59690`](3d59690a71)
Update module github.com/pion/turn/v4 to v4.1.1
-
[`be0657f`](be0657f17b)
Fix lint errors
-
[`e13ec52`](e13ec52278)
Update CI configs to v0.11.22
-
[`0b78af9`](0b78af9301)
Update module github.com/pion/dtls/v3 to v3.0.7
-
[`1d2f139`](1d2f139ce3)
Update module github.com/pion/turn/v4 to v4.1.0
-
[`2c04474`](2c04474e38)
Implement ICE Role conflict resolution
-
[`f6a1153`](f6a1153ce7)
Optimize slice allocation in UDPMuxDefault
-
[`cc019aa`](cc019aabdf)
Update module github.com/pion/logging to v0.2.4
-
[`2a0a17e`](2a0a17ed34)
Update module github.com/pion/turn/v4 to v4.0.2
-
[`b818e2c`](b818e2cbcf)
Update module github.com/pion/dtls/v3 to v3.0.6
-
[`8930d1b`](8930d1b7d0)
Update CI configs to v0.11.20
-
[`613ac5a`](613ac5a204)
Use atomic.Uint64 for thread-safe byte counters
-
[`eef8d96`](eef8d96d36)
Replace interface{} with any type alias
-
[`bbb9792`](bbb9792ca9)
Change activeTCPConn.close to atomic.Bool
-
[`753c2a0`](753c2a0fe8)
Update CI configs to v0.11.19
-
[`f32c107`](f32c107a62)
Update lint rules, force testify/assert for tests
</details>
---
### Configuration
📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).
🚦 **Automerge**: Enabled.
♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/pion/webrtc).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi4xOS45IiwidXBkYXRlZEluVmVyIjoiNDIuMTkuOSIsInRhcmdldEJyYW5jaCI6Im1hc3RlciIsImxhYmVscyI6W119-->
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
## Summary
Fixed inconsistent test duration and occational `panic timeout` in
Test_PeerConnection_RTX_E2E
```
panic: timeout
goroutine 4309 [running]:
github.com/pion/webrtc/v4.Test_PeerConnection_RTX_E2E.TimeOut.func5()
/Users/ytakeda/go/pkg/mod/github.com/pion/transport/v3@v3.1.1/test/util.go:27 +0xb4
created by time.goFunc
/Users/ytakeda/sdk/go1.25.4/src/time/sleep.go:215 +0x44
```
### Problem
The test was timing out intermittently (0.2s-18.6s variance) when run
with the race detector due to:
* Random 20% packet loss causing unpredictable RTX detection timing
* Missing goroutine cleanup causing hangs
* Race detector overhead amplifying timing issues
```
go test -v -race -run Test_PeerConnection_RTX_E2E -count 20
=== RUN Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (7.46s)
=== RUN Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (1.42s)
=== RUN Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.72s)
=== RUN Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (18.62s)
=== RUN Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (1.22s)
:
```
### Solution
1. Deterministic packet dropping - Changed from random 20% loss to dropping every 5th packet, ensuring predictable NACK/RTX triggering
2. Dynamic payload type detection - Uses negotiated payload type instead of hardcoded 96, making the test robust to codec configuration changes
3. Proper goroutine cleanup - Added context-based cleanup for RTCP reader and OnTrack callback
4. Fail-fast validation - Checks assertion return values and exits immediately on failure
5. Correct cleanup order - Closes peer connections before stopping the virtual network
### Result
* Consistent ~0.21s execution time (tested 50 runs with race detector)
* No more timeouts
* Still validates NACK/RTX behavior as intended by PR #2919
```
go test -v -race -run Test_PeerConnection_RTX_E2E -count 10
=== RUN Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
=== RUN Test_PeerConnection_RTX_E2E
--- PASS: Test_PeerConnection_RTX_E2E (0.21s)
PASS
ok github.com/pion/webrtc/v4 3.373s
```
The test intentionally drops the second outgoing RTP packet and verifies
that:
- exactly one NACK is sent for the missing packet,
- exactly one RTX retransmission is received,
- no additional NACK/RTX packets appear after a short grace period.
- The test is currently skipped (t.Skip()) so it doesn't break CI.
- Minimal Test for issue #3063
The code currently ignores the first packet when reading Simulcast IDs
from a new SSRC, and probes only subsequent packets. This commit makes
it so that we consider the first packet as well (which we already have
read). Helps if the publisher only sends Simulcast IDs on the first
packet.