Implement data ack in CADET MQ API
[oweals/gnunet.git] / src / include / gnunet_dnsparser_lib.h
index 0c310ba003feb342e9fb77c74cfa1e244841d5c2..9fe3491d672a734611d6dbad6e0f7194b44eacf9 100644 (file)
@@ -1,10 +1,10 @@
 /*
       This file is part of GNUnet
 /*
       This file is part of GNUnet
-      (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
+      Copyright (C) 2010-2014 GNUnet e.V.
 
       GNUnet is free software; you can redistribute it and/or modify
       it under the terms of the GNU General Public License as published
 
       GNUnet is free software; you can redistribute it and/or modify
       it under the terms of the GNU General Public License as published
-      by the Free Software Foundation; either version 2, or (at your
+      by the Free Software Foundation; either version 3, or (at your
       option) any later version.
 
       GNUnet is distributed in the hope that it will be useful, but
       option) any later version.
 
       GNUnet is distributed in the hope that it will be useful, but
 
       You should have received a copy of the GNU General Public License
       along with GNUnet; see the file COPYING.  If not, write to the
 
       You should have received a copy of the GNU General Public License
       along with GNUnet; see the file COPYING.  If not, write to the
-      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-      Boston, MA 02111-1307, USA.
+      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301, USA.
  */
 
 /**
  */
 
 /**
- * @file include/gnunet_dnsparser_lib.h
- * @brief API for helper library to parse DNS packets. 
  * @author Philipp Toelke
  * @author Christian Grothoff
  * @author Philipp Toelke
  * @author Christian Grothoff
+ *
+ * @file
+ * API for helper library to parse DNS packets.
+ *
+ * @defgroup dns-parser  DNS parser library
+ * Helper library to parse DNS packets.
+ * @{
  */
 #ifndef GNUNET_DNSPARSER_LIB_H
 #define GNUNET_DNSPARSER_LIB_H
 
  */
 #ifndef GNUNET_DNSPARSER_LIB_H
 #define GNUNET_DNSPARSER_LIB_H
 
-#include "platform.h"
-#include "gnunet_common.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_tun_lib.h"
+
+/**
+ * Maximum length of a label in DNS.
+ */
+#define GNUNET_DNSPARSER_MAX_LABEL_LENGTH 63
+
+/**
+ * Maximum length of a name in DNS.
+ */
+#define GNUNET_DNSPARSER_MAX_NAME_LENGTH 253
+
 
 /**
  * A few common DNS types.
 
 /**
  * A few common DNS types.
 #define GNUNET_DNSPARSER_TYPE_MX 15
 #define GNUNET_DNSPARSER_TYPE_TXT 16
 #define GNUNET_DNSPARSER_TYPE_AAAA 28
 #define GNUNET_DNSPARSER_TYPE_MX 15
 #define GNUNET_DNSPARSER_TYPE_TXT 16
 #define GNUNET_DNSPARSER_TYPE_AAAA 28
+#define GNUNET_DNSPARSER_TYPE_SRV 33
+#define GNUNET_DNSPARSER_TYPE_CERT 37
+#define GNUNET_DNSPARSER_TYPE_TLSA 52
+
 
 /**
 
 /**
- * A few common DNS classes (ok, only one is common, but I list a
- * couple more to make it clear what we're talking about here).
+ * A DNS query.
  */
  */
