mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
fix segmentation fault
This commit is contained in:
parent
5f4c9b0dfe
commit
19c2ece763
1 changed files with 73 additions and 50 deletions
123
ipset/ipset.c
123
ipset/ipset.c
|
|
@ -33,6 +33,23 @@ static int error_response(struct module_qstate* qstate, int id, int rcode) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct mnl_socket * open_mnl_socket() {
|
||||
struct mnl_socket *mnl;
|
||||
|
||||
mnl = mnl_socket_open(NETLINK_NETFILTER);
|
||||
if (!mnl) {
|
||||
log_err("ipset: could not open netfilter.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mnl_socket_bind(mnl, 0, MNL_SOCKET_AUTOPID) < 0) {
|
||||
mnl_socket_close(mnl);
|
||||
log_err("ipset: could not bind netfilter.");
|
||||
return NULL;
|
||||
}
|
||||
return mnl;
|
||||
}
|
||||
|
||||
static int add_to_ipset(struct mnl_socket *mnl, const char *setname, const void *ipaddr, int af) {
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfg;
|
||||
|
|
@ -98,8 +115,14 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg, stru
|
|||
uint8_t *rr_data;
|
||||
|
||||
mnl = (struct mnl_socket *)ie->mnl;
|
||||
if (mnl == NULL) {
|
||||
return -1;
|
||||
if (!mnl) {
|
||||
// retry to create mnl socket
|
||||
mnl = open_mnl_socket();
|
||||
if (!mnl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ie->mnl = mnl;
|
||||
}
|
||||
|
||||
for (i = 0; i < return_msg->rep->rrset_count; ++i) {
|
||||
|
|
@ -119,7 +142,7 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg, stru
|
|||
}
|
||||
}
|
||||
|
||||
if (setname != NULL) {
|
||||
if (setname) {
|
||||
dlen = sldns_wire2str_dname_buf(rrset->rk.dname, rrset->rk.dname_len, dname, BUFF_LEN);
|
||||
if (dlen == 0) {
|
||||
log_err("bad domain name");
|
||||
|
|
@ -146,6 +169,9 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg, stru
|
|||
ret = add_to_ipset(mnl, setname, rr_data + 2, af);
|
||||
if (ret < 0) {
|
||||
log_err("ipset: could not add %s into %s", dname, setname);
|
||||
|
||||
mnl_socket_close(mnl);
|
||||
ie->mnl = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -154,58 +180,48 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg, stru
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipset_init(struct module_env* env, int id) {
|
||||
struct mnl_socket *mnl;
|
||||
struct ipset_env *ipset_env;
|
||||
|
||||
struct ipset_env *ipset_env = (struct ipset_env *)calloc(1,
|
||||
sizeof(struct ipset_env));
|
||||
if(!ipset_env) {
|
||||
ipset_env = (struct ipset_env *)calloc(1, sizeof(struct ipset_env));
|
||||
if (!ipset_env) {
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
env->modinfo[id] = (void*)ipset_env;
|
||||
|
||||
env->modinfo[id] = (void *)ipset_env;
|
||||
|
||||
ipset_env->mnl == NULL;
|
||||
|
||||
ipset_env->name_v4 = env->cfg->ipset_name_v4;
|
||||
ipset_env->name_v6 = env->cfg->ipset_name_v6;
|
||||
|
||||
ipset_env->v4_enabled = (ipset_env->name_v4 == NULL) || (strlen(ipset_env->name_v4) == 0) ? 0 : 1;
|
||||
ipset_env->v6_enabled = (ipset_env->name_v6 == NULL) || (strlen(ipset_env->name_v6) == 0) ? 0 : 1;
|
||||
ipset_env->v4_enabled = !ipset_env->name_v4 || (strlen(ipset_env->name_v4) == 0) ? 0 : 1;
|
||||
ipset_env->v6_enabled = !ipset_env->name_v6 || (strlen(ipset_env->name_v6) == 0) ? 0 : 1;
|
||||
|
||||
if ((ipset_env->v4_enabled < 1) && (ipset_env->v6_enabled < 1)) {
|
||||
log_err("ipset: set name no configuration?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mnl = mnl_socket_open(NETLINK_NETFILTER);
|
||||
if (mnl <= 0) {
|
||||
log_err("ipset: could not open netfilter.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mnl_socket_bind(mnl, 0, MNL_SOCKET_AUTOPID) < 0) {
|
||||
mnl_socket_close(mnl);
|
||||
log_err("ipset: could not bind netfilter.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ipset_env->mnl = mnl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ipset_deinit(struct module_env *env, int id) {
|
||||
struct mnl_socket *mnl;
|
||||
struct ipset_env *ipset_env;
|
||||
|
||||
struct ipset_env* ipset_env;
|
||||
if(!env || !env->modinfo[id])
|
||||
if (!env || !env->modinfo[id]) {
|
||||
return;
|
||||
ipset_env = (struct ipset_env*)env->modinfo[id];
|
||||
}
|
||||
|
||||
ipset_env = (struct ipset_env *)env->modinfo[id];
|
||||
|
||||
mnl = (struct mnl_socket *)ipset_env->mnl;
|
||||
if (mnl) {
|
||||
|
|
@ -218,11 +234,13 @@ void ipset_deinit(struct module_env *env, int id) {
|
|||
}
|
||||
|
||||
static int ipset_new(struct module_qstate* qstate, int id) {
|
||||
struct ipset_qstate* iq = (struct ipset_qstate*)regional_alloc(
|
||||
struct ipset_qstate *iq = (struct ipset_qstate *)regional_alloc(
|
||||
qstate->region, sizeof(struct ipset_qstate));
|
||||
qstate->minfo[id] = iq;
|
||||
if(!iq)
|
||||
if (!iq) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(iq, 0, sizeof(*iq));
|
||||
/* initialise it */
|
||||
/* TODO */
|
||||
|
|
@ -236,42 +254,47 @@ void ipset_operate(struct module_qstate *qstate, enum module_ev event, int id,
|
|||
struct ipset_qstate *iq = (struct ipset_qstate *)qstate->minfo[id];
|
||||
verbose(VERB_QUERY, "ipset[module %d] operate: extstate:%s event:%s",
|
||||
id, strextstate(qstate->ext_state[id]), strmodulevent(event));
|
||||
if(iq) log_query_info(VERB_QUERY, "ipset operate: query",
|
||||
&qstate->qinfo);
|
||||
if (iq) {
|
||||
log_query_info(VERB_QUERY, "ipset operate: query", &qstate->qinfo);
|
||||
}
|
||||
|
||||
/* perform ipset state machine */
|
||||
if((event == module_event_new || event == module_event_pass) &&
|
||||
iq == NULL) {
|
||||
if(!ipset_new(qstate, id)) {
|
||||
if ((event == module_event_new || event == module_event_pass) && !iq) {
|
||||
if (!ipset_new(qstate, id)) {
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return;
|
||||
}
|
||||
iq = (struct ipset_qstate*)qstate->minfo[id];
|
||||
}
|
||||
|
||||
if(iq && (event == module_event_pass || event == module_event_new)) {
|
||||
if (iq && (event == module_event_pass || event == module_event_new)) {
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
return;
|
||||
}
|
||||
|
||||
if(iq && (event == module_event_moddone)) {
|
||||
ipset_update(qstate->env, qstate->return_msg, ie);
|
||||
if (iq && (event == module_event_moddone)) {
|
||||
if (qstate->return_msg && qstate->return_msg->rep) {
|
||||
ipset_update(qstate->env, qstate->return_msg, ie);
|
||||
}
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
}
|
||||
if(iq && outbound) {
|
||||
|
||||
if (iq && outbound) {
|
||||
/* ipset does not need to process responses at this time
|
||||
* ignore it.
|
||||
ipset_process_response(qstate, iq, ie, id, outbound, event);
|
||||
*/
|
||||
return;
|
||||
}
|
||||
if(event == module_event_error) {
|
||||
|
||||
if (event == module_event_error) {
|
||||
verbose(VERB_ALGO, "got called with event error, giving up");
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return;
|
||||
}
|
||||
if(!iq && (event == module_event_moddone)) {
|
||||
|
||||
if (!iq && (event == module_event_moddone)) {
|
||||
/* during priming, module done but we never started */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
|
|
@ -281,25 +304,26 @@ void ipset_operate(struct module_qstate *qstate, enum module_ev event, int id,
|
|||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
void ipset_inform_super(struct module_qstate* ATTR_UNUSED(qstate),
|
||||
int ATTR_UNUSED(id), struct module_qstate* ATTR_UNUSED(super)) {
|
||||
void ipset_inform_super(struct module_qstate *ATTR_UNUSED(qstate),
|
||||
int ATTR_UNUSED(id), struct module_qstate *ATTR_UNUSED(super)) {
|
||||
/* ipset does not use subordinate requests at this time */
|
||||
verbose(VERB_ALGO, "ipset inform_super was called");
|
||||
}
|
||||
|
||||
void ipset_clear(struct module_qstate* qstate, int id) {
|
||||
struct cachedb_qstate* iq;
|
||||
if(!qstate)
|
||||
void ipset_clear(struct module_qstate *qstate, int id) {
|
||||
struct cachedb_qstate *iq;
|
||||
if (!qstate) {
|
||||
return;
|
||||
iq = (struct cachedb_qstate*)qstate->minfo[id];
|
||||
if(iq) {
|
||||
}
|
||||
iq = (struct cachedb_qstate *)qstate->minfo[id];
|
||||
if (iq) {
|
||||
/* free contents of iq */
|
||||
/* TODO */
|
||||
}
|
||||
qstate->minfo[id] = NULL;
|
||||
}
|
||||
|
||||
size_t ipset_get_mem(struct module_env* env, int id) {
|
||||
size_t ipset_get_mem(struct module_env *env, int id) {
|
||||
struct ipset_env *ie = (struct ipset_env *)env->modinfo[id];
|
||||
if (!ie) {
|
||||
return 0;
|
||||
|
|
@ -320,4 +344,3 @@ struct module_func_block * ipset_get_funcblock(void) {
|
|||
return &ipset_block;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue