diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/BackgroundMessageRetriever.java b/app/src/main/java/org/thoughtcrime/securesms/messages/BackgroundMessageRetriever.java index 00b2623e7..e85b975be 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/BackgroundMessageRetriever.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/BackgroundMessageRetriever.java @@ -132,8 +132,7 @@ public class BackgroundMessageRetriever { * care of it. */ public static boolean shouldIgnoreFetch() { - return ApplicationDependencies.getAppForegroundObserver().isForegrounded() && - !ApplicationDependencies.getSignalServiceNetworkAccess().isCensored(); + return ApplicationDependencies.getAppForegroundObserver().isForegrounded(); } private static String logSuffix(long startTime) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.java b/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.java index 21748cfc7..eceac5164 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageObserver.java @@ -132,7 +132,7 @@ public class IncomingMessageObserver { } public boolean isDecryptionDrained() { - return decryptionDrained || networkAccess.isCensored(); + return decryptionDrained; } public void notifyDecryptionsDrained() { @@ -179,8 +179,7 @@ public class IncomingMessageObserver { return registered && (appVisible || !fcmEnabled || forceWebsocket || Util.hasItems(keepAliveTokens)) && - hasNetwork && - !networkAccess.isCensored(); + hasNetwork; } private synchronized void waitForConnectionNecessary() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.kt b/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.kt index b7c08e37e..325c1f5bb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.kt @@ -69,7 +69,7 @@ open class SignalServiceNetworkAccess(context: Context) { private const val COUNTRY_CODE_UZBEKISTAN = 998 private const val COUNTRY_CODE_UKRAINE = 380 - private const val G_HOST = "europe-west1-signal-cdn-reflector.cloudfunctions.net" + private const val G_HOST = "reflector-nrgwuv7kwq-uc.a.run.app" private const val F_SERVICE_HOST = "textsecure-service.whispersystems.org.global.prod.fastly.net" private const val F_STORAGE_HOST = "storage.signal.org.global.prod.fastly.net" private const val F_CDN_HOST = "cdn.signal.org.global.prod.fastly.net" @@ -276,7 +276,7 @@ open class SignalServiceNetworkAccess(context: Context) { val cdsUrls: Array = hostConfigs.map { SignalContactDiscoveryUrl("${it.baseUrl}/directory", it.host, gTrustStore, it.connectionSpec) }.toTypedArray() val kbsUrls: Array = hostConfigs.map { SignalKeyBackupServiceUrl("${it.baseUrl}/backup", it.host, gTrustStore, it.connectionSpec) }.toTypedArray() val storageUrls: Array = hostConfigs.map { SignalStorageUrl("${it.baseUrl}/storage", it.host, gTrustStore, it.connectionSpec) }.toTypedArray() - val cdsiUrls: Array = listOf(SignalCdsiUrl(BuildConfig.SIGNAL_CDSI_URL, serviceTrustStore)).toTypedArray() + val cdsiUrls: Array = hostConfigs.map { SignalCdsiUrl("${it.baseUrl}/cdsi", it.host, gTrustStore, it.connectionSpec) }.toTypedArray() return SignalServiceConfiguration( serviceUrls, diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/services/CdsiSocket.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/services/CdsiSocket.java index d5c3a4088..fd845c2c7 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/services/CdsiSocket.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/services/CdsiSocket.java @@ -14,6 +14,7 @@ import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulRespons import org.whispersystems.signalservice.api.push.exceptions.CdsiResourceExhaustedException; import org.whispersystems.signalservice.api.util.Tls12SocketFactory; import org.whispersystems.signalservice.api.util.TlsProxySocketFactory; +import org.whispersystems.signalservice.internal.configuration.SignalCdsiUrl; import org.whispersystems.signalservice.internal.configuration.SignalProxy; import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration; import org.whispersystems.signalservice.internal.push.CdsiResourceExhaustedResponse; @@ -29,7 +30,6 @@ import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.time.Instant; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; @@ -54,17 +54,17 @@ final class CdsiSocket { private static final String TAG = CdsiSocket.class.getSimpleName(); - private final OkHttpClient okhttp; - private final String baseUrl; - private final String mrEnclave; + private final SignalCdsiUrl cdsiUrl; + private final OkHttpClient okhttp; + private final String mrEnclave; private Cds2Client client; CdsiSocket(SignalServiceConfiguration configuration, String mrEnclave) { - this.baseUrl = configuration.getSignalCdsiUrls()[0].getUrl(); + this.cdsiUrl = chooseUrl(configuration.getSignalCdsiUrls()); this.mrEnclave = mrEnclave; - Pair socketFactory = createTlsSocketFactory(configuration.getSignalCdsiUrls()[0].getTrustStore()); + Pair socketFactory = createTlsSocketFactory(cdsiUrl.getTrustStore()); OkHttpClient.Builder builder = new OkHttpClient.Builder() .sslSocketFactory(new Tls12SocketFactory(socketFactory.first()), socketFactory.second()) @@ -89,13 +89,17 @@ final class CdsiSocket { return Observable.create(emitter -> { AtomicReference stage = new AtomicReference<>(Stage.WAITING_TO_INITIALIZE); - String url = String.format("%s/v1/%s/discovery", baseUrl, mrEnclave); - Request request = new Request.Builder() + String url = String.format("%s/v1/%s/discovery", cdsiUrl.getUrl(), mrEnclave); + Request.Builder request = new Request.Builder() .url(url) - .addHeader("Authorization", basicAuth(username, password)) - .build(); + .addHeader("Authorization", basicAuth(username, password)); - WebSocket webSocket = okhttp.newWebSocket(request, new WebSocketListener() { + if (cdsiUrl.getHostHeader().isPresent()) { + request.addHeader("Host", cdsiUrl.getHostHeader().get()); + Log.w(TAG, "Using alternate host: " + cdsiUrl.getHostHeader().get()); + } + + WebSocket webSocket = okhttp.newWebSocket(request.build(), new WebSocketListener() { @Override public void onOpen(WebSocket webSocket, Response response) { Log.d(TAG, "[onOpen]"); @@ -225,6 +229,10 @@ final class CdsiSocket { } } + private static SignalCdsiUrl chooseUrl(SignalCdsiUrl[] urls) { + return urls[(int) (Math.random() * urls.length)]; + } + private enum Stage { INIT, WAITING_FOR_CONNECTION, diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/websocket/WebSocketConnection.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/websocket/WebSocketConnection.java index 0b2e3509c..ae0fc90b0 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/websocket/WebSocketConnection.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/websocket/WebSocketConnection.java @@ -13,6 +13,7 @@ import org.whispersystems.signalservice.api.websocket.HealthMonitor; import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState; import org.whispersystems.signalservice.internal.configuration.SignalProxy; import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration; +import org.whispersystems.signalservice.internal.configuration.SignalServiceUrl; import org.whispersystems.signalservice.internal.util.BlacklistingTrustManager; import org.whispersystems.signalservice.internal.util.Util; @@ -75,6 +76,7 @@ public class WebSocketConnection extends WebSocketListener { private final Optional signalProxy; private final BehaviorSubject webSocketState; private final boolean allowStories; + private final SignalServiceUrl serviceUrl; private WebSocket client; @@ -105,8 +107,9 @@ public class WebSocketConnection extends WebSocketListener { this.healthMonitor = healthMonitor; this.webSocketState = BehaviorSubject.createDefault(WebSocketConnectionState.DISCONNECTED); this.allowStories = allowStories; + this.serviceUrl = serviceConfiguration.getSignalServiceUrls()[0]; - String uri = serviceConfiguration.getSignalServiceUrls()[0].getUrl().replace("https://", "wss://").replace("http://", "ws://"); + String uri = serviceUrl.getUrl().replace("https://", "wss://").replace("http://", "ws://"); if (credentialsProvider.isPresent()) { this.wsUri = uri + "/v1/websocket/" + extraPathUri + "?login=%s&password=%s"; @@ -162,6 +165,11 @@ public class WebSocketConnection extends WebSocketListener { requestBuilder.addHeader("X-Signal-Receive-Stories", allowStories ? "true" : "false"); + if (serviceUrl.getHostHeader().isPresent()) { + requestBuilder.addHeader("Host", serviceUrl.getHostHeader().get()); + Log.w(TAG, "Using alternate host: " + serviceUrl.getHostHeader().get()); + } + webSocketState.onNext(WebSocketConnectionState.CONNECTING); this.client = okHttpClient.newWebSocket(requestBuilder.build(), this);