diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-08-24 10:05:43 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-08-24 10:05:43 +0000 |
commit | 38be3ab6333e09e5689b4626bf9caa93bd1bbfba (patch) | |
tree | af3d6d4ccf52490ce788713e35d533aeaff74606 /src/dns | |
parent | 8babf5f841c8d364a0ab271e395f7e9a0e9b2632 (diff) | |
download | gnunet-38be3ab6333e09e5689b4626bf9caa93bd1bbfba.tar.gz gnunet-38be3ab6333e09e5689b4626bf9caa93bd1bbfba.zip |
-expose API for parsing individual DNS record types
Diffstat (limited to 'src/dns')
-rw-r--r-- | src/dns/dnsparser.c | 507 |
1 files changed, 313 insertions, 194 deletions
diff --git a/src/dns/dnsparser.c b/src/dns/dnsparser.c index 06438fb74..9509fe115 100644 --- a/src/dns/dnsparser.c +++ b/src/dns/dnsparser.c | |||
@@ -102,6 +102,87 @@ GNUNET_DNSPARSER_check_name (const char *name) | |||
102 | 102 | ||
103 | 103 | ||
104 | /** | 104 | /** |
105 | * Free SOA information record. | ||
106 | * | ||
107 | * @param soa record to free | ||
108 | */ | ||
109 | static void | ||
110 | free_soa (struct GNUNET_DNSPARSER_SoaRecord *soa) | ||
111 | { | ||
112 | if (NULL == soa) | ||
113 | return; | ||
114 | GNUNET_free_non_null (soa->mname); | ||
115 | GNUNET_free_non_null (soa->rname); | ||
116 | GNUNET_free (soa); | ||
117 | } | ||
118 | |||
119 | |||
120 | /** | ||
121 | * Free SRV information record. | ||
122 | * | ||
123 | * @param srv record to free | ||
124 | */ | ||
125 | static void | ||
126 | free_srv (struct GNUNET_DNSPARSER_SrvRecord *srv) | ||
127 | { | ||
128 | if (NULL == srv) | ||
129 | return; | ||
130 | GNUNET_free_non_null (srv->target); | ||
131 | GNUNET_free_non_null (srv->domain_name); | ||
132 | GNUNET_free_non_null (srv->proto); | ||
133 | GNUNET_free_non_null (srv->service); | ||
134 | GNUNET_free (srv); | ||
135 | } | ||
136 | |||
137 | |||
138 | /** | ||
139 | * Free MX information record. | ||
140 | * | ||
141 | * @param mx record to free | ||
142 | */ | ||
143 | static void | ||
144 | free_mx (struct GNUNET_DNSPARSER_MxRecord *mx) | ||
145 | { | ||
146 | if (NULL == mx) | ||
147 | return; | ||
148 | GNUNET_free_non_null (mx->mxhost); | ||
149 | GNUNET_free (mx); | ||
150 | } | ||
151 | |||
152 | |||
153 | /** | ||
154 | * Free the given DNS record. | ||
155 | * | ||
156 | * @param r record to free | ||
157 | */ | ||
158 | static void | ||
159 | free_record (struct GNUNET_DNSPARSER_Record *r) | ||
160 | { | ||
161 | GNUNET_free_non_null (r->name); | ||
162 | switch (r->type) | ||
163 | { | ||
164 | case GNUNET_DNSPARSER_TYPE_MX: | ||
165 | free_mx (r->data.mx); | ||
166 | break; | ||
167 | case GNUNET_DNSPARSER_TYPE_SOA: | ||
168 | free_soa (r->data.soa); | ||
169 | break; | ||
170 | case GNUNET_DNSPARSER_TYPE_SRV: | ||
171 | free_srv (r->data.srv); | ||
172 | break; | ||
173 | case GNUNET_DNSPARSER_TYPE_NS: | ||
174 | case GNUNET_DNSPARSER_TYPE_CNAME: | ||
175 | case GNUNET_DNSPARSER_TYPE_PTR: | ||
176 | GNUNET_free_non_null (r->data.hostname); | ||
177 | break; | ||
178 | default: | ||
179 | GNUNET_free_non_null (r->data.raw.data); | ||
180 | break; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | |||
185 | /** | ||
105 | * Parse name inside of a DNS query or record. | 186 | * Parse name inside of a DNS query or record. |
106 | * | 187 | * |
107 | * @param udp_payload entire UDP payload | 188 | * @param udp_payload entire UDP payload |
@@ -219,6 +300,24 @@ parse_name (const char *udp_payload, | |||
219 | 300 | ||
220 | 301 | ||
221 | /** | 302 | /** |
303 | * Parse name inside of a DNS query or record. | ||
304 | * | ||
305 | * @param udp_payload entire UDP payload | ||
306 | * @param udp_payload_length length of @a udp_payload | ||
307 | * @param off pointer to the offset of the name to parse in the udp_payload (to be | ||
308 | * incremented by the size of the name) | ||
309 | * @return name as 0-terminated C string on success, NULL if the payload is malformed | ||
310 | */ | ||
311 | char * | ||
312 | GNUNET_DNSPARSER_parse_name (const char *udp_payload, | ||
313 | size_t udp_payload_length, | ||
314 | size_t *off) | ||
315 | { | ||
316 | return parse_name (udp_payload, udp_payload_length, off, 0); | ||
317 | } | ||
318 | |||
319 | |||
320 | /** | ||
222 | * Parse a DNS query entry. | 321 | * Parse a DNS query entry. |
223 | * | 322 | * |
224 | * @param udp_payload entire UDP payload | 323 | * @param udp_payload entire UDP payload |
@@ -228,18 +327,18 @@ parse_name (const char *udp_payload, | |||
228 | * @param q where to write the query information | 327 | * @param q where to write the query information |
229 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the query is malformed | 328 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the query is malformed |
230 | */ | 329 | */ |
231 | static int | 330 | int |
232 | parse_query (const char *udp_payload, | 331 | GNUNET_DNSPARSER_parse_query (const char *udp_payload, |
233 | size_t udp_payload_length, | 332 | size_t udp_payload_length, |
234 | size_t *off, | 333 | size_t *off, |
235 | struct GNUNET_DNSPARSER_Query *q) | 334 | struct GNUNET_DNSPARSER_Query *q) |
236 | { | 335 | { |
237 | char *name; | 336 | char *name; |
238 | struct GNUNET_TUN_DnsQueryLine ql; | 337 | struct GNUNET_TUN_DnsQueryLine ql; |
239 | 338 | ||
240 | name = parse_name (udp_payload, | 339 | name = GNUNET_DNSPARSER_parse_name (udp_payload, |
241 | udp_payload_length, | 340 | udp_payload_length, |
242 | off, 0); | 341 | off); |
243 | if (NULL == name) | 342 | if (NULL == name) |
244 | return GNUNET_SYSERR; | 343 | return GNUNET_SYSERR; |
245 | q->name = name; | 344 | q->name = name; |
@@ -254,6 +353,168 @@ parse_query (const char *udp_payload, | |||
254 | 353 | ||
255 | 354 | ||
256 | /** | 355 | /** |
356 | * Parse a DNS SOA record. | ||
357 | * | ||
358 | * @param udp_payload reference to UDP packet | ||
359 | * @param udp_payload_length length of @a udp_payload | ||
360 | * @param off pointer to the offset of the query to parse in the SOA record (to be | ||
361 | * incremented by the size of the record), unchanged on error | ||
362 | * @return the parsed SOA record, NULL on error | ||
363 | */ | ||
364 | struct GNUNET_DNSPARSER_SoaRecord * | ||
365 | GNUNET_DNSPARSER_parse_soa (const char *udp_payload, | ||
366 | size_t udp_payload_length, | ||
367 | size_t *off) | ||
368 | { | ||
369 | struct GNUNET_DNSPARSER_SoaRecord *soa; | ||
370 | struct GNUNET_TUN_DnsSoaRecord soa_bin; | ||
371 | size_t old_off; | ||
372 | |||
373 | old_off = *off; | ||
374 | soa = GNUNET_new (struct GNUNET_DNSPARSER_SoaRecord); | ||
375 | soa->mname = GNUNET_DNSPARSER_parse_name (udp_payload, | ||
376 | udp_payload_length, | ||
377 | off); | ||
378 | soa->rname = GNUNET_DNSPARSER_parse_name (udp_payload, | ||
379 | udp_payload_length, | ||
380 | off); | ||
381 | if ( (NULL == soa->mname) || | ||
382 | (NULL == soa->rname) || | ||
383 | (*off + sizeof (struct GNUNET_TUN_DnsSoaRecord) > udp_payload_length) ) | ||
384 | { | ||
385 | free_soa (soa); | ||
386 | *off = old_off; | ||
387 | return NULL; | ||
388 | } | ||
389 | memcpy (&soa_bin, | ||
390 | &udp_payload[*off], | ||
391 | sizeof (struct GNUNET_TUN_DnsSoaRecord)); | ||
392 | soa->serial = ntohl (soa_bin.serial); | ||
393 | soa->refresh = ntohl (soa_bin.refresh); | ||
394 | soa->retry = ntohl (soa_bin.retry); | ||
395 | soa->expire = ntohl (soa_bin.expire); | ||
396 | soa->minimum_ttl = ntohl (soa_bin.minimum); | ||
397 | (*off) += sizeof (struct GNUNET_TUN_DnsSoaRecord); | ||
398 | return soa; | ||
399 | } | ||
400 | |||
401 | |||
402 | /** | ||
403 | * Parse a DNS MX record. | ||
404 | * | ||
405 | * @param udp_payload reference to UDP packet | ||
406 | * @param udp_payload_length length of @a udp_payload | ||
407 | * @param off pointer to the offset of the query to parse in the MX record (to be | ||
408 | * incremented by the size of the record), unchanged on error | ||
409 | * @return the parsed MX record, NULL on error | ||
410 | */ | ||
411 | struct GNUNET_DNSPARSER_MxRecord * | ||
412 | GNUNET_DNSPARSER_parse_mx (const char *udp_payload, | ||
413 | size_t udp_payload_length, | ||
414 | size_t *off) | ||
415 | { | ||
416 | struct GNUNET_DNSPARSER_MxRecord *mx; | ||
417 | uint16_t mxpref; | ||
418 | size_t old_off; | ||
419 | |||
420 | old_off = *off; | ||
421 | if (*off + sizeof (uint16_t) > udp_payload_length) | ||
422 | return NULL; | ||
423 | memcpy (&mxpref, &udp_payload[*off], sizeof (uint16_t)); | ||
424 | (*off) += sizeof (uint16_t); | ||
425 | mx = GNUNET_new (struct GNUNET_DNSPARSER_MxRecord); | ||
426 | mx->preference = ntohs (mxpref); | ||
427 | mx->mxhost = GNUNET_DNSPARSER_parse_name (udp_payload, | ||
428 | udp_payload_length, | ||
429 | off); | ||
430 | if (NULL == mx->mxhost) | ||
431 | { | ||
432 | free_mx (mx); | ||
433 | *off = old_off; | ||
434 | return NULL; | ||
435 | } | ||
436 | *off = old_off; | ||
437 | return mx; | ||
438 | } | ||
439 | |||
440 | |||
441 | /** | ||
442 | * Parse a DNS SRV record. | ||
443 | * | ||
444 | * @param r_name name of the SRV record | ||
445 | * @param udp_payload reference to UDP packet | ||
446 | * @param udp_payload_length length of @a udp_payload | ||
447 | * @param off pointer to the offset of the query to parse in the SRV record (to be | ||
448 | * incremented by the size of the record), unchanged on error | ||
449 | * @return the parsed SRV record, NULL on error | ||
450 | */ | ||
451 | struct GNUNET_DNSPARSER_SrvRecord * | ||
452 | GNUNET_DNSPARSER_parse_srv (const char *r_name, | ||
453 | const char *udp_payload, | ||
454 | size_t udp_payload_length, | ||
455 | size_t *off) | ||
456 | { | ||
457 | struct GNUNET_DNSPARSER_SrvRecord *srv; | ||
458 | struct GNUNET_TUN_DnsSrvRecord srv_bin; | ||
459 | size_t old_off; | ||
460 | char *ndup; | ||
461 | char *tok; | ||
462 | |||
463 | if ('_' != *r_name) | ||
464 | return NULL; /* all valid srv names must start with "_" */ | ||
465 | if (NULL == strstr (r_name, "._")) | ||
466 | return NULL; /* necessary string from "._$PROTO" not present */ | ||
467 | old_off = *off; | ||
468 | if (*off + sizeof (struct GNUNET_TUN_DnsSrvRecord) > udp_payload_length) | ||
469 | return NULL; | ||
470 | memcpy (&srv_bin, | ||
471 | &udp_payload[*off], | ||
472 | sizeof (struct GNUNET_TUN_DnsSrvRecord)); | ||
473 | (*off) += sizeof (struct GNUNET_TUN_DnsSrvRecord); | ||
474 | srv = GNUNET_new (struct GNUNET_DNSPARSER_SrvRecord); | ||
475 | srv->priority = ntohs (srv_bin.prio); | ||
476 | srv->weight = ntohs (srv_bin.weight); | ||
477 | srv->port = ntohs (srv_bin.port); | ||
478 | /* parse 'data.hostname' into components, which are | ||
479 | "_$SERVICE._$PROTO.$DOMAIN_NAME" */ | ||
480 | ndup = GNUNET_strdup (r_name); | ||
481 | tok = strtok (ndup, "."); | ||
482 | GNUNET_assert (NULL != tok); | ||
483 | GNUNET_assert ('_' == *tok); | ||
484 | srv->service = GNUNET_strdup (&tok[1]); | ||
485 | tok = strtok (NULL, "."); | ||
486 | if ( (NULL == tok) || ('_' != *tok) ) | ||
487 | { | ||
488 | free_srv (srv); | ||
489 | GNUNET_free (ndup); | ||
490 | *off = old_off; | ||
491 | return NULL; | ||
492 | } | ||
493 | srv->proto = GNUNET_strdup (&tok[1]); | ||
494 | tok = strtok (NULL, "."); | ||
495 | if (NULL == tok) | ||
496 | { | ||
497 | free_srv (srv); | ||
498 | GNUNET_free (ndup); | ||
499 | *off = old_off; | ||
500 | return NULL; | ||
501 | } | ||
502 | srv->domain_name = GNUNET_strdup (tok); | ||
503 | GNUNET_free (ndup); | ||
504 | srv->target = GNUNET_DNSPARSER_parse_name (udp_payload, | ||
505 | udp_payload_length, | ||
506 | off); | ||
507 | if (NULL == srv->target) | ||
508 | { | ||
509 | free_srv (srv); | ||
510 | *off = old_off; | ||
511 | return NULL; | ||
512 | } | ||
513 | return srv; | ||
514 | } | ||
515 | |||
516 | |||
517 | /** | ||
257 | * Parse a DNS record entry. | 518 | * Parse a DNS record entry. |
258 | * | 519 | * |
259 | * @param udp_payload entire UDP payload | 520 | * @param udp_payload entire UDP payload |
@@ -263,25 +524,20 @@ parse_query (const char *udp_payload, | |||
263 | * @param r where to write the record information | 524 | * @param r where to write the record information |
264 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the record is malformed | 525 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the record is malformed |
265 | */ | 526 | */ |
266 | static int | 527 | int |
267 | parse_record (const char *udp_payload, | 528 | GNUNET_DNSPARSER_parse_record (const char *udp_payload, |
268 | size_t udp_payload_length, | 529 | size_t udp_payload_length, |
269 | size_t *off, | 530 | size_t *off, |
270 | struct GNUNET_DNSPARSER_Record *r) | 531 | struct GNUNET_DNSPARSER_Record *r) |
271 | { | 532 | { |
272 | char *name; | 533 | char *name; |
273 | struct GNUNET_TUN_DnsRecordLine rl; | 534 | struct GNUNET_TUN_DnsRecordLine rl; |
274 | size_t old_off; | 535 | size_t old_off; |
275 | struct GNUNET_TUN_DnsSoaRecord soa; | ||
276 | uint16_t mxpref; | ||
277 | uint16_t data_len; | 536 | uint16_t data_len; |
278 | struct GNUNET_TUN_DnsSrvRecord srv; | ||
279 | char *ndup; | ||
280 | char *tok; | ||
281 | 537 | ||
282 | name = parse_name (udp_payload, | 538 | name = GNUNET_DNSPARSER_parse_name (udp_payload, |
283 | udp_payload_length, | 539 | udp_payload_length, |
284 | off, 0); | 540 | off); |
285 | if (NULL == name) | 541 | if (NULL == name) |
286 | return GNUNET_SYSERR; | 542 | return GNUNET_SYSERR; |
287 | r->name = name; | 543 | r->name = name; |
@@ -296,98 +552,42 @@ parse_record (const char *udp_payload, | |||
296 | data_len = ntohs (rl.data_len); | 552 | data_len = ntohs (rl.data_len); |
297 | if (*off + data_len > udp_payload_length) | 553 | if (*off + data_len > udp_payload_length) |
298 | return GNUNET_SYSERR; | 554 | return GNUNET_SYSERR; |
555 | old_off = *off; | ||
299 | switch (r->type) | 556 | switch (r->type) |
300 | { | 557 | { |
301 | case GNUNET_DNSPARSER_TYPE_NS: | 558 | case GNUNET_DNSPARSER_TYPE_NS: |
302 | case GNUNET_DNSPARSER_TYPE_CNAME: | 559 | case GNUNET_DNSPARSER_TYPE_CNAME: |
303 | case GNUNET_DNSPARSER_TYPE_PTR: | 560 | case GNUNET_DNSPARSER_TYPE_PTR: |
304 | old_off = *off; | 561 | r->data.hostname = GNUNET_DNSPARSER_parse_name (udp_payload, |
305 | r->data.hostname = parse_name (udp_payload, | 562 | udp_payload_length, |
306 | udp_payload_length, | 563 | off); |
307 | off, 0); | ||
308 | if ( (NULL == r->data.hostname) || | 564 | if ( (NULL == r->data.hostname) || |
309 | (old_off + data_len != *off) ) | 565 | (old_off + data_len != *off) ) |
310 | return GNUNET_SYSERR; | 566 | return GNUNET_SYSERR; |
311 | return GNUNET_OK; | 567 | return GNUNET_OK; |
312 | case GNUNET_DNSPARSER_TYPE_SOA: | 568 | case GNUNET_DNSPARSER_TYPE_SOA: |
313 | old_off = *off; | 569 | r->data.soa = GNUNET_DNSPARSER_parse_soa (udp_payload, |
314 | r->data.soa = GNUNET_new (struct GNUNET_DNSPARSER_SoaRecord); | 570 | udp_payload_length, |
315 | r->data.soa->mname = parse_name (udp_payload, | 571 | off); |
316 | udp_payload_length, | 572 | if ( (NULL == r->data.soa) || |
317 | off, 0); | 573 | (old_off + data_len != *off) ) |
318 | r->data.soa->rname = parse_name (udp_payload, | ||
319 | udp_payload_length, | ||
320 | off, 0); | ||
321 | if ( (NULL == r->data.soa->mname) || | ||
322 | (NULL == r->data.soa->rname) || | ||
323 | (*off + sizeof (struct GNUNET_TUN_DnsSoaRecord) > udp_payload_length) ) | ||
324 | return GNUNET_SYSERR; | ||
325 | memcpy (&soa, &udp_payload[*off], sizeof (struct GNUNET_TUN_DnsSoaRecord)); | ||
326 | r->data.soa->serial = ntohl (soa.serial); | ||
327 | r->data.soa->refresh = ntohl (soa.refresh); | ||
328 | r->data.soa->retry = ntohl (soa.retry); | ||
329 | r->data.soa->expire = ntohl (soa.expire); | ||
330 | r->data.soa->minimum_ttl = ntohl (soa.minimum); | ||
331 | (*off) += sizeof (struct GNUNET_TUN_DnsSoaRecord); | ||
332 | if (old_off + data_len != *off) | ||
333 | return GNUNET_SYSERR; | 574 | return GNUNET_SYSERR; |
334 | return GNUNET_OK; | 575 | return GNUNET_OK; |
335 | case GNUNET_DNSPARSER_TYPE_MX: | 576 | case GNUNET_DNSPARSER_TYPE_MX: |
336 | old_off = *off; | 577 | r->data.mx = GNUNET_DNSPARSER_parse_mx (udp_payload, |
337 | if (*off + sizeof (uint16_t) > udp_payload_length) | 578 | udp_payload_length, |
338 | return GNUNET_SYSERR; | 579 | off); |
339 | memcpy (&mxpref, &udp_payload[*off], sizeof (uint16_t)); | 580 | if ( (NULL == r->data.mx) || |
340 | (*off) += sizeof (uint16_t); | 581 | (old_off + data_len != *off) ) |
341 | r->data.mx = GNUNET_new (struct GNUNET_DNSPARSER_MxRecord); | ||
342 | r->data.mx->preference = ntohs (mxpref); | ||
343 | r->data.mx->mxhost = parse_name (udp_payload, | ||
344 | udp_payload_length, | ||
345 | off, 0); | ||
346 | if (old_off + data_len != *off) | ||
347 | return GNUNET_SYSERR; | 582 | return GNUNET_SYSERR; |
348 | return GNUNET_OK; | 583 | return GNUNET_OK; |
349 | case GNUNET_DNSPARSER_TYPE_SRV: | 584 | case GNUNET_DNSPARSER_TYPE_SRV: |
350 | if ('_' != *r->name) | 585 | r->data.srv = GNUNET_DNSPARSER_parse_srv (r->name, |
351 | return GNUNET_SYSERR; /* all valid srv names must start with "_" */ | 586 | udp_payload, |
352 | if (NULL == strstr (r->name, "._")) | 587 | udp_payload_length, |
353 | return GNUNET_SYSERR; /* necessary string from "._$PROTO" not present */ | 588 | off); |
354 | old_off = *off; | 589 | if ( (NULL == r->data.srv) || |
355 | if (*off + sizeof (struct GNUNET_TUN_DnsSrvRecord) > udp_payload_length) | 590 | (old_off + data_len != *off) ) |
356 | return GNUNET_SYSERR; | ||
357 | memcpy (&srv, &udp_payload[*off], sizeof (struct GNUNET_TUN_DnsSrvRecord)); | ||
358 | (*off) += sizeof (struct GNUNET_TUN_DnsSrvRecord); | ||
359 | r->data.srv = GNUNET_new (struct GNUNET_DNSPARSER_SrvRecord); | ||
360 | r->data.srv->priority = ntohs (srv.prio); | ||
361 | r->data.srv->weight = ntohs (srv.weight); | ||
362 | r->data.srv->port = ntohs (srv.port); | ||
363 | /* parse 'data.hostname' into components, which are | ||
364 | "_$SERVICE._$PROTO.$DOMAIN_NAME" */ | ||
365 | ndup = GNUNET_strdup (r->name); | ||
366 | tok = strtok (ndup, "."); | ||
367 | GNUNET_assert (NULL != tok); | ||
368 | GNUNET_assert ('_' == *tok); | ||
369 | r->data.srv->service = GNUNET_strdup (&tok[1]); | ||
370 | tok = strtok (NULL, "."); | ||
371 | if ( (NULL == tok) || ('_' != *tok) ) | ||
372 | { | ||
373 | GNUNET_free (r->data.srv); | ||
374 | GNUNET_free (ndup); | ||
375 | return GNUNET_SYSERR; | ||
376 | } | ||
377 | r->data.srv->proto = GNUNET_strdup (&tok[1]); | ||
378 | tok = strtok (NULL, "."); | ||
379 | if (NULL == tok) | ||
380 | { | ||
381 | GNUNET_free (r->data.srv); | ||
382 | GNUNET_free (ndup); | ||
383 | return GNUNET_SYSERR; | ||
384 | } | ||
385 | r->data.srv->domain_name = GNUNET_strdup (tok); | ||
386 | GNUNET_free (ndup); | ||
387 | r->data.srv->target = parse_name (udp_payload, | ||
388 | udp_payload_length, | ||
389 | off, 0); | ||
390 | if (old_off + data_len != *off) | ||
391 | return GNUNET_SYSERR; | 591 | return GNUNET_SYSERR; |
392 | return GNUNET_OK; | 592 | return GNUNET_OK; |
393 | default: | 593 | default: |
@@ -433,10 +633,10 @@ GNUNET_DNSPARSER_parse (const char *udp_payload, | |||
433 | p->num_queries = n; | 633 | p->num_queries = n; |
434 | for (i=0;i<n;i++) | 634 | for (i=0;i<n;i++) |
435 | if (GNUNET_OK != | 635 | if (GNUNET_OK != |
436 | parse_query (udp_payload, | 636 | GNUNET_DNSPARSER_parse_query (udp_payload, |
437 | udp_payload_length, | 637 | udp_payload_length, |
438 | &off, | 638 | &off, |
439 | &p->queries[i])) | 639 | &p->queries[i])) |
440 | goto error; | 640 | goto error; |
441 | } | 641 | } |
442 | n = ntohs (dns->answer_rcount); | 642 | n = ntohs (dns->answer_rcount); |
@@ -446,10 +646,10 @@ GNUNET_DNSPARSER_parse (const char *udp_payload, | |||
446 | p->num_answers = n; | 646 | p->num_answers = n; |
447 | for (i=0;i<n;i++) | 647 | for (i=0;i<n;i++) |
448 | if (GNUNET_OK != | 648 | if (GNUNET_OK != |
449 | parse_record (udp_payload, | 649 | GNUNET_DNSPARSER_parse_record (udp_payload, |
450 | udp_payload_length, | 650 | udp_payload_length, |
451 | &off, | 651 | &off, |
452 | &p->answers[i])) | 652 | &p->answers[i])) |
453 | goto error; | 653 | goto error; |
454 | } | 654 | } |
455 | n = ntohs (dns->authority_rcount); | 655 | n = ntohs (dns->authority_rcount); |
@@ -459,10 +659,10 @@ GNUNET_DNSPARSER_parse (const char *udp_payload, | |||
459 | p->num_authority_records = n; | 659 | p->num_authority_records = n; |
460 | for (i=0;i<n;i++) | 660 | for (i=0;i<n;i++) |
461 | if (GNUNET_OK != | 661 | if (GNUNET_OK != |
462 | parse_record (udp_payload, | 662 | GNUNET_DNSPARSER_parse_record (udp_payload, |
463 | udp_payload_length, | 663 | udp_payload_length, |
464 | &off, | 664 | &off, |
465 | &p->authority_records[i])) | 665 | &p->authority_records[i])) |
466 | goto error; | 666 | goto error; |
467 | } | 667 | } |
468 | n = ntohs (dns->additional_rcount); | 668 | n = ntohs (dns->additional_rcount); |
@@ -472,10 +672,10 @@ GNUNET_DNSPARSER_parse (const char *udp_payload, | |||
472 | p->num_additional_records = n; | 672 | p->num_additional_records = n; |
473 | for (i=0;i<n;i++) | 673 | for (i=0;i<n;i++) |
474 | if (GNUNET_OK != | 674 | if (GNUNET_OK != |
475 | parse_record (udp_payload, | 675 | GNUNET_DNSPARSER_parse_record (udp_payload, |
476 | udp_payload_length, | 676 | udp_payload_length, |
477 | &off, | 677 | &off, |
478 | &p->additional_records[i])) | 678 | &p->additional_records[i])) |
479 | goto error; | 679 | goto error; |
480 | } | 680 | } |
481 | return p; | 681 | return p; |
@@ -486,87 +686,6 @@ GNUNET_DNSPARSER_parse (const char *udp_payload, | |||
486 | 686 | ||
487 | 687 | ||
488 | /** | 688 | /** |
489 | * Free SOA information record. | ||
490 | * | ||
491 | * @param soa record to free | ||
492 | */ | ||
493 | static void | ||
494 | free_soa (struct GNUNET_DNSPARSER_SoaRecord *soa) | ||
495 | { | ||
496 | if (NULL == soa) | ||
497 | return; | ||
498 | GNUNET_free_non_null (soa->mname); | ||
499 | GNUNET_free_non_null (soa->rname); | ||
500 | GNUNET_free (soa); | ||
501 | } | ||
502 | |||
503 | |||
504 | /** | ||
505 | * Free SRV information record. | ||
506 | * | ||
507 | * @param srv record to free | ||
508 | */ | ||
509 | static void | ||
510 | free_srv (struct GNUNET_DNSPARSER_SrvRecord *srv) | ||
511 | { | ||
512 | if (NULL == srv) | ||
513 | return; | ||
514 | GNUNET_free_non_null (srv->target); | ||
515 | GNUNET_free_non_null (srv->domain_name); | ||
516 | GNUNET_free_non_null (srv->proto); | ||
517 | GNUNET_free_non_null (srv->service); | ||
518 | GNUNET_free (srv); | ||
519 | } | ||
520 | |||
521 | |||
522 | /** | ||
523 | * Free MX information record. | ||
524 | * | ||
525 | * @param mx record to free | ||
526 | */ | ||
527 | static void | ||
528 | free_mx (struct GNUNET_DNSPARSER_MxRecord *mx) | ||
529 | { | ||
530 | if (NULL == mx) | ||
531 | return; | ||
532 | GNUNET_free_non_null (mx->mxhost); | ||
533 | GNUNET_free (mx); | ||
534 | } | ||
535 | |||
536 | |||
537 | /** | ||
538 | * Free the given DNS record. | ||
539 | * | ||
540 | * @param r record to free | ||
541 | */ | ||
542 | static void | ||
543 | free_record (struct GNUNET_DNSPARSER_Record *r) | ||
544 | { | ||
545 | GNUNET_free_non_null (r->name); | ||
546 | switch (r->type) | ||
547 | { | ||
548 | case GNUNET_DNSPARSER_TYPE_MX: | ||
549 | free_mx (r->data.mx); | ||
550 | break; | ||
551 | case GNUNET_DNSPARSER_TYPE_SOA: | ||
552 | free_soa (r->data.soa); | ||
553 | break; | ||
554 | case GNUNET_DNSPARSER_TYPE_SRV: | ||
555 | free_srv (r->data.srv); | ||
556 | break; | ||
557 | case GNUNET_DNSPARSER_TYPE_NS: | ||
558 | case GNUNET_DNSPARSER_TYPE_CNAME: | ||
559 | case GNUNET_DNSPARSER_TYPE_PTR: | ||
560 | GNUNET_free_non_null (r->data.hostname); | ||
561 | break; | ||
562 | default: | ||
563 | GNUNET_free_non_null (r->data.raw.data); | ||
564 | break; | ||
565 | } | ||
566 | } | ||
567 | |||
568 | |||
569 | /** | ||
570 | * Free memory taken by a packet. | 689 | * Free memory taken by a packet. |
571 | * | 690 | * |
572 | * @param p packet to free | 691 | * @param p packet to free |