@@ -230,14 +230,16 @@ recordClass: (of_dns_resource_record_class_t)recordClass recordType: (of_dns_resource_record_type_t)recordType settings: (OFDNSResolverSettings *)settings nameServersIndex: (size_t)nameServersIndex searchDomainsIndex: (size_t)searchDomainsIndex + runLoopMode: (of_run_loop_mode_t)runLoopMode target: (id)target selector: (SEL)selector context: (id)context; -- (void)of_sendQuery: (OFDNSResolverQuery *)query; +- (void)of_sendQuery: (OFDNSResolverQuery *)query + runLoopMode: (of_run_loop_mode_t)runLoopMode; - (void)of_queryWithIDTimedOut: (OFDNSResolverQuery *)query; - (size_t)of_socket: (OFUDPSocket *)sock didSendBuffer: (void **)buffer bytesSent: (size_t)bytesSent receiver: (of_socket_address_t *)receiver @@ -915,21 +917,25 @@ recursion: recursion - 1 result: result]) found = true; if (!found) { + of_run_loop_mode_t runLoopMode = + [[OFRunLoop currentRunLoop] currentMode]; OFNumber *recordTypeNumber = [OFNumber numberWithInt: recordType]; + _expectedResponses++; [result addObject: [OFPair pairWithFirstObject: CNAME secondObject: recordTypeNumber]]; [_resolver asyncResolveHost: alias recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN recordType: recordType + runLoopMode: runLoopMode target: self selector: @selector(resolver: didResolveCNAME: answerRecords:authorityRecords: additionalRecords:context: @@ -1589,29 +1595,17 @@ _lastConfigReload = nil; [self of_obtainSystemConfig]; } -- (void)asyncResolveHost: (OFString *)host - target: (id)target - selector: (SEL)selector - context: (id)context -{ - [self asyncResolveHost: host - recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN - recordType: OF_DNS_RESOURCE_RECORD_TYPE_ALL - target: target - selector: selector - context: context]; -} - - (void)of_resolveHost: (OFString *)host recordClass: (of_dns_resource_record_class_t)recordClass recordType: (of_dns_resource_record_type_t)recordType settings: (OFDNSResolverSettings *)settings nameServersIndex: (size_t)nameServersIndex searchDomainsIndex: (size_t)searchDomainsIndex + runLoopMode: (of_run_loop_mode_t)runLoopMode target: (id)target selector: (SEL)selector context: (id)context { void *pool = objc_autoreleasePoolPush(); @@ -1655,18 +1649,50 @@ selector: selector context: context] autorelease]; [_queries setObject: query forKey: ID]; - [self of_sendQuery: query]; + [self of_sendQuery: query + runLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } + +- (void)asyncResolveHost: (OFString *)host + target: (id)target + selector: (SEL)selector + context: (id)context +{ + [self asyncResolveHost: host + recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN + recordType: OF_DNS_RESOURCE_RECORD_TYPE_ALL + runLoopMode: of_run_loop_mode_default + target: target + selector: selector + context: context]; +} + +- (void)asyncResolveHost: (OFString *)host + recordClass: (of_dns_resource_record_class_t)recordClass + recordType: (of_dns_resource_record_type_t)recordType + target: (id)target + selector: (SEL)selector + context: (id)context +{ + [self asyncResolveHost: host + recordClass: recordClass + recordType: recordType + runLoopMode: of_run_loop_mode_default + target: target + selector: selector + context: context]; +} - (void)asyncResolveHost: (OFString *)host recordClass: (of_dns_resource_record_class_t)recordClass recordType: (of_dns_resource_record_type_t)recordType + runLoopMode: (of_run_loop_mode_t)runLoopMode target: (id)target selector: (SEL)selector context: (id)context { void *pool = objc_autoreleasePoolPush(); @@ -1682,31 +1708,37 @@ recordClass: recordClass recordType: recordType settings: settings nameServersIndex: 0 searchDomainsIndex: 0 + runLoopMode: runLoopMode target: target selector: selector context: context]; objc_autoreleasePoolPop(pool); } - (void)of_sendQuery: (OFDNSResolverQuery *)query + runLoopMode: (of_run_loop_mode_t)runLoopMode { OFUDPSocket *sock; OFString *nameServer; [query->_cancelTimer invalidate]; [query->_cancelTimer release]; query->_cancelTimer = nil; - query->_cancelTimer = [[OFTimer - scheduledTimerWithTimeInterval: query->_settings->_timeout - target: self - selector: @selector(of_queryWithIDTimedOut:) - object: query - repeats: false] retain]; + query->_cancelTimer = [[OFTimer alloc] + initWithFireDate: [OFDate dateWithTimeIntervalSinceNow: + query->_settings->_timeout] + interval: query->_settings->_timeout + target: self + selector: @selector(of_queryWithIDTimedOut:) + object: query + repeats: false]; + [[OFRunLoop currentRunLoop] addTimer: query->_cancelTimer + forMode: runLoopMode]; nameServer = [query->_settings->_nameServers objectAtIndex: query->_nameServersIndex]; query->_usedNameServer = of_socket_address_parse_ip(nameServer, 53); @@ -1738,10 +1770,11 @@ } [sock asyncSendBuffer: [query->_queryData items] length: [query->_queryData count] receiver: query->_usedNameServer + runLoopMode: runLoopMode target: self selector: @selector(of_socket:didSendBuffer:bytesSent: receiver:context:exception:) context: query]; } @@ -1754,18 +1787,20 @@ return; if (query->_nameServersIndex + 1 < [query->_settings->_nameServers count]) { query->_nameServersIndex++; - [self of_sendQuery: query]; + [self of_sendQuery: query + runLoopMode: [[OFRunLoop currentRunLoop] currentMode]]; return; } if (query->_attempt < query->_settings->_maxAttempts) { query->_attempt++; query->_nameServersIndex = 0; - [self of_sendQuery: query]; + [self of_sendQuery: query + runLoopMode: [[OFRunLoop currentRunLoop] currentMode]]; return; } query = [[query retain] autorelease]; [_queries removeObjectForKey: query->_ID]; @@ -1798,10 +1833,11 @@ return 0; } [sock asyncReceiveIntoBuffer: [query allocMemoryWithSize: 512] length: 512 + runLoopMode: [[OFRunLoop currentRunLoop] currentMode] target: self selector: @selector(of_socket:didReceiveIntoBuffer: length:sender:context:exception:) context: nil]; @@ -1884,18 +1920,22 @@ error = OF_DNS_RESOLVER_ERROR_SERVER_FAILURE; break; case 3: if (query->_searchDomainsIndex + 1 < [query->_settings->_searchDomains count]) { + of_run_loop_mode_t runLoopMode = + [[OFRunLoop currentRunLoop] currentMode]; + query->_searchDomainsIndex++; [self of_resolveHost: query->_host recordClass: query->_recordClass recordType: query->_recordType settings: query->_settings nameServersIndex: query->_nameServersIndex searchDomainsIndex: query->_searchDomainsIndex + runLoopMode: runLoopMode target: query->_target selector: query->_selector context: query->_context]; return false; @@ -1958,30 +1998,39 @@ } - (void)asyncResolveSocketAddressesForHost: (OFString *)host target: (id)target selector: (SEL)selector - context: (nullable id)context + context: (id)context { -#ifdef OF_HAVE_IPV6 [self asyncResolveSocketAddressesForHost: host addressFamily: OF_SOCKET_ADDRESS_FAMILY_ANY + runLoopMode: of_run_loop_mode_default target: target selector: selector context: context]; -#else +} + +- (void)asyncResolveSocketAddressesForHost: (OFString *)host + addressFamily: (of_socket_address_family_t) + addressFamily + target: (id)target + selector: (SEL)selector + context: (id)context +{ [self asyncResolveSocketAddressesForHost: host - addressFamily: OF_SOCKET_ADDRESS_FAMILY_IPV4 + addressFamily: addressFamily + runLoopMode: of_run_loop_mode_default target: target selector: selector context: context]; -#endif } - (void)asyncResolveSocketAddressesForHost: (OFString *)host addressFamily: (of_socket_address_family_t) addressFamily + runLoopMode: (of_run_loop_mode_t)runLoopMode target: (id)target selector: (SEL)selector context: (id)userContext { void *pool = objc_autoreleasePoolPush(); @@ -1993,38 +2042,48 @@ selector: selector context: userContext] autorelease]; switch (addressFamily) { case OF_SOCKET_ADDRESS_FAMILY_IPV4: +#ifdef OF_HAVE_IPV6 case OF_SOCKET_ADDRESS_FAMILY_IPV6: +#endif context->_expectedResponses = 1; break; case OF_SOCKET_ADDRESS_FAMILY_ANY: +#ifdef OF_HAVE_IPV6 context->_expectedResponses = 2; +#else + context->_expectedResponses = 1; +#endif break; default: @throw [OFInvalidArgumentException exception]; } +#ifdef OF_HAVE_IPV6 if (addressFamily == OF_SOCKET_ADDRESS_FAMILY_IPV6 || addressFamily == OF_SOCKET_ADDRESS_FAMILY_ANY) [self asyncResolveHost: host recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN recordType: OF_DNS_RESOURCE_RECORD_TYPE_AAAA + runLoopMode: runLoopMode target: context selector: @selector(resolver:didResolveDomainName: answerRecords:authorityRecords: additionalRecords:context: exception:) context: [OFNumber numberWithInt: OF_DNS_RESOURCE_RECORD_TYPE_AAAA]]; +#endif if (addressFamily == OF_SOCKET_ADDRESS_FAMILY_IPV4 || addressFamily == OF_SOCKET_ADDRESS_FAMILY_ANY) [self asyncResolveHost: host recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN recordType: OF_DNS_RESOURCE_RECORD_TYPE_A + runLoopMode: runLoopMode target: context selector: @selector(resolver:didResolveDomainName: answerRecords:authorityRecords: additionalRecords:context: exception:)