ObjFW  Check-in [589a3e0f13]

Overview
Comment:OFDNSResolver: Add support for parsing AAAAs
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 589a3e0f13a7c12b3338a743e0bddc364efd81940b7602935cbb813186d342ec
User & Date: js on 2018-07-30 00:07:55
Other Links: manifest | tags
Context
2018-07-30
22:24
Create an OFDNSResourceRecord subclass per type check-in: bd5e1e2014 user: js tags: trunk
00:07
OFDNSResolver: Add support for parsing AAAAs check-in: 589a3e0f13 user: js tags: trunk
2018-07-29
19:13
OFDNSResolver: Allow specifying query class & type check-in: af30016cfb user: js tags: trunk
Changes

Modified src/OFDNSResolver.m from [11b30d4761] to [9fbb4cad64].

56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70







-
+








/*
 * TODO:
 *
 *  - Timeouts
 *  - Resolve with each search domain
 *  - Iterate through name servers
 *  - IPv6 (for responses and for talking to the name servers)
 *  - IPv6 for talking to the name servers
 *  - Fallback to TCP
 */

@interface OFDNSResolver_context: OFObject
{
	OFString *_host;
	OFArray OF_GENERIC(OFString *) *_nameServers, *_searchDomains;
180
181
182
183
184
185
186



























































187
188
189
190
191
192
193
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







		[components addObject: component];
	} while (componentLength > 0);

	*idx = i;

	return [components componentsJoinedByString: @"."];
}

static OFString *
parseAAAA(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) {
		if (buffer[i] == 0 && buffer[i + 1] == 0) {
			if (zerosStart >= 0)
				zerosCount++;
			else {
				zerosStart = i;
				zerosCount = 1;
			}
		} else {
			if (zerosCount > maxZerosCount) {
				maxZerosStart = zerosStart;
				maxZerosCount = zerosCount;
			}

			zerosStart = -1;
		}
	}
	if (zerosCount > maxZerosCount) {
		maxZerosStart = zerosStart;
		maxZerosCount = zerosCount;
	}

	if (maxZerosCount >= 2) {
		for (uint_fast8_t i = 0; i < maxZerosStart; i += 2) {
			[data appendFormat: (first ? @"%x" : @":%x"),
					    (buffer[i] << 8) | buffer[i + 1]];
			first = false;
		}

		[data appendString: @"::"];
		first = true;

		for (uint_fast8_t i = maxZerosStart + (maxZerosCount * 2);
		    i < 16; i += 2) {
			[data appendFormat: (first ? @"%x" : @":%x"),
					    (buffer[i] << 8) | buffer[i + 1]];
			first = false;
		}
	} else {
		for (uint_fast8_t i = 0; i < 16; i += 2) {
			[data appendFormat: (first ? @"%x" : @":%x"),
					    (buffer[i] << 8) | buffer[i + 1]];
			first = false;
		}
	}

	[data makeImmutable];

	return data;
}

static id
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)
{
	id data;
212
213
214
215
216
217
218







219
220
221
222
223
224
225
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291







+
+
+
+
+
+
+







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

			data = parseAAAA(&buffer[i]);
			break;
		default:
			data = [OFData dataWithItems: &buffer[i]
					       count: dataLength];
			break;
		}
	} else

Modified src/OFDNSResourceRecord.h from [b2d773ef59] to [ad1d163440].

24
25
26
27
28
29
30

31

32
33
34
35
36
37
38

39

40

41

42

43

44

45

46

47
48
49
50
51
52
53
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64







+

+







+

+

+

+

+

+

+

+

+








@class OFData;

/*!
 * @brief The class of a DNS resource record.
 */
typedef enum {
	/*! IN */
	OF_DNS_RESOURCE_RECORD_CLASS_IN	 =   1,
	/*! Any class. Only for queries. */
	OF_DNS_RESOURCE_RECORD_CLASS_ANY = 255,
} of_dns_resource_record_class_t;

/*!
 * @brief The type of a DNS resource record.
 */
typedef enum {
	/*! A */
	OF_DNS_RESOURCE_RECORD_TYPE_A	  =   1,
	/*! NS */
	OF_DNS_RESOURCE_RECORD_TYPE_NS	  =   2,
	/*! CNAME */
	OF_DNS_RESOURCE_RECORD_TYPE_CNAME =   5,
	/*! SOA */
	OF_DNS_RESOURCE_RECORD_TYPE_SOA	  =   6,
	/*! PTR */
	OF_DNS_RESOURCE_RECORD_TYPE_PTR	  =  12,
	/*! MX */
	OF_DNS_RESOURCE_RECORD_TYPE_MX	  =  15,
	/*! TXT */
	OF_DNS_RESOURCE_RECORD_TYPE_TXT	  =  16,
	/*! AAAA */
	OF_DNS_RESOURCE_RECORD_TYPE_AAAA  =  28,
	/*! All types. Only for queries. */
	OF_DNS_RESOURCE_RECORD_TYPE_ALL	  = 255,
} of_dns_resource_record_type_t;

/*!
 * @class OFDNSResourceRecord OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h
 *
 * @brief A class represenging a DNS resource record.