ObjFW  Check-in [7ba597c52d]

Overview
Comment:OFDNSResolver: Group records by domain name
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 7ba597c52d5afdd7e77eb31eef89ff8a72d9a638382ea98ab813f28466e411bb
User & Date: js on 2018-09-15 13:45:03
Other Links: manifest | tags
Context
2018-09-15
17:39
OFDNSResolver: Resolve CNAMEs for socket addresses check-in: 25b05b7bce user: js tags: trunk
13:45
OFDNSResolver: Group records by domain name check-in: 7ba597c52d user: js tags: trunk
2018-09-10
20:44
OFDNSResolver: Method to resolve host to addresses check-in: 8555d64ee6 user: js tags: trunk
Changes

Modified src/OFDNSResolver.h from [6f6cb9c138] to [ef34cbb838].

161
162
163
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
161
162
163
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







+
-
+

+
-
+

+
-
+






-
+
+


-
+

-
+







 * @param host The host to resolve
 * @param target The target to call with the result once resolving is done
 * @param selector The selector to call on the target. The signature must be
 *		   the following:
 *		   @parblock
 *
 *		       void (OFDNSResolver *resolver, OFString *domainName,
 *		           OFArray<OFDictionary<OFString *,
 *		           OFArray<__kindof OFDNSResourceRecord *>
 *		           __kindof OFDNSResourceRecord *> *>
 *		           *_Nullable answerRecords,
 *		           OFArray<OFDictionary<OFString *,
 *		           OFArray<__kindof OFDNSResourceRecord *>
 *		           __kindof OFDNSResourceRecord *> *>
 *		           *_Nullable authorityRecords,
 *		           OFArray<OFDictionary<OFString *,
 *		           OFArray<__kindof OFDNSResourceRecord *>
 *		           __kindof OFDNSResourceRecord *> *>
 *		           *_Nullable additionalRecords,
 *		           id _Nullable context, id _Nullable exception)
 *
 *		   `resolver` is the acting resolver.@n
 *		   `domainName` is the fully qualified domain name used to
 *		   resolve the host.@n
 *		   `answerRecords` are the answer records from the name server.
 *		   `answerRecords` are the answer records from the name server,
 *		   grouped by domain name.
 *		   @n
 *		   `authorityRecords` are the authority records from the name
 *		   server.@n
 *		   server, grouped by domain name.@n
 *		   `additionalRecords` are additional records sent by the name
 *		   server.@n
 *		   server, grouped by domain name.@n
 *		   `context` is the context object originally passed.@n
 *		   `exception` is an exception that happened during resolving,
 *		   otherwise nil.
 *		   @endparblock
 * @param context A context object to pass along to the target
 */
- (void)asyncResolveHost: (OFString *)host
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
226
227
228
229
230
231
205
206
207
208
209
210
211
212

213
214
215

216
217
218

219
220
221
222
223
224
225

226
227
228
229

230
231

232
233
234
235
236
237
238
239







+
-
+

+
-
+

+
-
+






-
+
+


-
+

-
+







 * @param recordType The desired type of the records to query
 * @param target The target to call with the result once resolving is done
 * @param selector The selector to call on the target. The signature must be
 *		   the following:
 *		   @parblock
 *
 *		       void (OFDNSResolver *resolver, OFString *domainName,
 *		           OFArray<OFDictionary<OFString *,
 *		           OFArray<__kindof OFDNSResourceRecord *>
 *		           __kindof OFDNSResourceRecord *> *>
 *		           *_Nullable answerRecords,
 *		           OFArray<OFDictionary<OFString *,
 *		           OFArray<__kindof OFDNSResourceRecord *>
 *		           __kindof OFDNSResourceRecord *> *>
 *		           *_Nullable authorityRecords,
 *		           OFArray<OFDictionary<OFString *,
 *		           OFArray<__kindof OFDNSResourceRecord *>
 *		           __kindof OFDNSResourceRecord *> *>
 *		           *_Nullable additionalRecords,
 *		           id _Nullable context, id _Nullable exception)
 *
 *		   `resolver` is the acting resolver.@n
 *		   `domainName` is the fully qualified domain name used to
 *		   resolve the host.@n
 *		   `answerRecords` are the answer records from the name server.
 *		   `answerRecords` are the answer records from the name server,
 *		   grouped by domain name.
 *		   @n
 *		   `authorityRecords` are the authority records from the name
 *		   server.@n
 *		   server, grouped by domain name.@n
 *		   `additionalRecords` are additional records sent by the name
 *		   server.@n
 *		   server, grouped by domain name.@n
 *		   `context` is the context object originally passed.@n
 *		   `exception` is an exception that happened during resolving,
 *		   otherwise nil.
 *		   @endparblock
 * @param context A context object to pass along to the target
 */
- (void)asyncResolveHost: (OFString *)host

Modified src/OFDNSResolver.m from [8914dd7f51] to [721e3310ec].

170
171
172
173
174
175
176
177
178
179



180
181
182
183
184
185
186
170
171
172
173
174
175
176



177
178
179
180
181
182
183
184
185
186







-
-
-
+
+
+








- (instancetype)initWithHost: (OFString *)host
		      target: (id)target
		    selector: (SEL)selector
		     context: (id)context;
-	(void)resolver: (OFDNSResolver *)resolver
  didResolveDomainName: (OFString *)domainName
	 answerRecords: (OFArray *)answerRecords
      authorityRecords: (OFArray *)authorityRecords
     additionalRecords: (OFArray *)additionalRecords
	 answerRecords: (OFDictionary *)answerRecords
      authorityRecords: (OFDictionary *)authorityRecords
     additionalRecords: (OFDictionary *)additionalRecords
	       context: (id)context
	     exception: (id)exception;
