summaryrefslogtreecommitdiff
path: root/app/src
diff options
context:
space:
mode:
Diffstat (limited to 'app/src')
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/connection/Connection.java3
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/CensorshipCircumventionFragment.java12
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java9
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java1
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java12
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java13
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java12
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/pluggableTransports/ObfsvpnClient.java11
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/pluggableTransports/models/ObfsvpnConfig.java4
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/pluggableTransports/models/QuicConfig.java24
-rw-r--r--app/src/main/res/values/untranslatable.xml1
11 files changed, 84 insertions, 18 deletions
diff --git a/app/src/main/java/de/blinkt/openvpn/core/connection/Connection.java b/app/src/main/java/de/blinkt/openvpn/core/connection/Connection.java
index 9943faff..6cd86105 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/connection/Connection.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/connection/Connection.java
@@ -45,7 +45,8 @@ public abstract class Connection implements Serializable, Cloneable {
public enum TransportProtocol {
UDP("udp"),
TCP("tcp"),
- KCP("kcp");
+ KCP("kcp"),
+ QUIC("quic");
final String protocol;
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/CensorshipCircumventionFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/CensorshipCircumventionFragment.java
index e8789b32..fc561d48 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/CensorshipCircumventionFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/CensorshipCircumventionFragment.java
@@ -3,6 +3,7 @@ package se.leap.bitmaskclient.base.fragments;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseObfs4;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseObfs4Kcp;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUsePortHopping;
+import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseObfs4Quic;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseSnowflake;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.hasSnowflakePrefs;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.resetSnowflakeSettings;
@@ -37,6 +38,7 @@ public class CensorshipCircumventionFragment extends Fragment {
public static int TUNNELING_AUTOMATICALLY = 100300000;
public static int TUNNELING_OBFS4 = 100300001;
public static int TUNNELING_OBFS4_KCP = 100300002;
+ public static int TUNNELING_QUIC = 100300003;
private @NonNull FCensorshipCircumventionBinding binding;
@@ -113,7 +115,7 @@ public class CensorshipCircumventionFragment extends Fragment {
private void initTunneling() {
RadioButton noneRadioButton = new RadioButton(binding.getRoot().getContext());
noneRadioButton.setText(getText(R.string.automatically_select));
- noneRadioButton.setChecked(!getUseObfs4() && !getUseObfs4Kcp());
+ noneRadioButton.setChecked(!getUseObfs4() && !getUseObfs4Kcp() && !getUseObfs4Quic());
noneRadioButton.setId(TUNNELING_AUTOMATICALLY);
binding.tunnelingRadioGroup.addView(noneRadioButton);
@@ -133,6 +135,14 @@ public class CensorshipCircumventionFragment extends Fragment {
binding.tunnelingRadioGroup.addView(obfs4KcpRadioButton);
}
+ if (ProviderObservable.getInstance().getCurrentProvider().supportsObfs4Quic()) {
+ RadioButton obfs4QuicRadioButton = new RadioButton(binding.getRoot().getContext());
+ obfs4QuicRadioButton.setText(getText(R.string.tunnelling_quic));
+ obfs4QuicRadioButton.setId(TUNNELING_QUIC);
+ obfs4QuicRadioButton.setChecked(getUseObfs4Quic());
+ binding.tunnelingRadioGroup.addView(obfs4QuicRadioButton);
+ }
+
binding.tunnelingRadioGroup.setOnCheckedChangeListener((group, checkedId) -> {
useBridges(true);
setUseTunnel(checkedId);
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java
index 4567bf97..598f9908 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java
@@ -15,6 +15,8 @@ import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getExcludedApps;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getPreferUDP;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getShowAlwaysOnDialog;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseBridges;
+import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseSnowflake;
+import static se.leap.bitmaskclient.base.utils.PreferenceHelper.hasSnowflakePrefs;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.preferUDP;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.resetSnowflakeSettings;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.setAllowExperimentalTransports;
@@ -22,6 +24,7 @@ import static se.leap.bitmaskclient.base.utils.PreferenceHelper.setUseObfuscatio
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.setUsePortHopping;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.setUseTunnel;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useBridges;
+import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useManualDiscoverySettings;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useObfuscationPinning;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useSnowflake;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useManualBridgeSettings;
@@ -132,14 +135,14 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh
manualConfigRoot.setVisibility(ProviderObservable.getInstance().getCurrentProvider().supportsPluggableTransports() ? VISIBLE : GONE);
IconTextEntry manualConfiguration = rootView.findViewById(R.id.bridge_manual_switch);
SwitchCompat manualConfigurationSwitch = rootView.findViewById(R.id.bridge_manual_switch_control);
- boolean usesManualBridge = useManualBridgeSettings();
- manualConfigurationSwitch.setChecked(usesManualBridge);
+ boolean useManualCircumventionSettings = useManualBridgeSettings() || useManualDiscoverySettings();
+ manualConfigurationSwitch.setChecked(useManualCircumventionSettings);
manualConfigurationSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
if (!buttonView.isPressed()) {
return;
}
resetManualConfig();
- if (!usesManualBridge){
+ if (!useManualCircumventionSettings){
openManualConfigurationFragment();
}
});
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java b/app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java
index 5a5d1d6e..44fc6e89 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java
@@ -192,6 +192,7 @@ public interface Constants {
String UDP = "udp";
String TCP = "tcp";
String KCP = "kcp";
+ String QUIC = "quic";
String CAPABILITIES = "capabilities";
String TRANSPORT = "transport";
String TYPE = "type";
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java b/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java
index 89cea76b..e056ada9 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java
@@ -17,6 +17,7 @@
package se.leap.bitmaskclient.base.models;
import static de.blinkt.openvpn.core.connection.Connection.TransportProtocol.KCP;
+import static de.blinkt.openvpn.core.connection.Connection.TransportProtocol.QUIC;
import static de.blinkt.openvpn.core.connection.Connection.TransportProtocol.TCP;
import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4;
import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4_HOP;
@@ -52,7 +53,6 @@ import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
-import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
@@ -303,11 +303,11 @@ public final class Provider implements Parcelable {
}
public boolean supportsPluggableTransports() {
- return supportsTransports(new Pair[]{new Pair<>(OBFS4, TCP), new Pair<>(OBFS4, KCP), new Pair<>(OBFS4_HOP, TCP), new Pair<>(OBFS4_HOP, KCP)});
+ return supportsTransports(new Pair[]{new Pair<>(OBFS4, TCP), new Pair<>(OBFS4, KCP), new Pair<>(OBFS4, QUIC), new Pair<>(OBFS4_HOP, TCP), new Pair<>(OBFS4_HOP, KCP), new Pair<>(OBFS4_HOP, QUIC)});
}
public boolean supportsExperimentalPluggableTransports() {
- return supportsTransports(new Pair[]{new Pair<>(OBFS4, KCP), new Pair<>(OBFS4_HOP, TCP), new Pair<>(OBFS4_HOP, KCP)});
+ return supportsTransports(new Pair[]{new Pair<>(OBFS4, KCP), new Pair<>(OBFS4_HOP, TCP), new Pair<>(OBFS4_HOP, KCP), new Pair<>(OBFS4, QUIC), new Pair<>(OBFS4_HOP, QUIC)});
}
@@ -319,8 +319,12 @@ public final class Provider implements Parcelable {
return supportsTransports(new Pair[]{new Pair<>(OBFS4, KCP)});
}
+ public boolean supportsObfs4Quic() {
+ return supportsTransports(new Pair[]{new Pair<>(OBFS4, QUIC)});
+ }
+
public boolean supportsObfs4Hop() {
- return supportsTransports(new Pair[]{new Pair<>(OBFS4_HOP, KCP),new Pair<>(OBFS4_HOP, TCP)});
+ return supportsTransports(new Pair[]{new Pair<>(OBFS4_HOP, KCP), new Pair<>(OBFS4_HOP, QUIC), new Pair<>(OBFS4_HOP, TCP)});
}
private boolean supportsTransports(Pair<TransportType, TransportProtocol>[] transportTypes) {
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java b/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java
index b7c6db5d..d2bb4d1b 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java
@@ -4,6 +4,7 @@ import static android.content.Context.MODE_PRIVATE;
import static se.leap.bitmaskclient.base.fragments.CensorshipCircumventionFragment.TUNNELING_AUTOMATICALLY;
import static se.leap.bitmaskclient.base.fragments.CensorshipCircumventionFragment.TUNNELING_OBFS4;
import static se.leap.bitmaskclient.base.fragments.CensorshipCircumventionFragment.TUNNELING_OBFS4_KCP;
+import static se.leap.bitmaskclient.base.fragments.CensorshipCircumventionFragment.TUNNELING_QUIC;
import static se.leap.bitmaskclient.base.models.Constants.ALLOW_EXPERIMENTAL_TRANSPORTS;
import static se.leap.bitmaskclient.base.models.Constants.ALLOW_TETHERING_BLUETOOTH;
import static se.leap.bitmaskclient.base.models.Constants.ALLOW_TETHERING_USB;
@@ -615,8 +616,16 @@ public class PreferenceHelper {
return getUseTunnel() == TUNNELING_OBFS4_KCP;
}
- public static boolean useManualBridgeSettings(){
- return (hasSnowflakePrefs() && getUseSnowflake()) || getUseObfs4() || getUseObfs4Kcp() || getUsePortHopping();
+ public static boolean getUseObfs4Quic() {
+ return getUseTunnel() == TUNNELING_QUIC;
+ }
+
+ public static boolean useManualBridgeSettings() {
+ return getUseObfs4() || getUseObfs4Kcp() || getUseObfs4Quic() || getUsePortHopping();
+ }
+
+ public static boolean useManualDiscoverySettings() {
+ return hasSnowflakePrefs() && getUseSnowflake();
}
public static void setUseTunnel(int tunnel) {
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
index 9655013c..76aece23 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
@@ -26,6 +26,7 @@ import static se.leap.bitmaskclient.base.models.Constants.HOST;
import static se.leap.bitmaskclient.base.models.Constants.IAT_MODE;
import static se.leap.bitmaskclient.base.models.Constants.KCP;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICATE;
+import static se.leap.bitmaskclient.base.models.Constants.QUIC;
import static se.leap.bitmaskclient.base.models.Constants.SORTED_GATEWAYS;
import static se.leap.bitmaskclient.base.models.Constants.TCP;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningCert;
@@ -37,6 +38,7 @@ import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseBridges;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseObfs4;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseObfs4Kcp;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUsePortHopping;
+import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseObfs4Quic;
import android.content.Context;
import android.util.Log;
@@ -174,7 +176,7 @@ public class GatewaysManager {
if (getUsePortHopping()) {
return new TransportType[]{OBFS4_HOP};
- } else if (getUseObfs4() || getUseObfs4Kcp()) {
+ } else if (getUseObfs4() || getUseObfs4Kcp() || getUseObfs4Quic()) {
return new TransportType[]{OBFS4};
} else {
return new TransportType[]{OBFS4, OBFS4_HOP};
@@ -192,10 +194,12 @@ public class GatewaysManager {
return Set.of(TCP);
} else if (getUseObfs4Kcp()) {
return Set.of(KCP);
+ } else if (getUseObfs4Quic()) {
+ return Set.of(QUIC);
} else {
// If neither Obf4 nor Obf4Kcp are used, and bridges are enabled,
- // then use both TCP and KCP (based on the original logic).
- return Set.of(TCP, KCP);
+ // then allow to use any of these protocols
+ return Set.of(TCP, KCP, QUIC);
}
}
@@ -492,7 +496,7 @@ public class GatewaysManager {
options.put(CERT, getObfuscationPinningCert());
options.put(IAT_MODE, "0");
modelsBridge.options(options);
- modelsBridge.transport(getObfuscationPinningKCP() ? "kcp" : "tcp");
+ modelsBridge.transport(getObfuscationPinningKCP() ? KCP : TCP);
modelsBridge.type(OBFS4.toString());
modelsBridge.host(PINNED_OBFUSCATION_PROXY);
Gateway gateway = new Gateway(modelsEIPService, secrets, modelsBridge, provider.getApiVersion());
diff --git a/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/ObfsvpnClient.java b/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/ObfsvpnClient.java
index 6ee49951..9fdf3670 100644
--- a/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/ObfsvpnClient.java
+++ b/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/ObfsvpnClient.java
@@ -1,5 +1,8 @@
package se.leap.bitmaskclient.pluggableTransports;
+import static se.leap.bitmaskclient.base.models.Constants.KCP;
+import static se.leap.bitmaskclient.base.models.Constants.QUIC;
+
import android.util.Log;
import client.Client;
@@ -12,6 +15,7 @@ import se.leap.bitmaskclient.pluggableTransports.models.HoppingConfig;
import se.leap.bitmaskclient.pluggableTransports.models.KcpConfig;
import se.leap.bitmaskclient.pluggableTransports.models.Obfs4Options;
import se.leap.bitmaskclient.pluggableTransports.models.ObfsvpnConfig;
+import se.leap.bitmaskclient.pluggableTransports.models.QuicConfig;
public class ObfsvpnClient implements EventLogger {
@@ -29,14 +33,17 @@ public class ObfsvpnClient implements EventLogger {
//FIXME: use a different strategy here
//Basically we would want to track if the more performant transport protocol (KCP?/TCP?) usage was successful
//if so, we stick to it, otherwise we flip the flag
- boolean kcpEnabled = Constants.KCP.equals(options.transport.getProtocols()[0]);
+ String protocol = options.transport.getProtocols()[0];
+ boolean kcpEnabled = KCP.equals(protocol);
+ boolean quicEnabled = QUIC.equals(protocol);
boolean hoppingEnabled = options.transport.getTransportType() == Connection.TransportType.OBFS4_HOP;
if (!hoppingEnabled && (options.transport.getPorts() == null || options.transport.getPorts().length == 0)) {
throw new IllegalStateException("obf4 based transport has no bridge ports configured");
}
KcpConfig kcpConfig = new KcpConfig(kcpEnabled);
+ QuicConfig quicConfig = new QuicConfig(quicEnabled);
HoppingConfig hoppingConfig = new HoppingConfig(hoppingEnabled,IP+":"+PORT, options, 10, 10);
- ObfsvpnConfig obfsvpnConfig = new ObfsvpnConfig(IP+":"+PORT, hoppingConfig, kcpConfig, options.bridgeIP, options.transport.getPorts()[0], options.transport.getOptions().getCert() );
+ ObfsvpnConfig obfsvpnConfig = new ObfsvpnConfig(IP+":"+PORT, hoppingConfig, kcpConfig, quicConfig, options.bridgeIP, options.transport.getPorts()[0], options.transport.getOptions().getCert() );
try {
Log.d(TAG, obfsvpnConfig.toString());
client = Client.newFFIClient(obfsvpnConfig.toString());
diff --git a/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/models/ObfsvpnConfig.java b/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/models/ObfsvpnConfig.java
index 9f85c4a0..cfcd6b6c 100644
--- a/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/models/ObfsvpnConfig.java
+++ b/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/models/ObfsvpnConfig.java
@@ -11,14 +11,16 @@ public class ObfsvpnConfig {
final String proxyAddr;
final HoppingConfig hoppingConfig;
final KcpConfig kcpConfig;
+ final QuicConfig quicConfig;
final String remoteIp;
final String remotePort;
final String obfs4Cert;
- public ObfsvpnConfig(String proxyAddress, HoppingConfig hoppingConfig, KcpConfig kcpConfig, String remoteIP, String remotePort, String obfsv4Cert) {
+ public ObfsvpnConfig(String proxyAddress, HoppingConfig hoppingConfig, KcpConfig kcpConfig, QuicConfig quicConfig, String remoteIP, String remotePort, String obfsv4Cert) {
this.proxyAddr = proxyAddress;
this.hoppingConfig = hoppingConfig;
this.kcpConfig = kcpConfig;
+ this.quicConfig = quicConfig;
this.remoteIp = remoteIP;
this.remotePort = remotePort;
this.obfs4Cert = obfsv4Cert;
diff --git a/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/models/QuicConfig.java b/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/models/QuicConfig.java
new file mode 100644
index 00000000..dd377dd7
--- /dev/null
+++ b/app/src/main/java/se/leap/bitmaskclient/pluggableTransports/models/QuicConfig.java
@@ -0,0 +1,24 @@
+package se.leap.bitmaskclient.pluggableTransports.models;
+
+import androidx.annotation.NonNull;
+
+import com.google.gson.FieldNamingPolicy;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class QuicConfig {
+ final boolean enabled;
+
+ public QuicConfig(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ Gson gson = new GsonBuilder()
+ .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
+ .create();
+ return gson.toJson(this);
+ }
+}
diff --git a/app/src/main/res/values/untranslatable.xml b/app/src/main/res/values/untranslatable.xml
index bd8fa0e7..3d499e85 100644
--- a/app/src/main/res/values/untranslatable.xml
+++ b/app/src/main/res/values/untranslatable.xml
@@ -76,4 +76,5 @@
</string-array>
<string name="tunnelling_obfs4" translatable="false">Obfs4</string>
<string name="tunnelling_obfs4_kcp" translatable="false">Obfs4+KCP</string>
+ <string name="tunnelling_quic" translatable="false">Quic</string>
</resources>