-#define GNUNET_DNSPARSER_CLASS_INTERNET 1
-#define GNUNET_DNSPARSER_CLASS_CHAOS 3
-#define GNUNET_DNSPARSER_CLASS_HESIOD 4
+struct GNUNET_DNSPARSER_Query
+{
 
 
-#define GNUNET_DNSPARSER_OPCODE_QUERY 0
-#define GNUNET_DNSPARSER_OPCODE_INVERSE_QUERY 1
-#define GNUNET_DNSPARSER_OPCODE_STATUS 2
+  /**
+   * Name of the record that the query is for (0-terminated).
+   * In UTF-8 format.  The library will convert from and to DNS-IDNA
+   * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
+   * individual label is well-formed.  If a given name is not well-formed,
+   * creating the DNS packet will fail.
+   */
+  char *name;
+
+  /**
+   * See GNUNET_DNSPARSER_TYPE_*.
+   */
+  uint16_t type;
+
+  /**
+   * See GNUNET_TUN_DNS_CLASS_*.
+   */
+  uint16_t dns_traffic_class;
+
+};
 
 
-/**
- * RFC 1035 codes.
- */
-#define GNUNET_DNSPARSER_RETURN_CODE_NO_ERROR 0
-#define GNUNET_DNSPARSER_RETURN_CODE_FORMAT_ERROR 1
-#define GNUNET_DNSPARSER_RETURN_CODE_SERVER_FAILURE 2
-#define GNUNET_DNSPARSER_RETURN_CODE_NAME_ERROR 3
-#define GNUNET_DNSPARSER_RETURN_CODE_NOT_IMPLEMENTED 4
-#define GNUNET_DNSPARSER_RETURN_CODE_REFUSED 5
 
 /**
 
 /**
- * RFC 2136 codes
+ * Information from MX records (RFC 1035).
  */
  */
-#define GNUNET_DNSPARSER_RETURN_CODE_YXDOMAIN 6
-#define GNUNET_DNSPARSER_RETURN_CODE_YXRRSET 7
-#define GNUNET_DNSPARSER_RETURN_CODE_NXRRSET 8
-#define GNUNET_DNSPARSER_RETURN_CODE_NOT_AUTH 9
-#define GNUNET_DNSPARSER_RETURN_CODE_NOT_ZONE 10
+struct GNUNET_DNSPARSER_MxRecord
+{
+
+  /**
+   * Preference for this entry (lower value is higher preference).
+   */
+  uint16_t preference;
+
+  /**
+   * Name of the mail server.
+   * In UTF-8 format.  The library will convert from and to DNS-IDNA
+   * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
+   * individual label is well-formed.  If a given name is not well-formed,
+   * creating the DNS packet will fail.
+   */
+  char *mxhost;
+
+};
+
 
 /**
 
 /**
- * DNS flags (largely RFC 1035 / RFC 2136).
+ * Information from SRV records (RFC 2782).
  */
  */
