openvidu-test-e2e: cut the SFU ICE-TCP port too in connection quality tests to avoid unwanted reconnections and get the LOST event

pull/907/head
pabloFuente 2026-09-07 00:00:05 +02:00
parent 8a2653fc05
commit a06aea54c4
2 changed files with 24 additions and 8 deletions

View File

@ -17,6 +17,14 @@ public class NetworkConditioner {
private static final String PUMBA_IMAGE = "gaiaadm/pumba:1.2.1";
private static final String NETTOOLS_IMAGE = "ghcr.io/alexei-led/pumba-alpine-nettools:sha-19e0a46";
/**
* TCP port of the SFU's ICE-TCP candidates (livekit.yaml {@code rtc.tcp_port}).
* Every OUTBOUND impairment meant to cut a publisher's media must cover it too.
* (clients can reconnect to this port with an ICE restart when the UDP media
* path is dead).
*/
public static final String SFU_ICE_TCP_PORT = "7881";
private static final String DOCKER_SOCK = "/var/run/docker.sock";
// Where Pumba installs the netem qdisc of a port-scoped netem impairment. Pumba
@ -217,17 +225,24 @@ public class NetworkConditioner {
* unlike a flaky 100-filter netem
*
* Stops the running Pumba first (avoids conflicting root qdiscs), then installs
* a SINGLE iptables OUTPUT DROP rule over the whole {@code mediaPortRange}
* (e.g. "7900-7999").
* an iptables OUTPUT DROP rule over the whole UDP {@code mediaPortRange} (e.g.
* "7900-7999") plus one over the SFU's ICE-TCP port
* ({@link #SFU_ICE_TCP_PORT}), so the browser's reconnect cannot fail over to
* TCP and escape the blackout.
*/
public static void blackoutOutbound(String targetContainer, String mediaPortRange, int durationSec) {
clear();
final String iptablesRange = mediaPortRange.replace('-', ':'); // iptables ranges are low:high
log.info("Total OUTBOUND blackout (100% loss) on container {} across SFU media port range {} "
+ "(single iptables OUTPUT DROP)", targetContainer, mediaPortRange);
log.info("Total OUTBOUND blackout (100% loss) on container {} across SFU media port range {} and "
+ "ICE-TCP port {} (iptables OUTPUT DROP)", targetContainer, mediaPortRange, SFU_ICE_TCP_PORT);
String out = nettools(targetContainer, "iptables",
"-A OUTPUT -o eth0 -p udp --dport " + iptablesRange + " -j DROP");
log.info("blackout iptables -A OUTPUT result: {}", out);
log.info("blackout iptables -A OUTPUT (udp {}) result: {}", iptablesRange, out);
// clear() flushes the whole OUTPUT chain, so this rule goes away with the other
// one
String outTcp = nettools(targetContainer, "iptables",
"-A OUTPUT -o eth0 -p tcp --dport " + SFU_ICE_TCP_PORT + " -j DROP");
log.info("blackout iptables -A OUTPUT (tcp {}) result: {}", SFU_ICE_TCP_PORT, outTcp);
blackoutContainer = targetContainer;
}

View File

@ -1011,9 +1011,10 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
regularUser.getEventManager().clearAllCurrentEvents();
if (outboundPacketLoss != null) {
// Drop packets the client sends through the publisher PC
NetworkConditioner.applyLossToOutboundPackets(getNetemContainerName(punchbagUser), publisherPortInSfu,
outboundPacketLoss, 10000);
// Drop packets the client sends through the publisher PC. The SFU's ICE-TCP
// port is impaired alike to avoid TCP fallbacks from the client side
NetworkConditioner.applyLossToOutboundPackets(getNetemContainerName(punchbagUser),
publisherPortInSfu + "," + NetworkConditioner.SFU_ICE_TCP_PORT, outboundPacketLoss, 10000);
}
if (inboundPacketLoss != null) {
// Drop packets the client receives through the subscriber PC (or publisher PC