dns_cache_rrset_t * dns_engine_query(dns_msg_question_t *q, dns_config_zone_t *zone, dns_tls_t *tls) { int rcode, noerror = 0; dns_engine_t *engine; dns_engine_param_t param; dns_cache_rrset_t *rrset; dns_config_zone_engine_t *ze; if ((rrset = dns_cache_new(q, tls)) == NULL) { plog(LOG_ERR, "%s: can't allocate new cache", MODULE); return NULL; } ze = (dns_config_zone_engine_t *) dns_list_head(&zone->z_search.zs_engine); while (ze != NULL) { engine = (dns_engine_t *) ze->ze_engine; if (engine->eng_query != NULL) { plog(LOG_DEBUG, "%s: query \"%s\" engine", MODULE, engine->eng_name); dns_cache_setrcode(rrset, DNS_RCODE_NOERROR); param.ep_zone = zone; param.ep_conf = ze->ze_econf; if (engine->eng_query(¶m, rrset, q, tls) < 0) { dns_cache_release(rrset, tls); return NULL; } rcode = dns_cache_getrcode(rrset); plog(LOG_DEBUG, "%s: rcode %d (%s)", MODULE, rcode, dns_proto_rcode_string(rcode)); if (rcode == DNS_RCODE_NOERROR) noerror = 1; if (rcode != DNS_RCODE_NOERROR && rcode != DNS_RCODE_NXDOMAIN) return rrset; // XXX merge answers? if (dns_cache_count_answer(rrset) > 0) return rrset; } ze = (dns_config_zone_engine_t *) dns_list_next(&zone->z_search.zs_engine, &ze->ze_elem); } dns_cache_setrcode(rrset, (noerror) ? DNS_RCODE_NOERROR : DNS_RCODE_NXDOMAIN); dns_cache_negative(rrset, 0); return rrset; }
} TestSuite(dnscache, .init = app_startup, .fini = app_shutdown); Test(dnscache, test_expiration) { DNSCacheOptions options = { .cache_size = 50000, .expire = 3, .expire_failed = 1, .hosts = NULL }; DNSCache *cache = dns_cache_new(&options); gint cache_size = 10000; _fill_dns_cache(cache, cache_size); assert_no_forget(cache, cache_size); /* negative entries should expire by now, positive ones still present */ _invalidate_with_sleep(2); assert_forget_negative(cache, cache_size); /* everything should be expired by now */ _invalidate_with_sleep(2); assert_forget_all(cache, cache_size); dns_cache_free(cache); }