-struct GNUNET_DNSPARSER_Flags
+struct GNUNET_DNSPARSER_SrvRecord
 {
 {
+
   /**
   /**
-   * Set to 1 if recursion is desired (client -> server)
+   * Hostname offering the service.
+   * In UTF-8 format.  The library will convert from and to DNS-IDNA
+   * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
+   * individual label is well-formed.  If a given name is not well-formed,
+   * creating the DNS packet will fail.
    */
    */
-  unsigned int recursion_desired    : 1 GNUNET_PACKED;  
-  
+  char *target;
+
   /**
   /**
-   * Set to 1 if message is truncated
+   * Preference for this entry (lower value is higher preference).  Clients
+   * will contact hosts from the lowest-priority group first and fall back
+   * to higher priorities if the low-priority entries are unavailable.
    */
    */
-  unsigned int message_truncated    : 1 GNUNET_PACKED; 
-  
+  uint16_t priority;
+
   /**
   /**
-   * Set to 1 if this is an authoritative answer
+   * Relative weight for records with the same priority.  Clients will use
+   * the hosts of the same (lowest) priority with a probability proportional
+   * to the weight given.
    */
    */
-  unsigned int authoritative_answer : 1 GNUNET_PACKED;
-  
+  uint16_t weight;
+
   /**
   /**
-   * See GNUNET_DNSPARSER_OPCODE_ defines.
+   * TCP or UDP port of the service.
    */
    */
-  unsigned int opcode               : 4 GNUNET_PACKED;  
-  
+  uint16_t port;
+
+};
+
+
+/**
+ * DNS CERT types as defined in RFC 4398.
+ */
+enum GNUNET_DNSPARSER_CertType
+{
+  /**
+   *  Reserved value
+   */
+  GNUNET_DNSPARSER_CERTTYPE_RESERVED = 0,
+
+  /**
+   * An x509 PKIX certificate
+   */
+  GNUNET_DNSPARSER_CERTTYPE_PKIX = 1,
+
   /**
   /**
-   * query:0, response:1
+   * A SKPI certificate
    */
    */
-  unsigned int query_or_response    : 1 GNUNET_PACKED;  
-  
+  GNUNET_DNSPARSER_CERTTYPE_SKPI = 2,
+
+  /**
+   * A PGP certificate
+   */
+  GNUNET_DNSPARSER_CERTTYPE_PGP = 3,
+
   /**
   /**
-   * See GNUNET_DNSPARSER_RETURN_CODE_ defines.
+   * An x509 PKIX cert URL
    */
    */
-  unsigned int return_code          : 4 GNUNET_PACKED; 
-  
+  GNUNET_DNSPARSER_CERTTYPE_IPKIX = 4,
+
   /**
   /**
-   * See RFC 4035.
+   * A SKPI cert URL
    */
    */
-  unsigned int checking_disabled    : 1 GNUNET_PACKED; 
-  
+  GNUNET_DNSPARSER_CERTTYPE_ISKPI = 5,
+
   /**
   /**
-   * Response has been cryptographically verified, RFC 4035.
+   * A PGP cert fingerprint and URL
    */
    */
-  unsigned int authenticated_data   : 1 GNUNET_PACKED;
-  
+  GNUNET_DNSPARSER_CERTTYPE_IPGP = 6,
+
   /**
   /**
-   * Always zero.
+   * An attribute Certificate
    */
    */
-  unsigned int zero                 : 1 GNUNET_PACKED;
-  
+  GNUNET_DNSPARSER_CERTTYPE_ACPKIX = 7,
+
   /**
   /**
-   * Set to 1 if recursion is available (server -> client)
+   * An attribute cert URL
    */
    */
-  unsigned int recursion_available  : 1 GNUNET_PACKED; 
-  
+  GNUNET_DNSPARSER_CERTTYPE_IACKPIX = 8
 };
 
 
 /**
 };
 
 
 /**
- * A DNS query.
+ * DNSCERT algorithms as defined in http://www.iana.org/assignments/
+ *  dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml, under dns-sec-alg-numbers-1
  */
  */
-struct GNUNET_DNSPARSER_Query
+enum GNUNET_DNSPARSER_CertAlgorithm
 {
 {
+  /**
+   * No defined
+   */
+  GNUNET_DNSPARSER_CERTALGO_UNDEFINED = 0,
 
   /**
 
   /**
-   * Name of the record that the query is for (0-terminated).
+   * RSA/MD5
    */
    */
-  char *name;
+  GNUNET_DNSPARSER_CERTALGO_RSAMD5 = 1,
 
   /**
 
   /**
-   * See GNUNET_DNSPARSER_TYPE_*.
+   * Diffie-Hellman
    */
    */
-  uint16_t type;
+  GNUNET_DNSPARSER_CERTALGO_DH = 2,
+
+  /**
+   * DSA/SHA1
+   */
+  GNUNET_DNSPARSER_CERTALGO_DSASHA = 3,
+
+  /**
+   * Reserved
+   */
+  GNUNET_DNSPARSER_CERTALGO_RSRVD4 = 4,
+
+  /**
+   * RSA/SHA1
+   */
+  GNUNET_DNSPARSER_CERTALGO_RSASHA = 5,
+
+  /**
+   * DSA/NSEC3/SHA
+   */
+  GNUNET_DNSPARSER_CERTALGO_DSANSEC3 = 6,
+
+  /**
+   * RSA/NSEC3/SHA
+   */
+  GNUNET_DNSPARSER_CERTALGO_RSANSEC3 = 7,
+
+  /**
+   * RSA/SHA256
+   */
+  GNUNET_DNSPARSER_CERTALGO_RSASHA256 = 8,
+
+  /**
+   * Reserved
+   */
+  GNUNET_DNSPARSER_CERTALGO_RSRVD9 = 9,
 
   /**
 
   /**
-   * See GNUNET_DNSPARSER_CLASS_*.
+   * RSA/SHA512
    */
    */
-  uint16_t class;
+  GNUNET_DNSPARSER_CERTALGO_RSASHA512 = 10,
+
+  /**
+   * GOST R 34.10-2001
+   */
+  GNUNET_DNSPARSER_CERTALGO_GOST_R34 = 12,
+
+  /**
+   * ECDSA Curve P-256/SHA256
+   */
+  GNUNET_DNSPARSER_CERTALGO_ECDSA_P256SHA256 = 13,
+
+  /**
+   * ECDSA Curve P-384/SHA384
+   */
+  GNUNET_DNSPARSER_CERTALGO_ECDSA_P384SHA384 = 14
 
 };
 
 
 /**
 
 };
 
 
 /**
- * Information from MX records (RFC 1035).
+ * Information from CERT records (RFC 4034).
  */
  */
-struct GNUNET_DNSPARSER_MxRecord
+struct GNUNET_DNSPARSER_CertRecord
 {
 {
-  
+
   /**
   /**
-   * Preference for this entry (lower value is higher preference).
+   * Certificate type
    */
    */
-  uint16_t preference;
+  enum GNUNET_DNSPARSER_CertType cert_type;
 
   /**
 
   /**
-   * Name of the mail server.
+   * Certificate KeyTag
    */
    */
-  char *mxhost;
+  uint16_t cert_tag;
+
+  /**
+   * Algorithm
+   */
+  enum GNUNET_DNSPARSER_CertAlgorithm algorithm;
+
+  /**
+   * Number of bytes in @e certificate_data
+   */
+  size_t certificate_size;
+
+  /**
+   * Data of the certificate.
+   */
+  char *certificate_data;
 
 };
 
 
 };
 
-  
+
 /**
  * Information from SOA records (RFC 1035).
  */
 struct GNUNET_DNSPARSER_SoaRecord
 {
 /**
  * Information from SOA records (RFC 1035).
  */
 struct GNUNET_DNSPARSER_SoaRecord
 {
-  
+
   /**
   /**
-   *The domainname of the name server that was the
+   * The domainname of the name server that was the
    * original or primary source of data for this zone.
    * original or primary source of data for this zone.
+   * In UTF-8 format.  The library will convert from and to DNS-IDNA
+   * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
+   * individual label is well-formed.  If a given name is not well-formed,
+   * creating the DNS packet will fail.
    */
   char *mname;
 
   /**
    * A domainname which specifies the mailbox of the
    * person responsible for this zone.
    */
   char *mname;
 
   /**
    * A domainname which specifies the mailbox of the
    * person responsible for this zone.
+   * In UTF-8 format.  The library will convert from and to DNS-IDNA
+   * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
+   * individual label is well-formed.  If a given name is not well-formed,
+   * creating the DNS packet will fail.
    */
   char *rname;
 
   /**
    */
   char *rname;
 
   /**
-   * The version number of the original copy of the zone.  
+   * The version number of the original copy of the zone.
    */
   uint32_t serial;
 
    */
   uint32_t serial;
 
@@ -219,7 +368,7 @@ struct GNUNET_DNSPARSER_SoaRecord
    * from this zone.
    */
   uint32_t minimum_ttl;
    * from this zone.
    */
   uint32_t minimum_ttl;
-  
+
 };
 
 
 };
 
 
@@ -249,27 +398,48 @@ struct GNUNET_DNSPARSER_Record
 
   /**
    * Name of the record that the query is for (0-terminated).
 
   /**
    * Name of the record that the query is for (0-terminated).
+   * In UTF-8 format.  The library will convert from and to DNS-IDNA
+   * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
+   * individual label is well-formed.  If a given name is not well-formed,
+   * creating the DNS packet will fail.
    */
   char *name;
 
    */
   char *name;
 
-  union 
+  /**
+   * Payload of the record (which one of these is valid depends on the 'type').
+   */
+  union
   {
 
     /**
      * For NS, CNAME and PTR records, this is the uncompressed 0-terminated hostname.
   {
 
     /**
      * For NS, CNAME and PTR records, this is the uncompressed 0-terminated hostname.
+   * In UTF-8 format.  The library will convert from and to DNS-IDNA
+   * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
+   * individual label is well-formed.  If a given name is not well-formed,
+   * creating the DNS packet will fail.
      */
     char *hostname;
      */
     char *hostname;
-    
+
     /**
      * SOA data for SOA records.
      */
     struct GNUNET_DNSPARSER_SoaRecord *soa;
     /**
      * SOA data for SOA records.
      */
     struct GNUNET_DNSPARSER_SoaRecord *soa;
-    
+
+    /**
+     * CERT data for CERT records.
+     */
+    struct GNUNET_DNSPARSER_CertRecord *cert;
+
     /**
      * MX data for MX records.
      */
     struct GNUNET_DNSPARSER_MxRecord *mx;
 
     /**
      * MX data for MX records.
      */
     struct GNUNET_DNSPARSER_MxRecord *mx;
 
+    /**
+     * SRV data for SRV records.
+     */
+    struct GNUNET_DNSPARSER_SrvRecord *srv;
+
     /**
      * Raw data for all other types.
      */
     /**
      * Raw data for all other types.
      */
@@ -289,9 +459,9 @@ struct GNUNET_DNSPARSER_Record
   uint16_t type;
 
   /**
   uint16_t type;
 
   /**
-   * See GNUNET_DNSPARSER_CLASS_*.
+   * See GNUNET_TUN_DNS_CLASS_*.
    */
    */
-  uint16_t class;
+  uint16_t dns_traffic_class;
 
 };
 
 
 };
 
@@ -343,8 +513,8 @@ struct GNUNET_DNSPARSER_Packet
 
   /**
    * Bitfield of DNS flags.
 
   /**
    * Bitfield of DNS flags.
-   */ 
-  struct GNUNET_DNSPARSER_Flags flags;
+   */
+  struct GNUNET_TUN_DnsFlags flags;
 
   /**
    * DNS ID (to match replies to requests).
 
   /**
    * DNS ID (to match replies to requests).
@@ -354,12 +524,37 @@ struct GNUNET_DNSPARSER_Packet
 };
 
 
 };
 
 
+/**
+ * Check if a label in UTF-8 format can be coded into valid IDNA.
+ * This can fail if the ASCII-conversion becomes longer than 63 characters.
+ *
+ * @param label label to check (UTF-8 string)
+ * @return #GNUNET_OK if the label can be converted to IDNA,
+ *         #GNUNET_SYSERR if the label is not valid for DNS names
+ */
+int
+GNUNET_DNSPARSER_check_label (const char *label);
+
+
+/**
+ * Check if a hostname in UTF-8 format can be coded into valid IDNA.
+ * This can fail if a label becomes longer than 63 characters or if
+ * the entire name exceeds 253 characters.
+ *
+ * @param name name to check (UTF-8 string)
+ * @return #GNUNET_OK if the label can be converted to IDNA,
+ *         #GNUNET_SYSERR if the label is not valid for DNS names
+ */
+int
+GNUNET_DNSPARSER_check_name (const char *name);
+
+
 /**
  * Parse a UDP payload of a DNS packet in to a nice struct for further
  * processing and manipulation.
  *
  * @param udp_payload wire-format of the DNS packet
 /**
  * Parse a UDP payload of a DNS packet in to a nice struct for further
  * processing and manipulation.
  *
  * @param udp_payload wire-format of the DNS packet
- * @param udp_payload_length number of bytes in udp_payload 
+ * @param udp_payload_length number of bytes in @a udp_payload
  * @return NULL on error, otherwise the parsed packet
  */
 struct GNUNET_DNSPARSER_Packet *
  * @return NULL on error, otherwise the parsed packet
  */
 struct GNUNET_DNSPARSER_Packet *
@@ -377,15 +572,18 @@ GNUNET_DNSPARSER_free_packet (struct GNUNET_DNSPARSER_Packet *p);
 
 
 /**
 
 
 /**
- * Given a DNS packet, generate the corresponding UDP payload.
+ * Given a DNS packet @a p, generate the corresponding UDP payload.
+ * Note that we do not attempt to pack the strings with pointers
+ * as this would complicate the code and this is about being
+ * simple and secure, not fast, fancy and broken like bind.
  *
  * @param p packet to pack
  * @param max maximum allowed size for the resulting UDP payload
  * @param buf set to a buffer with the packed message
  *
  * @param p packet to pack
  * @param max maximum allowed size for the resulting UDP payload
  * @param buf set to a buffer with the packed message
- * @param buf_length set to the length of buf
- * @return GNUNET_SYSERR if 'p' is invalid
- *         GNUNET_NO if 'p' was truncated (but there is still a result in 'buf')
- *         GNUNET_OK if 'p' was packed completely into '*buf'
+ * @param buf_length set to the length of @a buf
+ * @return #GNUNET_SYSERR if @a p is invalid
+ *         #GNUNET_NO if @a p was truncated (but there is still a result in @a buf)
+ *         #GNUNET_OK if @a p was packed completely into @a buf
  */
 int
 GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
  */
 int
 GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
@@ -393,5 +591,304 @@ GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
                       char **buf,
                       size_t *buf_length);
 
                       char **buf,
                       size_t *buf_length);
 
