Index: src/OFDNSResolver.m ================================================================== --- src/OFDNSResolver.m +++ src/OFDNSResolver.m @@ -219,87 +219,32 @@ *idx = i; return [components componentsJoinedByString: @"."]; } -static OFString * -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; - - for (uint_fast8_t i = 0; i < 16; i += 2) { - if (buffer[i] == 0 && buffer[i + 1] == 0) { - if (zerosStart >= 0) - zerosCount++; - else { - zerosStart = i; - zerosCount = 1; - } - } else { - if (zerosCount > maxZerosCount) { - maxZerosStart = zerosStart; - maxZerosCount = zerosCount; - } - - zerosStart = -1; - } - } - if (zerosCount > maxZerosCount) { - maxZerosStart = zerosStart; - maxZerosCount = zerosCount; - } - - if (maxZerosCount >= 2) { - for (uint_fast8_t i = 0; i < maxZerosStart; i += 2) { - [data appendFormat: (first ? @"%x" : @":%x"), - (buffer[i] << 8) | buffer[i + 1]]; - first = false; - } - - [data appendString: @"::"]; - first = true; - - for (uint_fast8_t i = maxZerosStart + (maxZerosCount * 2); - i < 16; i += 2) { - [data appendFormat: (first ? @"%x" : @":%x"), - (buffer[i] << 8) | buffer[i + 1]]; - first = false; - } - } else { - for (uint_fast8_t i = 0; i < 16; i += 2) { - [data appendFormat: (first ? @"%x" : @":%x"), - (buffer[i] << 8) | buffer[i + 1]]; - first = false; - } - } - - [data makeImmutable]; - - return data; -} - 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, uint16_t dataLength) { if (recordType == OF_DNS_RESOURCE_RECORD_TYPE_A && recordClass == OF_DNS_RESOURCE_RECORD_CLASS_IN) { - OFString *address; + of_socket_address_t address; if (dataLength != 4) @throw [OFInvalidServerReplyException exception]; - address = [OFString stringWithFormat: @"%u.%u.%u.%u", - buffer[i], buffer[i + 1], buffer[i + 2], buffer[i + 3]]; + memset(&address, 0, sizeof(address)); + address.family = OF_SOCKET_ADDRESS_FAMILY_IPV4; + address.length = sizeof(address.sockaddr.in); + + address.sockaddr.in.sin_family = AF_INET; + memcpy(&address.sockaddr.in.sin_addr.s_addr, buffer + i, 4); return [[[OFADNSResourceRecord alloc] initWithName: name - address: address + address: &address TTL: TTL] autorelease]; } else if (recordType == OF_DNS_RESOURCE_RECORD_TYPE_NS) { size_t j = i; OFString *authoritativeHost = parseName(buffer, length, &j, MAX_ALLOWED_POINTERS); @@ -451,21 +396,29 @@ 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; + of_socket_address_t address; if (dataLength != 16) - @throw [OFInvalidServerReplyException - exception]; + @throw [OFInvalidServerReplyException exception]; - address = parseAAAAData(&buffer[i]); + memset(&address, 0, sizeof(address)); + address.family = OF_SOCKET_ADDRESS_FAMILY_IPV6; + address.length = sizeof(address.sockaddr.in6); + +#ifdef AF_INET6 + address.sockaddr.in6.sin6_family = AF_INET6; +#else + address.sockaddr.in6.sin6_family = AF_UNSPEC; +#endif + memcpy(address.sockaddr.in6.sin6_addr.s6_addr, buffer + i, 16); return [[[OFAAAADNSResourceRecord alloc] initWithName: name - address: address + address: &address TTL: TTL] autorelease]; } else if (recordType == OF_DNS_RESOURCE_RECORD_TYPE_SRV && recordClass == OF_DNS_RESOURCE_RECORD_CLASS_IN) { uint16_t priority, weight, port; size_t j; Index: src/OFDNSResourceRecord.h ================================================================== --- src/OFDNSResourceRecord.h +++ src/OFDNSResourceRecord.h @@ -15,10 +15,12 @@ * file. */ #import "OFObject.h" #import "OFString.h" + +#import "socket.h" OF_ASSUME_NONNULL_BEGIN /*! @file */ @@ -119,17 +121,17 @@ * * @brief A class representing an A DNS resource record. */ @interface OFADNSResourceRecord: OFDNSResourceRecord { - OFString *_address; + of_socket_address_t _address; } /*! * @brief The IPv4 address of the resource record. */ -@property (readonly, nonatomic) OFString *address; +@property (readonly, nonatomic) const of_socket_address_t *address; - (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; @@ -142,11 +144,11 @@ * @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 + address: (const of_socket_address_t *)address TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end /*! * @class OFAAAADNSResourceRecord \ @@ -154,17 +156,17 @@ * * @brief A class represenging a DNS resource record. */ @interface OFAAAADNSResourceRecord: OFDNSResourceRecord { - OFString *_address; + of_socket_address_t _address; } /*! * @brief The IPv6 address of the resource record. */ -@property (readonly, nonatomic) OFString *address; +@property (readonly, nonatomic) const of_socket_address_t *address; - (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; @@ -177,11 +179,11 @@ * @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 + address: (const of_socket_address_t *)address TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end /*! * @class OFCNAMEDNSResourceRecord \ Index: src/OFDNSResourceRecord.m ================================================================== --- src/OFDNSResourceRecord.m +++ src/OFDNSResourceRecord.m @@ -171,44 +171,35 @@ of_dns_resource_record_type_to_string(_recordType), _TTL]; } @end @implementation OFADNSResourceRecord -@synthesize address = _address; - - (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 - address: (OFString *)address + address: (const of_socket_address_t *)address TTL: (uint32_t)TTL { self = [super initWithName: name recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN recordType: OF_DNS_RESOURCE_RECORD_TYPE_A TTL: TTL]; - @try { - _address = [address copy]; - } @catch (id e) { - [self release]; - @throw e; - } + _address = *address; return self; } -- (void)dealloc +- (const of_socket_address_t *)address { - [_address release]; - - [super dealloc]; + return &_address; } - (bool)isEqual: (id)otherObject { OFADNSResourceRecord *otherRecord; @@ -225,12 +216,11 @@ return false; if (otherRecord->_recordType != _recordType) return false; - if (otherRecord->_address != _address && - ![otherRecord->_address isEqual: _address]) + if (!of_socket_address_equal(&otherRecord->_address, &_address)) return false; return true; } @@ -243,11 +233,11 @@ 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, [_address hash]); + OF_HASH_ADD_HASH(hash, of_socket_address_hash(&_address)); OF_HASH_FINALIZE(hash); return hash; } @@ -258,49 +248,41 @@ @"<%@:\n" @"\tName = %@\n" @"\tAddress = %@\n" @"\tTTL = %" PRIu32 "\n" @">", - [self className], _name, _address, _TTL]; + [self className], _name, + of_socket_address_ip_string(&_address, NULL), _TTL]; } @end @implementation OFAAAADNSResourceRecord -@synthesize address = _address; - - (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 - address: (OFString *)address + address: (const of_socket_address_t *)address TTL: (uint32_t)TTL { self = [super initWithName: name recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN recordType: OF_DNS_RESOURCE_RECORD_TYPE_AAAA TTL: TTL]; - @try { - _address = [address copy]; - } @catch (id e) { - [self release]; - @throw e; - } + _address = *address; return self; } -- (void)dealloc +- (const of_socket_address_t *)address { - [_address release]; - - [super dealloc]; + return &_address; } - (bool)isEqual: (id)otherObject { OFAAAADNSResourceRecord *otherRecord; @@ -317,12 +299,11 @@ return false; if (otherRecord->_recordType != _recordType) return false; - if (otherRecord->_address != _address && - ![otherRecord->_address isEqual: _address]) + if (!of_socket_address_equal(&otherRecord->_address, &_address)) return false; return true; } @@ -335,11 +316,11 @@ 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, [_address hash]); + OF_HASH_ADD_HASH(hash, of_socket_address_hash(&_address)); OF_HASH_FINALIZE(hash); return hash; } @@ -350,11 +331,12 @@ @"<%@:\n" @"\tName = %@\n" @"\tAddress = %@\n" @"\tTTL = %" PRIu32 "\n" @">", - [self className], _name, _address, _TTL]; + [self className], _name, + of_socket_address_ip_string(&_address, NULL), _TTL]; } @end @implementation OFCNAMEDNSResourceRecord @synthesize alias = _alias; Index: src/ObjFW.h ================================================================== --- src/ObjFW.h +++ src/ObjFW.h @@ -75,10 +75,11 @@ # import "OFTCPSocket.h" # import "OFUDPSocket.h" # import "OFTLSSocket.h" # import "OFKernelEventObserver.h" # import "OFDNSResolver.h" +# import "OFDNSResourceRecord.h" #endif #ifdef OF_HAVE_SOCKETS # ifdef OF_HAVE_THREADS # import "OFHTTPClient.h" # endif Index: src/socket.m ================================================================== --- src/socket.m +++ src/socket.m @@ -239,11 +239,11 @@ OFArray OF_GENERIC(OFString *) *components; uint32_t addr; memset(&ret, '\0', sizeof(ret)); ret.family = OF_SOCKET_ADDRESS_FAMILY_IPV4; - ret.length = sizeof(struct sockaddr_in); + ret.length = sizeof(ret.sockaddr.in); addrIn->sin_family = AF_INET; addrIn->sin_port = OF_BSWAP16_IF_LE(port); components = [IPv4 componentsSeparatedByString: @"."]; @@ -303,11 +303,11 @@ struct sockaddr_in6 *addrIn6 = &ret.sockaddr.in6; size_t doubleColon; memset(&ret, '\0', sizeof(ret)); ret.family = OF_SOCKET_ADDRESS_FAMILY_IPV6; - ret.length = sizeof(struct sockaddr_in6); + ret.length = sizeof(ret.sockaddr.in6); #ifdef AF_INET6 addrIn6->sin6_family = AF_INET6; #else addrIn6->sin6_family = AF_UNSPEC;