diff options
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/unwind/frontend.c | 3 | ||||
-rw-r--r-- | sbin/unwind/frontend.h | 3 | ||||
-rw-r--r-- | sbin/unwind/resolver.c | 161 | ||||
-rw-r--r-- | sbin/unwind/unwind.h | 3 |
4 files changed, 125 insertions, 45 deletions
diff --git a/sbin/unwind/frontend.c b/sbin/unwind/frontend.c index 5e125a21fa6..edc019d0567 100644 --- a/sbin/unwind/frontend.c +++ b/sbin/unwind/frontend.c @@ -1,4 +1,4 @@ -/* $OpenBSD: frontend.c,v 1.35 2019/11/19 14:46:33 florian Exp $ */ +/* $OpenBSD: frontend.c,v 1.36 2019/11/19 14:47:46 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser <florian@openbsd.org> @@ -1040,6 +1040,7 @@ handle_route_message(struct rt_msghdr *rtm, struct sockaddr **rti_info) return; } rdns_proposal.if_index = rtm->rtm_index; + rdns_proposal.src = rtm->rtm_priority; memcpy(&rdns_proposal.rtdns, rtdns, sizeof(rdns_proposal.rtdns)); if (rtm->rtm_flags & RTF_UP) frontend_imsg_compose_resolver(IMSG_ADD_DNS, 0, diff --git a/sbin/unwind/frontend.h b/sbin/unwind/frontend.h index 3f639d71a8b..10ee9952bf9 100644 --- a/sbin/unwind/frontend.h +++ b/sbin/unwind/frontend.h @@ -1,4 +1,4 @@ -/* $OpenBSD: frontend.h,v 1.4 2019/11/11 05:51:06 florian Exp $ */ +/* $OpenBSD: frontend.h,v 1.5 2019/11/19 14:47:46 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser <florian@openbsd.org> @@ -28,6 +28,7 @@ TAILQ_HEAD(trust_anchor_head, trust_anchor); struct imsg_rdns_proposal { uint32_t if_index; + int src; struct sockaddr_rtdns rtdns; }; diff --git a/sbin/unwind/resolver.c b/sbin/unwind/resolver.c index b7b050c2599..ead3861fbd5 100644 --- a/sbin/unwind/resolver.c +++ b/sbin/unwind/resolver.c @@ -1,4 +1,4 @@ -/* $OpenBSD: resolver.c,v 1.67 2019/11/19 14:46:33 florian Exp $ */ +/* $OpenBSD: resolver.c,v 1.68 2019/11/19 14:47:46 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser <florian@openbsd.org> @@ -159,6 +159,7 @@ 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 *); +int replace_dhcp_forwarders(struct imsg_rdns_proposal *); struct uw_forwarder *find_forwarder(struct uw_forwarder_head *, const char *); @@ -1890,56 +1891,68 @@ add_autoconf_forwarders(struct imsg_rdns_proposal *rdns_proposal) char ntopbuf[INET6_ADDRSTRLEN], *src; const char *ns; - af = rdns_proposal->rtdns.sr_family; - src = rdns_proposal->rtdns.sr_dns; - - switch (af) { - case AF_INET: - rdns_count = (rdns_proposal->rtdns.sr_len - - offsetof(struct sockaddr_rtdns, sr_dns)) / - sizeof(struct in_addr); - break; - case AF_INET6: - rdns_count = (rdns_proposal->rtdns.sr_len - - offsetof(struct sockaddr_rtdns, sr_dns)) / - sizeof(struct in6_addr); - break; - default: - log_warnx("%s: unsupported address family: %d", __func__, af); - return; - } + if (rdns_proposal->src == RTP_PROPOSAL_DHCLIENT) + /* dhclient does not do remove / add */ + changed = replace_dhcp_forwarders(rdns_proposal); + else { + af = rdns_proposal->rtdns.sr_family; + src = rdns_proposal->rtdns.sr_dns; - for (i = 0; i < rdns_count; i++) { switch (af) { case AF_INET: - if (((struct in_addr *)src)->s_addr == INADDR_ANY) - continue; - ns = inet_ntop(af, (struct in_addr *)src, ntopbuf, - INET6_ADDRSTRLEN); - src += sizeof(struct in_addr); + rdns_count = (rdns_proposal->rtdns.sr_len - + offsetof(struct sockaddr_rtdns, sr_dns)) / + sizeof(struct in_addr); break; case AF_INET6: - if (IN6_IS_ADDR_LOOPBACK((struct in6_addr *)src)) - continue; - ns = inet_ntop(af, (struct in6_addr *)src, ntopbuf, - INET6_ADDRSTRLEN); - src += sizeof(struct in6_addr); + rdns_count = (rdns_proposal->rtdns.sr_len - + offsetof(struct sockaddr_rtdns, sr_dns)) / + sizeof(struct in6_addr); + break; + default: + log_warnx("%s: unsupported address family: %d", + __func__, af); + return; } - log_debug("%s: %s", __func__, ns); - if (find_forwarder(&autoconf_forwarder_list, ns) == NULL) { - if ((uw_forwarder = calloc(1, sizeof(struct - uw_forwarder))) == NULL) - fatal(NULL); - if (strlcpy(uw_forwarder->name, ns, - sizeof(uw_forwarder->name)) >= - sizeof(uw_forwarder->name)) - fatalx("strlcpy"); - TAILQ_INSERT_TAIL(&autoconf_forwarder_list, - uw_forwarder, entry); - changed = 1; + for (i = 0; i < rdns_count; i++) { + switch (af) { + case AF_INET: + if (((struct in_addr *)src)->s_addr == + INADDR_LOOPBACK) + continue; + ns = inet_ntop(af, (struct in_addr *)src, + ntopbuf, + INET6_ADDRSTRLEN); + src += sizeof(struct in_addr); + break; + case AF_INET6: + if (IN6_IS_ADDR_LOOPBACK((struct in6_addr + *)src)) + continue; + ns = inet_ntop(af, (struct in6_addr *)src, + ntopbuf, INET6_ADDRSTRLEN); + src += sizeof(struct in6_addr); + } + + log_debug("%s: %s", __func__, ns); + if (find_forwarder(&autoconf_forwarder_list, ns) == + NULL) { + if ((uw_forwarder = calloc(1, sizeof(struct + uw_forwarder))) == NULL) + fatal(NULL); + if (strlcpy(uw_forwarder->name, ns, + sizeof(uw_forwarder->name)) >= + sizeof(uw_forwarder->name)) + fatalx("strlcpy"); + uw_forwarder->src = rdns_proposal->src; + TAILQ_INSERT_TAIL(&autoconf_forwarder_list, + uw_forwarder, entry); + changed = 1; + } } } + if (changed) { new_forwarders(0); new_asr_forwarders(); @@ -2010,6 +2023,70 @@ rem_autoconf_forwarders(struct imsg_rdns_proposal *rdns_proposal) log_debug("%s: forwarders didn't change", __func__); } +int +replace_dhcp_forwarders(struct imsg_rdns_proposal *rdns_proposal) +{ + struct uw_forwarder_head new_forwarder_list; + struct uw_forwarder *uw_forwarder, *tmp; + int i, rdns_count, changed = 0; + char ntopbuf[INET6_ADDRSTRLEN], *src; + const char *ns; + + if (rdns_proposal->rtdns.sr_family != AF_INET) + return changed; + + TAILQ_INIT(&new_forwarder_list); + rdns_count = (rdns_proposal->rtdns.sr_len - offsetof(struct + sockaddr_rtdns, sr_dns)) / sizeof(struct in_addr); + src = rdns_proposal->rtdns.sr_dns; + + for (i = 0; i < rdns_count; i++) { + if (((struct in_addr *)src)->s_addr == INADDR_ANY) + continue; + ns = inet_ntop(AF_INET, (struct in_addr *)src, ntopbuf, + INET6_ADDRSTRLEN); + log_debug("%s: %s", __func__, ns); + src += sizeof(struct in_addr); + if ((uw_forwarder = calloc(1, sizeof(struct uw_forwarder))) == + NULL) + fatal(NULL); + if (strlcpy(uw_forwarder->name, ns, sizeof(uw_forwarder->name)) + >= sizeof(uw_forwarder->name)) + fatalx("strlcpy"); + uw_forwarder->src = rdns_proposal->src; + TAILQ_INSERT_TAIL(&new_forwarder_list, uw_forwarder, entry); + } + + TAILQ_FOREACH(tmp, &autoconf_forwarder_list, entry) + if (tmp->src != RTP_PROPOSAL_DHCLIENT) { + if ((uw_forwarder = calloc(1, sizeof(struct uw_forwarder))) == + NULL) + fatal(NULL); + if (strlcpy(uw_forwarder->name, tmp->name, + sizeof(uw_forwarder->name)) >= sizeof(uw_forwarder->name)) + fatalx("strlcpy"); + uw_forwarder->src = tmp->src; + TAILQ_INSERT_TAIL(&new_forwarder_list, uw_forwarder, entry); + } + + changed = check_forwarders_changed(&new_forwarder_list, + &autoconf_forwarder_list); + + log_debug("%s: changed: %d", __func__, changed); + if (changed) + replace_forwarders(&new_forwarder_list, + &autoconf_forwarder_list); + else { + while ((tmp = TAILQ_FIRST(&new_forwarder_list)) != NULL) { + TAILQ_REMOVE(&new_forwarder_list, tmp, entry); + free(tmp); + } + } + + return changed; + +} + struct uw_forwarder * find_forwarder(struct uw_forwarder_head *list, const char *name) { struct uw_forwarder *uw_forwarder; diff --git a/sbin/unwind/unwind.h b/sbin/unwind/unwind.h index 37a0e0fcc0e..36090986d64 100644 --- a/sbin/unwind/unwind.h +++ b/sbin/unwind/unwind.h @@ -1,4 +1,4 @@ -/* $OpenBSD: unwind.h,v 1.29 2019/11/19 14:46:33 florian Exp $ */ +/* $OpenBSD: unwind.h,v 1.30 2019/11/19 14:47:46 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser <florian@openbsd.org> @@ -125,6 +125,7 @@ enum imsg_type { struct uw_forwarder { TAILQ_ENTRY(uw_forwarder) entry; char name[1024]; /* XXX */ + int src; uint16_t port; }; |