diff options
Diffstat (limited to 'src/libknot/packet/response.c')
-rw-r--r-- | src/libknot/packet/response.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/libknot/packet/response.c b/src/libknot/packet/response.c index d113cdf..9f6277c 100644 --- a/src/libknot/packet/response.c +++ b/src/libknot/packet/response.c @@ -814,6 +814,53 @@ static int knot_response_realloc_rrsets(const knot_rrset_t ***rrsets, } /*----------------------------------------------------------------------------*/ +/*! + * \brief Reallocate space for Wildcard nodes. + * + * \retval KNOT_EOK + * \retval KNOT_ENOMEM + */ +static int knot_response_realloc_wc_nodes(const knot_node_t ***nodes, + const knot_dname_t ***snames, + short *max_count, + short default_max_count, short step) +{ + dbg_packet("Max count: %d, default max count: %d\n", + *max_count, default_max_count); + int free_old = (*max_count) != default_max_count; + + const knot_node_t **old_nodes = *nodes; + const knot_dname_t **old_snames = *snames; + + short new_max_count = *max_count + step; + + const knot_node_t **new_nodes = (const knot_node_t **)malloc( + new_max_count * sizeof(knot_node_t *)); + CHECK_ALLOC_LOG(new_nodes, KNOT_ENOMEM); + + const knot_dname_t **new_snames = (const knot_dname_t **)malloc( + new_max_count * sizeof(knot_dname_t *)); + if (new_snames == NULL) { + free(new_nodes); + return KNOT_ENOMEM; + } + + memcpy(new_nodes, *nodes, (*max_count) * sizeof(knot_node_t *)); + memcpy(new_snames, *snames, (*max_count) * sizeof(knot_dname_t *)); + + *nodes = new_nodes; + *snames = new_snames; + *max_count = new_max_count; + + if (free_old) { + free(old_nodes); + free(old_snames); + } + + return KNOT_EOK; +} + +/*----------------------------------------------------------------------------*/ /* API functions */ /*----------------------------------------------------------------------------*/ @@ -915,9 +962,20 @@ void knot_response_clear(knot_packet_t *resp, int clear_question) resp->an_rrsets = 0; resp->ns_rrsets = 0; resp->ar_rrsets = 0; + resp->compression.count = 0; + + /*! \todo Temporary RRSets are not deallocated, which may potentially + * lead to memory leaks should this function be used in other + * cases than with XFR-out. + */ knot_packet_free_tmp_rrsets(resp); resp->tmp_rrsets_count = 0; + + /*! \todo If this function is used in other cases than with XFR-out, + * the list of wildcard nodes should be cleared here. + */ + resp->header.ancount = 0; resp->header.nscount = 0; resp->header.arcount = 0; @@ -1201,3 +1259,33 @@ int knot_response_add_nsid(knot_packet_t *response, const uint8_t *data, return knot_edns_add_option(&response->opt_rr, EDNS_OPTION_NSID, length, data); } + +/*----------------------------------------------------------------------------*/ + +int knot_response_add_wildcard_node(knot_packet_t *response, + const knot_node_t *node, + const knot_dname_t *sname) +{ + if (response == NULL || node == NULL || sname == NULL) { + return KNOT_EBADARG; + } + + if (response->wildcard_nodes.count == response->wildcard_nodes.max + && knot_response_realloc_wc_nodes(&response->wildcard_nodes.nodes, + &response->wildcard_nodes.snames, + &response->wildcard_nodes.max, + DEFAULT_WILDCARD_NODES, + STEP_WILDCARD_NODES) != KNOT_EOK) { + return KNOT_ENOMEM; + } + + response->wildcard_nodes.nodes[response->wildcard_nodes.count] = node; + response->wildcard_nodes.snames[response->wildcard_nodes.count] = sname; + ++response->wildcard_nodes.count; + + dbg_response("Current wildcard nodes count: %d, max count: %d\n", + response->wildcard_nodes.count, + response->wildcard_nodes.max); + + return KNOT_EOK; +} |