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.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
<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.EXPAND_STATUS_BAR"/>
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||||
android:maxSdkVersion="18"/>
|
android:maxSdkVersion="18"/>
|
||||||
|
@ -18,10 +18,7 @@ import com.google.gson.JsonParseException;
|
|||||||
import com.google.gson.stream.JsonReader;
|
import com.google.gson.stream.JsonReader;
|
||||||
import org.itxtech.daedalus.activity.MainActivity;
|
import org.itxtech.daedalus.activity.MainActivity;
|
||||||
import org.itxtech.daedalus.service.DaedalusVpnService;
|
import org.itxtech.daedalus.service.DaedalusVpnService;
|
||||||
import org.itxtech.daedalus.util.Configurations;
|
import org.itxtech.daedalus.util.*;
|
||||||
import org.itxtech.daedalus.util.Logger;
|
|
||||||
import org.itxtech.daedalus.util.Rule;
|
|
||||||
import org.itxtech.daedalus.util.RuleResolver;
|
|
||||||
import org.itxtech.daedalus.util.server.DNSServer;
|
import org.itxtech.daedalus.util.server.DNSServer;
|
||||||
import org.itxtech.daedalus.util.server.DNSServerHelper;
|
import org.itxtech.daedalus.util.server.DNSServerHelper;
|
||||||
|
|
||||||
@ -217,6 +214,17 @@ public class Daedalus extends Application {
|
|||||||
public static void activateService(Context context) {
|
public static void activateService(Context context) {
|
||||||
DaedalusVpnService.primaryServer = DNSServerHelper.getAddressById(DNSServerHelper.getPrimary());
|
DaedalusVpnService.primaryServer = DNSServerHelper.getAddressById(DNSServerHelper.getPrimary());
|
||||||
DaedalusVpnService.secondaryServer = DNSServerHelper.getAddressById(DNSServerHelper.getSecondary());
|
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)
|
if (getInstance().prefs.getBoolean("settings_foreground", false)
|
||||||
&& Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
|
&& Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
|
||||||
Logger.info("Starting foreground service");
|
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.activity.MainActivity;
|
||||||
import org.itxtech.daedalus.util.server.DNSServerHelper;
|
import org.itxtech.daedalus.util.server.DNSServerHelper;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Daedalus Project
|
* Daedalus Project
|
||||||
*
|
*
|
||||||
@ -31,23 +33,21 @@ public class GlobalConfigFragment extends PreferenceFragmentCompat {
|
|||||||
|
|
||||||
addPreferencesFromResource(R.xml.perf_settings);
|
addPreferencesFromResource(R.xml.perf_settings);
|
||||||
|
|
||||||
ListPreference primaryServer = findPreference("primary_server");
|
boolean visible = !Daedalus.getPrefs().getBoolean("settings_use_system_dns", false);
|
||||||
primaryServer.setEntries(DNSServerHelper.getNames(Daedalus.getInstance()));
|
for (String k : new ArrayList<String>() {{
|
||||||
primaryServer.setEntryValues(DNSServerHelper.getIds());
|
add("primary_server");
|
||||||
primaryServer.setSummary(DNSServerHelper.getDescription(primaryServer.getValue(), Daedalus.getInstance()));
|
add("secondary_server");
|
||||||
primaryServer.setOnPreferenceChangeListener((preference, newValue) -> {
|
}}) {
|
||||||
preference.setSummary(DNSServerHelper.getDescription((String) newValue, Daedalus.getInstance()));
|
ListPreference listPref = findPreference(k);
|
||||||
return true;
|
listPref.setVisible(visible);
|
||||||
});
|
listPref.setEntries(DNSServerHelper.getNames(Daedalus.getInstance()));
|
||||||
|
listPref.setEntryValues(DNSServerHelper.getIds());
|
||||||
ListPreference secondaryServer = findPreference("secondary_server");
|
listPref.setSummary(DNSServerHelper.getDescription(listPref.getValue(), Daedalus.getInstance()));
|
||||||
secondaryServer.setEntries(DNSServerHelper.getNames(Daedalus.getInstance()));
|
listPref.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||||
secondaryServer.setEntryValues(DNSServerHelper.getIds());
|
preference.setSummary(DNSServerHelper.getDescription((String) newValue, Daedalus.getInstance()));
|
||||||
secondaryServer.setSummary(DNSServerHelper.getDescription(secondaryServer.getValue(), Daedalus.getInstance()));
|
return true;
|
||||||
secondaryServer.setOnPreferenceChangeListener((preference, newValue) -> {
|
});
|
||||||
preference.setSummary(DNSServerHelper.getDescription((String) newValue, Daedalus.getInstance()));
|
}
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
EditTextPreference testDNSServers = findPreference("dns_test_servers");
|
EditTextPreference testDNSServers = findPreference("dns_test_servers");
|
||||||
testDNSServers.setSummary(testDNSServers.getText());
|
testDNSServers.setSummary(testDNSServers.getText());
|
||||||
@ -110,6 +110,13 @@ public class GlobalConfigFragment extends PreferenceFragmentCompat {
|
|||||||
|
|
||||||
updateOptions(advanced.isChecked(), "settings_advanced");
|
updateOptions(advanced.isChecked(), "settings_advanced");
|
||||||
updateOptions(appFilter.isChecked(), "settings_app_filter");
|
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) {
|
private void updateOptions(boolean checked, String pref) {
|
||||||
|
@ -346,7 +346,7 @@ public class DaedalusVpnService extends VpnService implements Runnable {
|
|||||||
if (time - lastUpdate >= 1000) {
|
if (time - lastUpdate >= 1000) {
|
||||||
lastUpdate = time;
|
lastUpdate = time;
|
||||||
if (notification != null) {
|
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);
|
NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
manager.notify(NOTIFICATION_ACTIVATED, notification.build());
|
manager.notify(NOTIFICATION_ACTIVATED, notification.build());
|
||||||
}
|
}
|
||||||
@ -358,11 +358,8 @@ public class DaedalusVpnService extends VpnService implements Runnable {
|
|||||||
public VpnNetworkException(String s) {
|
public VpnNetworkException(String s) {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
public VpnNetworkException(String s, Throwable t) {
|
public VpnNetworkException(String s, Throwable t) {
|
||||||
super(s, 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_dark_theme">使用暗主题</string>
|
||||||
<string name="settings_dns_query_method">DNS 查询方式</string>
|
<string name="settings_dns_query_method">DNS 查询方式</string>
|
||||||
<string name="settings_foreground">运行前台服务</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_name">规则名称</string>
|
||||||
<string name="settings_rule_type">规则类型</string>
|
<string name="settings_rule_type">规则类型</string>
|
||||||
|
@ -66,6 +66,7 @@
|
|||||||
<string name="settings_dark_theme">Use Dark Theme</string>
|
<string name="settings_dark_theme">Use Dark Theme</string>
|
||||||
<string name="settings_dns_query_method">DNS Query Method</string>
|
<string name="settings_dns_query_method">DNS Query Method</string>
|
||||||
<string name="settings_foreground">Run service in Foreground</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_tcp">TCP</string>
|
||||||
<string name="settings_dns_udp">UDP</string>
|
<string name="settings_dns_udp">UDP</string>
|
||||||
|
@ -6,12 +6,15 @@
|
|||||||
android:key="settingsServer"
|
android:key="settingsServer"
|
||||||
android:title="@string/settings_server">
|
android:title="@string/settings_server">
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:key="settings_use_system_dns"
|
||||||
|
android:title="@string/settings_use_system_dns"
|
||||||
|
android:defaultValue="false"/>
|
||||||
<ListPreference
|
<ListPreference
|
||||||
android:key="primary_server"
|
android:key="primary_server"
|
||||||
android:title="@string/primary_server"
|
android:title="@string/primary_server"
|
||||||
android:defaultValue="0">
|
android:defaultValue="0">
|
||||||
</ListPreference>
|
</ListPreference>
|
||||||
|
|
||||||
<ListPreference
|
<ListPreference
|
||||||
android:key="secondary_server"
|
android:key="secondary_server"
|
||||||
android:title="@string/secondary_server"
|
android:title="@string/secondary_server"
|
||||||
|
Loading…
Reference in New Issue
Block a user