@@ -44,22 +44,20 @@ #ifndef SOCK_DNS # define SOCK_DNS 0 #endif -#define BUFFER_LENGTH OF_DNS_RESOLVER_BUFFER_LENGTH -#define MAX_DNS_RESPONSE_LENGTH 65536 +static const size_t bufferLength = OFDNSResolverBufferLength; +static const size_t maxDNSResponseLength = 65536; /* * RFC 1035 doesn't specify if pointers to pointers are allowed, and if so how * many. Since it's unspecified, we have to assume that it might happen, but we * also want to limit it to avoid DoS. Limiting it to 16 levels of pointers and * immediately rejecting pointers to itself seems like a fair balance. */ -#define MAX_ALLOWED_POINTERS 16 - -#define CNAME_RECURSION 3 +static const uint_fast8_t maxAllowedPointers = 16; @interface OFDNSResolver () - (void)of_contextTimedOut: (OFDNSResolverContext *)context; @end @@ -190,11 +188,11 @@ address: &address TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeNS) { size_t j = i; OFString *authoritativeHost = parseName(buffer, length, &j, - MAX_ALLOWED_POINTERS); + maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerReplyException exception]; return [[[OFNSDNSResourceRecord alloc] @@ -203,11 +201,11 @@ authoritativeHost: authoritativeHost TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeCNAME) { size_t j = i; OFString *alias = parseName(buffer, length, &j, - MAX_ALLOWED_POINTERS); + maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerReplyException exception]; return [[[OFCNAMEDNSResourceRecord alloc] @@ -216,20 +214,20 @@ alias: alias TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeSOA) { size_t j = i; OFString *primaryNameServer = parseName(buffer, length, &j, - MAX_ALLOWED_POINTERS); + maxAllowedPointers); OFString *responsiblePerson; uint32_t serialNumber, refreshInterval, retryInterval; uint32_t expirationInterval, minTTL; if (j > i + dataLength) @throw [OFInvalidServerReplyException exception]; responsiblePerson = parseName(buffer, length, &j, - MAX_ALLOWED_POINTERS); + maxAllowedPointers); if (dataLength - (j - i) != 20) @throw [OFInvalidServerReplyException exception]; serialNumber = (buffer[j] << 24) | (buffer[j + 1] << 16) | @@ -257,11 +255,11 @@ minTTL: minTTL TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypePTR) { size_t j = i; OFString *domainName = parseName(buffer, length, &j, - MAX_ALLOWED_POINTERS); + maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerReplyException exception]; return [[[OFPTRDNSResourceRecord alloc] @@ -298,11 +296,11 @@ preference = (buffer[i] << 8) | buffer[i + 1]; j = i + 2; mailExchange = parseName(buffer, length, &j, - MAX_ALLOWED_POINTERS); + maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerReplyException exception]; return [[[OFMXDNSResourceRecord alloc] @@ -338,18 +336,18 @@ textStrings: textStrings TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeRP) { size_t j = i; OFString *mailbox = parseName(buffer, length, &j, - MAX_ALLOWED_POINTERS); + maxAllowedPointers); OFString *TXTDomainName; if (j > i + dataLength) @throw [OFInvalidServerReplyException exception]; TXTDomainName = parseName(buffer, length, &j, - MAX_ALLOWED_POINTERS); + maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerReplyException exception]; return [[[OFRPDNSResourceRecord alloc] @@ -392,11 +390,11 @@ priority = (buffer[i] << 8) | buffer[i + 1]; weight = (buffer[i + 2] << 8) | buffer[i + 3]; port = (buffer[i + 4] << 8) | buffer[i + 5]; j = i + 6; - target = parseName(buffer, length, &j, MAX_ALLOWED_POINTERS); + target = parseName(buffer, length, &j, maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerReplyException exception]; return [[[OFSRVDNSResourceRecord alloc] @@ -422,11 +420,11 @@ 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); + maxAllowedPointers); OFDNSClass DNSClass; OFDNSRecordType recordType; uint32_t TTL; uint16_t dataLength; OFDNSResourceRecord *record; @@ -776,11 +774,11 @@ [sock asyncSendData: context->_queryData receiver: &context->_usedNameServer runLoopMode: runLoopMode]; [sock asyncReceiveIntoBuffer: _buffer - length: BUFFER_LENGTH + length: bufferLength runLoopMode: runLoopMode]; } - (void)asyncPerformQuery: (OFDNSQuery *)query delegate: (id )delegate @@ -861,14 +859,14 @@ /* * Cancel any pending queries, to avoid a send being still pending and * trying to access the query once it no longer exists. */ [_IPv4Socket cancelAsyncRequests]; - [_IPv4Socket asyncReceiveIntoBuffer: _buffer length: BUFFER_LENGTH]; + [_IPv4Socket asyncReceiveIntoBuffer: _buffer length: bufferLength]; #ifdef OF_HAVE_IPV6 [_IPv6Socket cancelAsyncRequests]; - [_IPv6Socket asyncReceiveIntoBuffer: _buffer length: BUFFER_LENGTH]; + [_IPv6Socket asyncReceiveIntoBuffer: _buffer length: bufferLength]; #endif exception = [OFDNSQueryFailedException exceptionWithQuery: context->_query errorCode: OFDNSResolverErrorCodeTimeout]; @@ -1009,11 +1007,11 @@ * query. * * TODO: Compare to our query, just in case? */ for (uint_fast16_t j = 0; j < numQuestions; j++) { - parseName(buffer, length, &i, MAX_ALLOWED_POINTERS); + parseName(buffer, length, &i, maxAllowedPointers); i += 4; } answerRecords = parseSection(buffer, length, &i, numAnswers); authorityRecords = parseSection(buffer, length, &i, @@ -1115,11 +1113,11 @@ context->_responseLength = 0; return nil; } if (context->_TCPBuffer == nil) - context->_TCPBuffer = OFAllocMemory(MAX_DNS_RESPONSE_LENGTH, 1); + context->_TCPBuffer = OFAllocMemory(maxDNSResponseLength, 1); [sock asyncReadIntoBuffer: context->_TCPBuffer exactLength: 2]; return nil; } @@ -1146,11 +1144,11 @@ OFEnsure(length == 2); context->_responseLength = (ucBuffer[0] << 8) | ucBuffer[1]; - if (context->_responseLength > MAX_DNS_RESPONSE_LENGTH) + if (context->_responseLength > maxDNSResponseLength) @throw [OFOutOfRangeException exception]; if (context->_responseLength == 0) goto done;