diff options
Diffstat (limited to 'src/libknot/packet/packet.h')
-rw-r--r-- | src/libknot/packet/packet.h | 96 |
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_ */ /*! @} */ |