+/* ***************** low-level packing API ******************** */
+
+/**
+ * Add a DNS name to the UDP packet at the given location, converting
+ * the name to IDNA notation as necessary.
+ *
+ * @param dst where to write the name (UDP packet)
+ * @param dst_len number of bytes in @a dst
+ * @param off pointer to offset where to write the name (increment by bytes used)
+ *            must not be changed if there is an error
+ * @param name name to write
+ * @return #GNUNET_SYSERR if @a name is invalid
+ *         #GNUNET_NO if @a name did not fit
+ *         #GNUNET_OK if @a name was added to @a dst
+ */
+int
+GNUNET_DNSPARSER_builder_add_name (char *dst,
+                                  size_t dst_len,
+                                  size_t *off,
+                                  const char *name);
+
+
+/**
+ * Add a DNS query to the UDP packet at the given location.
+ *
+ * @param dst where to write the query
+ * @param dst_len number of bytes in @a dst
+ * @param off pointer to offset where to write the query (increment by bytes used)
+ *            must not be changed if there is an error
+ * @param query query to write
+ * @return #GNUNET_SYSERR if @a query is invalid
+ *         #GNUNET_NO if @a query did not fit
+ *         #GNUNET_OK if @a query was added to @a dst
+ */
+int
+GNUNET_DNSPARSER_builder_add_query (char *dst,
+                                   size_t dst_len,
+                                   size_t *off,
+                                   const struct GNUNET_DNSPARSER_Query *query);
+
+
+/**
+ * Add an MX record to the UDP packet at the given location.
+ *
+ * @param dst where to write the mx record
+ * @param dst_len number of bytes in @a dst
+ * @param off pointer to offset where to write the mx information (increment by bytes used);
+ *            can also change if there was an error
+ * @param mx mx information to write
+ * @return #GNUNET_SYSERR if @a mx is invalid
+ *         #GNUNET_NO if @a mx did not fit
+ *         #GNUNET_OK if @a mx was added to @a dst
+ */
+int
+GNUNET_DNSPARSER_builder_add_mx (char *dst,
+                                size_t dst_len,
+                                size_t *off,
+                                const struct GNUNET_DNSPARSER_MxRecord *mx);
+
+
+/**
+ * Add an SOA record to the UDP packet at the given location.
+ *
+ * @param dst where to write the SOA record
+ * @param dst_len number of bytes in @a dst
+ * @param off pointer to offset where to write the SOA information (increment by bytes used)
+ *            can also change if there was an error
+ * @param soa SOA information to write
+ * @return #GNUNET_SYSERR if @a soa is invalid
+ *         #GNUNET_NO if @a soa did not fit
+ *         #GNUNET_OK if @a soa was added to @a dst
+ */
+int
+GNUNET_DNSPARSER_builder_add_soa (char *dst,
+                                 size_t dst_len,
+                                 size_t *off,
+                                 const struct GNUNET_DNSPARSER_SoaRecord *soa);
+
+
+/**
+ * Add CERT record to the UDP packet at the given location.
+ *
+ * @param dst where to write the CERT record
+ * @param dst_len number of bytes in @a dst
+ * @param off pointer to offset where to write the CERT information (increment by bytes used)
+ *            can also change if there was an error
+ * @param cert CERT information to write
+ * @return #GNUNET_SYSERR if @a soa is invalid
+ *         #GNUNET_NO if @a soa did not fit
+ *         #GNUNET_OK if @a soa was added to @a dst
+ */
+int
+GNUNET_DNSPARSER_builder_add_cert (char *dst,
+                                   size_t dst_len,
+                                   size_t *off,
+                                   const struct GNUNET_DNSPARSER_CertRecord *cert);
+
+
+/**
+ * Add an SRV record to the UDP packet at the given location.
+ *
+ * @param dst where to write the SRV record
+ * @param dst_len number of bytes in @a dst
+ * @param off pointer to offset where to write the SRV information (increment by bytes used)
+ *            can also change if there was an error
+ * @param srv SRV information to write
+ * @return #GNUNET_SYSERR if @a srv is invalid
+ *         #GNUNET_NO if @a srv did not fit
+ *         #GNUNET_OK if @a srv was added to @a dst
+ */
+int
+GNUNET_DNSPARSER_builder_add_srv (char *dst,
+                                 size_t dst_len,
+                                 size_t *off,
+                                 const struct GNUNET_DNSPARSER_SrvRecord *srv);
+
+/* ***************** low-level parsing API ******************** */
+
+/**
+ * Parse a DNS record entry.
+ *
+ * @param udp_payload entire UDP payload
+ * @param udp_payload_length length of @a udp_payload
+ * @param off pointer to the offset of the record to parse in the udp_payload (to be
+ *                    incremented by the size of the record)
+ * @param r where to write the record information
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR if the record is malformed
+ */
+int
+GNUNET_DNSPARSER_parse_record (const char *udp_payload,
+                              size_t udp_payload_length,
+                              size_t *off,
+                              struct GNUNET_DNSPARSER_Record *r);
+
+
+/**
+ * Parse name inside of a DNS query or record.
+ *
+ * @param udp_payload entire UDP payload
+ * @param udp_payload_length length of @a udp_payload
+ * @param off pointer to the offset of the name to parse in the udp_payload (to be
+ *                    incremented by the size of the name)
+ * @return name as 0-terminated C string on success, NULL if the payload is malformed
+ */
+char *
+GNUNET_DNSPARSER_parse_name (const char *udp_payload,
+                            size_t udp_payload_length,
+                            size_t *off);
+
+
+/**
+ * Parse a DNS query entry.
+ *
+ * @param udp_payload entire UDP payload
+ * @param udp_payload_length length of @a udp_payload
+ * @param off pointer to the offset of the query to parse in the udp_payload (to be
+ *                    incremented by the size of the query)
+ * @param q where to write the query information
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR if the query is malformed
+ */
+int
+GNUNET_DNSPARSER_parse_query (const char *udp_payload,
+                             size_t udp_payload_length,
+                             size_t *off,
+                             struct GNUNET_DNSPARSER_Query *q);
+
+
+/**
+ * Parse a DNS SOA record.
+ *
+ * @param udp_payload reference to UDP packet
+ * @param udp_payload_length length of @a udp_payload
+ * @param off pointer to the offset of the query to parse in the SOA record (to be
+ *                    incremented by the size of the record), unchanged on error
+ * @return the parsed SOA record, NULL on error
+ */
+struct GNUNET_DNSPARSER_SoaRecord *
+GNUNET_DNSPARSER_parse_soa (const char *udp_payload,
+                           size_t udp_payload_length,
+                           size_t *off);
+
+
+/**
+ * Parse a DNS CERT record.
+ *
+ * @param udp_payload reference to UDP packet
+ * @param udp_payload_length length of @a udp_payload
+ * @param off pointer to the offset of the query to parse in the CERT record (to be
+ *                    incremented by the size of the record), unchanged on error
+ * @return the parsed CERT record, NULL on error
+ */
+struct GNUNET_DNSPARSER_CertRecord *
+GNUNET_DNSPARSER_parse_cert (const char *udp_payload,
+                             size_t udp_payload_length,
+                             size_t *off);
+
+
+/**
+ * Parse a DNS MX record.
+ *
+ * @param udp_payload reference to UDP packet
+ * @param udp_payload_length length of @a udp_payload
+ * @param off pointer to the offset of the query to parse in the MX record (to be
+ *                    incremented by the size of the record), unchanged on error
+ * @return the parsed MX record, NULL on error
+ */
+struct GNUNET_DNSPARSER_MxRecord *
+GNUNET_DNSPARSER_parse_mx (const char *udp_payload,
+                          size_t udp_payload_length,
+                          size_t *off);
+
+
+/**
+ * Parse a DNS SRV record.
+ *
+ * @param udp_payload reference to UDP packet
+ * @param udp_payload_length length of @a udp_payload
+ * @param off pointer to the offset of the query to parse in the SRV record (to be
+ *                    incremented by the size of the record), unchanged on error
+ * @return the parsed SRV record, NULL on error
+ */
+struct GNUNET_DNSPARSER_SrvRecord *
+GNUNET_DNSPARSER_parse_srv (const char *udp_payload,
+                           size_t udp_payload_length,
+                           size_t *off);
+
+/* ***************** low-level deallocation API ******************** */
+
+/**
+ * Free the given DNS record.
+ *
+ * @param r record to free
+ */
+void
+GNUNET_DNSPARSER_free_record (struct GNUNET_DNSPARSER_Record *r);
+
+
+/**
+ * Free MX information record.
+ *
+ * @param mx record to free
+ */
+void
+GNUNET_DNSPARSER_free_mx (struct GNUNET_DNSPARSER_MxRecord *mx);
+
+
+/**
+ * Free SRV information record.
+ *
+ * @param srv record to free
+ */
+void
+GNUNET_DNSPARSER_free_srv (struct GNUNET_DNSPARSER_SrvRecord *srv);
+
+
+/**
+ * Free SOA information record.
+ *
+ * @param soa record to free
+ */
+void
+GNUNET_DNSPARSER_free_soa (struct GNUNET_DNSPARSER_SoaRecord *soa);
+
+
+/**
+ * Free CERT information record.
+ *
+ * @param cert record to free
+ */
+void
+GNUNET_DNSPARSER_free_cert (struct GNUNET_DNSPARSER_CertRecord *cert);
+
+
+/**
+ * Convert a block of binary data to HEX.
+ *
+ * @param data binary data to convert
+ * @param data_size number of bytes in @a data
+ * @return HEX string (lower case)
+ */
+char *
+GNUNET_DNSPARSER_bin_to_hex (const void *data,
+                             size_t data_size);
+
+
+/**
+ * Convert a HEX string to block of binary data.
+ *
+ * @param hex HEX string to convert (may contain mixed case)
+ * @param data where to write result, must be
+ *             at least `strlen(hex)/2` bytes long
+ * @return number of bytes written to data
+ */
+size_t
+GNUNET_DNSPARSER_hex_to_bin (const char *hex,
+                             void *data);
+
 
 #endif
 
 #endif
+
+/** @} */  /* end of group */