ObjFW  Check-in [650fdd14e3]

Overview
Comment:OFDNSResolver: Add support for parsing MX records
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 650fdd14e3b4bd4c509cc81995a5515161afb4966990ddc732b23c80241cdb8b
User & Date: js on 2018-07-31 00:41:28
Other Links: manifest | tags
Context
2018-07-31
23:48
OFDNSResolver: Add support for {NS,PTR,TXT} RRs check-in: 1124f7d4d4 user: js tags: trunk
00:41
OFDNSResolver: Add support for parsing MX records check-in: 650fdd14e3 user: js tags: trunk
2018-07-30
22:24
Create an OFDNSResourceRecord subclass per type check-in: bd5e1e2014 user: js tags: trunk
Changes

Modified src/OFDNSResolver.m from [16d3a398be] to [1105a5a101].

246
247
248
249
250
251
252
253

254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270







271
272
273







274















275
276
277
278
279
280
281



282




283
284
285
286
287
288
289
290







291
292
293
294
295







296
297
298
299
300
301
302
303
304
305
306
307








308
309
310
311
312
313
314
246
247
248
249
250
251
252

253
254
255
256
257
258
259
260
261
262
263
264

265
266
267
268

269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285

286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
318
319

320

321
322
323
324
325
326
327
328

329
330

331
332
333
334
335
336
337
338
339

340
341







342
343
344
345
346
347
348
349
350
351
352
353
354
355
356







-
+











-




-
+
+
+
+
+
+
+



+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







+
+
+
-
+
+
+
+





-

-
+
+
+
+
+
+
+

-


-
+
+
+
+
+
+
+


-


-
-
-
-
-
-
-
+
+
+
+
+
+
+
+







}

