error handling
[oweals/gnunet.git] / src / include / gnunet_dnsparser_lib.h
1 /*
2       This file is part of GNUnet
3       Copyright (C) 2010-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  * @author Philipp Toelke
23  * @author Christian Grothoff
24  *
25  * @file
26  * API for helper library to parse DNS packets.
27  *
28  * @defgroup dns-parser  DNS parser library
29  * Helper library to parse DNS packets.
30  * @{
31  */
32 #ifndef GNUNET_DNSPARSER_LIB_H
33 #define GNUNET_DNSPARSER_LIB_H
34
35 #include "gnunet_util_lib.h"
36
37 /**
38  * Maximum length of a label in DNS.
39  */
40 #define GNUNET_DNSPARSER_MAX_LABEL_LENGTH 63
41
42 /**
43  * Maximum length of a name in DNS.
44  */
45 #define GNUNET_DNSPARSER_MAX_NAME_LENGTH 253
46
47
48 /**
49  * A few common DNS types.
50  */
51 #define GNUNET_DNSPARSER_TYPE_ANY 0
52 #define GNUNET_DNSPARSER_TYPE_A 1
53 #define GNUNET_DNSPARSER_TYPE_NS 2
54 #define GNUNET_DNSPARSER_TYPE_CNAME 5
55 #define GNUNET_DNSPARSER_TYPE_SOA 6
56 #define GNUNET_DNSPARSER_TYPE_PTR 12
57 #define GNUNET_DNSPARSER_TYPE_MX 15
58 #define GNUNET_DNSPARSER_TYPE_TXT 16
59 #define GNUNET_DNSPARSER_TYPE_RP 17
60 #define GNUNET_DNSPARSER_TYPE_AFSDB 18
61 #define GNUNET_DNSPARSER_TYPE_SIG 24
62 #define GNUNET_DNSPARSER_TYPE_KEY 25
63 #define GNUNET_DNSPARSER_TYPE_AAAA 28
64 #define GNUNET_DNSPARSER_TYPE_LOC 29
65 #define GNUNET_DNSPARSER_TYPE_SRV 33
66 #define GNUNET_DNSPARSER_TYPE_NAPTR 35
67 #define GNUNET_DNSPARSER_TYPE_KX 36
68 #define GNUNET_DNSPARSER_TYPE_CERT 37
69 #define GNUNET_DNSPARSER_TYPE_DNAME 39
70 #define GNUNET_DNSPARSER_TYPE_APL 42
71 #define GNUNET_DNSPARSER_TYPE_DS 43
72 #define GNUNET_DNSPARSER_TYPE_SSHFP 44
73 #define GNUNET_DNSPARSER_TYPE_IPSECKEY 45
74 #define GNUNET_DNSPARSER_TYPE_RRSIG 46
75 #define GNUNET_DNSPARSER_TYPE_NSEC 47
76 #define GNUNET_DNSPARSER_TYPE_DNSKEY 48
77 #define GNUNET_DNSPARSER_TYPE_DHCID 49
78 #define GNUNET_DNSPARSER_TYPE_NSEC3 50
79 #define GNUNET_DNSPARSER_TYPE_NSEC3PARAM 51
80 #define GNUNET_DNSPARSER_TYPE_TLSA 52
81 #define GNUNET_DNSPARSER_TYPE_HIP 55
82 #define GNUNET_DNSPARSER_TYPE_CDS 59
83 #define GNUNET_DNSPARSER_TYPE_CDNSKEY 60
84 #define GNUNET_DNSPARSER_TYPE_OPENPGPKEY 61
85 #define GNUNET_DNSPARSER_TYPE_TKEY 249
86 #define GNUNET_DNSPARSER_TYPE_TSIG 250
87 #define GNUNET_DNSPARSER_TYPE_ALL 255
88 #define GNUNET_DNSPARSER_TYPE_URI 256
89 #define GNUNET_DNSPARSER_TYPE_CAA 257
90 #define GNUNET_DNSPARSER_TYPE_TA 32768
91
92 /**
93  * A DNS query.
94  */
95 struct GNUNET_DNSPARSER_Query
96 {
97   /**
98    * Name of the record that the query is for (0-terminated).
99    * In UTF-8 format.  The library will convert from and to DNS-IDNA
100    * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
101    * individual label is well-formed.  If a given name is not well-formed,
102    * creating the DNS packet will fail.
103    */
104   char *name;
105
106   /**
107    * See GNUNET_DNSPARSER_TYPE_*.
108    */
109   uint16_t type;
110
111   /**
112    * See GNUNET_TUN_DNS_CLASS_*.
113    */
114   uint16_t dns_traffic_class;
115 };
116
117
118 /**
119  * Information from MX records (RFC 1035).
120  */
121 struct GNUNET_DNSPARSER_MxRecord
122 {
123   /**
124    * Preference for this entry (lower value is higher preference).
125    */
126   uint16_t preference;
127
128   /**
129    * Name of the mail server.
130    * In UTF-8 format.  The library will convert from and to DNS-IDNA
131    * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
132    * individual label is well-formed.  If a given name is not well-formed,
133    * creating the DNS packet will fail.
134    */
135   char *mxhost;
136 };
137
138
139 /**
140  * Information from SRV records (RFC 2782).
141  */
142 struct GNUNET_DNSPARSER_SrvRecord
143 {
144   /**
145    * Hostname offering the service.
146    * In UTF-8 format.  The library will convert from and to DNS-IDNA
147    * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
148    * individual label is well-formed.  If a given name is not well-formed,
149    * creating the DNS packet will fail.
150    */
151   char *target;
152
153   /**
154    * Preference for this entry (lower value is higher preference).  Clients
155    * will contact hosts from the lowest-priority group first and fall back
156    * to higher priorities if the low-priority entries are unavailable.
157    */
158   uint16_t priority;
159
160   /**
161    * Relative weight for records with the same priority.  Clients will use
162    * the hosts of the same (lowest) priority with a probability proportional
163    * to the weight given.
164    */
165   uint16_t weight;
166
167   /**
168    * TCP or UDP port of the service.
169    */
170   uint16_t port;
171 };
172
173
174 /**
175  * DNS CERT types as defined in RFC 4398.
176  */
177 enum GNUNET_DNSPARSER_CertType
178 {
179   /**
180    *  Reserved value
181    */
182   GNUNET_DNSPARSER_CERTTYPE_RESERVED = 0,
183
184   /**
185    * An x509 PKIX certificate
186    */
187   GNUNET_DNSPARSER_CERTTYPE_PKIX = 1,
188
189   /**
190    * A SKPI certificate
191    */
192   GNUNET_DNSPARSER_CERTTYPE_SKPI = 2,
193
194   /**
195    * A PGP certificate
196    */
197   GNUNET_DNSPARSER_CERTTYPE_PGP = 3,
198
199   /**
200    * An x509 PKIX cert URL
201    */
202   GNUNET_DNSPARSER_CERTTYPE_IPKIX = 4,
203
204   /**
205    * A SKPI cert URL
206    */
207   GNUNET_DNSPARSER_CERTTYPE_ISKPI = 5,
208
209   /**
210    * A PGP cert fingerprint and URL
211    */
212   GNUNET_DNSPARSER_CERTTYPE_IPGP = 6,
213
214   /**
215    * An attribute Certificate
216    */
217   GNUNET_DNSPARSER_CERTTYPE_ACPKIX = 7,
218
219   /**
220    * An attribute cert URL
221    */
222   GNUNET_DNSPARSER_CERTTYPE_IACKPIX = 8
223 };
224
225
226 /**
227  * DNSCERT algorithms as defined in http://www.iana.org/assignments/
228  *  dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml, under dns-sec-alg-numbers-1
229  */
230 enum GNUNET_DNSPARSER_CertAlgorithm
231 {
232   /**
233    * No defined
234    */
235   GNUNET_DNSPARSER_CERTALGO_UNDEFINED = 0,
236
237   /**
238    * RSA/MD5
239    */
240   GNUNET_DNSPARSER_CERTALGO_RSAMD5 = 1,
241
242   /**
243    * Diffie-Hellman
244    */
245   GNUNET_DNSPARSER_CERTALGO_DH = 2,
246
247   /**
248    * DSA/SHA1
249    */
250   GNUNET_DNSPARSER_CERTALGO_DSASHA = 3,
251
252   /**
253    * Reserved
254    */
255   GNUNET_DNSPARSER_CERTALGO_RSRVD4 = 4,
256
257   /**
258    * RSA/SHA1
259    */
260   GNUNET_DNSPARSER_CERTALGO_RSASHA = 5,
261
262   /**
263    * DSA/NSEC3/SHA
264    */
265   GNUNET_DNSPARSER_CERTALGO_DSANSEC3 = 6,
266
267   /**
268    * RSA/NSEC3/SHA
269    */
270   GNUNET_DNSPARSER_CERTALGO_RSANSEC3 = 7,
271
272   /**
273    * RSA/SHA256
274    */
275   GNUNET_DNSPARSER_CERTALGO_RSASHA256 = 8,
276
277   /**
278    * Reserved
279    */
280   GNUNET_DNSPARSER_CERTALGO_RSRVD9 = 9,
281
282   /**
283    * RSA/SHA512
284    */
285   GNUNET_DNSPARSER_CERTALGO_RSASHA512 = 10,
286
287   /**
288    * GOST R 34.10-2001
289    */
290   GNUNET_DNSPARSER_CERTALGO_GOST_R34 = 12,
291
292   /**
293    * ECDSA Curve P-256/SHA256
294    */
295   GNUNET_DNSPARSER_CERTALGO_ECDSA_P256SHA256 = 13,
296
297   /**
298    * ECDSA Curve P-384/SHA384
299    */
300   GNUNET_DNSPARSER_CERTALGO_ECDSA_P384SHA384 = 14
301 };
302
303
304 /**
305  * Information from CERT records (RFC 4034).
306  */
307 struct GNUNET_DNSPARSER_CertRecord
308 {
309   /**
310    * Certificate type
311    */
312   enum GNUNET_DNSPARSER_CertType cert_type;
313
314   /**
315    * Certificate KeyTag
316    */
317   uint16_t cert_tag;
318
319   /**
320    * Algorithm
321    */
322   enum GNUNET_DNSPARSER_CertAlgorithm algorithm;
323
324   /**
325    * Number of bytes in @e certificate_data
326    */
327   size_t certificate_size;
328
329   /**
330    * Data of the certificate.
331    */
332   char *certificate_data;
333 };
334
335
336 /**
337  * Information from SOA records (RFC 1035).
338  */
339 struct GNUNET_DNSPARSER_SoaRecord
340 {
341   /**
342    * The domainname of the name server that was the
343    * original or primary source of data for this zone.
344    * In UTF-8 format.  The library will convert from and to DNS-IDNA
345    * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
346    * individual label is well-formed.  If a given name is not well-formed,
347    * creating the DNS packet will fail.
348    */
349   char *mname;
350
351   /**
352    * A domainname which specifies the mailbox of the
353    * person responsible for this zone.
354    * In UTF-8 format.  The library will convert from and to DNS-IDNA
355    * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
356    * individual label is well-formed.  If a given name is not well-formed,
357    * creating the DNS packet will fail.
358    */
359   char *rname;
360
361   /**
362    * The version number of the original copy of the zone.
363    */
364   uint32_t serial;
365
366   /**
367    * Time interval before the zone should be refreshed.
368    */
369   uint32_t refresh;
370
371   /**
372    * Time interval that should elapse before a failed refresh should
373    * be retried.
374    */
375   uint32_t retry;
376
377   /**
378    * Time value that specifies the upper limit on the time interval
379    * that can elapse before the zone is no longer authoritative.
380    */
381   uint32_t expire;
382
383   /**
384    * The bit minimum TTL field that should be exported with any RR
385    * from this zone.
386    */
387   uint32_t minimum_ttl;
388 };
389
390
391 /**
392  * Information from CAA records (RFC 6844).
393  * The tag is followed by the tag_len.
394  * The value is followed by the tag for (d - tag_len - 2) bytes
395  */
396 struct GNUNET_DNSPARSER_CaaRecord
397 {
398   /**
399    * The flags of the CAA record.
400    */
401   uint8_t flags;
402
403   /**
404    * The length of the tag.
405    */
406   uint8_t tag_len;
407 };
408
409
410 /**
411  * Binary record information (unparsed).
412  */
413 struct GNUNET_DNSPARSER_RawRecord
414 {
415   /**
416    * Binary record data.
417    */
418   void *data;
419
420   /**
421    * Number of bytes in data.
422    */
423   size_t data_len;
424 };
425
426
427 /**
428  * A DNS response record.
429  */
430 struct GNUNET_DNSPARSER_Record
431 {
432   /**
433    * Name of the record that the query is for (0-terminated).
434    * In UTF-8 format.  The library will convert from and to DNS-IDNA
435    * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
436    * individual label is well-formed.  If a given name is not well-formed,
437    * creating the DNS packet will fail.
438    */
439   char *name;
440
441   /**
442    * Payload of the record (which one of these is valid depends on the 'type').
443    */
444   union
445   {
446     /**
447      * For NS, CNAME and PTR records, this is the uncompressed 0-terminated hostname.
448      * In UTF-8 format.  The library will convert from and to DNS-IDNA
449      * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
450      * individual label is well-formed.  If a given name is not well-formed,
451      * creating the DNS packet will fail.
452      */
453     char *hostname;
454
455     /**
456      * SOA data for SOA records.
457      */
458     struct GNUNET_DNSPARSER_SoaRecord *soa;
459
460     /**
461      * CERT data for CERT records.
462      */
463     struct GNUNET_DNSPARSER_CertRecord *cert;
464
465     /**
466      * MX data for MX records.
467      */
468     struct GNUNET_DNSPARSER_MxRecord *mx;
469
470     /**
471      * SRV data for SRV records.
472      */
473     struct GNUNET_DNSPARSER_SrvRecord *srv;
474
475     /**
476      * Raw data for all other types.
477      */
478     struct GNUNET_DNSPARSER_RawRecord raw;
479   } data;
480
481
482   /**
483    * When does the record expire?
484    */
485   struct GNUNET_TIME_Absolute expiration_time;
486
487   /**
488    * See GNUNET_DNSPARSER_TYPE_*.
489    */
490   uint16_t type;
491
492   /**
493    * See GNUNET_TUN_DNS_CLASS_*.
494    */
495   uint16_t dns_traffic_class;
496 };
497
498
499 /**
500  * Easy-to-process, parsed version of a DNS packet.
501  */
502 struct GNUNET_DNSPARSER_Packet
503 {
504   /**
505    * Array of all queries in the packet, must contain "num_queries" entries.
506    */
507   struct GNUNET_DNSPARSER_Query *queries;
508
509   /**
510    * Array of all answers in the packet, must contain "num_answers" entries.
511    */
512   struct GNUNET_DNSPARSER_Record *answers;
513
514   /**
515    * Array of all authority records in the packet, must contain "num_authority_records" entries.
516    */
517   struct GNUNET_DNSPARSER_Record *authority_records;
518
519   /**
520    * Array of all additional answers in the packet, must contain "num_additional_records" entries.
521    */
522   struct GNUNET_DNSPARSER_Record *additional_records;
523
524   /**
525    * Number of queries in the packet.
526    */
527   unsigned int num_queries;
528
529   /**
530    * Number of answers in the packet, should be 0 for queries.
531    */
532   unsigned int num_answers;
533
534   /**
535    * Number of authoritative answers in the packet, should be 0 for queries.
536    */
537   unsigned int num_authority_records;
538
539   /**
540    * Number of additional records in the packet, should be 0 for queries.
541    */
542   unsigned int num_additional_records;
543
544   /**
545    * Bitfield of DNS flags.
546    */
547   struct GNUNET_TUN_DnsFlags flags;
548
549   /**
550    * DNS ID (to match replies to requests).
551    */
552   uint16_t id;
553 };
554
555
556 /**
557  * Check if a label in UTF-8 format can be coded into valid IDNA.
558  * This can fail if the ASCII-conversion becomes longer than 63 characters.
559  *
560  * @param label label to check (UTF-8 string)
561  * @return #GNUNET_OK if the label can be converted to IDNA,
562  *         #GNUNET_SYSERR if the label is not valid for DNS names
563  */
564 int
565 GNUNET_DNSPARSER_check_label (const char *label);
566
567
568 /**
569  * Check if a hostname in UTF-8 format can be coded into valid IDNA.
570  * This can fail if a label becomes longer than 63 characters or if
571  * the entire name exceeds 253 characters.
572  *
573  * @param name name to check (UTF-8 string)
574  * @return #GNUNET_OK if the label can be converted to IDNA,
575  *         #GNUNET_SYSERR if the label is not valid for DNS names
576  */
577 int
578 GNUNET_DNSPARSER_check_name (const char *name);
579
580
581 /**
582  * Parse a UDP payload of a DNS packet in to a nice struct for further
583  * processing and manipulation.
584  *
585  * @param udp_payload wire-format of the DNS packet
586  * @param udp_payload_length number of bytes in @a udp_payload
587  * @return NULL on error, otherwise the parsed packet
588  */
589 struct GNUNET_DNSPARSER_Packet *
590 GNUNET_DNSPARSER_parse (const char *udp_payload,
591                         size_t udp_payload_length);
592
593
594 /**
595  * Free memory taken by a packet.
596  *
597  * @param p packet to free
598  */
599 void
600 GNUNET_DNSPARSER_free_packet (struct GNUNET_DNSPARSER_Packet *p);
601
602
603 /**
604  * Given a DNS packet @a p, generate the corresponding UDP payload.
605  * Note that we do not attempt to pack the strings with pointers
606  * as this would complicate the code and this is about being
607  * simple and secure, not fast, fancy and broken like bind.
608  *
609  * @param p packet to pack
610  * @param max maximum allowed size for the resulting UDP payload
611  * @param buf set to a buffer with the packed message
612  * @param buf_length set to the length of @a buf
613  * @return #GNUNET_SYSERR if @a p is invalid
614  *         #GNUNET_NO if @a p was truncated (but there is still a result in @a buf)
615  *         #GNUNET_OK if @a p was packed completely into @a buf
616  */
617 int
618 GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
619                        uint16_t max,
620                        char **buf,
621                        size_t *buf_length);
622
623 /* ***************** low-level packing API ******************** */
624
625 /**
626  * Add a DNS name to the UDP packet at the given location, converting
627  * the name to IDNA notation as necessary.
628  *
629  * @param dst where to write the name (UDP packet)
630  * @param dst_len number of bytes in @a dst
631  * @param off pointer to offset where to write the name (increment by bytes used)
632  *            must not be changed if there is an error
633  * @param name name to write
634  * @return #GNUNET_SYSERR if @a name is invalid
635  *         #GNUNET_NO if @a name did not fit
636  *         #GNUNET_OK if @a name was added to @a dst
637  */
638 int
639 GNUNET_DNSPARSER_builder_add_name (char *dst,
640                                    size_t dst_len,
641                                    size_t *off,
642                                    const char *name);
643
644
645 /**
646  * Add a DNS query to the UDP packet at the given location.
647  *
648  * @param dst where to write the query
649  * @param dst_len number of bytes in @a dst
650  * @param off pointer to offset where to write the query (increment by bytes used)
651  *            must not be changed if there is an error
652  * @param query query to write
653  * @return #GNUNET_SYSERR if @a query is invalid
654  *         #GNUNET_NO if @a query did not fit
655  *         #GNUNET_OK if @a query was added to @a dst
656  */
657 int
658 GNUNET_DNSPARSER_builder_add_query (char *dst,
659                                     size_t dst_len,
660                                     size_t *off,
661                                     const struct GNUNET_DNSPARSER_Query *query);
662
663
664 /**
665  * Add an MX record to the UDP packet at the given location.
666  *
667  * @param dst where to write the mx record
668  * @param dst_len number of bytes in @a dst
669  * @param off pointer to offset where to write the mx information (increment by bytes used);
670  *            can also change if there was an error
671  * @param mx mx information to write
672  * @return #GNUNET_SYSERR if @a mx is invalid
673  *         #GNUNET_NO if @a mx did not fit
674  *         #GNUNET_OK if @a mx was added to @a dst
675  */
676 int
677 GNUNET_DNSPARSER_builder_add_mx (char *dst,
678                                  size_t dst_len,
679                                  size_t *off,
680                                  const struct GNUNET_DNSPARSER_MxRecord *mx);
681
682
683 /**
684  * Add an SOA record to the UDP packet at the given location.
685  *
686  * @param dst where to write the SOA record
687  * @param dst_len number of bytes in @a dst
688  * @param off pointer to offset where to write the SOA information (increment by bytes used)
689  *            can also change if there was an error
690  * @param soa SOA information to write
691  * @return #GNUNET_SYSERR if @a soa is invalid
692  *         #GNUNET_NO if @a soa did not fit
693  *         #GNUNET_OK if @a soa was added to @a dst
694  */
695 int
696 GNUNET_DNSPARSER_builder_add_soa (char *dst,
697                                   size_t dst_len,
698                                   size_t *off,
699                                   const struct GNUNET_DNSPARSER_SoaRecord *soa);
700
701
702 /**
703  * Add CERT record to the UDP packet at the given location.
704  *
705  * @param dst where to write the CERT record
706  * @param dst_len number of bytes in @a dst
707  * @param off pointer to offset where to write the CERT information (increment by bytes used)
708  *            can also change if there was an error
709  * @param cert CERT information to write
710  * @return #GNUNET_SYSERR if @a soa is invalid
711  *         #GNUNET_NO if @a soa did not fit
712  *         #GNUNET_OK if @a soa was added to @a dst
713  */
714 int
715 GNUNET_DNSPARSER_builder_add_cert (char *dst,
716                                    size_t dst_len,
717                                    size_t *off,
718                                    const struct
719                                    GNUNET_DNSPARSER_CertRecord *cert);
720
721
722 /**
723  * Add an SRV record to the UDP packet at the given location.
724  *
725  * @param dst where to write the SRV record
726  * @param dst_len number of bytes in @a dst
727  * @param off pointer to offset where to write the SRV information (increment by bytes used)
728  *            can also change if there was an error
729  * @param srv SRV information to write
730  * @return #GNUNET_SYSERR if @a srv is invalid
731  *         #GNUNET_NO if @a srv did not fit
732  *         #GNUNET_OK if @a srv was added to @a dst
733  */
734 int
735 GNUNET_DNSPARSER_builder_add_srv (char *dst,
736                                   size_t dst_len,
737                                   size_t *off,
738                                   const struct GNUNET_DNSPARSER_SrvRecord *srv);
739
740 /* ***************** low-level parsing API ******************** */
741
742 /**
743  * Parse a DNS record entry.
744  *
745  * @param udp_payload entire UDP payload
746  * @param udp_payload_length length of @a udp_payload
747  * @param off pointer to the offset of the record to parse in the udp_payload (to be
748  *                    incremented by the size of the record)
749  * @param r where to write the record information
750  * @return #GNUNET_OK on success, #GNUNET_SYSERR if the record is malformed
751  */
752 int
753 GNUNET_DNSPARSER_parse_record (const char *udp_payload,
754                                size_t udp_payload_length,
755                                size_t *off,
756                                struct GNUNET_DNSPARSER_Record *r);
757
758
759 /**
760  * Parse name inside of a DNS query or record.
761  *
762  * @param udp_payload entire UDP payload
763  * @param udp_payload_length length of @a udp_payload
764  * @param off pointer to the offset of the name to parse in the udp_payload (to be
765  *                    incremented by the size of the name)
766  * @return name as 0-terminated C string on success, NULL if the payload is malformed
767  */
768 char *
769 GNUNET_DNSPARSER_parse_name (const char *udp_payload,
770                              size_t udp_payload_length,
771                              size_t *off);
772
773
774 /**
775  * Parse a DNS query entry.
776  *
777  * @param udp_payload entire UDP payload
778  * @param udp_payload_length length of @a udp_payload
779  * @param off pointer to the offset of the query to parse in the udp_payload (to be
780  *                    incremented by the size of the query)
781  * @param q where to write the query information
782  * @return #GNUNET_OK on success, #GNUNET_SYSERR if the query is malformed
783  */
784 int
785 GNUNET_DNSPARSER_parse_query (const char *udp_payload,
786                               size_t udp_payload_length,
787                               size_t *off,
788                               struct GNUNET_DNSPARSER_Query *q);
789
790
791 /**
792  * Parse a DNS SOA record.
793  *
794  * @param udp_payload reference to UDP packet
795  * @param udp_payload_length length of @a udp_payload
796  * @param off pointer to the offset of the query to parse in the SOA record (to be
797  *                    incremented by the size of the record), unchanged on error
798  * @return the parsed SOA record, NULL on error
799  */
800 struct GNUNET_DNSPARSER_SoaRecord *
801 GNUNET_DNSPARSER_parse_soa (const char *udp_payload,
802                             size_t udp_payload_length,
803                             size_t *off);
804
805
806 /**
807  * Parse a DNS CERT record.
808  *
809  * @param udp_payload reference to UDP packet
810  * @param udp_payload_length length of @a udp_payload
811  * @param off pointer to the offset of the query to parse in the CERT record (to be
812  *                    incremented by the size of the record), unchanged on error
813  * @return the parsed CERT record, NULL on error
814  */
815 struct GNUNET_DNSPARSER_CertRecord *
816 GNUNET_DNSPARSER_parse_cert (const char *udp_payload,
817                              size_t udp_payload_length,
818                              size_t *off);
819
820
821 /**
822  * Parse a DNS MX record.
823  *
824  * @param udp_payload reference to UDP packet
825  * @param udp_payload_length length of @a udp_payload
826  * @param off pointer to the offset of the query to parse in the MX record (to be
827  *                    incremented by the size of the record), unchanged on error
828  * @return the parsed MX record, NULL on error
829  */
830 struct GNUNET_DNSPARSER_MxRecord *
831 GNUNET_DNSPARSER_parse_mx (const char *udp_payload,
832                            size_t udp_payload_length,
833                            size_t *off);
834
835
836 /**
837  * Parse a DNS SRV record.
838  *
839  * @param udp_payload reference to UDP packet
840  * @param udp_payload_length length of @a udp_payload
841  * @param off pointer to the offset of the query to parse in the SRV record (to be
842  *                    incremented by the size of the record), unchanged on error
843  * @return the parsed SRV record, NULL on error
844  */
845 struct GNUNET_DNSPARSER_SrvRecord *
846 GNUNET_DNSPARSER_parse_srv (const char *udp_payload,
847                             size_t udp_payload_length,
848                             size_t *off);
849
850 /* ***************** low-level duplication API ******************** */
851
852 /**
853  * Duplicate (deep-copy) the given DNS record
854  *
855  * @param r the record
856  * @return the newly allocated record
857  */
858 struct GNUNET_DNSPARSER_Record *
859 GNUNET_DNSPARSER_duplicate_record (const struct GNUNET_DNSPARSER_Record *r);
860
861
862 /**
863  * Duplicate (deep-copy) the given DNS record
864  *
865  * @param r the record
866  * @return the newly allocated record
867  */
868 struct GNUNET_DNSPARSER_SoaRecord *
869 GNUNET_DNSPARSER_duplicate_soa_record (const struct
870                                        GNUNET_DNSPARSER_SoaRecord *r);
871
872
873 /**
874  * Duplicate (deep-copy) the given DNS record
875  *
876  * @param r the record
877  * @return the newly allocated record
878  */
879 struct GNUNET_DNSPARSER_CertRecord *
880 GNUNET_DNSPARSER_duplicate_cert_record (const struct
881                                         GNUNET_DNSPARSER_CertRecord *r);
882
883
884 /**
885  * Duplicate (deep-copy) the given DNS record
886  *
887  * @param r the record
888  * @return the newly allocated record
889  */
890 struct GNUNET_DNSPARSER_MxRecord *
891 GNUNET_DNSPARSER_duplicate_mx_record (const struct
892                                       GNUNET_DNSPARSER_MxRecord *r);
893
894
895 /**
896  * Duplicate (deep-copy) the given DNS record
897  *
898  * @param r the record
899  * @return the newly allocated record
900  */
901 struct GNUNET_DNSPARSER_SrvRecord *
902 GNUNET_DNSPARSER_duplicate_srv_record (const struct
903                                        GNUNET_DNSPARSER_SrvRecord *r);
904
905
906 /* ***************** low-level deallocation API ******************** */
907
908 /**
909  * Free the given DNS record.
910  *
911  * @param r record to free
912  */
913 void
914 GNUNET_DNSPARSER_free_record (struct GNUNET_DNSPARSER_Record *r);
915
916
917 /**
918  * Free MX information record.
919  *
920  * @param mx record to free
921  */
922 void
923 GNUNET_DNSPARSER_free_mx (struct GNUNET_DNSPARSER_MxRecord *mx);
924
925
926 /**
927  * Free SRV information record.
928  *
929  * @param srv record to free
930  */
931 void
932 GNUNET_DNSPARSER_free_srv (struct GNUNET_DNSPARSER_SrvRecord *srv);
933
934
935 /**
936  * Free SOA information record.
937  *
938  * @param soa record to free
939  */
940 void
941 GNUNET_DNSPARSER_free_soa (struct GNUNET_DNSPARSER_SoaRecord *soa);
942
943
944 /**
945  * Free CERT information record.
946  *
947  * @param cert record to free
948  */
949 void
950 GNUNET_DNSPARSER_free_cert (struct GNUNET_DNSPARSER_CertRecord *cert);
951
952
953 /**
954  * Convert a block of binary data to HEX.
955  *
956  * @param data binary data to convert
957  * @param data_size number of bytes in @a data
958  * @return HEX string (lower case)
959  */
960 char *
961 GNUNET_DNSPARSER_bin_to_hex (const void *data,
962                              size_t data_size);
963
964
965 /**
966  * Convert a HEX string to block of binary data.
967  *
968  * @param hex HEX string to convert (may contain mixed case)
969  * @param data where to write result, must be
970  *             at least `strlen(hex)/2` bytes long
971  * @return number of bytes written to data
972  */
973 size_t
974 GNUNET_DNSPARSER_hex_to_bin (const char *hex,
975                              void *data);
976
977
978 #endif
979
980 /** @} */  /* end of group */