From 125dc9525b34089903ccd4402a2e9bf8c6c7f801 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 11 Dec 2019 12:27:05 +0100 Subject: [PATCH] lib/resolver: support/bypass IP literals libc-ares doesn't do IP literals, so we have to do that before running off to do DNS. Since this isn't BMP specific, move to lib/ so NHRP can benefit too. Signed-off-by: David Lamparter --- bgpd/bgp_bmp.c | 31 +++++++++++++------------------ lib/resolver.c | 32 +++++++++++++++++++++++++++++++- lib/resolver.h | 4 ++++ 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index b8862c6049..b376d51a1c 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -1669,27 +1669,22 @@ static void bmp_active_resolved(struct resolver_query *resq, int numaddrs, unsigned i; if (numaddrs <= 0) { - int ret; - - ba->addrpos = 0; - ba->addrtotal = 1; - ret = str2sockunion(ba->hostname, &ba->addrs[0]); - if (ret < 0) { - ba->addrtotal = 0; - ba->curretry += ba->curretry / 2; - bmp_active_setup(ba); - return; - } - } else { - if (numaddrs > (int)array_size(ba->addrs)) - numaddrs = array_size(ba->addrs); - + zlog_warn("bmp[%s]: hostname resolution failed", ba->hostname); + ba->curretry += ba->curretry / 2; ba->addrpos = 0; - ba->addrtotal = numaddrs; - for (i = 0; i < ba->addrtotal; i++) - memcpy(&ba->addrs[i], &addr[i], sizeof(ba->addrs[0])); + ba->addrtotal = 0; + bmp_active_setup(ba); + return; } + if (numaddrs > (int)array_size(ba->addrs)) + numaddrs = array_size(ba->addrs); + + ba->addrpos = 0; + ba->addrtotal = numaddrs; + for (i = 0; i < ba->addrtotal; i++) + memcpy(&ba->addrs[i], &addr[i], sizeof(ba->addrs[0])); + bmp_active_connect(ba); } diff --git a/lib/resolver.c b/lib/resolver.c index fb8aeed92f..938ebd4143 100644 --- a/lib/resolver.c +++ b/lib/resolver.c @@ -180,11 +180,25 @@ static void ares_address_cb(void *arg, int status, int timeouts, callback(query, i, &addr[0]); } +static int resolver_cb_literal(struct thread *t) +{ + struct resolver_query *query = THREAD_ARG(t); + void (*callback)(struct resolver_query *, int, union sockunion *); + + callback = query->callback; + query->callback = NULL; + + callback(query, 1, &query->literal_addr); + return 0; +} + void resolver_resolve(struct resolver_query *query, int af, const char *hostname, void (*callback)(struct resolver_query *, int, union sockunion *)) { + int ret; + if (query->callback != NULL) { flog_err( EC_LIB_RESOLVER, @@ -193,10 +207,26 @@ void resolver_resolve(struct resolver_query *query, int af, return; } + query->callback = callback; + query->literal_cb = NULL; + + ret = str2sockunion(hostname, &query->literal_addr); + if (ret == 0) { + if (resolver_debug) + zlog_debug("[%p] Resolving '%s' (IP literal)", + query, hostname); + + /* for consistency with proper name lookup, don't call the + * callback immediately; defer to thread loop + */ + thread_add_timer_msec(state.master, resolver_cb_literal, + query, 0, &query->literal_cb); + return; + } + if (resolver_debug) zlog_debug("[%p] Resolving '%s'", query, hostname); - query->callback = callback; ares_gethostbyname(state.channel, hostname, af, ares_address_cb, query); resolver_update_timeouts(&state); } diff --git a/lib/resolver.h b/lib/resolver.h index bc6326edaa..a418377a29 100644 --- a/lib/resolver.h +++ b/lib/resolver.h @@ -15,6 +15,10 @@ struct resolver_query { void (*callback)(struct resolver_query *, int n, union sockunion *); + + /* used to immediate provide the result if IP literal is passed in */ + union sockunion literal_addr; + struct thread *literal_cb; }; void resolver_init(struct thread_master *tm); -- 2.39.5