Skip to content
File

Blob: firmware/vendor/str0m/tests/ice-remote-binding-keepalive.rs

rust83 lines
1use std::net::Ipv4Addr;
2use std::time::Duration;
3 
4use netem::NetemConfig;
5use str0m::{Event, IceConnectionState, RtcError};
6 
7mod common;
8use common::{Peer, TestRtc, init_crypto_default, init_log, progress};
9 
10/// Test that candidate pairs are kept alive based on incoming binding requests,
11/// even when outgoing binding requests are not being responded to.
12///
13/// This specifically tests the fix for issue #846 where Chrome v144+ would cause
14/// disconnections when not using ICE Lite mode. The fix ensures that
15/// `is_still_possible()` considers recently received binding requests as evidence
16/// of connectivity, similar to how ICE Lite mode works.
17#[test]
18pub fn pair_kept_alive_by_remote_binding_requests() -> Result<(), RtcError> {
19 init_log();
20 init_crypto_default();
21 
22 // Create two non-ICE-lite peers
23 let mut l = TestRtc::new(Peer::Left);
24 let mut r = TestRtc::new(Peer::Right);
25 
26 // Add some latency to simulate real network conditions
27 l.set_netem(NetemConfig::new().latency(Duration::from_millis(10)));
28 r.set_netem(NetemConfig::new().latency(Duration::from_millis(10)));
29 
30 l.add_host_candidate((Ipv4Addr::new(1, 1, 1, 1), 1000).into());
31 r.add_host_candidate((Ipv4Addr::new(2, 2, 2, 2), 2000).into());
32 
33 let mut change = l.sdp_api();
34 change.add_channel("ch".into());
35 let (offer, pending) = change.apply().unwrap();
36 let answer = r.sdp_api().accept_offer(offer)?;
37 l.sdp_api().accept_answer(pending, answer)?;
38 
39 // First, establish the connection
40 loop {
41 if l.duration() > Duration::from_secs(5) {
42 panic!("Timeout waiting for initial connection");
43 }
44 
45 if l.is_connected() && r.is_connected() {
46 break;
47 }
48 
49 progress(&mut l, &mut r)?;
50 }
51 
52 // Now continue running for a while to ensure the connection stays stable
53 // This tests that the pairs are not prematurely pruned
54 let stable_start = l.duration();
55 loop {
56 if l.duration() - stable_start > Duration::from_secs(3) {
57 // Connection remained stable for 3 seconds
58 break;
59 }
60 
61 let l_disconnected = l.events.iter().any(|(_, e)| {
62 matches!(
63 e,
64 Event::IceConnectionStateChange(IceConnectionState::Disconnected)
65 )
66 });
67 let r_disconnected = r.events.iter().any(|(_, e)| {
68 matches!(
69 e,
70 Event::IceConnectionStateChange(IceConnectionState::Disconnected)
71 )
72 });
73 
74 if l_disconnected || r_disconnected {
75 panic!("Connection was unexpectedly disconnected during stability test");
76 }
77 
78 progress(&mut l, &mut r)?;
79 }
80 
81 Ok(())
82}