diff --git a/app/build.gradle b/app/build.gradle index 5236c75d0..dc68de0fc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -111,6 +111,7 @@ dependencies { implementation "com.microsoft.appcenter:appcenter-crashes:${appCenterSdkVersion}" implementation "com.microsoft.appcenter:appcenter-distribute:${appCenterSdkVersion}" implementation 'com.squareup.okhttp3:okhttp:3.14.7' + implementation 'com.squareup.okhttp3:okhttp-dnsoverhttps:3.14.7' implementation 'com.takisoft.preferencex:preferencex:1.1.0' implementation 'tech.rectifier.preferencex-android:preferencex-simplemenu:88f93154b2' implementation 'org.ccil.cowan.tagsoup:tagsoup:1.2.1' diff --git a/app/src/main/java/com/hippo/ehviewer/Settings.java b/app/src/main/java/com/hippo/ehviewer/Settings.java index aa938f389..167c9e857 100755 --- a/app/src/main/java/com/hippo/ehviewer/Settings.java +++ b/app/src/main/java/com/hippo/ehviewer/Settings.java @@ -91,7 +91,8 @@ public class Settings { public static final String KEY_ENABLE_FINGERPRINT = "enable_fingerprint"; public static final String KEY_READ_CACHE_SIZE = "read_cache_size"; public static final int DEFAULT_READ_CACHE_SIZE = 160; - public static final String KEY_BUILT_IN_HOSTS = "built_in_hosts"; + public static final String KEY_BUILT_IN_HOSTS = "built_in_hosts_2"; + public static final String KEY_DOH = "dns_over_https"; public static final String KEY_APP_LANGUAGE = "app_language"; private static final String TAG = Settings.class.getSimpleName(); private static final String KEY_VERSION_CODE = "version_code"; @@ -235,6 +236,7 @@ public class Settings { private static final String KEY_SAVE_CRASH_LOG = "save_crash_log"; private static final boolean DEFAULT_SAVE_CRASH_LOG = false; private static final boolean DEFAULT_BUILT_IN_HOSTS = false; + private static final boolean DEFAULT_DOH = false; private static final String DEFAULT_APP_LANGUAGE = "system"; private static final String KEY_PROXY_TYPE = "proxy_type"; private static final int DEFAULT_PROXY_TYPE = EhProxySelector.TYPE_SYSTEM; @@ -272,9 +274,9 @@ public class Settings { private static void fixDefaultValue(Context context) { // Enable builtin hosts if the country is CN - if (!sSettingsPre.contains(KEY_BUILT_IN_HOSTS)) { + if (!sSettingsPre.contains(KEY_DOH)) { if ("CN".equals(Locale.getDefault().getCountry())) { - putBuiltInHosts(true); + putDoH(true); } } } @@ -1002,6 +1004,14 @@ public class Settings { putBoolean(KEY_BUILT_IN_HOSTS, value); } + public static boolean getDoH() { + return getBoolean(KEY_DOH, DEFAULT_DOH); + } + + public static void putDoH(boolean value) { + putBoolean(KEY_DOH, value); + } + public static String getAppLanguage() { return getString(KEY_APP_LANGUAGE, DEFAULT_APP_LANGUAGE); } diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhDns.java b/app/src/main/java/com/hippo/ehviewer/client/EhDns.java index 0b3b57be3..7af0da90c 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhDns.java +++ b/app/src/main/java/com/hippo/ehviewer/client/EhDns.java @@ -37,6 +37,9 @@ import java.util.List; import java.util.Map; import okhttp3.Dns; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.dnsoverhttps.DnsOverHttps; public class EhDns implements Dns { @@ -53,9 +56,27 @@ public class EhDns implements Dns { } private final Hosts hosts; + private static DnsOverHttps dnsOverHttps; public EhDns(Context context) { hosts = EhApplication.getHosts(context); + DnsOverHttps.Builder builder = new DnsOverHttps.Builder() + .client(new OkHttpClient.Builder().build()) + .url(HttpUrl.get("https://cloudflare-dns.com/dns-query")); + try { + builder.bootstrapDnsHosts(InetAddress.getByName("162.159.36.1"), + InetAddress.getByName("162.159.46.1"), + InetAddress.getByName("1.1.1.1"), + InetAddress.getByName("1.0.0.1"), + InetAddress.getByName("162.159.132.53"), + InetAddress.getByName("2606:4700:4700::1111"), + InetAddress.getByName("2606:4700:4700::1001"), + InetAddress.getByName("2606:4700:4700::0064"), + InetAddress.getByName("2606:4700:4700::6400")); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + dnsOverHttps = builder.post(true).build(); } private static void put(Map map, String host, String ip) { @@ -79,6 +100,12 @@ public class EhDns implements Dns { return Collections.singletonList(inetAddress); } } + if (Settings.getDoH()) { + List inetAddresses = dnsOverHttps.lookup(hostname); + if (inetAddresses != null && inetAddresses.size() > 0) { + return inetAddresses; + } + } try { return Arrays.asList(InetAddress.getAllByName(hostname)); diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index a302827fa..03b661ff0 100755 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -734,4 +734,6 @@ 从剪贴板导入 未在剪贴板中发现 Cookeis。 从搜索记录中删除“%s”? + 安全 DNS(DoH) + 解决某些地区的 DNS 污染问题 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bbdd10800..fb868df2b 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -598,6 +598,8 @@ %1$s Built-in hosts.txt Apply the built-in host-to-IP mapping provided by the app.\nIt can be overridden by custom hosts.txt. + DNS over HTTPS + Workaround DNS poisoning in some nations. Custom hosts.txt Map hostnames to IP addresses.\nIt can override built-in hosts.txt. Pattern protection diff --git a/app/src/main/res/xml/advanced_settings.xml b/app/src/main/res/xml/advanced_settings.xml index 6c4bee393..b635a594a 100644 --- a/app/src/main/res/xml/advanced_settings.xml +++ b/app/src/main/res/xml/advanced_settings.xml @@ -86,6 +86,13 @@ app:activity="com.hippo.ehviewer.ui.HostsActivity" app:iconSpaceReserved="false" /> + +