ObjFW  Diff

Differences From Artifact [2df523d351]:

To Artifact [536c83ec11]:


1
2
3
4
5
6
7
8
9
10
11
/*
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
 *               2018, 2019, 2020
 *   Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *

<
<
|







1


2
3
4
5
6
7
8
9
/*


 * Copyright (c) 2008-2021 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
		    buffer, length, *i, dataLength);
		*i += dataLength;

		array = [ret objectForKey: name];

		if (array == nil) {
			array = [OFMutableArray array];
			[ret setObject: array
				forKey: name];
		}

		[array addObject: record];
	}

	objectEnumerator = [ret objectEnumerator];
	while ((array = [objectEnumerator nextObject]) != nil)







|
<







449
450
451
452
453
454
455
456

457
458
459
460
461
462
463
		    buffer, length, *i, dataLength);
		*i += dataLength;

		array = [ret objectForKey: name];

		if (array == nil) {
			array = [OFMutableArray array];
			[ret setObject: array forKey: name];

		}

		[array addObject: record];
	}

	objectEnumerator = [ret objectEnumerator];
	while ((array = [objectEnumerator nextObject]) != nil)
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
		_delegate = [delegate retain];

		queryData = [OFMutableData dataWithCapacity: 512];

		/* Header */

		tmp = OF_BSWAP16_IF_LE(_ID.unsignedShortValue);
		[queryData addItems: &tmp
			      count: 2];

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

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

		/* ANCOUNT, NSCOUNT and ARCOUNT */
		[queryData increaseCountBy: 6];

		/* Question */

		/* QNAME */
		for (OFString *component in







|
<
<


|
<
<


|
<
<







487
488
489
490
491
492
493
494


495
496
497


498
499
500


501
502
503
504
505
506
507
		_delegate = [delegate retain];

		queryData = [OFMutableData dataWithCapacity: 512];

		/* Header */

		tmp = OF_BSWAP16_IF_LE(_ID.unsignedShortValue);
		[queryData addItems: &tmp count: 2];


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


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


		/* ANCOUNT, NSCOUNT and ARCOUNT */
		[queryData increaseCountBy: 6];

		/* Question */

		/* QNAME */
		for (OFString *component in
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
			[queryData addItem: &length8];
			[queryData addItems: component.UTF8String
				      count: length];
		}

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

		/* QCLASS */
		tmp = OF_BSWAP16_IF_LE(_query.DNSClass);
		[queryData addItems: &tmp
			      count: 2];

		[queryData makeImmutable];

		_queryData = [queryData copy];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];







|
<
<


|
<
<







516
517
518
519
520
521
522
523


524
525
526


527
528
529
530
531
532
533
			[queryData addItem: &length8];
			[queryData addItems: component.UTF8String
				      count: length];
		}

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


		/* QCLASS */
		tmp = OF_BSWAP16_IF_LE(_query.DNSClass);
		[queryData addItems: &tmp count: 2];


		[queryData makeImmutable];

		_queryData = [queryData copy];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729

