diff options
Diffstat (limited to 'lib/resolver.c')
| -rw-r--r-- | lib/resolver.c | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/lib/resolver.c b/lib/resolver.c index fb8aeed92f..1be47bd6e1 100644 --- a/lib/resolver.c +++ b/lib/resolver.c @@ -145,7 +145,8 @@ static void ares_address_cb(void *arg, int status, int timeouts, { struct resolver_query *query = (struct resolver_query *)arg; union sockunion addr[16]; - void (*callback)(struct resolver_query *, int, union sockunion *); + void (*callback)(struct resolver_query *, const char *, int, + union sockunion *); size_t i; callback = query->callback; @@ -153,9 +154,10 @@ static void ares_address_cb(void *arg, int status, int timeouts, if (status != ARES_SUCCESS) { if (resolver_debug) - zlog_debug("[%p] Resolving failed", query); + zlog_debug("[%p] Resolving failed (%s)", + query, ares_strerror(status)); - callback(query, -1, NULL); + callback(query, ares_strerror(status), -1, NULL); return; } @@ -177,14 +179,29 @@ static void ares_address_cb(void *arg, int status, int timeouts, if (resolver_debug) zlog_debug("[%p] Resolved with %d results", query, (int)i); - callback(query, i, &addr[0]); + callback(query, NULL, i, &addr[0]); +} + +static int resolver_cb_literal(struct thread *t) +{ + struct resolver_query *query = THREAD_ARG(t); + void (*callback)(struct resolver_query *, const char *, int, + union sockunion *); + + callback = query->callback; + query->callback = NULL; + + callback(query, ARES_SUCCESS, 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 *)) + void (*callback)(struct resolver_query *, const char *, + int, union sockunion *)) { + int ret; + if (query->callback != NULL) { flog_err( EC_LIB_RESOLVER, @@ -193,10 +210,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); } |
