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