@@ -170,24 +170,20 @@ @end @interface OFDNSResolver_AsyncResolveSocketAddressesContext: OFObject { OFString *_host; - id _target; - SEL _selector; - id _context; + id _delegate; OFMutableArray OF_GENERIC(OF_KINDOF(OFDNSResourceRecord *)) *_records; OFDNSResolver *_resolver; OFString *_domainName; @public unsigned int _expectedResponses; } - (instancetype)initWithHost: (OFString *)host - target: (id)target - selector: (SEL)selector - context: (id)context; + delegate: (id)delegate; - (bool)parseRecords: (OFArray *)records answerRecords: (OFDictionary *)answerRecords additionalRecords: (OFDictionary *)additionalRecords recordType: (of_dns_resource_record_type_t)recordType recursion: (unsigned int)recursion @@ -213,23 +209,18 @@ additionalRecords: (OFDictionary *)additionalRecords context: (id)context exception: (id)exception; @end -@interface OFDNSResolver_ResolveSocketAddressesContext: OFObject +@interface OFDNSResolver_ResolveSocketAddressesDelegate: OFObject + { @public bool _done; OFData *_socketAddresses; id _exception; } - -- (void)resolver: (OFDNSResolver *)resolver - didResolveDomainName: (OFString *)domainName - socketAddresses: (OFData *)socketAddresses - context: (id)context - exception: (id)exception; @end @interface OFDNSResolver () - (void)of_setDefaults; - (void)of_obtainSystemConfig; @@ -258,10 +249,17 @@ searchDomainsIndex: (size_t)searchDomainsIndex runLoopMode: (of_run_loop_mode_t)runLoopMode target: (id)target selector: (SEL)selector context: (id)context; +- (void)of_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)of_sendQuery: (OFDNSResolverQuery *)query runLoopMode: (of_run_loop_mode_t)runLoopMode; - (void)of_queryWithIDTimedOut: (OFDNSResolverQuery *)query; @end @@ -835,21 +833,17 @@ } @end @implementation OFDNSResolver_AsyncResolveSocketAddressesContext - (instancetype)initWithHost: (OFString *)host - target: (id)target - selector: (SEL)selector - context: (id)context + delegate: (id)delegate { self = [super init]; @try { _host = [host copy]; - _target = [target retain]; - _selector = selector; - _context = [context retain]; + _delegate = [delegate retain]; _records = [[OFMutableArray alloc] init]; } @catch (id e) { [self release]; @throw e; @@ -859,12 +853,11 @@ } - (void)dealloc { [_host release]; - [_target release]; - [_context release]; + [_delegate release]; [_records release]; [_resolver release]; [_domainName release]; [super dealloc]; @@ -940,21 +933,22 @@ [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: - exception:) - context: recordTypeNumber]; + [_resolver of_asyncResolveHost: alias + recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN + recordType: recordType + runLoopMode: runLoopMode + target: self + selector: @selector(resolver: + didResolveCNAME: + answerRecords: + authorityRecords: + additionalRecords:context: + exception:) + context: recordTypeNumber]; } } - (void)resolver: (OFDNSResolver *)resolver didResolveCNAME: (OFString *)CNAME @@ -1033,15 +1027,13 @@ [self done]; } - (void)done { - void (*method)(id, SEL, OFDNSResolver *, OFString *, OFData *, id, id) = - (void (*)(id, SEL, OFDNSResolver *, OFString *, OFData *, id, id)) - [_target methodForSelector: _selector]; OFMutableData *addresses = [OFMutableData dataWithItemSize: sizeof(of_socket_address_t)]; + id exception = nil; for (id record in _records) { if (![record isKindOfClass: [OFDNSResourceRecord class]]) continue; @@ -1055,25 +1047,23 @@ } } [addresses makeImmutable]; - if ([addresses count] > 0) - method(_target, _selector, _resolver, _domainName, addresses, - _context, nil); - else { - OFResolveHostFailedException *e; - - e = [OFResolveHostFailedException + if ([addresses count] == 0) + exception = [OFResolveHostFailedException exceptionWithHost: _host recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN recordType: 0 error: OF_DNS_RESOLVER_ERROR_UNKNOWN]; - method(_target, _selector, _resolver, _domainName, nil, - _context, e); - } + if ([_delegate respondsToSelector: @selector( + resolver:didResolveDomainName:socketAddresses:exception:)]) + [_delegate resolver: _resolver + didResolveDomainName: _domainName + socketAddresses: (exception == nil ? addresses : nil) + exception: exception]; } - (void)resolver: (OFDNSResolver *)resolver didResolveDomainName: (OFString *)domainName answerRecords: (OFDictionary *)answerRecords @@ -1120,11 +1110,11 @@ if (_expectedResponses == 0) [self done]; } @end -@implementation OFDNSResolver_ResolveSocketAddressesContext +@implementation OFDNSResolver_ResolveSocketAddressesDelegate - (void)dealloc { [_socketAddresses release]; [_exception release]; @@ -1132,11 +1122,10 @@ } - (void)resolver: (OFDNSResolver *)resolver didResolveDomainName: (OFString *)domainName socketAddresses: (OFData *)socketAddresses - context: (id)context exception: (id)exception { _socketAddresses = [socketAddresses retain]; _exception = [exception retain]; _done = true; @@ -1685,48 +1674,84 @@ [self of_sendQuery: query runLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } + +- (void)of_resolver: (OFDNSResolver *)resolver + didResolveDomainName: (OFString *)domainName + answerRecords: (of_dns_resolver_records_t)answerRecords + authorityRecords: (of_dns_resolver_records_t)authorityRecords + additionalRecords: (of_dns_resolver_records_t)additionalRecords + context: (id)delegate + exception: (id)exception +{ + if ([delegate respondsToSelector: @selector(resolver: + didResolveDomainName:answerRecords:authorityRecords: + additionalRecords:exception:)]) + [delegate resolver: resolver + didResolveDomainName: domainName + answerRecords: answerRecords + authorityRecords: authorityRecords + additionalRecords: additionalRecords + exception: exception]; +} - (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]; + delegate: (id )delegate +{ + [self of_asyncResolveHost: host + recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN + recordType: OF_DNS_RESOURCE_RECORD_TYPE_ALL + runLoopMode: of_run_loop_mode_default + target: self + selector: @selector(of_resolver:didResolveDomainName: + answerRecords:authorityRecords: + additionalRecords:context:exception:) + context: delegate]; } - (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]; + delegate: (id )delegate +{ + [self of_asyncResolveHost: host + recordClass: recordClass + recordType: recordType + runLoopMode: of_run_loop_mode_default + target: self + selector: @selector(of_resolver:didResolveDomainName: + answerRecords:authorityRecords: + additionalRecords:context:exception:) + context: delegate]; } - (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 + delegate: (id )delegate +{ + [self of_asyncResolveHost: host + recordClass: recordClass + recordType: recordType + runLoopMode: runLoopMode + target: self + selector: @selector(of_resolver:didResolveDomainName: + answerRecords:authorityRecords: + additionalRecords:context:exception:) + context: delegate]; +} + +- (void)of_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(); OFDNSResolverSettings *settings = [[[OFDNSResolverSettings alloc] initWithNameServers: _nameServers searchDomains: _searchDomains @@ -2014,77 +2039,75 @@ return true; } - (void)asyncResolveSocketAddressesForHost: (OFString *)host - target: (id)target - selector: (SEL)selector - context: (id)context + delegate: (id )delegate { [self asyncResolveSocketAddressesForHost: host addressFamily: OF_SOCKET_ADDRESS_FAMILY_ANY runLoopMode: of_run_loop_mode_default - target: target - selector: selector - context: context]; + delegate: delegate]; } - (void)asyncResolveSocketAddressesForHost: (OFString *)host addressFamily: (of_socket_address_family_t) addressFamily - target: (id)target - selector: (SEL)selector - context: (id)context + delegate: (id )delegate { [self asyncResolveSocketAddressesForHost: host addressFamily: addressFamily runLoopMode: of_run_loop_mode_default - target: target - selector: selector - context: context]; + delegate: delegate]; } - (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 + delegate: (id )delegate { OFArray OF_GENERIC(OFString *) *aliases; void *pool; OFDNSResolver_AsyncResolveSocketAddressesContext *context; @try { of_socket_address_t address = of_socket_address_parse_ip(host, 0); - void (*method)(id, SEL, OFDNSResolver *, OFString *, OFData *, - id, id) = (void (*)(id, SEL, OFDNSResolver *, OFString *, - OFData *, id, id))[target methodForSelector: selector]; OFData *addresses; if (addressFamily != OF_SOCKET_ADDRESS_FAMILY_ANY && address.family != addressFamily) { - method(target, selector, self, host, nil, userContext, - [OFInvalidArgumentException exception]); + if ([delegate respondsToSelector: @selector(resolver: + didResolveDomainName:socketAddresses:exception:)]) { + OFInvalidArgumentException *exception = + [OFInvalidArgumentException exception]; + + [delegate resolver: self + didResolveDomainName: host + socketAddresses: nil + exception: exception]; + } return; } addresses = [OFData dataWithItems: &address - itemSize: sizeof(address) - count: 1]; - method(target, selector, self, host, addresses, userContext, - nil); + itemSize: sizeof(address) + count: 1]; + + if ([delegate respondsToSelector: @selector(resolver: + didResolveDomainName:socketAddresses:exception:)]) + [delegate resolver: self + didResolveDomainName: host + socketAddresses: addresses + exception: nil]; + return; } @catch (OFInvalidFormatException *e) { } if ((aliases = [_staticHosts objectForKey: host]) != nil) { - void (*method)(id, SEL, OFDNSResolver *, OFString *, OFData *, - id, id) = (void (*)(id, SEL, OFDNSResolver *, OFString *, - OFData *, id, id))[target methodForSelector: selector]; OFMutableData *addresses = [OFMutableData dataWithItemSize: sizeof(of_socket_address_t)]; for (OFString *alias in aliases) { of_socket_address_t address; @@ -2103,52 +2126,65 @@ } [addresses makeImmutable]; if ([addresses count] == 0) { - OFResolveHostFailedException *exception; - of_dns_resource_record_type_t type; + id exception = nil; + of_dns_resource_record_type_t recordType; switch (addressFamily) { case OF_SOCKET_ADDRESS_FAMILY_ANY: - type = OF_DNS_RESOURCE_RECORD_TYPE_ALL; + recordType = OF_DNS_RESOURCE_RECORD_TYPE_ALL; break; case OF_SOCKET_ADDRESS_FAMILY_IPV4: - type = OF_DNS_RESOURCE_RECORD_TYPE_A; + recordType = OF_DNS_RESOURCE_RECORD_TYPE_A; break; case OF_SOCKET_ADDRESS_FAMILY_IPV6: - type = OF_DNS_RESOURCE_RECORD_TYPE_AAAA; + recordType = OF_DNS_RESOURCE_RECORD_TYPE_AAAA; break; default: - method(target, selector, self, host, nil, - userContext, - [OFInvalidArgumentException exception]); - return; - } - - exception = [OFResolveHostFailedException - exceptionWithHost: host - recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN - recordType: type - error: OF_DNS_RESOLVER_ERROR_NO_RESULT]; - method(target, selector, self, host, nil, userContext, - exception); - return; - } - - method(target, selector, self, host, addresses, userContext, - nil); + exception = + [OFInvalidArgumentException exception]; + break; + } + + if (exception == nil) { + of_dns_resource_record_class_t recordClass = + OF_DNS_RESOURCE_RECORD_CLASS_IN; + of_dns_resolver_error_t error = + OF_DNS_RESOLVER_ERROR_NO_RESULT; + + exception = [OFResolveHostFailedException + exceptionWithHost: host + recordClass: recordClass + recordType: recordType + error: error]; + } + + if ([delegate respondsToSelector: @selector(resolver: + didResolveDomainName:socketAddresses:exception:)]) + [delegate resolver: self + didResolveDomainName: host + socketAddresses: nil + exception: exception]; + } + + if ([delegate respondsToSelector: @selector(resolver: + didResolveDomainName:socketAddresses:exception:)]) + [delegate resolver: self + didResolveDomainName: host + socketAddresses: addresses + exception: nil]; + return; } pool = objc_autoreleasePoolPush(); context = [[[OFDNSResolver_AsyncResolveSocketAddressesContext alloc] initWithHost: host - target: target - selector: selector - context: userContext] autorelease]; + delegate: delegate] autorelease]; switch (addressFamily) { case OF_SOCKET_ADDRESS_FAMILY_IPV4: #ifdef OF_HAVE_IPV6 case OF_SOCKET_ADDRESS_FAMILY_IPV6: @@ -2166,37 +2202,42 @@ @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]]; + addressFamily == OF_SOCKET_ADDRESS_FAMILY_ANY) { + OFNumber *recordTypeNumber = + [OFNumber numberWithInt: OF_DNS_RESOURCE_RECORD_TYPE_AAAA]; + + [self of_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: recordTypeNumber]; + } #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:) - context: [OFNumber numberWithInt: - OF_DNS_RESOURCE_RECORD_TYPE_A]]; + [self of_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:) + context: [OFNumber numberWithInt: + OF_DNS_RESOURCE_RECORD_TYPE_A]]; objc_autoreleasePoolPop(pool); } - (OFData *)resolveSocketAddressesForHost: (OFString *)host @@ -2203,38 +2244,33 @@ addressFamily: (of_socket_address_family_t) addressFamily { void *pool = objc_autoreleasePoolPush(); OFRunLoop *runLoop = [OFRunLoop currentRunLoop]; - OFDNSResolver_ResolveSocketAddressesContext *context; + OFDNSResolver_ResolveSocketAddressesDelegate *delegate; OFData *ret; - context = [[[OFDNSResolver_ResolveSocketAddressesContext + delegate = [[[OFDNSResolver_ResolveSocketAddressesDelegate alloc] init] autorelease]; [self asyncResolveSocketAddressesForHost: host addressFamily: addressFamily runLoopMode: resolveRunLoopMode - target: context - selector: @selector(resolver: - didResolveDomainName: - socketAddresses:context: - exception:) - context: nil]; - - while (!context->_done) + delegate: delegate]; + + while (!delegate->_done) [runLoop runMode: resolveRunLoopMode beforeDate: nil]; /* Cleanup */ [runLoop runMode: resolveRunLoopMode beforeDate: [OFDate date]]; - if (context->_exception != nil) - @throw context->_exception; + if (delegate->_exception != nil) + @throw delegate->_exception; - ret = [context->_socketAddresses retain]; + ret = [delegate->_socketAddresses retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; }