aboutsummaryrefslogtreecommitdiff
path: root/src/gnsrecord/plugin_gnsrecord_dns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gnsrecord/plugin_gnsrecord_dns.c')
-rw-r--r--src/gnsrecord/plugin_gnsrecord_dns.c812
1 files changed, 0 insertions, 812 deletions
diff --git a/src/gnsrecord/plugin_gnsrecord_dns.c b/src/gnsrecord/plugin_gnsrecord_dns.c
deleted file mode 100644
index 123c59905..000000000
--- a/src/gnsrecord/plugin_gnsrecord_dns.c
+++ /dev/null
@@ -1,812 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2013, 2014 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file gnsrecord/plugin_gnsrecord_dns.c
23 * @brief gnsrecord plugin to provide the API for basic DNS records
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_dnsparser_lib.h"
29#include "gnunet_gnsrecord_plugin.h"
30
31
32/**
33 * Convert the 'value' of a record to a string.
34 *
35 * @param cls closure, unused
36 * @param type type of the record
37 * @param data value in binary encoding
38 * @param data_size number of bytes in @a data
39 * @return NULL on error, otherwise human-readable representation of the value
40 */
41static char *
42dns_value_to_string (void *cls,
43 uint32_t type,
44 const void *data,
45 size_t data_size)
46{
47 char *result;
48 char tmp[INET6_ADDRSTRLEN];
49
50 switch (type)
51 {
52 case GNUNET_DNSPARSER_TYPE_A:
53 if (data_size != sizeof(struct in_addr))
54 return NULL;
55 if (NULL == inet_ntop (AF_INET, data, tmp, sizeof(tmp)))
56 return NULL;
57 return GNUNET_strdup (tmp);
58
59 case GNUNET_DNSPARSER_TYPE_NS: {
60 char *ns;
61 size_t off;
62
63 off = 0;
64 ns = GNUNET_DNSPARSER_parse_name (data, data_size, &off);
65 if ((NULL == ns) || (off != data_size))
66 {
67 GNUNET_break_op (0);
68 GNUNET_free (ns);
69 return NULL;
70 }
71 return ns;
72 }
73
74 case GNUNET_DNSPARSER_TYPE_CNAME: {
75 char *cname;
76 size_t off;
77
78 off = 0;
79 cname = GNUNET_DNSPARSER_parse_name (data, data_size, &off);
80 if ((NULL == cname) || (off != data_size))
81 {
82 GNUNET_break_op (0);
83 GNUNET_free (cname);
84 return NULL;
85 }
86 return cname;
87 }
88
89 case GNUNET_DNSPARSER_TYPE_SOA: {
90 struct GNUNET_DNSPARSER_SoaRecord *soa;
91 size_t off;
92
93 off = 0;
94 soa = GNUNET_DNSPARSER_parse_soa (data, data_size, &off);
95 if ((NULL == soa) || (off != data_size))
96 {
97 GNUNET_break_op (0);
98 if (NULL != soa)
99 GNUNET_DNSPARSER_free_soa (soa);
100 return NULL;
101 }
102 GNUNET_asprintf (&result,
103 "rname=%s mname=%s %u,%u,%u,%u,%u",
104 soa->rname,
105 soa->mname,
106 soa->serial,
107 soa->refresh,
108 soa->retry,
109 soa->expire,
110 soa->minimum_ttl);
111 GNUNET_DNSPARSER_free_soa (soa);
112 return result;
113 }
114
115 case GNUNET_DNSPARSER_TYPE_PTR: {
116 char *ptr;
117 size_t off;
118
119 off = 0;
120 ptr = GNUNET_DNSPARSER_parse_name (data, data_size, &off);
121 if ((NULL == ptr) || (off != data_size))
122 {
123 GNUNET_break_op (0);
124 GNUNET_free (ptr);
125 return NULL;
126 }
127 return ptr;
128 }
129
130 case GNUNET_DNSPARSER_TYPE_CERT: {
131 struct GNUNET_DNSPARSER_CertRecord *cert;
132 size_t off;
133 char *base64;
134 int len;
135
136 off = 0;
137 cert = GNUNET_DNSPARSER_parse_cert (data, data_size, &off);
138 if ((NULL == cert) || (off != data_size))
139 {
140 GNUNET_break_op (0);
141 GNUNET_DNSPARSER_free_cert (cert);
142 return NULL;
143 }
144 len = GNUNET_STRINGS_base64_encode (cert->certificate_data,
145 cert->certificate_size,
146 &base64);
147 GNUNET_asprintf (&result,
148 "%u %u %u %.*s",
149 cert->cert_type,
150 cert->cert_tag,
151 cert->algorithm,
152 len,
153 base64);
154 GNUNET_free (base64);
155 GNUNET_DNSPARSER_free_cert (cert);
156 return result;
157 }
158
159 case GNUNET_DNSPARSER_TYPE_MX: {
160 struct GNUNET_DNSPARSER_MxRecord *mx;
161 size_t off;
162
163 off = 0;
164 mx = GNUNET_DNSPARSER_parse_mx (data, data_size, &off);
165 if ((NULL == mx) || (off != data_size))
166 {
167 GNUNET_break_op (0);
168 GNUNET_DNSPARSER_free_mx (mx);
169 return NULL;
170 }
171 GNUNET_asprintf (&result,
172 "%u,%s",
173 (unsigned int) mx->preference,
174 mx->mxhost);
175 GNUNET_DNSPARSER_free_mx (mx);
176 return result;
177 }
178
179 case GNUNET_DNSPARSER_TYPE_TXT:
180 return GNUNET_strndup (data, data_size);
181
182 case GNUNET_DNSPARSER_TYPE_AAAA:
183 if (data_size != sizeof(struct in6_addr))
184 return NULL;
185 if (NULL == inet_ntop (AF_INET6, data, tmp, sizeof(tmp)))
186 return NULL;
187 return GNUNET_strdup (tmp);
188
189 case GNUNET_DNSPARSER_TYPE_SRV: {
190 struct GNUNET_DNSPARSER_SrvRecord *srv;
191 size_t off;
192
193 off = 0;
194 srv = GNUNET_DNSPARSER_parse_srv (data, data_size, &off);
195 if ((NULL == srv) || (off != data_size))
196 {
197 GNUNET_break_op (0);
198 if (NULL != srv)
199 GNUNET_DNSPARSER_free_srv (srv);
200 return NULL;
201 }
202 GNUNET_asprintf (&result,
203 "%d %d %d %s",
204 srv->priority,
205 srv->weight,
206 srv->port,
207 srv->target);
208 GNUNET_DNSPARSER_free_srv (srv);
209 return result;
210 }
211
212 case GNUNET_DNSPARSER_TYPE_TLSA: {
213 const struct GNUNET_TUN_DnsTlsaRecord *tlsa;
214 char *tlsa_str;
215 char *hex;
216
217 if (data_size < sizeof(struct GNUNET_TUN_DnsTlsaRecord))
218 return NULL; /* malformed */
219 tlsa = data;
220 hex =
221 GNUNET_DNSPARSER_bin_to_hex (&tlsa[1],
222 data_size
223 - sizeof(struct GNUNET_TUN_DnsTlsaRecord));
224 if (0 == GNUNET_asprintf (&tlsa_str,
225 "%u %u %u %s",
226 (unsigned int) tlsa->usage,
227 (unsigned int) tlsa->selector,
228 (unsigned int) tlsa->matching_type,
229 hex))
230 {
231 GNUNET_free (hex);
232 GNUNET_free (tlsa_str);
233 return NULL;
234 }
235 GNUNET_free (hex);
236 return tlsa_str;
237 }
238
239 case GNUNET_DNSPARSER_TYPE_CAA: { // RFC6844
240 const struct GNUNET_DNSPARSER_CaaRecord *caa;
241 char tag[15]; // between 1 and 15 bytes
242 char value[data_size];
243 char *caa_str;
244 if (data_size < sizeof(struct GNUNET_DNSPARSER_CaaRecord))
245 return NULL; /* malformed */
246 caa = data;
247 if ((1 > caa->tag_len) || (15 < caa->tag_len))
248 return NULL; /* malformed */
249 memset (tag, 0, sizeof(tag));
250 memset (value, 0, data_size);
251 memcpy (tag, &caa[1], caa->tag_len);
252 memcpy (value,
253 (char *) &caa[1] + caa->tag_len,
254 data_size - caa->tag_len - 2);
255 if (0 == GNUNET_asprintf (&caa_str,
256 "%u %s %s",
257 (unsigned int) caa->flags,
258 tag,
259 value))
260 {
261 GNUNET_free (caa_str);
262 return NULL;
263 }
264 return caa_str;
265 }
266
267 default:
268 return NULL;
269 }
270}
271
272
273/**
274 * Convert RFC 4394 Mnemonics to the corresponding integer values.
275 *
276 * @param mnemonic string to look up
277 * @return the value, 0 if not found
278 */
279static unsigned int
280rfc4398_mnemonic_to_value (const char *mnemonic)
281{
282 static struct
283 {
284 const char *mnemonic;
285 unsigned int val;
286 } table[] = { { "PKIX", 1 },
287 { "SPKI", 2 },
288 { "PGP", 3 },
289 { "IPKIX", 4 },
290 { "ISPKI", 5 },
291 { "IPGP", 6 },
292 { "ACPKIX", 7 },
293 { "IACPKIX", 8 },
294 { "URI", 253 },
295 { "OID", 254 },
296 { NULL, 0 } };
297 unsigned int i;
298
299 for (i = 0; NULL != table[i].mnemonic; i++)
300 if (0 == strcasecmp (mnemonic, table[i].mnemonic))
301 return table[i].val;
302 return 0;
303}
304
305
306/**
307 * Convert RFC 4034 algorithm types to the corresponding integer values.
308 *
309 * @param mnemonic string to look up
310 * @return the value, 0 if not found
311 */
312static unsigned int
313rfc4034_mnemonic_to_value (const char *mnemonic)
314{
315 static struct
316 {
317 const char *mnemonic;
318 unsigned int val;
319 } table[] = { { "RSAMD5", 1 },
320 { "DH", 2 },
321 { "DSA", 3 },
322 { "ECC", 4 },
323 { "RSASHA1", 5 },
324 { "INDIRECT", 252 },
325 { "PRIVATEDNS", 253 },
326 { "PRIVATEOID", 254 },
327 { NULL, 0 } };
328 unsigned int i;
329
330 for (i = 0; NULL != table[i].mnemonic; i++)
331 if (0 == strcasecmp (mnemonic, table[i].mnemonic))
332 return table[i].val;
333 return 0;
334}
335
336
337/**
338 * Convert human-readable version of a 'value' of a record to the binary
339 * representation.
340 *
341 * @param cls closure, unused
342 * @param type type of the record
343 * @param s human-readable string
344 * @param data set to value in binary encoding (will be allocated)
345 * @param data_size set to number of bytes in @a data
346 * @return #GNUNET_OK on success
347 */
348static int
349dns_string_to_value (void *cls,
350 uint32_t type,
351 const char *s,
352 void **data,
353 size_t *data_size)
354{
355 struct in_addr value_a;
356 struct in6_addr value_aaaa;
357 struct GNUNET_TUN_DnsTlsaRecord *tlsa;
358
359 if (NULL == s)
360 return GNUNET_SYSERR;
361 switch (type)
362 {
363 case GNUNET_DNSPARSER_TYPE_A:
364 if (1 != inet_pton (AF_INET, s, &value_a))
365 {
366 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
367 _ ("Unable to parse IPv4 address `%s'\n"),
368 s);
369 return GNUNET_SYSERR;
370 }
371 *data = GNUNET_new (struct in_addr);
372 GNUNET_memcpy (*data, &value_a, sizeof(value_a));
373 *data_size = sizeof(value_a);
374 return GNUNET_OK;
375
376 case GNUNET_DNSPARSER_TYPE_NS: {
377 char nsbuf[256];
378 size_t off;
379
380 off = 0;
381 if (GNUNET_OK !=
382 GNUNET_DNSPARSER_builder_add_name (nsbuf, sizeof(nsbuf), &off, s))
383 {
384 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
385 _ ("Failed to serialize NS record with value `%s'\n"),
386 s);
387 return GNUNET_SYSERR;
388 }
389 *data_size = off;
390 *data = GNUNET_malloc (off);
391 GNUNET_memcpy (*data, nsbuf, off);
392 return GNUNET_OK;
393 }
394
395 case GNUNET_DNSPARSER_TYPE_CNAME: {
396 char cnamebuf[256];
397 size_t off;
398
399 off = 0;
400 if (GNUNET_OK != GNUNET_DNSPARSER_builder_add_name (cnamebuf,
401 sizeof(cnamebuf),
402 &off,
403 s))
404 {
405 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
406 _ ("Failed to serialize CNAME record with value `%s'\n"),
407 s);
408 return GNUNET_SYSERR;
409 }
410 *data_size = off;
411 *data = GNUNET_malloc (off);
412 GNUNET_memcpy (*data, cnamebuf, off);
413 return GNUNET_OK;
414 }
415
416 case GNUNET_DNSPARSER_TYPE_CERT: {
417 char *sdup;
418 const char *typep;
419 const char *keyp;
420 const char *algp;
421 const char *certp;
422 unsigned int type;
423 unsigned int key;
424 unsigned int alg;
425 size_t cert_size;
426 char *cert_data;
427 struct GNUNET_DNSPARSER_CertRecord cert;
428
429 sdup = GNUNET_strdup (s);
430 typep = strtok (sdup, " ");
431 if ((NULL == typep) ||
432 ((0 == (type = rfc4398_mnemonic_to_value (typep))) &&
433 ((1 != sscanf (typep, "%u", &type)) || (type > UINT16_MAX))))
434 {
435 GNUNET_free (sdup);
436 return GNUNET_SYSERR;
437 }
438 keyp = strtok (NULL, " ");
439 if ((NULL == keyp) || (1 != sscanf (keyp, "%u", &key)) ||
440 (key > UINT16_MAX))
441 {
442 GNUNET_free (sdup);
443 return GNUNET_SYSERR;
444 }
445 alg = 0;
446 algp = strtok (NULL, " ");
447 if ((NULL == algp) ||
448 ((0 == (type = rfc4034_mnemonic_to_value (typep))) &&
449 ((1 != sscanf (algp, "%u", &alg)) || (alg > UINT8_MAX))))
450 {
451 GNUNET_free (sdup);
452 return GNUNET_SYSERR;
453 }
454 certp = strtok (NULL, " ");
455 if ((NULL == certp) || (0 == strlen (certp)))
456 {
457 GNUNET_free (sdup);
458 return GNUNET_SYSERR;
459 }
460 cert_size = GNUNET_STRINGS_base64_decode (certp,
461 strlen (certp),
462 (void **) &cert_data);
463 GNUNET_free (sdup);
464 cert.cert_type = type;
465 cert.cert_tag = key;
466 cert.algorithm = alg;
467 cert.certificate_size = cert_size;
468 cert.certificate_data = cert_data;
469 {
470 char certbuf[cert_size + sizeof(struct GNUNET_TUN_DnsCertRecord)];
471 size_t off;
472
473 off = 0;
474 if (GNUNET_OK != GNUNET_DNSPARSER_builder_add_cert (certbuf,
475 sizeof(certbuf),
476 &off,
477 &cert))
478 {
479 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
480 _ ("Failed to serialize CERT record with %u bytes\n"),
481 (unsigned int) cert_size);
482 GNUNET_free (cert_data);
483 return GNUNET_SYSERR;
484 }
485 *data_size = off;
486 *data = GNUNET_malloc (off);
487 GNUNET_memcpy (*data, certbuf, off);
488 }
489 GNUNET_free (cert_data);
490 return GNUNET_OK;
491 }
492
493 case GNUNET_DNSPARSER_TYPE_SOA: {
494 struct GNUNET_DNSPARSER_SoaRecord soa;
495 char soabuf[540];
496 char soa_rname[253 + 1];
497 char soa_mname[253 + 1];
498 unsigned int soa_serial;
499 unsigned int soa_refresh;
500 unsigned int soa_retry;
501 unsigned int soa_expire;
502 unsigned int soa_min;
503 size_t off;
504
505 if (7 != sscanf (s,
506 "rname=%253s mname=%253s %u,%u,%u,%u,%u",
507 soa_rname,
508 soa_mname,
509 &soa_serial,
510 &soa_refresh,
511 &soa_retry,
512 &soa_expire,
513 &soa_min))
514 {
515 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
516 _ ("Unable to parse SOA record `%s'\n"),
517 s);
518 return GNUNET_SYSERR;
519 }
520 soa.mname = soa_mname;
521 soa.rname = soa_rname;
522 soa.serial = (uint32_t) soa_serial;
523 soa.refresh = (uint32_t) soa_refresh;
524 soa.retry = (uint32_t) soa_retry;
525 soa.expire = (uint32_t) soa_expire;
526 soa.minimum_ttl = (uint32_t) soa_min;
527 off = 0;
528 if (GNUNET_OK !=
529 GNUNET_DNSPARSER_builder_add_soa (soabuf, sizeof(soabuf), &off, &soa))
530 {
531 GNUNET_log (
532 GNUNET_ERROR_TYPE_ERROR,
533 _ ("Failed to serialize SOA record with mname `%s' and rname `%s'\n"),
534 soa_mname,
535 soa_rname);
536 return GNUNET_SYSERR;
537 }
538 *data_size = off;
539 *data = GNUNET_malloc (off);
540 GNUNET_memcpy (*data, soabuf, off);
541 return GNUNET_OK;
542 }
543
544 case GNUNET_DNSPARSER_TYPE_PTR: {
545 char ptrbuf[256];
546 size_t off;
547
548 off = 0;
549 if (GNUNET_OK !=
550 GNUNET_DNSPARSER_builder_add_name (ptrbuf, sizeof(ptrbuf), &off, s))
551 {
552 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
553 _ ("Failed to serialize PTR record with value `%s'\n"),
554 s);
555 return GNUNET_SYSERR;
556 }
557 *data_size = off;
558 *data = GNUNET_malloc (off);
559 GNUNET_memcpy (*data, ptrbuf, off);
560 return GNUNET_OK;
561 }
562
563 case GNUNET_DNSPARSER_TYPE_MX: {
564 struct GNUNET_DNSPARSER_MxRecord mx;
565 char mxbuf[258];
566 char mxhost[253 + 1];
567 unsigned int mx_pref;
568 size_t off;
569
570 if (2 != sscanf (s, "%u,%253s", &mx_pref, mxhost))
571 {
572 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
573 _ ("Unable to parse MX record `%s'\n"),
574 s);
575 return GNUNET_SYSERR;
576 }
577 mx.preference = (uint16_t) mx_pref;
578 mx.mxhost = mxhost;
579 off = 0;
580
581 if (GNUNET_OK !=
582 GNUNET_DNSPARSER_builder_add_mx (mxbuf, sizeof(mxbuf), &off, &mx))
583 {
584 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
585 _ ("Failed to serialize MX record with hostname `%s'\n"),
586 mxhost);
587 return GNUNET_SYSERR;
588 }
589 *data_size = off;
590 *data = GNUNET_malloc (off);
591 GNUNET_memcpy (*data, mxbuf, off);
592 return GNUNET_OK;
593 }
594
595 case GNUNET_DNSPARSER_TYPE_SRV: {
596 struct GNUNET_DNSPARSER_SrvRecord srv;
597 char srvbuf[270];
598 char srvtarget[253 + 1];
599 unsigned int priority;
600 unsigned int weight;
601 unsigned int port;
602 size_t off;
603
604 if (4 != sscanf (s, "%u %u %u %253s", &priority, &weight, &port,
605 srvtarget))
606 {
607 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
608 _ ("Unable to parse SRV record `%s'\n"),
609 s);
610 return GNUNET_SYSERR;
611 }
612 srv.priority = (uint16_t) priority;
613 srv.weight = (uint16_t) weight;
614 srv.port = (uint16_t) port;
615 srv.target = srvtarget;
616 off = 0;
617 if (GNUNET_OK !=
618 GNUNET_DNSPARSER_builder_add_srv (srvbuf, sizeof(srvbuf), &off, &srv))
619 {
620 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
621 _ ("Failed to serialize SRV record with target `%s'\n"),
622 srvtarget);
623 return GNUNET_SYSERR;
624 }
625 *data_size = off;
626 *data = GNUNET_malloc (off);
627 GNUNET_memcpy (*data, srvbuf, off);
628 return GNUNET_OK;
629 }
630
631 case GNUNET_DNSPARSER_TYPE_TXT:
632 *data = GNUNET_strdup (s);
633 *data_size = strlen (s);
634 return GNUNET_OK;
635
636 case GNUNET_DNSPARSER_TYPE_AAAA:
637 if (1 != inet_pton (AF_INET6, s, &value_aaaa))
638 {
639 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
640 _ ("Unable to parse IPv6 address `%s'\n"),
641 s);
642 return GNUNET_SYSERR;
643 }
644 *data = GNUNET_new (struct in6_addr);
645 *data_size = sizeof(struct in6_addr);
646 GNUNET_memcpy (*data, &value_aaaa, sizeof(value_aaaa));
647 return GNUNET_OK;
648
649 case GNUNET_DNSPARSER_TYPE_TLSA: {
650 unsigned int usage;
651 unsigned int selector;
652 unsigned int matching_type;
653 size_t slen = strlen (s) + 1;
654 char hex[slen];
655
656 if (4 != sscanf (s, "%u %u %u %s", &usage, &selector, &matching_type,
657 hex))
658 {
659 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
660 _ ("Unable to parse TLSA record string `%s'\n"),
661 s);
662 *data_size = 0;
663 return GNUNET_SYSERR;
664 }
665
666 *data_size = sizeof(struct GNUNET_TUN_DnsTlsaRecord) + strlen (hex) / 2;
667 *data = tlsa = GNUNET_malloc (*data_size);
668 tlsa->usage = (uint8_t) usage;
669 tlsa->selector = (uint8_t) selector;
670 tlsa->matching_type = (uint8_t) matching_type;
671 if (strlen (hex) / 2 != GNUNET_DNSPARSER_hex_to_bin (hex, &tlsa[1]))
672 {
673 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
674 _ ("Unable to parse TLSA record string `%s'\n"),
675 s);
676 GNUNET_free (*data);
677 *data = NULL;
678 *data_size = 0;
679 return GNUNET_SYSERR;
680 }
681 return GNUNET_OK;
682 }
683
684 case GNUNET_DNSPARSER_TYPE_CAA: { // RFC6844
685 struct GNUNET_DNSPARSER_CaaRecord *caa;
686 unsigned int flags;
687 char tag[15]; // Max tag length 15
688 char value[strlen (s) + 1]; // Should be more than enough
689
690 if (3 != sscanf (s, "%u %s %[^\n]", &flags, tag, value))
691 {
692 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
693 _ ("Unable to parse CAA record string `%s'\n"),
694 s);
695 *data_size = 0;
696 return GNUNET_SYSERR;
697 }
698 *data_size = sizeof(struct GNUNET_DNSPARSER_CaaRecord) + strlen (tag)
699 + strlen (value);
700 *data = caa = GNUNET_malloc (*data_size);
701 caa->flags = flags;
702 memcpy (&caa[1], tag, strlen (tag));
703 caa->tag_len = strlen (tag);
704 memcpy ((char *) &caa[1] + caa->tag_len, value, strlen (value));
705 return GNUNET_OK;
706 }
707
708 default:
709 return GNUNET_SYSERR;
710 }
711}
712
713
714/**
715 * Mapping of record type numbers to human-readable
716 * record type names.
717 */
718static struct
719{
720 const char *name;
721 uint32_t number;
722} name_map[] = { { "A", GNUNET_DNSPARSER_TYPE_A },
723 { "NS", GNUNET_DNSPARSER_TYPE_NS },
724 { "CNAME", GNUNET_DNSPARSER_TYPE_CNAME },
725 { "SOA", GNUNET_DNSPARSER_TYPE_SOA },
726 { "PTR", GNUNET_DNSPARSER_TYPE_PTR },
727 { "MX", GNUNET_DNSPARSER_TYPE_MX },
728 { "TXT", GNUNET_DNSPARSER_TYPE_TXT },
729 { "AAAA", GNUNET_DNSPARSER_TYPE_AAAA },
730 { "SRV", GNUNET_DNSPARSER_TYPE_SRV },
731 { "TLSA", GNUNET_DNSPARSER_TYPE_TLSA },
732 { "CERT", GNUNET_DNSPARSER_TYPE_CERT },
733 { "CAA", GNUNET_DNSPARSER_TYPE_CAA },
734 { NULL, UINT32_MAX } };
735
736
737/**
738 * Convert a type name (e.g. "AAAA") to the corresponding number.
739 *
740 * @param cls closure, unused
741 * @param dns_typename name to convert
742 * @return corresponding number, UINT32_MAX on error
743 */
744static uint32_t
745dns_typename_to_number (void *cls, const char *dns_typename)
746{
747 unsigned int i;
748
749 i = 0;
750 while ((NULL != name_map[i].name) &&
751 (0 != strcasecmp (dns_typename, name_map[i].name)))
752 i++;
753 return name_map[i].number;
754}
755
756
757/**
758 * Convert a type number to the corresponding type string (e.g. 1 to "A")
759 *
760 * @param cls closure, unused
761 * @param type number of a type to convert
762 * @return corresponding typestring, NULL on error
763 */
764static const char *
765dns_number_to_typename (void *cls, uint32_t type)
766{
767 unsigned int i;
768
769 i = 0;
770 while ((NULL != name_map[i].name) && (type != name_map[i].number))
771 i++;
772 return name_map[i].name;
773}
774
775
776/**
777 * Entry point for the plugin.
778 *
779 * @param cls NULL
780 * @return the exported block API
781 */
782void *
783libgnunet_plugin_gnsrecord_dns_init (void *cls)
784{
785 struct GNUNET_GNSRECORD_PluginFunctions *api;
786
787 api = GNUNET_new (struct GNUNET_GNSRECORD_PluginFunctions);
788 api->value_to_string = &dns_value_to_string;
789 api->string_to_value = &dns_string_to_value;
790 api->typename_to_number = &dns_typename_to_number;
791 api->number_to_typename = &dns_number_to_typename;
792 return api;
793}
794
795
796/**
797 * Exit point from the plugin.
798 *
799 * @param cls the return value from #libgnunet_plugin_block_test_init
800 * @return NULL
801 */
802void *
803libgnunet_plugin_gnsrecord_dns_done (void *cls)
804{
805 struct GNUNET_GNSRECORD_PluginFunctions *api = cls;
806
807 GNUNET_free (api);
808 return NULL;
809}
810
811
812/* end of plugin_gnsrecord_dns.c */