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