diff --git a/proguard-rules.pro b/proguard-rules.pro index 7b52e73..c70bd52 100644 --- a/proguard-rules.pro +++ b/proguard-rules.pro @@ -36,7 +36,7 @@ # 对外接口类 -keep public class com.tencent.msdk.dns.DnsService {*;} -keep public class com.tencent.msdk.dns.core.IpSet {*;} --keep public class com.tencent.msdk.dns.core.ipRank.IpRankItem {*;} +-keep public class com.tencent.msdk.dns.core.rank.IpRankItem {*;} -keep public class com.tencent.msdk.dns.DnsConfig {*;} -keep public class com.tencent.msdk.dns.HttpDnsResponseObserver {*;} -keep public class com.tencent.msdk.dns.DnsConfig$Builder {*;} diff --git a/src/main/java/com/tencent/msdk/dns/BackupResolver.java b/src/main/java/com/tencent/msdk/dns/BackupResolver.java index aedc5b3..e96fe95 100644 --- a/src/main/java/com/tencent/msdk/dns/BackupResolver.java +++ b/src/main/java/com/tencent/msdk/dns/BackupResolver.java @@ -39,7 +39,8 @@ private BackupResolver() { // 尝试切回主ip的间隔时间,默认为10分钟 private final long mInterval = 10 * 60 * 1000; - public static BackupResolver getInstance() {//静态get方法 + public static BackupResolver getInstance() { + // 静态get方法 if (mBackupResolver == null) { synchronized (BackupResolver.class) { if (mBackupResolver == null) { @@ -53,7 +54,7 @@ public static BackupResolver getInstance() {//静态get方法 public void init(DnsConfig dnsConfig) { mConfig = dnsConfig; mErrorCount = new AtomicInteger(0); - // http和https是两个IP + // http和https是两个IP dnsIps = getBackUpIps(); } @@ -66,9 +67,11 @@ public void getServerIps() { private ArrayList getBackUpIps() { if (Const.HTTPS_CHANNEL.equals(mConfig.channel) && !BuildConfig.HTTPS_TOLERANCE_SERVER.isEmpty()) { - return new ArrayList(Arrays.asList(BuildConfig.HTTPS_INIT_SERVER, BuildConfig.HTTPS_TOLERANCE_SERVER)); + return new ArrayList(Arrays.asList(BuildConfig.HTTPS_INIT_SERVER, + BuildConfig.HTTPS_TOLERANCE_SERVER)); } else { - return new ArrayList(Arrays.asList(BuildConfig.HTTP_INIT_SERVER, BuildConfig.HTTP_TOLERANCE_SERVER)); + return new ArrayList(Arrays.asList(BuildConfig.HTTP_INIT_SERVER, + BuildConfig.HTTP_TOLERANCE_SERVER)); } } @@ -97,12 +100,10 @@ public boolean getCanReport(int errorCount) { /** * 主IP故障,切换备份IP策略 - * 1. 主备IP切换:在精确性、速度上折中处理,主IP解析的同时,会发起LocalDNS解析,若主IP首次解析不成功,立即返回 上次解析结果,如果没有上次解析结果,则返回LocalDNS解析结果,如果主IP 3次解析不成功,则切换到备份IP进行解析。 - *

- * 2. 备份IP 切换 域名兜底:所有备份IP都经超过3次不通,切换到域名兜底解析。 - *

+ * 1. 主备IP切换:在精确性、速度上折中处理,主IP解析的同时,会发起LocalDNS解析,若主IP首次解析不成功,立即返回 + * 上次解析结果,如果没有上次解析结果,则返回LocalDNS解析结果,如果主IP 3次解析不成功,则切换到备份IP进行解析。 + * 2. 备份IP切换 域名兜底:所有备份IP都经超过3次不通,切换到域名兜底解析。 * 3. 恢复:每隔10min切回测试一次主IP(不主动探测主备IP是否恢复) - *

