diff options
author | Florian Obser <florian@cvs.openbsd.org> | 2019-12-08 09:47:52 +0000 |
---|---|---|
committer | Florian Obser <florian@cvs.openbsd.org> | 2019-12-08 09:47:52 +0000 |
commit | e84799efe580f9f409f377e101ac82ed512ef534 (patch) | |
tree | 25c72d12edda152aea2d5771420b8ef2bda9b4c9 | |
parent | d579e03d713f44b063f926623346dcb8461ddf53 (diff) |
Turn opportunistic DoT into their own strategies.
This is beneficial since we prefer strategies according to their
performance.
Previously name servers were upgraded to opportunistic DoT if it was
available even if the round trip times went through the roof and there
was no way to got back to plain udp/53 DNS.
To make up a bit of space in the unwindctl status output, name servers
learned via DHCP or SLAAC are printed in a new subcommand.
The status output will be further improved shortly.
Input & OK otto
-rw-r--r-- | sbin/unwind/control.c | 3 | ||||
-rw-r--r-- | sbin/unwind/parse.y | 18 | ||||
-rw-r--r-- | sbin/unwind/resolver.c | 200 | ||||
-rw-r--r-- | sbin/unwind/resolver.h | 3 | ||||
-rw-r--r-- | sbin/unwind/unwind.c | 4 | ||||
-rw-r--r-- | sbin/unwind/unwind.conf.5 | 15 | ||||
-rw-r--r-- | sbin/unwind/unwind.h | 9 | ||||
-rw-r--r-- | usr.sbin/unwindctl/parser.c | 11 | ||||
-rw-r--r-- | usr.sbin/unwindctl/parser.h | 5 | ||||
-rw-r--r-- | usr.sbin/unwindctl/unwindctl.8 | 9 | ||||
-rw-r--r-- | usr.sbin/unwindctl/unwindctl.c | 73 |
11 files changed, 196 insertions, 154 deletions
diff --git a/sbin/unwind/control.c b/sbin/unwind/control.c index e676c1c7a3f..13a6f340a84 100644 --- a/sbin/unwind/control.c +++ b/sbin/unwind/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.13 2019/12/03 14:35:04 otto Exp $ */ +/* $OpenBSD: control.c,v 1.14 2019/12/08 09:47:50 florian Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -273,6 +273,7 @@ control_dispatch_imsg(int fd, short event, void *bula) log_setverbose(verbose); break; case IMSG_CTL_STATUS: + case IMSG_CTL_AUTOCONF: if (IMSG_DATA_SIZE(imsg) != 0) break; frontend_imsg_compose_resolver(imsg.hdr.type, 0, NULL, diff --git a/sbin/unwind/parse.y b/sbin/unwind/parse.y index ee4026d7ba9..01b87dd17ad 100644 --- a/sbin/unwind/parse.y +++ b/sbin/unwind/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.21 2019/12/01 14:37:34 otto Exp $ */ +/* $OpenBSD: parse.y,v 1.22 2019/12/08 09:47:50 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser <florian@openbsd.org> @@ -100,7 +100,7 @@ typedef struct { %} %token INCLUDE ERROR -%token FORWARDER DOT PORT +%token FORWARDER DOT PORT ODOT_FORWARDER ODOT_DHCP %token AUTHENTICATION NAME PREFERENCE RECURSOR DHCP STUB %token BLOCK LIST LOG FORCE ACCEPT BOGUS @@ -214,11 +214,13 @@ prefoptsl : prefopt { } ; -prefopt : DOT { $$ = UW_RES_DOT; } - | FORWARDER { $$ = UW_RES_FORWARDER; } - | RECURSOR { $$ = UW_RES_RECURSOR; } - | DHCP { $$ = UW_RES_DHCP; } - | STUB { $$ = UW_RES_ASR; } +prefopt : DOT { $$ = UW_RES_DOT; } + | FORWARDER { $$ = UW_RES_FORWARDER; } + | ODOT_FORWARDER { $$ = UW_RES_ODOT_FORWARDER; } + | RECURSOR { $$ = UW_RES_RECURSOR; } + | DHCP { $$ = UW_RES_DHCP; } + | ODOT_DHCP { $$ = UW_RES_ODOT_DHCP; } + | STUB { $$ = UW_RES_ASR; } ; uw_forwarder : FORWARDER forwarder_block @@ -418,6 +420,8 @@ lookup(char *s) {"list", LIST}, {"log", LOG}, {"name", NAME}, + {"oDoT-dhcp", ODOT_DHCP}, + {"oDoT-forwarder", ODOT_FORWARDER}, {"port", PORT}, {"preference", PREFERENCE}, {"recursor", RECURSOR}, diff --git a/sbin/unwind/resolver.c b/sbin/unwind/resolver.c index 814c97052fd..d36176fe470 100644 --- a/sbin/unwind/resolver.c +++ b/sbin/unwind/resolver.c @@ -1,4 +1,4 @@ -/* $OpenBSD: resolver.c,v 1.102 2019/12/06 19:39:14 florian Exp $ */ +/* $OpenBSD: resolver.c,v 1.103 2019/12/08 09:47:50 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser <florian@openbsd.org> @@ -104,7 +104,6 @@ struct uw_resolver { int stop; enum uw_resolver_state state; enum uw_resolver_type type; - int oppdot; int check_running; int64_t median; int64_t histogram[nitems(histogram_limits)]; @@ -150,11 +149,10 @@ void ub_resolve_done(void *, int, void *, int, int, char *, int); void asr_resolve_done(struct asr_result *, void *); void new_recursor(void); -void new_forwarders(int); -void new_asr_forwarders(void); -void new_static_forwarders(int); +void new_forwarders(void); +void new_static_forwarders(void); void new_static_dot_forwarders(void); -struct uw_resolver *create_resolver(enum uw_resolver_type, int); +struct uw_resolver *create_resolver(enum uw_resolver_type); void set_unified_cache(struct uw_resolver *); void free_resolver(struct uw_resolver *); void set_forwarders(struct uw_resolver *, @@ -174,6 +172,7 @@ void resolver_unref(struct uw_resolver *); int resolver_cmp(const void *, const void *); void restart_resolvers(void); void show_status(pid_t); +void show_autoconf(pid_t); void send_resolver_info(struct uw_resolver *, pid_t); void send_detailed_resolver_info(struct uw_resolver *, pid_t); @@ -521,6 +520,12 @@ resolver_dispatch_frontend(int fd, short event, void *bula) __func__, IMSG_DATA_SIZE(imsg)); show_status(imsg.hdr.pid); break; + case IMSG_CTL_AUTOCONF: + if (IMSG_DATA_SIZE(imsg) != 0) + fatalx("%s: IMSG_CTL_AUTOCONF wrong length: " + "%lu", __func__, IMSG_DATA_SIZE(imsg)); + show_autoconf(imsg.hdr.pid); + break; case IMSG_NEW_TA: /* make sure this is a string */ ((char *)imsg.data)[IMSG_DATA_SIZE(imsg) - 1] = '\0'; @@ -533,9 +538,8 @@ resolver_dispatch_frontend(int fd, short event, void *bula) case IMSG_NEW_TAS_DONE: if (merge_tas(&new_trust_anchors, &trust_anchors)) { new_recursor(); - new_forwarders(0); - new_asr_forwarders(); - new_static_forwarders(0); + new_forwarders(); + new_static_forwarders(); new_static_dot_forwarders(); } break; @@ -660,7 +664,7 @@ resolver_dispatch_main(int fd, short event, void *bula) merge_config(resolver_conf, nconf); nconf = NULL; if (forwarders_changed) - new_static_forwarders(0); + new_static_forwarders(); if (dot_forwarders_changed) new_static_dot_forwarders(); break; @@ -851,7 +855,9 @@ resolve(struct uw_resolver *res, const char* name, int rrtype, int rrclass, break; case UW_RES_RECURSOR: case UW_RES_DHCP: + case UW_RES_ODOT_DHCP: case UW_RES_FORWARDER: + case UW_RES_ODOT_FORWARDER: case UW_RES_DOT: if ((err = ub_resolve_event(res->ctx, name, rrtype, rrclass, cb_data, ub_resolve_done, NULL)) != 0) { @@ -1058,60 +1064,65 @@ new_recursor(void) if (TAILQ_EMPTY(&trust_anchors)) return; - resolvers[UW_RES_RECURSOR] = create_resolver(UW_RES_RECURSOR, 0); + resolvers[UW_RES_RECURSOR] = create_resolver(UW_RES_RECURSOR); set_unified_cache(resolvers[UW_RES_RECURSOR]); check_resolver(resolvers[UW_RES_RECURSOR]); } void -new_forwarders(int oppdot) +new_forwarders(void) { free_resolver(resolvers[UW_RES_DHCP]); resolvers[UW_RES_DHCP] = NULL; + free_resolver(resolvers[UW_RES_ODOT_DHCP]); + resolvers[UW_RES_ODOT_DHCP] = NULL; + + free_resolver(resolvers[UW_RES_ASR]); + resolvers[UW_RES_ASR] = NULL; + if (TAILQ_EMPTY(&autoconf_forwarder_list)) return; + resolvers[UW_RES_ASR] = create_resolver(UW_RES_ASR); + check_resolver(resolvers[UW_RES_ASR]); + if (TAILQ_EMPTY(&trust_anchors)) return; - resolvers[UW_RES_DHCP] = create_resolver(UW_RES_DHCP, oppdot); + resolvers[UW_RES_DHCP] = create_resolver(UW_RES_DHCP); set_unified_cache(resolvers[UW_RES_DHCP]); - check_resolver(resolvers[UW_RES_DHCP]); -} - -void -new_asr_forwarders(void) -{ - free_resolver(resolvers[UW_RES_ASR]); - resolvers[UW_RES_ASR] = NULL; - - if (TAILQ_EMPTY(&autoconf_forwarder_list)) - return; - resolvers[UW_RES_ASR] = create_resolver(UW_RES_ASR, 0); - - check_resolver(resolvers[UW_RES_ASR]); + resolvers[UW_RES_ODOT_DHCP] = create_resolver(UW_RES_ODOT_DHCP); + set_unified_cache(resolvers[UW_RES_ODOT_DHCP]); + check_resolver(resolvers[UW_RES_ODOT_DHCP]); } void -new_static_forwarders(int oppdot) +new_static_forwarders(void) { free_resolver(resolvers[UW_RES_FORWARDER]); resolvers[UW_RES_FORWARDER] = NULL; + free_resolver(resolvers[UW_RES_ODOT_FORWARDER]); + resolvers[UW_RES_ODOT_FORWARDER] = NULL; + if (TAILQ_EMPTY(&resolver_conf->uw_forwarder_list)) return; if (TAILQ_EMPTY(&trust_anchors)) return; - resolvers[UW_RES_FORWARDER] = create_resolver(UW_RES_FORWARDER, oppdot); + resolvers[UW_RES_FORWARDER] = create_resolver(UW_RES_FORWARDER); set_unified_cache(resolvers[UW_RES_FORWARDER]); - check_resolver(resolvers[UW_RES_FORWARDER]); + + resolvers[UW_RES_ODOT_FORWARDER] = + create_resolver(UW_RES_ODOT_FORWARDER); + set_unified_cache(resolvers[UW_RES_ODOT_FORWARDER]); + check_resolver(resolvers[UW_RES_ODOT_FORWARDER]); } void @@ -1126,7 +1137,7 @@ new_static_dot_forwarders(void) if (TAILQ_EMPTY(&trust_anchors)) return; - resolvers[UW_RES_DOT] = create_resolver(UW_RES_DOT, 0); + resolvers[UW_RES_DOT] = create_resolver(UW_RES_DOT); set_unified_cache(resolvers[UW_RES_DOT]); check_resolver(resolvers[UW_RES_DOT]); @@ -1153,7 +1164,7 @@ static const struct { }; struct uw_resolver * -create_resolver(enum uw_resolver_type type, int oppdot) +create_resolver(enum uw_resolver_type type) { struct uw_resolver *res; struct trust_anchor *ta; @@ -1201,7 +1212,9 @@ create_resolver(enum uw_resolver_type type, int oppdot) break; case UW_RES_RECURSOR: case UW_RES_DHCP: + case UW_RES_ODOT_DHCP: case UW_RES_FORWARDER: + case UW_RES_ODOT_FORWARDER: case UW_RES_DOT: if ((res->ctx = ub_ctx_create_event(ev_base)) == NULL) { free(res); @@ -1259,26 +1272,22 @@ create_resolver(enum uw_resolver_type type, int oppdot) case UW_RES_RECURSOR: break; case UW_RES_DHCP: - res->oppdot = oppdot; - if (oppdot) { - set_forwarders(res, &autoconf_forwarder_list, 853); - ub_ctx_set_option(res->ctx, "tls-cert-bundle:", - TLS_DEFAULT_CA_CERT_FILE); - ub_ctx_set_tls(res->ctx, 1); - } else - set_forwarders(res, &autoconf_forwarder_list, 0); + set_forwarders(res, &autoconf_forwarder_list, 0); + break; + case UW_RES_ODOT_DHCP: + set_forwarders(res, &autoconf_forwarder_list, 853); + ub_ctx_set_option(res->ctx, "tls-cert-bundle:", + TLS_DEFAULT_CA_CERT_FILE); + ub_ctx_set_tls(res->ctx, 1); break; case UW_RES_FORWARDER: - res->oppdot = oppdot; - if (oppdot) { - set_forwarders(res, &resolver_conf->uw_forwarder_list, - 853); - ub_ctx_set_option(res->ctx, "tls-cert-bundle:", - TLS_DEFAULT_CA_CERT_FILE); - ub_ctx_set_tls(res->ctx, 1); - } else - set_forwarders(res, &resolver_conf->uw_forwarder_list, - 0); + set_forwarders(res, &resolver_conf->uw_forwarder_list, 0); + break; + case UW_RES_ODOT_FORWARDER: + set_forwarders(res, &resolver_conf->uw_forwarder_list, 853); + ub_ctx_set_option(res->ctx, "tls-cert-bundle:", + TLS_DEFAULT_CA_CERT_FILE); + ub_ctx_set_tls(res->ctx, 1); break; case UW_RES_DOT: set_forwarders(res, &resolver_conf->uw_dot_forwarder_list, 0); @@ -1294,7 +1303,9 @@ create_resolver(enum uw_resolver_type type, int oppdot) /* for the forwarder cases allow AS112 zones */ switch(res->type) { case UW_RES_DHCP: + case UW_RES_ODOT_DHCP: case UW_RES_FORWARDER: + case UW_RES_ODOT_FORWARDER: case UW_RES_DOT: for (i = 0; i < nitems(as112_zones); i++) { if((err = ub_ctx_set_option(res->ctx, "local-zone:", @@ -1386,40 +1397,23 @@ check_resolver(struct uw_resolver *resolver_to_check) if (resolver_to_check->check_running) return; - if ((res = create_resolver(resolver_to_check->type, 0)) == NULL) + if ((res = create_resolver(resolver_to_check->type)) == NULL) return; resolver_ref(resolver_to_check); + resolver_to_check->check_running++; if (resolve(res, ".", LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN, resolver_to_check, check_resolver_done) != 0) { + resolver_to_check->check_running--; 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); - } else - resolver_to_check->check_running++; - - if (!(resolver_to_check->type == UW_RES_DHCP || - resolver_to_check->type == UW_RES_FORWARDER)) - return; - - if ((res = create_resolver(resolver_to_check->type, 1)) == NULL) - return; - - resolver_ref(resolver_to_check); + } - if (resolve(res, ".", LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN, - resolver_to_check, check_resolver_done) != 0) { - /* do not overwrite normal DNS state, it might work */ - 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); - } else - resolver_to_check->check_running++; } void @@ -1443,41 +1437,11 @@ check_resolver_done(struct uw_resolver *res, void *arg, int rcode, } if (rcode == LDNS_RCODE_SERVFAIL) { - log_debug("%s: %s%s rcode: SERVFAIL", __func__, - uw_resolver_type_str[checked_resolver->type], res->oppdot ? - " (OppDot)" : ""); - - if (res->oppdot == checked_resolver->oppdot) { - checked_resolver->state = DEAD; - if (checked_resolver->oppdot) { - /* downgrade from opportunistic DoT */ - switch (checked_resolver->type) { - case UW_RES_DHCP: - new_forwarders(0); - break; - case UW_RES_FORWARDER: - new_static_forwarders(0); - break; - default: - break; - } - } - } - goto out; - } + log_debug("%s: %s rcode: SERVFAIL", __func__, + uw_resolver_type_str[checked_resolver->type]); - if (res->oppdot && !checked_resolver->oppdot) { - /* upgrade to opportunistic DoT */ - switch (checked_resolver->type) { - case UW_RES_DHCP: - new_forwarders(1); - break; - case UW_RES_FORWARDER: - new_static_forwarders(1); - break; - default: - break; - } + checked_resolver->state = DEAD; + goto out; } if (sec == SECURE) { @@ -1498,9 +1462,9 @@ check_resolver_done(struct uw_resolver *res, void *arg, int rcode, } else checked_resolver->state = DEAD; /* we know the root exists */ - log_debug("%s: %s%s: %s", __func__, - uw_resolver_type_str[checked_resolver->type], res->oppdot ? - " (OppDot)" : "", uw_resolver_state_str[checked_resolver->state]); + log_debug("%s: %s: %s", __func__, + uw_resolver_type_str[checked_resolver->type], + uw_resolver_state_str[checked_resolver->state]); if (log_getverbose() & OPT_VERBOSE2 && (str = sldns_wire2str_pkt(answer_packet, answer_len)) != NULL) { @@ -1679,17 +1643,14 @@ void restart_resolvers(void) { new_recursor(); - new_static_forwarders(0); + new_static_forwarders(); new_static_dot_forwarders(); - new_forwarders(0); - new_asr_forwarders(); + new_forwarders(); } void show_status(pid_t pid) { - struct uw_forwarder *uw_forwarder; - struct ctl_forwarder_info cfi; struct resolver_preference res_pref; int i; @@ -1699,6 +1660,15 @@ show_status(pid_t pid) for (i = 0; i < resolver_conf->res_pref.len; i++) send_resolver_info(resolvers[res_pref.types[i]], pid); + resolver_imsg_compose_frontend(IMSG_CTL_END, pid, NULL, 0); +} + +void +show_autoconf(pid_t pid) +{ + struct uw_forwarder *uw_forwarder; + struct ctl_forwarder_info cfi; + TAILQ_FOREACH(uw_forwarder, &autoconf_forwarder_list, entry) { memset(&cfi, 0, sizeof(cfi)); cfi.if_index = uw_forwarder->if_index; @@ -1724,7 +1694,6 @@ send_resolver_info(struct uw_resolver *res, pid_t pid) cri.state = res->state; cri.type = res->type; - cri.oppdot = res->oppdot; cri.median = res->median; memcpy(cri.histogram, res->histogram, sizeof(cri.histogram)); @@ -1932,8 +1901,7 @@ replace_autoconf_forwarders(struct imsg_rdns_proposal *rdns_proposal) if (changed) { replace_forwarders(&new_forwarder_list, &autoconf_forwarder_list); - new_forwarders(0); - new_asr_forwarders(); + new_forwarders(); } else { while ((tmp = TAILQ_FIRST(&new_forwarder_list)) != NULL) { TAILQ_REMOVE(&new_forwarder_list, tmp, entry); diff --git a/sbin/unwind/resolver.h b/sbin/unwind/resolver.h index 9478ae9395c..899b493d86c 100644 --- a/sbin/unwind/resolver.h +++ b/sbin/unwind/resolver.h @@ -1,4 +1,4 @@ -/* $OpenBSD: resolver.h,v 1.15 2019/12/02 06:26:52 otto Exp $ */ +/* $OpenBSD: resolver.h,v 1.16 2019/12/08 09:47:50 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser <florian@openbsd.org> @@ -50,7 +50,6 @@ struct ctl_resolver_info { enum uw_resolver_state state; enum uw_resolver_type type; int64_t median; - int oppdot; int64_t histogram[nitems(histogram_limits)]; int64_t latest_histogram[nitems(histogram_limits)]; }; diff --git a/sbin/unwind/unwind.c b/sbin/unwind/unwind.c index c7eb83198ed..f37bb8b6ae4 100644 --- a/sbin/unwind/unwind.c +++ b/sbin/unwind/unwind.c @@ -1,4 +1,4 @@ -/* $OpenBSD: unwind.c,v 1.44 2019/12/03 16:16:25 florian Exp $ */ +/* $OpenBSD: unwind.c,v 1.45 2019/12/08 09:47:50 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser <florian@openbsd.org> @@ -686,8 +686,10 @@ config_new_empty(void) { static enum uw_resolver_type default_res_pref[] = { UW_RES_DOT, + UW_RES_ODOT_FORWARDER, UW_RES_FORWARDER, UW_RES_RECURSOR, + UW_RES_ODOT_DHCP, UW_RES_DHCP, UW_RES_ASR}; struct uw_conf *xconf; diff --git a/sbin/unwind/unwind.conf.5 b/sbin/unwind/unwind.conf.5 index bfd97b08424..d0cfc20ab0b 100644 --- a/sbin/unwind/unwind.conf.5 +++ b/sbin/unwind/unwind.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: unwind.conf.5,v 1.22 2019/12/05 15:07:37 otto Exp $ +.\" $OpenBSD: unwind.conf.5,v 1.23 2019/12/08 09:47:50 florian Exp $ .\" .\" Copyright (c) 2018 Florian Obser <florian@openbsd.org> .\" Copyright (c) 2005 Esben Norby <norby@openbsd.org> @@ -18,7 +18,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: December 5 2019 $ +.Dd $Mdocdate: December 8 2019 $ .Dt UNWIND.CONF 5 .Os .Sh NAME @@ -100,13 +100,22 @@ See Will never validate. Useful when running behind broken middle boxes that do not like edns0. .It Ic dhcp -Name servers learned via DHCP. +Name servers learned via DHCP or SLAAC. +.It Ic oDoT-dhcp +Name servers learned via DHCP or SLAAC. +.Nm unwind +tries to opportunistically use DNS over TLS. .It Ic DoT DNS over TLS name servers configured in .Nm . .It Ic forwarder Name servers configured in .Nm . +.It Ic oDoT-forwarder +Name servers configured in +.Nm . +.Nm unwind +tries to opportunistically use DNS over TLS. .It Ic recursor .Nm unwind itself recursively resolves names. diff --git a/sbin/unwind/unwind.h b/sbin/unwind/unwind.h index d19a321e94f..e9f9353cb99 100644 --- a/sbin/unwind/unwind.h +++ b/sbin/unwind/unwind.h @@ -1,4 +1,4 @@ -/* $OpenBSD: unwind.h,v 1.44 2019/12/04 19:07:14 florian Exp $ */ +/* $OpenBSD: unwind.h,v 1.45 2019/12/08 09:47:50 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser <florian@openbsd.org> @@ -59,8 +59,10 @@ static const char * const log_procnames[] = { enum uw_resolver_type { UW_RES_RECURSOR, UW_RES_DHCP, + UW_RES_ODOT_DHCP, UW_RES_ASR, UW_RES_FORWARDER, + UW_RES_ODOT_FORWARDER, UW_RES_DOT, UW_RES_NONE }; @@ -68,16 +70,20 @@ enum uw_resolver_type { static const char * const uw_resolver_type_str[] = { "recursor", "dhcp", + "oDoT-dhcp", "stub", "forwarder", + "oDoT-forwarder", "DoT" }; static const char * const uw_resolver_type_short[] = { "rec", "dhcp", + "dhcp", "stub", "forw", + "forw", "DoT" }; @@ -93,6 +99,7 @@ enum imsg_type { IMSG_CTL_LOG_VERBOSE, IMSG_CTL_RELOAD, IMSG_CTL_STATUS, + IMSG_CTL_AUTOCONF, IMSG_RECONF_CONF, IMSG_RECONF_BLOCKLIST_FILE, IMSG_RECONF_FORWARDER, diff --git a/usr.sbin/unwindctl/parser.c b/usr.sbin/unwindctl/parser.c index 95734a957e8..c091a4efecb 100644 --- a/usr.sbin/unwindctl/parser.c +++ b/usr.sbin/unwindctl/parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.c,v 1.9 2019/12/03 14:35:05 otto Exp $ */ +/* $OpenBSD: parser.c,v 1.10 2019/12/08 09:47:51 florian Exp $ */ /* * Copyright (c) 2004 Esben Norby <norby@openbsd.org> @@ -50,10 +50,11 @@ struct token { static const struct token t_main[]; static const struct token t_log[]; +static const struct token t_status[]; static const struct token t_main[] = { {KEYWORD, "reload", RELOAD, NULL}, - {KEYWORD, "status", STATUS, NULL}, + {KEYWORD, "status", STATUS, t_status}, {KEYWORD, "log", NONE, t_log}, {ENDTOKEN, "", NONE, NULL} }; @@ -65,6 +66,12 @@ static const struct token t_log[] = { {ENDTOKEN, "", NONE, NULL} }; +static const struct token t_status[] = { + {NOTOKEN, "", NONE, NULL}, + {KEYWORD, "autoconf", AUTOCONF, NULL}, + {ENDTOKEN, "", NONE, NULL} +}; + static const struct token *match_token(const char *, const struct token *, struct parse_result *); static void show_valid_args(const struct token *); diff --git a/usr.sbin/unwindctl/parser.h b/usr.sbin/unwindctl/parser.h index 3f96b6fe22f..7baba5a231a 100644 --- a/usr.sbin/unwindctl/parser.h +++ b/usr.sbin/unwindctl/parser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.h,v 1.7 2019/12/03 14:35:05 otto Exp $ */ +/* $OpenBSD: parser.h,v 1.8 2019/12/08 09:47:51 florian Exp $ */ /* * Copyright (c) 2004 Esben Norby <norby@openbsd.org> @@ -24,7 +24,8 @@ enum actions { LOG_BRIEF, RELOAD, PORTAL, - STATUS + STATUS, + AUTOCONF }; struct parse_result { diff --git a/usr.sbin/unwindctl/unwindctl.8 b/usr.sbin/unwindctl/unwindctl.8 index 0d2c844bef1..c27e407536c 100644 --- a/usr.sbin/unwindctl/unwindctl.8 +++ b/usr.sbin/unwindctl/unwindctl.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: unwindctl.8,v 1.8 2019/12/03 14:35:05 otto Exp $ +.\" $OpenBSD: unwindctl.8,v 1.9 2019/12/08 09:47:51 florian Exp $ .\" .\" Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: December 3 2019 $ +.Dd $Mdocdate: December 8 2019 $ .Dt UNWINDCTL 8 .Os .Sh NAME @@ -55,6 +55,11 @@ Enable very noisy debug logging. Reload the configuration file. .It Cm status Show a status summary. +.It Cm status Cm autoconf +Show nameservers learned from +.Xr dhclient 8 +or +.Xr slaacd 8 . .El .Sh FILES .Bl -tag -width "/dev/unwind.sockXX" -compact diff --git a/usr.sbin/unwindctl/unwindctl.c b/usr.sbin/unwindctl/unwindctl.c index e6ba86b647e..afe2d7ed1eb 100644 --- a/usr.sbin/unwindctl/unwindctl.c +++ b/usr.sbin/unwindctl/unwindctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: unwindctl.c,v 1.23 2019/12/06 12:59:48 otto Exp $ */ +/* $OpenBSD: unwindctl.c,v 1.24 2019/12/08 09:47:51 florian Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> @@ -45,6 +45,7 @@ __dead void usage(void); int show_status_msg(struct imsg *); +int show_autoconf_msg(struct imsg *); void histogram_header(void); void print_histogram(const char *name, int64_t[], size_t); @@ -72,7 +73,7 @@ main(int argc, char *argv[]) int done = 0; int i, n, verbose = 0; int ch; - char *sockname; + char *sockname, *oDoT; sockname = UNWIND_SOCKET; while ((ch = getopt(argc, argv, "s:")) != -1) { @@ -145,6 +146,9 @@ main(int argc, char *argv[]) case STATUS: imsg_compose(ibuf, IMSG_CTL_STATUS, 0, 0, -1, NULL, 0); break; + case AUTOCONF: + imsg_compose(ibuf, IMSG_CTL_AUTOCONF, 0, 0, -1, NULL, 0); + break; default: usage(); } @@ -169,6 +173,9 @@ main(int argc, char *argv[]) case STATUS: done = show_status_msg(&imsg); break; + case AUTOCONF: + done = show_autoconf_msg(&imsg); + break; default: break; } @@ -181,9 +188,20 @@ main(int argc, char *argv[]) if (histogram_cnt) histogram_header(); for (i = 0; i < histogram_cnt; i++) { + switch(info[i].type) { + case UW_RES_ODOT_FORWARDER: + case UW_RES_ODOT_DHCP: + if (info[i].state == DEAD) + continue; + oDoT = "(oT)"; + break; + default: + oDoT = ""; + break; + } print_histogram(uw_resolver_type_short[info[i].type], info[i].histogram, nitems(info[i].histogram)); - print_histogram("", info[i].latest_histogram, + print_histogram(oDoT, info[i].latest_histogram, nitems(info[i].latest_histogram)); } return (0); @@ -192,37 +210,58 @@ main(int argc, char *argv[]) int show_status_msg(struct imsg *imsg) { - static int header, autoconf_forwarders, last_src; - static int label_len, line_len; - static uint32_t last_if_index; static char fwd_line[80]; struct ctl_resolver_info *cri; - struct ctl_forwarder_info *cfi; - char ifnamebuf[IFNAMSIZ]; - char *if_name; - - if (!header++) - printf("preference:\n"); switch (imsg->hdr.type) { case IMSG_CTL_RESOLVER_INFO: cri = imsg->data; - printf("%-10s %s%s, median RTT: ", + memcpy(&info[histogram_cnt++], cri, sizeof(info[0])); + switch(cri->type) { + case UW_RES_ODOT_FORWARDER: + case UW_RES_ODOT_DHCP: + if (cri->state == DEAD) + return (0); + default: + break; + } + printf("%-15s %s, median RTT: ", uw_resolver_type_str[cri->type], - uw_resolver_state_str[cri->state], - cri->oppdot ? " (opportunistic DoT)" : ""); + uw_resolver_state_str[cri->state]); if (cri->median == 0) printf("N/A\n"); else if (cri->median == INT64_MAX) printf("Inf\n"); else printf("%lldms\n", cri->median); - memcpy(&info[histogram_cnt++], cri, sizeof(info[0])); break; + case IMSG_CTL_END: + if (fwd_line[0] != '\0') + printf("%s\n", fwd_line); + return (1); + default: + break; + } + + return (0); +} + +int +show_autoconf_msg(struct imsg *imsg) +{ + static int autoconf_forwarders, last_src; + static int label_len, line_len; + static uint32_t last_if_index; + static char fwd_line[80]; + struct ctl_forwarder_info *cfi; + char ifnamebuf[IFNAMSIZ]; + char *if_name; + + switch (imsg->hdr.type) { case IMSG_CTL_AUTOCONF_RESOLVER_INFO: cfi = imsg->data; if (!autoconf_forwarders++) - printf("\nlearned forwarders:\n"); + printf("autoconfiguration forwarders:\n"); if (cfi->if_index != last_if_index || cfi->src != last_src) { if_name = if_indextoname(cfi->if_index, ifnamebuf); if (fwd_line[0] != '\0') { |