@end

@interface OFDNSResolver ()
- (void)of_setDefaults;
- (void)of_obtainSystemConfig;
583
584
585
586
587
588
589
590

591
592
593


594

595
596
597
598
599
600
601
583
584
585
586
587
588
589

590
591
592
593
594
595

596
597
598
599
600
601
602
603







-
+



+
+
-
+







		return [[[OFDNSResourceRecord alloc]
		    initWithName: name
		     recordClass: recordClass
		      recordType: recordType
			     TTL: TTL] autorelease];
}

static OFArray *
static OFDictionary *
parseSection(const unsigned char *buffer, size_t length, size_t *i,
    uint_fast16_t count)
{
	OFMutableDictionary *ret = [OFMutableDictionary dictionary];
	OFEnumerator OF_GENERIC(OFMutableArray *) *objectEnumerator;
	OFMutableArray *ret = [OFMutableArray array];
	OFMutableArray *array;

	for (uint_fast16_t j = 0; j < count; j++) {
		OFString *name = parseName(buffer, length, i,
		    MAX_ALLOWED_POINTERS);
		of_dns_resource_record_class_t recordClass;
		of_dns_resource_record_type_t recordType;
		uint32_t TTL;
616
617
618
619
620
621
622








623

624




625
626
627
628
629
630
631
632
633



634
635
636
637
638




639
640
641
642
643
644
645
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632

633
634
635
636
637
638
639
640
641
642
643
644
645


646
647
648
649




650
651
652
653
654
655
656
657
658
659
660







+
+
+
+
+
+
+
+
-
+

+
+
+
+







-
-
+
+
+

-
-
-
-
+
+
+
+







		if (*i + dataLength > length)
			@throw [OFTruncatedDataException exception];

		record = parseResourceRecord(name, recordClass, recordType, TTL,
		    buffer, length, *i, dataLength);
		*i += dataLength;

		array = [ret objectForKey: name];

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

		[ret addObject: record];
		[array addObject: record];
	}

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

	[ret makeImmutable];

	return ret;
}

static void callback(id target, SEL selector, OFDNSResolver *resolver,
    OFString *domainName, OFArray *answerRecords, OFArray *authorityRecords,
    OFArray *additionalRecords, id context, id exception)
    OFString *domainName, OFDictionary *answerRecords,
    OFDictionary *authorityRecords, OFDictionary *additionalRecords, id context,
    id exception)
{
	void (*method)(id, SEL, OFDNSResolver *, OFString *, OFArray *,
	    OFArray *, OFArray *, id, id) = (void (*)(id, SEL, OFDNSResolver *,
	    OFString *, OFArray *, OFArray *, OFArray *, id, id))
	    [target methodForSelector: selector];
	void (*method)(id, SEL, OFDNSResolver *, OFString *, OFDictionary *,
	    OFDictionary *, OFDictionary *, id, id) = (void (*)(id, SEL,
	    OFDNSResolver *, OFString *, OFDictionary *, OFDictionary *,
	    OFDictionary *, id, id))[target methodForSelector: selector];

	method(target, selector, resolver, domainName, answerRecords,
	    authorityRecords, additionalRecords, context, exception);
}

@implementation OFDNSResolverSettings
- (instancetype)initWithNameServers: (OFArray *)nameServers
812
813
814
815
816
817
818
819
820
821



822
823
824
825
826
827
828
829
830
831
832
833
834
835
836


837
838
839
840
841
842
843
844
845
827
828
829
830
831
832
833



834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849


850
851


852
853
854
855
856
857
858







-
-
-
+
+
+













-
-
+
+
-
-







	[_records release];

	[super dealloc];
}

-	(void)resolver: (OFDNSResolver *)resolver
  didResolveDomainName: (OFString *)domainName
	 answerRecords: (OFArray *)answerRecords
      authorityRecords: (OFArray *)authorityRecords
     additionalRecords: (OFArray *)additionalRecords
	 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_socket_address_family_t addressFamily = [context intValue];

	_expectedResponses--;

	if (exception == nil) {
		for (OFDNSResourceRecord *record in answerRecords) {
			if (![[record name] isEqual: domainName])
		for (OFDNSResourceRecord *record in
		    [answerRecords objectForKey: domainName]) {
				continue;

			if ([record recordClass] !=
			    OF_DNS_RESOURCE_RECORD_CLASS_IN)
				continue;

			switch ([record recordType]) {
			case OF_DNS_RESOURCE_RECORD_TYPE_A:
				if (addressFamily ==
1609
1610
1611
1612
1613
1614
1615
1616
1617


1618
1619
1620
1621
1622
1623
1624
1622
1623
1624
1625
1626
1627
1628


1629
1630
1631
1632
1633
1634
1635
1636
1637







-
-
+
+







-      (bool)of_socket: (OFUDPSocket *)sock
  didReceiveIntoBuffer: (unsigned char *)buffer
		length: (size_t)length
		sender: (of_socket_address_t)sender
	       context: (id)context
	     exception: (id)exception
{
	OFArray *answerRecords = nil, *authorityRecords = nil;
	OFArray *additionalRecords = nil;
	OFDictionary *answerRecords = nil, *authorityRecords = nil;
	OFDictionary *additionalRecords = nil;
	OFNumber *ID;
	OFDNSResolverQuery *query;

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