diff --git a/MSDKDns.xcodeproj/project.pbxproj b/MSDKDns.xcodeproj/project.pbxproj index 5b77e89..4aaa6b0 100644 --- a/MSDKDns.xcodeproj/project.pbxproj +++ b/MSDKDns.xcodeproj/project.pbxproj @@ -628,7 +628,7 @@ LINK_WITH_STANDARD_LIBRARIES = NO; MACH_O_TYPE = mh_object; MACOSX_DEPLOYMENT_TARGET = ""; - MARKETING_VERSION = 1.3.5; + MARKETING_VERSION = 1.4.0; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = "-fembed-bitcode"; OTHER_LDFLAGS = ( @@ -667,7 +667,7 @@ LINK_WITH_STANDARD_LIBRARIES = NO; MACH_O_TYPE = mh_object; MACOSX_DEPLOYMENT_TARGET = ""; - MARKETING_VERSION = 1.3.5; + MARKETING_VERSION = 1.4.0; OTHER_CFLAGS = "-fembed-bitcode"; OTHER_LDFLAGS = ( "-ObjC", @@ -704,7 +704,7 @@ LINK_WITH_STANDARD_LIBRARIES = NO; MACH_O_TYPE = mh_object; MACOSX_DEPLOYMENT_TARGET = ""; - MARKETING_VERSION = 1.3.5; + MARKETING_VERSION = 1.4.0; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = "-fembed-bitcode"; OTHER_LDFLAGS = ( @@ -743,7 +743,7 @@ LINK_WITH_STANDARD_LIBRARIES = NO; MACH_O_TYPE = mh_object; MACOSX_DEPLOYMENT_TARGET = ""; - MARKETING_VERSION = 1.3.5; + MARKETING_VERSION = 1.4.0; OTHER_CFLAGS = "-fembed-bitcode"; OTHER_LDFLAGS = ( "-ObjC", diff --git a/MSDKDns/CacheManager/MSDKDnsManager.h b/MSDKDns/CacheManager/MSDKDnsManager.h index e0c7d0d..1846906 100644 --- a/MSDKDns/CacheManager/MSDKDnsManager.h +++ b/MSDKDns/CacheManager/MSDKDnsManager.h @@ -26,6 +26,7 @@ - (void)getHostsByNames:(NSArray *)domains verbose:(BOOL)verbose returnIps:(void (^)(NSDictionary * ipsDict))handler; - (NSDictionary *)getHostsByNames:(NSArray *)domains verbose:(BOOL)verbose; +- (void)refreshCacheDelay:(NSArray *)domains clearDispatchTag:(BOOL)needClear; - (void)preResolveDomains; - (void)dnsHasDone:(MSDKDnsService *)service; - (void)cacheDomainInfo:(NSDictionary *)domainInfo Domain:(NSString *)domain; @@ -37,4 +38,11 @@ - (NSString *)currentDnsServer; - (void)switchDnsServer; - (void)switchToMainServer; + +// 添加domain进入延迟记录字典里面 +- (void)msdkDnsAddDomainOpenDelayDispatch: (NSString *)domain; +- (void)msdkDnsClearDomainOpenDelayDispatch:(NSString *)domain; +// 批量删除 +- (void)msdkDnsClearDomainsOpenDelayDispatch:(NSArray *)domains; +- (NSMutableDictionary *)msdkDnsGetDomainISOpenDelayDispatch; @end diff --git a/MSDKDns/CacheManager/MSDKDnsManager.m b/MSDKDns/CacheManager/MSDKDnsManager.m index c5da2c8..251a310 100644 --- a/MSDKDns/CacheManager/MSDKDnsManager.m +++ b/MSDKDns/CacheManager/MSDKDnsManager.m @@ -23,6 +23,8 @@ @interface MSDKDnsManager () @property (nonatomic, assign, readwrite) int serverIndex; @property (nonatomic, strong, readwrite) NSDate *firstFailTime; // 记录首次失败的时间 @property (nonatomic, assign, readwrite) BOOL waitToSwitch; // 防止连续多次切换 +// 延迟记录字典,记录哪些域名已经开启了延迟解析请求 +@property (strong, nonatomic, readwrite) NSMutableDictionary* domainISOpenDelayDispatch; @end @@ -90,6 +92,7 @@ - (NSDictionary *)getHostsByNames:(NSArray *)domains verbose:(BOOL)verbose { } // 全部有缓存时,直接返回 if([toCheckDomains count] == 0) { + // NSLog(@"有缓存"); NSDictionary * result = verbose ? [self fullResultDictionary:domains fromCache:cacheDomainDict] : [self resultDictionary:domains fromCache:cacheDomainDict]; @@ -107,6 +110,7 @@ - (NSDictionary *)getHostsByNames:(NSArray *)domains verbose:(BOOL)verbose { MSDKDnsService * dnsService = [[MSDKDnsService alloc] init]; [self.serviceArray addObject:dnsService]; __weak __typeof__(self) weakSelf = self; + // NSLog(@"%@, MSDKDns Result is toCheckDomains",toCheckDomains); [dnsService getHostsByNames:toCheckDomains TimeOut:timeOut DnsId:dnsId DnsKey:dnsKey NetStack:netStack encryptType:encryptType returnIps:^() { __strong __typeof(self) strongSelf = weakSelf; if (strongSelf) { @@ -197,6 +201,29 @@ - (void)getHostsByNames:(NSArray *)domains } }]; }); + +} + +#pragma mark 发送解析请求刷新缓存 + +- (void)refreshCacheDelay:(NSArray *)domains clearDispatchTag:(BOOL)needClear { + // 获取当前ipv4/ipv6/双栈网络环境 + msdkdns::MSDKDNS_TLocalIPStack netStack = [self detectAddressType]; + __block float timeOut = 2.0; + timeOut = [[MSDKDnsParamsManager shareInstance] msdkDnsGetMTimeOut]; + //进行httpdns请求 + int dnsId = [[MSDKDnsParamsManager shareInstance] msdkDnsGetMDnsId]; + NSString * dnsKey = [[MSDKDnsParamsManager shareInstance] msdkDnsGetMDnsKey]; + HttpDnsEncryptType encryptType = [[MSDKDnsParamsManager shareInstance] msdkDnsGetEncryptType]; + + MSDKDnsService * dnsService = [[MSDKDnsService alloc] init]; + [dnsService getHostsByNames:domains TimeOut:timeOut DnsId:dnsId DnsKey:dnsKey NetStack:netStack encryptType:encryptType returnIps:^{ + if(needClear){ + // 当请求结束了需要将该域名开启的标志清除,方便下次继续开启延迟解析请求 + // NSLog(@"延时更新请求结束!请求域名为%@",domains); + [self msdkDnsClearDomainsOpenDelayDispatch:domains]; + } + }]; } - (void)preResolveDomains { @@ -502,10 +529,13 @@ - (NSMutableDictionary *)formatParams:(BOOL)isFromCache Domain:(NSString *)domai NSString * httpDnsTTL_4A = @""; NSString * httpDnsErrCode_A = @""; NSString * httpDnsErrCode_4A = @""; + NSString * httpDnsErrCode_BOTH = @""; NSString * httpDnsErrMsg_A = @""; NSString * httpDnsErrMsg_4A = @""; + NSString * httpDnsErrMsg_BOTH = @""; NSString * httpDnsRetry_A = @""; NSString * httpDnsRetry_4A = @""; + NSString * httpDnsRetry_BOTH = @""; NSString * cache_A = @""; NSString * cache_4A = @""; NSString * dns_A = @"0"; @@ -579,6 +609,13 @@ - (NSMutableDictionary *)formatParams:(BOOL)isFromCache Domain:(NSString *)domai httpDnsErrMsg_4A = httpDnsInfo_A[kDnsErrMsg]; httpDnsRetry_4A = httpDnsInfo_A[kDnsRetry]; } + + NSDictionary * httpDnsInfo_BOTH = cacheInfo[kMSDKHttpDnsInfo_BOTH]; + if (httpDnsInfo_BOTH) { + httpDnsErrCode_BOTH = httpDnsInfo_BOTH[kDnsErrCode]; + httpDnsErrMsg_BOTH = httpDnsInfo_BOTH[kDnsErrMsg]; + httpDnsRetry_BOTH = httpDnsInfo_BOTH[kDnsRetry]; + } } } @@ -610,14 +647,17 @@ - (NSMutableDictionary *)formatParams:(BOOL)isFromCache Domain:(NSString *)domai //ErrCode [params setValue:httpDnsErrCode_A forKey:kMSDKDns_A_ErrCode]; [params setValue:httpDnsErrCode_4A forKey:kMSDKDns_4A_ErrCode]; + [params setValue:httpDnsErrCode_BOTH forKey:kMSDKDns_BOTH_ErrCode]; //ErrMsg [params setValue:httpDnsErrMsg_A forKey:kMSDKDns_A_ErrMsg]; [params setValue:httpDnsErrMsg_4A forKey:kMSDKDns_4A_ErrMsg]; + [params setValue:httpDnsErrMsg_BOTH forKey:kMSDKDns_BOTH_ErrMsg]; //Retry [params setValue:httpDnsRetry_A forKey:kMSDKDns_A_Retry]; [params setValue:httpDnsRetry_4A forKey:kMSDKDns_4A_Retry]; + [params setValue:httpDnsRetry_BOTH forKey:kMSDKDns_BOTH_Retry]; //dns [params setValue:dns_A forKey:kMSDKDns_DNS_A_IP]; @@ -716,4 +756,40 @@ - (void)switchToMainServer { }); } +# pragma mark - operate delay tag + +- (void)msdkDnsAddDomainOpenDelayDispatch: (NSString *)domain { + dispatch_async([MSDKDnsInfoTool msdkdns_queue], ^{ + if (domain && domain.length > 0) { + MSDKDNSLOG(@"domainISOpenDelayDispatch add domain:%@", domain); + if (!self.domainISOpenDelayDispatch) { + self.domainISOpenDelayDispatch = [[NSMutableDictionary alloc] init]; + } + [self.domainISOpenDelayDispatch setObject:@YES forKey:domain]; + } + }); +} + +- (void)msdkDnsClearDomainOpenDelayDispatch:(NSString *)domain { + if (domain && domain.length > 0) { + // NSLog(@"请求结束,清除标志.请求域名为%@",domain); + MSDKDNSLOG(@"The cache update request end! request domain:%@",domain); + MSDKDNSLOG(@"domainISOpenDelayDispatch remove domain:%@", domain); + if (self.domainISOpenDelayDispatch) { + [self.domainISOpenDelayDispatch removeObjectForKey:domain]; + } + } +} + +- (void)msdkDnsClearDomainsOpenDelayDispatch:(NSArray *)domains { + for(int i = 0; i < [domains count]; i++) { + NSString* domain = [domains objectAtIndex:i]; + [self msdkDnsClearDomainOpenDelayDispatch:domain]; + } +} + +- (NSMutableDictionary *)msdkDnsGetDomainISOpenDelayDispatch { + return _domainISOpenDelayDispatch; +} + @end diff --git a/MSDKDns/CacheManager/MSDKDnsNetworkManager.m b/MSDKDns/CacheManager/MSDKDnsNetworkManager.m index 605cb66..068432e 100644 --- a/MSDKDns/CacheManager/MSDKDnsNetworkManager.m +++ b/MSDKDns/CacheManager/MSDKDnsNetworkManager.m @@ -4,6 +4,7 @@ #import "MSDKDnsNetworkManager.h" #import "MSDKDnsLog.h" +#import "MSDKDnsInfoTool.h" #import "MSDKDnsManager.h" #import "MSDKDnsParamsManager.h" #import @@ -68,32 +69,36 @@ - (instancetype)init queue:nil usingBlock:^(NSNotification *note) { - MSDKDNSLOG(@"Network did changed,clear MSDKDns cache"); - //网络状态发生变化时清除缓存 - [[MSDKDnsManager shareInstance] clearAllCache]; - //重置ip指针 - [[MSDKDnsManager shareInstance] switchToMainServer]; - }]; + MSDKDNSLOG(@"Network did changed,clear MSDKDns cache"); + //网络状态发生变化时清除缓存 + [[MSDKDnsManager shareInstance] clearAllCache]; + //对保活域名发送解析请求 + [self getHostsByKeepAliveDomains]; + //重置ip指针 + [[MSDKDnsManager shareInstance] switchToMainServer]; + }]; [NSNotificationCenter.defaultCenter addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:nil usingBlock:^(NSNotification *note) { - MSDKDNSLOG(@"Application did enter background,clear MSDKDns cache"); - //进入后台时清除缓存,暂停网络监测 - [[MSDKDnsManager shareInstance] clearAllCache]; - [self.reachability stopNotifier]; - }]; + MSDKDNSLOG(@"Application did enter background,clear MSDKDns cache"); + //进入后台时清除缓存,暂停网络监测 + [[MSDKDnsManager shareInstance] clearAllCache]; + [self.reachability stopNotifier]; + }]; [NSNotificationCenter.defaultCenter addObserverForName:UIApplicationWillEnterForegroundNotification object:nil queue:nil usingBlock:^(NSNotification *note) { - //进入前台时,开启网络监测 - [self.reachability startNotifier]; - }]; + //进入前台时,开启网络监测 + [self.reachability startNotifier]; + //对保活域名发送解析请求 + [self getHostsByKeepAliveDomains]; + }]; _reachability = [MSDKDnsReachability reachabilityForInternetConnection]; [_reachability startNotifier]; @@ -275,4 +280,14 @@ -(NSString*) localWiFiIPAddress { return waddr; } +- (void)getHostsByKeepAliveDomains{ + //对保活域名发送解析请求 + dispatch_async([MSDKDnsInfoTool msdkdns_queue], ^{ + NSArray *keepAliveDomains = [[MSDKDnsParamsManager shareInstance] msdkDnsGetKeepAliveDomains]; + if (keepAliveDomains && keepAliveDomains.count > 0) { + [[MSDKDnsManager shareInstance] refreshCacheDelay:keepAliveDomains clearDispatchTag:NO]; + } + }); +} + @end diff --git a/MSDKDns/CacheManager/MSDKDnsParamsManager.h b/MSDKDns/CacheManager/MSDKDnsParamsManager.h index e0f9a19..cb57bcc 100644 --- a/MSDKDns/CacheManager/MSDKDnsParamsManager.h +++ b/MSDKDns/CacheManager/MSDKDnsParamsManager.h @@ -27,6 +27,7 @@ - (void)msdkDnsSetEnableReport: (BOOL)enableReport; - (void)msdkDnsSetPreResolvedDomains: (NSArray *)domains; - (void)msdkDnsSetAddressType: (HttpDnsAddressType)addressType; +- (void)msdkDnsSetKeepAliveDomains: (NSArray *)domains; - (NSString *) msdkDnsGetMDnsIp; - (NSString *) msdkDnsGetMOpenId; @@ -44,4 +45,5 @@ - (BOOL)msdkDnsGetEnableReport; - (NSArray *)msdkDnsGetPreResolvedDomains; - (HttpDnsAddressType)msdkDnsGetAddressType; +- (NSArray *)msdkDnsGetKeepAliveDomains; @end diff --git a/MSDKDns/CacheManager/MSDKDnsParamsManager.m b/MSDKDns/CacheManager/MSDKDnsParamsManager.m index c35abaf..6908502 100644 --- a/MSDKDns/CacheManager/MSDKDnsParamsManager.m +++ b/MSDKDns/CacheManager/MSDKDnsParamsManager.m @@ -32,6 +32,8 @@ @interface MSDKDnsParamsManager() @property (assign, nonatomic, readwrite) BOOL enableReport; @property (strong, nonatomic, readwrite) NSArray* preResolvedDomains; @property (assign, nonatomic, readwrite) HttpDnsAddressType msdkAddressType; +@property (strong, nonatomic, readwrite) NSArray* keepAliveDomains; + @end @implementation MSDKDnsParamsManager @@ -156,6 +158,14 @@ - (void)msdkDnsSetAddressType: (HttpDnsAddressType)addressType { }); } +- (void)msdkDnsSetKeepAliveDomains: (NSArray *)domains { + dispatch_async([MSDKDnsInfoTool msdkdns_queue], ^{ + self.keepAliveDomains = [domains copy]; + }); +} + + + #pragma mark - getter - (BOOL)msdkDnsGetHttpOnly { @@ -229,4 +239,10 @@ - (HttpDnsAddressType)msdkDnsGetAddressType { return _msdkAddressType; } +- (NSArray *)msdkDnsGetKeepAliveDomains { + return _keepAliveDomains; +} + + + @end diff --git a/MSDKDns/MSDKDns.h b/MSDKDns/MSDKDns.h index bbe0a5c..06425fd 100644 --- a/MSDKDns/MSDKDns.h +++ b/MSDKDns/MSDKDns.h @@ -5,7 +5,7 @@ #ifndef __MSDKDns_H__ #define __MSDKDns_H__ -#define MSDKDns_Version @"1.3.5" +#define MSDKDns_Version @"1.4.0" #import @@ -79,6 +79,11 @@ typedef struct DnsConfigStruct { */ - (void) WGSetPreResolvedDomains:(NSArray *)domains; +/** + * 设置保活的域名,设置的域名会定时更新缓存,数量不能大于8个 + */ +- (void) WGSetKeepAliveDomains:(NSArray *)domains; + #pragma mark - 域名解析接口,按需调用 /** 域名同步解析(通用接口) diff --git a/MSDKDns/MSDKDns.m b/MSDKDns/MSDKDns.m index 9429655..d7e2ec5 100644 --- a/MSDKDns/MSDKDns.m +++ b/MSDKDns/MSDKDns.m @@ -100,6 +100,12 @@ - (void) WGSetPreResolvedDomains:(NSArray *)domains { [[MSDKDnsManager shareInstance] preResolveDomains]; } +- (void) WGSetKeepAliveDomains:(NSArray *)domains { + if (domains) { + [[MSDKDnsParamsManager shareInstance] msdkDnsSetKeepAliveDomains:domains]; + } +} + - (void) WGSetHijackDomainArray:(NSArray *)hijackDomainArray { if (hijackDomainArray) { [[MSDKDnsParamsManager shareInstance] setHijackDomainArray:[hijackDomainArray copy]]; diff --git a/MSDKDns/MSDKDnsInfoTool.h b/MSDKDns/MSDKDnsInfoTool.h index d9be288..fef0b55 100644 --- a/MSDKDns/MSDKDnsInfoTool.h +++ b/MSDKDns/MSDKDnsInfoTool.h @@ -3,6 +3,7 @@ */ #import +#import "Resolver/HttpsDnsResolver.h" @interface MSDKDnsInfoTool : NSObject @@ -14,9 +15,9 @@ + (NSString *) encryptUseDES:(NSString *)plainText key:(NSString *)key; + (NSString *) decryptUseDES:(NSString *)cipherString key:(NSString *)key; -+ (NSURL *) httpsUrlWithDomain:(NSString *)domain DnsId:(int)dnsId DnsKey:(NSString *)dnsKey Use4A:(BOOL)use4A; ++ (NSURL *) httpsUrlWithDomain:(NSString *)domain DnsId:(int)dnsId DnsKey:(NSString *)dnsKey IPType:(HttpDnsIPType)ipType; + (NSString *)encryptUseAES:(NSString *)plainText key:(NSString *)key; + (NSString *)decryptUseAES:(NSString *)cipherString key:(NSString *)key; -+ (NSURL *) httpsUrlWithDomain:(NSString *)domain DnsId:(int)dnsId DnsKey:(NSString *)dnsKey Use4A:(BOOL)use4A encryptType:(NSInteger)encryptType; //encryptType: 0 des,1 aes ++ (NSURL *) httpsUrlWithDomain:(NSString *)domain DnsId:(int)dnsId DnsKey:(NSString *)dnsKey IPType:(HttpDnsIPType)ipType encryptType:(NSInteger)encryptType; //encryptType: 0 des,1 aes @end diff --git a/MSDKDns/MSDKDnsInfoTool.m b/MSDKDns/MSDKDnsInfoTool.m index 9fa2589..608e276 100644 --- a/MSDKDns/MSDKDnsInfoTool.m +++ b/MSDKDns/MSDKDnsInfoTool.m @@ -388,12 +388,12 @@ + (NSData *)bytesFromHexString:(NSString *)hexString length:(int)len return newData; } -+ (NSURL *) httpsUrlWithDomain:(NSString *)domain DnsId:(int)dnsId DnsKey:(NSString *)dnsKey Use4A:(BOOL)use4A ++ (NSURL *) httpsUrlWithDomain:(NSString *)domain DnsId:(int)dnsId DnsKey:(NSString *)dnsKey IPType:(HttpDnsIPType)ipType { - return [self httpsUrlWithDomain:domain DnsId:dnsId DnsKey:dnsKey Use4A:use4A encryptType:HttpDnsEncryptTypeDES]; + return [self httpsUrlWithDomain:domain DnsId:dnsId DnsKey:dnsKey IPType:ipType encryptType:HttpDnsEncryptTypeDES]; } -+ (NSURL *) httpsUrlWithDomain:(NSString *)domain DnsId:(int)dnsId DnsKey:(NSString *)dnsKey Use4A:(BOOL)use4A encryptType:(NSInteger)encryptType ++ (NSURL *) httpsUrlWithDomain:(NSString *)domain DnsId:(int)dnsId DnsKey:(NSString *)dnsKey IPType:(HttpDnsIPType)ipType encryptType:(NSInteger)encryptType { if (!domain || domain.length == 0) { MSDKDNSLOG(@"HttpDns Domain cannot be empty!"); @@ -435,8 +435,10 @@ + (NSURL *) httpsUrlWithDomain:(NSString *)domain DnsId:(int)dnsId DnsKey:(NSStr httpServer = serviceIp; } NSString * urlStr = [NSString stringWithFormat:@"%@://%@/d?dn=%@&clientip=1&ttl=1&query=1&id=%d", protocol, httpServer, domainEncrypStr, dnsId]; - if (use4A) { + if (ipType == HttpDnsTypeIPv6) { urlStr = [urlStr stringByAppendingString:@"&type=aaaa"]; + }else if (ipType == HttpDnsTypeDual) { + urlStr = [urlStr stringByAppendingString:@"&type=addrs"]; } if (encryptType == HttpDnsEncryptTypeAES) { urlStr = [urlStr stringByAppendingFormat:@"&alg=aes"]; diff --git a/MSDKDns/MSDKDnsPrivate.h b/MSDKDns/MSDKDnsPrivate.h index 6de0c53..29329f2 100644 --- a/MSDKDns/MSDKDnsPrivate.h +++ b/MSDKDns/MSDKDnsPrivate.h @@ -21,6 +21,7 @@ static NSString * const kMSDKHttpDnsCache_A = @"httpDnsCache_A"; static NSString * const kMSDKHttpDnsCache_4A = @"httpDnsCache_4A"; static NSString * const kMSDKHttpDnsInfo_A = @"httpDnsInfo_A"; static NSString * const kMSDKHttpDnsInfo_4A = @"httpDnsInfo_4A"; +static NSString * const kMSDKHttpDnsInfo_BOTH = @"httpDnsInfo_BOTH"; static NSString * const kMSDKLocalDnsCache = @"localDnsCache"; //HttpDns解析结果数据上报相关 @@ -54,6 +55,9 @@ static NSString * const kMSDKDns_4A_TTL = @"hdns_4a_ttl"; // 域名 static NSString * const kMSDKDns_4A_ClientIP = @"hdns_4a_client_ip"; // 域名解析AAAA记录结果客户端IP static NSString * const kMSDKDns_4A_Time = @"hdns_4a_time_ms"; // 域名解析AAAA记录耗时(单位ms) static NSString * const kMSDKDns_4A_Retry = @"hdns_4a_retry"; // 域名解析AAAA记录重试次数 +static NSString * const kMSDKDns_BOTH_Retry = @"hdns_both_retry"; // 双栈域名解析重试次数 +static NSString * const kMSDKDns_BOTH_ErrCode = @"hdns_both_err_code"; // 双栈域名解析解析错误码 +static NSString * const kMSDKDns_BOTH_ErrMsg = @"hdns_both_err_msg"; // 双栈域名解析解析错误信息 static NSString * const kMSDKDns_DNS_A_IP = @"dns_ips"; // 域名解析结果v4 IP,多个ip以“,”拼接 static NSString * const kMSDKDns_DNS_4A_IP = @"dns_4a_ips"; // 域名解析结果v6 IP,多个ip以“,”拼接 diff --git a/MSDKDns/MSDKDnsService.m b/MSDKDns/MSDKDnsService.m index 31f9b3b..84c34a3 100644 --- a/MSDKDns/MSDKDnsService.m +++ b/MSDKDns/MSDKDnsService.m @@ -17,6 +17,7 @@ @interface MSDKDnsService () @property (strong, nonatomic) NSArray * toCheckDomains; @property (strong, nonatomic) HttpsDnsResolver * httpDnsResolver_A; @property (strong, nonatomic) HttpsDnsResolver * httpDnsResolver_4A; +@property (strong, nonatomic) HttpsDnsResolver * httpDnsResolver_BOTH; @property (strong, nonatomic) LocalDnsResolver * localDnsResolver; @property (nonatomic, strong) void (^ completionHandler)(); @property (atomic, assign) BOOL isCallBack; @@ -79,18 +80,24 @@ - (void)startCheck:(float)timeOut DnsId:(int)dnsId DnsKey:(NSString *)dnsKey enc self.dnsKey = dnsKey; self.encryptType = encryptType; - if (_netStack != msdkdns::MSDKDNS_ELocalIPStack_IPv4) { + if (_netStack == msdkdns::MSDKDNS_ELocalIPStack_IPv6) { dispatch_async([MSDKDnsInfoTool msdkdns_resolver_queue], ^{ [self startHttpDns_4A:timeOut DnsId:dnsId DnsKey:dnsKey encryptType:encryptType]; }); } - if (_netStack != msdkdns::MSDKDNS_ELocalIPStack_IPv6) { + if (_netStack == msdkdns::MSDKDNS_ELocalIPStack_IPv4) { dispatch_async([MSDKDnsInfoTool msdkdns_resolver_queue], ^{ [self startHttpDns:timeOut DnsId:dnsId DnsKey:dnsKey encryptType:encryptType]; }); } + if (_netStack == msdkdns::MSDKDNS_ELocalIPStack_Dual) { + dispatch_async([MSDKDnsInfoTool msdkdns_resolver_queue], ^{ + [self startHttpDnsBoth:timeOut DnsId:dnsId DnsKey:dnsKey encryptType:encryptType]; + }); + } + BOOL httpOnly = [[MSDKDnsParamsManager shareInstance] msdkDnsGetHttpOnly]; if (!httpOnly) { dispatch_async([MSDKDnsInfoTool msdkdns_resolver_queue], ^{ @@ -105,7 +112,16 @@ - (void)startCheck:(float)timeOut DnsId:(int)dnsId DnsKey:(NSString *)dnsKey enc }); } -//进行httpdns请求 +//进行httpdns ipv4和ipv6合并请求 +- (void)startHttpDnsBoth:(float)timeOut DnsId:(int)dnsId DnsKey:(NSString *)dnsKey encryptType:(NSInteger)encryptType +{ + MSDKDNSLOG(@"%@ StartHttpDns!", self.toCheckDomains); + self.httpDnsResolver_BOTH = [[HttpsDnsResolver alloc] init]; + self.httpDnsResolver_BOTH.delegate = self; + [self.httpDnsResolver_BOTH startWithDomains:self.toCheckDomains TimeOut:timeOut DnsId:dnsId DnsKey:dnsKey NetStack:msdkdns::MSDKDNS_ELocalIPStack_Dual encryptType:encryptType]; +} + +//进行httpdns ipv4请求 - (void)startHttpDns:(float)timeOut DnsId:(int)dnsId DnsKey:(NSString *)dnsKey encryptType:(NSInteger)encryptType { MSDKDNSLOG(@"%@ StartHttpDns!", self.toCheckDomains); @@ -114,7 +130,7 @@ - (void)startHttpDns:(float)timeOut DnsId:(int)dnsId DnsKey:(NSString *)dnsKey e [self.httpDnsResolver_A startWithDomains:self.toCheckDomains TimeOut:timeOut DnsId:dnsId DnsKey:dnsKey NetStack:msdkdns::MSDKDNS_ELocalIPStack_IPv4 encryptType:encryptType]; } - +//进行httpdns ipv6请求 - (void)startHttpDns_4A:(float)timeOut DnsId:(int)dnsId DnsKey:(NSString *)dnsKey encryptType:(NSInteger)encryptType { MSDKDNSLOG(@"%@ StartHttpDns!", self.toCheckDomains); @@ -140,9 +156,59 @@ - (void)resolver:(MSDKDnsResolver *)resolver didGetDomainInfo:(NSDictionary *)do [self cacheDomainInfo:resolver]; NSDictionary * info = @{kDnsErrCode:MSDKDns_Success, kDnsErrMsg:@"", kDnsRetry:@"0"}; [self callBack:resolver Info:info]; + if (resolver == self.httpDnsResolver_A || resolver == self.httpDnsResolver_4A || resolver == self.httpDnsResolver_BOTH) { + NSArray *keepAliveDomains = [[MSDKDnsParamsManager shareInstance] msdkDnsGetKeepAliveDomains]; + // 获取延迟记录字典 + NSMutableDictionary *domainISOpenDelayDispatch = [[MSDKDnsManager shareInstance] msdkDnsGetDomainISOpenDelayDispatch]; + [domainInfo enumerateKeysAndObjectsUsingBlock:^(id _Nonnull domain, id _Nonnull obj, BOOL * _Nonnull stop) { + // NSLog(@"domain = %@", domain); + // NSLog(@"domainInfo = %@", domainInfo); + + // 判断此次请求的域名中有多少属于保活域名,是则开启延时解析请求,自动刷新缓存 + if (keepAliveDomains && domain && [keepAliveDomains containsObject:domain]) { + + NSMutableString * afterTime = [[NSMutableString alloc] init]; + + if(resolver == self.httpDnsResolver_BOTH){ + NSDictionary *domainResult = domainInfo[domain]; + if (domainResult) { + NSDictionary *ipv4Value = [domainResult objectForKey:@"ipv4"]; + NSDictionary *ipv6Value = [domainResult objectForKey:@"ipv6"]; + if (ipv6Value) { + NSString *ttl = [ipv6Value objectForKey:kTTL]; + afterTime = [[NSMutableString alloc]initWithString:ttl]; + } + if (ipv4Value) { + NSString *ttl = [ipv4Value objectForKey:kTTL]; + afterTime = [[NSMutableString alloc]initWithString:ttl]; + } + } + }else{ + NSDictionary *domainResult = domainInfo[domain]; + if (domainResult) { + NSString *ttl = [domainResult objectForKey:kTTL]; + afterTime = [[NSMutableString alloc]initWithString:ttl]; + } + } + + // NSLog(@"4444444延时更新请求等待,预计在%f秒后开始!请求域名为%@",afterTime.floatValue,domain); + if (!domainISOpenDelayDispatch[domain] && afterTime) { + // 使用静态字典来记录该域名是否开启了一个延迟解析请求,如果已经开启则忽略,没有则立马开启一个 + [[MSDKDnsManager shareInstance] msdkDnsAddDomainOpenDelayDispatch:domain]; + MSDKDNSLOG(@"Start the delayed execution task, it is expected to start requesting the domain name %@ after %f seconds", domain, afterTime.floatValue); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW,afterTime.floatValue* NSEC_PER_SEC), [MSDKDnsInfoTool msdkdns_queue], ^{ + // NSLog(@"延时更新请求开始!请求域名为%@",domain); + MSDKDNSLOG(@"The cache update request start! request domain:%@",domain); + [[MSDKDnsManager shareInstance] refreshCacheDelay:@[domain] clearDispatchTag:YES]; + }); + } + + } + }]; + } }); // 正常解析结果上报,上报解析耗时 - if(resolver == self.httpDnsResolver_A || resolver == self.httpDnsResolver_4A) { + if (resolver == self.httpDnsResolver_A || resolver == self.httpDnsResolver_4A || resolver == self.httpDnsResolver_BOTH) { if ([[MSDKDnsParamsManager shareInstance] msdkDnsGetEnableReport] && [[AttaReport sharedInstance] shoulReportDnsSpend]) { NSDictionary *domainDic = [domainInfo objectForKey:[self.toCheckDomains firstObject]]; NSString* routeip = [[MSDKDnsParamsManager shareInstance] msdkDnsGetRouteIp]; @@ -189,6 +255,10 @@ - (void) retryHttpDns:(MSDKDnsResolver *)resolver { dispatch_async([MSDKDnsInfoTool msdkdns_retry_queue], ^{ [self startHttpDns_4A:self.timeOut DnsId:self.dnsId DnsKey:self.dnsKey encryptType:self.encryptType]; }); + } else if (resolver == self.httpDnsResolver_BOTH) { + dispatch_async([MSDKDnsInfoTool msdkdns_retry_queue], ^{ + [self startHttpDnsBoth:self.timeOut DnsId:self.dnsId DnsKey:self.dnsKey encryptType:self.encryptType]; + }); } } else { MSDKDNSLOG(@"fail %lu times, switch server!", (unsigned long)[[MSDKDnsParamsManager shareInstance] msdkDnsGetRetryTimesBeforeSwitchServer]); @@ -243,7 +313,11 @@ - (void)callBack:(MSDKDnsResolver *)resolver Info:(NSDictionary *)info { } else if (resolver && (resolver == self.httpDnsResolver_4A)) { [cacheDict setObject:info forKey:kMSDKHttpDnsInfo_4A]; - + + } else if (resolver && (resolver == self.httpDnsResolver_BOTH)) { + + [cacheDict setObject:info forKey:kMSDKHttpDnsInfo_BOTH]; + } if (cacheDict && domain) { @@ -253,20 +327,21 @@ - (void)callBack:(MSDKDnsResolver *)resolver Info:(NSDictionary *)info { MSDKDNSLOG(@"callBack! :%@", self.toCheckDomains); BOOL httpOnly = [[MSDKDnsParamsManager shareInstance] msdkDnsGetHttpOnly]; - //LocalHttp 和 HttpDns均完成,则返回结果 - if (httpOnly || self.localDnsResolver.isFinished) { - if (self.httpDnsResolver_A && self.httpDnsResolver_4A) { - if (self.httpDnsResolver_A.isFinished && self.httpDnsResolver_4A.isFinished) { - [self callNotify]; - } - } else if (self.httpDnsResolver_A && !self.httpDnsResolver_4A) { - if (self.httpDnsResolver_A.isFinished) { - [self callNotify]; - } - } else if (!self.httpDnsResolver_A && self.httpDnsResolver_4A) { - if (self.httpDnsResolver_4A.isFinished) { - [self callNotify]; - } + if (self.httpDnsResolver_A && self.httpDnsResolver_4A) { + if (self.httpDnsResolver_A.isFinished && self.httpDnsResolver_4A.isFinished) { + [self callNotify]; + } + } else if (self.httpDnsResolver_A && !self.httpDnsResolver_4A) { + if (self.httpDnsResolver_A.isFinished) { + [self callNotify]; + } + } else if (!self.httpDnsResolver_A && self.httpDnsResolver_4A) { + if (self.httpDnsResolver_4A.isFinished) { + [self callNotify]; + } + } else if (self.httpDnsResolver_BOTH) { + if (self.httpDnsResolver_BOTH.isFinished) { + [self callNotify]; } } } @@ -309,13 +384,25 @@ - (void)cacheDomainInfo:(MSDKDnsResolver *)resolver { if (cacheValue) { [cacheDict setObject:cacheValue forKey:kMSDKHttpDnsCache_4A]; } - + } else if (resolver && (resolver == self.localDnsResolver) && self.localDnsResolver.domainInfo) { NSDictionary *cacheValue = [self.localDnsResolver.domainInfo objectForKey:domain]; if (cacheValue) { [cacheDict setObject:cacheValue forKey:kMSDKLocalDnsCache]; } + } else if (resolver && (resolver == self.httpDnsResolver_BOTH) && self.httpDnsResolver_BOTH.domainInfo) { + NSDictionary *cacheValue = [self.httpDnsResolver_BOTH.domainInfo objectForKey:domain]; + if (cacheValue) { + NSDictionary *ipv4CacheValue = [cacheValue objectForKey:@"ipv4"]; + NSDictionary *ipv6CacheValue = [cacheValue objectForKey:@"ipv6"]; + if (ipv4CacheValue) { + [cacheDict setObject:ipv4CacheValue forKey:kMSDKHttpDnsCache_A]; + } + if (ipv6CacheValue) { + [cacheDict setObject:ipv6CacheValue forKey:kMSDKHttpDnsCache_4A]; + } + } } if (cacheDict && domain) { diff --git a/MSDKDns/Resolver/HttpsDnsResolver.m b/MSDKDns/Resolver/HttpsDnsResolver.m index 19699c0..2996fea 100644 --- a/MSDKDns/Resolver/HttpsDnsResolver.m +++ b/MSDKDns/Resolver/HttpsDnsResolver.m @@ -14,7 +14,7 @@ @interface HttpsDnsResolver() 1 ? [ipsStr substringFromIndex:ipsStr.length - 1] : @""; - if ([tempStr isEqualToString:@";"]) { - ipsStr = [ipsStr substringToIndex:ipsStr.length - 1]; - } - NSArray *ipsArray = [ipsStr componentsSeparatedByString:@";"]; - //校验ip合法性 - BOOL isIPLegal = [self isIPLegal:ipsArray Use4A:_use4A]; - - if (isIPLegal) { - double timeInterval = [[NSDate date] timeIntervalSince1970]; - NSString * ttlExpried = [NSString stringWithFormat:@"%0.0f", (timeInterval + ttl.floatValue * 0.75)]; - NSString * timeConsuming = [NSString stringWithFormat:@"%d", [self dnsTimeConsuming]]; - NSString * channel = @"http"; - return @{kIP:ipsArray, kClientIP:clientIP, kTTL:ttl, kTTLExpired:ttlExpried, kDnsTimeConsuming:timeConsuming, kChannel:channel}; - } + } + return nil; +} + +-(NSDictionary *)parseIPString:(NSString *)iPstring ClientIP:(NSString *)clientIP Use4A:(BOOL)use4A { + NSString *ipsStr = nil; + NSString *ttl = nil; + NSArray * tmpArr = [iPstring componentsSeparatedByString:@","]; + if (tmpArr && [tmpArr count] == 2) { + ipsStr = tmpArr[0]; + ttl = tmpArr[1]; + } + NSString * tempStr = ipsStr.length > 1 ? [ipsStr substringFromIndex:ipsStr.length - 1] : @""; + if ([tempStr isEqualToString:@";"]) { + ipsStr = [ipsStr substringToIndex:ipsStr.length - 1]; + } + NSArray *ipsArray = [ipsStr componentsSeparatedByString:@";"]; + //校验ip合法性 + BOOL isIPLegal = [self isIPLegal:ipsArray Use4A:use4A]; + + if (isIPLegal) { + double timeInterval = [[NSDate date] timeIntervalSince1970]; + NSString * ttlExpried = [NSString stringWithFormat:@"%0.0f", (timeInterval + ttl.floatValue * 0.75)]; + NSString * timeConsuming = [NSString stringWithFormat:@"%d", [self dnsTimeConsuming]]; + NSString * channel = @"http"; + return @{kIP:ipsArray, kClientIP:clientIP, kTTL:ttl, kTTLExpired:ttlExpried, kDnsTimeConsuming:timeConsuming, kChannel:channel}; } return nil; } diff --git a/MSDKDns/Resolver/MSDKDnsResolver.h b/MSDKDns/Resolver/MSDKDnsResolver.h index 1723c2f..36956de 100644 --- a/MSDKDns/Resolver/MSDKDnsResolver.h +++ b/MSDKDns/Resolver/MSDKDnsResolver.h @@ -6,6 +6,12 @@ #import "MSDKDnsPrivate.h" #import "msdkdns_local_ip_stack.h" +typedef enum { + HttpDnsTypeIPv4 = 1, // 只支持ipv4 + HttpDnsTypeIPv6 = 2, // 只支持ipv6 + HttpDnsTypeDual = 3, // 支持双协议栈 +} HttpDnsIPType; + @class MSDKDnsResolver; @protocol MSDKDnsResolverDelegate