Make sure not more than one libsignal Network instance is ever created

Co-authored-by: Greyson Parrelli <greyson@signal.org>
This commit is contained in:
moiseev-signal
2024-04-01 11:33:10 -07:00
committed by Greyson Parrelli
parent 544cc06f13
commit 78e36b85d4
6 changed files with 35 additions and 7 deletions
@@ -98,7 +98,7 @@ object ContactDiscoveryRefreshV2 {
Optional.empty(), Optional.empty(),
BuildConfig.CDSI_MRENCLAVE, BuildConfig.CDSI_MRENCLAVE,
10_000, 10_000,
if (FeatureFlags.useLibsignalNetForCdsiLookup()) BuildConfig.LIBSIGNAL_NET_ENV else null if (FeatureFlags.useLibsignalNetForCdsiLookup()) ApplicationDependencies.getLibsignalNetwork() else null
) { ) {
Log.i(TAG, "Ignoring token for one-off lookup.") Log.i(TAG, "Ignoring token for one-off lookup.")
} }
@@ -163,7 +163,7 @@ object ContactDiscoveryRefreshV2 {
Optional.ofNullable(token), Optional.ofNullable(token),
BuildConfig.CDSI_MRENCLAVE, BuildConfig.CDSI_MRENCLAVE,
timeoutMs, timeoutMs,
if (FeatureFlags.useLibsignalNetForCdsiLookup()) BuildConfig.LIBSIGNAL_NET_ENV else null if (FeatureFlags.useLibsignalNetForCdsiLookup()) ApplicationDependencies.getLibsignalNetwork() else null
) { tokenToSave -> ) { tokenToSave ->
stopwatch.split("network-pre-token") stopwatch.split("network-pre-token")
if (!isPartialRefresh) { if (!isPartialRefresh) {
@@ -8,6 +8,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import org.signal.core.util.concurrent.DeadlockDetector; import org.signal.core.util.concurrent.DeadlockDetector;
import org.signal.libsignal.net.Network;
import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations; import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations;
import org.signal.libsignal.zkgroup.receipts.ClientZkReceiptOperations; import org.signal.libsignal.zkgroup.receipts.ClientZkReceiptOperations;
import org.thoughtcrime.securesms.components.TypingStatusRepository; import org.thoughtcrime.securesms.components.TypingStatusRepository;
@@ -85,6 +86,7 @@ public class ApplicationDependencies {
private static final Object FRAME_RATE_TRACKER_LOCK = new Object(); private static final Object FRAME_RATE_TRACKER_LOCK = new Object();
private static final Object JOB_MANAGER_LOCK = new Object(); private static final Object JOB_MANAGER_LOCK = new Object();
private static final Object SIGNAL_HTTP_CLIENT_LOCK = new Object(); private static final Object SIGNAL_HTTP_CLIENT_LOCK = new Object();
private static final Object LIBSIGNAL_NETWORK_LOCK = new Object();
private static Application application; private static Application application;
private static Provider provider; private static Provider provider;
@@ -129,6 +131,7 @@ public class ApplicationDependencies {
private static volatile DeadlockDetector deadlockDetector; private static volatile DeadlockDetector deadlockDetector;
private static volatile ClientZkReceiptOperations clientZkReceiptOperations; private static volatile ClientZkReceiptOperations clientZkReceiptOperations;
private static volatile ScheduledMessageManager scheduledMessagesManager; private static volatile ScheduledMessageManager scheduledMessagesManager;
private static volatile Network libsignalNetwork;
@MainThread @MainThread
public static void init(@NonNull Application application, @NonNull Provider provider) { public static void init(@NonNull Application application, @NonNull Provider provider) {
@@ -685,6 +688,17 @@ public class ApplicationDependencies {
return deadlockDetector; return deadlockDetector;
} }
public static @NonNull Network getLibsignalNetwork() {
if (libsignalNetwork == null) {
synchronized (LIBSIGNAL_NETWORK_LOCK) {
if (libsignalNetwork == null) {
libsignalNetwork = provider.provideLibsignalNetwork();
}
}
}
return libsignalNetwork;
}
public interface Provider { public interface Provider {
@NonNull GroupsV2Operations provideGroupsV2Operations(@NonNull SignalServiceConfiguration signalServiceConfiguration); @NonNull GroupsV2Operations provideGroupsV2Operations(@NonNull SignalServiceConfiguration signalServiceConfiguration);
@NonNull SignalServiceAccountManager provideSignalServiceAccountManager(@NonNull SignalServiceConfiguration signalServiceConfiguration, @NonNull GroupsV2Operations groupsV2Operations); @NonNull SignalServiceAccountManager provideSignalServiceAccountManager(@NonNull SignalServiceConfiguration signalServiceConfiguration, @NonNull GroupsV2Operations groupsV2Operations);
@@ -723,5 +737,6 @@ public class ApplicationDependencies {
@NonNull DeadlockDetector provideDeadlockDetector(); @NonNull DeadlockDetector provideDeadlockDetector();
@NonNull ClientZkReceiptOperations provideClientZkReceiptOperations(@NonNull SignalServiceConfiguration signalServiceConfiguration); @NonNull ClientZkReceiptOperations provideClientZkReceiptOperations(@NonNull SignalServiceConfiguration signalServiceConfiguration);
@NonNull ScheduledMessageManager provideScheduledMessageManager(); @NonNull ScheduledMessageManager provideScheduledMessageManager();
@NonNull Network provideLibsignalNetwork();
} }
} }
@@ -11,6 +11,7 @@ import androidx.annotation.VisibleForTesting;
import org.signal.core.util.ThreadUtil; import org.signal.core.util.ThreadUtil;
import org.signal.core.util.concurrent.DeadlockDetector; import org.signal.core.util.concurrent.DeadlockDetector;
import org.signal.core.util.concurrent.SignalExecutors; import org.signal.core.util.concurrent.SignalExecutors;
import org.signal.libsignal.net.Network;
import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations; import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations;
import org.signal.libsignal.zkgroup.receipts.ClientZkReceiptOperations; import org.signal.libsignal.zkgroup.receipts.ClientZkReceiptOperations;
import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.BuildConfig;
@@ -228,6 +229,11 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
return new ScheduledMessageManager(context); return new ScheduledMessageManager(context);
} }
@Override
public @NonNull Network provideLibsignalNetwork() {
return new Network(BuildConfig.LIBSIGNAL_NET_ENV);
}
@Override @Override
public @NonNull TypingStatusRepository provideTypingStatusRepository() { public @NonNull TypingStatusRepository provideTypingStatusRepository() {
return new TypingStatusRepository(); return new TypingStatusRepository();
@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.dependencies;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import org.signal.core.util.concurrent.DeadlockDetector; import org.signal.core.util.concurrent.DeadlockDetector;
import org.signal.libsignal.net.Network;
import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations; import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations;
import org.signal.libsignal.zkgroup.receipts.ClientZkReceiptOperations; import org.signal.libsignal.zkgroup.receipts.ClientZkReceiptOperations;
import org.thoughtcrime.securesms.components.TypingStatusRepository; import org.thoughtcrime.securesms.components.TypingStatusRepository;
@@ -232,4 +233,9 @@ public class MockApplicationDependencyProvider implements ApplicationDependencie
public @NonNull ScheduledMessageManager provideScheduledMessageManager() { public @NonNull ScheduledMessageManager provideScheduledMessageManager() {
return null; return null;
} }
@Override
public @NonNull Network provideLibsignalNetwork() {
return null;
}
} }
@@ -365,12 +365,12 @@ public class SignalServiceAccountManager {
Optional<byte[]> token, Optional<byte[]> token,
String mrEnclave, String mrEnclave,
Long timeoutMs, Long timeoutMs,
@Nullable Network.Environment libsignalNetEnv, @Nullable Network libsignalNetwork,
Consumer<byte[]> tokenSaver) Consumer<byte[]> tokenSaver)
throws IOException throws IOException
{ {
CdsiAuthResponse auth = pushServiceSocket.getCdsiAuth(); CdsiAuthResponse auth = pushServiceSocket.getCdsiAuth();
CdsiV2Service service = new CdsiV2Service(configuration, mrEnclave, libsignalNetEnv); CdsiV2Service service = new CdsiV2Service(configuration, mrEnclave, libsignalNetwork);
CdsiV2Service.Request request = new CdsiV2Service.Request(previousE164s, newE164s, serviceIds, token); CdsiV2Service.Request request = new CdsiV2Service.Request(previousE164s, newE164s, serviceIds, token);
Single<ServiceResponse<CdsiV2Service.Response>> single = service.getRegisteredUsers(auth.getUsername(), auth.getPassword(), request, tokenSaver); Single<ServiceResponse<CdsiV2Service.Response>> single = service.getRegisteredUsers(auth.getUsername(), auth.getPassword(), request, tokenSaver);
@@ -33,6 +33,8 @@ import java.util.concurrent.Future;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Nullable;
import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Single; import io.reactivex.rxjava3.core.Single;
import okio.ByteString; import okio.ByteString;
@@ -51,10 +53,9 @@ public final class CdsiV2Service {
private final CdsiRequestHandler cdsiRequestHandler; private final CdsiRequestHandler cdsiRequestHandler;
public CdsiV2Service(SignalServiceConfiguration configuration, String mrEnclave, Network.Environment libsignalEnv) { public CdsiV2Service(SignalServiceConfiguration configuration, String mrEnclave, @Nullable Network network) {
if (libsignalEnv != null) { if (network != null) {
Network network = new Network(libsignalEnv);
this.cdsiRequestHandler = (username, password, request, tokenSaver) -> { this.cdsiRequestHandler = (username, password, request, tokenSaver) -> {
try { try {
Log.i(TAG, "Starting CDSI lookup via libsignal-net"); Log.i(TAG, "Starting CDSI lookup via libsignal-net");