From 339f5fedeb0a9d17d79898d3657056b6e6b2e39a Mon Sep 17 00:00:00 2001 From: Brutus5000 Date: Mon, 24 Feb 2025 00:44:24 +0100 Subject: [PATCH] Always use public STUN servers --- .../faforever/iceadapter/ice/GameSession.java | 13 ++++++++- .../iceadapter/ice/PeerIceModule.java | 28 +++++++++++++------ 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/ice-adapter/src/main/java/com/faforever/iceadapter/ice/GameSession.java b/ice-adapter/src/main/java/com/faforever/iceadapter/ice/GameSession.java index 95a5c44..dc313f9 100644 --- a/ice-adapter/src/main/java/com/faforever/iceadapter/ice/GameSession.java +++ b/ice-adapter/src/main/java/com/faforever/iceadapter/ice/GameSession.java @@ -37,6 +37,11 @@ public class GameSession { private static final String STUN = "stun"; private static final String TURN = "turn"; + private static final List PUBLIC_STUN_SERVERS = List.of( + new TransportAddress("stun.cloudflare.com", 3478, Transport.UDP), + new TransportAddress("stun.l.google.com", 19302, Transport.UDP), + new TransportAddress("stun.sipgate.net", 3478, Transport.UDP)); + @Getter private final Map peers = new ConcurrentHashMap<>(); @@ -104,7 +109,13 @@ public void close() { * Called by the client via jsonRPC */ public static void setIceServers(List> iceServersData) { - GameSession.iceServers.clear(); + iceServers.clear(); + + PUBLIC_STUN_SERVERS.forEach(stunServer -> { + var iceServer = new IceServer(); + iceServer.getStunAddresses().add(stunServer); + iceServers.add(iceServer); + }); if (iceServersData.isEmpty()) { return; diff --git a/ice-adapter/src/main/java/com/faforever/iceadapter/ice/PeerIceModule.java b/ice-adapter/src/main/java/com/faforever/iceadapter/ice/PeerIceModule.java index 6784319..5f10b76 100644 --- a/ice-adapter/src/main/java/com/faforever/iceadapter/ice/PeerIceModule.java +++ b/ice-adapter/src/main/java/com/faforever/iceadapter/ice/PeerIceModule.java @@ -78,6 +78,7 @@ public PeerIceModule(Peer peer) { /** * Updates the current iceState and informs the client via RPC + * * @param newState the new State */ private void setState(IceState newState) { @@ -124,16 +125,22 @@ private void createAgent() { private void gatherCandidates() { log.info(getLogPrefix() + "Gathering ice candidates"); - List iceServers = getViableIceServers(); - - iceServers.stream() + // For STUN all servers are relevant (latency is not an issue) + GameSession.getIceServers().stream() .flatMap(s -> s.getStunAddresses().stream()) - .map(StunCandidateHarvester::new) - .forEach(agent::addCandidateHarvester); - iceServers.forEach(iceServer -> iceServer.getTurnAddresses().stream() - .map(a -> new TurnCandidateHarvester( - a, new LongTermCredential(iceServer.getTurnUsername(), iceServer.getTurnCredential()))) - .forEach(agent::addCandidateHarvester)); + .forEach(address -> { + log.info("Add STUN harvester for {}", address.getHostName()); + agent.addCandidateHarvester(new StunCandidateHarvester(address)); + }); + + // TURN is latency sensitive + List iceServers = getViableIceServers(); + iceServers.forEach(iceServer -> iceServer.getTurnAddresses().forEach(address -> { + var harvester = new TurnCandidateHarvester( + address, new LongTermCredential(iceServer.getTurnUsername(), iceServer.getTurnCredential())); + log.info("Add TURN harvester for {}", address.getHostName()); + agent.addCandidateHarvester(harvester); + })); CompletableFuture gatheringFuture = CompletableFuture.runAsync(() -> { try { @@ -238,6 +245,7 @@ private List getViableIceServers() { /** * Starts harvesting local candidates if in answer mode, then initiates the actual ICE process + * * @param remoteCandidatesMessage */ public synchronized void onIceMessageReceived(CandidatesMessage remoteCandidatesMessage) { @@ -418,6 +426,7 @@ private synchronized void reinitIce() { /** * Data received from FA, prepends prefix and sends it via ICE to the other peer + * * @param faData * @param length */ @@ -430,6 +439,7 @@ void onFaDataReceived(byte[] faData, int length) { /** * Send date via ice to the other peer + * * @param data * @param offset * @param length