Index: src/OFDNSResolver.m ================================================================== --- src/OFDNSResolver.m +++ src/OFDNSResolver.m @@ -416,10 +416,31 @@ return [[[OFTXTDNSResourceRecord alloc] initWithName: name recordClass: recordClass textData: textData + TTL: TTL] autorelease]; + } else if (recordType == OF_DNS_RESOURCE_RECORD_TYPE_RP) { + size_t j = i; + OFString *mailbox = parseName(buffer, length, &j, + MAX_ALLOWED_POINTERS); + OFString *TXTDomainName; + + if (j > i + dataLength) + @throw [OFInvalidServerReplyException exception]; + + TXTDomainName = parseName(buffer, length, &j, + MAX_ALLOWED_POINTERS); + + if (j != i + dataLength) + @throw [OFInvalidServerReplyException exception]; + + return [[[OFRPDNSResourceRecord alloc] + initWithName: name + recordClass: recordClass + mailbox: mailbox + TXTDomainName: TXTDomainName TTL: TTL] autorelease]; } else if (recordType == OF_DNS_RESOURCE_RECORD_TYPE_AAAA && recordClass == OF_DNS_RESOURCE_RECORD_CLASS_IN) { OFString *address; Index: src/OFDNSResourceRecord.h ================================================================== --- src/OFDNSResourceRecord.h +++ src/OFDNSResourceRecord.h @@ -52,10 +52,12 @@ OF_DNS_RESOURCE_RECORD_TYPE_HINFO = 13, /*! MX */ OF_DNS_RESOURCE_RECORD_TYPE_MX = 15, /*! TXT */ OF_DNS_RESOURCE_RECORD_TYPE_TXT = 16, + /*! RP */ + OF_DNS_RESOURCE_RECORD_TYPE_RP = 17, /*! AAAA */ OF_DNS_RESOURCE_RECORD_TYPE_AAAA = 28, /*! All types. Only for queries. */ OF_DNS_RESOURCE_RECORD_TYPE_ALL = 255, } of_dns_resource_record_type_t; @@ -100,10 +102,11 @@ * * @param name The name for the resource record * @param recordClass The class code for the resource record * @param recordType The type code for the resource record * @param TTL The time to live for the resource record + * @return An initialized OFDNSResourceRecord */ - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass recordType: (of_dns_resource_record_type_t)recordType TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @@ -118,11 +121,11 @@ { OFString *_address; } /*! - * The IPv4 address of the resource record. + * @brief The IPv4 address of the resource record. */ @property (readonly, nonatomic) OFString *address; - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass @@ -134,10 +137,11 @@ * specified name, class, address and time to live. * * @param name The name for the resource record * @param address The address for the resource record * @param TTL The time to live for the resource record + * @return An initialized OFADNSResourceRecord */ - (instancetype)initWithName: (OFString *)name address: (OFString *)address TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end @@ -152,11 +156,11 @@ { OFString *_address; } /*! - * The IPv6 address of the resource record. + * @brief The IPv6 address of the resource record. */ @property (readonly, nonatomic) OFString *address; - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass @@ -168,10 +172,11 @@ * specified name, class, address and time to live. * * @param name The name for the resource record * @param address The address for the resource record * @param TTL The time to live for the resource record + * @return An initialized OFAAAADNSResourceRecord */ - (instancetype)initWithName: (OFString *)name address: (OFString *)address TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end @@ -186,11 +191,11 @@ { OFString *_alias; } /*! - * The alias of the resource record. + * @brief The alias of the resource record. */ @property (readonly, nonatomic) OFString *alias; - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass @@ -203,10 +208,11 @@ * * @param name The name for the resource record * @param recordClass The class code for the resource record * @param alias The alias for the resource record * @param TTL The time to live for the resource record + * @return An initialized OFCNAMEDNSResourceRecord */ - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass alias: (OFString *)alias TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @@ -222,33 +228,34 @@ { OFString *_CPU, *_OS; } /*! - * The CPU of the host info of the resource record. + * @brief The CPU of the host info of the resource record. */ @property (readonly, nonatomic) OFString *CPU; /*! - * The OS of the host info of the resource record. + * @brief The OS of the host info of the resource record. */ @property (readonly, nonatomic) OFString *OS; - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass recordType: (of_dns_resource_record_type_t)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; /*! - * @brief Initializes an already allocated OFPTRDNSResourceRecord with the + * @brief Initializes an already allocated OFHINFODNSResourceRecord with the * specified name, class, domain name and time to live. * * @param name The name for the resource record * @param recordClass The class code for the resource record * @param CPU The CPU of the host info for the resource record * @param OS The OS of the host info for the resource record * @param TTL The time to live for the resource record + * @return An initialized OFHINFODNSResourceRecord */ - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass CPU: (OFString *)CPU OS: (OFString *)OS @@ -266,16 +273,16 @@ uint16_t _preference; OFString *_mailExchange; } /*! - * The preference of the resource record. + * @brief The preference of the resource record. */ @property (readonly, nonatomic) uint16_t preference; /*! - * The mail exchange of the resource record. + * @brief The mail exchange of the resource record. */ @property (readonly, nonatomic) OFString *mailExchange; - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass @@ -289,10 +296,11 @@ * @param name The name for the resource record * @param recordClass The class code for the resource record * @param preference The preference for the resource record * @param mailExchange The mail exchange for the resource record * @param TTL The time to live for the resource record + * @return An initialized OFMXDNSResourceRecord */ - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass preference: (uint16_t)preference mailExchange: (OFString *)mailExchange @@ -309,11 +317,11 @@ { OFString *_authoritativeHost; } /*! - * The authoritative host of the resource record. + * @brief The authoritative host of the resource record. */ @property (readonly, nonatomic) OFString *authoritativeHost; - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass @@ -326,10 +334,11 @@ * * @param name The name for the resource record * @param recordClass The class code for the resource record * @param authoritativeHost The authoritative host for the resource record * @param TTL The time to live for the resource record + * @return An initialized OFNSDNSResourceRecord */ - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass authoritativeHost: (OFString *)authoritativeHost TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @@ -345,11 +354,11 @@ { OFString *_domainName; } /*! - * The domain name of the resource record. + * @brief The domain name of the resource record. */ @property (readonly, nonatomic) OFString *domainName; - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass @@ -362,17 +371,64 @@ * * @param name The name for the resource record * @param recordClass The class code for the resource record * @param domainName The domain name for the resource record * @param TTL The time to live for the resource record + * @return An initialized OFPTRDNSResourceRecord */ - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass domainName: (OFString *)domainName TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end +/*! + * @class OFRPNSResourceRecord \ + * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h + * + * @brief A class representing an RP DNS resource record. + */ +@interface OFRPDNSResourceRecord: OFDNSResourceRecord +{ + OFString *_mailbox, *_TXTDomainName; +} + +/*! + * @brief The mailbox of the responsible person of the resource record. + */ +@property (readonly, nonatomic) OFString *mailbox; + +/*! + * @brief A domain name that contains a TXT resource record for the responsible + * person of the resource record. + */ +@property (readonly, nonatomic) OFString *TXTDomainName; + +- (instancetype)initWithName: (OFString *)name + recordClass: (of_dns_resource_record_class_t)recordClass + recordType: (of_dns_resource_record_type_t)recordType + TTL: (uint32_t)TTL OF_UNAVAILABLE; + +/*! + * @brief Initializes an already allocated OFRPDNSResourceRecord with the + * specified name, class, alias and time to live. + * + * @param name The name for the resource record + * @param recordClass The class code for the resource record + * @param mailbox The mailbox of the responsible person of the resource record + * @param TXTDomainName A domain name that contains a TXT resource record for + * the responsible person of the resource record + * @param TTL The time to live for the resource record + * @return An initialized OFRPDNSResourceRecord + */ +- (instancetype)initWithName: (OFString *)name + recordClass: (of_dns_resource_record_class_t)recordClass + mailbox: (OFString *)mailbox + TXTDomainName: (OFString *)TXTDomainName + TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; +@end + /*! * @class OFSOADNSResourceRecord \ * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class representing an SOA DNS resource record. @@ -383,50 +439,51 @@ uint32_t _serialNumber, _refreshInterval, _retryInterval; uint32_t _expirationInterval, _minTTL; } /*! - * The the primary name server for the zone. + * @brief The the primary name server for the zone. */ @property (readonly, nonatomic) OFString *primaryNameServer; /*! - * The mailbox of the person responsible for the zone. + * @brief The mailbox of the person responsible for the zone. */ @property (readonly, nonatomic) OFString *responsiblePerson; /*! - * The serial number of the original copy of the zone. + * @brief The serial number of the original copy of the zone. */ @property (readonly, nonatomic) uint32_t serialNumber; /*! - * The refresh interval of the zone. + * @brief The refresh interval of the zone. */ @property (readonly, nonatomic) uint32_t refreshInterval; /*! - * The retry interval of the zone. + * @brief The retry interval of the zone. */ @property (readonly, nonatomic) uint32_t retryInterval; /*! - * The expiration interval of the zone. + * @brief The expiration interval of the zone. */ @property (readonly, nonatomic) uint32_t expirationInterval; + /*! - * The minimum TTL of the zone. + * @brief The minimum TTL of the zone. */ @property (readonly, nonatomic) uint32_t minTTL; - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass recordType: (of_dns_resource_record_type_t)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; /*! - * @brief Initializes an already allocated OFTXTDNSResourceRecord with the + * @brief Initializes an already allocated OFSOADNSResourceRecord with the * specified name, class, text data and time to live. * * @param name The name for the resource record * @param recordClass The class code for the resource record * @param primaryNameServer The the primary name server for the zone @@ -435,10 +492,11 @@ * @param refreshInterval The refresh interval of the zone * @param retryInterval The retry interval of the zone * @param expirationInterval The expiration interval of the zone * @param minTTL The minimum TTL of the zone * @param TTL The time to live for the resource record + * @return An initialized OFSOADNSResourceRecord */ - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass primaryNameServer: (OFString *)primaryNameServer responsiblePerson: (OFString *)responsiblePerson @@ -460,11 +518,11 @@ { OFData *_textData; } /*! - * The text of the resource record. + * @brief The text of the resource record. */ @property (readonly, nonatomic) OFData *textData; - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass @@ -477,10 +535,11 @@ * * @param name The name for the resource record * @param recordClass The class code for the resource record * @param textData The data for the resource record * @param TTL The time to live for the resource record + * @return An initialized OFTXTDNSResourceRecord */ - (instancetype)initWithName: (OFString *)name recordClass: (of_dns_resource_record_class_t)recordClass textData: (OFData *)textData TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; Index: src/OFDNSResourceRecord.m ================================================================== --- src/OFDNSResourceRecord.m +++ src/OFDNSResourceRecord.m @@ -55,10 +55,12 @@ return @"HINFO"; case OF_DNS_RESOURCE_RECORD_TYPE_MX: return @"MX"; case OF_DNS_RESOURCE_RECORD_TYPE_TXT: return @"TXT"; + case OF_DNS_RESOURCE_RECORD_TYPE_RP: + return @"RP"; case OF_DNS_RESOURCE_RECORD_TYPE_AAAA: return @"AAAA"; case OF_DNS_RESOURCE_RECORD_TYPE_ALL: return @"all"; default: @@ -106,10 +108,12 @@ recordType = OF_DNS_RESOURCE_RECORD_TYPE_HINFO; else if ([string isEqual: @"MX"]) recordType = OF_DNS_RESOURCE_RECORD_TYPE_MX; else if ([string isEqual: @"TXT"]) recordType = OF_DNS_RESOURCE_RECORD_TYPE_TXT; + else if ([string isEqual: @"RP"]) + recordType = OF_DNS_RESOURCE_RECORD_TYPE_RP; else if ([string isEqual: @"AAAA"]) recordType = OF_DNS_RESOURCE_RECORD_TYPE_AAAA; else @throw [OFInvalidArgumentException exception]; @@ -839,10 +843,115 @@ [self className], _name, of_dns_resource_record_class_to_string(_recordClass), _domainName, _TTL]; } @end + +@implementation OFRPDNSResourceRecord +@synthesize mailbox = _mailbox, TXTDomainName = _TXTDomainName; + +- (instancetype)initWithName: (OFString *)name + recordClass: (of_dns_resource_record_class_t)recordClass + recordType: (of_dns_resource_record_type_t)recordType + TTL: (uint32_t)TTL +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)initWithName: (OFString *)name + recordClass: (of_dns_resource_record_class_t)recordClass + mailbox: (OFString *)mailbox + TXTDomainName: (OFString *)TXTDomainName + TTL: (uint32_t)TTL +{ + self = [super initWithName: name + recordClass: recordClass + recordType: OF_DNS_RESOURCE_RECORD_TYPE_RP + TTL: TTL]; + + @try { + _mailbox = [mailbox copy]; + _TXTDomainName = [TXTDomainName copy]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [_mailbox release]; + [_TXTDomainName release]; + + [super dealloc]; +} + +- (bool)isEqual: (id)otherObject +{ + OFRPDNSResourceRecord *otherRecord; + + if (![otherObject isKindOfClass: [OFRPDNSResourceRecord class]]) + return false; + + otherRecord = otherObject; + + if (otherRecord->_name != _name && ![otherRecord->_name isEqual: _name]) + return false; + + if (otherRecord->_recordClass != _recordClass) + return false; + + if (otherRecord->_recordType != _recordType) + return false; + + if (otherRecord->_mailbox != _mailbox && + ![otherRecord->_mailbox isEqual: _mailbox]) + return false; + + if (otherRecord->_TXTDomainName != _TXTDomainName && + ![otherRecord->_TXTDomainName isEqual: _TXTDomainName]) + return false; + + return true; +} + +- (uint32_t)hash +{ + uint32_t hash; + + OF_HASH_INIT(hash); + + OF_HASH_ADD_HASH(hash, [_name hash]); + OF_HASH_ADD(hash, _recordClass >> 8); + OF_HASH_ADD(hash, _recordClass); + OF_HASH_ADD(hash, _recordType >> 8); + OF_HASH_ADD(hash, _recordType); + OF_HASH_ADD_HASH(hash, [_mailbox hash]); + OF_HASH_ADD_HASH(hash, [_TXTDomainName hash]); + + OF_HASH_FINALIZE(hash); + + return hash; +} + +- (OFString *)description +{ + return [OFString stringWithFormat: + @"<%@:\n" + @"\tName = %@\n" + @"\tClass = %@\n" + @"\tMailbox = %@\n" + @"\tTXT Domain Name = %@\n" + @"\tTTL = %" PRIu32 "\n" + @">", + [self className], _name, + of_dns_resource_record_class_to_string(_recordClass), _mailbox, + _TXTDomainName, _TTL]; +} +@end @implementation OFSOADNSResourceRecord @synthesize primaryNameServer = _primaryNameServer; @synthesize responsiblePerson = _responsiblePerson; @synthesize serialNumber = _serialNumber, refreshInterval = _refreshInterval;