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