- (void)of_sendQueryForContext: (OFDNSResolverContext *)context
		   runLoopMode: (of_run_loop_mode_t)runLoopMode
{
	OFUDPSocket *sock;
	OFString *nameServer;

	[_queries setObject: context
		     forKey: context->_ID];

	[context->_cancelTimer invalidate];
	[context->_cancelTimer release];
	context->_cancelTimer = nil;
	context->_cancelTimer = [[OFTimer alloc]
	    initWithFireDate: [OFDate dateWithTimeIntervalSinceNow:
				  context->_settings->_timeout]







|
<







701
702
703
704
705
706
707
708

709
710
711
712
713
714
715

- (void)of_sendQueryForContext: (OFDNSResolverContext *)context
		   runLoopMode: (of_run_loop_mode_t)runLoopMode
{
	OFUDPSocket *sock;
	OFString *nameServer;

	[_queries setObject: context forKey: context->_ID];


	[context->_cancelTimer invalidate];
	[context->_cancelTimer release];
	context->_cancelTimer = nil;
	context->_cancelTimer = [[OFTimer alloc]
	    initWithFireDate: [OFDate dateWithTimeIntervalSinceNow:
				  context->_settings->_timeout]
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
	nameServer = [context->_settings->_nameServers
	    objectAtIndex: context->_nameServersIndex];

	if (context->_settings->_usesTCP) {
		OF_ENSURE(context->_TCPSocket == nil);

		context->_TCPSocket = [[OFTCPSocket alloc] init];
		[_TCPQueries setObject: context
				forKey: context->_TCPSocket];

		context->_TCPSocket.delegate = self;
		[context->_TCPSocket asyncConnectToHost: nameServer
						   port: 53
					    runLoopMode: runLoopMode];
		return;
	}







|
<







724
725
726
727
728
729
730
731

732
733
734
735
736
737
738
	nameServer = [context->_settings->_nameServers
	    objectAtIndex: context->_nameServersIndex];

	if (context->_settings->_usesTCP) {
		OF_ENSURE(context->_TCPSocket == nil);

		context->_TCPSocket = [[OFTCPSocket alloc] init];
		[_TCPQueries setObject: context forKey: context->_TCPSocket];


		context->_TCPSocket.delegate = self;
		[context->_TCPSocket asyncConnectToHost: nameServer
						   port: 53
					    runLoopMode: runLoopMode];
		return;
	}
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
	}

	context = [[[OFDNSResolverContext alloc]
	    initWithQuery: query
		       ID: ID
		 settings: _settings
		 delegate: delegate] autorelease];
	[self of_sendQueryForContext: context
			 runLoopMode: runLoopMode];

	objc_autoreleasePoolPop(pool);
}

- (void)of_contextTimedOut: (OFDNSResolverContext *)context
{
	of_run_loop_mode_t runLoopMode = [OFRunLoop currentRunLoop].currentMode;







|
<







818
819
820
821
822
823
824
825

826
827
828
829
830
831
832
	}

	context = [[[OFDNSResolverContext alloc]
	    initWithQuery: query
		       ID: ID
		 settings: _settings
		 delegate: delegate] autorelease];
	[self of_sendQueryForContext: context runLoopMode: runLoopMode];


	objc_autoreleasePoolPop(pool);
}

- (void)of_contextTimedOut: (OFDNSResolverContext *)context
{
	of_run_loop_mode_t runLoopMode = [OFRunLoop currentRunLoop].currentMode;
857
858
859
860
861
862
863
864
865
866
867
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
		context->_TCPSocket = nil;
		context->_responseLength = 0;
	}

	if (context->_nameServersIndex + 1 <
	    context->_settings->_nameServers.count) {
		context->_nameServersIndex++;
		[self of_sendQueryForContext: context
				 runLoopMode: runLoopMode];
		return;
	}

	if (++context->_attempt < context->_settings->_maxAttempts) {
		context->_nameServersIndex = 0;
		[self of_sendQueryForContext: context
				 runLoopMode: runLoopMode];
		return;
	}

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

	/*
	 * 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];
#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







|
<





|
<











|
<


|
<







841
842
843
844
845
846
847
848

849
850
851
852
853
854

855
856
857
858
859
860
861
862
863
864
865
866

867
868
869

870
871
872
873
874
875
876
		context->_TCPSocket = nil;
		context->_responseLength = 0;
	}

	if (context->_nameServersIndex + 1 <
	    context->_settings->_nameServers.count) {
		context->_nameServersIndex++;
		[self of_sendQueryForContext: context runLoopMode: runLoopMode];

		return;
	}

	if (++context->_attempt < context->_settings->_maxAttempts) {
		context->_nameServersIndex = 0;
		[self of_sendQueryForContext: context runLoopMode: runLoopMode];

		return;
	}

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

	/*
	 * 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];

#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
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
		if (queryDataCount > UINT16_MAX)
			@throw [OFOutOfRangeException exception];

		context->_TCPQueryData = [[OFMutableData alloc]
		    initWithCapacity: queryDataCount + 2];

		tmp = OF_BSWAP16_IF_LE(queryDataCount);
		[context->_TCPQueryData addItems: &tmp
					   count: sizeof(tmp)];
		[context->_TCPQueryData addItems: context->_queryData.items
					   count: queryDataCount];
	}

	[sock asyncWriteData: context->_TCPQueryData];
}








|
<







1082
1083
1084
1085
1086
1087
1088
1089

1090
1091
1092
1093
1094
1095
1096
		if (queryDataCount > UINT16_MAX)
			@throw [OFOutOfRangeException exception];

		context->_TCPQueryData = [[OFMutableData alloc]
		    initWithCapacity: queryDataCount + 2];

		tmp = OF_BSWAP16_IF_LE(queryDataCount);
		[context->_TCPQueryData addItems: &tmp count: sizeof(tmp)];

		[context->_TCPQueryData addItems: context->_queryData.items
					   count: queryDataCount];
	}

	[sock asyncWriteData: context->_TCPQueryData];
}

1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
		context->_responseLength = 0;
		return nil;
	}

	if (context->_TCPBuffer == nil)
		context->_TCPBuffer = of_alloc(MAX_DNS_RESPONSE_LENGTH, 1);

	[sock asyncReadIntoBuffer: context->_TCPBuffer
		      exactLength: 2];
	return nil;
}

-      (bool)stream: (OFStream *)stream
  didReadIntoBuffer: (void *)buffer
	     length: (size_t)length
	  exception: (id)exception







|
<







1115
1116
1117
1118
1119
1120
1121
1122

1123
1124
1125
1126
1127
1128
1129
		context->_responseLength = 0;
		return nil;
	}

	if (context->_TCPBuffer == nil)
		context->_TCPBuffer = of_alloc(MAX_DNS_RESPONSE_LENGTH, 1);

	[sock asyncReadIntoBuffer: context->_TCPBuffer exactLength: 2];

	return nil;
}

-      (bool)stream: (OFStream *)stream
  didReadIntoBuffer: (void *)buffer
	     length: (size_t)length
	  exception: (id)exception
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
	if (length != context->_responseLength)
		/*
		 * The connection was closed before we received the entire
		 * response.
		 */
		goto done;

	[self of_handleResponseBuffer: buffer
			       length: length
			       sender: NULL];

done:
	[_TCPQueries removeObjectForKey: context->_TCPSocket];
	[context->_TCPSocket release];
	context->_TCPSocket = nil;
	context->_responseLength = 0;








|
<
<







1162
1163
1164
1165
1166
1167
1168
1169


1170
1171
1172
1173
1174
1175
1176
	if (length != context->_responseLength)
		/*
		 * The connection was closed before we received the entire
		 * response.
		 */
		goto done;

	[self of_handleResponseBuffer: buffer length: length sender: NULL];



done:
	[_TCPQueries removeObjectForKey: context->_TCPSocket];
	[context->_TCPSocket release];
	context->_TCPSocket = nil;
	context->_responseLength = 0;