Skip to content

Commit

Permalink
Add fixed proxy port entry in settings, disable by default. User is a…
Browse files Browse the repository at this point in the history
…ble to specify a fixed proxy port in allow LAN mode now.
  • Loading branch information
TchaikovDriver authored and wongsyrone committed Jun 25, 2022
1 parent 45dc449 commit e0964bc
Show file tree
Hide file tree
Showing 13 changed files with 278 additions and 111 deletions.
61 changes: 43 additions & 18 deletions app/src/main/java/io/github/trojan_gfw/igniter/ProxyService.java
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,7 @@ interface RuleApplier {
void applyRule(VpnService.Builder builder, String packageName) throws PackageManager.NameNotFoundException;
}

private void addExtraDNS(VpnService.Builder b) {
SettingsDataManager dataManager = new SettingsDataManager(this);
private void addExtraDNS(VpnService.Builder b, SettingsDataManager dataManager) {
List<String> dnsList = dataManager.loadExtraDNSList();
for (String dns : dnsList) {
LogHelper.i(TAG, "add DnsServer: " + dns);
Expand All @@ -356,7 +355,8 @@ public int onStartCommand(Intent intent, int flags, int startId) {

VpnService.Builder b = new VpnService.Builder();
applyApplicationOrientedRule(b);
addExtraDNS(b);
SettingsDataManager settingsDataManager = new SettingsDataManager(this);
addExtraDNS(b, settingsDataManager);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// VPN apps targeting {@link android.os.Build.VERSION_CODES#Q} or above will be
// considered metered by default, because of which Google Play Store treat the network
Expand Down Expand Up @@ -430,30 +430,55 @@ public int onStartCommand(Intent intent, int flags, int startId) {
int fd = pfd.getFd();

startNetworkConnectivityMonitor();

long trojanPort;
try {
trojanPort = Freeport.getFreePort();
} catch (Exception e) {
e.printStackTrace();
trojanPort = 1081;
final int fixedPort = settingsDataManager.loadFixedPort();
long trojanPort, clashSocksPort = 1080; // default value in case fail to get free port
// Determine trojanPort and clashSocksPort according to the user configurations (Clash, fixed port).
// If allowLan is false, both trojanPort and clashSocksPort will be assigned by Freeport.
// If allowLan is true, user-specified port will be assigned to clashSocksPort if clash is enable,
// otherwise, user-specified port will be assigned to trojanPort. Eventually, the user-specified
// port will be assigned to tun2socksPort, which is visible to user over the notification.
if (enable_clash) {
try {
do {
trojanPort = Freeport.getFreePort();
} while (trojanPort == fixedPort);
} catch (Exception e) {
e.printStackTrace();
trojanPort = 1081;
}
if (!allowLan || -1 == fixedPort) {
try {
do { // clash and trojan should NOT listen on the same port
clashSocksPort = Freeport.getFreePort();
}
while (clashSocksPort == trojanPort);
} catch (Exception e) {
e.printStackTrace();
}
} else {
clashSocksPort = fixedPort;
}
} else {
if (!allowLan || -1 == fixedPort) {
try {
trojanPort = Freeport.getFreePort();
} catch (Exception e) {
e.printStackTrace();
trojanPort = 1081;
}
} else {
trojanPort = fixedPort;
}
}

LogHelper.i("Igniter", "trojan port is " + trojanPort);
TrojanHelper.ChangeListenPort(Globals.getTrojanConfigPath(), trojanPort);
TrojanHelper.ShowConfig(Globals.getTrojanConfigPath());

JNIHelper.trojan(Globals.getTrojanConfigPath());

long clashSocksPort = 1080; // default value in case fail to get free port
if (enable_clash) {
try {

// clash and trojan should NOT listen on the same port
do {
clashSocksPort = Freeport.getFreePort();
}
while (clashSocksPort == trojanPort);

LogHelper.i("igniter", "clash port is " + clashSocksPort);
ClashHelper.ShowConfig(Globals.getClashConfigPath());
ClashStartOptions clashStartOptions = new ClashStartOptions();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ public abstract class Constants {
public static final String PREFERENCE_KEY_FIRST_START = "first_start";
public static final String PREFERENCE_KEY_PROXY_IN_ALLOW_MODE = "proxy_allow_mode";
public static final String PREFERENCE_KEY_EXTRA_DNS = "extra_dns";
public static final String PREFERENCE_KEY_FIXED_PORT = "fixed_port";
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,52 +10,76 @@
public abstract class PreferenceUtils {

public static boolean getBooleanPreference(ContentResolver resolver, Uri uri, String key, boolean defaultValue) {
try (Cursor query = ContentResolverCompat.query(resolver, uri, new String[]{key}, null,
null, null, null)) {
if (query.moveToFirst()) {
int columnIndex = query.getColumnIndex(key);
if (columnIndex >= 0) {
int type = query.getType(columnIndex);
switch (type) {
case Cursor.FIELD_TYPE_STRING:
return Boolean.parseBoolean(query.getString(columnIndex));
case Cursor.FIELD_TYPE_INTEGER:
return query.getInt(columnIndex) == 1;
default:
return defaultValue;
}
}
return getPreference(resolver, uri, key, defaultValue, ((cursor, columnIndex, type, defValue) -> {
switch (type) {
case Cursor.FIELD_TYPE_STRING:
return Boolean.parseBoolean(cursor.getString(columnIndex));
case Cursor.FIELD_TYPE_INTEGER:
return cursor.getInt(columnIndex) == 1;
default:
return defValue;
}
}
return defaultValue;
}));
}

public static void putBooleanPreference(ContentResolver resolver, Uri uri, String key, boolean value) {
putPreference(resolver, uri, key, value, (v, contentValues) -> contentValues.put(key, v));
}

public static String getStringPreference(ContentResolver resolver, Uri uri, String key, String defVal) {
return getPreference(resolver, uri, key, defVal, ((cursor, columnIndex, type, defValue) -> {
if (Cursor.FIELD_TYPE_STRING == type) {
return cursor.getString(columnIndex);
}
return defVal;
}));
}

public static void putStringPreference(ContentResolver resolver, Uri uri, String key, String value) {
putPreference(resolver, uri, key, value, (v, contentValues) -> contentValues.put(key, v));
}

public static void putIntPreference(ContentResolver resolver, Uri uri, String key, int value) {
putPreference(resolver, uri, key, value, (v, contentValues) -> contentValues.put(key, v));
}

public static int getIntPreference(ContentResolver resolver, Uri uri, String key, int defVal) {
return getPreference(resolver, uri, key, defVal, ((cursor, columnIndex, type, defValue) -> {
if (Cursor.FIELD_TYPE_INTEGER == type) {
return cursor.getInt(columnIndex);
}
return defVal;
}));
}

private static <T> void putPreference(ContentResolver resolver, Uri uri, String key, T value,
ContentValuePutter<T> putter) {
ContentValues contentValues = new ContentValues(1);
contentValues.put(key, value);
putter.onPutValue(value, contentValues);
resolver.update(uri, contentValues, null, null);
}

public static String getStringPreference(ContentResolver resolver, Uri uri, String key, String defVal) {
private static <T> T getPreference(ContentResolver resolver, Uri uri, String key, T defVal,
CursorReader<T> reader) {
try (Cursor query = ContentResolverCompat.query(resolver, uri, new String[]{key}, null,
null, null, null)) {
if (query == null) return defVal;
if (query.moveToFirst()) {
int columnIndex = query.getColumnIndex(key);
if (columnIndex >= 0) {
int type = query.getType(columnIndex);
if (type == Cursor.FIELD_TYPE_STRING) {
return query.getString(columnIndex);
}
return defVal;
return reader.onReadValue(query, columnIndex, type, defVal);
}
}
}
return defVal;
}

public static void putStringPreference(ContentResolver resolver, Uri uri, String key, String value) {
ContentValues contentValues = new ContentValues(1);
contentValues.put(key, value);
resolver.update(uri, contentValues, null, null);
interface ContentValuePutter<T> {
void onPutValue(T value, ContentValues contentValues);
}

interface CursorReader<T> {
T onReadValue(Cursor cursor, int columnIndex, int type, T defValue);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public interface SettingsContract {
interface Presenter extends BasePresenter {
void addDNSInput();
void removeDNSInput(int viewIndex);
void saveDNSList(@NonNull List<String> dnsList);
void saveSettings(@NonNull List<String> dnsList, String port);
void exit();
}
interface View extends BaseView<Presenter> {
Expand All @@ -24,6 +24,7 @@ interface View extends BaseView<Presenter> {
void appendDNSInput();
void removeDNSInput(int index);
void showExitConfirm();
void showPortNumberError();
@AnyThread
void showLoading();
@AnyThread
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@ public interface ISettingsDataManager {
List<String> loadExtraDNSList();
@WorkerThread
void saveExtraDNSList(@NonNull List<String> dnsList);
void saveFixedPort(int port);

/***
* Load fixed port from settings. If no fixed port is specified, returns -1.
*/
int loadFixedPort();
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,18 @@ public void saveExtraDNSList(@NonNull List<String> dnsList) {
Uri.parse(Constants.PREFERENCE_URI), Constants.PREFERENCE_KEY_EXTRA_DNS,
jsonArray.toString());
}

@Override
public void saveFixedPort(int port) {
PreferenceUtils.putIntPreference(mContext.getContentResolver(),
Uri.parse(Constants.PREFERENCE_URI),
Constants.PREFERENCE_KEY_FIXED_PORT, port);
}

@Override
public int loadFixedPort() {
return PreferenceUtils.getIntPreference(mContext.getContentResolver(),
Uri.parse(Constants.PREFERENCE_URI),
Constants.PREFERENCE_KEY_FIXED_PORT, -1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.FragmentActivity;

import com.google.android.material.textfield.TextInputEditText;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
Expand All @@ -34,9 +36,10 @@ public class SettingsFragment extends BaseFragment
implements SettingsContract.View, InputEntryView.Listener {
public static final String TAG = "SettingsFragment";
private SettingsContract.Presenter mPresenter;
private LinearLayout mParentLl, mDNSInputLl;
private LinearLayout mDNSInputLl;
private ImageView mAddDNSIv;
private LoadingDialog mLoadingDialog;
private TextInputEditText mPortTiet;
private final List<InputEntryView> mExtraDNSInputList = new LinkedList<>();

public SettingsFragment() {
Expand Down Expand Up @@ -64,9 +67,9 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
}

private void findViews() {
mParentLl = findViewById(R.id.settings_parent_ll);
mDNSInputLl = findViewById(R.id.settings_dns_list_ll);
mAddDNSIv = findViewById(R.id.settings_add_dns_input_iv);
mPortTiet = findViewById(R.id.settings_port_tiet);
FragmentActivity activity = getActivity();
if (activity instanceof AppCompatActivity) {
Toolbar toolbar = findViewById(R.id.settings_top_bar);
Expand Down Expand Up @@ -133,12 +136,18 @@ private List<String> getInputDNSList() {
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
final int id = item.getItemId();
if (R.id.action_save_settings == id) {
mPresenter.saveDNSList(getInputDNSList());
mPresenter.saveSettings(getInputDNSList(), mPortTiet.getEditableText().toString());
return true;
}
return super.onOptionsItemSelected(item);
}

@Override
public void showPortNumberError() {
runOnUiThread(() -> SnackbarUtils
.showTextShort(requireView(), R.string.settings_port_help_text));
}

@Override
public void showLoading() {
runOnUiThread(() -> {
Expand Down Expand Up @@ -166,7 +175,6 @@ public void onDelete(InputEntryView view) {
@Override
public void showExtraDNSList(@NonNull List<String> dnsList) {
runOnUiThread(() -> {
LinearLayout layout = mDNSInputLl;
for (int i = 0, size = dnsList.size(); i < size; i++) {
String dns = dnsList.get(i);
createInputEntry(dns);
Expand All @@ -176,7 +184,8 @@ public void showExtraDNSList(@NonNull List<String> dnsList) {

@Override
public void showDNSFormatError(int errorIndexInList) {
mExtraDNSInputList.get(errorIndexInList).setError(getString(R.string.settings_dns_format_error));
runOnUiThread(() -> mExtraDNSInputList
.get(errorIndexInList).setError(getString(R.string.settings_dns_format_error)));
}

@Override
Expand Down
Loading

0 comments on commit e0964bc

Please sign in to comment.