diff --git a/app/src/main/java/org/fptn/vpn/utils/NetworkType.java b/app/src/main/java/org/fptn/vpn/enums/NetworkType.java
similarity index 70%
rename from app/src/main/java/org/fptn/vpn/utils/NetworkType.java
rename to app/src/main/java/org/fptn/vpn/enums/NetworkType.java
index d1448160..8df81340 100644
--- a/app/src/main/java/org/fptn/vpn/utils/NetworkType.java
+++ b/app/src/main/java/org/fptn/vpn/enums/NetworkType.java
@@ -1,4 +1,4 @@
-package org.fptn.vpn.utils;
+package org.fptn.vpn.enums;
public enum NetworkType {
WIFI, CELLULAR, ETHERNET, UNKNOWN
diff --git a/app/src/main/java/org/fptn/vpn/enums/ObfuscationMethodEnum.java b/app/src/main/java/org/fptn/vpn/enums/ObfuscationMethodEnum.java
new file mode 100644
index 00000000..8f7ab866
--- /dev/null
+++ b/app/src/main/java/org/fptn/vpn/enums/ObfuscationMethodEnum.java
@@ -0,0 +1,27 @@
+package org.fptn.vpn.enums;
+
+import androidx.annotation.NonNull;
+
+import lombok.Getter;
+
+public enum ObfuscationMethodEnum {
+ NONE("None", 0),
+ TLS_APP_DATA("TLS App Data", 1),
+ TLS_APP_DATA_BASE_64("TLS App Data + base64", 2);
+
+ final String description;
+
+ @Getter
+ final int id;
+
+ ObfuscationMethodEnum(String description, int id) {
+ this.description = description;
+ this.id = id;
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ return description;
+ }
+}
diff --git a/app/src/main/java/org/fptn/vpn/services/CustomVpnConnection.java b/app/src/main/java/org/fptn/vpn/services/CustomVpnConnection.java
index 6750af28..8b1d656a 100644
--- a/app/src/main/java/org/fptn/vpn/services/CustomVpnConnection.java
+++ b/app/src/main/java/org/fptn/vpn/services/CustomVpnConnection.java
@@ -18,11 +18,12 @@
import org.fptn.vpn.database.model.FptnServerDto;
import org.fptn.vpn.enums.ConnectionState;
import org.fptn.vpn.enums.HandlerMessageTypes;
+import org.fptn.vpn.enums.ObfuscationMethodEnum;
import org.fptn.vpn.services.websocket.WebSocketAlreadyShutdownException;
import org.fptn.vpn.services.websocket.WebSocketClientWrapper;
import org.fptn.vpn.utils.DataRateCalculator;
import org.fptn.vpn.utils.IPUtils;
-import org.fptn.vpn.utils.NetworkType;
+import org.fptn.vpn.enums.NetworkType;
import org.fptn.vpn.vpnclient.exception.ErrorCode;
import org.fptn.vpn.vpnclient.exception.PVNClientException;
@@ -101,7 +102,8 @@ public CustomVpnConnection(final CustomVpnService service,
final String currentIPAddress,
final NetworkType currentNetworkType,
final int maxReconnectCount,
- int delayBetweenAttempts) throws PVNClientException {
+ final int delayBetweenAttempts,
+ final ObfuscationMethodEnum obfuscationMethod) throws PVNClientException {
this.service = service;
this.connectionId = connectionId;
this.fptnServerDto = fptnServerDto;
@@ -112,7 +114,8 @@ public CustomVpnConnection(final CustomVpnService service,
sniHostName,
this::onConnectionOpen,
this::onMessageReceived,
- this::onConnectionFailure
+ this::onConnectionFailure,
+ obfuscationMethod
);
this.maxReconnectCount = maxReconnectCount;
this.delayBetweenAttempts = delayBetweenAttempts;
diff --git a/app/src/main/java/org/fptn/vpn/services/CustomVpnService.java b/app/src/main/java/org/fptn/vpn/services/CustomVpnService.java
index 58a629ed..873fd747 100644
--- a/app/src/main/java/org/fptn/vpn/services/CustomVpnService.java
+++ b/app/src/main/java/org/fptn/vpn/services/CustomVpnService.java
@@ -36,9 +36,10 @@
import org.fptn.vpn.database.model.FptnServerDto;
import org.fptn.vpn.enums.ConnectionState;
import org.fptn.vpn.enums.HandlerMessageTypes;
+import org.fptn.vpn.enums.NetworkType;
+import org.fptn.vpn.enums.ObfuscationMethodEnum;
import org.fptn.vpn.repository.FptnServerRepository;
import org.fptn.vpn.services.tile.FptnTileService;
-import org.fptn.vpn.utils.NetworkType;
import org.fptn.vpn.utils.NetworkUtils;
import org.fptn.vpn.utils.NotificationUtils;
import org.fptn.vpn.utils.SharedPrefUtils;
@@ -455,6 +456,7 @@ private void connect(FptnServerDto fptnServerDto, String sniHostname) {
int delayBetweenAttempts = SharedPrefUtils.getDelayBetweenReconnect(this);
try {
+ ObfuscationMethodEnum obfuscationMethod = SharedPrefUtils.getObfuscationMethod(this);
CustomVpnConnection connection = new CustomVpnConnection(
this,
nextConnectionId.getAndIncrement(),
@@ -463,7 +465,8 @@ private void connect(FptnServerDto fptnServerDto, String sniHostname) {
currentIPAddress,
networkType,
maxReconnectCount,
- delayBetweenAttempts);
+ delayBetweenAttempts,
+ obfuscationMethod);
connection.setConfigureVpnIntent(launchMainActivityPendingIntent);
connection.start();
diff --git a/app/src/main/java/org/fptn/vpn/services/websocket/NativeWebSocketClientImpl.java b/app/src/main/java/org/fptn/vpn/services/websocket/NativeWebSocketClientImpl.java
index f4540fa2..4b14d5d1 100644
--- a/app/src/main/java/org/fptn/vpn/services/websocket/NativeWebSocketClientImpl.java
+++ b/app/src/main/java/org/fptn/vpn/services/websocket/NativeWebSocketClientImpl.java
@@ -2,6 +2,7 @@
import android.util.Log;
+import org.fptn.vpn.enums.ObfuscationMethodEnum;
import org.fptn.vpn.services.websocket.callback.OnFailureCallback;
import org.fptn.vpn.services.websocket.callback.OnMessageReceivedCallback;
import org.fptn.vpn.services.websocket.callback.OnOpenCallback;
@@ -24,6 +25,7 @@ public class NativeWebSocketClientImpl {
private final OnOpenCallback onOpenCallback;
private final OnMessageReceivedCallback onMessageReceivedCallback;
private final OnFailureCallback onFailureCallback;
+ private final ObfuscationMethodEnum obfuscationMethod;
private long nativeHandle;
@@ -36,11 +38,17 @@ public NativeWebSocketClientImpl(
String md5ServerFingerprint,
OnOpenCallback onOpenCallback,
OnMessageReceivedCallback onMessageReceivedCallback,
- OnFailureCallback onFailureCallback) throws PVNClientException {
+ OnFailureCallback onFailureCallback,
+ ObfuscationMethodEnum obfuscationMethod) throws PVNClientException {
this.onOpenCallback = onOpenCallback;
this.onMessageReceivedCallback = onMessageReceivedCallback;
this.onFailureCallback = onFailureCallback;
+ this.obfuscationMethod = obfuscationMethod;
+
+ // TODO: WHAT TO DO WITH OBFUSCATION METHOD?
+ // USE THIS
+ String obfuscation = obfuscationMethod.name(); // NONE, TLS_APP_DATA, TLS_APP_DATA_BASE_64
this.nativeHandle = nativeCreate(
host,
port,
diff --git a/app/src/main/java/org/fptn/vpn/services/websocket/WebSocketClientWrapper.java b/app/src/main/java/org/fptn/vpn/services/websocket/WebSocketClientWrapper.java
index aefc1fb7..05a5562d 100644
--- a/app/src/main/java/org/fptn/vpn/services/websocket/WebSocketClientWrapper.java
+++ b/app/src/main/java/org/fptn/vpn/services/websocket/WebSocketClientWrapper.java
@@ -3,6 +3,7 @@
import android.util.Log;
import org.fptn.vpn.database.model.FptnServerDto;
+import org.fptn.vpn.enums.ObfuscationMethodEnum;
import org.fptn.vpn.services.websocket.callback.OnFailureCallback;
import org.fptn.vpn.services.websocket.callback.OnMessageReceivedCallback;
import org.fptn.vpn.services.websocket.callback.OnOpenCallback;
@@ -24,6 +25,7 @@ public class WebSocketClientWrapper {
private final OnMessageReceivedCallback onMessageReceivedCallback;
private final OnFailureCallback onFailureCallback;
private final NativeHttpsClientImpl nativeHttpsClient;
+ private final ObfuscationMethodEnum obfuscationMethod;
private NativeWebSocketClientImpl nativeWebSocketClient;
@@ -35,7 +37,8 @@ public WebSocketClientWrapper(FptnServerDto fptnServerDto,
String sniHostName,
OnOpenCallback onOpenCallback,
OnMessageReceivedCallback onMessageReceivedCallback,
- OnFailureCallback onFailureCallback) {
+ OnFailureCallback onFailureCallback,
+ ObfuscationMethodEnum obfuscationMethod) {
this.fptnServerDto = fptnServerDto;
this.tunAddress = tunAddress;
this.sniHostName = sniHostName;
@@ -43,6 +46,7 @@ public WebSocketClientWrapper(FptnServerDto fptnServerDto,
this.onMessageReceivedCallback = onMessageReceivedCallback;
this.onFailureCallback = onFailureCallback;
this.nativeHttpsClient = new NativeHttpsClientImpl(fptnServerDto.host, fptnServerDto.port, this.sniHostName, fptnServerDto.md5ServerFingerprint);
+ this.obfuscationMethod = obfuscationMethod;
}
public synchronized void startWebSocket() throws PVNClientException, WebSocketAlreadyShutdownException {
@@ -61,7 +65,8 @@ public synchronized void startWebSocket() throws PVNClientException, WebSocketAl
fptnServerDto.md5ServerFingerprint,
onOpenCallback,
onMessageReceivedCallback,
- onFailureCallback
+ onFailureCallback,
+ obfuscationMethod
);
Log.d(getTag(), "startWebSocket() nativeWebSocketClient.start() Thread.id: " + Thread.currentThread().getId());
nativeWebSocketClient.start();
diff --git a/app/src/main/java/org/fptn/vpn/utils/NetworkUtils.java b/app/src/main/java/org/fptn/vpn/utils/NetworkUtils.java
index 56694828..834c62d7 100644
--- a/app/src/main/java/org/fptn/vpn/utils/NetworkUtils.java
+++ b/app/src/main/java/org/fptn/vpn/utils/NetworkUtils.java
@@ -5,6 +5,8 @@
import android.net.NetworkRequest;
import android.util.Log;
+import org.fptn.vpn.enums.NetworkType;
+
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
diff --git a/app/src/main/java/org/fptn/vpn/utils/SharedPrefUtils.java b/app/src/main/java/org/fptn/vpn/utils/SharedPrefUtils.java
index 0aa32c0f..ab7f0911 100644
--- a/app/src/main/java/org/fptn/vpn/utils/SharedPrefUtils.java
+++ b/app/src/main/java/org/fptn/vpn/utils/SharedPrefUtils.java
@@ -2,10 +2,10 @@
import android.content.Context;
import android.content.SharedPreferences;
-import android.util.Log;
import org.fptn.vpn.R;
import org.fptn.vpn.core.common.Constants;
+import org.fptn.vpn.enums.ObfuscationMethodEnum;
public class SharedPrefUtils {
private static final String TAG = SharedPrefUtils.class.getSimpleName();
@@ -87,8 +87,6 @@ public static int getReconnectAttemptsCount(Context context) {
}
public static void saveReconnectAttemptsCount(Context context, int count) {
- Log.d(TAG, "saveReconnectAttemptsCount: " + count);
-
SharedPreferences sharedPreferences = context.getSharedPreferences(Constants.APPLICATION_SHARED_PREFERENCES, Context.MODE_PRIVATE);
sharedPreferences.edit().putInt(Constants.RECONNECT_ATTEMPTS_COUNT_SHARED_PREF_KEY, count).apply();
}
@@ -100,8 +98,18 @@ public static int getDelayBetweenReconnect(Context context) {
}
public static void saveDelayBetweenReconnect(Context context, int delayInSeconds) {
- Log.d(TAG, "saveDelayBetweenReconnect: " + delayInSeconds);
SharedPreferences sharedPreferences = context.getSharedPreferences(Constants.APPLICATION_SHARED_PREFERENCES, Context.MODE_PRIVATE);
sharedPreferences.edit().putInt(Constants.RECONNECT_DELAY_BETWEEN_SHARED_PREF_KEY, delayInSeconds).apply();
}
+
+
+ public static ObfuscationMethodEnum getObfuscationMethod(Context context) {
+ SharedPreferences sharedPreferences = context.getSharedPreferences(Constants.APPLICATION_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ return ObfuscationMethodEnum.valueOf(sharedPreferences.getString(Constants.OBFUSCATION_METHOD_SHARED_PREF_KEY, ObfuscationMethodEnum.NONE.name()));
+ }
+
+ public static void saveObfuscationMethod(Context context, ObfuscationMethodEnum obfuscationMethodEnum) {
+ SharedPreferences sharedPreferences = context.getSharedPreferences(Constants.APPLICATION_SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ sharedPreferences.edit().putString(Constants.OBFUSCATION_METHOD_SHARED_PREF_KEY, obfuscationMethodEnum.name()).apply();
+ }
}
diff --git a/app/src/main/java/org/fptn/vpn/views/SettingsActivity.java b/app/src/main/java/org/fptn/vpn/views/SettingsActivity.java
index 3067ee3c..66030a05 100644
--- a/app/src/main/java/org/fptn/vpn/views/SettingsActivity.java
+++ b/app/src/main/java/org/fptn/vpn/views/SettingsActivity.java
@@ -22,6 +22,7 @@
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SeekBar;
+import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
@@ -32,18 +33,19 @@
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModelProvider;
+import com.google.android.material.bottomnavigation.BottomNavigationView;
+import com.google.android.material.textfield.TextInputEditText;
+
import org.fptn.vpn.R;
+import org.fptn.vpn.enums.ObfuscationMethodEnum;
import org.fptn.vpn.services.tile.FptnTileService;
import org.fptn.vpn.utils.PermissionsUtils;
import org.fptn.vpn.utils.SharedPrefUtils;
import org.fptn.vpn.viewmodel.FptnServerViewModel;
import org.fptn.vpn.views.adapter.FptnServerAdapter;
-
-import com.google.android.material.bottomnavigation.BottomNavigationView;
-import com.google.android.material.textfield.TextInputEditText;
+import org.fptn.vpn.views.adapter.ObfuscationMethodAdapter;
import java.util.Optional;
-import java.util.concurrent.Executors;
import lombok.Getter;
@@ -401,6 +403,13 @@ public void onStopTrackingTouch(SeekBar seekBar) {
seekBarDelayBetween.setProgress(0);
seekBarDelayBetween.setProgress(delayBetweenReconnect - 1);
+ /* Obfuscation method spinner*/
+ Spinner obfuscationMethodSpinner = dialogView.findViewById(R.id.obfuscation_method_spinner);
+ obfuscationMethodSpinner.setAdapter(new ObfuscationMethodAdapter());
+
+ ObfuscationMethodEnum obfuscationMethod = SharedPrefUtils.getObfuscationMethod(this);
+ obfuscationMethodSpinner.setSelection(obfuscationMethod.getId());
+
builder.setPositiveButton(getString(R.string.save_button), (dialog, which) -> {
Log.d(TAG, "experimentalFeaturesDialog: save");
SharedPrefUtils.saveReconnectOnChangeNetworkTypeEnabled(this, switchNetworkType.isChecked());
@@ -415,6 +424,9 @@ public void onStopTrackingTouch(SeekBar seekBar) {
int delayBetweenProgress = seekBarDelayBetween.getProgress();
SharedPrefUtils.saveDelayBetweenReconnect(this, delayBetweenProgress + 1);
+
+ ObfuscationMethodEnum selectedObfuscationMethod = (ObfuscationMethodEnum) obfuscationMethodSpinner.getSelectedItem();
+ SharedPrefUtils.saveObfuscationMethod(this, selectedObfuscationMethod);
});
builder.setNegativeButton(getString(R.string.cancel_button), (dialog, which) -> {
Log.d(TAG, "experimentalFeaturesDialog: cancel");
diff --git a/app/src/main/java/org/fptn/vpn/views/adapter/ObfuscationMethodAdapter.java b/app/src/main/java/org/fptn/vpn/views/adapter/ObfuscationMethodAdapter.java
new file mode 100644
index 00000000..66c74303
--- /dev/null
+++ b/app/src/main/java/org/fptn/vpn/views/adapter/ObfuscationMethodAdapter.java
@@ -0,0 +1,47 @@
+package org.fptn.vpn.views.adapter;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+import org.fptn.vpn.R;
+import org.fptn.vpn.enums.ObfuscationMethodEnum;
+
+import lombok.Getter;
+
+@Getter
+public class ObfuscationMethodAdapter extends BaseAdapter {
+ private final ObfuscationMethodEnum[] values = ObfuscationMethodEnum.values();
+
+ public ObfuscationMethodAdapter() {
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return values.length;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return values[position];
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return values[position].getId();
+ }
+
+ @Override
+ public View getView(int position, View view, ViewGroup parent) {
+ if (view == null) {
+ view = LayoutInflater.from(parent.getContext()).inflate(R.layout.obfuscation_method_spinner_item, parent, false);
+ }
+
+ TextView label = view.findViewById(R.id.obfuscation_method_spinner_item_label);
+ label.setText(values[position].toString());
+ return view;
+ }
+}
diff --git a/app/src/main/res/layout/experimental_settings_dialog.xml b/app/src/main/res/layout/experimental_settings_dialog.xml
index f6971bcc..9ab45dc1 100644
--- a/app/src/main/res/layout/experimental_settings_dialog.xml
+++ b/app/src/main/res/layout/experimental_settings_dialog.xml
@@ -156,6 +156,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml
index 1b0e09b1..1f4e1b80 100644
--- a/app/src/main/res/values-ru-rRU/strings.xml
+++ b/app/src/main/res/values-ru-rRU/strings.xml
@@ -150,4 +150,6 @@ https://play.google.com/store/apps/details?id=org.fptn.vpn
Плитка быстрых настроек была добавлена ранее
Плитка быстрых настроек добавлена
Плитка быстрых настроек не добавлена!
+ Настроки протокола:
+ Маскировка:
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5de2aded..2352cc5d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -174,4 +174,7 @@ https://play.google.com/store/apps/details?id=org.fptn.vpn
Tile already added
Tile added successfully
Tile addition failed!
+
+ Protocol settings:
+ Obfuscation:
diff --git a/core/common/src/main/kotlin/org/fptn/vpn/core/common/Constants.kt b/core/common/src/main/kotlin/org/fptn/vpn/core/common/Constants.kt
index 39b0d786..6dabc4f5 100644
--- a/core/common/src/main/kotlin/org/fptn/vpn/core/common/Constants.kt
+++ b/core/common/src/main/kotlin/org/fptn/vpn/core/common/Constants.kt
@@ -22,4 +22,5 @@ object Constants {
"RECONNECT_ON_CHANGE_NETWORK_TYPE_ENABLED"
const val RECONNECT_ATTEMPTS_COUNT_SHARED_PREF_KEY: String = "RECONNECT_ATTEMPTS_COUNT_SHARED_PREF_KEY"
const val RECONNECT_DELAY_BETWEEN_SHARED_PREF_KEY: String = "RECONNECT_DELAY_BETWEEN_SHARED_PREF_KEY"
+ const val OBFUSCATION_METHOD_SHARED_PREF_KEY: String = "TLS_OBFUSCATION_METHOD_SHARED_PREF_KEY"
}