DNS: add Use System DNS as upstream DNS. close #113
This commit is contained in:
parent
77c7ce2135
commit
37fa796303
@ -4,6 +4,7 @@
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="18"/>
|
||||
|
@ -18,10 +18,7 @@ import com.google.gson.JsonParseException;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import org.itxtech.daedalus.activity.MainActivity;
|
||||
import org.itxtech.daedalus.service.DaedalusVpnService;
|
||||
import org.itxtech.daedalus.util.Configurations;
|
||||
import org.itxtech.daedalus.util.Logger;
|
||||
import org.itxtech.daedalus.util.Rule;
|
||||
import org.itxtech.daedalus.util.RuleResolver;
|
||||
import org.itxtech.daedalus.util.*;
|
||||
import org.itxtech.daedalus.util.server.DNSServer;
|
||||
import org.itxtech.daedalus.util.server.DNSServerHelper;
|
||||
|
||||
@ -217,6 +214,17 @@ public class Daedalus extends Application {
|
||||
public static void activateService(Context context) {
|
||||
DaedalusVpnService.primaryServer = DNSServerHelper.getAddressById(DNSServerHelper.getPrimary());
|
||||
DaedalusVpnService.secondaryServer = DNSServerHelper.getAddressById(DNSServerHelper.getSecondary());
|
||||
if (getPrefs().getBoolean("settings_use_system_dns", false)) {
|
||||
String[] servers = DnsServersDetector.getServers(context);
|
||||
if (servers != null) {
|
||||
if (servers.length >= 2) {
|
||||
DaedalusVpnService.primaryServer = servers[0];
|
||||
DaedalusVpnService.secondaryServer = servers[1];
|
||||
} else {
|
||||
DaedalusVpnService.primaryServer = DaedalusVpnService.secondaryServer = servers[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (getInstance().prefs.getBoolean("settings_foreground", false)
|
||||
&& Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
|
||||
Logger.info("Starting foreground service");
|
||||
|
@ -9,6 +9,8 @@ import org.itxtech.daedalus.activity.AppFilterActivity;
|
||||
import org.itxtech.daedalus.activity.MainActivity;
|
||||
import org.itxtech.daedalus.util.server.DNSServerHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Daedalus Project
|
||||
*
|
||||
@ -31,23 +33,21 @@ public class GlobalConfigFragment extends PreferenceFragmentCompat {
|
||||
|
||||
addPreferencesFromResource(R.xml.perf_settings);
|
||||
|
||||
ListPreference primaryServer = findPreference("primary_server");
|
||||
primaryServer.setEntries(DNSServerHelper.getNames(Daedalus.getInstance()));
|
||||
primaryServer.setEntryValues(DNSServerHelper.getIds());
|
||||
primaryServer.setSummary(DNSServerHelper.getDescription(primaryServer.getValue(), Daedalus.getInstance()));
|
||||
primaryServer.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
preference.setSummary(DNSServerHelper.getDescription((String) newValue, Daedalus.getInstance()));
|
||||
return true;
|
||||
});
|
||||
|
||||
ListPreference secondaryServer = findPreference("secondary_server");
|
||||
secondaryServer.setEntries(DNSServerHelper.getNames(Daedalus.getInstance()));
|
||||
secondaryServer.setEntryValues(DNSServerHelper.getIds());
|
||||
secondaryServer.setSummary(DNSServerHelper.getDescription(secondaryServer.getValue(), Daedalus.getInstance()));
|
||||
secondaryServer.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean visible = !Daedalus.getPrefs().getBoolean("settings_use_system_dns", false);
|
||||
for (String k : new ArrayList<String>() {{
|
||||
add("primary_server");
|
||||
add("secondary_server");
|
||||
}}) {
|
||||
ListPreference listPref = findPreference(k);
|
||||
listPref.setVisible(visible);
|
||||
listPref.setEntries(DNSServerHelper.getNames(Daedalus.getInstance()));
|
||||
listPref.setEntryValues(DNSServerHelper.getIds());
|
||||
listPref.setSummary(DNSServerHelper.getDescription(listPref.getValue(), Daedalus.getInstance()));
|
||||
listPref.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
preference.setSummary(DNSServerHelper.getDescription((String) newValue, Daedalus.getInstance()));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
EditTextPreference testDNSServers = findPreference("dns_test_servers");
|
||||
testDNSServers.setSummary(testDNSServers.getText());
|
||||
@ -110,6 +110,13 @@ public class GlobalConfigFragment extends PreferenceFragmentCompat {
|
||||
|
||||
updateOptions(advanced.isChecked(), "settings_advanced");
|
||||
updateOptions(appFilter.isChecked(), "settings_app_filter");
|
||||
|
||||
findPreference("settings_use_system_dns").setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean vis = !(boolean) newValue;
|
||||
findPreference("primary_server").setVisible(vis);
|
||||
findPreference("secondary_server").setVisible(vis);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private void updateOptions(boolean checked, String pref) {
|
||||
|
@ -346,7 +346,7 @@ public class DaedalusVpnService extends VpnService implements Runnable {
|
||||
if (time - lastUpdate >= 1000) {
|
||||
lastUpdate = time;
|
||||
if (notification != null) {
|
||||
notification.setContentTitle(getResources().getString(R.string.notice_queries) + " " + String.valueOf(provider.getDnsQueryTimes()));
|
||||
notification.setContentTitle(getResources().getString(R.string.notice_queries) + " " + provider.getDnsQueryTimes());
|
||||
NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
manager.notify(NOTIFICATION_ACTIVATED, notification.build());
|
||||
}
|
||||
@ -358,11 +358,8 @@ public class DaedalusVpnService extends VpnService implements Runnable {
|
||||
public VpnNetworkException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public VpnNetworkException(String s, Throwable t) {
|
||||
super(s, t);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,166 @@
|
||||
package org.itxtech.daedalus.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.*;
|
||||
import android.os.Build;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Daedalus Project
|
||||
*
|
||||
* @author iTX Technologies
|
||||
* @link https://itxtech.org
|
||||
* <p>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
public class DnsServersDetector {
|
||||
//https://stackoverflow.com/a/48973823
|
||||
private static final String METHOD_EXEC_PROP_DELIM = "]: [";
|
||||
|
||||
public static String[] getServers(Context context) {
|
||||
String[] result;
|
||||
result = getServersMethodSystemProperties();
|
||||
if (result != null && result.length > 0) {
|
||||
return result;
|
||||
}
|
||||
result = getServersMethodConnectivityManager(context);
|
||||
if (result != null && result.length > 0) {
|
||||
return result;
|
||||
}
|
||||
result = getServersMethodExec();
|
||||
if (result != null && result.length > 0) {
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String[] getServersMethodConnectivityManager(Context context) {
|
||||
ArrayList<String> priorityServersArrayList = new ArrayList<>();
|
||||
ArrayList<String> serversArrayList = new ArrayList<>();
|
||||
ConnectivityManager connectivityManager =
|
||||
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
if (connectivityManager != null) {
|
||||
for (Network network : connectivityManager.getAllNetworks()) {
|
||||
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(network);
|
||||
if (networkInfo.isConnected()) {
|
||||
LinkProperties linkProperties = connectivityManager.getLinkProperties(network);
|
||||
List<InetAddress> dnsServersList = linkProperties.getDnsServers();
|
||||
if (linkPropertiesHasDefaultRoute(linkProperties)) {
|
||||
for (InetAddress element : dnsServersList) {
|
||||
String dnsHost = element.getHostAddress();
|
||||
priorityServersArrayList.add(dnsHost);
|
||||
}
|
||||
} else {
|
||||
for (InetAddress element : dnsServersList) {
|
||||
String dnsHost = element.getHostAddress();
|
||||
serversArrayList.add(dnsHost);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (priorityServersArrayList.isEmpty()) {
|
||||
priorityServersArrayList.addAll(serversArrayList);
|
||||
}
|
||||
if (priorityServersArrayList.size() > 0) {
|
||||
return priorityServersArrayList.toArray(new String[0]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String[] getServersMethodSystemProperties() {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
final String re1 = "^\\d+(\\.\\d+){3}$";
|
||||
final String re2 = "^[0-9a-f]+(:[0-9a-f]*)+:[0-9a-f]+$";
|
||||
ArrayList<String> serversArrayList = new ArrayList<>();
|
||||
try {
|
||||
Class SystemProperties = Class.forName("android.os.SystemProperties");
|
||||
Method method = SystemProperties.getMethod("get", new Class[]{String.class});
|
||||
final String[] netdns = new String[]{"net.dns1", "net.dns2", "net.dns3", "net.dns4"};
|
||||
for (int i = 0; i < netdns.length; i++) {
|
||||
Object[] args = new Object[]{netdns[i]};
|
||||
String v = (String) method.invoke(null, args);
|
||||
if (v != null && (v.matches(re1) || v.matches(re2)) && !serversArrayList.contains(v)) {
|
||||
serversArrayList.add(v);
|
||||
}
|
||||
}
|
||||
if (serversArrayList.size() > 0) {
|
||||
return serversArrayList.toArray(new String[0]);
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
Logger.logException(ex);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String[] getServersMethodExec() {
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec("getprop");
|
||||
InputStream inputStream = process.getInputStream();
|
||||
LineNumberReader lineNumberReader = new LineNumberReader(new InputStreamReader(inputStream));
|
||||
Set<String> serversSet = methodExecParseProps(lineNumberReader);
|
||||
if (serversSet.size() > 0) {
|
||||
return serversSet.toArray(new String[0]);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Logger.logException(ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Set<String> methodExecParseProps(BufferedReader lineNumberReader) throws Exception {
|
||||
String line;
|
||||
Set<String> serversSet = new HashSet<String>(10);
|
||||
while ((line = lineNumberReader.readLine()) != null) {
|
||||
int split = line.indexOf(METHOD_EXEC_PROP_DELIM);
|
||||
if (split == -1) {
|
||||
continue;
|
||||
}
|
||||
String property = line.substring(1, split);
|
||||
int valueStart = split + METHOD_EXEC_PROP_DELIM.length();
|
||||
int valueEnd = line.length() - 1;
|
||||
if (valueEnd < valueStart) {
|
||||
continue;
|
||||
}
|
||||
String value = line.substring(valueStart, valueEnd);
|
||||
if (value.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (property.endsWith(".dns") || property.endsWith(".dns1") ||
|
||||
property.endsWith(".dns2") || property.endsWith(".dns3") ||
|
||||
property.endsWith(".dns4")) {
|
||||
InetAddress ip = InetAddress.getByName(value);
|
||||
if (ip == null) continue;
|
||||
value = ip.getHostAddress();
|
||||
if (value == null) continue;
|
||||
if (value.length() == 0) continue;
|
||||
serversSet.add(value);
|
||||
}
|
||||
}
|
||||
return serversSet;
|
||||
}
|
||||
|
||||
private static boolean linkPropertiesHasDefaultRoute(LinkProperties linkProperties) {
|
||||
for (RouteInfo route : linkProperties.getRoutes()) {
|
||||
if (route.isDefaultRoute()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -67,6 +67,7 @@
|
||||
<string name="settings_dark_theme">使用暗主题</string>
|
||||
<string name="settings_dns_query_method">DNS 查询方式</string>
|
||||
<string name="settings_foreground">运行前台服务</string>
|
||||
<string name="settings_use_system_dns">使用系統DNS作為上游DNS</string>
|
||||
|
||||
<string name="settings_rule_name">规则名称</string>
|
||||
<string name="settings_rule_type">规则类型</string>
|
||||
|
@ -66,6 +66,7 @@
|
||||
<string name="settings_dark_theme">Use Dark Theme</string>
|
||||
<string name="settings_dns_query_method">DNS Query Method</string>
|
||||
<string name="settings_foreground">Run service in Foreground</string>
|
||||
<string name="settings_use_system_dns">Use System DNS as upstream DNS</string>
|
||||
|
||||
<string name="settings_dns_tcp">TCP</string>
|
||||
<string name="settings_dns_udp">UDP</string>
|
||||
|
@ -6,12 +6,15 @@
|
||||
android:key="settingsServer"
|
||||
android:title="@string/settings_server">
|
||||
|
||||
<SwitchPreference
|
||||
android:key="settings_use_system_dns"
|
||||
android:title="@string/settings_use_system_dns"
|
||||
android:defaultValue="false"/>
|
||||
<ListPreference
|
||||
android:key="primary_server"
|
||||
android:title="@string/primary_server"
|
||||
android:defaultValue="0">
|
||||
</ListPreference>
|
||||
|
||||
<ListPreference
|
||||
android:key="secondary_server"
|
||||
android:title="@string/secondary_server"
|
||||
|
Loading…
Reference in New Issue
Block a user