-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
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;
}
#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))
* 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 */
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)
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)
{
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;
}
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) */
/**
* 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).
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
*/
#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;
+}
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 */
/**
/* 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. */
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.