@@ -60,10 +60,11 @@ * - 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; @@ -184,11 +185,11 @@ return [components componentsJoinedByString: @"."]; } static OFString * -parseAAAA(const unsigned char *buffer) +parseAAAAData(const unsigned char *buffer) { OFMutableString *data = [OFMutableString string]; int_fast8_t zerosStart = -1, maxZerosStart = -1; uint_fast8_t zerosCount = 0, maxZerosCount = 0; bool first = true; @@ -242,15 +243,16 @@ [data makeImmutable]; return data; } -static id -parseData(const unsigned char *buffer, size_t length, size_t i, - size_t dataLength, of_dns_resource_record_class_t recordClass, - of_dns_resource_record_type_t recordType) +static OF_KINDOF(OFDNSResourceRecord *) +createResourceRecord(OFString *name, of_dns_resource_record_class_t recordClass, + of_dns_resource_record_type_t recordType, uint32_t TTL, + const unsigned char *buffer, size_t length, size_t i, size_t dataLength) { + Class class; id data; if (recordClass == OF_DNS_RESOURCE_RECORD_CLASS_IN) { size_t j; @@ -258,18 +260,20 @@ case OF_DNS_RESOURCE_RECORD_TYPE_A: if (dataLength != 4) @throw [OFInvalidServerReplyException exception]; + class = [OFADNSResourceRecord class]; data = [OFString stringWithFormat: @"%u.%u.%u.%u", buffer[i], buffer[i + 1], buffer[i + 2], buffer[i + 3]]; break; case OF_DNS_RESOURCE_RECORD_TYPE_CNAME: j = i; + class = [OFCNAMEDNSResourceRecord class]; data = parseName(buffer, length, &j, ALLOWED_POINTER_LEVELS); if (j != i + dataLength) @throw [OFInvalidServerReplyException @@ -279,22 +283,30 @@ case OF_DNS_RESOURCE_RECORD_TYPE_AAAA: if (dataLength != 16) @throw [OFInvalidServerReplyException exception]; - data = parseAAAA(&buffer[i]); + class = [OFAAAADNSResourceRecord class]; + data = parseAAAAData(&buffer[i]); break; default: + class = [OFDNSResourceRecord class]; data = [OFData dataWithItems: &buffer[i] count: dataLength]; break; } - } else + } else { + class = [OFDNSResourceRecord class]; data = [OFData dataWithItems: &buffer[i] count: dataLength]; + } - return data; + return [[[class alloc] initWithName: name + recordClass: recordClass + recordType: recordType + data: data + TTL: TTL] autorelease]; } @implementation OFDNSResolver_context @synthesize host = _host, nameServers = _nameServers; @synthesize searchDomains = _searchDomains; @@ -747,11 +759,10 @@ ALLOWED_POINTER_LEVELS); of_dns_resource_record_class_t recordClass; of_dns_resource_record_type_t recordType; uint32_t TTL; uint16_t dataLength; - id data; OFDNSResourceRecord *record; if (i + 10 > length) @throw [OFTruncatedDataException exception]; @@ -764,21 +775,14 @@ i += 10; if (i + dataLength > length) @throw [OFTruncatedDataException exception]; - data = parseData(buffer, length, i, dataLength, - recordClass, recordType); + record = createResourceRecord(name, recordClass, + recordType, TTL, buffer, length, i, dataLength); i += dataLength; - record = [[[OFDNSResourceRecord alloc] - initWithName: name - recordClass: recordClass - recordType: recordType - data: data - TTL: TTL] autorelease]; - [answers addObject: record]; } } @catch (id e) { callback(target, selector, nil, [DNSResolverContext userContext], e);