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
}

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






		case OF_DNS_RESOURCE_RECORD_TYPE_CNAME:
			j = i;








			class = [OFCNAMEDNSResourceRecord class];














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

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






		default:
			class = [OFDNSResourceRecord class];
			data = [OFData dataWithItems: &buffer[i]
					       count: dataLength];
			break;






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

}

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







|











<




|
>
>
>
>
>
>



>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>







>
>
>
|
>
>
>





<

|
>
>
>
>
>
>

<


|
>
>
>
>
>
>


<


|
|
|
|
|
|
|
>







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


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

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

			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
			      recordType: recordType
			      preference: preference
				    data: data
				     TTL: TTL] autorelease];
		case OF_DNS_RESOURCE_RECORD_TYPE_AAAA:
			if (dataLength != 16)
				@throw [OFInvalidServerReplyException
				    exception];


			data = parseAAAAData(&buffer[i]);

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

			data = [OFData dataWithItems: &buffer[i]
					       count: dataLength];

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

		data = [OFData dataWithItems: &buffer[i]
				       count: dataLength];

		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

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

/*!
 * @brief The class of the data.
 */
@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;












- (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








|



















>
>
>
>
>
>
>
>
>
>
>







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 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
@interface OFCNAMEDNSResourceRecord: OFDNSResourceRecord
/*!
 * A string with the alias.
 */
@property (readonly, nonatomic) OFString *data;
@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







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












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

	return hash;
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"<OFDNSResourceRecord:\n"
	    @"\tName = %@\n"
	    @"\tClass = %@\n"
	    @"\tType = %@\n"
	    @"\tData = %@\n"
	    @"\tTTL = %" PRIu32 "\n"
	    @">",

	    _name, 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;
}
@end

@implementation OFAAAADNSResourceRecord











- (OFString *)data




{


















	return _data;
}
@end


@implementation OFCNAMEDNSResourceRecord






























- (OFString *)data
{
	return _data;












}
@end







|






>
|





<
<
|
<



>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

|
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

|
>
>
>
>
>
>
>
>
>
>
>
>


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:
	    @"<%@:\n"
	    @"\tName = %@\n"
	    @"\tClass = %@\n"
	    @"\tType = %@\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), _data, _TTL];
}
@end

@implementation OFADNSResourceRecord


@dynamic data;

@end

@implementation OFAAAADNSResourceRecord
@dynamic data;
@end

@implementation OFCNAMEDNSResourceRecord
@dynamic data;
@end

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

- (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 self;
}

- (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 [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