* 4. 通过参数控制 切换策略的次数判断(默认3次)、恢复主IP策略的时间间隔(默认10min) */ public String getDnsIp() { @@ -143,7 +144,8 @@ public void run() { try { String dnsIp = BackupResolver.getInstance().getDnsIp(); String domain = BuildConfig.DOMAIN_SERVICE_DOMAINS[0]; - LookupExtra lookupExtra = new LookupExtra(BuildConfig.DOMAIN_SERVICE_ID, BuildConfig.DOMSIN_SERVICE_KEY, BuildConfig.DOMAIN_SERVICE_TOKEN); + LookupExtra lookupExtra = new LookupExtra(BuildConfig.DOMAIN_SERVICE_ID, + BuildConfig.DOMSIN_SERVICE_KEY, BuildConfig.DOMAIN_SERVICE_TOKEN); LookupParameters lookupParameters = new LookupParameters.Builder() .dnsIp(dnsIp) .channel("DesHttp") diff --git a/src/main/java/com/tencent/msdk/dns/DnsConfig.java b/src/main/java/com/tencent/msdk/dns/DnsConfig.java index af8625b..0bedcbe 100644 --- a/src/main/java/com/tencent/msdk/dns/DnsConfig.java +++ b/src/main/java/com/tencent/msdk/dns/DnsConfig.java @@ -9,7 +9,7 @@ import com.tencent.msdk.dns.base.report.IReporter; import com.tencent.msdk.dns.base.utils.CommonUtils; import com.tencent.msdk.dns.core.Const; -import com.tencent.msdk.dns.core.ipRank.IpRankItem; +import com.tencent.msdk.dns.core.rank.IpRankItem; import com.tencent.msdk.dns.core.rest.share.LookupExtra; import java.util.ArrayList; @@ -62,16 +62,13 @@ public final class DnsConfig { public String routeIp; - private DnsConfig(int logLevel, - String appId, String userId, boolean initBuiltInReporters, - String dnsId, String dnsKey, String token, - int timeoutMills, - Set protectedDomains, - Set preLookupDomains, boolean enablePersistentCache, Set persistentCacheDomains, - Set ipRankItems, String channel, boolean enableReport, boolean blockFirst, + private DnsConfig(int logLevel, String appId, String userId, boolean initBuiltInReporters, String dnsId, + String dnsKey, String token, int timeoutMills, Set protectedDomains, + Set preLookupDomains, boolean enablePersistentCache, Set persistentCacheDomains + , Set ipRankItems, String channel, boolean enableReport, boolean blockFirst, int customNetStack, DnsExecutors.ExecutorSupplier executorSupplier, - ILookedUpListener lookedUpListener, List logNodes, - List reporters, boolean useExpiredIpEnable, boolean cachedIpEnable, String routeIp) { + ILookedUpListener lookedUpListener, List logNodes, List reporters, + boolean useExpiredIpEnable, boolean cachedIpEnable, String routeIp) { this.logLevel = logLevel; this.appId = appId; this.userId = userId; @@ -114,30 +111,30 @@ boolean needProtect(/* @Nullable */String hostname) { @Override public String toString() { - return "DnsConfig{" + - "logLevel=" + logLevel + - ", appId='" + appId + '\'' + - ", userId='" + userId + '\'' + - ", lookupExtra=" + lookupExtra + - ", timeoutMills=" + timeoutMills + - ", protectedDomains=" + CommonUtils.toString(protectedDomains) + - ", preLookupDomains=" + CommonUtils.toString(preLookupDomains) + - ", enablePersistentCache=" + enablePersistentCache + - ", persistentCacheDomains=" + CommonUtils.toString(persistentCacheDomains) + - ", IpRankItems=" + CommonUtils.toString(ipRankItems) + - ", channel='" + channel + '\'' + - ", enableReport='" + enableReport + '\'' + - ", blockFirst=" + blockFirst + - ", customNetStack=" + customNetStack + - ", executorSupplier=" + executorSupplier + - ", lookedUpListener=" + lookedUpListener + - ", logNodes=" + CommonUtils.toString(logNodes) + - ", reporters=" + CommonUtils.toString(reporters) + - ", useExpiredIpEnable=" + useExpiredIpEnable + - ", cachedIpEnable=" + cachedIpEnable + - ", enableDomainServer=" + enableDomainServer + - ", routeIp=" + routeIp + - '}'; + return "DnsConfig{" + + "logLevel=" + logLevel + + ", appId='" + appId + '\'' + + ", userId='" + userId + '\'' + + ", lookupExtra=" + lookupExtra + + ", timeoutMills=" + timeoutMills + + ", protectedDomains=" + CommonUtils.toString(protectedDomains) + + ", preLookupDomains=" + CommonUtils.toString(preLookupDomains) + + ", enablePersistentCache=" + enablePersistentCache + + ", persistentCacheDomains=" + CommonUtils.toString(persistentCacheDomains) + + ", IpRankItems=" + CommonUtils.toString(ipRankItems) + + ", channel='" + channel + '\'' + + ", enableReport='" + enableReport + '\'' + + ", blockFirst=" + blockFirst + + ", customNetStack=" + customNetStack + + ", executorSupplier=" + executorSupplier + + ", lookedUpListener=" + lookedUpListener + + ", logNodes=" + CommonUtils.toString(logNodes) + + ", reporters=" + CommonUtils.toString(reporters) + + ", useExpiredIpEnable=" + useExpiredIpEnable + + ", cachedIpEnable=" + cachedIpEnable + + ", enableDomainServer=" + enableDomainServer + + ", routeIp=" + routeIp + + '}'; } /* @VisibleForTesting */ @@ -169,10 +166,10 @@ boolean contains(String hostname) { @Override public String toString() { - return "WildcardDomain{" + - "mIsWildcard=" + mIsWildcard + - ", mNakedDomain='" + mNakedDomain + '\'' + - '}'; + return "WildcardDomain{" + + "mIsWildcard=" + mIsWildcard + + ", mNakedDomain='" + mNakedDomain + '\'' + + '}'; } } @@ -232,14 +229,18 @@ public static final class Builder { * SDK默认仅将日志通过logcat输出, tag统一使用HTTPDNS * 不设置时, 默认输出WARN及以上等级的日志 * - * @param logLevel 最低日志等级, 使用Log类定义的常量, 可选值为 + * @param logLevel 最低日志等级, 使用Log + * 类定义的常量, 可选值为 * VERBOSE, - * DEBUG, + * DEBUG + * , * INFO, * WARN, - * ERROR, + * ERROR + * , * ASSERT, - * 其中ASSERT即不输出任何日志 + * 其中 + * ASSERT即不输出任何日志 * @return 当前Builder实例, 方便链式调用 */ public Builder logLevel(int logLevel) { @@ -280,7 +281,7 @@ public Builder userId(String userId) { /** * 启停缓存自动刷新功能, 默认开启 * - * @param enablePersistentCache, 启停缓存自动刷新功能 + * @param enablePersistentCache 启停缓存自动刷新功能 * @return 当前Builder实例, 方便链式调用 */ public Builder enablePersistentCache(boolean enablePersistentCache) { @@ -342,12 +343,13 @@ public Builder dnsId(String dnsId) { /** * 设置DnsKey * - * @param dnsKey dnsKey, 即HTTPDNS服务的授权Id对应的加密密钥, 从腾讯云官网申请获得 + * @param dnsKey dnsKey, 即HTTPDNS服务的授权Id对应的加密密钥, 从腾讯云官网 + * 申请获得 * @return 当前Builder实例, 方便链式调用 * @throws IllegalArgumentException dnsKey为空时抛出 */ public Builder dnsKey(String dnsKey) { - if (TextUtils.isEmpty(dnsKey)) { + if (mChannel != Const.HTTPS_CHANNEL && TextUtils.isEmpty(dnsKey)) { throw new IllegalArgumentException("dnsKey".concat(Const.EMPTY_TIPS)); } mDnsKey = dnsKey; @@ -391,8 +393,7 @@ public Builder timeoutMills(int timeoutMills) { */ public Builder maxNumOfPreLookupDomains(int maxNumOfPreLookupDomains) { if (0 >= maxNumOfPreLookupDomains) { - throw new IllegalArgumentException( - "maxNumOfPreLookupDomains".concat(Const.LESS_THAN_0_TIPS)); + throw new IllegalArgumentException("maxNumOfPreLookupDomains".concat(Const.LESS_THAN_0_TIPS)); } mMaxNumOfPreLookupDomains = maxNumOfPreLookupDomains; return this; @@ -558,7 +559,8 @@ public Builder ipRankItems(List ipRankItems) { public Builder channel(String channel) { if (channel.equals(Const.HTTPS_CHANNEL) && BuildConfig.FLAVOR.equals("intl")) { - throw new IllegalArgumentException("httpdns-sdk-intl version still doesn't support " + Const.HTTPS_CHANNEL); + throw new IllegalArgumentException("httpdns-sdk-intl version still doesn't support " + + Const.HTTPS_CHANNEL); } mChannel = channel; return this; @@ -576,7 +578,8 @@ public Builder desHttp() { public Builder https() { if (BuildConfig.FLAVOR.equals("intl")) { - throw new IllegalArgumentException("httpdns-sdk-intl version still doesn't support " + Const.HTTPS_CHANNEL); + throw new IllegalArgumentException("httpdns-sdk-intl version still doesn't support " + + Const.HTTPS_CHANNEL); } mChannel = Const.HTTPS_CHANNEL; return this; @@ -618,16 +621,17 @@ public Builder nonBlockFirst() { /** * 设置{@link DnsExecutors.ExecutorSupplier}, 用于为SDK定制线程池 - * 不设置时, 默认使用THREAD_POOL_EXECUTOR作为SDK内部使用的线程池 + * 不设置时, 默认使用 + * THREAD_POOL_EXECUTOR作为SDK内部使用的线程池 * - * @param executorSupplier {@link DnsExecutors.ExecutorSupplier}接口实现类实例, SDK通过{@link DnsExecutors.ExecutorSupplier#get()}获取SDK内部使用的线程池 + * @param executorSupplier {@link DnsExecutors.ExecutorSupplier}接口实现类实例, + * SDK通过{@link DnsExecutors.ExecutorSupplier#get()}获取SDK内部使用的线程池 * @return 当前Builder实例, 方便链式调用 * @throws IllegalArgumentException executorSupplier为null时抛出 */ public Builder executorSupplier(DnsExecutors.ExecutorSupplier executorSupplier) { if (null == executorSupplier) { - throw new IllegalArgumentException( - "executorSupplier".concat(Const.NULL_POINTER_TIPS)); + throw new IllegalArgumentException("executorSupplier".concat(Const.NULL_POINTER_TIPS)); } mExecutorSupplier = executorSupplier; return this; @@ -642,8 +646,7 @@ public Builder executorSupplier(DnsExecutors.ExecutorSupplier executorSupplier) */ public Builder lookedUpListener(ILookedUpListener lookedUpListener) { if (null == lookedUpListener) { - throw new IllegalArgumentException( - "lookedUpListener".concat(Const.NULL_POINTER_TIPS)); + throw new IllegalArgumentException("lookedUpListener".concat(Const.NULL_POINTER_TIPS)); } mLookedUpListener = lookedUpListener; return this; @@ -690,8 +693,10 @@ public Builder setCustomNetStack(int customNetStack) { * 允许使用过期缓存 * * @param useExpiredIpEnable 默认false,解析时先取未过期的缓存结果,不满足则等待解析请求完成后返回解析结果 - * 设置为true时,会直接返回缓存的解析结果,没有缓存则返回0;0,用户可使用localdns(InetAddress)进行兜底。且在无缓存结果或缓存已过期时,会异步发起解析请求更新缓存。 - * 因异步API(getAddrByNameAsync,getAddrsByNameAsync)逻辑在回调中始终返回未过期的解析结果,设置为true时,异步API不可使用。建议使用同步API (getAddrByName,getAddrsByName) + * 设置为true时,会直接返回缓存的解析结果,没有缓存则返回0; + * 0,用户可使用localdns(InetAddress)进行兜底。且在无缓存结果或缓存已过期时,会异步发起解析请求更新缓存。 + * 因异步API(getAddrByNameAsync,getAddrsByNameAsync)逻辑在回调中始终返回未过期的解析结果,设置为true时,异步API + * 不可使用。建议使用同步API (getAddrByName,getAddrsByName) * @return 当前Builder实例, 方便链式调用 */ public Builder setUseExpiredIpEnable(boolean useExpiredIpEnable) { @@ -728,14 +733,20 @@ public Builder routeIp(String routeIp) { * @return DnsConfig实例 */ public DnsConfig build() { - return new DnsConfig(mLogLevel, - mAppId, mUserId, mInitBuiltInReporters, mDnsId, mDnsKey, mToken, - mTimeoutMills, - mProtectedDomains, mPreLookupDomains, mEnablePersistentCache, mPersistentCacheDomains, - mIpRankItems, mChannel, mEnableReport, mBlockFirst, - mCustomNetStack, mExecutorSupplier, - mLookedUpListener, mLogNodes, - mReporters, mUseExpiredIpEnable, mCachedIpEnable, mRouteIp); + if (TextUtils.isEmpty(mDnsId)) { + throw new IllegalArgumentException("dnsId".concat(Const.EMPTY_TIPS)); + } + if (mChannel != Const.HTTPS_CHANNEL && TextUtils.isEmpty(mDnsKey)) { + throw new IllegalArgumentException("dnsKey".concat(Const.EMPTY_TIPS)); + } + if (mChannel == Const.HTTPS_CHANNEL && TextUtils.isEmpty(mToken)) { + throw new IllegalArgumentException("token".concat(Const.EMPTY_TIPS)); + } + return new DnsConfig(mLogLevel, mAppId, mUserId, mInitBuiltInReporters, mDnsId, mDnsKey, mToken, + mTimeoutMills, mProtectedDomains, mPreLookupDomains, mEnablePersistentCache, + mPersistentCacheDomains, mIpRankItems, mChannel, mEnableReport, mBlockFirst, mCustomNetStack, + mExecutorSupplier, mLookedUpListener, mLogNodes, mReporters, mUseExpiredIpEnable, mCachedIpEnable + , mRouteIp); } } } diff --git a/src/main/java/com/tencent/msdk/dns/DnsService.java b/src/main/java/com/tencent/msdk/dns/DnsService.java index 7ceb9f2..8796dfb 100644 --- a/src/main/java/com/tencent/msdk/dns/DnsService.java +++ b/src/main/java/com/tencent/msdk/dns/DnsService.java @@ -57,7 +57,8 @@ public static Context getAppContext() { /** * 初始化SDK * - * @param context Context实例, SDK内部持有ApplicationContext用于监听网络切换等操作 + * @param context Context + * 实例, SDK内部持有ApplicationContext用于监听网络切换等操作 * @param config {@link DnsConfig}实例, 用于对SDK进行相关配置 * @throws IllegalArgumentException context为null时抛出 */ @@ -170,7 +171,7 @@ public static synchronized void setCachedIpEnable(boolean mCachedIpEnable) { /** * 设置是否上报,是否启用域名服务(获取底层配置) * - * @param mEnableReport 启用日志上报 + * @param mEnableReport 启用日志上报 * @param mEnableDomainServer 启用域名服务 */ public static void setDnsConfigFromServer(boolean mEnableReport, boolean mEnableDomainServer) { @@ -181,20 +182,27 @@ public static void setDnsConfigFromServer(boolean mEnableReport, boolean mEnable sConfig.enableDomainServer = mEnableDomainServer; } + /** + * 获取DNS详情(命中缓存数据) + * + * @param hostname 域名,支持多个域名,用,拼接 + * @return 解析数据 + */ public static String getDnsDetail(String hostname) { String dnsIp = BackupResolver.getInstance().getDnsIp(); - final LookupResult lookupResult = DnsManager.getResultFromCache(new LookupParameters.Builder() - .context(sAppContext) - .hostname(hostname) - .timeoutMills(sConfig.timeoutMills) - .dnsIp(dnsIp) - .lookupExtra(sConfig.lookupExtra) - .channel(sConfig.channel) - .fallback2Local(true) - .blockFirst(sConfig.blockFirst) - .enableAsyncLookup(false) - .customNetStack(sConfig.customNetStack) - .build()); + final LookupResult lookupResult = + DnsManager.getResultFromCache(new LookupParameters.Builder() + .context(sAppContext) + .hostname(hostname) + .timeoutMills(sConfig.timeoutMills) + .dnsIp(dnsIp) + .lookupExtra(sConfig.lookupExtra) + .channel(sConfig.channel) + .fallback2Local(true) + .blockFirst(sConfig.blockFirst) + .enableAsyncLookup(false) + .customNetStack(sConfig.customNetStack) + .build()); // 收集命中缓存的数据 DnsExecutors.WORK.execute(new Runnable() { @@ -275,7 +283,8 @@ private static IpSet getAddrsByName(/* @Nullable */String hostname, String dnsIp = BackupResolver.getInstance().getDnsIp(); // NOTE: trim操作太重,下层默认不再处理 - DnsLog.v("DnsService.getAddrsByName(%s, %s, %b, %b) called", hostname, channel, fallback2Local, enableAsyncLookup); + DnsLog.v("DnsService.getAddrsByName(%s, %s, %b, %b) called", hostname, channel, fallback2Local, + enableAsyncLookup); if (sConfig.needProtect(hostname)) { LookupResult lookupResult = DnsManager .lookupWrapper(new LookupParameters.Builder() @@ -316,7 +325,8 @@ private static IpSet getAddrsByName(/* @Nullable */String hostname, * @param domain 域名 * @return 解析结果 * 单独接口查询情况返回:IpSet{v4Ips=[xx.xx.xx.xx], v6Ips=[xxx], ips=null} - * 多域名批量查询返回:IpSet{v4Ips=[youtube.com:31.13.73.1, qq.com:123.151.137.18, qq.com:183.3.226.35, qq.com:61.129.7.47], v6Ips=[youtube.com.:2001::42d:9141], ips=null} + * 多域名批量查询返回:IpSet{v4Ips=[youtube.com:31.13.73.1, qq.com:123.151.137.18, qq.com:183.3.226.35, qq.com:61.129.7 + * .47], v6Ips=[youtube.com.:2001::42d:9141], ips=null} */ public static IpSet getAddrsByNamesEnableExpired(final String domain) { if (!sInited) { @@ -336,10 +346,9 @@ public void run() { } else { try { JSONObject temp = new JSONObject(result); - long expiredTime = Long.parseLong(temp.get("expired_time").toString()); - final String requestDomain = temp.get("request_name").toString(); - long current = System.currentTimeMillis(); - if (expiredTime < current) { + final String requestDomain = (String) temp.get("request_name"); + // requestDomain为过期域名统计 + if (!requestDomain.isEmpty()) { // 缓存过期,发起异步请求 DnsExecutors.WORK.execute(new Runnable() { @Override @@ -376,16 +385,14 @@ private static void setLookedUpListener( DnsManager.setLookupListener(new ILookupListener() { @Override - public void onLookedUp(LookupParameters lookupParameters, - LookupResult lookupResult) { + public void onLookedUp(LookupParameters lookupParameters, LookupResult lookupResult) { String hostname = lookupParameters.hostname; if (!(lookupResult.stat instanceof StatisticsMerge)) { DnsLog.d("Looked up for %s may be by LocalDns", hostname); return; } StatisticsMerge stat = (StatisticsMerge) lookupResult.stat; - LookupResult expectedLookupResult = - new LookupResult<>(lookupResult.ipSet, stat); + LookupResult expectedLookupResult = new LookupResult<>(lookupResult.ipSet, stat); if (lookupParameters.ignoreCurNetStack) { if (DnsDescription.Family.UN_SPECIFIC == lookupParameters.family) { lookedUpListener.onPreLookedUp(hostname, expectedLookupResult); @@ -429,8 +436,7 @@ private static void preLookupAndStartAsyncLookup() { } final int numOfPreLookupDomain = sConfig.preLookupDomains.size(); - final String[] preLookupDomainsList = - sConfig.preLookupDomains.toArray(new String[numOfPreLookupDomain]); + final String[] preLookupDomainsList = sConfig.preLookupDomains.toArray(new String[numOfPreLookupDomain]); final String preLookupDomains = CommonUtils.toStringList(preLookupDomainsList, ","); // 预解析调整为批量解析 diff --git a/src/main/java/com/tencent/msdk/dns/ILookedUpListener.java b/src/main/java/com/tencent/msdk/dns/ILookedUpListener.java index d03224d..4714ba5 100644 --- a/src/main/java/com/tencent/msdk/dns/ILookedUpListener.java +++ b/src/main/java/com/tencent/msdk/dns/ILookedUpListener.java @@ -11,7 +11,7 @@ public interface ILookedUpListener { /** * 通过接口调用完成域名解析后的回调 * - * @param hostname 域名 + * @param hostname 域名 * @param lookupResult {@link LookupResult}实例, 即域名解析结果 */ void onLookedUp(String hostname, LookupResult lookupResult); @@ -19,7 +19,7 @@ public interface ILookedUpListener { /** * 预解析完成一次域名解析后的回调 * - * @param hostname 域名 + * @param hostname 域名 * @param lookupResult {@link LookupResult}实例, 即域名解析结果 */ void onPreLookedUp(String hostname, LookupResult lookupResult); @@ -27,7 +27,7 @@ public interface ILookedUpListener { /** * 异步解析完成一次域名解析后的回调 * - * @param hostname 域名 + * @param hostname 域名 * @param lookupResult {@link LookupResult}实例, 即域名解析结果 */ void onAsyncLookedUp(String hostname, LookupResult lookupResult); diff --git a/src/main/java/com/tencent/msdk/dns/MSDKDnsResolver.java b/src/main/java/com/tencent/msdk/dns/MSDKDnsResolver.java index 25225ef..48992b0 100644 --- a/src/main/java/com/tencent/msdk/dns/MSDKDnsResolver.java +++ b/src/main/java/com/tencent/msdk/dns/MSDKDnsResolver.java @@ -43,28 +43,33 @@ public static MSDKDnsResolver getInstance() { /** * 初始化SDK * - * @param context Context实例, SDK内部持有ApplicationContext用于监听网络切换等操作 + * @param context Context + * 实例, SDK内部持有ApplicationContext用于监听网络切换等操作 * @param appId 即SDK appId, 从腾讯云官网申请获得 * @param debug 是否输出调试日志, true为输出, false不输出, SDK默认仅将日志通过logcat输出, tag统一使用HTTPDNS - * @param dnsIp 由外部传入的dnsIp,可选:"119.29.29.98"(仅支持 http 请求),"119.29.29.99"(仅支持 https 请求)以腾讯云文档(https://cloud.tencent.com/document/product/379/54976)提供的 IP 为准 + * @param dnsIp 由外部传入的dnsIp,可选:"119.29.29.98"(仅支持 http 请求),"119.29.29.99"(仅支持 https 请求)以腾讯云文档(https://cloud + * .tencent.com/document/product/379/54976)提供的 IP 为准 * @param timeout 域名解析请求超时时间, 单位为ms */ public void init(Context context, String appId, String dnsIp, boolean debug, int timeout) { try { // NOTE: 兼容旧版本实现, 参数不合法时不crash init(context, appId, null, null, dnsIp, debug, timeout); - } catch (Exception e) { + } catch (Exception ignored) { + DnsLog.e("exception: %s", ignored); } } /** * 初始化SDK * - * @param context Context实例, SDK内部持有ApplicationContext用于监听网络切换等操作 + * @param context Context + * 实例, SDK内部持有ApplicationContext用于监听网络切换等操作 * @param appId 即SDK appId, 从腾讯云官网申请获得 * @param dnsId 即HTTPDNS服务的授权Id, 从腾讯云官网申请获得 * @param dnsKey 即HTTPDNS服务的授权Id对应的加密密钥, 从腾讯云官网申请获得 - * @param dnsIp 由外部传入的dnsIp,可选:"119.29.29.98"(仅支持 http 请求),"119.29.29.99"(仅支持 https 请求)以腾讯云文档(https://cloud.tencent.com/document/product/379/54976)提供的 IP 为准 + * @param dnsIp 由外部传入的dnsIp,可选:"119.29.29.98"(仅支持 http 请求),"119.29.29.99"(仅支持 https 请求)以腾讯云文档(https://cloud + * .tencent.com/document/product/379/54976)提供的 IP 为准 * @param debug 是否输出调试日志, true为输出, false不输出, SDK默认仅将日志通过logcat输出, tag统一使用HTTPDNS * @param timeout 域名解析请求超时时间, 单位为ms */ @@ -76,11 +81,13 @@ public void init(Context context, String appId, String dnsId, String dnsKey, Str /** * 初始化SDK * - * @param context Context实例, SDK内部持有ApplicationContext用于监听网络切换等操作 + * @param context Context + * 实例, SDK内部持有ApplicationContext用于监听网络切换等操作 * @param appId 即SDK appId, 从腾讯云官网申请获得 * @param dnsId 即HTTPDNS服务的授权Id, 从腾讯云官网申请获得 * @param dnsKey 即HTTPDNS服务的授权Id对应的加密密钥, 从腾讯云官网申请获得 - * @param dnsIp 由外部传入的dnsIp,可选:"119.29.29.98"(仅支持 http 请求),"119.29.29.99"(仅支持 https 请求)以腾讯云文档(https://cloud.tencent.com/document/product/379/54976)提供的 IP 为准 + * @param dnsIp 由外部传入的dnsIp,可选:"119.29.29.98"(仅支持 http 请求),"119.29.29.99"(仅支持 https 请求)以腾讯云文档(https://cloud + * .tencent.com/document/product/379/54976)提供的 IP 为准 * @param debug 是否输出调试日志, true为输出, false不输出, SDK默认仅将日志通过logcat输出, tag统一使用HTTPDNS * @param timeout 域名解析请求超时时间, 单位为ms */ @@ -130,8 +137,10 @@ public void init(Context context, String appID, String dnsId, String dnsKey, Str * @param context 应用上下文,最好传入 ApplicationContext * @param appID 业务 appkey,即 SDK AppID,腾讯云官网(https://console.cloud.tencent.com/httpdns)申请获得,用于上报 * @param dnsId dns解析id,即授权id,腾讯云官网(https://console.cloud.tencent.com/httpdns)申请获得,用于域名解析鉴权 - * @param dnsKey dns解析key,即授权id对应的 key(加密密钥),在申请 SDK 后的邮箱里,腾讯云官网(https://console.cloud.tencent.com/httpdns)申请获得,用于域名解析鉴权 - * @param dnsIp 由外部传入的dnsIp,可选:"119.29.29.98"(仅支持 http 请求),"119.29.29.99"(仅支持 https 请求)以腾讯云文档(https://cloud.tencent.com/document/product/379/54976)提供的 IP 为准 + * @param dnsKey dns解析key,即授权id对应的 key(加密密钥),在申请 SDK 后的邮箱里,腾讯云官网(https://console.cloud.tencent + * .com/httpdns)申请获得,用于域名解析鉴权 + * @param dnsIp 由外部传入的dnsIp,可选:"119.29.29.98"(仅支持 http 请求),"119.29.29.99"(仅支持 https 请求)以腾讯云文档(https://cloud + * .tencent.com/document/product/379/54976)提供的 IP 为准 * @param debug 是否开启 debug 日志,true 为打开,false 为关闭,建议测试阶段打开,正式上线时关闭 * @param timeout dns请求超时时间,单位ms,建议设置2000 * @param channel 设置 channel,可选:DesHttp(默认), AesHttp, Https @@ -205,7 +214,7 @@ private void setUseExpiredIpEnable(boolean useExpiredIpEnable) { * @param openId 用户的唯一标识符, 腾讯业务建议直接使用OpenId, 腾讯云客户建议传入长度50位以内, 由字母数字下划线组合而成的字符串 * @return 是否设置成功, true为设置成功, false为设置失败 */ - @SuppressWarnings("UnusedReturnValue") + @SuppressWarnings({"UnusedReturnValue", "checkstyle:MethodName"}) public boolean WGSetDnsOpenId(String openId) { DnsLog.v("MSDKDnsResolver.WGSetDnsOpenId() called."); @@ -240,16 +249,6 @@ public String getAddrByName(String domain) { } } - /** - * 常规DNS解析逻辑 - * - * @param domain 域名 - * @return - */ - private String getAddrByNameNormal(String domain) { - return getAddrByName(domain, true); - } - public String getAddrByName(String domain, boolean fallback2Local) { DnsLog.v("MSDKDnsResolver.getAddrByName() called."); IpSet ipSet = IpSet.EMPTY; @@ -257,11 +256,22 @@ public String getAddrByName(String domain, boolean fallback2Local) { try { ipSet = DnsService.getAddrsByName(domain, fallback2Local); } catch (Exception ignored) { + DnsLog.e("exception: %s", ignored); } return CommonUtils.getIpfromSet(ipSet); } + /** + * 常规DNS解析逻辑 + * + * @param domain 域名 + * @return + */ + private String getAddrByNameNormal(String domain) { + return getAddrByName(domain, true); + } + /** * 异步进行域名解析 * 接口区分本地网络栈进行解析 @@ -289,7 +299,8 @@ public void run() { }); } else { try { - throw new IllegalAccessException("getAddrByNameAsync cannot be used when useExpiredIpEnable is set to true."); + throw new IllegalAccessException("getAddrByNameAsync cannot be used when useExpiredIpEnable is set " + + "to true."); } catch (IllegalAccessException e) { e.printStackTrace(); } @@ -314,7 +325,8 @@ private String getAddrByNameEnableExpired(final String domain) { * 进行域名解析(批量情况) * 接口区分本地网络栈进行解析 * 单独接口查询情况返回:IpSet{v4Ips=[xx.xx.xx.xx], v6Ips=[xxx], ips=null} - * 多域名批量查询返回:IpSet{v4Ips=[youtube.com:31.13.73.1, qq.com:123.151.137.18, qq.com:183.3.226.35, qq.com:61.129.7.47], v6Ips=[youtube.com.:2001::42d:9141], ips=null} + * 多域名批量查询返回:IpSet{v4Ips=[youtube.com:31.13.73.1, qq.com:123.151.137.18, qq.com:183.3.226.35, qq.com:61.129.7 + * .47], v6Ips=[youtube.com.:2001::42d:9141], ips=null} * * @param domain 域名 * @return 解析结果, 以';'分隔, ';'前为IPv4, ';'后为IPv6, 对应位置没有解析结果则为'0' @@ -327,16 +339,6 @@ public IpSet getAddrsByName(String domain) { } } - /** - * 常规域名解析(批量) - * - * @param domain - * @return - */ - private IpSet getAddrsByNameNormal(String domain) { - return getAddrsByName(domain, true); - } - private IpSet getAddrsByName(String domain, boolean useHttp) { DnsLog.v("MSDKDnsResolver.getAddrsByName() called."); @@ -345,16 +347,28 @@ private IpSet getAddrsByName(String domain, boolean useHttp) { try { ipSet = DnsService.getAddrsByName(domain, useHttp); } catch (Exception ignored) { + DnsLog.e("exception: %s", ignored); } return ipSet; } + /** + * 常规域名解析(批量) + * + * @param domain 域名 + * @return 解析结果 + */ + private IpSet getAddrsByNameNormal(String domain) { + return getAddrsByName(domain, true); + } + /** * 异步进行域名解析(批量情况) * 接口区分本地网络栈进行解析 * 单独接口查询情况返回:IpSet{v4Ips=[xx.xx.xx.xx], v6Ips=[xxx], ips=null} - * 多域名批量查询返回:IpSet{v4Ips=[youtube.com:31.13.73.1, qq.com:123.151.137.18, qq.com:183.3.226.35, qq.com:61.129.7.47], v6Ips=[youtube.com.:2001::42d:9141], ips=null} + * 多域名批量查询返回:IpSet{v4Ips=[youtube.com:31.13.73.1, qq.com:123.151.137.18, qq.com:183.3.226.35, qq.com:61.129.7 + * .47], v6Ips=[youtube.com.:2001::42d:9141], ips=null} * 注意需要先通过setHttpDnsResponseObserver设置回调的监听 * * @param domain 域名, 多域名以;分割 @@ -376,7 +390,8 @@ public void run() { }); } else { try { - throw new IllegalAccessException("getAddrsByNameAsync cannot be used when useExpiredIpEnable is set to true."); + throw new IllegalAccessException("getAddrsByNameAsync cannot be used when useExpiredIpEnable is set " + + "to true."); } catch (IllegalAccessException e) { e.printStackTrace(); } diff --git a/src/main/java/com/tencent/msdk/dns/base/executor/DnsExecutors.java b/src/main/java/com/tencent/msdk/dns/base/executor/DnsExecutors.java index 125b3e9..590a8e2 100644 --- a/src/main/java/com/tencent/msdk/dns/base/executor/DnsExecutors.java +++ b/src/main/java/com/tencent/msdk/dns/base/executor/DnsExecutors.java @@ -75,6 +75,7 @@ private static int setThreadPriority2Background() { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); } } catch (Exception ignored) { + DnsLog.e("exception: %s", ignored); } return oriPriority; } @@ -89,6 +90,7 @@ private static void restoreThreadPriority(int origPriority) { Process.setThreadPriority(origPriority); } } catch (Exception ignored) { + DnsLog.e("exception: %s", ignored); } } diff --git a/src/main/java/com/tencent/msdk/dns/base/lifecycle/ActivityLifecycleDetector.java b/src/main/java/com/tencent/msdk/dns/base/lifecycle/ActivityLifecycleDetector.java index 8278fcf..3b9e5de 100644 --- a/src/main/java/com/tencent/msdk/dns/base/lifecycle/ActivityLifecycleDetector.java +++ b/src/main/java/com/tencent/msdk/dns/base/lifecycle/ActivityLifecycleDetector.java @@ -2,24 +2,13 @@ import android.annotation.TargetApi; import android.app.Activity; -//import android.app.ActivityThread; import android.app.Application; -import android.app.Instrumentation; -import android.content.ComponentName; import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ActivityInfo; import android.os.Build; import android.os.Bundle; -import android.os.IBinder; -import android.os.PersistableBundle; -import android.view.KeyEvent; -import android.view.MotionEvent; import com.tencent.msdk.dns.base.log.DnsLog; -import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -78,7 +67,8 @@ public static synchronized boolean registerActivityLifecycleCallbacks( // // @TargetApi(Build.VERSION_CODES.LOLLIPOP) // @Override -// public void callActivityOnCreate(Activity activity, Bundle icicle, PersistableBundle persistentState) { +// public void callActivityOnCreate(Activity activity, Bundle icicle, PersistableBundle +// persistentState) { // DnsLog.d("%s.onCreate", activity); // // for (ActivityLifecycleCallbacksWrapper lifecycleCallbacks : sActivityLifecycleCallbacks) { @@ -145,7 +135,8 @@ public static synchronized boolean registerActivityLifecycleCallbacks( // // @TargetApi(Build.VERSION_CODES.LOLLIPOP) // @Override -// public void callActivityOnSaveInstanceState(Activity activity, Bundle outState, PersistableBundle outPersistentState) { +// public void callActivityOnSaveInstanceState(Activity activity, Bundle outState, +// PersistableBundle outPersistentState) { // DnsLog.d("%s.onSaveInstanceState", activity); // // for (ActivityLifecycleCallbacksWrapper lifecycleCallbacks : sActivityLifecycleCallbacks) { @@ -288,7 +279,8 @@ public static synchronized boolean registerActivityLifecycleCallbacks( // // startActivitySync: API28引入 //// @androidx.annotation.NonNull //// @Override -//// public Activity startActivitySync(@androidx.annotation.NonNull Intent intent, @androidx.annotation.Nullable Bundle options) { +//// public Activity startActivitySync(@androidx.annotation.NonNull Intent intent, @androidx +// .annotation.Nullable Bundle options) { //// return realInstrumentation.startActivitySync(intent, options); //// } // @@ -368,7 +360,8 @@ public static synchronized boolean registerActivityLifecycleCallbacks( // } // // @Override -// public Application newApplication(ClassLoader cl, String className, Context context) throws ClassNotFoundException, IllegalAccessException, InstantiationException { +// public Application newApplication(ClassLoader cl, String className, Context context) throws +// ClassNotFoundException, IllegalAccessException, InstantiationException { // return realInstrumentation.newApplication(cl, className, context); // } // @@ -378,12 +371,16 @@ public static synchronized boolean registerActivityLifecycleCallbacks( // } // // @Override -// public Activity newActivity(Class clazz, Context context, IBinder token, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, Object lastNonConfigurationInstance) throws IllegalAccessException, InstantiationException { -// return realInstrumentation.newActivity(clazz, context, token, application, intent, info, title, parent, id, lastNonConfigurationInstance); +// public Activity newActivity(Class clazz, Context context, IBinder token, Application +// application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, +// Object lastNonConfigurationInstance) throws IllegalAccessException, InstantiationException { +// return realInstrumentation.newActivity(clazz, context, token, application, intent, info, +// title, parent, id, lastNonConfigurationInstance); // } // // @Override -// public Activity newActivity(ClassLoader cl, String className, Intent intent) throws ClassNotFoundException, IllegalAccessException, InstantiationException { +// public Activity newActivity(ClassLoader cl, String className, Intent intent) throws +// ClassNotFoundException, IllegalAccessException, InstantiationException { // return realInstrumentation.newActivity(cl, className, intent); // } // @@ -394,8 +391,10 @@ public static synchronized boolean registerActivityLifecycleCallbacks( // // // callActivityOnRestoreInstanceState: API21引入 //// @Override -//// public void callActivityOnRestoreInstanceState(Activity activity, Bundle savedInstanceState, PersistableBundle persistentState) { -//// realInstrumentation.callActivityOnRestoreInstanceState(activity, savedInstanceState, persistentState); +//// public void callActivityOnRestoreInstanceState(Activity activity, Bundle savedInstanceState, +// PersistableBundle persistentState) { +//// realInstrumentation.callActivityOnRestoreInstanceState(activity, savedInstanceState, +// persistentState); //// } // // @Override @@ -405,7 +404,8 @@ public static synchronized boolean registerActivityLifecycleCallbacks( // // // callActivityOnPostCreate: API21引入 //// @Override -//// public void callActivityOnPostCreate(Activity activity, Bundle icicle, PersistableBundle persistentState) { +//// public void callActivityOnPostCreate(Activity activity, Bundle icicle, PersistableBundle +// persistentState) { //// realInstrumentation.callActivityOnPostCreate(activity, icicle, persistentState); //// } // diff --git a/src/main/java/com/tencent/msdk/dns/base/network/AbsNetworkChangeObservable.java b/src/main/java/com/tencent/msdk/dns/base/network/AbsNetworkChangeObservable.java index 168f41d..19e418b 100644 --- a/src/main/java/com/tencent/msdk/dns/base/network/AbsNetworkChangeObservable.java +++ b/src/main/java/com/tencent/msdk/dns/base/network/AbsNetworkChangeObservable.java @@ -1,8 +1,10 @@ package com.tencent.msdk.dns.base.network; import android.content.Context; + import com.tencent.msdk.dns.base.log.DnsLog; import com.tencent.msdk.dns.base.utils.NetworkUtils; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -51,9 +53,9 @@ private boolean isNetworkChanged(Context context) { return true; } int curNetType = NetworkUtils.getNetworkState(context); - if(mCurNetworkType == -1) { + if (mCurNetworkType == -1) { mCurNetworkType = curNetType; - } else if(mCurNetworkType != curNetType) { + } else if (mCurNetworkType != curNetType) { mCurNetworkType = curNetType; // NetType不相同才notify return true; diff --git a/src/main/java/com/tencent/msdk/dns/base/report/BeaconReporterImpl.java b/src/main/java/com/tencent/msdk/dns/base/report/BeaconReporterImpl.java index 866950b..3bf39bd 100644 --- a/src/main/java/com/tencent/msdk/dns/base/report/BeaconReporterImpl.java +++ b/src/main/java/com/tencent/msdk/dns/base/report/BeaconReporterImpl.java @@ -23,11 +23,11 @@ public String getName() { @Override public boolean canReport() { try { - Class UserAction = Class.forName(BEACON_CLASS_NAME); - DnsLog.d("find UserAction class for %s", UserAction); + Class userAction = Class.forName(BEACON_CLASS_NAME); + DnsLog.d("find userAction class for %s", userAction); return true; } catch (Throwable tr) { - DnsLog.d("Can not find UserAction class for %s", tr); + DnsLog.d("Can not find userAction class for %s", tr); return false; } } @@ -35,15 +35,15 @@ public boolean canReport() { @Override public boolean init(BeaconReporterInitParameters initParameter) { try { - Class UserAction = Class.forName(BEACON_CLASS_NAME); - Method initUserAction = UserAction.getMethod("initUserAction", Context.class); - Method setAppKey = UserAction.getMethod("setAppKey", String.class); + Class userAction = Class.forName(BEACON_CLASS_NAME); + Method initUserAction = userAction.getMethod("initUserAction", Context.class); + Method setAppKey = userAction.getMethod("setAppKey", String.class); initUserAction.invoke(null, initParameter.appContext); setAppKey.invoke(null, initParameter.appId); return true; } catch (Throwable tr) { - DnsLog.d("UserAction init failed %s", tr); + DnsLog.d("userAction init failed %s", tr); return false; } } @@ -51,13 +51,13 @@ public boolean init(BeaconReporterInitParameters initParameter) { @Override public boolean setDebug(boolean enabled) { try { - Class UserAction = Class.forName(BEACON_CLASS_NAME); - Method setLogAble = UserAction.getMethod("setLogAble", boolean.class, boolean.class); + Class userAction = Class.forName(BEACON_CLASS_NAME); + Method setLogAble = userAction.getMethod("setLogAble", boolean.class, boolean.class); setLogAble.invoke(null, enabled, enabled); return true; } catch (Throwable tr) { - DnsLog.d("UserAction setDebug failed %s", tr); + DnsLog.d("userAction setDebug failed %s", tr); return false; } } @@ -66,17 +66,18 @@ public boolean setDebug(boolean enabled) { boolean reportInternal(int env, String eventName, Map eventInfo) { // 这里进行实时上报, 对齐其他上报通道逻辑 try { - Class UserAction = Class.forName(BEACON_CLASS_NAME); - Method onUserAction = UserAction.getMethod("onUserAction", String.class, boolean.class, long.class, long.class, Map.class, boolean.class); + Class userAction = Class.forName(BEACON_CLASS_NAME); + Method onUserAction = userAction.getMethod("onUserAction", String.class, boolean.class, long.class, + long.class, Map.class, boolean.class); boolean isReport = (Boolean) onUserAction.invoke(null, eventName, true, 0, -1, eventInfo, true); - DnsLog.d("UserAction reportInternal success %s", isReport); + DnsLog.d("userAction reportInternal success %s", isReport); return isReport; } catch (Throwable tr) { - DnsLog.d("UserAction reportInternal failed %s", tr); + DnsLog.d("userAction reportInternal failed %s", tr); return false; } diff --git a/src/main/java/com/tencent/msdk/dns/base/report/ReportManager.java b/src/main/java/com/tencent/msdk/dns/base/report/ReportManager.java index 0bcea91..47faf3b 100644 --- a/src/main/java/com/tencent/msdk/dns/base/report/ReportManager.java +++ b/src/main/java/com/tencent/msdk/dns/base/report/ReportManager.java @@ -49,10 +49,10 @@ public static boolean canReport() { return !sBuiltInReporters.isEmpty() || !sCustomReporters.isEmpty(); } - public static - void initBuiltInReporter(int channel, InitParameters initParameters) { + public static + void initBuiltInReporter(int channel, InitParametersT initParameters) { @SuppressWarnings("unchecked") - IReporter reporter = ReporterFactory.getReporter(channel); + IReporter reporter = ReporterFactory.getReporter(channel); if (null == reporter) { DnsLog.d("Get builtIn reporter from channel: %d failed", channel); return; @@ -99,11 +99,11 @@ public static void report(int env, } } - if(!canReport()) { + if (!canReport()) { return; } - DnsLog.d("HTTPDNS_SDK_VER:" + BuildConfig.VERSION_NAME + ", Try to report %s", eventName); + DnsLog.d("HTTPDNS_SDK_VER:" + BuildConfig.VERSION_NAME + ", Try to report %s", eventName); for (IReporter reporter : sBuiltInReporters) { if (!reporter.report(env, eventName, eventInfo)) { diff --git a/src/main/java/com/tencent/msdk/dns/base/utils/CommonUtils.java b/src/main/java/com/tencent/msdk/dns/base/utils/CommonUtils.java index b0ef5dd..2f46ae9 100644 --- a/src/main/java/com/tencent/msdk/dns/base/utils/CommonUtils.java +++ b/src/main/java/com/tencent/msdk/dns/base/utils/CommonUtils.java @@ -23,6 +23,7 @@ public static void closeQuietly(/* @Nullable */Closeable closeable) { try { closeable.close(); } catch (IOException ignored) { + DnsLog.e("exception: %s", ignored); } } } @@ -104,7 +105,9 @@ public static String getIpfromSet(IpSet ipSet) { public static String[] templateIps(String[] ips, LookupParameters lookupParameters) { String requestHostname = lookupParameters.requestHostname; - if (ips.length > 0 && !lookupParameters.requestHostname.equals(lookupParameters.hostname) && requestHostname.split(",").length == 1) { + if (ips.length > 0 + && !lookupParameters.requestHostname.equals(lookupParameters.hostname) + && requestHostname.split(",").length == 1) { // 批量解析中单个域名下发请求的格式处理 List list = new ArrayList<>(); for (String ip : ips) { diff --git a/src/main/java/com/tencent/msdk/dns/base/utils/DebounceTask.java b/src/main/java/com/tencent/msdk/dns/base/utils/DebounceTask.java index 06f585e..14d883f 100644 --- a/src/main/java/com/tencent/msdk/dns/base/utils/DebounceTask.java +++ b/src/main/java/com/tencent/msdk/dns/base/utils/DebounceTask.java @@ -8,24 +8,24 @@ public class DebounceTask { private Long delay; private Runnable runnable; - public DebounceTask(Runnable runnable, Long delay) { + public DebounceTask(Runnable runnable, Long delay) { this.runnable = runnable; this.delay = delay; } - public static DebounceTask build(Runnable runnable, Long delay){ + public static DebounceTask build(Runnable runnable, Long delay) { return new DebounceTask(runnable, delay); } - public void run(){ - if(timer!=null){ + public void run() { + if (timer != null) { timer.cancel(); } timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { - timer=null; + timer = null; runnable.run(); } }, delay); diff --git a/src/main/java/com/tencent/msdk/dns/base/utils/HttpHelper.java b/src/main/java/com/tencent/msdk/dns/base/utils/HttpHelper.java index 675383d..e2290cd 100644 --- a/src/main/java/com/tencent/msdk/dns/base/utils/HttpHelper.java +++ b/src/main/java/com/tencent/msdk/dns/base/utils/HttpHelper.java @@ -30,10 +30,10 @@ public static String getRequest(String urlStr) { URL url = new URL(urlStr); String host = url.getHost(); String file = url.getFile(); - return GET_METHOD + ' ' + file + ' ' + HTTP_VERSION + CRLF + - "Connection: keep-alive" + CRLF + - HOST_HEADER + ": " + host + CRLF + - CRLF; + return GET_METHOD + ' ' + file + ' ' + HTTP_VERSION + CRLF + + "Connection: keep-alive" + CRLF + + HOST_HEADER + ": " + host + CRLF + + CRLF; } catch (MalformedURLException e) { return ""; } @@ -59,13 +59,17 @@ public static int findNonWhitespace(String sb, int offset) { return result; } + /** + * 处理请求数据,header处理 + * + * @param sb 请求数据字符串流 + * @param headers 管理header的map + */ public static void splitLineAddHeader(String sb, Map headers) { final int length = sb.length(); int nameStart; int nameEnd; int colonEnd; - int valueStart; - int valueEnd; nameStart = findNonWhitespace(sb, 0); for (nameEnd = nameStart; nameEnd < length; nameEnd++) { @@ -82,8 +86,8 @@ public static void splitLineAddHeader(String sb, Map headers) { } } - valueStart = findNonWhitespace(sb, colonEnd); - valueEnd = findEndOfString(sb, valueStart); + int valueStart = findNonWhitespace(sb, colonEnd); + int valueEnd = findEndOfString(sb, valueStart); String key = sb.substring(nameStart, nameEnd); if (valueStart > valueEnd) { // ignore @@ -100,6 +104,12 @@ public static void splitLineAddHeader(String sb, Map headers) { } } + /** + * 检验请求结果获取是否完结 + * + * @param rawRsp 请求返回内容 + * @return 布尔值 + */ public static boolean checkHttpRspFinished(String rawRsp) { if (TextUtils.isEmpty(rawRsp)) { return false; @@ -125,7 +135,8 @@ public static boolean checkHttpRspFinished(String rawRsp) { if (body.length() == cl) { return true; } - } catch (Exception ignore) { + } catch (Exception ignored) { + DnsLog.e("exception: %s", ignored); } } return false; diff --git a/src/main/java/com/tencent/msdk/dns/base/utils/IpValidator.java b/src/main/java/com/tencent/msdk/dns/base/utils/IpValidator.java index 9e1b2a3..607233a 100644 --- a/src/main/java/com/tencent/msdk/dns/base/utils/IpValidator.java +++ b/src/main/java/com/tencent/msdk/dns/base/utils/IpValidator.java @@ -7,24 +7,25 @@ public final class IpValidator { private static final Pattern IPV4_PATTERN = Pattern.compile( - "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\." + - "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + - "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + - "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$"); + "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\." + + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$"); // 这里主要是为了和iOS对齐, 其实用Inet6Address.getByName()来判断更好 private static final Pattern IPV6_PATTERN = Pattern.compile( - "([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|" + - "([0-9a-fA-F]{1,4}:){1,7}:|" + - "([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|" + - "([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|" + - "([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|" + - "([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|" + - "([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|" + - "[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|" + - ":((:[0-9a-fA-F]{1,4}){1,7}|:)|" + - "fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]+|" + - "::ffff(:0{1,4})?:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\\\\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])|" + - "([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\\\\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])"); + "([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|" + + "([0-9a-fA-F]{1,4}:){1,7}:|" + + "([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|" + + "([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|" + + "([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|" + + "([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|" + + "([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|" + + "[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|" + + ":((:[0-9a-fA-F]{1,4}){1,7}|:)|" + + "fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]+|" + + "::ffff(:0{1,4})?:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\\\\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])|" + + "([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\\\\.){3}(25[0-5]|(2[0-4]|1?[0-9])" + + "?[0-9])"); public static boolean isV4Ip(/* @Nullable */String ip) { String realIp = formatIp(ip); @@ -33,15 +34,16 @@ public static boolean isV4Ip(/* @Nullable */String ip) { public static boolean isV6Ip(/* @Nullable */String ip) { String realIp = formatIp(ip); - return !TextUtils.isEmpty(ip) && IPV6_PATTERN.matcher(ip).matches() || !TextUtils.isEmpty(realIp) && IPV6_PATTERN.matcher(realIp).matches(); + return !TextUtils.isEmpty(ip) && IPV6_PATTERN.matcher(ip).matches() + || !TextUtils.isEmpty(realIp) && IPV6_PATTERN.matcher(realIp).matches(); } // 带域名的ip转换适配批量查询 - private static String formatIp(String ip){ + private static String formatIp(String ip) { // 批量ip例子:baidu.com:39.156.69.79 - if(ip.contains(":")){ - int i=ip.indexOf(":"); - return ip.substring(i+1); + if (ip.contains(":")) { + int i = ip.indexOf(":"); + return ip.substring(i + 1); } return ip; } diff --git a/src/main/java/com/tencent/msdk/dns/base/utils/NetworkStack.java b/src/main/java/com/tencent/msdk/dns/base/utils/NetworkStack.java index 11f3d32..569556a 100644 --- a/src/main/java/com/tencent/msdk/dns/base/utils/NetworkStack.java +++ b/src/main/java/com/tencent/msdk/dns/base/utils/NetworkStack.java @@ -14,9 +14,9 @@ public static int get() { } public static boolean isInvalid(int networkStack) { - return NONE != networkStack && - IPV4_ONLY != networkStack && - IPV6_ONLY != networkStack && - DUAL_STACK != networkStack; + return NONE != networkStack + && IPV4_ONLY != networkStack + && IPV6_ONLY != networkStack + && DUAL_STACK != networkStack; } } diff --git a/src/main/java/com/tencent/msdk/dns/base/utils/NetworkUtils.java b/src/main/java/com/tencent/msdk/dns/base/utils/NetworkUtils.java index 53d5b26..a74d781 100644 --- a/src/main/java/com/tencent/msdk/dns/base/utils/NetworkUtils.java +++ b/src/main/java/com/tencent/msdk/dns/base/utils/NetworkUtils.java @@ -92,9 +92,10 @@ private static int getMobileNetworkClass(NetworkInfo info) { case TelephonyManager.NETWORK_TYPE_HSPAP: // [api13] 15 case 17: // [api25] NETWORK_TYPE_TD_SCDMA return NETWORK_CLASS_3_G; - case TelephonyManager.NETWORK_TYPE_LTE: // api11 13 - case 18: // TelephonyManager.NETWORK_TYPE_IWLAN [api25 18] - return NETWORK_CLASS_4_G; + // 圈复杂度优化,NETWORK_CLASS_4_G返回与default一致。 +// case TelephonyManager.NETWORK_TYPE_LTE: // api11 13 +// case 18: // TelephonyManager.NETWORK_TYPE_IWLAN [api25 18] +// return NETWORK_CLASS_4_G; default: return NETWORK_CLASS_4_G; } diff --git a/src/main/java/com/tencent/msdk/dns/core/ConfigFromServer.java b/src/main/java/com/tencent/msdk/dns/core/ConfigFromServer.java index 728ca3a..de25d86 100644 --- a/src/main/java/com/tencent/msdk/dns/core/ConfigFromServer.java +++ b/src/main/java/com/tencent/msdk/dns/core/ConfigFromServer.java @@ -17,6 +17,12 @@ public final class ConfigFromServer { private static boolean enableDomainServer; private static boolean enableReport; + /** + * 域名接入服务初始化 + * + * @param lookupExtra 加密数据 + * @param channel http,https + */ public static void init(LookupExtra lookupExtra, String channel) { String urlStr; if (channel.equals(Const.HTTPS_CHANNEL)) { diff --git a/src/main/java/com/tencent/msdk/dns/core/Const.java b/src/main/java/com/tencent/msdk/dns/core/Const.java index f5579ce..903acf8 100644 --- a/src/main/java/com/tencent/msdk/dns/core/Const.java +++ b/src/main/java/com/tencent/msdk/dns/core/Const.java @@ -21,6 +21,10 @@ public interface Const { int DEFAULT_TIME_INTERVAL = 0; + int MAX_DEFAULT_TTL = 6000; + + int MAX_CONNECT_TIME = 10 * 1000; + // 字节码优化, 详见https://jakewharton.com/the-economics-of-generated-code/ String NULL_POINTER_TIPS = " can not be null"; diff --git a/src/main/java/com/tencent/msdk/dns/core/CountDownManager.java b/src/main/java/com/tencent/msdk/dns/core/CountDownManager.java index 05f4944..848530b 100644 --- a/src/main/java/com/tencent/msdk/dns/core/CountDownManager.java +++ b/src/main/java/com/tencent/msdk/dns/core/CountDownManager.java @@ -1,6 +1,7 @@ package com.tencent.msdk.dns.core; import com.tencent.msdk.dns.base.executor.DnsExecutors; +import com.tencent.msdk.dns.base.log.DnsLog; import java.util.ArrayList; import java.util.Collections; @@ -91,6 +92,7 @@ public void run() { try { mRealTask.run(); } catch (Exception ignored) { + DnsLog.e("exception: %s", ignored); } if (!mRealTask.mIgnorable) { mCountDownLatch.countDown(); diff --git a/src/main/java/com/tencent/msdk/dns/core/DnsDescription.java b/src/main/java/com/tencent/msdk/dns/core/DnsDescription.java index bb3896d..08f5391 100644 --- a/src/main/java/com/tencent/msdk/dns/core/DnsDescription.java +++ b/src/main/java/com/tencent/msdk/dns/core/DnsDescription.java @@ -1,9 +1,9 @@ package com.tencent.msdk.dns.core; -import androidx.annotation.NonNull; - import android.text.TextUtils; +import androidx.annotation.NonNull; + public final class DnsDescription { public interface Family { diff --git a/src/main/java/com/tencent/msdk/dns/core/DnsManager.java b/src/main/java/com/tencent/msdk/dns/core/DnsManager.java index dc0ecd6..ac60b89 100644 --- a/src/main/java/com/tencent/msdk/dns/core/DnsManager.java +++ b/src/main/java/com/tencent/msdk/dns/core/DnsManager.java @@ -2,6 +2,8 @@ import android.os.SystemClock; +import androidx.annotation.NonNull; + import com.tencent.msdk.dns.base.compat.CollectionCompat; import com.tencent.msdk.dns.base.executor.DnsExecutors; import com.tencent.msdk.dns.base.log.DnsLog; @@ -94,16 +96,15 @@ public static void setLookupListener(/* @Nullable */ILookupListener lookupListen sLookupListener = lookupListener; } - public static - LookupResult getResultFromCache(LookupParameters lookupParams) { + public static + LookupResult getResultFromCache(LookupParameters lookupParams) { DnsGroup restDnsGroup = CHANNEL_DNS_GROUP_MAP.get(lookupParams.channel); if (restDnsGroup == null) { - return new LookupResult( - IpSet.EMPTY, new StatisticsMerge(lookupParams.appContext)); + return new LookupResult(IpSet.EMPTY, new StatisticsMerge(lookupParams.appContext)); } - LookupExtra lookupExtra = lookupParams.lookupExtra; + LookupExtraT lookupExtra = lookupParams.lookupExtra; - LookupContext lookupContext = LookupContext.wrap(lookupParams); + LookupContext lookupContext = LookupContext.wrap(lookupParams); if (!NetworkStack.isInvalid(lookupParams.customNetStack) && lookupParams.customNetStack > 0) { lookupContext.currentNetworkStack(lookupParams.customNetStack); } else { @@ -114,9 +115,8 @@ LookupResult getResultFromCache(LookupParameters ISorter sorter = sSorterFactory.create(currentNetworkStack); lookupContext.sorter(sorter); // snapshot - @SuppressWarnings("unchecked") IStatisticsMerge statMerge = - sStatMergeFactory.create( - (Class) lookupExtra.getClass(), lookupParams.appContext); + @SuppressWarnings("unchecked") IStatisticsMerge statMerge = + sStatMergeFactory.create((Class) lookupExtra.getClass(), lookupParams.appContext); lookupContext.statisticsMerge(statMerge); IDns dns; @@ -136,74 +136,42 @@ LookupResult getResultFromCache(LookupParameters statMerge.statContext(lookupContext); if (lookupResultFromCache.stat.lookupSuccess() || lookupResultFromCache.stat.lookupPartCached()) { lookupContext.sorter().put(dns, lookupResultFromCache.ipSet.ips); - lookupContext.statisticsMerge() - .merge(dns, lookupResultFromCache.stat); + lookupContext.statisticsMerge().merge(dns, lookupResultFromCache.stat); IpSet ipSet = sorter.sort(); statMerge.statResult(ipSet); - LookupResult lookupResult = - new LookupResult(ipSet, statMerge); - DnsLog.d("getResultFromCache by httpdns cache:" + - lookupResult.ipSet + "; " + lookupResult.stat); + LookupResult lookupResult = new LookupResult(ipSet, statMerge); + DnsLog.d("getResultFromCache by httpdns cache:" + lookupResult.ipSet + "; " + lookupResult.stat); return lookupResult; } - return new LookupResult( - IpSet.EMPTY, statMerge); + return new LookupResult(IpSet.EMPTY, statMerge); } // lookupParameters创建时会进行参数校验 - public static - LookupResult lookup(LookupParameters lookupParams) { + public static + LookupResult lookup(LookupParameters lookupParams) { if (null == lookupParams) { throw new IllegalArgumentException("lookupParams".concat(Const.NULL_POINTER_TIPS)); } // NOTE: 考虑同步检查正在运行的解析任务的代码块 - DnsLog.v("DnsManager.lookup(%s) called", lookupParams); long startTimeMills = SystemClock.elapsedRealtime(); - LookupLatchResultPair lookupLatchResultPair = RUNNING_LOOKUP_LATCH_MAP.get(lookupParams); if (null != lookupLatchResultPair) { - DnsLog.d( - "The same lookup task(for %s) is running, just wait for it", lookupParams); - CountDownLatch lookupLatch = lookupLatchResultPair.mLookupLatch; - try { - if (lookupLatch.await((long) (AWAIT_FOR_RUNNING_LOOKUP_FACTOR * lookupParams.timeoutMills), TimeUnit.MILLISECONDS)) { - // NOTE: await之后mLookupResult不为null - return lookupLatchResultPair.mLookupResultHolder.mLookupResult; - } - DnsLog.d("Await for running lookup for %s timeout", lookupParams); - return new LookupResult( - IpSet.EMPTY, new StatisticsMerge(lookupParams.appContext)); - } catch (Exception e) { - DnsLog.w(e, "Await for running lookup for %s failed", lookupParams); - int fixedTimeoutMills = (int) (lookupParams.timeoutMills - - (SystemClock.elapsedRealtime() - startTimeMills)); - if (0 < fixedTimeoutMills) { - return lookup(new LookupParameters.Builder<>(lookupParams) - .timeoutMills(fixedTimeoutMills) - .build() - ); - } - return new LookupResult( - IpSet.EMPTY, new StatisticsMerge(lookupParams.appContext)); - } + return getResultFromLatch(lookupParams, lookupLatchResultPair, startTimeMills); } -// 初始化CountDownLatch同步计数器 + // 初始化CountDownLatch同步计数器 CountDownLatch lookupLatch = new CountDownLatch(1); LookupResultHolder lookupResultHolder = new LookupResultHolder(); - RUNNING_LOOKUP_LATCH_MAP.put( - lookupParams, new LookupLatchResultPair(lookupLatch, lookupResultHolder)); + RUNNING_LOOKUP_LATCH_MAP.put(lookupParams, new LookupLatchResultPair(lookupLatch, lookupResultHolder)); - int timeoutMills = lookupParams.timeoutMills; - LookupExtra lookupExtra = lookupParams.lookupExtra; + final LookupExtraT lookupExtra = lookupParams.lookupExtra; String channel = lookupParams.channel; boolean fallback2Local = lookupParams.fallback2Local; - - LookupContext lookupContext = LookupContext.wrap(lookupParams); + LookupContext lookupContext = LookupContext.wrap(lookupParams); DnsGroup localDnsGroup = null; DnsGroup restDnsGroup = null; @@ -223,10 +191,8 @@ LookupResult lookup(LookupParameters lookupParams ISorter sorter = sSorterFactory.create(lookupContext.currentNetworkStack()); lookupContext.sorter(sorter); // snapshot - IRetry retry = sRetry; - @SuppressWarnings("unchecked") IStatisticsMerge statMerge = - sStatMergeFactory.create( - (Class) lookupExtra.getClass(), lookupParams.appContext); + @SuppressWarnings("unchecked") IStatisticsMerge statMerge = + sStatMergeFactory.create((Class) lookupExtra.getClass(), lookupParams.appContext); lookupContext.statisticsMerge(statMerge); CountDownManager.Transaction transaction = CountDownManager.beginTransaction(); @@ -272,95 +238,11 @@ public void run() { prepareTasks(localDnsGroup, lookupContext); } - int maxRetryTimes = retry.maxRetryTimes(); - int remainTimeMills = - timeoutMills - (int) (SystemClock.elapsedRealtime() - startTimeMills); - int waitTimeMills = - 0 < maxRetryTimes ? remainTimeMills / (maxRetryTimes + 1) : remainTimeMills; - int retriedTimes = 0; - CountDownLatch countDownLatch = transaction.commit(); lookupContext.countDownLatch(countDownLatch); - Selector selector = lookupContext.selector(); - if (null == selector) { - DnsLog.d("selector is null"); - // 仅阻塞解析 - // NOTE: 非localDNS解析进行countDownLatch,HDNS不被localDNS阻塞 - while (countDownLatch.getCount() > 0 && - SystemClock.elapsedRealtime() - startTimeMills < timeoutMills) { - try { - countDownLatch.await(waitTimeMills, TimeUnit.MILLISECONDS); - - } catch (Exception e) { - DnsLog.d(e, "sessions not empty, but exception"); - } - if (countDownLatch.getCount() > 0 && // 需要重试 - canRetry(startTimeMills, timeoutMills, maxRetryTimes, retriedTimes)) { - retriedTimes++; - remainTimeMills = timeoutMills - - (int) (SystemClock.elapsedRealtime() - startTimeMills); - LookupContext newLookupContext = - lookupContext.newLookupContext( - new LookupParameters.Builder<>(lookupParams) - .timeoutMills(remainTimeMills) - .curRetryTime(retriedTimes) - .build()); - retry.retryBlock(newLookupContext); - } - } - IpSet ipSet = sorter.sort(); - statMerge.statResult(ipSet); - LookupResult lookupResult = - new LookupResult(ipSet, statMerge); - lookupResultHolder.mLookupResult = lookupResult; - return lookupResult; - } - // 非阻塞解析 - // TODO: sessions加上对于解析结果可以忽略的支持(主要是支持LocalDns) - while (!sessions.isEmpty() && - SystemClock.elapsedRealtime() - startTimeMills < timeoutMills) { - // sleep以降低系统调用频率 - try { - Thread.sleep(SYSTEM_CALL_INTERVAL_MILLS); - } catch (Exception ignored) { - } - try { - DnsLog.d("selector %s wait for sessions:%d, mills:%d", - selector, sessions.size(), waitTimeMills); - selector.select(waitTimeMills); - } catch (Exception e) { - DnsLog.d(e, "sessions not empty, but exception"); - } - // Socket进行请求 - tryLookup(lookupContext); - if (!sessions.isEmpty() && // 需要重试 - canRetry(startTimeMills, timeoutMills, maxRetryTimes, retriedTimes)) { - DnsLog.d("sessions is not empty, sessions:%d, enter retry", sessions.size()); - retriedTimes++; - LookupContext newLookupContext = lookupContext.newLookupContext( - new LookupParameters.Builder<>(lookupParams) - .curRetryTime(retriedTimes) - .build()); - retry.retryNonBlock(newLookupContext); - } - } - // 阻塞解析 - remainTimeMills = timeoutMills - (int) (SystemClock.elapsedRealtime() - startTimeMills); - try { - if (sessions.size() > 0) { - DnsLog.d("selector wait for last timeout if sessions is not empty, sessions:%d, mills:%d", sessions.size(), waitTimeMills); - } - countDownLatch.await(remainTimeMills, TimeUnit.MILLISECONDS); - } catch (Exception ignored) { - } - IpSet ipSet = sorter.sort(); - statMerge.statResult(ipSet); - LookupResult lookupResult = - new LookupResult(ipSet, statMerge); - lookupResultHolder.mLookupResult = lookupResult; - - return lookupResult; + return getResultForSelector(countDownLatch, lookupContext, lookupParams, lookupResultHolder, sessions, + startTimeMills); } finally { // 结束超时的session, 统计收尾 endSessions(lookupContext); @@ -378,13 +260,153 @@ public void run() { selector.close(); DnsLog.d("%s closed", selector); } catch (IOException ignored) { + DnsLog.e("exception: %s", ignored); } } } } - public static - LookupResult lookupWrapper(LookupParameters lookupParams) { + private static LookupResult + getResultFromLatch(LookupParameters lookupParams, @NonNull LookupLatchResultPair lookupLatchResultPair, + long startTimeMills) { + DnsLog.d("The same lookup task(for %s) is running, just wait for it", lookupParams); + CountDownLatch lookupLatch = lookupLatchResultPair.mLookupLatch; + try { + if (lookupLatch.await((long) (AWAIT_FOR_RUNNING_LOOKUP_FACTOR * lookupParams.timeoutMills), + TimeUnit.MILLISECONDS)) { + // NOTE: await之后mLookupResult不为null + return lookupLatchResultPair.mLookupResultHolder.mLookupResult; + } + DnsLog.d("Await for running lookup for %s timeout", lookupParams); + return new LookupResult(IpSet.EMPTY, new StatisticsMerge(lookupParams.appContext)); + } catch (Exception e) { + DnsLog.w(e, "Await for running lookup for %s failed", lookupParams); + int fixedTimeoutMills = + (int) (lookupParams.timeoutMills - (SystemClock.elapsedRealtime() - startTimeMills)); + if (0 < fixedTimeoutMills) { + return lookup(new LookupParameters.Builder<>(lookupParams).timeoutMills(fixedTimeoutMills).build()); + } + return new LookupResult(IpSet.EMPTY, new StatisticsMerge(lookupParams.appContext)); + } + } + + private static + LookupResult getResultForNullSelector(CountDownLatch countDownLatch, + LookupContext lookupContext, + LookupParameters lookupParams, + LookupResultHolder lookupResultHolder, + long startTimeMills) { + IRetry retry = sRetry; + int maxRetryTimes = retry.maxRetryTimes(); + int timeoutMills = lookupParams.timeoutMills; + int remainTimeMills = timeoutMills - (int) (SystemClock.elapsedRealtime() - startTimeMills); + int waitTimeMills = 0 < maxRetryTimes ? remainTimeMills / (maxRetryTimes + 1) : remainTimeMills; + int retriedTimes = 0; + + DnsLog.d("selector is null"); + // 仅阻塞解析 + // NOTE: 非localDNS解析进行countDownLatch,HDNS不被localDNS阻塞 + while (countDownLatch.getCount() > 0 + && SystemClock.elapsedRealtime() - startTimeMills < timeoutMills) { + try { + countDownLatch.await(waitTimeMills, TimeUnit.MILLISECONDS); + + } catch (Exception e) { + DnsLog.d(e, "sessions not empty, but exception"); + } + if (countDownLatch.getCount() > 0 + // 需要重试 + && canRetry(startTimeMills, timeoutMills, maxRetryTimes, retriedTimes)) { + retriedTimes++; + remainTimeMills = timeoutMills - (int) (SystemClock.elapsedRealtime() - startTimeMills); + LookupContext newLookupContext = + lookupContext.newLookupContext( + new LookupParameters.Builder<>(lookupParams) + .timeoutMills(remainTimeMills) + .curRetryTime(retriedTimes) + .build()); + retry.retryBlock(newLookupContext); + } + } + ISorter sorter = lookupContext.sorter(); + StatisticsMerge statMerge = (StatisticsMerge) lookupContext.statisticsMerge(); + IpSet ipSet = sorter.sort(); + statMerge.statResult(ipSet); + LookupResult lookupResult = new LookupResult(ipSet, statMerge); + lookupResultHolder.mLookupResult = lookupResult; + return lookupResult; + } + + private static + LookupResult getResultForSelector(CountDownLatch countDownLatch, + LookupContext lookupContext, + LookupParameters lookupParams, + LookupResultHolder lookupResultHolder, + List sessions, + long startTimeMills) { + Selector selector = lookupContext.selector(); + if (selector == null) { + return getResultForNullSelector(countDownLatch, lookupContext, lookupParams, lookupResultHolder, + startTimeMills); + } + IRetry retry = sRetry; + int maxRetryTimes = retry.maxRetryTimes(); + int timeoutMills = lookupParams.timeoutMills; + int remainTimeMills = timeoutMills - (int) (SystemClock.elapsedRealtime() - startTimeMills); + int waitTimeMills = 0 < maxRetryTimes ? remainTimeMills / (maxRetryTimes + 1) : remainTimeMills; + int retriedTimes = 0; + + // 非阻塞解析 + // TODO: sessions加上对于解析结果可以忽略的支持(主要是支持LocalDns) + while (!sessions.isEmpty() && SystemClock.elapsedRealtime() - startTimeMills < timeoutMills) { + // sleep以降低系统调用频率 + try { + Thread.sleep(SYSTEM_CALL_INTERVAL_MILLS); + } catch (Exception ignored) { + DnsLog.e("exception: %s", ignored); + } + try { + DnsLog.d("selector %s wait for sessions:%d, mills:%d", selector, sessions.size(), waitTimeMills); + selector.select(waitTimeMills); + } catch (Exception e) { + DnsLog.d(e, "sessions not empty, but exception"); + } + // Socket进行请求 + tryLookup(lookupContext); + if (!sessions.isEmpty() + // 需要重试 + && canRetry(startTimeMills, timeoutMills, maxRetryTimes, retriedTimes)) { + DnsLog.d("sessions is not empty, sessions:%d, enter retry", sessions.size()); + retriedTimes++; + LookupContext newLookupContext = lookupContext.newLookupContext( + new LookupParameters.Builder<>(lookupParams) + .curRetryTime(retriedTimes) + .build()); + retry.retryNonBlock(newLookupContext); + } + } + // 阻塞解析 + remainTimeMills = timeoutMills - (int) (SystemClock.elapsedRealtime() - startTimeMills); + try { + if (sessions.size() > 0) { + DnsLog.d("selector wait for last timeout if sessions is not empty, sessions:%d, mills:%d", + sessions.size(), waitTimeMills); + } + countDownLatch.await(remainTimeMills, TimeUnit.MILLISECONDS); + } catch (Exception ignored) { + DnsLog.e("exception: %s", ignored); + } + ISorter sorter = lookupContext.sorter(); + StatisticsMerge statMerge = (StatisticsMerge) lookupContext.statisticsMerge(); + IpSet ipSet = sorter.sort(); + statMerge.statResult(ipSet); + LookupResult lookupResult = new LookupResult(ipSet, statMerge); + lookupResultHolder.mLookupResult = lookupResult; + return lookupResult; + } + + public static + LookupResult lookupWrapper(LookupParameters lookupParams) { LookupResult lookupResult = lookup(lookupParams); DnsLog.d("LookupResult %s", lookupResult.ipSet); if (null != sLookupListener) { @@ -393,45 +415,46 @@ LookupResult lookupWrapper(LookupParameters looku return lookupResult; } - private static - void prepareTasks(DnsGroup dnsGroup, LookupContext lookupContext) { + private static + void prepareTasks(DnsGroup dnsGroup, LookupContext lookupContext) { int curNetStack = lookupContext.currentNetworkStack(); // int family = lookupContext.family(); boolean ignoreCurNetStack = lookupContext.ignoreCurrentNetworkStack(); // ignoreCurNetStack = true / localdns, 双栈同时请求 - if (null != dnsGroup.mUnspecDns && - (ignoreCurNetStack || curNetStack == NetworkStack.DUAL_STACK || dnsGroup.mUnspecDns instanceof LocalDns)) { + if (null != dnsGroup.mUnspecDns + && (ignoreCurNetStack || curNetStack == NetworkStack.DUAL_STACK + || dnsGroup.mUnspecDns instanceof LocalDns)) { //noinspection unchecked - prepareTask((IDns) dnsGroup.mUnspecDns, lookupContext); - } else if (null != dnsGroup.mInetDns && + prepareTask((IDns) dnsGroup.mUnspecDns, lookupContext); + } else if (null != dnsGroup.mInetDns // 异步解析不关注当前网络栈 - (ignoreCurNetStack || curNetStack == NetworkStack.IPV4_ONLY)) { + && (ignoreCurNetStack || curNetStack == NetworkStack.IPV4_ONLY)) { //noinspection unchecked - prepareTask((IDns) dnsGroup.mInetDns, lookupContext); - } else if (null != dnsGroup.mInet6Dns && + prepareTask((IDns) dnsGroup.mInetDns, lookupContext); + } else if (null != dnsGroup.mInet6Dns // 异步解析不关注当前网络栈 - (ignoreCurNetStack || curNetStack == NetworkStack.IPV6_ONLY)) { + && (ignoreCurNetStack || curNetStack == NetworkStack.IPV6_ONLY)) { //noinspection unchecked - prepareTask((IDns) dnsGroup.mInet6Dns, lookupContext); + prepareTask((IDns) dnsGroup.mInet6Dns, lookupContext); } } - private static - void prepareTask(final IDns dns, LookupContext lookupContext) { + private static + void prepareTask(final IDns dns, LookupContext lookupContext) { DnsLog.d("prepareTask:" + dns); lookupContext.dnses().add(dns); - if (lookupContext.blockFirst() || + if (lookupContext.blockFirst() // NOTE: 临时方案, 避免LocalDns冗余创建Selector - Const.LOCAL_CHANNEL.equals(dns.getDescription().channel)) { + || Const.LOCAL_CHANNEL.equals(dns.getDescription().channel)) { LookupHelper.prepareBlockLookupTask(dns, lookupContext); return; } IDns.ISession session; // HTTPS情况下也采用HTTPCONNECTION做请求 - if (!Const.HTTPS_CHANNEL.equals(lookupContext.channel()) && ((null != lookupContext.selector()) || tryOpenSelector(lookupContext)) && - null != (session = dns.getSession(lookupContext))) { + if (!Const.HTTPS_CHANNEL.equals(lookupContext.channel()) && ((null != lookupContext.selector()) + || tryOpenSelector(lookupContext)) && null != (session = dns.getSession(lookupContext))) { LookupHelper.prepareNonBlockLookupTask(session, lookupContext); } else { LookupHelper.prepareBlockLookupTask(dns, lookupContext); @@ -450,8 +473,7 @@ private static boolean tryOpenSelector(LookupContext lookupContext) { } } - private static - void tryLookup(LookupContext lookupContext) { + private static void tryLookup(LookupContext lookupContext) { Iterator sessionIterator = lookupContext.sessions().iterator(); while (sessionIterator.hasNext()) { IDns.ISession session = sessionIterator.next(); @@ -460,8 +482,7 @@ void tryLookup(LookupContext lookupContext) { } IDns.ISession.IToken token = session.getToken(); if (token.isReadable()) { - DnsLog.d("%s event readable", - session.getDns().getDescription()); + DnsLog.d("%s event readable", session.getDns().getDescription()); String[] ips = session.receiveResponse(); if (session.getStatistics().lookupSuccess() || session.getStatistics().lookupFailed()) { IDns dns = session.getDns(); @@ -470,19 +491,16 @@ void tryLookup(LookupContext lookupContext) { if (session.getStatistics().lookupSuccess()) { lookupContext.sorter().put(dns, ips); } - lookupContext.statisticsMerge() - .merge(dns, session.getStatistics()); + lookupContext.statisticsMerge().merge(dns, session.getStatistics()); continue; } } else if (token.isWritable()) { - DnsLog.d("%s event writable", - session.getDns().getDescription()); + DnsLog.d("%s event writable", session.getDns().getDescription()); // 发起请求 session.request(); } else { if (token.isConnectable()) { - DnsLog.d("%s event connectable", - session.getDns().getDescription()); + DnsLog.d("%s event connectable", session.getDns().getDescription()); session.connect(); } // 如果不是writable,则每次都需要finishConnect @@ -492,8 +510,7 @@ void tryLookup(LookupContext lookupContext) { // 每次检查下,及时清理 if (!token.isAvailable()) { - DnsLog.d("%s event not available, maybe closed", - session.getDns().getDescription()); + DnsLog.d("%s event not available, maybe closed", session.getDns().getDescription()); IDns dns = session.getDns(); sessionIterator.remove(); lookupContext.dnses().remove(dns); @@ -501,16 +518,15 @@ void tryLookup(LookupContext lookupContext) { } } - private static boolean canRetry(long startTimeMills, int timeoutMills, - int maxRetryTimes, int retriedTimes) { - return retriedTimes < maxRetryTimes && + private static boolean canRetry(long startTimeMills, int timeoutMills, int maxRetryTimes, int retriedTimes) { + return retriedTimes < maxRetryTimes // NOTE: 本次查询已经超时 - (int) (SystemClock.elapsedRealtime() - startTimeMills) > - timeoutMills * (retriedTimes + 1) / (maxRetryTimes + 1); + && (int) (SystemClock.elapsedRealtime() - startTimeMills) + > timeoutMills * (retriedTimes + 1) / (maxRetryTimes + 1); } - private static - void endSessions(LookupContext lookupContext) { + private static + void endSessions(LookupContext lookupContext) { for (IDns.ISession session : lookupContext.sessions()) { session.end(); lookupContext.statisticsMerge().merge(session.getDns(), session.getStatistics()); @@ -518,8 +534,7 @@ void endSessions(LookupContext lookupContext) { } private static void clearEndedSession(LookupContext lookupContext) { - @SuppressWarnings("unchecked") - Iterator sessionIterator = lookupContext.sessions().iterator(); + @SuppressWarnings("unchecked") Iterator sessionIterator = lookupContext.sessions().iterator(); while (sessionIterator.hasNext()) { IDns.ISession session = sessionIterator.next(); if (session.isEnd()) { @@ -545,14 +560,12 @@ private static class LookupLatchResultPair { final CountDownLatch mLookupLatch; final LookupResultHolder mLookupResultHolder; - public LookupLatchResultPair( - CountDownLatch lookupLatch, LookupResultHolder lookupResultHolder) { + public LookupLatchResultPair(CountDownLatch lookupLatch, LookupResultHolder lookupResultHolder) { if (null == lookupLatch) { throw new IllegalArgumentException("lookupLatch".concat(Const.NULL_POINTER_TIPS)); } if (null == lookupResultHolder) { - throw new IllegalArgumentException( - "lookupResultHolder".concat(Const.NULL_POINTER_TIPS)); + throw new IllegalArgumentException("lookupResultHolder".concat(Const.NULL_POINTER_TIPS)); } mLookupLatch = lookupLatch; diff --git a/src/main/java/com/tencent/msdk/dns/core/IRetry.java b/src/main/java/com/tencent/msdk/dns/core/IRetry.java index cf8437b..fe9c0d2 100644 --- a/src/main/java/com/tencent/msdk/dns/core/IRetry.java +++ b/src/main/java/com/tencent/msdk/dns/core/IRetry.java @@ -6,6 +6,6 @@ public interface IRetry { void retryNonBlock(LookupContext lookupContext); - - void retryBlock(LookupContext lookupContext); + + void retryBlock(LookupContext lookupContext); } diff --git a/src/main/java/com/tencent/msdk/dns/core/IStatisticsMerge.java b/src/main/java/com/tencent/msdk/dns/core/IStatisticsMerge.java index f6d2a4a..ab98699 100644 --- a/src/main/java/com/tencent/msdk/dns/core/IStatisticsMerge.java +++ b/src/main/java/com/tencent/msdk/dns/core/IStatisticsMerge.java @@ -9,9 +9,9 @@ interface IFactory { IFactory DEFAULT = new IFactory() { @Override - public - IStatisticsMerge create(Class klass, Context context) { - return new IStatisticsMerge() { + public + IStatisticsMerge create(Class klass, Context context) { + return new IStatisticsMerge() { @Override public void merge(IDns dns, IDns.IStatistics stat) { @@ -40,24 +40,25 @@ public boolean lookupFailed() { return false; } - @Override - public boolean lookupPartCached() { - return false; - } + @Override + public boolean lookupPartCached() { + return false; + } @Override public String toJsonResult() { - return "{\"v4_ips\":\"\",\"v4_ttl\":\"\",\"v4_client_ip\":\"\",\"v6_ips\":\"\",\"v6_ttl\":\"\",\"v6_client_ip\":\"\"}"; + return "{\"v4_ips\":\"\",\"v4_ttl\":\"\",\"v4_client_ip\":\"\",\"v6_ips\":\"\"," + + "\"v6_ttl\":\"\",\"v6_client_ip\":\"\"}"; } }; } }; - - IStatisticsMerge create(Class klass, Context context); + + IStatisticsMerge create(Class klass, Context context); } - void merge(IDns dns, Statistics stat); + void merge(IDns dns, StatisticsT stat); void statContext(LookupContext lookupContext); diff --git a/src/main/java/com/tencent/msdk/dns/core/IpSet.java b/src/main/java/com/tencent/msdk/dns/core/IpSet.java index 04eb984..48637d7 100644 --- a/src/main/java/com/tencent/msdk/dns/core/IpSet.java +++ b/src/main/java/com/tencent/msdk/dns/core/IpSet.java @@ -52,10 +52,10 @@ public IpSet(String[] ips) { @Override public String toString() { - return "IpSet{" + - "v4Ips=" + Arrays.toString(v4Ips) + - ", v6Ips=" + Arrays.toString(v6Ips) + - ", ips=" + Arrays.toString(ips) + - '}'; + return "IpSet{" + + "v4Ips=" + Arrays.toString(v4Ips) + + ", v6Ips=" + Arrays.toString(v6Ips) + + ", ips=" + Arrays.toString(ips) + + '}'; } } diff --git a/src/main/java/com/tencent/msdk/dns/core/LookupContext.java b/src/main/java/com/tencent/msdk/dns/core/LookupContext.java index 02f10bc..c52d18b 100644 --- a/src/main/java/com/tencent/msdk/dns/core/LookupContext.java +++ b/src/main/java/com/tencent/msdk/dns/core/LookupContext.java @@ -33,8 +33,8 @@ private LookupContext(LookupParameters lookupParams) { } - public static - LookupContext wrap(LookupParameters lookupParams) { + public static + LookupContext wrap(LookupParameters lookupParams) { // 参数检查由构造方法完成 return new LookupContext<>(lookupParams); } @@ -242,16 +242,16 @@ public List sessions() { @Override public String toString() { - return "LookupContext{" + - "mLookupParams=" + mLookupParams + - ", mCurNetStack=" + mCurNetStack + - ", mSorter=" + mSorter + - ", mStatMerge=" + mStatMerge + - ", mTransaction=" + mTransaction + - ", mCountDownLatch=" + mCountDownLatch + - ", mSelector=" + mSelector + - ", mDnses=" + mDnses + - ", mSessions=" + mSessions + - '}'; + return "LookupContext{" + + "mLookupParams=" + mLookupParams + + ", mCurNetStack=" + mCurNetStack + + ", mSorter=" + mSorter + + ", mStatMerge=" + mStatMerge + + ", mTransaction=" + mTransaction + + ", mCountDownLatch=" + mCountDownLatch + + ", mSelector=" + mSelector + + ", mDnses=" + mDnses + + ", mSessions=" + mSessions + + '}'; } } diff --git a/src/main/java/com/tencent/msdk/dns/core/LookupHelper.java b/src/main/java/com/tencent/msdk/dns/core/LookupHelper.java index d9df331..4409be4 100644 --- a/src/main/java/com/tencent/msdk/dns/core/LookupHelper.java +++ b/src/main/java/com/tencent/msdk/dns/core/LookupHelper.java @@ -1,17 +1,18 @@ package com.tencent.msdk.dns.core; import com.tencent.msdk.dns.base.log.DnsLog; + import java.util.Set; public final class LookupHelper { - public static - void prepareNonBlockLookupTask(IDns.ISession session, LookupContext lookupContext) { + public static + void prepareNonBlockLookupTask(IDns.ISession session, LookupContext lookupContext) { prepareNonBlockLookupTask(session, lookupContext, false); } - public static - void prepareNonBlockLookupTask(IDns.ISession session, LookupContext lookupContext, boolean forRetry) { + public static + void prepareNonBlockLookupTask(IDns.ISession session, LookupContext lookupContext, boolean forRetry) { if (null == session) { throw new IllegalArgumentException("session".concat(Const.NULL_POINTER_TIPS)); } @@ -39,9 +40,9 @@ void prepareNonBlockLookupTask(IDns.ISession session, LookupContext } } - public static - void prepareBlockLookupTask(final IDns dns, - final LookupContext lookupContext) { + public static + void prepareBlockLookupTask(final IDns dns, + final LookupContext lookupContext) { if (null == dns) { throw new IllegalArgumentException("dns".concat(Const.NULL_POINTER_TIPS)); } diff --git a/src/main/java/com/tencent/msdk/dns/core/LookupParameters.java b/src/main/java/com/tencent/msdk/dns/core/LookupParameters.java index a7e9c9f..62de085 100644 --- a/src/main/java/com/tencent/msdk/dns/core/LookupParameters.java +++ b/src/main/java/com/tencent/msdk/dns/core/LookupParameters.java @@ -67,20 +67,20 @@ public boolean equals(Object o) { return false; } LookupParameters that = (LookupParameters) o; - return timeoutMills == that.timeoutMills && - fallback2Local == that.fallback2Local && - blockFirst == that.blockFirst && - family == that.family && - ignoreCurNetStack == that.ignoreCurNetStack && - customNetStack == that.customNetStack && - enableAsyncLookup == that.enableAsyncLookup && - curRetryTime == that.curRetryTime && - netChangeLookup == that.netChangeLookup && - CommonUtils.equals(appContext, that.appContext) && - CommonUtils.equals(hostname, that.hostname) && - CommonUtils.equals(dnsIp, that.dnsIp) && - CommonUtils.equals(lookupExtra, that.lookupExtra) && - CommonUtils.equals(channel, that.channel); + return timeoutMills == that.timeoutMills + && fallback2Local == that.fallback2Local + && blockFirst == that.blockFirst + && family == that.family + && ignoreCurNetStack == that.ignoreCurNetStack + && customNetStack == that.customNetStack + && enableAsyncLookup == that.enableAsyncLookup + && curRetryTime == that.curRetryTime + && netChangeLookup == that.netChangeLookup + && CommonUtils.equals(appContext, that.appContext) + && CommonUtils.equals(hostname, that.hostname) + && CommonUtils.equals(dnsIp, that.dnsIp) + && CommonUtils.equals(lookupExtra, that.lookupExtra) + && CommonUtils.equals(channel, that.channel); } public void setRequestHostname(String hostname) { @@ -96,22 +96,22 @@ public int hashCode() { @Override public String toString() { - return "LookupParameters{" + - "appContext=" + appContext + - ", hostname='" + hostname + '\'' + - ", timeoutMills=" + timeoutMills + - ", dnsIp=" + dnsIp + - ", lookupExtra=" + lookupExtra + - ", channel='" + channel + '\'' + - ", fallback2Local=" + fallback2Local + - ", blockFirst=" + blockFirst + - ", family=" + family + - ", ignoreCurNetStack=" + ignoreCurNetStack + - ", customNetStack=" + customNetStack + - ", enableAsyncLookup=" + enableAsyncLookup + - ", curRetryTime=" + curRetryTime + - ", netChangeLookup=" + netChangeLookup + - '}'; + return "LookupParameters{" + + "appContext=" + appContext + + ", hostname='" + hostname + '\'' + + ", timeoutMills=" + timeoutMills + + ", dnsIp=" + dnsIp + + ", lookupExtra=" + lookupExtra + + ", channel='" + channel + '\'' + + ", fallback2Local=" + fallback2Local + + ", blockFirst=" + blockFirst + + ", family=" + family + + ", ignoreCurNetStack=" + ignoreCurNetStack + + ", customNetStack=" + customNetStack + + ", enableAsyncLookup=" + enableAsyncLookup + + ", curRetryTime=" + curRetryTime + + ", netChangeLookup=" + netChangeLookup + + '}'; } public static final class Builder { diff --git a/src/main/java/com/tencent/msdk/dns/core/LookupResult.java b/src/main/java/com/tencent/msdk/dns/core/LookupResult.java index 19d88ee..a0d8a8e 100644 --- a/src/main/java/com/tencent/msdk/dns/core/LookupResult.java +++ b/src/main/java/com/tencent/msdk/dns/core/LookupResult.java @@ -46,9 +46,9 @@ public LookupResult(IpSet ipSet, Statistics stat) { @Override public String toString() { - return "LookupResult{" + - "ipSet=" + ipSet + - ", stat=" + stat + - '}'; + return "LookupResult{" + + "ipSet=" + ipSet + + ", stat=" + stat + + '}'; } } diff --git a/src/main/java/com/tencent/msdk/dns/core/cache/Cache.java b/src/main/java/com/tencent/msdk/dns/core/cache/Cache.java index 4d3e418..dc886e8 100644 --- a/src/main/java/com/tencent/msdk/dns/core/cache/Cache.java +++ b/src/main/java/com/tencent/msdk/dns/core/cache/Cache.java @@ -20,7 +20,8 @@ public final class Cache implements ICache { private final Map mHostnameIpsMap = new ConcurrentHashMap<>(); - private final LookupCacheDao lookupCacheDao = LookupCacheDatabase.getInstance(DnsService.getAppContext()).lookupCacheDao(); + private final LookupCacheDao lookupCacheDao = + LookupCacheDatabase.getInstance(DnsService.getAppContext()).lookupCacheDao(); private boolean getCachedIpEnable() { return DnsService.getDnsConfig().cachedIpEnable; @@ -58,8 +59,8 @@ public void clearCache(String hostname) { CacheHolder.instance.clear(); } else { String[] hostnameArr = hostname.split(","); - if(hostnameArr.length > 1) { - for(String tempHostname: hostnameArr) { + if (hostnameArr.length > 1) { + for (String tempHostname : hostnameArr) { CacheHolder.instance.delete(tempHostname); } } else { diff --git a/src/main/java/com/tencent/msdk/dns/core/local/LocalDns.java b/src/main/java/com/tencent/msdk/dns/core/local/LocalDns.java index ab9f366..7475d59 100644 --- a/src/main/java/com/tencent/msdk/dns/core/local/LocalDns.java +++ b/src/main/java/com/tencent/msdk/dns/core/local/LocalDns.java @@ -20,8 +20,8 @@ public final class LocalDns implements IDns { - private final DnsDescription mDescription = - new DnsDescription(Const.LOCAL_CHANNEL, DnsDescription.Family.UN_SPECIFIC); + private final DnsDescription mDescription = new DnsDescription(Const.LOCAL_CHANNEL, + DnsDescription.Family.UN_SPECIFIC); /** * @hide @@ -50,23 +50,6 @@ public LookupResult lookup(LookupParameters lookupParams) { return new LookupResult<>(CommonUtils.templateIps(stat.ips, lookupParams), stat); } - @Override - public LookupResult getResultFromCache(LookupParameters lookupParams) { - Statistics stat = new Statistics(); - stat.startLookup(); - stat.endLookup(); - // Local DNS暂不作缓存 - return new LookupResult<>(stat.ips, stat); - } - - /** - * @hide - */ - @Override - public ISession getSession(LookupContext lookupContext) { - return null; - } - private String[] lookup(String hostname) { if (TextUtils.isEmpty(hostname)) { throw new IllegalArgumentException("hostname".concat(Const.EMPTY_TIPS)); @@ -115,6 +98,23 @@ private String[] lookup(String hostname) { return ips; } + @Override + public LookupResult getResultFromCache(LookupParameters lookupParams) { + Statistics stat = new Statistics(); + stat.startLookup(); + stat.endLookup(); + // Local DNS暂不作缓存 + return new LookupResult<>(stat.ips, stat); + } + + /** + * @hide + */ + @Override + public ISession getSession(LookupContext lookupContext) { + return null; + } + /** * LocalDNS域名解析统计数据类 */ @@ -124,15 +124,15 @@ public static class Statistics extends AbsStatistics { @Override public String toString() { - return "Statistics{" + - "ips=" + Arrays.toString(ips) + - ", costTimeMills=" + costTimeMills + - '}'; + return "Statistics{" + + "ips=" + Arrays.toString(ips) + + ", costTimeMills=" + costTimeMills + + '}'; } - @Override - public boolean lookupPartCached() { - return false; - } + @Override + public boolean lookupPartCached() { + return false; + } } } diff --git a/src/main/java/com/tencent/msdk/dns/core/ipRank/IpRankCallback.java b/src/main/java/com/tencent/msdk/dns/core/rank/IpRankCallback.java similarity index 68% rename from src/main/java/com/tencent/msdk/dns/core/ipRank/IpRankCallback.java rename to src/main/java/com/tencent/msdk/dns/core/rank/IpRankCallback.java index 59d61b2..9375bba 100644 --- a/src/main/java/com/tencent/msdk/dns/core/ipRank/IpRankCallback.java +++ b/src/main/java/com/tencent/msdk/dns/core/rank/IpRankCallback.java @@ -1,4 +1,4 @@ -package com.tencent.msdk.dns.core.ipRank; +package com.tencent.msdk.dns.core.rank; public interface IpRankCallback { void onResult(String hostname, String[] sortedIps); diff --git a/src/main/java/com/tencent/msdk/dns/core/ipRank/IpRankHelper.java b/src/main/java/com/tencent/msdk/dns/core/rank/IpRankHelper.java similarity index 95% rename from src/main/java/com/tencent/msdk/dns/core/ipRank/IpRankHelper.java rename to src/main/java/com/tencent/msdk/dns/core/rank/IpRankHelper.java index 87b6ae1..b868e0d 100644 --- a/src/main/java/com/tencent/msdk/dns/core/ipRank/IpRankHelper.java +++ b/src/main/java/com/tencent/msdk/dns/core/rank/IpRankHelper.java @@ -1,4 +1,4 @@ -package com.tencent.msdk.dns.core.ipRank; +package com.tencent.msdk.dns.core.rank; import com.tencent.msdk.dns.DnsService; import com.tencent.msdk.dns.base.executor.DnsExecutors; @@ -46,7 +46,8 @@ public void ipv4Rank(String hostname, String[] ips, final IpRankCallback ipRankC if (ipRankItem != null) { // 发起IP测速线程任务 - DnsExecutors.WORK.execute(new IpRankTask(hostname, ipv4Lists.toArray(new String[ipv4Lists.size()]), ipRankItem, new IpRankCallback() { + DnsExecutors.WORK.execute(new IpRankTask(hostname, ipv4Lists.toArray(new String[ipv4Lists.size()]), + ipRankItem, new IpRankCallback() { @Override public void onResult(String hostname, String[] sortedIps) { if (ipRankCallback != null) { diff --git a/src/main/java/com/tencent/msdk/dns/core/ipRank/IpRankItem.java b/src/main/java/com/tencent/msdk/dns/core/rank/IpRankItem.java similarity index 91% rename from src/main/java/com/tencent/msdk/dns/core/ipRank/IpRankItem.java rename to src/main/java/com/tencent/msdk/dns/core/rank/IpRankItem.java index 85c2320..e7b84ce 100644 --- a/src/main/java/com/tencent/msdk/dns/core/ipRank/IpRankItem.java +++ b/src/main/java/com/tencent/msdk/dns/core/rank/IpRankItem.java @@ -1,4 +1,4 @@ -package com.tencent.msdk.dns.core.ipRank; +package com.tencent.msdk.dns.core.rank; public class IpRankItem { private final String hostName; diff --git a/src/main/java/com/tencent/msdk/dns/core/ipRank/IpRankTask.java b/src/main/java/com/tencent/msdk/dns/core/rank/IpRankTask.java similarity index 91% rename from src/main/java/com/tencent/msdk/dns/core/ipRank/IpRankTask.java rename to src/main/java/com/tencent/msdk/dns/core/rank/IpRankTask.java index 8beea6d..940d554 100644 --- a/src/main/java/com/tencent/msdk/dns/core/ipRank/IpRankTask.java +++ b/src/main/java/com/tencent/msdk/dns/core/rank/IpRankTask.java @@ -1,7 +1,9 @@ -package com.tencent.msdk.dns.core.ipRank; +package com.tencent.msdk.dns.core.rank; import android.util.Pair; +import com.tencent.msdk.dns.core.Const; + import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; @@ -11,7 +13,8 @@ import java.util.Comparator; public class IpRankTask implements Runnable { - private int MAX_CONNECT_TIME = 10 * 1000; + + private int timeouts = Const.MAX_CONNECT_TIME; private String hostname; private String[] ips; private IpRankItem ipRankItem; @@ -71,10 +74,10 @@ public int compare(Pair o1, Pair o2) { private int ipSpeedTask(String ip, int port) { Socket socket = new Socket(); long start = System.currentTimeMillis(); - long end = start + MAX_CONNECT_TIME; + long end = start + timeouts; SocketAddress remoteAddress = new InetSocketAddress(ip, port); try { - socket.connect(remoteAddress, MAX_CONNECT_TIME); + socket.connect(remoteAddress, timeouts); end = System.currentTimeMillis(); } catch (IOException e) { e.printStackTrace(); diff --git a/src/main/java/com/tencent/msdk/dns/core/rest/aeshttp/AesCipherSuite.java b/src/main/java/com/tencent/msdk/dns/core/rest/aeshttp/AesCipherSuite.java index 777d716..89c45be 100644 --- a/src/main/java/com/tencent/msdk/dns/core/rest/aeshttp/AesCipherSuite.java +++ b/src/main/java/com/tencent/msdk/dns/core/rest/aeshttp/AesCipherSuite.java @@ -81,8 +81,8 @@ public static String decrypt(/* @Nullable */String content, /* @Nullable */Strin * 使用密码获取AES密钥 */ public static SecretKeySpec getSecretKey(String secretKey) throws UnsupportedEncodingException { - String Key = toMakeKey(secretKey); - return new SecretKeySpec(Key.getBytes(CHARSET), KEY_ALGORITHM); + String key = toMakeKey(secretKey); + return new SecretKeySpec(key.getBytes(CHARSET), KEY_ALGORITHM); } /** diff --git a/src/main/java/com/tencent/msdk/dns/core/rest/aeshttp/AesHttpDns.java b/src/main/java/com/tencent/msdk/dns/core/rest/aeshttp/AesHttpDns.java index e30ad6f..63f1ed3 100644 --- a/src/main/java/com/tencent/msdk/dns/core/rest/aeshttp/AesHttpDns.java +++ b/src/main/java/com/tencent/msdk/dns/core/rest/aeshttp/AesHttpDns.java @@ -34,11 +34,14 @@ public String getTargetUrl(String dnsIp, String hostname, LookupExtra lookupExtr String reqContent; switch (mFamily) { case DnsDescription.Family.INET: - reqContent = RequestBuilder.buildInetRequest(encryptHostname, lookupExtra.bizId); break; + reqContent = RequestBuilder.buildInetRequest(encryptHostname, lookupExtra.bizId); + break; case DnsDescription.Family.INET6: - reqContent = RequestBuilder.buildInet6Request(encryptHostname, lookupExtra.bizId); break; + reqContent = RequestBuilder.buildInet6Request(encryptHostname, lookupExtra.bizId); + break; case DnsDescription.Family.UN_SPECIFIC: - reqContent = RequestBuilder.buildDoubRequest(encryptHostname, lookupExtra.bizId); break; + reqContent = RequestBuilder.buildDoubRequest(encryptHostname, lookupExtra.bizId); + break; default: throw new IllegalStateException("Unexpected value: " + mFamily); } diff --git a/src/main/java/com/tencent/msdk/dns/core/rest/https/HttpsDns.java b/src/main/java/com/tencent/msdk/dns/core/rest/https/HttpsDns.java index 1beb57d..9e1843b 100644 --- a/src/main/java/com/tencent/msdk/dns/core/rest/https/HttpsDns.java +++ b/src/main/java/com/tencent/msdk/dns/core/rest/https/HttpsDns.java @@ -2,9 +2,7 @@ import com.tencent.msdk.dns.core.Const; import com.tencent.msdk.dns.core.DnsDescription; - import com.tencent.msdk.dns.core.rest.share.AbsHttpDns; - import com.tencent.msdk.dns.core.rest.share.AbsHttpDnsConfig; import com.tencent.msdk.dns.core.rest.share.LookupExtra; import com.tencent.msdk.dns.core.rest.share.RequestBuilder; @@ -35,11 +33,14 @@ public String getTargetUrl(String dnsIp, String hostname, LookupExtra lookupExtr String reqContent; switch (mFamily) { case DnsDescription.Family.INET: - reqContent = RequestBuilder.buildHttpsInetRequest(hostname, lookupExtra.bizId, lookupExtra.token); break; + reqContent = RequestBuilder.buildHttpsInetRequest(hostname, lookupExtra.bizId, lookupExtra.token); + break; case DnsDescription.Family.INET6: - reqContent = RequestBuilder.buildHttpsInet6Request(hostname, lookupExtra.bizId, lookupExtra.token); break; + reqContent = RequestBuilder.buildHttpsInet6Request(hostname, lookupExtra.bizId, lookupExtra.token); + break; case DnsDescription.Family.UN_SPECIFIC: - reqContent = RequestBuilder.buildHttpsDoubRequest(hostname, lookupExtra.bizId, lookupExtra.token); break; + reqContent = RequestBuilder.buildHttpsDoubRequest(hostname, lookupExtra.bizId, lookupExtra.token); + break; default: throw new IllegalStateException("Unexpected value: " + mFamily); } diff --git a/src/main/java/com/tencent/msdk/dns/core/rest/share/AbsHttpDns.java b/src/main/java/com/tencent/msdk/dns/core/rest/share/AbsHttpDns.java index 38c0227..3f44845 100644 --- a/src/main/java/com/tencent/msdk/dns/core/rest/share/AbsHttpDns.java +++ b/src/main/java/com/tencent/msdk/dns/core/rest/share/AbsHttpDns.java @@ -105,7 +105,8 @@ public LookupResult lookup(LookupParameters lookupParams) { rawRspContent += lineTxt; } // 去除最后的"\n"字符避免干扰 ResponseParser 区分批量查询的结果 - rawRspContent = rawRspContent.length() > 0 ? rawRspContent.substring(0, rawRspContent.length() - 2) : ""; + rawRspContent = rawRspContent.length() > 0 ? rawRspContent.substring(0, rawRspContent.length() - 2) : + ""; reader.close(); stat.statusCode = connection.getResponseCode(); } catch (Exception e) { @@ -118,6 +119,9 @@ public LookupResult lookup(LookupParameters lookupParams) { throw e; } + if (stat.statusCode == 401) { + mCacheHelper.clearErrorRspCache(hostname); + } // 解密 String rspContent = decrypt(rawRspContent, lookupExtra.bizKey); DnsLog.d(getTag() + "lookup byUrl: %s, rsp:[%s]", urlStr, rspContent); @@ -131,6 +135,9 @@ public LookupResult lookup(LookupParameters lookupParams) { if (rsp == Response.EMPTY) { stat.isGetEmptyResponse = true; stat.errorCode = ErrorCode.PARSE_RESPONSE_CONTENT_FAILED_ERROR_CODE; + if (stat.statusCode == 200) { + mCacheHelper.clearErrorRspCache(hostname); + } return new LookupResult<>(stat.ips, stat); } stat.clientIp = rsp.clientIp; @@ -140,12 +147,16 @@ public LookupResult lookup(LookupParameters lookupParams) { DnsLog.d(getTag() + "receive success, but no record"); stat.isGetEmptyResponse = true; stat.errorCode = ErrorCode.NO_RECORD; + if (stat.statusCode == 200) { + mCacheHelper.clearErrorRspCache(hostname); + } return new LookupResult<>(stat.ips, stat); } + // 返回值正常处理 mCacheHelper.put(lookupParams, rsp); stat.errorCode = ErrorCode.SUCCESS; - stat.expiredTime = System.currentTimeMillis() + rsp.ttl * 1000; + stat.expiredTime = stat.getExpiredTime(rsp.ttl); } catch (Exception e) { DnsLog.d(e, getTag() + "lookup failed"); } finally { @@ -212,7 +223,9 @@ public boolean isReadable() { @Override public boolean isWritable() { if (null != mChannel) { - DnsLog.d(getTag() + ", channel isConnected:" + mChannel.isConnected() + ", writable:" + super.isWritable()); + DnsLog.d(getTag() + + ", channel isConnected:" + mChannel.isConnected() + + ", writable:" + super.isWritable()); return mChannel.isConnected() && super.isWritable(); } return super.isWritable(); @@ -256,7 +269,8 @@ public IToken getToken() { } try { // Selector注册监听 - mSelectionKey = mChannel.register(selector, SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE); + mSelectionKey = mChannel.register(selector, + SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE); mSelectionKey.attach(mChannel); } catch (Exception e) { mStat.errorCode = ErrorCode.REGISTER_CHANNEL_FAILED_ERROR_CODE; @@ -352,7 +366,7 @@ protected int requestInternal() { @Override protected Response responseInternal() { DnsLog.d(getTag() + "receive responseInternal call"); - LookupExtra lookupExtra = mLookupContext.lookupExtra(); + final LookupExtra lookupExtra = mLookupContext.lookupExtra(); if (mReadBuffer == null) { mReadBuffer = ByteBuffer.allocate(TCP_CONTINUOUS_RCV_BUF_SIZE); } @@ -396,6 +410,9 @@ protected Response responseInternal() { } } while (rspLen >= 0); DnsLog.d(getTag() + "receive response get total len:%d", totalLen); + String rspHttpRsp = sb.toString(); + mStat.statusCode = HttpHelper.responseStatus(rspHttpRsp); + DnsLog.v(getTag() + "receive rspHttpRsp:{\n%s}", rspHttpRsp); if (rspLen == 0) { DnsLog.d(getTag() + "receive response failed, need continue, for total len:%d", totalLen); @@ -409,11 +426,9 @@ protected Response responseInternal() { mStat.errorCode = ErrorCode.RESPONSE_FAILED_FOR_EXCEPTION_ERROR_CODE; return Response.EMPTY; } - String rspHttpRsp = sb.toString(); - DnsLog.v(getTag() + "receive rspHttpRsp:{\n%s}", rspHttpRsp); + String rspBody = HttpHelper.responseBody(rspHttpRsp); String rspContent = decrypt(rspBody, lookupExtra.bizKey); - mStat.statusCode = HttpHelper.responseStatus(rspHttpRsp); DnsLog.d(getTag() + "receive rawLen:%d, raw:[%s], rsp body content:[%s]", totalLen, rspBody, rspContent); if (TextUtils.isEmpty(rspContent)) { mStat.isGetEmptyResponse = true; diff --git a/src/main/java/com/tencent/msdk/dns/core/rest/share/AbsHttpDnsConfig.java b/src/main/java/com/tencent/msdk/dns/core/rest/share/AbsHttpDnsConfig.java index f5967e7..e7d0c32 100644 --- a/src/main/java/com/tencent/msdk/dns/core/rest/share/AbsHttpDnsConfig.java +++ b/src/main/java/com/tencent/msdk/dns/core/rest/share/AbsHttpDnsConfig.java @@ -1,5 +1,7 @@ package com.tencent.msdk.dns.core.rest.share; +import com.tencent.msdk.dns.base.log.DnsLog; + import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; @@ -18,6 +20,7 @@ public SocketAddress getTargetSocketAddress(String dnsIp, int family) { try { mBizTargetSockAddr = new InetSocketAddress(InetAddress.getByName(dnsIp), getBizTargetPort()); } catch (Exception ignored) { + DnsLog.e("exception: %s", ignored); } // } return mBizTargetSockAddr; diff --git a/src/main/java/com/tencent/msdk/dns/core/rest/share/AbsRestDns.java b/src/main/java/com/tencent/msdk/dns/core/rest/share/AbsRestDns.java index 4a01be7..fc69046 100644 --- a/src/main/java/com/tencent/msdk/dns/core/rest/share/AbsRestDns.java +++ b/src/main/java/com/tencent/msdk/dns/core/rest/share/AbsRestDns.java @@ -18,7 +18,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * 负责缓存管理 @@ -46,75 +48,75 @@ protected boolean tryGetResultFromCache( } final String[] hostnameArr = lookupParams.hostname.split(","); - List tempCachedips = new ArrayList<>(); - String[] tempIps; - // 对批量域名返回值做处理 + Map result = handleHostnameCached(hostnameArr); + + String[] cachedIps = (String[]) result.get("ips"); + StringBuilder requestHostname = (StringBuilder) result.get("requestHostname"); + boolean cached = (boolean) result.get("cached"); + + stat.ips = cachedIps; + if (DnsService.getDnsConfig().useExpiredIpEnable) { + // 乐观DNS以requestHostname来判断过期域名,requestHostname不存在时,无过期域名。 + lookupParams.setRequestHostname(requestHostname.toString()); + } else if (requestHostname.length() > 0) { + lookupParams.setRequestHostname(requestHostname.toString()); + } + + if (cached) { + stat.cached = true; + stat.errorCode = ErrorCode.SUCCESS; + DnsLog.d("Lookup for %s, cache hit", lookupParams.hostname); + return true; + } + + if (cachedIps.length > 0) { + stat.hadPartCachedIps = true; + } + + return false; + } + + private Map handleHostnameCached(String[] hostnameArr) { boolean cached = true; + String[] ips = Const.EMPTY_IPS; + String[] tempIps; // 未命中缓存的请求域名&乐观DNS场景下,缓存过期需要请求的域名 StringBuilder requestHostname = new StringBuilder(); - int ttl = 600; - long expiredTime = System.currentTimeMillis() + ttl * 1000; - String clientIp = ""; - boolean useExpiredIpEnable = DnsService.getDnsConfig().useExpiredIpEnable; - if (hostnameArr.length > 1) { - for (String hostname : hostnameArr) { - LookupResult lookupResult = mCacheHelper.get(hostname); - if (null != lookupResult && !CommonUtils.isEmpty(tempIps = lookupResult.ipSet.ips)) { + List cachedIps = new ArrayList<>(); + for (String hostname : hostnameArr) { + LookupResult lookupResult = mCacheHelper.get(hostname); + if (null != lookupResult && !CommonUtils.isEmpty(tempIps = lookupResult.ipSet.ips)) { + if (hostnameArr.length > 1) { for (String ip : tempIps) { - tempCachedips.add(hostname + ":" + ip); - } - Statistics cachedStat = (Statistics) lookupResult.stat; - ttl = Math.min(ttl, cachedStat.ttl); - expiredTime = Math.min(expiredTime, cachedStat.expiredTime); - clientIp = cachedStat.clientIp; - if (useExpiredIpEnable && cachedStat.expiredTime < System.currentTimeMillis()) { - requestHostname.append(hostname).append(','); + cachedIps.add(hostname + ":" + ip); } } else { - cached = false; - requestHostname.append(hostname).append(','); + ips = tempIps; } - } - requestHostname = new StringBuilder(requestHostname.length() > 0 ? requestHostname.substring(0, requestHostname.length() - 1) : ""); - if (tempCachedips.size() > 0) { - stat.ips = tempCachedips.toArray(new String[tempCachedips.size()]); - } - } else { - LookupResult lookupResult = mCacheHelper.get(hostnameArr[0]); - if (null != lookupResult && !CommonUtils.isEmpty(tempIps = lookupResult.ipSet.ips)) { - stat.ips = tempIps; Statistics cachedStat = (Statistics) lookupResult.stat; - ttl = cachedStat.ttl; - expiredTime = cachedStat.expiredTime; - clientIp = cachedStat.clientIp; - if (useExpiredIpEnable && cachedStat.expiredTime < System.currentTimeMillis()) { - requestHostname = new StringBuilder(hostnameArr[0]); + + if (DnsService.getDnsConfig().useExpiredIpEnable + && cachedStat.expiredTime < System.currentTimeMillis()) { + requestHostname.append(hostname).append(','); } } else { cached = false; - requestHostname = new StringBuilder(hostnameArr[0]); + requestHostname.append(hostname).append(','); } } - if (requestHostname.length() > 0) { - lookupParams.setRequestHostname(requestHostname.toString()); - } - - if (cached) { - stat.cached = true; - stat.errorCode = ErrorCode.SUCCESS; - stat.clientIp = clientIp; - stat.ttl = ttl; - stat.expiredTime = expiredTime; - DnsLog.d("Lookup for %s, cache hit", lookupParams.hostname); - return true; + requestHostname = new StringBuilder(requestHostname.length() > 0 ? requestHostname.substring(0, + requestHostname.length() - 1) : ""); + if (cachedIps.size() > 0) { + ips = cachedIps.toArray(new String[cachedIps.size()]); } - if (tempCachedips.size() > 0) { - stat.hadPartCachedIps = true; - } + Map result = new HashMap<>(); + result.put("requestHostname", requestHostname); + result.put("ips", ips); + result.put("cached", cached); - return false; + return result; } @Override @@ -168,8 +170,7 @@ public AbsSession(LookupContext lookupContext, IDns dns, AbsSession // NOTE: 先判断是否命中缓存, 改变状态 // 获取解析结果统一由receiveResponse完成 - if (!lookupContext.enableAsyncLookup() && - null != mCacheHelper.get(lookupContext.hostname())) { + if (!lookupContext.enableAsyncLookup() && null != mCacheHelper.get(lookupContext.hostname())) { mState = State.READABLE; } } @@ -183,8 +184,8 @@ public void connect() { try { connectRes = connectInternal(); } finally { - if (connectRes != NonBlockResult.NON_BLOCK_RESULT_NEED_CONTINUE && - State.ENDED != mState) { + if (connectRes != NonBlockResult.NON_BLOCK_RESULT_NEED_CONTINUE + && State.ENDED != mState) { mState = State.WRITABLE; } } @@ -224,16 +225,19 @@ public final String[] receiveResponse() { rsp = responseInternal(); + if ((rsp == Response.EMPTY || rsp == Response.NEED_CONTINUE || rsp.ips.length == 0) + && mStat.statusCode == 200 + || mStat.statusCode == 401) { + mCacheHelper.clearErrorRspCache(lookupParameters.requestHostname); + } + if (mStat.errorCode == ErrorCode.SUCCESS) { - mCacheHelper.put(mLookupContext.asLookupParameters(), rsp); + mCacheHelper.put(lookupParameters, rsp); } -// if (rsp != Response.EMPTY && rsp != Response.NEED_CONTINUE && rsp.ips.length > 0) { -// mStat.errorCode = ErrorCode.SUCCESS; -// mCacheHelper.put(mLookupContext.asLookupParameters(), rsp); -// } + mStat.clientIp = rsp.clientIp; mStat.ttl = rsp.ttl; - mStat.expiredTime = System.currentTimeMillis() + rsp.ttl * 1000L; + mStat.expiredTime = mStat.getExpiredTime(rsp.ttl); mStat.ips = rsp.ips; } finally { if (rsp != Response.NEED_CONTINUE) { @@ -407,7 +411,7 @@ public static class Statistics extends AbsStatistics implements Serializable { /** * 解析结果TTL(缓存有效时间), 单位s */ - public int ttl = Const.DEFAULT_TIME_INTERVAL; + public transient Map ttl = new HashMap<>(); public long expiredTime = 0; /** @@ -433,21 +437,35 @@ public static class Statistics extends AbsStatistics implements Serializable { public Statistics() { } - Statistics(String[] ips, String clientIp, int ttl) { + Statistics(String[] ips, String clientIp, Map ttl) { if (null == ips) { throw new IllegalArgumentException("ips".concat(Const.NULL_POINTER_TIPS)); } if (TextUtils.isEmpty(clientIp)) { throw new IllegalArgumentException("clientIp".concat(Const.EMPTY_TIPS)); } - if (Response.isTtlInvalid(ttl)) { + if (ttl.isEmpty()) { throw new IllegalArgumentException("ttl".concat(Const.INVALID_TIPS)); } this.ips = ips; this.clientIp = clientIp; this.ttl = ttl; - this.expiredTime = System.currentTimeMillis() + ttl * 1000L; + this.expiredTime = getExpiredTime(ttl); + } + + public long getExpiredTime(Map ttl) { + if (ttl.isEmpty()) { + return 0; + } + int min = Const.MAX_DEFAULT_TTL; + for (String key : ttl.keySet()) { + int value = ttl.get(key); + if (!Response.isTtlInvalid(value)) { + min = Math.min(value, min); + } + } + return System.currentTimeMillis() + min * 1000L; } @Override @@ -462,21 +480,21 @@ public boolean lookupSuccess() { @Override public String toString() { - return "Statistics{" + - "errorCode=" + errorCode + - ", errorMsg='" + errorMsg + '\'' + - ", statusCode=" + statusCode + - ", clientIp='" + clientIp + '\'' + - ", ttl=" + ttl + - ", expiredTime=" + expiredTime + - ", retryTimes=" + retryTimes + - ", cached=" + cached + - ", asyncLookup=" + asyncLookup + - ", netChangeLookup=" + netChangeLookup + - ", ips=" + Arrays.toString(ips) + - ", costTimeMills=" + costTimeMills + - ", startLookupTimeMills=" + startLookupTimeMills + - '}'; + return "Statistics{" + + "errorCode=" + errorCode + + ", errorMsg='" + errorMsg + '\'' + + ", statusCode=" + statusCode + + ", clientIp='" + clientIp + '\'' + + ", ttl=" + ttl + + ", expiredTime=" + expiredTime + + ", retryTimes=" + retryTimes + + ", cached=" + cached + + ", asyncLookup=" + asyncLookup + + ", netChangeLookup=" + netChangeLookup + + ", ips=" + Arrays.toString(ips) + + ", costTimeMills=" + costTimeMills + + ", startLookupTimeMills=" + startLookupTimeMills + + '}'; } } } diff --git a/src/main/java/com/tencent/msdk/dns/core/rest/share/CacheHelper.java b/src/main/java/com/tencent/msdk/dns/core/rest/share/CacheHelper.java index 8e9e6b6..41c9058 100644 --- a/src/main/java/com/tencent/msdk/dns/core/rest/share/CacheHelper.java +++ b/src/main/java/com/tencent/msdk/dns/core/rest/share/CacheHelper.java @@ -12,13 +12,12 @@ import com.tencent.msdk.dns.base.network.NetworkChangeManager; import com.tencent.msdk.dns.core.Const; import com.tencent.msdk.dns.core.DnsManager; -import com.tencent.msdk.dns.core.ICache; import com.tencent.msdk.dns.core.IDns; import com.tencent.msdk.dns.core.LookupParameters; import com.tencent.msdk.dns.core.LookupResult; import com.tencent.msdk.dns.core.cache.Cache; -import com.tencent.msdk.dns.core.ipRank.IpRankCallback; -import com.tencent.msdk.dns.core.ipRank.IpRankHelper; +import com.tencent.msdk.dns.core.rank.IpRankCallback; +import com.tencent.msdk.dns.core.rank.IpRankHelper; import com.tencent.msdk.dns.core.rest.share.rsp.Response; import com.tencent.msdk.dns.report.ReportHelper; @@ -47,7 +46,7 @@ public final class CacheHelper { CollectionCompat.>createSet()); private final IDns mDns; - private final ICache mCache = Cache.getInstance(); + private final Cache mCache = Cache.getInstance(); private final IpRankHelper mIpRankHelper = new IpRankHelper(); CacheHelper(IDns dns) { @@ -64,7 +63,18 @@ public LookupResult get(String hostname) { throw new IllegalArgumentException("hostname".concat(Const.EMPTY_TIPS)); } - return mCache.get(hostname); + LookupResult lookupResult = mCache.get(hostname); + if (lookupResult != null) { + AbsRestDns.Statistics cachedStat = (AbsRestDns.Statistics) lookupResult.stat; + final boolean useExpiredIpEnable = DnsService.getDnsConfig().useExpiredIpEnable; + // 乐观DNS或者未过期 + if (useExpiredIpEnable || cachedStat.expiredTime > System.currentTimeMillis()) { + return lookupResult; + } + DnsLog.d("Cache of %s(%d) expired", hostname, mDns.getDescription().family); + mCache.delete(hostname); + } + return null; } public void update(String hostname, LookupResult lookupResult) { @@ -75,6 +85,12 @@ public void update(String hostname, LookupResult lookupResult) { mCache.add(hostname, lookupResult); } + /** + * 解析结果处理,缓存管理,IP优选 + * + * @param lookupParams 解析参数 + * @param rsp 解析返回结果 + */ public void put(LookupParameters lookupParams, Response rsp) { if (null == lookupParams) { throw new IllegalArgumentException("lookupParams".concat(Const.NULL_POINTER_TIPS)); @@ -84,6 +100,7 @@ public void put(LookupParameters lookupParams, Response rsp) { } if (Response.EMPTY == rsp) { + clearErrorRspCache(lookupParams.requestHostname); return; } @@ -104,13 +121,17 @@ public void put(LookupParameters lookupParams, Response rsp) { for (final String hostname : hostnameArr) { - List ipsList= ipsWithHostname.get(hostname); + List ipsList = ipsWithHostname.get(hostname); if (ipsList != null) { String[] ips = ipsList.toArray(new String[0]); - AbsRestDns.Statistics stat = new AbsRestDns.Statistics(ips, rsp.clientIp, rsp.ttl); + final int ttlOfHostname = hostnameArr.length > 1 ? rsp.ttl.get(hostname) : rsp.ttl.get("onehost"); + Map ttl = new HashMap() {{ + put(hostname, ttlOfHostname); + }}; + AbsRestDns.Statistics stat = new AbsRestDns.Statistics(ips, rsp.clientIp, ttl); stat.errorCode = ErrorCode.SUCCESS; mCache.add(hostname, new LookupResult<>(ips, stat)); - cacheUpdateTask(lookupParams, rsp, hostname); + cacheUpdateTask(lookupParams, ttlOfHostname, hostname); // 发起IP优选服务 mIpRankHelper.ipv4Rank(hostname, ips, new IpRankCallback() { @@ -124,19 +145,17 @@ public void onResult(String hostname, String[] sortedIps) { } } }); + } else { + // 批量解析中,解析结果不存在时处理。 + clearErrorRspCache(hostname); } } } - private void cacheUpdateTask(LookupParameters lookupParams, Response rsp, final String hostname) { + private void cacheUpdateTask(LookupParameters lookupParams, int ttl, final String hostname) { PendingTasks pendingTasks = mHostnamePendingTasksMap.get(hostname); if (null != pendingTasks) { - if (null != pendingTasks.removeExpiredCacheTask) { - mPendingTasks.remove(pendingTasks.removeExpiredCacheTask); - DnsExecutors.MAIN.cancel(pendingTasks.removeExpiredCacheTask); - pendingTasks.removeExpiredCacheTask = null; - } if (null != pendingTasks.asyncLookupTask) { mPendingTasks.remove(pendingTasks.asyncLookupTask); DnsExecutors.MAIN.cancel(pendingTasks.asyncLookupTask); @@ -180,23 +199,7 @@ public void run() { pendingTasks.asyncLookupTask = asyncLookupTask; mPendingTasks.add(asyncLookupTask); DnsExecutors.MAIN.schedule( - asyncLookupTask, (long) (ASYNC_LOOKUP_FACTOR * rsp.ttl * 1000)); - } else { - // 不允许使用过期缓存时,ttl*100%应执行缓存清空任务。 - final boolean useExpiredIpEnable = DnsService.getDnsConfig().useExpiredIpEnable; - if (!useExpiredIpEnable) { - final Runnable removeExpiredCacheTask = new Runnable() { - @Override - public void run() { - DnsLog.d("Cache of %s(%d) expired", hostname, mDns.getDescription().family); - mCache.delete(hostname); - mPendingTasks.remove(this); - } - }; - pendingTasks.removeExpiredCacheTask = removeExpiredCacheTask; - mPendingTasks.add(removeExpiredCacheTask); - DnsExecutors.MAIN.schedule(removeExpiredCacheTask, (long) (rsp.ttl * 1000)); - } + asyncLookupTask, (long) (ASYNC_LOOKUP_FACTOR * ttl * 1000)); } if (!mHostnamePendingTasksMap.containsKey(hostname)) { @@ -204,6 +207,13 @@ public void run() { } } + public void clearErrorRspCache(String hostname) { + // 乐观DNS场景下,当httpdns请求服务正常返回解析结果异常(为空,解析结果不存在)时,清除缓存。 + if (DnsService.getDnsConfig().useExpiredIpEnable) { + mCache.clearCache(hostname); + } + } + private void listenNetworkChange() { NetworkChangeManager.addNetworkChangeListener( new IOnNetworkChangeListener() { diff --git a/src/main/java/com/tencent/msdk/dns/core/rest/share/DataConverter.java b/src/main/java/com/tencent/msdk/dns/core/rest/share/DataConverter.java index 47d42bc..fe7c5cb 100644 --- a/src/main/java/com/tencent/msdk/dns/core/rest/share/DataConverter.java +++ b/src/main/java/com/tencent/msdk/dns/core/rest/share/DataConverter.java @@ -4,11 +4,11 @@ public final class DataConverter { - private static final char[] DIGITS = new char[] { + private static final char[] DIGITS = new char[]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; public static String bytes2HexString(byte[] bytes) { - if (null == bytes|| 0 == bytes.length) { + if (null == bytes || 0 == bytes.length) { return ""; } char[] buf = new char[2 * bytes.length]; @@ -28,8 +28,8 @@ public static byte[] hexString2Bytes(String hexString) { int len = hexString.length(); byte[] data = new byte[len / 2]; for (int i = 0; i + 1 < len; i += 2) { - data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + - Character.digit(hexString.charAt(i + 1), 16)); + data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + + Character.digit(hexString.charAt(i + 1), 16)); } return data; } diff --git a/src/main/java/com/tencent/msdk/dns/core/rest/share/LookupExtra.java b/src/main/java/com/tencent/msdk/dns/core/rest/share/LookupExtra.java index d9026d9..c3a5e0a 100644 --- a/src/main/java/com/tencent/msdk/dns/core/rest/share/LookupExtra.java +++ b/src/main/java/com/tencent/msdk/dns/core/rest/share/LookupExtra.java @@ -15,9 +15,6 @@ public LookupExtra(String bizId, String bizKey, String token) { if (TextUtils.isEmpty(bizId)) { throw new IllegalArgumentException("bizId".concat(Const.EMPTY_TIPS)); } - if (TextUtils.isEmpty(bizKey)) { - throw new IllegalArgumentException("bizKey".concat(Const.EMPTY_TIPS)); - } this.bizId = bizId; this.bizKey = bizKey; @@ -26,10 +23,10 @@ public LookupExtra(String bizId, String bizKey, String token) { @Override public String toString() { - return "LookupExtra{" + - "bizId='" + bizId + '\'' + - ", bizKey='" + bizKey + '\'' + - ", token='" + token + '\'' + - '}'; + return "LookupExtra{" + + "bizId='" + bizId + '\'' + + ", bizKey='" + bizKey + '\'' + + ", token='" + token + '\'' + + '}'; } } diff --git a/src/main/java/com/tencent/msdk/dns/core/rest/share/RequestBuilder.java b/src/main/java/com/tencent/msdk/dns/core/rest/share/RequestBuilder.java index 10e2507..5ab7042 100644 --- a/src/main/java/com/tencent/msdk/dns/core/rest/share/RequestBuilder.java +++ b/src/main/java/com/tencent/msdk/dns/core/rest/share/RequestBuilder.java @@ -20,27 +20,28 @@ public static String buildInetRequest(String encryptedHostname, String bizId) { return buildRequest(encryptedHostname, bizId, INET_REQUEST_FORMAT, false); } - public static String buildInet6Request(String encryptedHostname, String bizId) { - return buildRequest(encryptedHostname, bizId, INET6_REQUEST_FORMAT, false); - } - - public static String buildDoubRequest(String encryptedHostname, String bizId) { - return buildRequest(encryptedHostname, bizId, DOUB_REQUEST_FORMAT, false); - } - public static String buildInetRequest(String encryptedHostname, String bizId, boolean isServerHostname) { return buildRequest(encryptedHostname, bizId, INET_REQUEST_FORMAT, isServerHostname); } + public static String buildInet6Request(String encryptedHostname, String bizId) { + return buildRequest(encryptedHostname, bizId, INET6_REQUEST_FORMAT, false); + } + public static String buildInet6Request(String encryptedHostname, String bizId, boolean isServerHostname) { return buildRequest(encryptedHostname, bizId, INET6_REQUEST_FORMAT, isServerHostname); } + public static String buildDoubRequest(String encryptedHostname, String bizId) { + return buildRequest(encryptedHostname, bizId, DOUB_REQUEST_FORMAT, false); + } + public static String buildDoubRequest(String encryptedHostname, String bizId, boolean isServerHostname) { return buildRequest(encryptedHostname, bizId, DOUB_REQUEST_FORMAT, isServerHostname); } - private static String buildRequest(String encryptedHostname, String bizId, String format, boolean isServerHostname) { + private static String buildRequest(String encryptedHostname, String bizId, String format, + boolean isServerHostname) { if (TextUtils.isEmpty(bizId)) { throw new IllegalArgumentException("bizId".concat(Const.EMPTY_TIPS)); } diff --git a/src/main/java/com/tencent/msdk/dns/core/rest/share/rsp/Response.java b/src/main/java/com/tencent/msdk/dns/core/rest/share/rsp/Response.java index 6a4348f..4994a64 100644 --- a/src/main/java/com/tencent/msdk/dns/core/rest/share/rsp/Response.java +++ b/src/main/java/com/tencent/msdk/dns/core/rest/share/rsp/Response.java @@ -8,20 +8,24 @@ import com.tencent.msdk.dns.core.DnsDescription; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; public final class Response { + static HashMap DEFAULT_TTL = new HashMap<>(); + public static final Response EMPTY = - new Response(Const.INVALID_IP, Const.EMPTY_IPS, Const.DEFAULT_TIME_INTERVAL); + new Response(Const.INVALID_IP, Const.EMPTY_IPS, DEFAULT_TTL); public static final Response NEED_CONTINUE = - new Response(Const.INVALID_IP, Const.EMPTY_IPS, Const.DEFAULT_TIME_INTERVAL); + new Response(Const.INVALID_IP, Const.EMPTY_IPS, DEFAULT_TTL); public final String clientIp; public final String[] ips; - public final int ttl; + public final Map ttl; - Response(int family, String clientIp, String[] ips, int ttl) { + Response(int family, String clientIp, String[] ips, Map ttl) { // NOTE: 区分inet和inet6, 不允许unspecific family = DnsDescription.Family.INET6 == family ? family : DnsDescription.Family.INET; if (TextUtils.isEmpty(clientIp)) { @@ -36,7 +40,7 @@ public final class Response { // if (CommonUtils.isEmpty(ips)) { // throw new IllegalArgumentException("ips".concat(Const.EMPTY_TIPS)); // } - if (isTtlInvalid(ttl)) { + if (ttl.isEmpty()) { throw new IllegalArgumentException("ttl".concat(Const.INVALID_TIPS)); } @@ -45,7 +49,7 @@ public final class Response { this.ttl = ttl; } - Response(String clientIp, String[] inet4Ips, String[] inet6Ips, int ttl) { + Response(String clientIp, String[] inet4Ips, String[] inet6Ips, Map ttl) { // NOTE: 允许unspecific if (TextUtils.isEmpty(clientIp)) { throw new IllegalArgumentException("clientIp".concat(Const.EMPTY_TIPS)); @@ -58,7 +62,7 @@ public final class Response { inet4Ips = fixIps(DnsDescription.Family.INET, inet4Ips); inet6Ips = fixIps(DnsDescription.Family.INET6, inet6Ips); - if (isTtlInvalid(ttl)) { + if (ttl.isEmpty()) { throw new IllegalArgumentException("ttl".concat(Const.INVALID_TIPS)); } int inet4IpsLength = inet4Ips.length; @@ -73,7 +77,7 @@ public final class Response { } // NOTE: 仅用于创建空实现, 空实现实际上为无效值, 无法通过常规构造器创建 - private Response(String clientIp, String[] ips, int ttl) { + private Response(String clientIp, String[] ips, Map ttl) { this.clientIp = clientIp; this.ips = ips; this.ttl = ttl; diff --git a/src/main/java/com/tencent/msdk/dns/core/rest/share/rsp/ResponseParser.java b/src/main/java/com/tencent/msdk/dns/core/rest/share/rsp/ResponseParser.java index 5826de3..4a6e638 100644 --- a/src/main/java/com/tencent/msdk/dns/core/rest/share/rsp/ResponseParser.java +++ b/src/main/java/com/tencent/msdk/dns/core/rest/share/rsp/ResponseParser.java @@ -8,6 +8,8 @@ import com.tencent.msdk.dns.core.DnsDescription; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -38,10 +40,10 @@ public static Response parseResponse(int family, String rawRsp) { // format: ip;ip;ip;...,ttl|client ip // like: 123.59.226.2;123.59.226.3,303|59.37.125.43 // 批量查询情况 + Map ttl = new HashMap<>(); if (rspList.length > 1) { ArrayList ipsList = new ArrayList(); String clientIp = ""; - int ttl = 0; // 遍历 for (String rsp : rspList) { // 批量情况会携带域名信息 @@ -56,10 +58,10 @@ public static Response parseResponse(int family, String rawRsp) { clientIp = rspMatcher.group(4) + ","; String[] tmpIps = rspMatcher.group(2).split(IP_SPLITTER); // 将域名和ip组装为 host:ip的形式存入clientIp - for (int n = 0; n < tmpIps.length; n++) { - ipsList.add(host + ":" + tmpIps[n]); + for (String tmpIp : tmpIps) { + ipsList.add(host + ":" + tmpIp); } - ttl = Integer.parseInt(rspMatcher.group(3)); + ttl.put(host, Integer.parseInt(rspMatcher.group(3))); } catch (Exception e) { DnsLog.w(e, "Parse external response failed"); return Response.EMPTY; @@ -68,7 +70,7 @@ public static Response parseResponse(int family, String rawRsp) { if (ipsList.size() == 0) { return Response.EMPTY; } - String ips[] = ipsList.toArray(new String[ipsList.size()]); + String[] ips = ipsList.toArray(new String[ipsList.size()]); return new Response(family, clientIp, ips, ttl); } else { // 普通查询 @@ -79,7 +81,8 @@ public static Response parseResponse(int family, String rawRsp) { try { String clientIp = rspMatcher.group(3); String[] ips = rspMatcher.group(1).split(IP_SPLITTER); - int ttl = Integer.parseInt(rspMatcher.group(2)); + // 单个域名未传递,暂用onehost代替 + ttl.put("onehost", Integer.parseInt(rspMatcher.group(2))); return new Response(family, clientIp, ips, ttl); } catch (Exception e) { DnsLog.w(e, "Parse external response failed"); @@ -90,13 +93,14 @@ public static Response parseResponse(int family, String rawRsp) { public static Response parseDoubResponse(@NonNull String[] rspList) { // format: ip;ip;ip;...,ttl|client ip - // like: www.qq.com.:121.14.77.221;121.14.77.201,120-2402:4e00:1020:1404:0:9227:71a3:83d2;2402:4e00:1020:1404:0:9227:71ab:2b74,120|113.108.77.69 + // like: www.qq.com.:120.14.67.201,120-2402:4e00:1011:1414:0:9226:71a3:83d2; + // 2412:4e30:1020:1474:0:9257:71ab:2b74,120|127.0.0.1 // 批量查询情况 + Map ttl = new HashMap<>(); if (rspList.length > 1) { ArrayList inet4IpsList = new ArrayList(); ArrayList inet6IpsList = new ArrayList(); String clientIp = ""; - int ttl = 0; // 遍历 for (String rsp : rspList) { // 批量情况会携带域名信息 @@ -111,16 +115,17 @@ public static Response parseDoubResponse(@NonNull String[] rspList) { String[] inet4Ips = rspMatcher.group(2).split(IP_SPLITTER); String[] inet6Ips = rspMatcher.group(4).split(IP_SPLITTER); - // todo:ttl先按ipv4的获取 - ttl = Integer.parseInt(rspMatcher.group(3)); + // ttl先按ipv4, ipv6的最小值的获取 + ttl.put(host, Math.min(Integer.parseInt(rspMatcher.group(3)), + Integer.parseInt(rspMatcher.group(5)))); // 将域名和ip组装为 host:ip的形式存入clientIp - for (int n = 0; n < inet4Ips.length; n++) { - inet4IpsList.add(host + ":" + inet4Ips[n]); + for (String inet4Ip : inet4Ips) { + inet4IpsList.add(host + ":" + inet4Ip); } - for (int n = 0; n < inet6Ips.length; n++) { - inet6IpsList.add(host + ":" + inet6Ips[n]); + for (String inet6Ip : inet6Ips) { + inet6IpsList.add(host + ":" + inet6Ip); } } catch (Exception e) { DnsLog.w(e, "Parse external response failed"); @@ -130,8 +135,8 @@ public static Response parseDoubResponse(@NonNull String[] rspList) { if (inet4IpsList.size() == 0 && inet6IpsList.size() == 0) { return Response.EMPTY; } - String inet4IpsTemp[] = inet4IpsList.toArray(new String[inet4IpsList.size()]); - String inet6IpsTemp[] = inet6IpsList.toArray(new String[inet6IpsList.size()]); + String[] inet4IpsTemp = inet4IpsList.toArray(new String[inet4IpsList.size()]); + String[] inet6IpsTemp = inet6IpsList.toArray(new String[inet6IpsList.size()]); return new Response(clientIp, inet4IpsTemp, inet6IpsTemp, ttl); } else { try { @@ -144,8 +149,9 @@ public static Response parseDoubResponse(@NonNull String[] rspList) { String clientIp = rspMatcher.group(5); String[] inet4Ips = rspMatcher.group(1).split(IP_SPLITTER); String[] inet6Ips = rspMatcher.group(3).split(IP_SPLITTER); - // todo:ttl先按ipv4的获取 - int ttl = Integer.parseInt(rspMatcher.group(2)); + // ttl先按ipv4, ipv6的最小值的获取 + int value = Math.min(Integer.parseInt(rspMatcher.group(2)), Integer.parseInt(rspMatcher.group(4))); + ttl.put("onehost", value); return new Response(clientIp, inet4Ips, inet6Ips, ttl); } catch (Exception e) { diff --git a/src/main/java/com/tencent/msdk/dns/core/retry/Retry.java b/src/main/java/com/tencent/msdk/dns/core/retry/Retry.java index 4dd1c37..d0271cf 100644 --- a/src/main/java/com/tencent/msdk/dns/core/retry/Retry.java +++ b/src/main/java/com/tencent/msdk/dns/core/retry/Retry.java @@ -36,8 +36,8 @@ public void retryNonBlock(LookupContext lookupContext) { @SuppressWarnings({"SynchronizationOnLocalVariableOrMethodParameter", "unchecked"}) @Override - public - void retryBlock(LookupContext lookupContext) { + public + void retryBlock(LookupContext lookupContext) { if (null == lookupContext) { throw new IllegalArgumentException("lookupContext".concat(Const.NULL_POINTER_TIPS)); } diff --git a/src/main/java/com/tencent/msdk/dns/core/stat/StatisticsMerge.java b/src/main/java/com/tencent/msdk/dns/core/stat/StatisticsMerge.java index b6ccd0d..486099f 100644 --- a/src/main/java/com/tencent/msdk/dns/core/stat/StatisticsMerge.java +++ b/src/main/java/com/tencent/msdk/dns/core/stat/StatisticsMerge.java @@ -91,7 +91,7 @@ public StatisticsMerge(Context context) { } @Override - public void merge(IDns dns, Statistics stat) { + public void merge(IDns dns, StatisticsT stat) { if (null == dns) { throw new IllegalArgumentException("dns".concat(Const.NULL_POINTER_TIPS)); } @@ -174,31 +174,32 @@ public String toJsonResult() { try { jsonObject.put("v4_ips", ipSet == null ? "" : CommonUtils.toStringList(ipSet.v4Ips, ",")); jsonObject.put("v6_ips", ipSet == null ? "" : CommonUtils.toStringList(ipSet.v6Ips, ",")); - jsonObject.put("request_name", requestHostname); + jsonObject.put("request_name", requestHostname == null ? "" : requestHostname); jsonObject.put("ttl", String.valueOf(restDnsStat.ttl)); jsonObject.put("client_ip", String.valueOf(restDnsStat.clientIp)); jsonObject.put("expired_time", String.valueOf(restDnsStat.expiredTime)); return jsonObject.toString(); - } catch (Exception ignore) { + } catch (Exception ignored) { + DnsLog.e("exception: %s", ignored); } return ""; } @Override public String toString() { - return super.toString() + "{" + - "netType='" + netType + '\'' + - ", hostname='" + hostname + '\'' + - ", requestHostname='" + requestHostname + '\'' + - ", channel='" + channel + '\'' + - ", curNetStack=" + curNetStack + - ", localDnsStat=" + localDnsStat + - ", restDnsStat=" + restDnsStat + - ", ipSet=" + ipSet + - ", lookupSuccess=" + lookupSuccess + - ", lookupGetEmptyResponse=" + lookupFailed + - ", hasBeenMerge=" + hasBeenMerge + - '}'; + return super.toString() + + "{netType='" + netType + '\'' + + ", hostname='" + hostname + '\'' + + ", requestHostname='" + requestHostname + '\'' + + ", channel='" + channel + '\'' + + ", curNetStack=" + curNetStack + + ", localDnsStat=" + localDnsStat + + ", restDnsStat=" + restDnsStat + + ", ipSet=" + ipSet + + ", lookupSuccess=" + lookupSuccess + + ", lookupGetEmptyResponse=" + lookupFailed + + ", hasBeenMerge=" + hasBeenMerge + + '}'; } } diff --git a/src/main/java/com/tencent/msdk/dns/core/stat/StatisticsMergeFactory.java b/src/main/java/com/tencent/msdk/dns/core/stat/StatisticsMergeFactory.java index 5226f1f..ecc6c00 100644 --- a/src/main/java/com/tencent/msdk/dns/core/stat/StatisticsMergeFactory.java +++ b/src/main/java/com/tencent/msdk/dns/core/stat/StatisticsMergeFactory.java @@ -10,8 +10,8 @@ public final class StatisticsMergeFactory implements IStatisticsMerge.IFactory { @Override - public - IStatisticsMerge create(Class klass, Context context) { + public + IStatisticsMerge create(Class klass, Context context) { if (null == klass) { throw new IllegalArgumentException("klass".concat(Const.NULL_POINTER_TIPS)); } @@ -21,7 +21,7 @@ IStatisticsMerge create(Class klass, Context c if (LookupExtra.class.equals(klass)) { //noinspection unchecked - return (IStatisticsMerge) new StatisticsMerge(context); + return (IStatisticsMerge) new StatisticsMerge(context); } return IStatisticsMerge.IFactory.DEFAULT.create(klass, context); } diff --git a/src/main/java/com/tencent/msdk/dns/report/AttaHelper.java b/src/main/java/com/tencent/msdk/dns/report/AttaHelper.java index ca4cd4d..f8dec13 100644 --- a/src/main/java/com/tencent/msdk/dns/report/AttaHelper.java +++ b/src/main/java/com/tencent/msdk/dns/report/AttaHelper.java @@ -9,6 +9,7 @@ import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; +import java.util.Map; /** @@ -33,11 +34,11 @@ public static Runnable report(final String carrier, final long eventTime, final String dnsIp, final long spend, - final long ldns_spend, - final String req_dn, - final String req_type, - final long req_timeout, - final int req_ttl, + final long ldnsSpend, + final String reqDn, + final String reqType, + final long reqTimeout, + final Map reqTtl, final long errorCode, final int statusCode, final boolean isCache, @@ -65,11 +66,12 @@ public void run() { + "&systemName=" + SYSTEMNANE + "&systemVersion=" + SYSTEMVERSION + "&spend=" + spend - + "&ldns_spend=" + ldns_spend - + "&req_dn=" + req_dn - + "&req_type=" + req_type - + "&req_timeout=" + req_timeout - + "&req_ttl=" + req_ttl + + "&ldns_spend=" + ldnsSpend + + "&req_dn=" + reqDn + + "&req_type=" + reqType + + "&req_timeout=" + reqTimeout + // todo: ttl需处理,先上报0 + + "&req_ttl= 0" + "&errorCode=" + errorCode + "&statusCode=" + statusCode + "&sessionId=" + SESSIONID @@ -87,11 +89,11 @@ public void run() { //设置读取超时时间(毫秒) connection.setReadTimeout(2000); connection.connect(); - int respCode = connection.getResponseCode(); } catch (IOException e) { e.printStackTrace(); } finally { - if (connection != null) {//关闭连接 + if (connection != null) { + //关闭连接 connection.disconnect(); DnsLog.d("Atta上报关闭"); } @@ -114,7 +116,7 @@ public static String getSimOperator(Context context) { } else { // 通过getSimOperator方法获取运营商设备信息 carrierCode = tm.getSimOperator(); //mobile data - //String netOperator = tm.getNetworkOperator(); //Dial Net + // String netOperator = tm.getNetworkOperator(); //Dial Net return carrierCode; } } @@ -155,6 +157,8 @@ public static String getReqType(int curNetStack) { case 3: reqType = "dual"; break; + default: + break; } return reqType; } diff --git a/src/main/java/com/tencent/msdk/dns/report/CacheStatisticsReport.java b/src/main/java/com/tencent/msdk/dns/report/CacheStatisticsReport.java index d30601a..f02de9b 100644 --- a/src/main/java/com/tencent/msdk/dns/report/CacheStatisticsReport.java +++ b/src/main/java/com/tencent/msdk/dns/report/CacheStatisticsReport.java @@ -33,7 +33,7 @@ public static void add(LookupResult lookupResult) { } // 命中缓存的数据,统计上报 - for(String hostname: hostnameArr) { + for (String hostname : hostnameArr) { if (!statisticsMap.containsKey(hostname)) { if (statMerge.lookupSuccess()) { // Object[costTimeMillsTotal, emptyCount, resultCount] @@ -59,7 +59,7 @@ public static void add(LookupResult lookupResult) { public static String[] compare(String[] strArr1, String[] strArr2) { List list = new ArrayList<>(); List list2 = Arrays.asList(strArr2); - for(String str: strArr1) { + for (String str : strArr1) { if (!list2.contains(str)) { list.add(str); } diff --git a/src/main/java/com/tencent/msdk/dns/report/ReportConst.java b/src/main/java/com/tencent/msdk/dns/report/ReportConst.java index fcc8d00..62f91de 100644 --- a/src/main/java/com/tencent/msdk/dns/report/ReportConst.java +++ b/src/main/java/com/tencent/msdk/dns/report/ReportConst.java @@ -2,12 +2,18 @@ interface ReportConst { - String PRE_LOOKUP_EVENT_NAME = "HDNSPreLookup"; // 预解析 - String ASYNC_LOOKUP_EVENT_NAME = "HDNSLookupAsync"; // 缓存自动刷新(异步) - String LOOKUP_METHOD_CALLED_EVENT_NAME = "HDNSGetHostByName"; // 普通解析 - String LOOKUP_FROM_CACHED_EVENT_NAME = "HDNSLookupCached"; // 命中缓存 - String EXPIRED_ASYNC_LOOKUP_EVENT_NAME = "HDNSLookupExpiredAsync"; // useExpiredIpEnable为true时的异步更新缓存事件,区别于HDNSLookupAsync - String DOMAIN_SERVER_LOOKUP_EVENT_NAME = "HDNSGetDomainIP"; // 域名服务 + // 预解析 + String PRE_LOOKUP_EVENT_NAME = "HDNSPreLookup"; + // 缓存自动刷新(异步) + String ASYNC_LOOKUP_EVENT_NAME = "HDNSLookupAsync"; + // 普通解析 + String LOOKUP_METHOD_CALLED_EVENT_NAME = "HDNSGetHostByName"; + // 命中缓存 + String LOOKUP_FROM_CACHED_EVENT_NAME = "HDNSLookupCached"; + // useExpiredIpEnable为true时的异步更新缓存事件,区别于HDNSLookupAsync + String EXPIRED_ASYNC_LOOKUP_EVENT_NAME = "HDNSLookupExpiredAsync"; + // 域名服务 + String DOMAIN_SERVER_LOOKUP_EVENT_NAME = "HDNSGetDomainIP"; String IP_SPLITTER = ","; diff --git a/src/main/java/com/tencent/msdk/dns/report/ReportHelper.java b/src/main/java/com/tencent/msdk/dns/report/ReportHelper.java index 129a65c..4c781a7 100644 --- a/src/main/java/com/tencent/msdk/dns/report/ReportHelper.java +++ b/src/main/java/com/tencent/msdk/dns/report/ReportHelper.java @@ -1,5 +1,7 @@ package com.tencent.msdk.dns.report; +import static com.tencent.msdk.dns.base.executor.DnsExecutors.MAIN; + import android.app.Activity; import com.tencent.msdk.dns.BackupResolver; @@ -7,7 +9,6 @@ import com.tencent.msdk.dns.DnsConfig; import com.tencent.msdk.dns.DnsService; import com.tencent.msdk.dns.base.compat.CollectionCompat; -import com.tencent.msdk.dns.base.executor.DnsExecutors; import com.tencent.msdk.dns.base.lifecycle.ActivityLifecycleCallbacksWrapper; import com.tencent.msdk.dns.base.lifecycle.ActivityLifecycleDetector; import com.tencent.msdk.dns.base.log.DnsLog; @@ -30,8 +31,8 @@ public final class ReportHelper { public void run() { // atta上报统计数据 attaReportStatisticsEvent(); - DnsExecutors.MAIN.cancel(sReportAsyncLookupEventTask); - DnsExecutors.MAIN.schedule( + MAIN.cancel(sReportAsyncLookupEventTask); + MAIN.schedule( sReportAsyncLookupEventTask, REPORT_ASYNC_LOOKUP_EVENT_INTERVAL_MILLS); } }; @@ -114,12 +115,6 @@ public static void reportLookupMethodCalledEvent(LookupResult lookupResult) { // NOTE: 上报字段增减, 记得修改capacity Map lookupMethodCalledEventMap = CollectionCompat.createMap(20); -// IpSet ipSet = lookupResult.ipSet; -// lookupMethodCalledEventMap.put(ReportConst.INET_LOOKUP_IPS_KEY, -// CommonUtils.toStringList(ipSet.v4Ips, ReportConst.IP_SPLITTER)); -// lookupMethodCalledEventMap.put(ReportConst.INET6_LOOKUP_IPS_KEY, -// CommonUtils.toStringList(ipSet.v6Ips, ReportConst.IP_SPLITTER)); - lookupMethodCalledEventMap.put(ReportConst.CHANNEL_KEY, statMerge.channel); lookupMethodCalledEventMap.put(ReportConst.NETWORK_TYPE_KEY, statMerge.netType); lookupMethodCalledEventMap.put(ReportConst.HOSTNAME_KEY, statMerge.hostname); @@ -162,12 +157,12 @@ public static void reportLookupMethodCalledEvent(LookupResult lookupResult) { private static void startReportAsyncLookupEvent() { // NOTE: 无论是否存在可用的上报通道, 都应该不断消费异步解析结果 - DnsExecutors.MAIN.schedule( + MAIN.schedule( sReportAsyncLookupEventTask, REPORT_ASYNC_LOOKUP_EVENT_INTERVAL_MILLS); ActivityLifecycleDetector.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacksWrapper() { @Override public void onActivityStopped(Activity activity) { - DnsExecutors.MAIN.execute(sReportAsyncLookupEventTask); + MAIN.execute(sReportAsyncLookupEventTask); } }); } @@ -203,19 +198,41 @@ private static void attaReportLookupEvent(String eventName, LookupResult lookupR if (statMerge.restDnsStat.errorCode == 0) { // 请求成功后将ErrorCount置为0 backupInfo.setErrorCount(0); - DnsExecutors.MAIN.execute(AttaHelper.report(carrierCode, statMerge.netType, sDnsConfig.lookupExtra.bizId, sDnsConfig.appId, sDnsConfig.channel, eventName, System.currentTimeMillis(), dnsIp, statMerge.restDnsStat.costTimeMills, statMerge.localDnsStat.costTimeMills, statMerge.requestHostname, reqType, sDnsConfig.timeoutMills, statMerge.restDnsStat.ttl, statMerge.restDnsStat.errorCode, statMerge.restDnsStat.statusCode, statMerge.restDnsStat.cached, 1, CommonUtils.toStringList(statMerge.localDnsStat.ips, ReportConst.IP_SPLITTER), CommonUtils.toStringList(statMerge.restDnsStat.ips, ReportConst.IP_SPLITTER))); + MAIN.execute(AttaHelper.report(carrierCode, statMerge.netType, sDnsConfig.lookupExtra.bizId, + sDnsConfig.appId, sDnsConfig.channel, eventName, System.currentTimeMillis(), dnsIp, + statMerge.restDnsStat.costTimeMills, statMerge.localDnsStat.costTimeMills, + statMerge.requestHostname, reqType, sDnsConfig.timeoutMills, statMerge.restDnsStat.ttl, + statMerge.restDnsStat.errorCode, statMerge.restDnsStat.statusCode, + statMerge.restDnsStat.cached, 1, + CommonUtils.toStringList(statMerge.localDnsStat.ips, ReportConst.IP_SPLITTER), + CommonUtils.toStringList(statMerge.restDnsStat.ips, ReportConst.IP_SPLITTER))); } else { // ErrorCode==2 (超时)进行容灾处理,https请求存在请求异常超时时间>timeoutMills,此时errCode为1 - if (statMerge.restDnsStat.errorCode == 2 || (Const.HTTPS_CHANNEL.equals(sDnsConfig.channel) && (statMerge.restDnsStat.errorCode == 1))) { + if (statMerge.restDnsStat.errorCode == 2 + || (Const.HTTPS_CHANNEL.equals(sDnsConfig.channel) && (statMerge.restDnsStat.errorCode == 1))) { // 解析失败,仅当达到最大失败次数满足切换IP时候上报 if (backupInfo.getCanReport(backupInfo.getErrorCount() + 1)) { - DnsExecutors.MAIN.execute(AttaHelper.report(carrierCode, statMerge.netType, sDnsConfig.lookupExtra.bizId, sDnsConfig.appId, sDnsConfig.channel, eventName, System.currentTimeMillis(), dnsIp, statMerge.restDnsStat.costTimeMills, statMerge.localDnsStat.costTimeMills, statMerge.requestHostname, reqType, sDnsConfig.timeoutMills, statMerge.restDnsStat.ttl, statMerge.restDnsStat.errorCode, statMerge.restDnsStat.statusCode, statMerge.restDnsStat.cached, 1, CommonUtils.toStringList(statMerge.localDnsStat.ips, ReportConst.IP_SPLITTER), CommonUtils.toStringList(statMerge.restDnsStat.ips, ReportConst.IP_SPLITTER))); + MAIN.execute(AttaHelper.report(carrierCode, statMerge.netType, sDnsConfig.lookupExtra.bizId, + sDnsConfig.appId, sDnsConfig.channel, eventName, System.currentTimeMillis(), dnsIp, + statMerge.restDnsStat.costTimeMills, statMerge.localDnsStat.costTimeMills, + statMerge.requestHostname, reqType, sDnsConfig.timeoutMills, + statMerge.restDnsStat.ttl, statMerge.restDnsStat.errorCode, + statMerge.restDnsStat.statusCode, statMerge.restDnsStat.cached, 1, + CommonUtils.toStringList(statMerge.localDnsStat.ips, ReportConst.IP_SPLITTER), + CommonUtils.toStringList(statMerge.restDnsStat.ips, ReportConst.IP_SPLITTER))); } // 报错记录+1 backupInfo.incrementErrorCount(); DnsLog.d("dnsip连接失败, 当前失败次数:" + backupInfo.getErrorCount()); } else { - DnsExecutors.MAIN.execute(AttaHelper.report(carrierCode, statMerge.netType, sDnsConfig.lookupExtra.bizId, sDnsConfig.appId, sDnsConfig.channel, eventName, System.currentTimeMillis(), dnsIp, statMerge.restDnsStat.costTimeMills, statMerge.localDnsStat.costTimeMills, statMerge.requestHostname, reqType, sDnsConfig.timeoutMills, statMerge.restDnsStat.ttl, statMerge.restDnsStat.errorCode, statMerge.restDnsStat.statusCode, statMerge.restDnsStat.cached, 1, CommonUtils.toStringList(statMerge.localDnsStat.ips, ReportConst.IP_SPLITTER), CommonUtils.toStringList(statMerge.restDnsStat.ips, ReportConst.IP_SPLITTER))); + MAIN.execute(AttaHelper.report(carrierCode, statMerge.netType, sDnsConfig.lookupExtra.bizId, + sDnsConfig.appId, sDnsConfig.channel, eventName, System.currentTimeMillis(), dnsIp, + statMerge.restDnsStat.costTimeMills, statMerge.localDnsStat.costTimeMills, + statMerge.requestHostname, reqType, sDnsConfig.timeoutMills, statMerge.restDnsStat.ttl, + statMerge.restDnsStat.errorCode, statMerge.restDnsStat.statusCode, + statMerge.restDnsStat.cached, 1, + CommonUtils.toStringList(statMerge.localDnsStat.ips, ReportConst.IP_SPLITTER), + CommonUtils.toStringList(statMerge.restDnsStat.ips, ReportConst.IP_SPLITTER))); } } } @@ -238,11 +255,17 @@ private static void attaReportStatisticsEvent() { String dnsIp = BackupResolver.getInstance().getDnsIp(); if (errCount > 0) { // 为空的缓存统计项上报,解析结果不上报 - DnsExecutors.MAIN.execute(AttaHelper.report(carrierCode, "", sDnsConfig.lookupExtra.bizId, sDnsConfig.appId, sDnsConfig.channel, ReportConst.LOOKUP_FROM_CACHED_EVENT_NAME, System.currentTimeMillis(), dnsIp, spendAvg, 0, item.getKey(), "", sDnsConfig.timeoutMills, 0, 3, 0, true, errCount, null, null)); + MAIN.execute(AttaHelper.report(carrierCode, "", sDnsConfig.lookupExtra.bizId, sDnsConfig.appId, + sDnsConfig.channel, ReportConst.LOOKUP_FROM_CACHED_EVENT_NAME, System.currentTimeMillis(), + dnsIp, spendAvg, 0, item.getKey(), "", sDnsConfig.timeoutMills, null, 3, 0, true, errCount, null + , null)); } if (curCount > 0) { // 有值的缓存统计项上报,解析结果不上报 - DnsExecutors.MAIN.execute(AttaHelper.report(carrierCode, "", sDnsConfig.lookupExtra.bizId, sDnsConfig.appId, sDnsConfig.channel, ReportConst.LOOKUP_FROM_CACHED_EVENT_NAME, System.currentTimeMillis(), dnsIp, spendAvg, 0, item.getKey(), "", sDnsConfig.timeoutMills, 0, 0, 0, true, curCount, null, null)); + MAIN.execute(AttaHelper.report(carrierCode, "", sDnsConfig.lookupExtra.bizId, sDnsConfig.appId, + sDnsConfig.channel, ReportConst.LOOKUP_FROM_CACHED_EVENT_NAME, System.currentTimeMillis(), + dnsIp, spendAvg, 0, item.getKey(), "", sDnsConfig.timeoutMills, null, 0, 0, true, curCount, null + , null)); } } } diff --git a/src/main/java/com/tencent/msdk/dns/report/Session.java b/src/main/java/com/tencent/msdk/dns/report/Session.java index 1b83e93..b132df6 100644 --- a/src/main/java/com/tencent/msdk/dns/report/Session.java +++ b/src/main/java/com/tencent/msdk/dns/report/Session.java @@ -11,8 +11,9 @@ public static void setSessionId() { final String sampleAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; final Random random = new Random(); char[] buf = new char[12]; - for (int i = 0; i < 12; i++) + for (int i = 0; i < 12; i++) { buf[i] = sampleAlphabet.charAt(random.nextInt(sampleAlphabet.length())); + } sessionId = new String(buf); DnsLog.d("hello sessionId: " + sessionId); } diff --git a/src/main/java/com/tencent/msdk/dns/report/SpendReportResolver.java b/src/main/java/com/tencent/msdk/dns/report/SpendReportResolver.java index 9c47e0b..8750add 100644 --- a/src/main/java/com/tencent/msdk/dns/report/SpendReportResolver.java +++ b/src/main/java/com/tencent/msdk/dns/report/SpendReportResolver.java @@ -17,7 +17,8 @@ private SpendReportResolver() { // 解析耗时上报的间隔时间 private long mInterval = 5 * 60 * 1000; - public static SpendReportResolver getInstance() {//静态get方法 + public static SpendReportResolver getInstance() { + // 静态get方法 if (mSpendReportResolver == null) { synchronized (BackupResolver.class) { if (mSpendReportResolver == null) {