ObjFW  Diff

Differences From Artifact [cebc2efbe7]:

To Artifact [71348d0e6d]:


13
14
15
16
17
18
19

20
21
22
23
24
25
26
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"


#include <string.h>
#include "unistd_wrapper.h"

#import "OFDNSResolver.h"
#import "OFArray.h"
#import "OFCharacterSet.h"
#import "OFData.h"







>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#include <errno.h>
#include <string.h>
#include "unistd_wrapper.h"

#import "OFDNSResolver.h"
#import "OFArray.h"
#import "OFCharacterSet.h"
#import "OFData.h"
94
95
96
97
98
99
100

101
102
103
104
105
106
107
	of_time_interval_t _timeout;
	unsigned int _maxAttempts;
	size_t _attempt;
	id _target;
	SEL _selector;
	id _context;
	OFData *_queryData;

	OFTimer *_cancelTimer;
}

- (instancetype)initWithHost: (OFString *)host
		  domainName: (OFString *)domainName
		 recordClass: (of_dns_resource_record_class_t)recordClass
		  recordType: (of_dns_resource_record_type_t)recordType







>







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
	of_time_interval_t _timeout;
	unsigned int _maxAttempts;
	size_t _attempt;
	id _target;
	SEL _selector;
	id _context;
	OFData *_queryData;
	of_socket_address_t _usedNameServer;
	OFTimer *_cancelTimer;
}

- (instancetype)initWithHost: (OFString *)host
		  domainName: (OFString *)domainName
		 recordClass: (of_dns_resource_record_class_t)recordClass
		  recordType: (of_dns_resource_record_type_t)recordType
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
	[self of_sendQuery: query];

	objc_autoreleasePoolPop(pool);
}

- (void)of_sendQuery: (OFDNSResolverQuery *)query
{
	of_socket_address_t address;
	OFUDPSocket *sock;

	[query->_cancelTimer invalidate];
	[query->_cancelTimer release];
	query->_cancelTimer = nil;
	query->_cancelTimer = [[OFTimer
	    scheduledTimerWithTimeInterval: query->_timeout
				    target: self
				  selector: @selector(of_queryWithIDTimedOut:)
				    object: query
				   repeats: false] retain];

	address = of_socket_address_parse_ip(
	    [query->_nameServers objectAtIndex: query->_nameServersIndex], 53);

	switch (address.family) {
#ifdef OF_HAVE_IPV6
	case OF_SOCKET_ADDRESS_FAMILY_IPV6:
		if (_IPv6Socket == nil) {
			_IPv6Socket = [[OFUDPSocket alloc] init];
			[_IPv6Socket bindToHost: @"::"
					   port: 0];
			[_IPv6Socket setBlocking: false];







<












|


|







1075
1076
1077
1078
1079
1080
1081

1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
	[self of_sendQuery: query];

	objc_autoreleasePoolPop(pool);
}

- (void)of_sendQuery: (OFDNSResolverQuery *)query
{

	OFUDPSocket *sock;

	[query->_cancelTimer invalidate];
	[query->_cancelTimer release];
	query->_cancelTimer = nil;
	query->_cancelTimer = [[OFTimer
	    scheduledTimerWithTimeInterval: query->_timeout
				    target: self
				  selector: @selector(of_queryWithIDTimedOut:)
				    object: query
				   repeats: false] retain];

	query->_usedNameServer = of_socket_address_parse_ip(
	    [query->_nameServers objectAtIndex: query->_nameServersIndex], 53);

	switch (query->_usedNameServer.family) {
#ifdef OF_HAVE_IPV6
	case OF_SOCKET_ADDRESS_FAMILY_IPV6:
		if (_IPv6Socket == nil) {
			_IPv6Socket = [[OFUDPSocket alloc] init];
			[_IPv6Socket bindToHost: @"::"
					   port: 0];
			[_IPv6Socket setBlocking: false];
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
		break;
	default:
		@throw [OFInvalidArgumentException exception];
	}

	[sock asyncSendBuffer: [query->_queryData items]
		       length: [query->_queryData count]
		     receiver: address
		       target: self
		     selector: @selector(of_socket:didSendBuffer:bytesSent:
				   receiver:context:exception:)
		      context: query];
}

- (void)of_queryWithIDTimedOut: (OFDNSResolverQuery *)query







|







1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
		break;
	default:
		@throw [OFInvalidArgumentException exception];
	}

	[sock asyncSendBuffer: [query->_queryData items]
		       length: [query->_queryData count]
		     receiver: query->_usedNameServer
		       target: self
		     selector: @selector(of_socket:didSendBuffer:bytesSent:
				   receiver:context:exception:)
		      context: query];
}

- (void)of_queryWithIDTimedOut: (OFDNSResolverQuery *)query
1198
1199
1200
1201
1202
1203
1204
1205



1206
1207

1208
1209
1210
1211
1212
1213
1214
1215
1216



1217
1218
1219
1220
1221
1222
1223
	     exception: (id)exception
{
	OFArray *answerRecords = nil, *authorityRecords = nil;
	OFArray *additionalRecords = nil;
	OFNumber *ID;
	OFDNSResolverQuery *query;

	if (exception != nil)



		return false;


	if (length < 2)
		/* We can't get the ID to get the query. Give up. */
		return false;

	ID = [OFNumber numberWithUInt16: (buffer[0] << 8) | buffer[1]];
	query = [[[_queries objectForKey: ID] retain] autorelease];

	if (query == nil)
		return false;




	[query->_cancelTimer invalidate];
	[query->_cancelTimer release];
	query->_cancelTimer = nil;
	[_queries removeObjectForKey: ID];

	@try {







|
>
>
>

|
>

|
|





|
>
>
>







1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
	     exception: (id)exception
{
	OFArray *answerRecords = nil, *authorityRecords = nil;
	OFArray *additionalRecords = nil;
	OFNumber *ID;
	OFDNSResolverQuery *query;

	if (exception != nil) {
		if ([exception respondsToSelector: @selector(errNo)])
			return ([exception errNo] == EINTR);

		return false;
	}

	if (length < 2)
		/* We can't get the ID to get the query. Ignore packet. */
		return true;

	ID = [OFNumber numberWithUInt16: (buffer[0] << 8) | buffer[1]];
	query = [[[_queries objectForKey: ID] retain] autorelease];

	if (query == nil)
		return true;

	if (!of_socket_address_equal(&sender, &query->_usedNameServer))
		return true;

	[query->_cancelTimer invalidate];
	[query->_cancelTimer release];
	query->_cancelTimer = nil;
	[_queries removeObjectForKey: ID];

	@try {