Index: src/OFDNSResolver.h ================================================================== --- src/OFDNSResolver.h +++ src/OFDNSResolver.h @@ -23,10 +23,11 @@ @class OFArray OF_GENERIC(ObjectType); @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); @class OFNumber; +@class OFUDPSocket; /*! * @class OFDNSResolver OFDNSResolver.h ObjFW/OFDNSResolver.h * * @brief A class for resolving DNS names. @@ -38,10 +39,14 @@ OFArray OF_GENERIC(OFString *) *_nameServers; OFString *_Nullable _localDomain; OFArray OF_GENERIC(OFString *) *_searchDomains; size_t _minNumberOfDotsInAbsoluteName; bool _usesTCP; + OFUDPSocket *_IPv4Socket; +#ifdef OF_HAVE_IPV6 + OFUDPSocket *_IPv6Socket; +#endif OFMutableDictionary OF_GENERIC(OFNumber *, id) *_queries; } /*! * @brief A dictionary of static hosts. Index: src/OFDNSResolver.m ================================================================== --- src/OFDNSResolver.m +++ src/OFDNSResolver.m @@ -58,13 +58,11 @@ * TODO: * * - Timeouts * - Resolve with each search domain * - Iterate through name servers - * - IPv6 for talking to the name servers * - Fallback to TCP - * - More record types */ @interface OFDNSResolver_context: OFObject { OFString *_host; @@ -636,15 +634,21 @@ return self; } - (void)dealloc { + [self close]; + [_staticHosts release]; [_nameServers release]; [_localDomain release]; [_searchDomains release]; [_queries release]; + [_IPv4Socket release]; +#ifdef OF_HAVE_IPV6 + [_IPv6Socket release]; +#endif [super dealloc]; } #ifdef OF_HAVE_FILES @@ -1105,16 +1109,34 @@ selector: selector userContext: context] autorelease]; [_queries setObject: DNSResolverContext forKey: ID]; - sock = [OFUDPSocket socket]; - [sock bindToHost: @"0.0.0.0" - port: 0]; - address = of_socket_address_parse_ip( [[DNSResolverContext nameServers] firstObject], 53); + +#ifdef OF_HAVE_IPV6 + if (address.address.ss_family == AF_INET6) { + if (_IPv6Socket == nil) { + _IPv6Socket = [[OFUDPSocket alloc] init]; + [_IPv6Socket bindToHost: @"::" + port: 0]; + } + + sock = _IPv6Socket; + } else { +#endif + if (_IPv4Socket == nil) { + _IPv4Socket = [[OFUDPSocket alloc] init]; + [_IPv4Socket bindToHost: @"0.0.0.0" + port: 0]; + } + + sock = _IPv4Socket; +#ifdef OF_HAVE_IPV6 + } +#endif [sock asyncSendBuffer: [data items] length: [data count] receiver: address target: self @@ -1122,6 +1144,21 @@ receiver:context:exception:) context: nil]; objc_autoreleasePoolPop(pool); } + +- (void)close +{ + [_IPv4Socket cancelAsyncRequests]; + [_IPv4Socket close]; + [_IPv4Socket release]; + _IPv4Socket = nil; + +#ifdef OF_HAVE_IPV6 + [_IPv6Socket cancelAsyncRequests]; + [_IPv6Socket close]; + [_IPv6Socket release]; + _IPv6Socket = nil; +#endif +} @end