58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
+
|
* TODO:
*
* - 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;
OFArray OF_GENERIC(OFString *) *_nameServers, *_searchDomains;
size_t _nameServersIndex, _searchDomainsIndex;
|
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
|
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
|
-
+
|
*idx = i;
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;
for (uint_fast8_t i = 0; i < 16; i += 2) {
|
240
241
242
243
244
245
246
247
248
249
250
251
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
299
300
301
302
|
241
242
243
244
245
246
247
248
249
250
251
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
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
|
-
+
-
-
-
+
+
+
+
+
+
+
-
+
+
-
+
+
-
-
+
+
+
+
+
+
+
|
}
[data makeImmutable];
return data;
}
static id
static OF_KINDOF(OFDNSResourceRecord *)
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)
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;
switch (recordType) {
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
exception];
break;
case OF_DNS_RESOURCE_RECORD_TYPE_AAAA:
if (dataLength != 16)
@throw [OFInvalidServerReplyException
exception];
class = [OFAAAADNSResourceRecord class];
data = parseAAAA(&buffer[i]);
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;
@synthesize nameServersIndex = _nameServersIndex;
@synthesize searchDomainsIndex = _searchDomainsIndex, queryData = _queryData;
|
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
|
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
|
-
+
-
+
-
-
-
-
-
-
-
-
|
for (uint_fast16_t j = 0; j < numAnswers; j++) {
OFString *name = parseName(buffer, length, &i,
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];
recordType = (buffer[i] << 16) | buffer[i + 1];
recordClass = (buffer[i + 2] << 16) | buffer[i + 3];
TTL = (buffer[i + 4] << 24) | (buffer[i + 5] << 16) |
(buffer[i + 6] << 8) | buffer[i + 7];
dataLength = (buffer[i + 8] << 16) | buffer[i + 9];
i += 10;
if (i + dataLength > length)
@throw [OFTruncatedDataException exception];
record = createResourceRecord(name, recordClass,
data = parseData(buffer, length, i, dataLength,
recordType, TTL, buffer, length, i, dataLength);
recordClass, recordType);
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);
return false;
}
|