static OF_KINDOF(OFDNSResourceRecord *)
createResourceRecord(OFString *name, of_dns_resource_record_class_t recordClass,
    of_dns_resource_record_type_t recordType, uint32_t TTL,
    const unsigned char *buffer, size_t length, size_t i, size_t dataLength)
{
	Class class;
	uint16_t preference;
	id data;

	if (recordClass == OF_DNS_RESOURCE_RECORD_CLASS_IN) {
		size_t j;

		switch (recordType) {
		case OF_DNS_RESOURCE_RECORD_TYPE_A:
			if (dataLength != 4)
				@throw [OFInvalidServerReplyException
				    exception];

			class = [OFADNSResourceRecord class];
			data = [OFString stringWithFormat:
			    @"%u.%u.%u.%u",
			    buffer[i], buffer[i + 1],
			    buffer[i + 2], buffer[i + 3]];
			break;

			return [[[OFADNSResourceRecord alloc]
			    initWithName: name
			     recordClass: recordClass
			      recordType: recordType
				    data: data
				     TTL: TTL] autorelease];
		case OF_DNS_RESOURCE_RECORD_TYPE_CNAME:
			j = i;

			data = parseName(buffer, length, &j,
			    ALLOWED_POINTER_LEVELS);

			if (j != i + dataLength)
				@throw [OFInvalidServerReplyException
				    exception];

			class = [OFCNAMEDNSResourceRecord class];
			return [[[OFCNAMEDNSResourceRecord alloc]
			    initWithName: name
			     recordClass: recordClass
			      recordType: recordType
				    data: data
				     TTL: TTL] autorelease];
		case OF_DNS_RESOURCE_RECORD_TYPE_MX:
			if (dataLength < 2)
				@throw [OFInvalidServerReplyException
				    exception];

			preference = (buffer[i] << 8) | buffer[i + 1];

			j = i + 2;

			data = parseName(buffer, length, &j,
			    ALLOWED_POINTER_LEVELS);

			if (j != i + dataLength)
				@throw [OFInvalidServerReplyException
				    exception];

			return [[[OFMXDNSResourceRecord alloc]
			    initWithName: name
			     recordClass: recordClass
			break;
			      recordType: recordType
			      preference: preference
				    data: data
				     TTL: TTL] autorelease];
		case OF_DNS_RESOURCE_RECORD_TYPE_AAAA:
			if (dataLength != 16)
				@throw [OFInvalidServerReplyException
				    exception];

			class = [OFAAAADNSResourceRecord class];
			data = parseAAAAData(&buffer[i]);
			break;

			return [[[OFAAAADNSResourceRecord alloc]
			    initWithName: name
			     recordClass: recordClass
			      recordType: recordType
				    data: data
				     TTL: TTL] autorelease];
		default:
			class = [OFDNSResourceRecord class];
			data = [OFData dataWithItems: &buffer[i]
					       count: dataLength];
			break;

			return [[[OFDNSResourceRecord alloc]
			    initWithName: name
			     recordClass: recordClass
			      recordType: recordType
				    data: data
				     TTL: TTL] autorelease];
		}
	} else {
		class = [OFDNSResourceRecord class];
		data = [OFData dataWithItems: &buffer[i]
				       count: dataLength];
	}

	return [[[class alloc] initWithName: name
				recordClass: recordClass
				 recordType: recordType
				       data: data
					TTL: TTL] autorelease];

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

@implementation OFDNSResolver_context
@synthesize host = _host, nameServers = _nameServers;
@synthesize searchDomains = _searchDomains;
@synthesize nameServersIndex = _nameServersIndex;
@synthesize searchDomainsIndex = _searchDomainsIndex, queryData = _queryData;

Modified src/OFDNSResourceRecord.h from [78e8b495b5] to [610fb854ae].

74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100











101
102
103
104
105
106
107
74
75
76
77
78
79
80

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118







-
+



















+
+
+
+
+
+
+
+
+
+
+








/**
 * @brief The domain name to which the resource record belongs.
 */
@property (readonly, nonatomic) OFString *name;

/*!
 * @brief The class of the data.
 * @brief The resource record class code.
 */
@property (readonly, nonatomic) of_dns_resource_record_class_t recordClass;

/*!
 * @brief The resource record type code.
 */
@property (readonly, nonatomic) of_dns_resource_record_type_t recordType;

/*!
 * The class and type-dependent data of the resource.
 */
@property (readonly, nonatomic) id data;

/*!
 * @brief The number of seconds after which the resource record should be
 *	  discarded from the cache.
 */
@property (readonly, nonatomic) uint32_t TTL;

/*!
 * @brief Initializes an already allocated OFDNSResourceRecord with the
 *	  specified name, resource record class, resource record type, resource
 *	  record data and resource record time to live.
 *
 * @param name The name of the resource record
 * @param recordClass The class code for the resource record
 * @param recordType The type code for the resource record
 * @param data The data for the resource record
 * @param TTL The time to live for the resource record
 */
- (instancetype)initWithName: (OFString *)name
		 recordClass: (of_dns_resource_record_class_t)recordClass
		  recordType: (of_dns_resource_record_type_t)recordType
			data: (id)data
			 TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER;
@end

139
140
141
142
143
144
145
















































146
147
148
149
150
151
152
153
154
155
156
157
150
151
152
153
154
155
156
157
158
159
160
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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216







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












@interface OFCNAMEDNSResourceRecord: OFDNSResourceRecord
/*!
 * A string with the alias.
 */
@property (readonly, nonatomic) OFString *data;
@end

/*!
 * @class OFMXDNSResourceRecord \
 *	  OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h
 *
 * @brief A class representing an MX DNS resource record.
 */
@interface OFMXDNSResourceRecord: OFDNSResourceRecord
{
	uint16_t _preference;
}

/*!
 * The preference of the resource record.
 */
@property (readonly, nonatomic) uint16_t preference;

/*!
 * A string with the mail exchange.
 */
@property (readonly, nonatomic) OFString *data;

- (instancetype)initWithName: (OFString *)name
		 recordClass: (of_dns_resource_record_class_t)recordClass
		  recordType: (of_dns_resource_record_type_t)recordType
			data: (id)data
			 TTL: (uint32_t)TTL OF_UNAVAILABLE;

/*!
 * @brief Initializes an already allocated OFMXDNSResourceRecord with the
 *	  specified name, resource record class, resource record type, resource
 *	  record preference, resource record data and resource record time to
 *	  live.
 *
 * @param name The name of the resource record
 * @param recordClass The class code for the resource record
 * @param recordType The type code for the resource record
 * @param preference The preference of the resource record
 * @param data The data for the resource record
 * @param TTL The time to live for the resource record
 */
- (instancetype)initWithName: (OFString *)name
		 recordClass: (of_dns_resource_record_class_t)recordClass
		  recordType: (of_dns_resource_record_type_t)recordType
		  preference: (uint16_t)preference
			data: (id)data
			 TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER;
@end

#ifdef __cplusplus
extern "C" {
#endif
extern OFString *_Nonnull of_dns_resource_record_class_to_string(
    of_dns_resource_record_class_t recordClass);
extern OFString *_Nonnull of_dns_resource_record_type_to_string(
    of_dns_resource_record_type_t recordType);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/OFDNSResourceRecord.m from [745465fb73] to [698216c4aa].

145
146
147
148
149
150
151
152

153
154
155
156
157
158

159

160
161
162
163
164
165
166
167

168
169
170
171











172





173


















174

175
176
177
178
179



































180
181













182
183
145
146
147
148
149
150
151

152
153
154
155
156
157
158
159

160
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
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
253
254
255
256
257







-
+






+
-
+





-
-
-
+
-



+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+

-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+
+
+
+
+
+
+
+
+
+
+
+
+



	return hash;
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"<OFDNSResourceRecord:\n"
	    @"<%@:\n"
	    @"\tName = %@\n"
	    @"\tClass = %@\n"
	    @"\tType = %@\n"
	    @"\tData = %@\n"
	    @"\tTTL = %" PRIu32 "\n"
	    @">",
	    [self className], _name,
	    _name, of_dns_resource_record_class_to_string(_recordClass),
	    of_dns_resource_record_class_to_string(_recordClass),
	    of_dns_resource_record_type_to_string(_recordType), _data, _TTL];
}
@end

