Index: src/OFDNSResolver.h ================================================================== --- src/OFDNSResolver.h +++ src/OFDNSResolver.h @@ -23,10 +23,11 @@ OF_ASSUME_NONNULL_BEGIN #define OF_DNS_RESOLVER_BUFFER_LENGTH 512 @class OFArray OF_GENERIC(ObjectType); +@class OFDNSResolver; @class OFDNSResolverQuery; @class OFDate; @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); @class OFNumber; @@ -60,10 +61,57 @@ /*! The server does not have support for the requested query */ OF_DNS_RESOLVER_ERROR_SERVER_NOT_IMPLEMENTED, /*! The server refused the query */ OF_DNS_RESOLVER_ERROR_SERVER_REFUSED } of_dns_resolver_error_t; + +typedef OFDictionary OF_GENERIC(OFString *, + OFArray OF_GENERIC(OFDNSResourceRecord *) *) *of_dns_resolver_records_t; + +/*! + * @protocol OFDNSResolverDelegate OFDNSResolver.h ObjFW/OFDNSResolver.h + * + * @brief A delegate for OFDNSResolver. + */ +@protocol OFDNSResolverDelegate +@optional +/*! + * @brief This method is called when a DNS resolver resolved a domain name. + * + * @param resolver The acting resolver + * @param domainName The fully qualified domain name used to resolve the host + * @param answerRecords The answer records from the name server, grouped by + * domain name + * @param authorityRecords The authority records from the name server, grouped + * by domain name + * @param additionalRecords Additional records sent by the name server, grouped + * by domain name + * @param exception An exception that happened during resolving, or nil on + * success + */ +- (void)resolver: (OFDNSResolver *)resolver + didResolveDomainName: (OFString *)domainName + answerRecords: (nullable of_dns_resolver_records_t)answerRecords + authorityRecords: (nullable of_dns_resolver_records_t)authorityRecords + additionalRecords: (nullable of_dns_resolver_records_t)additionalRecords + exception: (nullable id)exception; + +/*! + * @brief This method is called when a DNS resolver resolved a domain name to + * socket addresses. + * + * @param resolver The acting resolver + * @param domainName The fully qualified domain name used to resolve the host + * @param socketAddresses OFData containing several of_socket_address_t + * @param exception The exception that occurred during resolving, or nil on + * success + */ +- (void)resolver: (OFDNSResolver *)resolver + didResolveDomainName: (OFString *)domainName + socketAddresses: (nullable OFData *)socketAddresses + exception: (nullable id)exception; +@end /*! * @class OFDNSResolver OFDNSResolver.h ObjFW/OFDNSResolver.h * * @brief A class for resolving DNS names. @@ -161,236 +209,80 @@ /*! * @brief Asynchronously resolves the specified host. * * @param host The host to resolve - * @param target The target to call with the result once resolving is done - * @param selector The selector to call on the target. The signature must be - * the following: - * @parblock - * - * void (OFDNSResolver *resolver, OFString *domainName, - * OFArray *> - * *_Nullable answerRecords, - * OFArray *> - * *_Nullable authorityRecords, - * OFArray *> - * *_Nullable additionalRecords, - * id _Nullable context, id _Nullable exception) - * - * `resolver` is the acting resolver.@n - * `domainName` is the fully qualified domain name used to - * resolve the host.@n - * `answerRecords` are the answer records from the name server, - * grouped by domain name. - * @n - * `authorityRecords` are the authority records from the name - * server, grouped by domain name.@n - * `additionalRecords` are additional records sent by the name - * server, grouped by domain name.@n - * `context` is the context object originally passed.@n - * `exception` is an exception that happened during resolving, - * otherwise nil. - * @endparblock - * @param context A context object to pass along to the target + * @param delegate The delegate to use for callbacks */ - (void)asyncResolveHost: (OFString *)host - target: (id)target - selector: (SEL)selector - context: (nullable id)context; + delegate: (id )delegate; /*! * @brief Asynchronously resolves the specified host. * * @param host The host to resolve * @param recordClass The desired class of the records to query * @param recordType The desired type of the records to query - * @param target The target to call with the result once resolving is done - * @param selector The selector to call on the target. The signature must be - * the following: - * @parblock - * - * void (OFDNSResolver *resolver, OFString *domainName, - * OFArray *> - * *_Nullable answerRecords, - * OFArray *> - * *_Nullable authorityRecords, - * OFArray *> - * *_Nullable additionalRecords, - * id _Nullable context, id _Nullable exception) - * - * `resolver` is the acting resolver.@n - * `domainName` is the fully qualified domain name used to - * resolve the host.@n - * `answerRecords` are the answer records from the name server, - * grouped by domain name. - * @n - * `authorityRecords` are the authority records from the name - * server, grouped by domain name.@n - * `additionalRecords` are additional records sent by the name - * server, grouped by domain name.@n - * `context` is the context object originally passed.@n - * `exception` is an exception that happened during resolving, - * otherwise nil. - * @endparblock - * @param context A context object to pass along to the target + * @param delegate The delegate to use for callbacks */ - (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: (nullable id)context; + delegate: (id )delegate; /*! * @brief Asynchronously resolves the specified host. * * @param host The host to resolve * @param recordClass The desired class of the records to query * @param recordType The desired type of the records to query * @param runLoopMode The run loop mode in which to resolve - * @param target The target to call with the result once resolving is done - * @param selector The selector to call on the target. The signature must be - * the following: - * @parblock - * - * void (OFDNSResolver *resolver, OFString *domainName, - * OFArray *> - * *_Nullable answerRecords, - * OFArray *> - * *_Nullable authorityRecords, - * OFArray *> - * *_Nullable additionalRecords, - * id _Nullable context, id _Nullable exception) - * - * `resolver` is the acting resolver.@n - * `domainName` is the fully qualified domain name used to - * resolve the host.@n - * `answerRecords` are the answer records from the name server, - * grouped by domain name. - * @n - * `authorityRecords` are the authority records from the name - * server, grouped by domain name.@n - * `additionalRecords` are additional records sent by the name - * server, grouped by domain name.@n - * `context` is the context object originally passed.@n - * `exception` is an exception that happened during resolving, - * otherwise nil. - * @endparblock - * @param context A context object to pass along to the target + * @param delegate The delegate to use for callbacks */ - (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: (nullable id)context; + delegate: (id )delegate; /*! * @brief Asynchronously resolves the specified host to socket addresses. * * @param host The host to resolve - * @param target The target to call with the result once resolving is done - * @param selector The selector to call on the target. The signature must be - * the following: - * @parblock - * - * void (OFDNSResolver *resolver, OFString *domainName, - * OFData *_Nullable, socketAddresses, - * id _Nullable context, id _Nullable exception) - * - * `resolver` is the acting resolver.@n - * `domainName` is the fully qualified domain name used to - * resolve the host.@n - * `socketAddresses` is OFData containing several - * of_socket_address_t.@n - * `context` is the context object originally passed.@n - * `exception` is an exception that happened during resolving, - * otherwise nil. - * @endparblock - * @param context A context object to pass along to the target + * @param delegate The delegate to use for callbacks */ - (void)asyncResolveSocketAddressesForHost: (OFString *)host - target: (id)target - selector: (SEL)selector - context: (nullable id)context; + delegate: (id ) + delegate; /*! * @brief Asynchronously resolves the specified host to socket addresses. * * @param host The host to resolve * @param addressFamily The desired socket address family - * @param target The target to call with the result once resolving is done - * @param selector The selector to call on the target. The signature must be - * the following: - * @parblock - * - * void (OFDNSResolver *resolver, OFString *domainName, - * OFData *_Nullable socketAddresses, - * id _Nullable context, id _Nullable exception) - * - * `resolver` is the acting resolver.@n - * `domainName` is the fully qualified domain name used to - * resolve the host.@n - * `socketAddresses` is OFData containing several - * of_socket_address_t.@n - * `context` is the context object originally passed.@n - * `exception` is an exception that happened during resolving, - * otherwise nil. - * @endparblock - * @param context A context object to pass along to the target + * @param delegate The delegate to use for callbacks */ - (void)asyncResolveSocketAddressesForHost: (OFString *)host addressFamily: (of_socket_address_family_t) addressFamily - target: (id)target - selector: (SEL)selector - context: (nullable id)context; + delegate: (id ) + delegate; /*! * @brief Asynchronously resolves the specified host to socket addresses. * * @param host The host to resolve * @param addressFamily The desired socket address family * @param runLoopMode The run loop mode in which to resolve - * @param target The target to call with the result once resolving is done - * @param selector The selector to call on the target. The signature must be - * the following: - * @parblock - * - * void (OFDNSResolver *resolver, OFString *domainName, - * OFData *_Nullable socketAddresses, - * id _Nullable context, id _Nullable exception) - * - * `resolver` is the acting resolver.@n - * `domainName` is the fully qualified domain name used to - * resolve the host.@n - * `socketAddresses` is OFData containing several - * of_socket_address_t.@n - * `context` is the context object originally passed.@n - * `exception` is an exception that happened during resolving, - * otherwise nil. - * @endparblock - * @param context A context object to pass along to the target + * @param delegate The delegate to use for callbacks */ - (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: (nullable id)context; + delegate: (id ) + delegate; /*! * @brief Synchronously resolves the specified host to socket addresses. * * @param host The host to resolve Index: src/OFDNSResolver.m ================================================================== --- src/OFDNSResolver.m +++ src/OFDNSResolver.m @@ -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]; } Index: src/OFTCPSocket.m ================================================================== --- src/OFTCPSocket.m +++ src/OFTCPSocket.m @@ -62,12 +62,12 @@ static of_run_loop_mode_t connectRunLoopMode = @"of_tcp_socket_connect_mode"; static OFString *defaultSOCKS5Host = nil; static uint16_t defaultSOCKS5Port = 1080; -@interface OFTCPSocket_AsyncConnectContext: OFObject +@interface OFTCPSocket_AsyncConnectDelegate: OFObject { OFTCPSocket *_socket; OFString *_host; uint16_t _port; OFString *_SOCKS5Host; @@ -106,15 +106,10 @@ SOCKS5Port: (uint16_t)SOCKS5Port block: (of_tcp_socket_async_connect_block_t)block; #endif - (void)didConnect; - (void)tryNextAddressWithRunLoopMode: (of_run_loop_mode_t)runLoopMode; -- (void)resolver: (OFDNSResolver *)resolver - didResolveDomainName: (OFString *)domainName - socketAddresses: (OFData *)socketAddresses - context: (id)context - exception: (id)exception; - (void)startWithRunLoopMode: (of_run_loop_mode_t)runLoopMode; - (void)sendSOCKS5Request; @end @interface OFTCPSocket_ConnectDelegate: OFObject @@ -123,11 +118,11 @@ bool _done; id _exception; } @end -@implementation OFTCPSocket_AsyncConnectContext +@implementation OFTCPSocket_AsyncConnectDelegate - (instancetype)initWithSocket: (OFTCPSocket *)sock host: (OFString *)host port: (uint16_t)port SOCKS5Host: (OFString *)SOCKS5Host SOCKS5Port: (uint16_t)SOCKS5Port @@ -302,11 +297,10 @@ } - (void)resolver: (OFDNSResolver *)resolver didResolveDomainName: (OFString *)domainName socketAddresses: (OFData *)socketAddresses - context: (id)context exception: (id)exception { if (exception != nil) { _exception = [exception retain]; [self didConnect]; @@ -351,16 +345,11 @@ [[OFThread DNSResolver] asyncResolveSocketAddressesForHost: host addressFamily: OF_SOCKET_ADDRESS_FAMILY_ANY runLoopMode: runLoopMode - target: self - selector: @selector(resolver: - didResolveDomainName: - socketAddresses:context: - exception:) - context: nil]; + delegate: self]; } - (void)sendSOCKS5Request { OFData *data = [OFData dataWithItems: "\x05\x01\x00" @@ -728,11 +717,11 @@ port: (uint16_t)port runLoopMode: (of_run_loop_mode_t)runLoopMode { void *pool = objc_autoreleasePoolPush(); - [[[[OFTCPSocket_AsyncConnectContext alloc] + [[[[OFTCPSocket_AsyncConnectDelegate alloc] initWithSocket: self host: host port: port SOCKS5Host: _SOCKS5Host SOCKS5Port: _SOCKS5Port @@ -758,11 +747,11 @@ runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_tcp_socket_async_connect_block_t)block { void *pool = objc_autoreleasePoolPush(); - [[[[OFTCPSocket_AsyncConnectContext alloc] + [[[[OFTCPSocket_AsyncConnectDelegate alloc] initWithSocket: self host: host port: port SOCKS5Host: _SOCKS5Host SOCKS5Port: _SOCKS5Port Index: utils/ofdns/OFDNS.m ================================================================== --- utils/ofdns/OFDNS.m +++ utils/ofdns/OFDNS.m @@ -21,22 +21,21 @@ #import "OFArray.h" #import "OFDNSResolver.h" #import "OFSandbox.h" #import "OFStdIOStream.h" -@interface OFDNS: OFObject +@interface OFDNS: OFObject @end OF_APPLICATION_DELEGATE(OFDNS) @implementation OFDNS -- (void)DNSResolver: (OFDNSResolver *)resolver +- (void)resolver: (OFDNSResolver *)resolver didResolveDomainName: (OFString *)domainName answerRecords: (OFArray *)answerRecords authorityRecords: (OFArray *)authorityRecords additionalRecords: (OFArray *)additionalRecords - context: (id)context exception: (id)exception { if (exception != nil) { [of_stderr writeFormat: @"Failed to resolve: %@\n", exception]; [OFApplication terminateWithStatus: 1]; @@ -97,12 +96,8 @@ } [resolver asyncResolveHost: [arguments objectAtIndex: 0] recordClass: recordClass recordType: recordType - target: self - selector: @selector(DNSResolver:didResolveDomainName: - answerRecords:authorityRecords: - additionalRecords:context:exception:) - context: nil]; + delegate: self]; } @end