︙ | | | ︙ | |
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
[components addObject: component];
} while (componentLength > 0);
return [components componentsJoinedByString: @"."];
}
static OF_KINDOF(OFDNSResourceRecord *)
parseResourceRecord(OFString *name, of_dns_class_t DNSClass,
of_dns_record_type_t recordType, uint32_t TTL, const unsigned char *buffer,
size_t length, size_t i, uint16_t dataLength)
{
if (recordType == OF_DNS_RECORD_TYPE_A && DNSClass == OF_DNS_CLASS_IN) {
OFSocketAddress address;
if (dataLength != 4)
@throw [OFInvalidServerReplyException exception];
memset(&address, 0, sizeof(address));
address.family = OFSocketAddressFamilyIPv4;
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
TTL: TTL] autorelease];
} else if (recordType == OF_DNS_RECORD_TYPE_NS) {
size_t j = i;
OFString *authoritativeHost = parseName(buffer, length, &j,
MAX_ALLOWED_POINTERS);
if (j != i + dataLength)
@throw [OFInvalidServerReplyException exception];
return [[[OFNSDNSResourceRecord alloc]
initWithName: name
DNSClass: DNSClass
authoritativeHost: authoritativeHost
TTL: TTL] autorelease];
} else if (recordType == OF_DNS_RECORD_TYPE_CNAME) {
size_t j = i;
OFString *alias = parseName(buffer, length, &j,
MAX_ALLOWED_POINTERS);
if (j != i + dataLength)
@throw [OFInvalidServerReplyException exception];
return [[[OFCNAMEDNSResourceRecord alloc]
initWithName: name
DNSClass: DNSClass
alias: alias
TTL: TTL] autorelease];
} else if (recordType == OF_DNS_RECORD_TYPE_SOA) {
size_t j = i;
OFString *primaryNameServer = parseName(buffer, length, &j,
MAX_ALLOWED_POINTERS);
OFString *responsiblePerson;
uint32_t serialNumber, refreshInterval, retryInterval;
uint32_t expirationInterval, minTTL;
|
|
|
|
|
|
|
|
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
[components addObject: component];
} while (componentLength > 0);
return [components componentsJoinedByString: @"."];
}
static OF_KINDOF(OFDNSResourceRecord *)
parseResourceRecord(OFString *name, OFDNSClass DNSClass,
OFDNSRecordType recordType, uint32_t TTL, const unsigned char *buffer,
size_t length, size_t i, uint16_t dataLength)
{
if (recordType == OFDNSRecordTypeA && DNSClass == OFDNSClassIN) {
OFSocketAddress address;
if (dataLength != 4)
@throw [OFInvalidServerReplyException exception];
memset(&address, 0, sizeof(address));
address.family = OFSocketAddressFamilyIPv4;
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
TTL: TTL] autorelease];
} else if (recordType == OFDNSRecordTypeNS) {
size_t j = i;
OFString *authoritativeHost = parseName(buffer, length, &j,
MAX_ALLOWED_POINTERS);
if (j != i + dataLength)
@throw [OFInvalidServerReplyException exception];
return [[[OFNSDNSResourceRecord alloc]
initWithName: name
DNSClass: DNSClass
authoritativeHost: authoritativeHost
TTL: TTL] autorelease];
} else if (recordType == OFDNSRecordTypeCNAME) {
size_t j = i;
OFString *alias = parseName(buffer, length, &j,
MAX_ALLOWED_POINTERS);
if (j != i + dataLength)
@throw [OFInvalidServerReplyException exception];
return [[[OFCNAMEDNSResourceRecord alloc]
initWithName: name
DNSClass: DNSClass
alias: alias
TTL: TTL] autorelease];
} else if (recordType == OFDNSRecordTypeSOA) {
size_t j = i;
OFString *primaryNameServer = parseName(buffer, length, &j,
MAX_ALLOWED_POINTERS);
OFString *responsiblePerson;
uint32_t serialNumber, refreshInterval, retryInterval;
uint32_t expirationInterval, minTTL;
|
︙ | | | ︙ | |
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
|
responsiblePerson: responsiblePerson
serialNumber: serialNumber
refreshInterval: refreshInterval
retryInterval: retryInterval
expirationInterval: expirationInterval
minTTL: minTTL
TTL: TTL] autorelease];
} else if (recordType == OF_DNS_RECORD_TYPE_PTR) {
size_t j = i;
OFString *domainName = parseName(buffer, length, &j,
MAX_ALLOWED_POINTERS);
if (j != i + dataLength)
@throw [OFInvalidServerReplyException exception];
return [[[OFPTRDNSResourceRecord alloc]
initWithName: name
DNSClass: DNSClass
domainName: domainName
TTL: TTL] autorelease];
} else if (recordType == OF_DNS_RECORD_TYPE_HINFO) {
size_t j = i;
OFString *CPU = parseString(buffer, length, &j);
OFString *OS;
if (j > i + dataLength)
@throw [OFInvalidServerReplyException exception];
OS = parseString(buffer, length, &j);
if (j != i + dataLength)
@throw [OFInvalidServerReplyException exception];
return [[[OFHINFODNSResourceRecord alloc]
initWithName: name
DNSClass: DNSClass
CPU: CPU
OS: OS
TTL: TTL] autorelease];
} else if (recordType == OF_DNS_RECORD_TYPE_MX) {
uint16_t preference;
size_t j;
OFString *mailExchange;
if (dataLength < 2)
@throw [OFInvalidServerReplyException exception];
|
|
|
|
|
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
|
responsiblePerson: responsiblePerson
serialNumber: serialNumber
refreshInterval: refreshInterval
retryInterval: retryInterval
expirationInterval: expirationInterval
minTTL: minTTL
TTL: TTL] autorelease];
} else if (recordType == OFDNSRecordTypePTR) {
size_t j = i;
OFString *domainName = parseName(buffer, length, &j,
MAX_ALLOWED_POINTERS);
if (j != i + dataLength)
@throw [OFInvalidServerReplyException exception];
return [[[OFPTRDNSResourceRecord alloc]
initWithName: name
DNSClass: DNSClass
domainName: domainName
TTL: TTL] autorelease];
} else if (recordType == OFDNSRecordTypeHINFO) {
size_t j = i;
OFString *CPU = parseString(buffer, length, &j);
OFString *OS;
if (j > i + dataLength)
@throw [OFInvalidServerReplyException exception];
OS = parseString(buffer, length, &j);
if (j != i + dataLength)
@throw [OFInvalidServerReplyException exception];
return [[[OFHINFODNSResourceRecord alloc]
initWithName: name
DNSClass: DNSClass
CPU: CPU
OS: OS
TTL: TTL] autorelease];
} else if (recordType == OFDNSRecordTypeMX) {
uint16_t preference;
size_t j;
OFString *mailExchange;
if (dataLength < 2)
@throw [OFInvalidServerReplyException exception];
|
︙ | | | ︙ | |
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
|
return [[[OFMXDNSResourceRecord alloc]
initWithName: name
DNSClass: DNSClass
preference: preference
mailExchange: mailExchange
TTL: TTL] autorelease];
} else if (recordType == OF_DNS_RECORD_TYPE_TXT) {
OFMutableArray *textStrings = [OFMutableArray array];
while (dataLength > 0) {
uint_fast8_t stringLength = buffer[i++];
dataLength--;
if (stringLength > dataLength)
|
|
|
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
|
return [[[OFMXDNSResourceRecord alloc]
initWithName: name
DNSClass: DNSClass
preference: preference
mailExchange: mailExchange
TTL: TTL] autorelease];
} else if (recordType == OFDNSRecordTypeTXT) {
OFMutableArray *textStrings = [OFMutableArray array];
while (dataLength > 0) {
uint_fast8_t stringLength = buffer[i++];
dataLength--;
if (stringLength > dataLength)
|
︙ | | | ︙ | |
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
|
[textStrings makeImmutable];
return [[[OFTXTDNSResourceRecord alloc]
initWithName: name
DNSClass: DNSClass
textStrings: textStrings
TTL: TTL] autorelease];
} else if (recordType == OF_DNS_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
DNSClass: DNSClass
mailbox: mailbox
TXTDomainName: TXTDomainName
TTL: TTL] autorelease];
} else if (recordType == OF_DNS_RECORD_TYPE_AAAA &&
DNSClass == OF_DNS_CLASS_IN) {
OFSocketAddress address;
if (dataLength != 16)
@throw [OFInvalidServerReplyException exception];
memset(&address, 0, sizeof(address));
address.family = OFSocketAddressFamilyIPv6;
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
TTL: TTL] autorelease];
} else if (recordType == OF_DNS_RECORD_TYPE_SRV &&
DNSClass == OF_DNS_CLASS_IN) {
uint16_t priority, weight, port;
size_t j;
OFString *target;
if (dataLength < 6)
@throw [OFInvalidServerReplyException exception];
|
|
|
|
|
|
|
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
|
[textStrings makeImmutable];
return [[[OFTXTDNSResourceRecord alloc]
initWithName: name
DNSClass: DNSClass
textStrings: textStrings
TTL: TTL] autorelease];
} else if (recordType == OFDNSRecordTypeRP) {
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
DNSClass: DNSClass
mailbox: mailbox
TXTDomainName: TXTDomainName
TTL: TTL] autorelease];
} else if (recordType == OFDNSRecordTypeAAAA &&
DNSClass == OFDNSClassIN) {
OFSocketAddress address;
if (dataLength != 16)
@throw [OFInvalidServerReplyException exception];
memset(&address, 0, sizeof(address));
address.family = OFSocketAddressFamilyIPv6;
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
TTL: TTL] autorelease];
} else if (recordType == OFDNSRecordTypeSRV &&
DNSClass == OFDNSClassIN) {
uint16_t priority, weight, port;
size_t j;
OFString *target;
if (dataLength < 6)
@throw [OFInvalidServerReplyException exception];
|
︙ | | | ︙ | |
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
|
OFMutableDictionary *ret = [OFMutableDictionary dictionary];
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);
of_dns_class_t DNSClass;
of_dns_record_type_t recordType;
uint32_t TTL;
uint16_t dataLength;
OFDNSResourceRecord *record;
if (*i + 10 > length)
@throw [OFTruncatedDataException exception];
|
|
|
|
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
|
OFMutableDictionary *ret = [OFMutableDictionary dictionary];
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);
OFDNSClass DNSClass;
OFDNSRecordType recordType;
uint32_t TTL;
uint16_t dataLength;
OFDNSResourceRecord *record;
if (*i + 10 > length)
@throw [OFTruncatedDataException exception];
|
︙ | | | ︙ | |
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
|
if (query.domainName.UTF8StringLength > 253)
@throw [OFOutOfRangeException exception];
if (_settings->_nameServers.count == 0) {
id exception = [OFDNSQueryFailedException
exceptionWithQuery: query
error: OF_DNS_RESOLVER_ERROR_NO_NAME_SERVER];
[delegate resolver: self
didPerformQuery: query
response: nil
exception: exception];
return;
}
|
|
|
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
|
if (query.domainName.UTF8StringLength > 253)
@throw [OFOutOfRangeException exception];
if (_settings->_nameServers.count == 0) {
id exception = [OFDNSQueryFailedException
exceptionWithQuery: query
errorCode: OFDNSResolverErrorCodeNoNameServer];
[delegate resolver: self
didPerformQuery: query
response: nil
exception: exception];
return;
}
|
︙ | | | ︙ | |
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
|
#ifdef OF_HAVE_IPV6
[_IPv6Socket cancelAsyncRequests];
[_IPv6Socket asyncReceiveIntoBuffer: _buffer length: BUFFER_LENGTH];
#endif
exception = [OFDNSQueryFailedException
exceptionWithQuery: context->_query
error: OF_DNS_RESOLVER_ERROR_TIMEOUT];
[context->_delegate resolver: self
didPerformQuery: context->_query
response: nil
exception: exception];
}
|
|
|
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
|
#ifdef OF_HAVE_IPV6
[_IPv6Socket cancelAsyncRequests];
[_IPv6Socket asyncReceiveIntoBuffer: _buffer length: BUFFER_LENGTH];
#endif
exception = [OFDNSQueryFailedException
exceptionWithQuery: context->_query
errorCode: OFDNSResolverErrorCodeTimeout];
[context->_delegate resolver: self
didPerformQuery: context->_query
response: nil
exception: exception];
}
|
︙ | | | ︙ | |
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
|
[context->_cancelTimer invalidate];
[context->_cancelTimer release];
context->_cancelTimer = nil;
[_queries removeObjectForKey: ID];
@try {
of_dns_resolver_error_t error = 0;
bool tryNextNameServer = false;
const unsigned char *queryDataBuffer;
size_t i;
uint16_t numQuestions, numAnswers, numAuthorityRecords;
uint16_t numAdditionalRecords;
if (length < 12)
|
|
|
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
|
[context->_cancelTimer invalidate];
[context->_cancelTimer release];
context->_cancelTimer = nil;
[_queries removeObjectForKey: ID];
@try {
OFDNSResolverErrorCode errorCode = 0;
bool tryNextNameServer = false;
const unsigned char *queryDataBuffer;
size_t i;
uint16_t numQuestions, numAnswers, numAuthorityRecords;
uint16_t numAdditionalRecords;
if (length < 12)
|
︙ | | | ︙ | |
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
|
}
/* RCODE */
switch (buffer[3] & 0x0F) {
case 0:
break;
case 1:
error = OF_DNS_RESOLVER_ERROR_SERVER_INVALID_FORMAT;
break;
case 2:
error = OF_DNS_RESOLVER_ERROR_SERVER_FAILURE;
tryNextNameServer = true;
break;
case 3:
error = OF_DNS_RESOLVER_ERROR_SERVER_NAME_ERROR;
break;
case 4:
error = OF_DNS_RESOLVER_ERROR_SERVER_NOT_IMPLEMENTED;
tryNextNameServer = true;
break;
case 5:
error = OF_DNS_RESOLVER_ERROR_SERVER_REFUSED;
tryNextNameServer = true;
break;
default:
error = OF_DNS_RESOLVER_ERROR_UNKNOWN;
tryNextNameServer = true;
break;
}
if (tryNextNameServer) {
if (context->_nameServersIndex + 1 <
context->_settings->_nameServers.count) {
|
|
|
|
|
|
|
|
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
|
}
/* RCODE */
switch (buffer[3] & 0x0F) {
case 0:
break;
case 1:
errorCode = OFDNSResolverErrorCodeServerInvalidFormat;
break;
case 2:
errorCode = OFDNSResolverErrorCodeServerFailure;
tryNextNameServer = true;
break;
case 3:
errorCode = OFDNSResolverErrorCodeServerNameError;
break;
case 4:
errorCode = OFDNSResolverErrorCodeServerNotImplemented;
tryNextNameServer = true;
break;
case 5:
errorCode = OFDNSResolverErrorCodeServerRefused;
tryNextNameServer = true;
break;
default:
errorCode = OFDNSResolverErrorCodeUnknown;
tryNextNameServer = true;
break;
}
if (tryNextNameServer) {
if (context->_nameServersIndex + 1 <
context->_settings->_nameServers.count) {
|
︙ | | | ︙ | |
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
|
return false;
}
}
if (buffer[3] & 0x0F)
@throw [OFDNSQueryFailedException
exceptionWithQuery: context->_query
error: error];
numQuestions = (buffer[4] << 8) | buffer[5];
numAnswers = (buffer[6] << 8) | buffer[7];
numAuthorityRecords = (buffer[8] << 8) | buffer[9];
numAdditionalRecords = (buffer[10] << 8) | buffer[11];
i = 12;
|
|
|
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
|
return false;
}
}
if (buffer[3] & 0x0F)
@throw [OFDNSQueryFailedException
exceptionWithQuery: context->_query
errorCode: errorCode];
numQuestions = (buffer[4] << 8) | buffer[5];
numAnswers = (buffer[6] << 8) | buffer[7];
numAuthorityRecords = (buffer[8] << 8) | buffer[9];
numAdditionalRecords = (buffer[10] << 8) | buffer[11];
i = 12;
|
︙ | | | ︙ | |
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
|
enumerator = [_queries objectEnumerator];
while ((context = [enumerator nextObject]) != nil) {
OFDNSQueryFailedException *exception;
exception = [OFDNSQueryFailedException
exceptionWithQuery: context->_query
error: OF_DNS_RESOLVER_ERROR_CANCELED];
[context->_delegate resolver: self
didPerformQuery: context->_query
response: nil
exception: exception];
}
[_queries removeAllObjects];
objc_autoreleasePoolPop(pool);
}
@end
|
|
|
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
|
enumerator = [_queries objectEnumerator];
while ((context = [enumerator nextObject]) != nil) {
OFDNSQueryFailedException *exception;
exception = [OFDNSQueryFailedException
exceptionWithQuery: context->_query
errorCode: OFDNSResolverErrorCodeCanceled];
[context->_delegate resolver: self
didPerformQuery: context->_query
response: nil
exception: exception];
}
[_queries removeAllObjects];
objc_autoreleasePoolPop(pool);
}
@end
|