@@ -111,10 +111,12 @@ * TODO: * * - Fallback to TCP */ +static of_run_loop_mode_t resolveRunLoopMode = @"of_dns_resolver_resolve_mode"; + @interface OFDNSResolverSettings: OFObject { @public OFArray OF_GENERIC(OFString *) *_nameServers, *_searchDomains; of_time_interval_t _timeout; @@ -158,11 +160,11 @@ target: (id)target selector: (SEL)selector context: (id)context; @end -@interface OFDNSResolver_ResolveSocketAddressContext: OFObject +@interface OFDNSResolver_AsyncResolveSocketAddressesContext: OFObject { OFString *_host; id _target; SEL _selector; id _context; @@ -203,10 +205,25 @@ authorityRecords: (OFDictionary *)authorityRecords additionalRecords: (OFDictionary *)additionalRecords context: (id)context exception: (id)exception; @end + +@interface OFDNSResolver_ResolveSocketAddressesContext: 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; #if defined(OF_HAVE_FILES) && !defined(OF_NINTENDO_3DS) @@ -821,11 +838,11 @@ [super dealloc]; } @end -@implementation OFDNSResolver_ResolveSocketAddressContext +@implementation OFDNSResolver_AsyncResolveSocketAddressesContext - (instancetype)initWithHost: (OFString *)host target: (id)target selector: (SEL)selector context: (id)context { @@ -1107,10 +1124,31 @@ if (_expectedResponses == 0) [self done]; } @end + +@implementation OFDNSResolver_ResolveSocketAddressesContext +- (void)dealloc +{ + [_socketAddresses release]; + [_exception release]; + + [super dealloc]; +} + +- (void)resolver: (OFDNSResolver *)resolver + didResolveDomainName: (OFString *)domainName + socketAddresses: (OFData *)socketAddresses + context: (id)context + exception: (id)exception +{ + _socketAddresses = [socketAddresses retain]; + _exception = [exception retain]; + _done = true; +} +@end @implementation OFDNSResolver @synthesize staticHosts = _staticHosts, nameServers = _nameServers; @synthesize localDomain = _localDomain, searchDomains = _searchDomains; @synthesize timeout = _timeout, maxAttempts = _maxAttempts; @@ -2032,13 +2070,13 @@ target: (id)target selector: (SEL)selector context: (id)userContext { void *pool = objc_autoreleasePoolPush(); - OFDNSResolver_ResolveSocketAddressContext *context; + OFDNSResolver_AsyncResolveSocketAddressesContext *context; - context = [[[OFDNSResolver_ResolveSocketAddressContext alloc] + context = [[[OFDNSResolver_AsyncResolveSocketAddressesContext alloc] initWithHost: host target: target selector: selector context: userContext] autorelease]; @@ -2090,10 +2128,50 @@ context: [OFNumber numberWithInt: OF_DNS_RESOURCE_RECORD_TYPE_A]]; objc_autoreleasePoolPop(pool); } + +- (OFData *)resolveSocketAddressesForHost: (OFString *)host + addressFamily: (of_socket_address_family_t) + addressFamily +{ + void *pool = objc_autoreleasePoolPush(); + OFRunLoop *runLoop = [OFRunLoop currentRunLoop]; + OFDNSResolver_ResolveSocketAddressesContext *context; + OFData *ret; + + context = [[[OFDNSResolver_ResolveSocketAddressesContext + alloc] init] autorelease]; + + [self asyncResolveSocketAddressesForHost: host + addressFamily: addressFamily + runLoopMode: resolveRunLoopMode + target: context + selector: @selector(resolver: + didResolveDomainName: + socketAddresses:context: + exception:) + context: nil]; + + while (!context->_done) + [runLoop runMode: resolveRunLoopMode + beforeDate: nil]; + + /* Cleanup */ + [runLoop runMode: resolveRunLoopMode + beforeDate: [OFDate date]]; + + if (context->_exception != nil) + @throw context->_exception; + + ret = [context->_socketAddresses retain]; + + objc_autoreleasePoolPop(pool); + + return [ret autorelease]; +} - (void)close { void *pool = objc_autoreleasePoolPush(); OFEnumerator OF_GENERIC(OFDNSResolverQuery *) *enumerator;