summaryrefslogtreecommitdiff
path: root/src/libknot/packet/packet.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libknot/packet/packet.h')
-rw-r--r--src/libknot/packet/packet.h96
1 files changed, 50 insertions, 46 deletions
diff --git a/src/libknot/packet/packet.h b/src/libknot/packet/packet.h
index ba85aed..0921fba 100644
--- a/src/libknot/packet/packet.h
+++ b/src/libknot/packet/packet.h
@@ -37,24 +37,6 @@
#include "zone/zone.h"
/*----------------------------------------------------------------------------*/
-/*!
- * \brief Structure for holding information needed for compressing domain names.
- *
- * It's a simple table of domain names and their offsets in wire format of the
- * packet.
- *
- * \todo Consider using some better lookup structure, such as skip-list.
- */
-struct knot_compressed_dnames {
- const knot_dname_t **dnames; /*!< Domain names present in packet. */
- size_t *offsets; /*!< Offsets of domain names in the packet. */
- int *to_free; /*< Indices of dnames to free. */
- short count; /*!< Count of items in the previous arrays. */
- short max; /*!< Capacity of the structure (allocated). */
- short default_count;
-};
-
-typedef struct knot_compressed_dnames knot_compressed_dnames_t;
struct knot_wildcard_nodes {
const knot_node_t **nodes; /*!< Wildcard nodes from CNAME processing. */
@@ -101,6 +83,18 @@ enum knot_packet_prealloc_type {
typedef enum knot_packet_prealloc_type knot_packet_prealloc_type_t;
+/* Maximum number of compressed names. */
+#define COMPR_MAXLEN 64
+/* Volatile portion of the compression table. */
+#define COMPR_VOLATILE (COMPR_MAXLEN / 4)
+#define COMPR_FIXEDLEN (COMPR_MAXLEN - COMPR_VOLATILE)
+
+/* Compression table pointer. */
+typedef struct {
+ uint16_t off; /*!< Packet data offset. */
+ uint8_t lbcount; /*!< Dname label count. */
+} knot_compr_ptr_t;
+
/*----------------------------------------------------------------------------*/
/*!
* \brief Structure representing a DNS packet.
@@ -120,8 +114,6 @@ struct knot_packet {
*/
knot_question_t question;
- uint8_t *owner_tmp; /*!< Allocated space for RRSet owner wire format.*/
-
const knot_rrset_t **answer; /*!< Answer RRSets. */
const knot_rrset_t **authority; /*!< Authority RRSets. */
const knot_rrset_t **additional; /*!< Additional RRSets. */
@@ -148,7 +140,7 @@ struct knot_packet {
size_t max_size; /*!< Maximum allowed size of the packet. */
/*! \brief Information needed for compressing domain names in packet. */
- knot_compressed_dnames_t compression;
+ knot_compr_ptr_t compression[COMPR_MAXLEN];
/*! \brief Wildcard nodes to be processed for NSEC/NSEC3. */
knot_wildcard_nodes_t wildcard_nodes;
@@ -161,11 +153,12 @@ struct knot_packet {
struct knot_packet *query; /*!< Associated query. */
knot_packet_prealloc_type_t prealloc_type;
-
+
size_t tsig_size; /*!< Space to reserve for the TSIG RR. */
knot_rrset_t *tsig_rr; /*!< TSIG RR stored in the packet. */
uint16_t flags; /*!< Packet flags. */
const knot_zone_t *zone; /*!< Associated zone. */
+ mm_ctx_t mm; /*!< Memory allocation context. */
};
typedef struct knot_packet knot_packet_t;
@@ -235,25 +228,6 @@ enum {
PREALLOC_QNAME = PREALLOC_QNAME_DNAME
+ PREALLOC_QNAME_NAME
+ PREALLOC_QNAME_LABELS,
- /*!
- * \brief Space for RR owner wire format.
- *
- * Temporary buffer, used when putting RRSets to the response.
- */
- PREALLOC_RR_OWNER = 256,
-
- /*! \brief Space for one part of the compression table (domain names).*/
- PREALLOC_DOMAINS =
- DEFAULT_DOMAINS_IN_RESPONSE * sizeof(knot_dname_t *),
- /*! \brief Space for other part of the compression table (offsets). */
- PREALLOC_OFFSETS =
- DEFAULT_DOMAINS_IN_RESPONSE * sizeof(size_t),
-
- PREALLOC_TO_FREE =
- DEFAULT_DOMAINS_IN_RESPONSE * sizeof(int),
-
- PREALLOC_COMPRESSION = PREALLOC_DOMAINS + PREALLOC_OFFSETS
- + PREALLOC_TO_FREE,
PREALLOC_WC_NODES =
DEFAULT_WILDCARD_NODES * sizeof(knot_node_t *),
@@ -271,15 +245,21 @@ enum {
/*! \brief Total preallocated size for the response. */
PREALLOC_RESPONSE = PREALLOC_PACKET
+ PREALLOC_QNAME
- + PREALLOC_RR_OWNER
+ PREALLOC_RRSETS(DEFAULT_ANCOUNT)
+ PREALLOC_RRSETS(DEFAULT_NSCOUNT)
+ PREALLOC_RRSETS(DEFAULT_ARCOUNT)
- + PREALLOC_COMPRESSION
+ PREALLOC_WC
+ PREALLOC_RRSETS(DEFAULT_TMP_RRSETS)
};
+/*! \brief Flags which control packet parsing. */
+typedef enum {
+ // Don't add duplicate rdata to rrset.
+ KNOT_PACKET_DUPL_NO_MERGE = 1,
+ // Skip RR if RRSet is not empty
+ KNOT_PACKET_DUPL_SKIP = 2
+} knot_packet_flag_t;
+
/*----------------------------------------------------------------------------*/
/*!
* \brief Creates new empty packet structure.
@@ -291,6 +271,13 @@ enum {
knot_packet_t *knot_packet_new(knot_packet_prealloc_type_t prealloc);
/*!
+ * \brief Memory managed version of new packet create.
+ *
+ * See knot_packet_new() for info about parameters and output.
+ */
+knot_packet_t *knot_packet_new_mm(knot_packet_prealloc_type_t prealloc, mm_ctx_t *mm);
+
+/*!
* \brief Parses the DNS packet from wire format.
*
* \param packet Packet structure to parse into.
@@ -299,14 +286,15 @@ knot_packet_t *knot_packet_new(knot_packet_prealloc_type_t prealloc);
* \param question_only Set to <> 0 if you do not want to parse the whole
* packet. In such case the parsing will end after the
* Question section. Set to 0 to parse the whole packet.
+ * \param flags Can control packet processing.
*
* \retval KNOT_EOK
*/
int knot_packet_parse_from_wire(knot_packet_t *packet,
const uint8_t *wireformat, size_t size,
- int question_only);
+ int question_only, knot_packet_flag_t flags);
-int knot_packet_parse_rest(knot_packet_t *packet);
+int knot_packet_parse_rest(knot_packet_t *packet, knot_packet_flag_t flags);
int knot_packet_parse_next_rr_answer(knot_packet_t *packet,
knot_rrset_t **rr);
@@ -316,6 +304,8 @@ int knot_packet_parse_next_rr_additional(knot_packet_t *packet,
size_t knot_packet_size(const knot_packet_t *packet);
+size_t knot_packet_max_size(const knot_packet_t *packet);
+
/*! \brief Returns size of the wireformat of Header and Question sections. */
size_t knot_packet_question_size(const knot_packet_t *packet);
@@ -361,6 +351,15 @@ void knot_packet_set_random_id(knot_packet_t *packet);
uint8_t knot_packet_opcode(const knot_packet_t *packet);
/*!
+ * \brief Return question section from the packet.
+ *
+ * \param packet Packet instance.
+ *
+ * \return pointer to question section.
+ */
+knot_question_t *knot_packet_question(knot_packet_t *packet);
+
+/*!
* \brief Returns the QNAME from the packet.
*
* \param packet Packet (with parsed query) to get the QNAME from.
@@ -384,7 +383,7 @@ uint16_t knot_packet_qtype(const knot_packet_t *packet);
* \param packet Packet containing question.
* \param qtype New QTYPE for question.
*/
-void knot_packet_set_qtype(knot_packet_t *packet, knot_rr_type_t qtype);
+void knot_packet_set_qtype(knot_packet_t *packet, uint16_t qtype);
/*!
@@ -573,6 +572,11 @@ void knot_packet_free(knot_packet_t **packet);
*/
void knot_packet_dump(const knot_packet_t *packet);
+/*!
+ * \brief Free all rrsets associated with packet.
+ */
+int knot_packet_free_rrsets(knot_packet_t *packet);
+
#endif /* _KNOT_PACKET_H_ */
/*! @} */