Index: src/OFDNSResolver.m ================================================================== --- src/OFDNSResolver.m +++ src/OFDNSResolver.m @@ -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); Index: src/OFDNSResourceRecord.h ================================================================== --- src/OFDNSResourceRecord.h +++ src/OFDNSResourceRecord.h @@ -59,11 +59,11 @@ } of_dns_resource_record_type_t; /*! * @class OFDNSResourceRecord OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * - * @brief A class represenging a DNS resource record. + * @brief A class representing a DNS resource record. */ @interface OFDNSResourceRecord: OFObject { OFString *_name; of_dns_resource_record_class_t _recordClass; @@ -87,14 +87,10 @@ */ @property (readonly, nonatomic) of_dns_resource_record_type_t recordType; /*! * The class and type-dependent data of the resource. - * - * For A and AAAA records, this is a string with the IP address. - * For CNAME records, this is a string with the alias. - * For anything else, this is OFData. */ @property (readonly, nonatomic) id data; /*! * @brief The number of seconds after which the resource record should be @@ -107,10 +103,48 @@ recordType: (of_dns_resource_record_type_t)recordType data: (id)data TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end +/*! + * @class OFADNSResourceRecord OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h + * + * @brief A class representing an A DNS resource record. + */ +@interface OFADNSResourceRecord: OFDNSResourceRecord +/*! + * A string with the IP address. + */ +@property (readonly, nonatomic) OFString *data; +@end + +/*! + * @class OFAAAADNSResourceRecord \ + * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h + * + * @brief A class represenging a DNS resource record. + */ +@interface OFAAAADNSResourceRecord: OFDNSResourceRecord +/*! + * A string with the IP address. + */ +@property (readonly, nonatomic) OFString *data; +@end + +/*! + * @class OFCNAMEDNSResourceRecord \ + * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h + * + * @brief A class representing a CNAME DNS resource record. + */ +@interface OFCNAMEDNSResourceRecord: OFDNSResourceRecord +/*! + * A string with the alias. + */ +@property (readonly, nonatomic) OFString *data; +@end + #ifdef __cplusplus extern "C" { #endif extern OFString *_Nonnull of_dns_resource_record_class_to_string( of_dns_resource_record_class_t recordClass); Index: src/OFDNSResourceRecord.m ================================================================== --- src/OFDNSResourceRecord.m +++ src/OFDNSResourceRecord.m @@ -158,5 +158,26 @@ @">", _name, of_dns_resource_record_class_to_string(_recordClass), of_dns_resource_record_type_to_string(_recordType), _data, _TTL]; } @end + +@implementation OFADNSResourceRecord +- (OFString *)data +{ + return _data; +} +@end + +@implementation OFAAAADNSResourceRecord +- (OFString *)data +{ + return _data; +} +@end + +@implementation OFCNAMEDNSResourceRecord +- (OFString *)data +{ + return _data; +} +@end