ObjFW  Diff

Differences From Artifact [2303b7b240]:

To Artifact [b26d10f3a6]:


195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
	   recursion: (unsigned int)recursion
	      result: (OFMutableArray *)result;
-    (void)resolver: (OFDNSResolver *)resolver
    didResolveCNAME: (OFString *)CNAME
      answerRecords: (OFDictionary *)answerRecords
   authorityRecords: (OFDictionary *)authorityRecords
  additionalRecords: (OFDictionary *)additionalRecords
	    context: (id)context
	  exception: (id)exception;
- (void)done;
-	(void)resolver: (OFDNSResolver *)resolver
  didResolveDomainName: (OFString *)domainName
	 answerRecords: (OFDictionary *)answerRecords
      authorityRecords: (OFDictionary *)authorityRecords
     additionalRecords: (OFDictionary *)additionalRecords
	       context: (id)context
	     exception: (id)exception;
@end

@interface OFDNSResolver_ResolveSocketAddressesDelegate: OFObject
    <OFDNSResolverDelegate>
{
@public







|







|







195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
	   recursion: (unsigned int)recursion
	      result: (OFMutableArray *)result;
-    (void)resolver: (OFDNSResolver *)resolver
    didResolveCNAME: (OFString *)CNAME
      answerRecords: (OFDictionary *)answerRecords
   authorityRecords: (OFDictionary *)authorityRecords
  additionalRecords: (OFDictionary *)additionalRecords
	    context: (OFNumber *)context
	  exception: (id)exception;
- (void)done;
-	(void)resolver: (OFDNSResolver *)resolver
  didResolveDomainName: (OFString *)domainName
	 answerRecords: (OFDictionary *)answerRecords
      authorityRecords: (OFDictionary *)authorityRecords
     additionalRecords: (OFDictionary *)additionalRecords
	       context: (OFNumber *)context
	     exception: (id)exception;
@end

@interface OFDNSResolver_ResolveSocketAddressesDelegate: OFObject
    <OFDNSResolverDelegate>
{
@public
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
		/* Not an IP address -> we can use it if it contains a dot. */
		size_t pos = [domain rangeOfString: @"."].location;

		if (pos == OF_NOT_FOUND)
			return nil;

		return [domain substringWithRange:
		    of_range(pos + 1, [domain length] - pos - 1)];
	}
}
#endif

static bool
isFQDN(OFString *host, OFDNSResolverSettings *settings)
{
	const char *UTF8String = [host UTF8String];
	size_t length = [host UTF8StringLength];
	unsigned int dots = 0;

	if ([host hasSuffix: @"."])
		return true;

	for (size_t i = 0; i < length; i++)
		if (UTF8String[i] == '.')







|







|
|







288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
		/* Not an IP address -> we can use it if it contains a dot. */
		size_t pos = [domain rangeOfString: @"."].location;

		if (pos == OF_NOT_FOUND)
			return nil;

		return [domain substringWithRange:
		    of_range(pos + 1, domain.length - pos - 1)];
	}
}
#endif

static bool
isFQDN(OFString *host, OFDNSResolverSettings *settings)
{
	const char *UTF8String = host.UTF8String;
	size_t length = host.UTF8StringLength;
	unsigned int dots = 0;

	if ([host hasSuffix: @"."])
		return true;

	for (size_t i = 0; i < length; i++)
		if (UTF8String[i] == '.')
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
				/* Pointing to itself?! */
				@throw [OFInvalidServerReplyException
				    exception];

			suffix = parseName(buffer, length, &j,
			    pointerLevel - 1);

			if ([components count] == 0)
				return suffix;
			else {
				[components addObject: suffix];
				return [components
				    componentsJoinedByString: @"."];
			}
		}







|







367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
				/* Pointing to itself?! */
				@throw [OFInvalidServerReplyException
				    exception];

			suffix = parseName(buffer, length, &j,
			    pointerLevel - 1);

			if (components.count == 0)
				return suffix;
			else {
				[components addObject: suffix];
				return [components
				    componentsJoinedByString: @"."];
			}
		}
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
		_selector = selector;
		_context = [context retain];

		queryData = [OFMutableData dataWithCapacity: 512];

		/* Header */

		tmp = OF_BSWAP16_IF_LE([ID uInt16Value]);
		[queryData addItems: &tmp
			      count: 2];

		/* RD */
		tmp = OF_BSWAP16_IF_LE(1 << 8);
		[queryData addItems: &tmp
			      count: 2];







