From 26b6853061142035159f472ad0aa8b2c62e270ab Mon Sep 17 00:00:00 2001 From: Max Lv Date: Sun, 18 Jun 2017 15:59:47 +0800 Subject: [PATCH] Add local DNS to dns list. #1281 --- .../com/github/shadowsocks/utils/Dns.java | 73 +++++++++++++++++++ .../com/github/shadowsocks/BaseService.scala | 17 ++++- 2 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 mobile/src/main/java/com/github/shadowsocks/utils/Dns.java diff --git a/mobile/src/main/java/com/github/shadowsocks/utils/Dns.java b/mobile/src/main/java/com/github/shadowsocks/utils/Dns.java new file mode 100644 index 0000000000..d203f978c2 --- /dev/null +++ b/mobile/src/main/java/com/github/shadowsocks/utils/Dns.java @@ -0,0 +1,73 @@ +/* + * Copyright 2010 Brave New Software Project, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.github.shadowsocks.utils; + +import android.annotation.SuppressLint; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.annotation.TargetApi; +import android.util.Log; +import android.net.ConnectivityManager; +import android.net.LinkProperties; +import android.os.Build; + +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Collection; +import java.net.InetAddress; + +public class Dns { + + public static String getDnsResolver(Context context) throws Exception { + Collection dnsResolvers = getDnsResolvers(context); + if (dnsResolvers.isEmpty()) { + throw new Exception("Couldn't find an active DNS resolver"); + } + String dnsResolver = dnsResolvers.iterator().next().toString(); + if (dnsResolver.startsWith("/")) { + dnsResolver = dnsResolver.substring(1); + } + return dnsResolver; + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + private static Collection getDnsResolvers(Context context) throws Exception { + ArrayList addresses = new ArrayList(); + ConnectivityManager connectivityManager = + (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); + Class LinkPropertiesClass = Class.forName("android.net.LinkProperties"); + Method getActiveLinkPropertiesMethod = ConnectivityManager.class.getMethod("getActiveLinkProperties", new Class []{}); + Object linkProperties = getActiveLinkPropertiesMethod.invoke(connectivityManager); + if (linkProperties != null) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + Method getDnsesMethod = LinkPropertiesClass.getMethod("getDnses", new Class []{}); + Collection dnses = (Collection)getDnsesMethod.invoke(linkProperties); + for (Object dns : dnses) { + addresses.add((InetAddress)dns); + } + } else { + for (InetAddress dns : ((LinkProperties)linkProperties).getDnsServers()) { + addresses.add(dns); + } + } + } + + return addresses; + } +} diff --git a/mobile/src/main/scala/com/github/shadowsocks/BaseService.scala b/mobile/src/main/scala/com/github/shadowsocks/BaseService.scala index 3727d4052b..efa325eb42 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/BaseService.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/BaseService.scala @@ -341,12 +341,21 @@ trait BaseService extends Service { val remoteDns = new JSONArray(profile.remoteDns.split(",").zipWithIndex.map { case (dns, i) => makeDns("UserDef-" + i, dns.trim) }) + val localDns = new JSONArray(Array( + makeDns("Primary-1", "119.29.29.29", edns = false), + makeDns("Primary-2", "114.114.114.114", edns = false) + )) + + try { + val localLinkDns = com.github.shadowsocks.utils.Dns.getDnsResolver(this) + localDns.put(makeDns("Primary-3", localLinkDns, edns = false)) + } catch { + case _: Exception => // Ignore + } + profile.route match { case Acl.BYPASS_CHN | Acl.BYPASS_LAN_CHN | Acl.GFWLIST | Acl.CUSTOM_RULES => config - .put("PrimaryDNS", new JSONArray(Array( - makeDns("Primary-1", "119.29.29.29", edns = false), - makeDns("Primary-2", "114.114.114.114", edns = false) - ))) + .put("PrimaryDNS", localDns) .put("AlternativeDNS", remoteDns) .put("IPNetworkFile", "china_ip_list.txt") .put("DomainFile", "gfwlist.txt")