diff --git a/app/build.gradle b/app/build.gradle index 6fcbcac..c74d6a4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,7 +8,7 @@ android { buildToolsVersion "28.0.3" defaultConfig { applicationId "org.itxtech.daedalus" - minSdkVersion 15 + minSdkVersion 21 targetSdkVersion 28 versionCode 19 versionName "1.14.0" @@ -39,12 +39,12 @@ android { dependencies { //Support - implementation 'androidx.appcompat:appcompat:1.1.0-beta01' + implementation 'androidx.appcompat:appcompat:1.1.0-rc01' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.percentlayout:percentlayout:1.0.0' implementation 'androidx.cardview:cardview:1.0.0' - implementation 'com.google.android.material:material:1.1.0-alpha07' - implementation 'androidx.recyclerview:recyclerview:1.1.0-alpha06' + implementation 'com.google.android.material:material:1.1.0-alpha08' + implementation 'androidx.recyclerview:recyclerview:1.1.0-beta01' //DNS implementation 'org.pcap4j:pcap4j-core:1.7.6' implementation 'org.pcap4j:pcap4j-packetfactory-static:1.7.6' @@ -52,7 +52,7 @@ dependencies { implementation 'com.google.code.gson:gson:2.8.5' implementation 'com.squareup.okhttp3:okhttp:3.14.1' //Analytics - implementation 'com.google.firebase:firebase-core:16.0.9' + implementation 'com.google.firebase:firebase-core:17.0.1' implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1' } diff --git a/app/src/main/java/org/itxtech/daedalus/Daedalus.java b/app/src/main/java/org/itxtech/daedalus/Daedalus.java index 03dea0b..9f9130e 100644 --- a/app/src/main/java/org/itxtech/daedalus/Daedalus.java +++ b/app/src/main/java/org/itxtech/daedalus/Daedalus.java @@ -135,7 +135,6 @@ public class Daedalus extends Application { } public static void initRuleResolver() { - if (Daedalus.getPrefs().getBoolean("settings_local_rules_resolution", false)) { ArrayList pendingLoad = new ArrayList<>(); ArrayList usingRules = configurations.getUsingRules(); if (usingRules != null && usingRules.size() > 0) { @@ -160,13 +159,11 @@ public class Daedalus extends Application { } } else { RuleResolver.clear(); - } } } public static void setRulesChanged() { - if (DaedalusVpnService.isActivated() && - getPrefs().getBoolean("settings_allow_dynamic_rule_reload", false)) { + if (DaedalusVpnService.isActivated()) { initRuleResolver(); } } diff --git a/app/src/main/java/org/itxtech/daedalus/fragment/RuleConfigFragment.java b/app/src/main/java/org/itxtech/daedalus/fragment/RuleConfigFragment.java index 88c2d6c..1c4caef 100644 --- a/app/src/main/java/org/itxtech/daedalus/fragment/RuleConfigFragment.java +++ b/app/src/main/java/org/itxtech/daedalus/fragment/RuleConfigFragment.java @@ -187,11 +187,7 @@ public class RuleConfigFragment extends ConfigFragment { ClickPreference ruleImportExternal = (ClickPreference) findPreference("ruleImportExternal"); ruleImportExternal.setOnPreferenceClickListener(preference -> { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - performFileSearch(); - } else { - Snackbar.make(getView(), R.string.notice_legacy_api, Snackbar.LENGTH_LONG).show(); - } + performFileSearch(); return false; }); diff --git a/app/src/main/java/org/itxtech/daedalus/fragment/RulesFragment.java b/app/src/main/java/org/itxtech/daedalus/fragment/RulesFragment.java index fa3e621..2dffccc 100644 --- a/app/src/main/java/org/itxtech/daedalus/fragment/RulesFragment.java +++ b/app/src/main/java/org/itxtech/daedalus/fragment/RulesFragment.java @@ -17,7 +17,6 @@ import com.google.android.material.snackbar.Snackbar; import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.R; import org.itxtech.daedalus.activity.ConfigActivity; -import org.itxtech.daedalus.service.DaedalusVpnService; import org.itxtech.daedalus.util.Rule; import java.io.File; @@ -61,14 +60,6 @@ public class RulesFragment extends ToolbarFragment implements Toolbar.OnMenuItem ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() { @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { - if (!Daedalus.getPrefs().getBoolean("settings_allow_dynamic_rule_reload", false)) { - if (viewHolder instanceof RulesFragment.ViewHolder) { - Rule rule = Rule.getRuleById(((ViewHolder) viewHolder).getId()); - if (rule != null && rule.isServiceAndUsing()) { - return 0; - } - } - } return makeMovementFlags(0, ItemTouchHelper.START | ItemTouchHelper.END); } @@ -121,11 +112,7 @@ public class RulesFragment extends ToolbarFragment implements Toolbar.OnMenuItem } if (id == R.id.action_reload) { - if (!Daedalus.getPrefs().getBoolean("settings_allow_dynamic_rule_reload", false)) { - Snackbar.make(getView(), R.string.notice_check_dynamic_rule_reload, Snackbar.LENGTH_SHORT).show(); - } else { - Daedalus.setRulesChanged(); - } + Daedalus.setRulesChanged(); } return true; } @@ -233,24 +220,18 @@ public class RulesFragment extends ToolbarFragment implements Toolbar.OnMenuItem @Override public void onClick(View v) { - if ((!Daedalus.getPrefs().getBoolean("settings_allow_dynamic_rule_reload", false) && - !DaedalusVpnService.isActivated()) || - Daedalus.getPrefs().getBoolean("settings_allow_dynamic_rule_reload", false)) { Rule rule = Rule.getRuleById(id); if (rule != null) { rule.setUsing(!v.isSelected()); v.setSelected(!v.isSelected()); Daedalus.setRulesChanged(); } - } } @Override public boolean onLongClick(View v) { Rule rule = Rule.getRuleById(id); - if (rule != null && - (Daedalus.getPrefs().getBoolean("settings_allow_dynamic_rule_reload", false) || - !rule.isServiceAndUsing())) { + if (rule != null) { Daedalus.getInstance().startActivity(new Intent(Daedalus.getInstance(), ConfigActivity.class) .putExtra(ConfigActivity.LAUNCH_ACTION_ID, Integer.parseInt(id)) .putExtra(ConfigActivity.LAUNCH_ACTION_FRAGMENT, ConfigActivity.LAUNCH_FRAGMENT_RULE) diff --git a/app/src/main/java/org/itxtech/daedalus/provider/HttpsIetfProvider.java b/app/src/main/java/org/itxtech/daedalus/provider/HttpsIetfProvider.java index 0b81e91..6cb86cb 100644 --- a/app/src/main/java/org/itxtech/daedalus/provider/HttpsIetfProvider.java +++ b/app/src/main/java/org/itxtech/daedalus/provider/HttpsIetfProvider.java @@ -8,7 +8,6 @@ import org.minidns.dnsmessage.DnsMessage; import org.pcap4j.packet.IpPacket; import java.io.IOException; -import java.util.concurrent.TimeUnit; /** * Daedalus Project @@ -22,14 +21,8 @@ import java.util.concurrent.TimeUnit; * (at your option) any later version. */ public class HttpsIetfProvider extends HttpsProvider { - private static final OkHttpClient HTTP_CLIENT = new OkHttpClient.Builder() - .connectTimeout(10, TimeUnit.SECONDS) - .readTimeout(10, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .addInterceptor((chain) -> chain.proceed(chain.request().newBuilder() - .header("Accept", "application/dns-message") - .build())) - .build(); + private OkHttpClient HTTP_CLIENT = getHttpClient("application/dns-message"); + public HttpsIetfProvider(ParcelFileDescriptor descriptor, DaedalusVpnService service) { super(descriptor, service); diff --git a/app/src/main/java/org/itxtech/daedalus/provider/HttpsJsonProvider.java b/app/src/main/java/org/itxtech/daedalus/provider/HttpsJsonProvider.java index 012aa72..a367870 100644 --- a/app/src/main/java/org/itxtech/daedalus/provider/HttpsJsonProvider.java +++ b/app/src/main/java/org/itxtech/daedalus/provider/HttpsJsonProvider.java @@ -13,7 +13,6 @@ import org.minidns.record.*; import org.pcap4j.packet.IpPacket; import java.io.IOException; -import java.util.concurrent.TimeUnit; /** * Daedalus Project @@ -32,14 +31,7 @@ public class HttpsJsonProvider extends HttpsProvider { * https://developers.google.com/speed/public-dns/docs/dns-over-https */ - private static final OkHttpClient HTTP_CLIENT = new OkHttpClient.Builder() - .connectTimeout(10, TimeUnit.SECONDS) - .readTimeout(10, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .addInterceptor((chain) -> chain.proceed(chain.request().newBuilder() - .header("Accept", "application/dns-json") - .build())) - .build(); + private OkHttpClient HTTP_CLIENT = getHttpClient("application/dns-json"); public HttpsJsonProvider(ParcelFileDescriptor descriptor, DaedalusVpnService service) { super(descriptor, service); diff --git a/app/src/main/java/org/itxtech/daedalus/provider/HttpsProvider.java b/app/src/main/java/org/itxtech/daedalus/provider/HttpsProvider.java index 497739c..e3fed27 100644 --- a/app/src/main/java/org/itxtech/daedalus/provider/HttpsProvider.java +++ b/app/src/main/java/org/itxtech/daedalus/provider/HttpsProvider.java @@ -8,9 +8,11 @@ import android.system.OsConstants; import android.system.StructPollfd; import android.util.Log; import androidx.annotation.NonNull; +import okhttp3.OkHttpClient; import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.service.DaedalusVpnService; import org.itxtech.daedalus.util.Logger; +import org.itxtech.daedalus.util.server.DNSServerHelper; import org.minidns.dnsmessage.DnsMessage; import org.pcap4j.packet.IpPacket; import org.pcap4j.packet.IpSelector; @@ -21,8 +23,10 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.net.InetAddress; +import java.util.Arrays; import java.util.Iterator; import java.util.LinkedList; +import java.util.concurrent.TimeUnit; /** * Daedalus Project @@ -36,7 +40,8 @@ import java.util.LinkedList; * (at your option) any later version. */ abstract public class HttpsProvider extends Provider { - protected static final String HTTPS_SUFFIX = "https://"; + + public static final String HTTPS_SUFFIX = "https://"; private static final String TAG = "HttpsProvider"; @@ -46,6 +51,23 @@ abstract public class HttpsProvider extends Provider { super(descriptor, service); } + protected OkHttpClient getHttpClient(String accept) { + return new OkHttpClient.Builder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(10, TimeUnit.SECONDS) + .writeTimeout(10, TimeUnit.SECONDS) + .addInterceptor((chain) -> chain.proceed(chain.request().newBuilder() + .header("Accept", accept) + .build())) + .dns(hostname -> { + if (DNSServerHelper.domainCache.containsKey(hostname)) { + return DNSServerHelper.domainCache.get(hostname); + } + return Arrays.asList(InetAddress.getAllByName(hostname)); + }) + .build(); + } + @TargetApi(Build.VERSION_CODES.LOLLIPOP) public void process() { try { diff --git a/app/src/main/java/org/itxtech/daedalus/provider/ProviderPicker.java b/app/src/main/java/org/itxtech/daedalus/provider/ProviderPicker.java index ed4749c..7dcc492 100644 --- a/app/src/main/java/org/itxtech/daedalus/provider/ProviderPicker.java +++ b/app/src/main/java/org/itxtech/daedalus/provider/ProviderPicker.java @@ -24,7 +24,7 @@ public class ProviderPicker { //This section mush be the same as the one in arrays.xml public static Provider getProvider(ParcelFileDescriptor descriptor, DaedalusVpnService service) { - switch (Integer.valueOf(Daedalus.getPrefs().getString("settings_dns_query_method", "0"))) { + switch (getDnsQueryMethod()) { case DNS_QUERY_METHOD_UDP: return new UdpProvider(descriptor, service); case DNS_QUERY_METHOD_TCP: @@ -38,4 +38,8 @@ public class ProviderPicker { } return new UdpProvider(descriptor, service); } + + public static int getDnsQueryMethod() { + return Integer.valueOf(Daedalus.getPrefs().getString("settings_dns_query_method", "0")); + } } diff --git a/app/src/main/java/org/itxtech/daedalus/service/DaedalusVpnService.java b/app/src/main/java/org/itxtech/daedalus/service/DaedalusVpnService.java index 1b7a20b..b1ec42b 100644 --- a/app/src/main/java/org/itxtech/daedalus/service/DaedalusVpnService.java +++ b/app/src/main/java/org/itxtech/daedalus/service/DaedalusVpnService.java @@ -13,9 +13,7 @@ import android.os.Build; import android.os.ParcelFileDescriptor; import android.system.OsConstants; import android.util.Log; - import androidx.core.app.NotificationCompat; - import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.R; import org.itxtech.daedalus.activity.MainActivity; @@ -129,7 +127,6 @@ public class DaedalusVpnService extends VpnService implements Runnable { } Daedalus.initRuleResolver(); - DNSServerHelper.buildPortCache(); if (this.mThread == null) { this.mThread = new Thread(this, "DaedalusVpn"); @@ -190,7 +187,7 @@ public class DaedalusVpnService extends VpnService implements Runnable { if (shouldRefresh) { RuleResolver.clear(); - DNSServerHelper.clearPortCache(); + DNSServerHelper.clearCache(); Logger.info("Daedalus VPN service has stopped"); } @@ -237,6 +234,7 @@ public class DaedalusVpnService extends VpnService implements Runnable { @Override public void run() { try { + DNSServerHelper.buildCache(); Builder builder = new Builder() .setSession("Daedalus") .setConfigureIntent(PendingIntent.getActivity(this, 0, diff --git a/app/src/main/java/org/itxtech/daedalus/util/Configurations.java b/app/src/main/java/org/itxtech/daedalus/util/Configurations.java index 97afd53..d4a7630 100644 --- a/app/src/main/java/org/itxtech/daedalus/util/Configurations.java +++ b/app/src/main/java/org/itxtech/daedalus/util/Configurations.java @@ -2,9 +2,9 @@ package org.itxtech.daedalus.util; import com.google.gson.Gson; import com.google.gson.stream.JsonReader; - import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.util.server.CustomDNSServer; +import org.itxtech.daedalus.util.server.DNSServer; import java.io.File; import java.io.FileReader; @@ -28,6 +28,7 @@ public class Configurations { private static File file; + private ArrayList builtInDNSServers; private ArrayList customDNSServers; private ArrayList filterAppObjects; diff --git a/app/src/main/java/org/itxtech/daedalus/util/Rule.java b/app/src/main/java/org/itxtech/daedalus/util/Rule.java index b7041c8..76713de 100644 --- a/app/src/main/java/org/itxtech/daedalus/util/Rule.java +++ b/app/src/main/java/org/itxtech/daedalus/util/Rule.java @@ -1,7 +1,6 @@ package org.itxtech.daedalus.util; import org.itxtech.daedalus.Daedalus; -import org.itxtech.daedalus.service.DaedalusVpnService; import java.io.File; import java.util.ArrayList; @@ -104,10 +103,6 @@ public class Rule { this.downloadUrl = downloadUrl; } - public boolean isServiceAndUsing() { - return DaedalusVpnService.isActivated() && isUsing(); - } - public void addToConfig() { if (getType() == Rule.TYPE_HOSTS) { Daedalus.configurations.getHostsRules().add(this); @@ -123,11 +118,9 @@ public class Rule { Daedalus.configurations.getDnsmasqRules().remove(this); } File file = new File(getFileName()); - Logger.info("Delete rule " + getName() + " result: " + String.valueOf(file.delete())); + Logger.info("Delete rule " + getName() + " result: " + file.delete()); } - - //STATIC METHODS public static String[] getBuildInRuleNames() { ArrayList names = new ArrayList<>(Daedalus.RULES.size()); for (Rule rule : Daedalus.RULES) { diff --git a/app/src/main/java/org/itxtech/daedalus/util/server/DNSServerHelper.java b/app/src/main/java/org/itxtech/daedalus/util/server/DNSServerHelper.java index ad9f1cb..09e9ac4 100644 --- a/app/src/main/java/org/itxtech/daedalus/util/server/DNSServerHelper.java +++ b/app/src/main/java/org/itxtech/daedalus/util/server/DNSServerHelper.java @@ -1,12 +1,18 @@ package org.itxtech.daedalus.util.server; import android.content.Context; +import android.net.Uri; import org.itxtech.daedalus.Daedalus; +import org.itxtech.daedalus.provider.HttpsProvider; +import org.itxtech.daedalus.provider.ProviderPicker; import org.itxtech.daedalus.service.DaedalusVpnService; +import org.itxtech.daedalus.util.Logger; import java.net.InetAddress; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; /** * Daedalus Project @@ -21,12 +27,21 @@ import java.util.HashMap; */ public class DNSServerHelper { private static HashMap portCache = null; + public static HashMap> domainCache = null; - public static void clearPortCache() { + public static void clearCache() { portCache = null; + domainCache = null; } - public static void buildPortCache() { + public static void buildCache() { + domainCache = new HashMap<>(); + if (ProviderPicker.getDnsQueryMethod() >= ProviderPicker.DNS_QUERY_METHOD_HTTPS_IETF && + !Daedalus.getPrefs().getBoolean("settings_dont_build_doh_cache", false)) { + buildDomainCache(getAddressById(getPrimary())); + buildDomainCache(getAddressById(getSecondary())); + } + portCache = new HashMap<>(); for (DNSServer server : Daedalus.DNS_SERVERS) { portCache.put(server.getAddress(), server.getPort()); @@ -35,7 +50,16 @@ public class DNSServerHelper { for (CustomDNSServer server : Daedalus.configurations.getCustomDNSServers()) { portCache.put(server.getAddress(), server.getPort()); } + } + private static void buildDomainCache(String addr) { + addr = HttpsProvider.HTTPS_SUFFIX + addr; + String host = Uri.parse(addr).getHost(); + try { + domainCache.put(host, Arrays.asList(InetAddress.getAllByName(host))); + } catch (Exception e) { + Logger.logException(e); + } } public static int getPortOrDefault(InetAddress address, int defaultPort) { diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 6f2285e..05ee9a3 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -60,12 +60,11 @@ 支持和帮助 高级系统设置 开启 - 本地规则解析 使用手册 访问 GitHub wiki 页面。 日志大小限制 调试输出 - 允许动态更新规则 + 不缓存 DoH DNS 的 IP地址 使用暗主题 DNS 查询方式 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index e9f9a0a..5aae473 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -60,12 +60,11 @@ 支援與說明 進階系統設定 開啟 - 本機規則解析 使用手冊 造訪 GitHub wiki 頁面。 紀錄檔大小限制 调试输出 TODO - 允許動態規則重新載入 + 不缓存 DoH DNS 的 IP地址 使用暗主题 規則名稱 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d32b179..d0cf25c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -59,11 +59,10 @@ Help & Support Advanced System Settings On - Local Rules Resolver Log Size Limit Manual Visit GitHub wiki page. - Allow Dynamic Rule Reloading + Don\'t build DNS Cache for DoH DNS Debug Output Use Dark Theme DNS Query Method diff --git a/app/src/main/res/xml/perf_settings.xml b/app/src/main/res/xml/perf_settings.xml index 0e2c78a..0a5f9cd 100644 --- a/app/src/main/res/xml/perf_settings.xml +++ b/app/src/main/res/xml/perf_settings.xml @@ -81,13 +81,8 @@ android:defaultValue="false" android:enabled="false"/> -