|







757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
		_selector = selector;
		_context = [context retain];

		queryData = [OFMutableData dataWithCapacity: 512];

		/* Header */

		tmp = OF_BSWAP16_IF_LE(ID.uInt16Value);
		[queryData addItems: &tmp
			      count: 2];

		/* RD */
		tmp = OF_BSWAP16_IF_LE(1 << 8);
		[queryData addItems: &tmp
			      count: 2];
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
		[queryData increaseCountBy: 6];

		/* Question */

		/* QNAME */
		for (OFString *component in
		    [domainName componentsSeparatedByString: @"."]) {
			size_t length = [component UTF8StringLength];
			uint8_t length8;

			if (length > 63 || [queryData count] + length > 512)
				@throw [OFOutOfRangeException exception];

			length8 = (uint8_t)length;
			[queryData addItem: &length8];
			[queryData addItems: [component UTF8String]
				      count: length];
		}

		/* QTYPE */
		tmp = OF_BSWAP16_IF_LE(recordType);
		[queryData addItems: &tmp
			      count: 2];







|


|




|







779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
		[queryData increaseCountBy: 6];

		/* Question */

		/* QNAME */
		for (OFString *component in
		    [domainName componentsSeparatedByString: @"."]) {
			size_t length = component.UTF8StringLength;
			uint8_t length8;

			if (length > 63 || queryData.count + length > 512)
				@throw [OFOutOfRangeException exception];

			length8 = (uint8_t)length;
			[queryData addItem: &length8];
			[queryData addItems: component.UTF8String
				      count: length];
		}

		/* QTYPE */
		tmp = OF_BSWAP16_IF_LE(recordType);
		[queryData addItems: &tmp
			      count: 2];
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
   additionalRecords: (OFDictionary *)additionalRecords
	  recordType: (of_dns_resource_record_type_t)recordType
	   recursion: (unsigned int)recursion
	      result: (OFMutableArray *)result
{
	bool found = false;

	for (OF_KINDOF(OFDNSResourceRecord *) record in records) {
		if ([record recordClass] != OF_DNS_RESOURCE_RECORD_CLASS_IN)
			continue;

		if ([record recordType] == recordType) {
			[result addObject: record];
			found = true;
		} else if ([record recordType] ==
		    OF_DNS_RESOURCE_RECORD_TYPE_CNAME) {
			[self	resolveCNAME: record
			       answerRecords: answerRecords
			   additionalRecords: additionalRecords
				  recordType: recordType
				   recursion: recursion
				      result: result];
			found = true;
		}
	}

	return found;
}

