From 886984861f52ba7e722e95f94595815a798506eb Mon Sep 17 00:00:00 2001 From: Adel Lahlou Date: Thu, 27 Feb 2025 12:17:06 -0800 Subject: [PATCH] remove performance based turn routing from CallRoutingControllerV2 --- .../textsecuregcm/WhisperServerService.java | 46 +------ .../controllers/CallRoutingControllerV2.java | 42 +------ .../CallRoutingControllerV2Test.java | 113 +----------------- 3 files changed, 12 insertions(+), 189 deletions(-) diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java index c2b0bd986..70f2e1f24 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java @@ -94,10 +94,6 @@ import org.whispersystems.textsecuregcm.backup.BackupsDb; import org.whispersystems.textsecuregcm.backup.Cdn3BackupCredentialGenerator; import org.whispersystems.textsecuregcm.backup.Cdn3RemoteStorageManager; import org.whispersystems.textsecuregcm.badges.ConfiguredProfileBadgeConverter; -import org.whispersystems.textsecuregcm.calls.routing.CallDnsRecordsManager; -import org.whispersystems.textsecuregcm.calls.routing.CallRoutingTableManager; -import org.whispersystems.textsecuregcm.calls.routing.DynamicConfigTurnRouter; -import org.whispersystems.textsecuregcm.calls.routing.TurnCallRouter; import org.whispersystems.textsecuregcm.captcha.CaptchaChecker; import org.whispersystems.textsecuregcm.captcha.CaptchaClient; import org.whispersystems.textsecuregcm.captcha.RegistrationCaptchaManager; @@ -142,7 +138,6 @@ import org.whispersystems.textsecuregcm.filters.RemoteDeprecationFilter; import org.whispersystems.textsecuregcm.filters.RequestStatisticsFilter; import org.whispersystems.textsecuregcm.filters.RestDeprecationFilter; import org.whispersystems.textsecuregcm.filters.TimestampResponseFilter; -import org.whispersystems.textsecuregcm.geo.MaxMindDatabaseManager; import org.whispersystems.textsecuregcm.grpc.AccountsAnonymousGrpcService; import org.whispersystems.textsecuregcm.grpc.AccountsGrpcService; import org.whispersystems.textsecuregcm.grpc.ErrorMappingInterceptor; @@ -813,45 +808,6 @@ public class WhisperServerService extends Application tokens = new ArrayList<>(); try { - if (experimentEnrollmentManager.isEnrolled(auth.getAccount().getNumber(), aci, "cloudflareTurn")) { - tokens.add(cloudflareTurnCredentialsManager.retrieveFromCloudflare()); - } + tokens.add(cloudflareTurnCredentialsManager.retrieveFromCloudflare()); } catch (Exception e) { - // emit counter, rely on Signal URL fallback CallRoutingControllerV2.CLOUDFLARE_TURN_ERROR_COUNTER.increment(); + throw e; } - Optional address = Optional.empty(); - try { - final String remoteAddress = (String) requestContext.getProperty( - RemoteAddressFilter.REMOTE_ADDRESS_ATTRIBUTE_NAME); - address = Optional.of(InetAddress.getByName(remoteAddress)); - } catch (UnknownHostException e) { - INVALID_IP_COUNTER.increment(); - } - - TurnServerOptions options = turnCallRouter.getRoutingFor(aci, address); - tokens.add(tokenGenerator.generateWithTurnServerOptions(options)); - return new GetCallingRelaysResponse(tokens); } diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/CallRoutingControllerV2Test.java b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/CallRoutingControllerV2Test.java index 1936fc816..3be9dc32b 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/CallRoutingControllerV2Test.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/CallRoutingControllerV2Test.java @@ -6,8 +6,6 @@ package org.whispersystems.textsecuregcm.controllers; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; @@ -18,11 +16,7 @@ import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; import io.dropwizard.testing.junit5.ResourceExtension; import jakarta.ws.rs.core.Response; import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.nio.charset.StandardCharsets; import java.util.List; -import java.util.Optional; import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -31,10 +25,6 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.whispersystems.textsecuregcm.auth.AuthenticatedDevice; import org.whispersystems.textsecuregcm.auth.CloudflareTurnCredentialsManager; import org.whispersystems.textsecuregcm.auth.TurnToken; -import org.whispersystems.textsecuregcm.auth.TurnTokenGenerator; -import org.whispersystems.textsecuregcm.calls.routing.TurnCallRouter; -import org.whispersystems.textsecuregcm.calls.routing.TurnServerOptions; -import org.whispersystems.textsecuregcm.experiment.ExperimentEnrollmentManager; import org.whispersystems.textsecuregcm.limits.RateLimiter; import org.whispersystems.textsecuregcm.limits.RateLimiters; import org.whispersystems.textsecuregcm.mappers.RateLimitExceededExceptionMapper; @@ -47,11 +37,6 @@ class CallRoutingControllerV2Test { private static final String GET_CALL_RELAYS_PATH = "v2/calling/relays"; private static final String REMOTE_ADDRESS = "123.123.123.1"; - private static final TurnServerOptions TURN_SERVER_OPTIONS = new TurnServerOptions( - "example.domain.org", - Optional.of(List.of("stun:12.34.56.78")), - Optional.of(List.of("stun:example.domain.org")) - ); private static final TurnToken CLOUDFLARE_TURN_TOKEN = new TurnToken( "ABC", "XYZ", @@ -61,12 +46,8 @@ class CallRoutingControllerV2Test { private static final RateLimiters rateLimiters = mock(RateLimiters.class); private static final RateLimiter getCallEndpointLimiter = mock(RateLimiter.class); - private static final ExperimentEnrollmentManager experimentEnrollmentManager = mock( - ExperimentEnrollmentManager.class); - private static final TurnTokenGenerator turnTokenGenerator = new TurnTokenGenerator("bloop".getBytes(StandardCharsets.UTF_8)); private static final CloudflareTurnCredentialsManager cloudflareTurnCredentialsManager = mock( CloudflareTurnCredentialsManager.class); - private static final TurnCallRouter turnCallRouter = mock(TurnCallRouter.class); private static final ResourceExtension resources = ResourceExtension.builder() .addProvider(AuthHelper.getAuthFilter()) @@ -75,8 +56,7 @@ class CallRoutingControllerV2Test { .addProvider(new TestRemoteAddressFilterProvider(REMOTE_ADDRESS)) .setMapper(SystemMapper.jsonMapper()) .setTestContainerFactory(new GrizzlyWebTestContainerFactory()) - .addResource(new CallRoutingControllerV2(rateLimiters, turnCallRouter, turnTokenGenerator, - experimentEnrollmentManager, cloudflareTurnCredentialsManager)) + .addResource(new CallRoutingControllerV2(rateLimiters, cloudflareTurnCredentialsManager)) .build(); @BeforeEach @@ -86,58 +66,19 @@ class CallRoutingControllerV2Test { @AfterEach void tearDown() { - reset(experimentEnrollmentManager, rateLimiters, getCallEndpointLimiter, turnCallRouter); + reset( rateLimiters, getCallEndpointLimiter); } - void initializeMocksWith(Optional signalTurn, Optional cloudflare) { - signalTurn.ifPresent(options -> { + void initializeMocksWith(TurnToken cloudflareToken) { try { - when(turnCallRouter.getRoutingFor( - eq(AuthHelper.VALID_UUID), - eq(Optional.of(InetAddress.getByName(REMOTE_ADDRESS)))) - ).thenReturn(options); - } catch (UnknownHostException ignored) { - } - }); - cloudflare.ifPresent(token -> { - when(experimentEnrollmentManager.isEnrolled(AuthHelper.VALID_NUMBER, AuthHelper.VALID_UUID, "cloudflareTurn")) - .thenReturn(true); - try { - when(cloudflareTurnCredentialsManager.retrieveFromCloudflare()).thenReturn(token); + when(cloudflareTurnCredentialsManager.retrieveFromCloudflare()).thenReturn(cloudflareToken); } catch (IOException ignored) { } - }); - } - - @Test - void testGetRelaysSignalRoutingOnly() { - TurnServerOptions options = TURN_SERVER_OPTIONS; - initializeMocksWith(Optional.of(options), Optional.empty()); - - try (Response rawResponse = resources.getJerseyTest() - .target(GET_CALL_RELAYS_PATH) - .request() - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD)) - .get()) { - - assertThat(rawResponse.getStatus()).isEqualTo(200); - - CallRoutingControllerV2.GetCallingRelaysResponse response = rawResponse.readEntity( - CallRoutingControllerV2.GetCallingRelaysResponse.class); - List relays = response.relays(); - assertThat(relays).hasSize(1); - assertThat(relays.getFirst().username()).isNotEmpty(); - assertThat(relays.getFirst().password()).isNotEmpty(); - assertThat(relays.getFirst().hostname()).isEqualTo(options.hostname()); - assertThat(relays.getFirst().urlsWithIps()).isEqualTo(options.urlsWithIps().get()); - assertThat(relays.getFirst().urls()).isEqualTo(options.urlsWithHostname().get()); - } } @Test void testGetRelaysBothRouting() { - TurnServerOptions options = TURN_SERVER_OPTIONS; - initializeMocksWith(Optional.of(options), Optional.of(CLOUDFLARE_TURN_TOKEN)); + initializeMocksWith(CLOUDFLARE_TURN_TOKEN); try (Response rawResponse = resources.getJerseyTest() .target(GET_CALL_RELAYS_PATH) @@ -151,49 +92,7 @@ class CallRoutingControllerV2Test { CallRoutingControllerV2.GetCallingRelaysResponse.class); List relays = response.relays(); - assertThat(relays).hasSize(2); - - assertThat(relays.getFirst()).isEqualTo(CLOUDFLARE_TURN_TOKEN); - - TurnToken token = relays.get(1); - assertThat(token.username()).isNotEmpty(); - assertThat(token.password()).isNotEmpty(); - assertThat(token.hostname()).isEqualTo(options.hostname()); - assertThat(token.urlsWithIps()).isEqualTo(options.urlsWithIps().get()); - assertThat(token.urls()).isEqualTo(options.urlsWithHostname().get()); - } - } - - @Test - void testGetRelaysInvalidIpSuccess() throws UnknownHostException { - TurnServerOptions options = new TurnServerOptions( - "example.domain.org", - Optional.of(List.of()), - Optional.of(List.of("stun:example.domain.org")) - ); - - when(turnCallRouter.getRoutingFor( - eq(AuthHelper.VALID_UUID), - eq(Optional.of(InetAddress.getByName(REMOTE_ADDRESS)))) - ).thenReturn(options); - try (Response rawResponse = resources.getJerseyTest() - .target(GET_CALL_RELAYS_PATH) - .request() - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD)) - .get()) { - - assertThat(rawResponse.getStatus()).isEqualTo(200); - CallRoutingControllerV2.GetCallingRelaysResponse response = rawResponse.readEntity( - CallRoutingControllerV2.GetCallingRelaysResponse.class - ); - - assertThat(response.relays()).hasSize(1); - TurnToken token = response.relays().getFirst(); - assertThat(token.username()).isNotEmpty(); - assertThat(token.password()).isNotEmpty(); - assertThat(token.hostname()).isEqualTo(options.hostname()); - assertThat(token.urlsWithIps()).isEqualTo(options.urlsWithIps().get()); - assertThat(token.urls()).isEqualTo(options.urlsWithHostname().get()); + assertThat(relays).isEqualTo(List.of(CLOUDFLARE_TURN_TOKEN)); } }