diff options
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/unwind/resolver.c | 216 | ||||
-rw-r--r-- | sbin/unwind/unwind.h | 3 |
2 files changed, 98 insertions, 121 deletions
diff --git a/sbin/unwind/resolver.c b/sbin/unwind/resolver.c index a3cb7045a30..cc2939c44d6 100644 --- a/sbin/unwind/resolver.c +++ b/sbin/unwind/resolver.c @@ -1,4 +1,4 @@ -/* $OpenBSD: resolver.c,v 1.62 2019/11/12 20:26:36 florian Exp $ */ +/* $OpenBSD: resolver.c,v 1.63 2019/11/14 08:30:10 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser <florian@openbsd.org> @@ -92,14 +92,11 @@ struct uw_resolver { int64_t histogram[nitems(histogram_limits)]; }; -struct check_resolver_data { - struct uw_resolver *res; - struct uw_resolver *check_res; -}; - struct resolver_cb_data { - void (*cb)(void *, int, void *, int, int, char *); - void *data; + void (*cb)(struct uw_resolver *, void *, int, void *, + int, int, char *); + void *data; + struct uw_resolver *res; }; __dead void resolver_shutdown(void); @@ -108,9 +105,10 @@ void resolver_dispatch_frontend(int, short, void *); void resolver_dispatch_captiveportal(int, short, void *); void resolver_dispatch_main(int, short, void *); int resolve(struct uw_resolver *, const char*, int, int, - void*, void (*cb)(void *, int, void *, int, int, - char *)); -void resolve_done(void *, int, void *, int, int, char *); + void*, void (*cb)(struct uw_resolver *, void *, + int, void *, int, int, char *)); +void resolve_done(struct uw_resolver *, void *, int, void *, + int, int, char *); void ub_resolve_done(void *, int, void *, int, int, char *, int); void asr_resolve_done(struct asr_result *, void *); @@ -129,8 +127,8 @@ void set_forwarders_oppdot(struct uw_resolver *, void resolver_check_timo(int, short, void *); void resolver_free_timo(int, short, void *); void check_resolver(struct uw_resolver *); -void check_resolver_done(void *, int, void *, int, int, - char *); +void check_resolver_done(struct uw_resolver *, void *, int, + void *, int, int, char *); void schedule_recheck_all_resolvers(void); int check_forwarders_changed(struct uw_forwarder_head *, struct uw_forwarder_head *); @@ -154,8 +152,8 @@ int check_captive_portal_changed(struct uw_conf *, struct uw_conf *); void trust_anchor_resolve(void); void trust_anchor_timo(int, short, void *); -void trust_anchor_resolve_done(void *, int, void *, int, - int, char *); +void trust_anchor_resolve_done(struct uw_resolver *, void *, + int, void *, int, int, char *); void add_autoconf_forwarders(struct imsg_rdns_proposal *); void rem_autoconf_forwarders(struct imsg_rdns_proposal *); struct uw_forwarder *find_forwarder(struct uw_forwarder_head *, @@ -480,14 +478,10 @@ resolver_dispatch_frontend(int fd, short event, void *bula) log_debug("%s: choosing %s", __func__, uw_resolver_type_str[res->type]); - query_imsg->resolver = res; - resolver_ref(res); - clock_gettime(CLOCK_MONOTONIC, &query_imsg->tp); - if ((resolve(res, query_imsg->qname, query_imsg->t, - query_imsg->c, query_imsg, resolve_done)) != 0) - resolver_unref(res); + resolve(res, query_imsg->qname, query_imsg->t, + query_imsg->c, query_imsg, resolve_done); break; case IMSG_FORWARDER: /* make sure this is a string */ @@ -773,16 +767,20 @@ resolver_dispatch_main(int fd, short event, void *bula) int resolve(struct uw_resolver *res, const char* name, int rrtype, int rrclass, - void *mydata, void (*cb)(void *, int, void *, int, int, char *)) + void *mydata, void (*cb)(struct uw_resolver *, void *, int, void *, int, + int, char *)) { struct resolver_cb_data *cb_data = NULL; struct asr_query *aq = NULL; int err; + resolver_ref(res); + if ((cb_data = malloc(sizeof(*cb_data))) == NULL) goto err; cb_data->cb = cb; cb_data->data = mydata; + cb_data->res = res; switch(res->type) { case UW_RES_ASR: @@ -816,15 +814,15 @@ resolve(struct uw_resolver *res, const char* name, int rrtype, int rrclass, err: free(cb_data); free(aq); + resolver_unref(res); return 1; } void -resolve_done(void *arg, int rcode, void *answer_packet, int answer_len, - int sec, char *why_bogus) +resolve_done(struct uw_resolver *res, void *arg, int rcode, + void *answer_packet, int answer_len, int sec, char *why_bogus) { struct query_imsg *query_imsg; - struct uw_resolver *res; struct timespec tp, elapsed; int64_t ms; size_t i; @@ -833,7 +831,6 @@ resolve_done(void *arg, int rcode, void *answer_packet, int answer_len, clock_gettime(CLOCK_MONOTONIC, &tp); query_imsg = (struct query_imsg *)arg; - res = (struct uw_resolver *)query_imsg->resolver; timespecsub(&tp, &query_imsg->tp, &elapsed); @@ -886,7 +883,6 @@ resolve_done(void *arg, int rcode, void *answer_packet, int answer_len, answer_packet, answer_len); free(query_imsg); - resolver_unref(res); return; servfail: @@ -894,7 +890,6 @@ servfail: resolver_imsg_compose_frontend(IMSG_ANSWER_HEADER, 0, query_imsg, sizeof(*query_imsg)); free(query_imsg); - resolver_unref(res); } void @@ -1259,95 +1254,83 @@ resolver_free_timo(int fd, short events, void *arg) } void -check_resolver(struct uw_resolver *res) +check_resolver(struct uw_resolver *resolver_to_check) { - struct uw_resolver *check_res; - struct check_resolver_data *data; + struct uw_resolver *res; log_debug("%s: create_resolver", __func__); - if ((check_res = create_resolver(res->type, 0)) == NULL) - fatal("%s", __func__); - if ((data = malloc(sizeof(*data))) == NULL) + if ((res = create_resolver(resolver_to_check->type, 0)) == NULL) fatal("%s", __func__); - resolver_ref(check_res); - resolver_ref(res); - data->check_res = check_res; - data->res = res; + resolver_ref(resolver_to_check); - if (resolve(check_res, ".", LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN, - data, check_resolver_done) != 0) { - res->state = UNKNOWN; - resolver_unref(check_res); - resolver_unref(res); - res->check_tv.tv_sec = RESOLVER_CHECK_SEC; - evtimer_add(&res->check_ev, &res->check_tv); + if (resolve(res, ".", LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN, + resolver_to_check, check_resolver_done) != 0) { + resolver_to_check->state = UNKNOWN; + resolver_unref(resolver_to_check); + resolver_to_check->check_tv.tv_sec = RESOLVER_CHECK_SEC; + evtimer_add(&resolver_to_check->check_ev, + &resolver_to_check->check_tv); log_debug("%s: evtimer_add: %lld - %s: %s", __func__, - data->res->check_tv.tv_sec, - uw_resolver_type_str[data->res->type], - uw_resolver_state_str[data->res->state]); + resolver_to_check->check_tv.tv_sec, + uw_resolver_type_str[resolver_to_check->type], + uw_resolver_state_str[resolver_to_check->state]); } - if (!(res->type == UW_RES_DHCP || res->type == UW_RES_FORWARDER)) + if (!(resolver_to_check->type == UW_RES_DHCP || + resolver_to_check->type == UW_RES_FORWARDER)) return; log_debug("%s: create_resolver for oppdot", __func__); - if ((check_res = create_resolver(res->type, 1)) == NULL) - fatal("%s", __func__); - if ((data = malloc(sizeof(*data))) == NULL) + if ((res = create_resolver(resolver_to_check->type, 1)) == NULL) fatal("%s", __func__); - resolver_ref(check_res); - resolver_ref(res); - data->check_res = check_res; - data->res = res; + resolver_ref(resolver_to_check); - if (resolve(check_res, ".", LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN, - data, check_resolver_done) != 0) { + if (resolve(res, ".", LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN, + resolver_to_check, check_resolver_done) != 0) { log_debug("check oppdot failed"); /* do not overwrite normal DNS state, it might work */ - resolver_unref(check_res); - resolver_unref(res); + resolver_unref(resolver_to_check); - res->check_tv.tv_sec = RESOLVER_CHECK_SEC; - evtimer_add(&res->check_ev, &res->check_tv); + resolver_to_check->check_tv.tv_sec = RESOLVER_CHECK_SEC; + evtimer_add(&resolver_to_check->check_ev, + &resolver_to_check->check_tv); log_debug("%s: evtimer_add: %lld - %s: %s", __func__, - data->res->check_tv.tv_sec, - uw_resolver_type_str[data->res->type], - uw_resolver_state_str[data->res->state]); + resolver_to_check->check_tv.tv_sec, + uw_resolver_type_str[resolver_to_check->type], + uw_resolver_state_str[resolver_to_check->state]); } } void -check_resolver_done(void *arg, int rcode, void *answer_packet, int answer_len, - int sec, char *why_bogus) +check_resolver_done(struct uw_resolver *res, void *arg, int rcode, + void *answer_packet, int answer_len, int sec, char *why_bogus) { - struct check_resolver_data *data; - struct timeval tv = {0, 1}; - enum uw_resolver_state prev_state; - char *str; - - data = (struct check_resolver_data *)arg; + struct uw_resolver *checked_resolver = arg; + struct timeval tv = {0, 1}; + enum uw_resolver_state prev_state; + char *str; log_debug("%s: %s rcode: %d", __func__, - uw_resolver_type_str[data->res->type], rcode); + uw_resolver_type_str[checked_resolver->type], rcode); - prev_state = data->res->state; + prev_state = checked_resolver->state; if (answer_len < LDNS_HEADER_SIZE) { - data->res->state = DEAD; + checked_resolver->state = DEAD; log_warnx("bad packet: too short"); goto out; } if (rcode == LDNS_RCODE_SERVFAIL) { - if (data->check_res->oppdot == data->res->oppdot) { - data->res->state = DEAD; - if (data->res->oppdot) { + if (res->oppdot == checked_resolver->oppdot) { + checked_resolver->state = DEAD; + if (checked_resolver->oppdot) { /* downgrade from opportunistic DoT */ - switch (data->res->type) { + switch (checked_resolver->type) { case UW_RES_DHCP: new_forwarders(0); break; @@ -1362,9 +1345,9 @@ check_resolver_done(void *arg, int rcode, void *answer_packet, int answer_len, goto out; } - if (data->check_res->oppdot && !data->res->oppdot) { + if (res->oppdot && !checked_resolver->oppdot) { /* upgrade to opportunistic DoT */ - switch (data->res->type) { + switch (checked_resolver->type) { case UW_RES_DHCP: new_forwarders(1); break; @@ -1382,56 +1365,57 @@ check_resolver_done(void *arg, int rcode, void *answer_packet, int answer_len, } if (sec == SECURE) { - data->res->state = VALIDATING; + checked_resolver->state = VALIDATING; if (!(evtimer_pending(&trust_anchor_timer, NULL))) evtimer_add(&trust_anchor_timer, &tv); } else if (rcode == LDNS_RCODE_NOERROR && LDNS_RCODE_WIRE((uint8_t*)answer_packet) == LDNS_RCODE_NOERROR) { log_debug("%s: why bogus: %s", __func__, why_bogus); - data->res->state = RESOLVING; + checked_resolver->state = RESOLVING; /* best effort */ - data->res->why_bogus = strdup(why_bogus); + checked_resolver->why_bogus = strdup(why_bogus); } else - data->res->state = DEAD; /* we know the root exists */ + checked_resolver->state = DEAD; /* we know the root exists */ out: - if (!data->res->stop && data->res->state == DEAD) { + if (!checked_resolver->stop && checked_resolver->state == DEAD) { if (prev_state == DEAD) - data->res->check_tv.tv_sec *= 2; + checked_resolver->check_tv.tv_sec *= 2; else - data->res->check_tv.tv_sec = RESOLVER_CHECK_SEC; + checked_resolver->check_tv.tv_sec = RESOLVER_CHECK_SEC; - if (data->res->check_tv.tv_sec > RESOLVER_CHECK_MAXSEC) - data->res->check_tv.tv_sec = RESOLVER_CHECK_MAXSEC; + if (checked_resolver->check_tv.tv_sec > RESOLVER_CHECK_MAXSEC) + checked_resolver->check_tv.tv_sec = + RESOLVER_CHECK_MAXSEC; - evtimer_add(&data->res->check_ev, &data->res->check_tv); + evtimer_add(&checked_resolver->check_ev, + &checked_resolver->check_tv); log_debug("%s: evtimer_add: %lld - %s: %s", __func__, - data->res->check_tv.tv_sec, - uw_resolver_type_str[data->res->type], - uw_resolver_state_str[data->res->state]); + checked_resolver->check_tv.tv_sec, + uw_resolver_type_str[checked_resolver->type], + uw_resolver_state_str[checked_resolver->state]); } log_debug("%s: %s: %s", __func__, - uw_resolver_type_str[data->res->type], - uw_resolver_state_str[data->res->state]); - - log_debug("%s: %p - %p", __func__, data->res, data->res->ctx); + uw_resolver_type_str[checked_resolver->type], + uw_resolver_state_str[checked_resolver->state]); - resolver_unref(data->res); - data->check_res->stop = 1; /* do not free in callback */ - resolver_unref(data->check_res); + log_debug("%s: %p - %p", __func__, checked_resolver, + checked_resolver->ctx); - free(data); + resolver_unref(checked_resolver); + res->stop = 1; /* do not free in callback */ } void asr_resolve_done(struct asr_result *ar, void *arg) { struct resolver_cb_data *cb_data = arg; - cb_data->cb(cb_data->data, ar->ar_rcode, ar->ar_data, ar->ar_datalen, 0, - ""); + cb_data->cb(cb_data->res, cb_data->data, ar->ar_rcode, ar->ar_data, + ar->ar_datalen, 0, ""); free(ar->ar_data); + resolver_unref(cb_data->res); free(cb_data); } @@ -1440,8 +1424,9 @@ ub_resolve_done(void *arg, int rcode, void *answer_packet, int answer_len, int sec, char *why_bogus, int was_ratelimited) { struct resolver_cb_data *cb_data = arg; - cb_data->cb(cb_data->data, rcode, answer_packet, answer_len, sec, - why_bogus); + cb_data->cb(cb_data->res, cb_data->data, rcode, answer_packet, + answer_len, sec, why_bogus); + resolver_unref(cb_data->res); free(cb_data); } @@ -1784,13 +1769,10 @@ trust_anchor_resolve(void) if (res == NULL || res->state < VALIDATING) goto err; - resolver_ref(res); - - if (resolve(res, ".", LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, res, - trust_anchor_resolve_done) != 0) { - resolver_unref(res); + if (resolve(res, ".", LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, NULL, + trust_anchor_resolve_done) != 0) goto err; - } + return; err: evtimer_add(&trust_anchor_timer, &tv); @@ -1803,10 +1785,9 @@ trust_anchor_timo(int fd, short events, void *arg) } void -trust_anchor_resolve_done(void *arg, int rcode, void *answer_packet, - int answer_len, int sec, char *why_bogus) +trust_anchor_resolve_done(struct uw_resolver *res, void *arg, int rcode, + void *answer_packet, int answer_len, int sec, char *why_bogus) { - struct uw_resolver *res; struct ub_result *result; sldns_buffer *buf = NULL; struct regional *region = NULL; @@ -1815,8 +1796,6 @@ trust_anchor_resolve_done(void *arg, int rcode, void *answer_packet, uint16_t dnskey_flags; char *str, rdata_buf[1024], *ta; - res = (struct uw_resolver *)arg; - if ((result = calloc(1, sizeof(*result))) == NULL) goto out; @@ -1892,7 +1871,6 @@ out: sldns_buffer_free(buf); regional_destroy(region); ub_resolve_free(result); - resolver_unref(res); evtimer_add(&trust_anchor_timer, &tv); } diff --git a/sbin/unwind/unwind.h b/sbin/unwind/unwind.h index 9e762681ac7..7079ec3ed72 100644 --- a/sbin/unwind/unwind.h +++ b/sbin/unwind/unwind.h @@ -1,4 +1,4 @@ -/* $OpenBSD: unwind.h,v 1.26 2019/11/12 15:34:37 florian Exp $ */ +/* $OpenBSD: unwind.h,v 1.27 2019/11/14 08:30:10 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser <florian@openbsd.org> @@ -153,7 +153,6 @@ struct query_imsg { int c; int err; int bogus; - void *resolver; struct timespec tp; }; |