- Remove ECS option after REFUSED answer

- Fix small memory leak in edns_opt_copy_alloc



git-svn-id: file:///svn/unbound/trunk@4100 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Ralph Dolmans 2017-04-10 09:12:04 +00:00
parent 4e0787dcf3
commit a5c7c469ee
9 changed files with 103 additions and 8 deletions

View file

@ -1,8 +1,12 @@
7 april 2017: George
10 April 2017: Ralph
- Remove ECS option after REFUSED answer
- Fix small memory leak in edns_opt_copy_alloc
7 April 2017: George
- Fix pythonmod for cb changes.
- Some whitespace fixup.
7 april 2017: Ralph
7 April 2017: Ralph
- Unlock view in respip unit test
6 April 2017: Ralph

View file

@ -227,6 +227,8 @@ subnetmod_init(struct module_env *env, int id)
env, id);
inplace_cb_register((void*)ecs_edns_back_parsed,
inplace_cb_edns_back_parsed, NULL, env, id);
inplace_cb_register((void*)ecs_query_response,
inplace_cb_query_response, NULL, env, id);
lock_rw_init(&sn_env->biglock);
return 1;
}
@ -588,6 +590,26 @@ subnet_option_from_ss(struct sockaddr_storage *ss, struct ecs_data* ecs,
#endif /* INET6 */
}
int
ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
int id, void* ATTR_UNUSED(cbargs))
{
struct subnet_qstate *sq;
if(!response || !(sq=(struct subnet_qstate*)qstate->minfo[id]))
return 1;
if(sq->subnet_sent &&
FLAGS_GET_RCODE(response->rep->flags) == LDNS_RCODE_REFUSED) {
/* REFUSED reponse to ECS query, remove ECS option. */
edns_opt_list_remove(&qstate->edns_opts_back_out,
qstate->env->cfg->client_subnet_opcode);
sq->subnet_sent = 0;
memset(&sq->ecs_server_out, 0, sizeof(sq->ecs_server_out));
}
return 1;
}
int
ecs_edns_back_parsed(struct module_qstate* qstate, int id,
void* ATTR_UNUSED(cbargs))

View file

@ -123,4 +123,8 @@ int ecs_whitelist_check(struct query_info* qinfo, uint16_t flags,
* store. Called just after parsing EDNS data from server. */
int ecs_edns_back_parsed(struct module_qstate* qstate, int id, void* cbargs);
/** Remove ECS record from back_out when query resulted in REFUSED response. */
int ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
int id, void* cbargs);
#endif /* SUBNETMOD_H */

View file