- (void)resolveCNAME: (OFCNAMEDNSResourceRecord *)CNAME
       answerRecords: (OFDictionary *)answerRecords
   additionalRecords: (OFDictionary *)additionalRecords
	  recordType: (of_dns_resource_record_type_t)recordType
	   recursion: (unsigned int)recursion
	      result: (OFMutableArray *)result
{
	OFString *alias = [CNAME alias];
	bool found = false;

	if (recursion == 0)
		return;

	if ([self parseRecords: [answerRecords objectForKey: alias]
		 answerRecords: answerRecords







|
|


|


|

|



















|







868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
   additionalRecords: (OFDictionary *)additionalRecords
	  recordType: (of_dns_resource_record_type_t)recordType
	   recursion: (unsigned int)recursion
	      result: (OFMutableArray *)result
{
	bool found = false;

	for (OFDNSResourceRecord *record in records) {
		if (record.recordClass != OF_DNS_RESOURCE_RECORD_CLASS_IN)
			continue;

		if (record.recordType == recordType) {
			[result addObject: record];
			found = true;
		} else if (record.recordType ==
		    OF_DNS_RESOURCE_RECORD_TYPE_CNAME) {
			[self	resolveCNAME: (OFCNAMEDNSResourceRecord *)record
			       answerRecords: answerRecords
			   additionalRecords: additionalRecords
				  recordType: recordType
				   recursion: recursion
				      result: result];
			found = true;
		}
	}

	return found;
}

- (void)resolveCNAME: (OFCNAMEDNSResourceRecord *)CNAME
       answerRecords: (OFDictionary *)answerRecords
   additionalRecords: (OFDictionary *)additionalRecords
	  recordType: (of_dns_resource_record_type_t)recordType
	   recursion: (unsigned int)recursion
	      result: (OFMutableArray *)result
{
	OFString *alias = CNAME.alias;
	bool found = false;

	if (recursion == 0)
		return;

	if ([self parseRecords: [answerRecords objectForKey: alias]
		 answerRecords: answerRecords
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
		    recordType: recordType
		     recursion: recursion - 1
			result: result])
		found = true;

	if (!found) {
		of_run_loop_mode_t runLoopMode =
		    [[OFRunLoop currentRunLoop] currentMode];
		OFNumber *recordTypeNumber =
		    [OFNumber numberWithInt: recordType];

		_expectedResponses++;

		[result addObject:
		    [OFPair pairWithFirstObject: CNAME







|







921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
		    recordType: recordType
		     recursion: recursion - 1
			result: result])
		found = true;

	if (!found) {
		of_run_loop_mode_t runLoopMode =
		    [OFRunLoop currentRunLoop].currentMode;
		OFNumber *recordTypeNumber =
		    [OFNumber numberWithInt: recordType];

		_expectedResponses++;

		[result addObject:
		    [OFPair pairWithFirstObject: CNAME
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
}

-    (void)resolver: (OFDNSResolver *)resolver
    didResolveCNAME: (OFString *)CNAME
      answerRecords: (OFDictionary *)answerRecords
   authorityRecords: (OFDictionary *)authorityRecords
  additionalRecords: (OFDictionary *)additionalRecords
	    context: (id)context
	  exception: (id)exception
{
	/*
	 * TODO: Error handling could be improved. Ignore error if there are
	 * responses, otherwise propagate error.
	 */

	of_dns_resource_record_type_t recordType = [context unsignedIntValue];
	bool found = false;
	OFMutableArray *records;
	size_t count;

	OF_ENSURE(resolver == _resolver);

	_expectedResponses--;







|







|







951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
}

-    (void)resolver: (OFDNSResolver *)resolver
    didResolveCNAME: (OFString *)CNAME
      answerRecords: (OFDictionary *)answerRecords
   authorityRecords: (OFDictionary *)authorityRecords
  additionalRecords: (OFDictionary *)additionalRecords
	    context: (OFNumber *)context
	  exception: (id)exception
{
	/*
	 * TODO: Error handling could be improved. Ignore error if there are
	 * responses, otherwise propagate error.
	 */

	of_dns_resource_record_type_t recordType = context.unsignedIntValue;
	bool found = false;
	OFMutableArray *records;
	size_t count;

	OF_ENSURE(resolver == _resolver);

	_expectedResponses--;
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
	if (!found) {
		if (_expectedResponses == 0)
			[self done];

		return;
	}

	count = [_records count];
	for (size_t i = 0; i < count; i++) {
		id object = [_records objectAtIndex: i];

		if (![object isKindOfClass: [OFPair class]])
			continue;

		if (![[[object firstObject] alias] isEqual: CNAME])
			continue;

		if ([[object secondObject] unsignedIntValue] != recordType)
			continue;

		[_records removeObjectAtIndex: i];
		[_records insertObjectsFromArray: records
					 atIndex: i];
		i += [records count] - 1;
	}

	if (_expectedResponses == 0)
		[self done];
}

- (void)done







|















|







1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
	if (!found) {
		if (_expectedResponses == 0)
			[self done];

		return;
	}

	count = _records.count;
	for (size_t i = 0; i < count; i++) {
		id object = [_records objectAtIndex: i];

		if (![object isKindOfClass: [OFPair class]])
			continue;

		if (![[[object firstObject] alias] isEqual: CNAME])
			continue;

		if ([[object secondObject] unsignedIntValue] != recordType)
			continue;

		[_records removeObjectAtIndex: i];
		[_records insertObjectsFromArray: records
					 atIndex: i];
		i += records.count - 1;
	}

	if (_expectedResponses == 0)
		[self done];
}

- (void)done
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
		default:
			break;
		}
	}

	[addresses makeImmutable];

	if ([addresses count] == 0)
		exception = [OFResolveHostFailedException
		    exceptionWithHost: _host
			  recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN
			   recordType: 0
				error: OF_DNS_RESOLVER_ERROR_UNKNOWN];

	if ([_delegate respondsToSelector: @selector(
	    resolver:didResolveDomainName:socketAddresses:exception:)])
		[_delegate	resolver: _resolver
		    didResolveDomainName: _domainName
			 socketAddresses: (exception == nil ? addresses : nil)
			       exception: exception];
}

-	(void)resolver: (OFDNSResolver *)resolver
  didResolveDomainName: (OFString *)domainName
	 answerRecords: (OFDictionary *)answerRecords
      authorityRecords: (OFDictionary *)authorityRecords
     additionalRecords: (OFDictionary *)additionalRecords
	       context: (id)context
	     exception: (id)exception
{
	/*
	 * TODO: Error handling could be improved. Ignore error if there are
	 * responses, otherwise propagate error.
	 */

	of_dns_resource_record_type_t recordType = [context unsignedIntValue];

	if (_resolver != nil)
		OF_ENSURE(resolver == _resolver);
	else
		_resolver = [resolver retain];

	_expectedResponses--;







|



















|







|







1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
		default:
			break;
		}
	}

	[addresses makeImmutable];

	if (addresses.count == 0)
		exception = [OFResolveHostFailedException
		    exceptionWithHost: _host
			  recordClass: OF_DNS_RESOURCE_RECORD_CLASS_IN
			   recordType: 0
				error: OF_DNS_RESOLVER_ERROR_UNKNOWN];

	if ([_delegate respondsToSelector: @selector(
	    resolver:didResolveDomainName:socketAddresses:exception:)])
		[_delegate	resolver: _resolver
		    didResolveDomainName: _domainName
			 socketAddresses: (exception == nil ? addresses : nil)
			       exception: exception];
}

-	(void)resolver: (OFDNSResolver *)resolver
  didResolveDomainName: (OFString *)domainName
	 answerRecords: (OFDictionary *)answerRecords
      authorityRecords: (OFDictionary *)authorityRecords
     additionalRecords: (OFDictionary *)additionalRecords
	       context: (OFNumber *)context
	     exception: (id)exception
{
	/*
	 * TODO: Error handling could be improved. Ignore error if there are
	 * responses, otherwise propagate error.
	 */

	of_dns_resource_record_type_t recordType = context.unsignedIntValue;

	if (_resolver != nil)
		OF_ENSURE(resolver == _resolver);
	else
		_resolver = [resolver retain];

	_expectedResponses--;
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
		if (pos != OF_NOT_FOUND)
			line = [line substringWithRange: of_range(0, pos)];

		components = [line
		    componentsSeparatedByCharactersInSet: whitespaceCharacterSet
						 options: OF_STRING_SKIP_EMPTY];

		if ([components count] < 2) {
			objc_autoreleasePoolPop(pool2);
			continue;
		}

		address = [components firstObject];
		hosts = [components objectsInRange:
		    of_range(1, [components count] - 1)];

		for (OFString *host in hosts) {
			addresses = [staticHosts objectForKey: host];

			if (addresses == nil) {
				addresses = [OFMutableArray array];
				[staticHosts setObject: addresses







|




|

|







1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
		if (pos != OF_NOT_FOUND)
			line = [line substringWithRange: of_range(0, pos)];

		components = [line
		    componentsSeparatedByCharactersInSet: whitespaceCharacterSet
						 options: OF_STRING_SKIP_EMPTY];

		if (components.count < 2) {
			objc_autoreleasePoolPop(pool2);
			continue;
		}

		address = components.firstObject;
		hosts = [components objectsInRange:
		    of_range(1, components.count - 1)];

		for (OFString *host in hosts) {
			addresses = [staticHosts objectForKey: host];

			if (addresses == nil) {
				addresses = [OFMutableArray array];
				[staticHosts setObject: addresses
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
		if (pos != OF_NOT_FOUND)
			line = [line substringWithRange: of_range(0, pos)];

		components = [line
		    componentsSeparatedByCharactersInSet: whitespaceCharacterSet
						 options: OF_STRING_SKIP_EMPTY];

		if ([components count] < 2) {
			objc_autoreleasePoolPop(pool2);
			continue;
		}

		option = [components firstObject];
		arguments = [components objectsInRange:
		    of_range(1, [components count] - 1)];

		if ([option isEqual: @"nameserver"]) {
			if ([arguments count] != 1) {
				objc_autoreleasePoolPop(pool2);
				continue;
			}

			[nameServers addObject: [arguments firstObject]];
		} else if ([option isEqual: @"domain"]) {
			if ([arguments count] != 1) {
				objc_autoreleasePoolPop(pool2);
				continue;
			}

			[_localDomain release];
			_localDomain = [[arguments firstObject] copy];
		} else if ([option isEqual: @"search"]) {
			[_searchDomains release];
			_searchDomains = [arguments copy];
		} else if ([option isEqual: @"options"])
			for (OFString *argument in arguments)
				[self of_parseResolvConfOption: argument];








|




|

|


|






|





|







1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
		if (pos != OF_NOT_FOUND)
			line = [line substringWithRange: of_range(0, pos)];

		components = [line
		    componentsSeparatedByCharactersInSet: whitespaceCharacterSet
						 options: OF_STRING_SKIP_EMPTY];

		if (components.count < 2) {
			objc_autoreleasePoolPop(pool2);
			continue;
		}

		option = components.firstObject;
		arguments = [components objectsInRange:
		    of_range(1, components.count - 1)];

		if ([option isEqual: @"nameserver"]) {
			if (arguments.count != 1) {
				objc_autoreleasePoolPop(pool2);
				continue;
			}

			[nameServers addObject: [arguments firstObject]];
		} else if ([option isEqual: @"domain"]) {
			if (arguments.count != 1) {
				objc_autoreleasePoolPop(pool2);
				continue;
			}

			[_localDomain release];
			_localDomain = [arguments.firstObject copy];
		} else if ([option isEqual: @"search"]) {
			[_searchDomains release];
			_searchDomains = [arguments copy];
		} else if ([option isEqual: @"options"])
			for (OFString *argument in arguments)
				[self of_parseResolvConfOption: argument];

1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
}

- (void)of_parseResolvConfOption: (OFString *)option
{
	@try {
		if ([option hasPrefix: @"ndots:"]) {
			option = [option substringWithRange:
			    of_range(6, [option length] - 6)];

			_minNumberOfDotsInAbsoluteName =
			    (unsigned int)[option decimalValue];
		} else if ([option hasPrefix: @"timeout:"]) {
			option = [option substringWithRange:
			    of_range(8, [option length] - 8)];

			_timeout = [option decimalValue];
		} else if ([option hasPrefix: @"attempts:"]) {
			option = [option substringWithRange:
			    of_range(9, [option length] - 9)];

			_maxAttempts = (unsigned int)[option decimalValue];
		} else if ([option hasPrefix: @"reload-period:"]) {
			option = [option substringWithRange:
			    of_range(14, [option length] - 14)];

			_configReloadInterval = [option decimalValue];
		} else if ([option isEqual: @"tcp"])
			_usesTCP = true;
	} @catch (OFInvalidFormatException *e) {
	}
}
# endif
#endif







|


|


|

|


|

|


|

|







1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
}

- (void)of_parseResolvConfOption: (OFString *)option
{
	@try {
		if ([option hasPrefix: @"ndots:"]) {
			option = [option substringWithRange:
			    of_range(6, option.length - 6)];

			_minNumberOfDotsInAbsoluteName =
			    (unsigned int)option.decimalValue;
		} else if ([option hasPrefix: @"timeout:"]) {
			option = [option substringWithRange:
			    of_range(8, option.length - 8)];

			_timeout = option.decimalValue;
		} else if ([option hasPrefix: @"attempts:"]) {
			option = [option substringWithRange:
			    of_range(9, option.length - 9)];

			_maxAttempts = (unsigned int)option.decimalValue;
		} else if ([option hasPrefix: @"reload-period:"]) {
			option = [option substringWithRange:
			    of_range(14, option.length - 14)];

			_configReloadInterval = option.decimalValue;
		} else if ([option isEqual: @"tcp"])
			_usesTCP = true;
	} @catch (OFInvalidFormatException *e) {
	}
}
# endif
#endif
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
	nameServers = [OFMutableArray array];

	for (iter = &fixedInfo->DnsServerList; iter != NULL; iter = iter->Next)
		[nameServers addObject:
		    [OFString stringWithCString: iter->IpAddress.String
				       encoding: encoding]];

	if ([nameServers count] > 0) {
		[nameServers makeImmutable];
		_nameServers = [nameServers copy];
	}

	if (fixedInfo->DomainName[0] != '\0')
		_localDomain = [[OFString alloc]
		    initWithCString: fixedInfo->DomainName







|







1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
	nameServers = [OFMutableArray array];

	for (iter = &fixedInfo->DnsServerList; iter != NULL; iter = iter->Next)
		[nameServers addObject:
		    [OFString stringWithCString: iter->IpAddress.String
				       encoding: encoding]];

	if (nameServers.count > 0) {
		[nameServers makeImmutable];
		_nameServers = [nameServers copy];
	}

	if (fixedInfo->DomainName[0] != '\0')
		_localDomain = [[OFString alloc]
		    initWithCString: fixedInfo->DomainName
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
			iter = (struct DomainNameServerNode *)
			    iter->dnsn_MinNode.mln_Succ;
		}
	} @finally {
		ReleaseDomainNameServerList(nameServerList);
	}

	if ([nameServers count] > 0) {
		[nameServers makeImmutable];
		_nameServers = [nameServers copy];
	}

	if (GetDefaultDomainName(buffer, sizeof(buffer)))
		_localDomain = [[OFString alloc] initWithCString: buffer
							encoding: encoding];







|







1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
			iter = (struct DomainNameServerNode *)
			    iter->dnsn_MinNode.mln_Succ;
		}
	} @finally {
		ReleaseDomainNameServerList(nameServerList);
	}

	if (nameServers.count > 0) {
		[nameServers makeImmutable];
		_nameServers = [nameServers copy];
	}

	if (GetDefaultDomainName(buffer, sizeof(buffer)))
		_localDomain = [[OFString alloc] initWithCString: buffer
							encoding: encoding];
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
			continue;

		[nameServers addObject: [OFString stringWithFormat:
		    @"%u.%u.%u.%u", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF,
		    (ip >> 8) & 0xFF, ip & 0xFF]];
	}

	if ([nameServers count] > 0) {
		[nameServers makeImmutable];
		_nameServers = [nameServers copy];
	}
}
#endif

- (void)of_reloadSystemConfig
{
	/*
	 * TODO: Rather than reparsing every, check what actually changed
	 * (mtime) and only reset those.
	 */

	if (_lastConfigReload != nil && _configReloadInterval > 0 &&
	    [_lastConfigReload timeIntervalSinceNow] < _configReloadInterval)
		return;

	[_staticHosts release];
	_staticHosts = nil;

	[_nameServers release];
	_nameServers = nil;







|














|







1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
			continue;

		[nameServers addObject: [OFString stringWithFormat:
		    @"%u.%u.%u.%u", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF,
		    (ip >> 8) & 0xFF, ip & 0xFF]];
	}

	if (nameServers.count > 0) {
		[nameServers makeImmutable];
		_nameServers = [nameServers copy];
	}
}
#endif

- (void)of_reloadSystemConfig
{
	/*
	 * TODO: Rather than reparsing every, check what actually changed
	 * (mtime) and only reset those.
	 */

	if (_lastConfigReload != nil && _configReloadInterval > 0 &&
	    _lastConfigReload.timeIntervalSinceNow < _configReloadInterval)
		return;

	[_staticHosts release];
	_staticHosts = nil;

	[_nameServers release];
	_nameServers = nil;
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
		OFString *searchDomain = [settings->_searchDomains
		    objectAtIndex: searchDomainsIndex];

		domainName = [OFString stringWithFormat: @"%@.%@.",
		    host, searchDomain];
	}

	if ([domainName UTF8StringLength] > 253)
		@throw [OFOutOfRangeException exception];

	query = [[[OFDNSResolverQuery alloc]
		  initWithHost: host
		    domainName: domainName
		   recordClass: recordClass
		    recordType: recordType







|







1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
		OFString *searchDomain = [settings->_searchDomains
		    objectAtIndex: searchDomainsIndex];

		domainName = [OFString stringWithFormat: @"%@.%@.",
		    host, searchDomain];
	}

	if (domainName.UTF8StringLength > 253)
		@throw [OFOutOfRangeException exception];

	query = [[[OFDNSResolverQuery alloc]
		  initWithHost: host
		    domainName: domainName
		   recordClass: recordClass
		    recordType: recordType
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
		if (_IPv6Socket == nil) {
			of_socket_address_t address =
			    of_socket_address_parse_ip(@"::", 0);

			_IPv6Socket = [[OFUDPSocket alloc] init];
			[_IPv6Socket of_bindToAddress: &address
					    extraType: SOCK_DNS];
			[_IPv6Socket setBlocking: false];
			[_IPv6Socket setDelegate: self];
			[_IPv6Socket asyncReceiveIntoBuffer: _buffer
						     length: BUFFER_LENGTH];
		}

		sock = _IPv6Socket;
		break;
#endif
	case OF_SOCKET_ADDRESS_FAMILY_IPV4:
		if (_IPv4Socket == nil) {
			of_socket_address_t address =
			    of_socket_address_parse_ip(@"0.0.0.0", 0);

			_IPv4Socket = [[OFUDPSocket alloc] init];
			[_IPv4Socket of_bindToAddress: &address
					    extraType: SOCK_DNS];
			[_IPv4Socket setBlocking: false];
			[_IPv4Socket setDelegate: self];
			[_IPv4Socket asyncReceiveIntoBuffer: _buffer
						     length: BUFFER_LENGTH];
		}

		sock = _IPv4Socket;
		break;
	default:







|
|















|
|







1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
		if (_IPv6Socket == nil) {
			of_socket_address_t address =
			    of_socket_address_parse_ip(@"::", 0);

			_IPv6Socket = [[OFUDPSocket alloc] init];
			[_IPv6Socket of_bindToAddress: &address
					    extraType: SOCK_DNS];
			_IPv6Socket.blocking = false;
			_IPv6Socket.delegate = self;
			[_IPv6Socket asyncReceiveIntoBuffer: _buffer
						     length: BUFFER_LENGTH];
		}

		sock = _IPv6Socket;
		break;
#endif
	case OF_SOCKET_ADDRESS_FAMILY_IPV4:
		if (_IPv4Socket == nil) {
			of_socket_address_t address =
			    of_socket_address_parse_ip(@"0.0.0.0", 0);

			_IPv4Socket = [[OFUDPSocket alloc] init];
			[_IPv4Socket of_bindToAddress: &address
					    extraType: SOCK_DNS];
			_IPv4Socket.blocking = false;
			_IPv4Socket.delegate = self;
			[_IPv4Socket asyncReceiveIntoBuffer: _buffer
						     length: BUFFER_LENGTH];
		}

		sock = _IPv4Socket;
		break;
	default:
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
{
	OFResolveHostFailedException *exception;

	if (query == nil)
		return;

	if (query->_nameServersIndex + 1 <
	    [query->_settings->_nameServers count]) {
		query->_nameServersIndex++;
		[self of_sendQuery: query
		       runLoopMode: [[OFRunLoop currentRunLoop] currentMode]];
		return;
	}

	if (query->_attempt < query->_settings->_maxAttempts) {
		query->_attempt++;
		query->_nameServersIndex = 0;
		[self of_sendQuery: query
		       runLoopMode: [[OFRunLoop currentRunLoop] currentMode]];
		return;
	}

	query = [[query retain] autorelease];
	[_queries removeObjectForKey: query->_ID];

	/*







|


|







|







1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
{
	OFResolveHostFailedException *exception;

	if (query == nil)
		return;

	if (query->_nameServersIndex + 1 <
	    query->_settings->_nameServers.count) {
		query->_nameServersIndex++;
		[self of_sendQuery: query
		       runLoopMode: [OFRunLoop currentRunLoop].currentMode];
		return;
	}

	if (query->_attempt < query->_settings->_maxAttempts) {
		query->_attempt++;
		query->_nameServersIndex = 0;
		[self of_sendQuery: query
		       runLoopMode: [OFRunLoop currentRunLoop].currentMode];
		return;
	}

	query = [[query retain] autorelease];
	[_queries removeObjectForKey: query->_ID];

	/*
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
		   recordType: query->_recordType
			error: OF_DNS_RESOLVER_ERROR_TIMEOUT];

	callback(query->_target, query->_selector, self, query->_domainName,
	    nil, nil, nil, query->_context, exception);
}

-	  (bool)socket: (OF_KINDOF(OFUDPSocket *))sock
  didReceiveIntoBuffer: (void *)buffer_
		length: (size_t)length
		sender: (const of_socket_address_t *)sender
	     exception: (id)exception
{
	unsigned char *buffer = buffer_;
	OFDictionary *answerRecords = nil, *authorityRecords = nil;







|







1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
		   recordType: query->_recordType
			error: OF_DNS_RESOLVER_ERROR_TIMEOUT];

	callback(query->_target, query->_selector, self, query->_domainName,
	    nil, nil, nil, query->_context, exception);
}

-	  (bool)socket: (OFUDPSocket *)sock
  didReceiveIntoBuffer: (void *)buffer_
		length: (size_t)length
		sender: (const of_socket_address_t *)sender
	     exception: (id)exception
{
	unsigned char *buffer = buffer_;
	OFDictionary *answerRecords = nil, *authorityRecords = nil;
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
		of_dns_resolver_error_t error;
		uint16_t numQuestions, numAnswers, numAuthorityRecords;
		uint16_t numAdditionalRecords;

		if (length < 12)
			@throw [OFTruncatedDataException exception];

		if ([query->_queryData itemSize] != 1 ||
		    [query->_queryData count] < 12)
			@throw [OFInvalidArgumentException exception];

		queryDataBuffer = [query->_queryData items];

		/* QR */
		if ((buffer[2] & 0x80) == 0)
			@throw [OFInvalidServerReplyException exception];

		/* Opcode */
		if ((buffer[2] & 0x78) != (queryDataBuffer[2] & 0x78))







|
|


|







1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
		of_dns_resolver_error_t error;
		uint16_t numQuestions, numAnswers, numAuthorityRecords;
		uint16_t numAdditionalRecords;

		if (length < 12)
			@throw [OFTruncatedDataException exception];

		if (query->_queryData.itemSize != 1 ||
		    query->_queryData.count < 12)
			@throw [OFInvalidArgumentException exception];

		queryDataBuffer = query->_queryData.items;

		/* QR */
		if ((buffer[2] & 0x80) == 0)
			@throw [OFInvalidServerReplyException exception];

		/* Opcode */
		if ((buffer[2] & 0x78) != (queryDataBuffer[2] & 0x78))
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
			error = OF_DNS_RESOLVER_ERROR_SERVER_INVALID_FORMAT;
			break;
		case 2:
			error = OF_DNS_RESOLVER_ERROR_SERVER_FAILURE;
			break;
		case 3:
			if (query->_searchDomainsIndex + 1 <
			    [query->_settings->_searchDomains count]) {
				of_run_loop_mode_t runLoopMode =
				    [[OFRunLoop currentRunLoop] currentMode];

				query->_searchDomainsIndex++;

				[self of_resolveHost: query->_host
					 recordClass: query->_recordClass
					  recordType: query->_recordType
					    settings: query->_settings







|

|







1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
			error = OF_DNS_RESOLVER_ERROR_SERVER_INVALID_FORMAT;
			break;
		case 2:
			error = OF_DNS_RESOLVER_ERROR_SERVER_FAILURE;
			break;
		case 3:
			if (query->_searchDomainsIndex + 1 <
			    query->_settings->_searchDomains.count) {
				of_run_loop_mode_t runLoopMode =
				    [OFRunLoop currentRunLoop].currentMode;

				query->_searchDomainsIndex++;

				[self of_resolveHost: query->_host
					 recordClass: query->_recordClass
					  recordType: query->_recordType
					    settings: query->_settings
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
				continue;

			[addresses addItem: &address];
		}

		[addresses makeImmutable];

		if ([addresses count] == 0) {
			of_dns_resource_record_type_t recordType = 0;

			addresses = nil;

			switch (addressFamily) {
			case OF_SOCKET_ADDRESS_FAMILY_ANY:
				recordType = OF_DNS_RESOURCE_RECORD_TYPE_ALL;







|







2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
				continue;

			[addresses addItem: &address];
		}

		[addresses makeImmutable];

		if (addresses.count == 0) {
			of_dns_resource_record_type_t recordType = 0;

			addresses = nil;

			switch (addressFamily) {
			case OF_SOCKET_ADDRESS_FAMILY_ANY:
				recordType = OF_DNS_RESOURCE_RECORD_TYPE_ALL;