@@ -172,13 +172,13 @@ target: (id)target selector: (SEL)selector context: (id)context; - (void)resolver: (OFDNSResolver *)resolver didResolveDomainName: (OFString *)domainName - answerRecords: (OFArray *)answerRecords - authorityRecords: (OFArray *)authorityRecords - additionalRecords: (OFArray *)additionalRecords + answerRecords: (OFDictionary *)answerRecords + authorityRecords: (OFDictionary *)authorityRecords + additionalRecords: (OFDictionary *)additionalRecords context: (id)context exception: (id)exception; @end @interface OFDNSResolver () @@ -585,15 +585,17 @@ recordClass: recordClass recordType: recordType TTL: TTL] autorelease]; } -static OFArray * +static OFDictionary * parseSection(const unsigned char *buffer, size_t length, size_t *i, uint_fast16_t count) { - OFMutableArray *ret = [OFMutableArray array]; + OFMutableDictionary *ret = [OFMutableDictionary dictionary]; + OFEnumerator OF_GENERIC(OFMutableArray *) *objectEnumerator; + OFMutableArray *array; for (uint_fast16_t j = 0; j < count; j++) { OFString *name = parseName(buffer, length, i, MAX_ALLOWED_POINTERS); of_dns_resource_record_class_t recordClass; @@ -618,26 +620,39 @@ record = parseResourceRecord(name, recordClass, recordType, TTL, buffer, length, *i, dataLength); *i += dataLength; - [ret addObject: record]; + array = [ret objectForKey: name]; + + if (array == nil) { + array = [OFMutableArray array]; + [ret setObject: array + forKey: name]; + } + + [array addObject: record]; } + + objectEnumerator = [ret objectEnumerator]; + while ((array = [objectEnumerator nextObject]) != nil) + [array makeImmutable]; [ret makeImmutable]; return ret; } static void callback(id target, SEL selector, OFDNSResolver *resolver, - OFString *domainName, OFArray *answerRecords, OFArray *authorityRecords, - OFArray *additionalRecords, id context, id exception) + OFString *domainName, OFDictionary *answerRecords, + OFDictionary *authorityRecords, OFDictionary *additionalRecords, id context, + id exception) { - void (*method)(id, SEL, OFDNSResolver *, OFString *, OFArray *, - OFArray *, OFArray *, id, id) = (void (*)(id, SEL, OFDNSResolver *, - OFString *, OFArray *, OFArray *, OFArray *, id, id)) - [target methodForSelector: selector]; + void (*method)(id, SEL, OFDNSResolver *, OFString *, OFDictionary *, + OFDictionary *, OFDictionary *, id, id) = (void (*)(id, SEL, + OFDNSResolver *, OFString *, OFDictionary *, OFDictionary *, + OFDictionary *, id, id))[target methodForSelector: selector]; method(target, selector, resolver, domainName, answerRecords, authorityRecords, additionalRecords, context, exception); } @@ -814,13 +829,13 @@ [super dealloc]; } - (void)resolver: (OFDNSResolver *)resolver didResolveDomainName: (OFString *)domainName - answerRecords: (OFArray *)answerRecords - authorityRecords: (OFArray *)authorityRecords - additionalRecords: (OFArray *)additionalRecords + answerRecords: (OFDictionary *)answerRecords + authorityRecords: (OFDictionary *)authorityRecords + additionalRecords: (OFDictionary *)additionalRecords context: (id)context exception: (id)exception { /* * TODO: Error handling could be improved. Ignore error if there are @@ -830,14 +845,12 @@ of_socket_address_family_t addressFamily = [context intValue]; _expectedResponses--; if (exception == nil) { - for (OFDNSResourceRecord *record in answerRecords) { - if (![[record name] isEqual: domainName]) - continue; - + for (OFDNSResourceRecord *record in + [answerRecords objectForKey: domainName]) { if ([record recordClass] != OF_DNS_RESOURCE_RECORD_CLASS_IN) continue; switch ([record recordType]) { @@ -1611,12 +1624,12 @@ length: (size_t)length sender: (of_socket_address_t)sender context: (id)context exception: (id)exception { - OFArray *answerRecords = nil, *authorityRecords = nil; - OFArray *additionalRecords = nil; + OFDictionary *answerRecords = nil, *authorityRecords = nil; + OFDictionary *additionalRecords = nil; OFNumber *ID; OFDNSResolverQuery *query; if (exception != nil) { if ([exception respondsToSelector: @selector(errNo)])