@ -2194,6 +2194,10 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
int dnsseclame = 0;
enum response_type type;
iq->num_current_queries--;
if(!inplace_cb_query_response_call(qstate->env, qstate, iq->response))
log_err("unable to call query_response callback");
if(iq->response == NULL) {
/* Don't increment qname when QNAME minimisation is enabled */
if(qstate->env->cfg->qname_minimisation)

View file

@ -1074,6 +1074,19 @@ int inplace_cb_edns_back_parsed_call(struct module_env* env,
return 1;
}
int inplace_cb_query_response_call(struct module_env* env,
struct module_qstate* qstate, struct dns_msg* response) {
struct inplace_cb* cb =
env->inplace_cb_lists[inplace_cb_query_response];
for(; cb; cb=cb->next) {
fptr_ok(fptr_whitelist_inplace_cb_query_response(
(inplace_cb_query_response_func_type*)cb->cb));
(void)(*(inplace_cb_query_response_func_type*)cb->cb)(qstate,
response, cb->id, cb->cb_arg);
}
return 1;
}
struct edns_option* edns_opt_copy_region(struct edns_option* list,
struct regional* region)
{
@ -1164,6 +1177,7 @@ struct edns_option* edns_opt_copy_alloc(struct edns_option* list)
if(s->opt_data) {
s->opt_data = memdup(s->opt_data, s->opt_len);
if(!s->opt_data) {
free(s);
edns_opt_list_free(result);
return NULL;
}

View file

@ -50,14 +50,13 @@ struct iovec;
struct regional;
struct edns_data;
struct edns_option;
struct inplace_cb_reply;
struct inplace_cb_query;
struct inplace_cb_edns_back_parsed;
struct inplace_cb;
struct module_qstate;
struct module_env;
struct msg_parse;
struct rrset_parse;
struct local_rrset;
struct dns_msg;
/** calculate the prefetch TTL as 90% of original. Calculation
* without numerical overflow (uin32_t) */
@ -625,8 +624,8 @@ int inplace_cb_query_call(struct module_env* env, struct query_info* qinfo,
/**
* Call the registered functions in the inplace_cb_edns_back_parsed linked list.
* This function is going to get called after receiving a reply from a
* nameserver.
* This function is going to get called after parsing the EDNS data on the
* reply from a nameserver.
* @param env: module environment.
* @param qstate: module qstate.
* @return false on failure (a callback function returned an error).
@ -634,6 +633,18 @@ int inplace_cb_query_call(struct module_env* env, struct query_info* qinfo,
int inplace_cb_edns_back_parsed_call(struct module_env* env,
struct module_qstate* qstate);
/**
* Call the registered functions in the inplace_cb_query_reponse linked list.
* This function is going to get called after receiving a reply from a
* nameserver.
* @param env: module environment.
* @param qstate: module qstate.
* @param response: received response
* @return false on failure (a callback function returned an error).
*/
int inplace_cb_query_response_call(struct module_env* env,
struct module_qstate* qstate, struct dns_msg* response);
/**
* Copy edns option list allocated to the new region
*/

View file

@ -518,3 +518,15 @@ int fptr_whitelist_inplace_cb_edns_back_parsed(
#endif
return 0;
}
int fptr_whitelist_inplace_cb_query_response(
inplace_cb_query_response_func_type* fptr)
{
#ifdef CLIENT_SUBNET
if(fptr == &ecs_query_response)
return 1;
#else
(void)fptr;
#endif
return 0;
}

View file

@ -359,6 +359,14 @@ int fptr_whitelist_inplace_cb_query(inplace_cb_query_func_type* fptr);
int fptr_whitelist_inplace_cb_edns_back_parsed(
inplace_cb_edns_back_parsed_func_type* fptr);
/**
* Check function pointer whitelist for inplace_cb_query_response func values.
* @param fptr: function pointer to check.
* @return false if not in whitelist.
*/
int fptr_whitelist_inplace_cb_query_response(
inplace_cb_query_response_func_type* fptr);
/** Due to module breakage by fptr wlist, these test app declarations
* are presented here */
/**

View file

@ -198,6 +198,9 @@ enum inplace_cb_list_type {
/* Inplace callbacks for when a query is ready to be sent to the back.*/
inplace_cb_query,
/* Inplace callback for when a reply is received from the back. */
inplace_cb_query_response,
/* Inplace callback for when EDNS is parsed on a reply received from the
* back. */
inplace_cb_edns_back_parsed,
/* Total number of types. Used for array initialization.
* Should always be last. */
@ -272,15 +275,28 @@ typedef int inplace_cb_query_func_type(struct query_info* qinfo, uint16_t flags,
int id, void* callback);
/**
* Inplace callback function called after receiving reply from back.
* Inplace callback function called after parsing edns on query reply.
* Called as func(qstate, cb_args)
* Where:
* qstate: the query state
* id: module id
* cb_args: argument passed when registering callback.
*/
typedef int inplace_cb_edns_back_parsed_func_type(struct module_qstate* qstate,
int id, void* cb_args);
/**
* Inplace callback function called after parsing query response.
* Called as func(qstate, id, cb_args)
* Where:
* qstate: the query state
* response: query response
* id: module id
* cb_args: argument passed when registering callback.
*/
typedef int inplace_cb_query_response_func_type(struct module_qstate* qstate,
struct dns_msg* response, int id, void* cb_args);
/**
* Module environment.
* Services and data provided to the module.