@implementation OFADNSResourceRecord
- (OFString *)data
{
	return _data;
@dynamic data;
}
@end

@implementation OFAAAADNSResourceRecord
@dynamic data;
@end

@implementation OFCNAMEDNSResourceRecord
@dynamic data;
@end

@implementation OFMXDNSResourceRecord
@dynamic data;
@synthesize preference = _preference;

- (OFString *)data
- (instancetype)initWithName: (OFString *)name
		 recordClass: (of_dns_resource_record_class_t)recordClass
		  recordType: (of_dns_resource_record_type_t)recordType
			data: (id)data
			 TTL: (uint32_t)TTL
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithName: (OFString *)name
		 recordClass: (of_dns_resource_record_class_t)recordClass
		  recordType: (of_dns_resource_record_type_t)recordType
		  preference: (uint16_t)preference
			data: (id)data
			 TTL: (uint32_t)TTL
{
	self = [super initWithName: name
		       recordClass: recordClass
			recordType: recordType
			      data: data
			       TTL: TTL];

	_preference = preference;

	return _data;
	return self;
}
@end

@implementation OFCNAMEDNSResourceRecord
- (OFString *)data

- (bool)isEqual: (id)otherObject
{
	OFMXDNSResourceRecord *otherRecord;

	if (![otherObject isKindOfClass: [OFMXDNSResourceRecord class]])
		return false;

	otherRecord = otherObject;

	if (![super isEqual: otherRecord])
		return false;

	if (otherRecord->_preference != _preference)
		return false;

	return true;
}

- (uint32_t)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, [super hash]);
	OF_HASH_ADD(hash, _preference >> 8);
	OF_HASH_ADD(hash, _preference);

	OF_HASH_FINALIZE(hash);

	return hash;
}

- (OFString *)description
{
	return _data;
	return [OFString stringWithFormat:
	    @"<%@:\n"
	    @"\tName = %@\n"
	    @"\tClass = %@\n"
	    @"\tType = %@\n"
	    @"\tPreference = %" PRIu16 "\n"
	    @"\tData = %@\n"
	    @"\tTTL = %" PRIu32 "\n"
	    @">",
	    [self className], _name,
	    of_dns_resource_record_class_to_string(_recordClass),
	    of_dns_resource_record_type_to_string(_recordType), _preference,
	    _data, _TTL];
}
@end