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