From: tobhe Date: Fri, 10 Feb 2023 19:51:08 +0000 (+0000) Subject: Add support for configuring multiple name servers as roadwarrior X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=6ce4deec4a3504866c6f879513b597cc7116b5d1;p=openbsd Add support for configuring multiple name servers as roadwarrior client. This allows us to have a fallback in case one connection fails. Tested by Ryan Kavanagh ok patrick@ --- diff --git a/sbin/iked/vroute.c b/sbin/iked/vroute.c index 89a7f01cc5e..7f900e771e3 100644 --- a/sbin/iked/vroute.c +++ b/sbin/iked/vroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vroute.c,v 1.17 2022/07/18 19:32:16 tobhe Exp $ */ +/* $OpenBSD: vroute.c,v 1.18 2023/02/10 19:51:08 tobhe Exp $ */ /* * Copyright (c) 2021 Tobias Heider @@ -76,12 +76,14 @@ TAILQ_HEAD(vroute_routes, vroute_route); struct vroute_dns { struct sockaddr_storage vd_addr; int vd_ifidx; + TAILQ_ENTRY(vroute_dns) vd_entry; }; +TAILQ_HEAD(vroute_dnss, vroute_dns); struct iked_vroute_sc { struct vroute_addrs ivr_addrs; struct vroute_routes ivr_routes; - struct vroute_dns *ivr_dns; + struct vroute_dnss ivr_dnss; struct event ivr_routeev; int ivr_iosock; int ivr_iosock6; @@ -103,6 +105,7 @@ vroute_rtmsg_cb(int fd, short events, void *arg) { struct iked *env = (struct iked *) arg; struct iked_vroute_sc *ivr = env->sc_vroute; + struct vroute_dns *dns; static uint8_t *buf; struct rt_msghdr *rtm; ssize_t n; @@ -133,11 +136,12 @@ vroute_rtmsg_cb(int fd, short events, void *arg) switch(rtm->rtm_type) { case RTM_PROPOSAL: - if (rtm->rtm_priority == RTP_PROPOSAL_SOLICIT && - ivr->ivr_dns) { - log_debug("%s: got solicit", __func__); - vroute_dodns(env, (struct sockaddr *)&ivr->ivr_dns->vd_addr, 1, - ivr->ivr_dns->vd_ifidx); + if (rtm->rtm_priority == RTP_PROPOSAL_SOLICIT) { + TAILQ_FOREACH(dns, &ivr->ivr_dnss, vd_entry) { + log_debug("%s: got solicit", __func__); + vroute_dodns(env, (struct sockaddr *) &dns->vd_addr, + 1, dns->vd_ifidx); + } } break; default: @@ -171,6 +175,7 @@ vroute_init(struct iked *env) fatal("%s: setsockopt(ROUTE_MSGFILTER)", __func__); TAILQ_INIT(&ivr->ivr_addrs); + TAILQ_INIT(&ivr->ivr_dnss); TAILQ_INIT(&ivr->ivr_routes); ivr->ivr_pid = getpid(); @@ -189,6 +194,7 @@ vroute_cleanup(struct iked *env) struct iked_vroute_sc *ivr = env->sc_vroute; struct vroute_addr *addr; struct vroute_route *route; + struct vroute_dns *dns; while ((addr = TAILQ_FIRST(&ivr->ivr_addrs))) { if_indextoname(addr->va_ifidx, ifname); @@ -209,10 +215,11 @@ vroute_cleanup(struct iked *env) free(route); } - if (ivr->ivr_dns) { - vroute_dodns(env, (struct sockaddr *)&ivr->ivr_dns->vd_addr, 0, - ivr->ivr_dns->vd_ifidx); - free(ivr->ivr_dns); + while ((dns = TAILQ_FIRST(&ivr->ivr_dnss))) { + vroute_dodns(env, (struct sockaddr *)&dns->vd_addr, 0, + dns->vd_ifidx); + TAILQ_REMOVE(&ivr->ivr_dnss, dns, vd_entry); + free(dns); } } @@ -334,7 +341,6 @@ vroute_setdns(struct iked *env, int add, struct sockaddr *addr, int vroute_getdns(struct iked *env, struct imsg *imsg) { - struct iked_vroute_sc *ivr = env->sc_vroute; struct sockaddr *dns; uint8_t *ptr; size_t left; @@ -361,12 +367,8 @@ vroute_getdns(struct iked *env, struct imsg *imsg) add = (imsg->hdr.type == IMSG_VDNS_ADD); if (add) { - if (ivr->ivr_dns != NULL) - return (0); vroute_insertdns(env, ifidx, dns); } else { - if (ivr->ivr_dns == NULL) - return (0); vroute_removedns(env, ifidx, dns); } @@ -432,19 +434,23 @@ vroute_insertdns(struct iked *env, int ifidx, struct sockaddr *addr) memcpy(&dns->vd_addr, addr, addr->sa_len); dns->vd_ifidx = ifidx; - ivr->ivr_dns = dns; + TAILQ_INSERT_TAIL(&ivr->ivr_dnss, dns, vd_entry); } void vroute_removedns(struct iked *env, int ifidx, struct sockaddr *addr) { struct iked_vroute_sc *ivr = env->sc_vroute; + struct vroute_dns *dns, *tdns; + + TAILQ_FOREACH_SAFE(dns, &ivr->ivr_dnss, vd_entry, tdns) { + if (ifidx != dns->vd_ifidx) + continue; + if (sockaddr_cmp(addr, (struct sockaddr *) &dns->vd_addr, -1)) + continue; - if (ifidx == ivr->ivr_dns->vd_ifidx && - sockaddr_cmp(addr, (struct sockaddr *) - &ivr->ivr_dns->vd_addr, -1) == 0) { - free(ivr->ivr_dns); - ivr->ivr_dns = NULL; + TAILQ_REMOVE(&ivr->ivr_dnss, dns, vd_entry); + free(dns); } }