diff --git a/evdns.c b/evdns.c index 469f63b6..af10da8c 100644 --- a/evdns.c +++ b/evdns.c @@ -5440,8 +5440,9 @@ evdns_cache_lookup(struct evdns_base *base, EVDNS_UNLOCK(base); out: if (n_found) { - /* Note that we return an empty answer if we found entries for - * this hostname but none were of the right address type. */ + if (!ai) { + return EVUTIL_EAI_ADDRFAMILY; + } *res = ai; return 0; } else { @@ -5764,15 +5765,19 @@ evdns_getaddrinfo(struct evdns_base *dns_base, } /* If there is an entry in the hosts file, we should give it now. */ - if (!evdns_getaddrinfo_fromhosts(dns_base, nodename, &hints, port, &res)) { - cb(0, res, arg); + err = evdns_getaddrinfo_fromhosts(dns_base, nodename, &hints, port, &res); + if (!err || err == EVUTIL_EAI_ADDRFAMILY) { + cb(err, res, arg); return NULL; } /* See if we have it in the cache */ - if (!dns_base->disable_cache && !evdns_cache_lookup(dns_base, nodename, &hints, port, &res)) { - cb(0, res, arg); - return NULL; + if (!dns_base->disable_cache) { + err = evdns_cache_lookup(dns_base, nodename, &hints, port, &res); + if (!err || err == EVUTIL_EAI_ADDRFAMILY) { + cb(err, res, arg); + return NULL; + } } /* Okay, things are serious now. We're going to need to actually diff --git a/include/event2/dns.h b/include/event2/dns.h index 73af0ac4..5af662f4 100644 --- a/include/event2/dns.h +++ b/include/event2/dns.h @@ -819,6 +819,7 @@ struct evdns_getaddrinfo_request; * - For ai_protocol, we only handle IPPROTO_TCP, IPPROTO_UDP, and 0. * - If we cached a response exclusively for a different address type (e.g. * PF_INET), we will set addrinfo to NULL (e.g. queried with PF_INET6) + * and return EVUTIL_EAI_ADDRFAMILY. * - Cache isn't hit when AI_CANONNAME is set but cached server response * doesn't contain CNAME. * - If we can answer immediately (e.g. using hosts file, there is an error diff --git a/test/regress_dns.c b/test/regress_dns.c index 804717a4..6f92aa9f 100644 --- a/test/regress_dns.c +++ b/test/regress_dns.c @@ -2155,7 +2155,7 @@ test_getaddrinfo_async(void *arg) tt_assert(!b_out[2].ai->ai_next); test_ai_eq(b_out[2].ai, "[b0b::f00d]:8002", SOCK_STREAM, IPPROTO_TCP); - /* 2.5: v6only.example.com cache lookup with PF_INET should return NULL addressinfo. */ + /* 2.5: v6only.example.com cache lookup with PF_INET should return EVUTIL_EAI_ADDRFAMILY. */ hints.ai_family = PF_INET; hints.ai_flags = 0; evutil_freeaddrinfo(b_out[2].ai); // since this is reused @@ -2164,7 +2164,7 @@ test_getaddrinfo_async(void *arg) &hints, gai_cb, &b_out[2]); tt_assert(!r); // check - tt_int_op(b_out[2].err, ==, 0); + tt_int_op(b_out[2].err, ==, EVUTIL_EAI_ADDRFAMILY); tt_assert(!b_out[2].ai); /* 3: v4assert.example.com should have been cached */