int noit_check_resolver_fetch(const char *target, char *buff, int len, uint8_t prefer_family) { int i, rv; uint8_t progression[2]; dns_cache_node *n; void *vnode; buff[0] = '\0'; if(!target) return -1; progression[0] = prefer_family; progression[1] = (prefer_family == AF_INET) ? AF_INET6 : AF_INET; if(mtev_hash_retrieve(&etc_hosts_cache, target, strlen(target), &vnode)) { static_host_node *node = vnode; for(i=0; i<2; i++) { switch(progression[i]) { case AF_INET: if(node->has_ip4) { inet_ntop(AF_INET, &node->ip4, buff, len); return 1; } break; case AF_INET6: if(node->has_ip6) { inet_ntop(AF_INET6, &node->ip6, buff, len); return 1; } break; } } } rv = -1; DCLOCK(); n = mtev_skiplist_find(&nc_dns_cache, target, NULL); if(n != NULL) { if(n->last_updated == 0) goto leave; /* not resolved yet */ rv = n->ip4_cnt + n->ip6_cnt; for(i=0; i<2; i++) { switch(progression[i]) { case AF_INET: if(n->ip4_cnt > 0) { inet_ntop(AF_INET, &n->ip4[0], buff, len); goto leave; } break; case AF_INET6: if(n->ip6_cnt > 0) { inet_ntop(AF_INET6, &n->ip6[0], buff, len); goto leave; } break; } } } leave: DCUNLOCK(); return rv; }
static void noit_check_resolver_remind_internal(const char *target, mtev_boolean needs_lock) { dns_cache_node *n; if(!target) return; if(needs_lock) DCLOCK(); n = mtev_skiplist_find(&nc_dns_cache, target, NULL); if(n != NULL) { n->last_needed = time(NULL); if(needs_lock) DCUNLOCK(); return; } n = calloc(1, sizeof(*n)); n->target = strdup(target); n->last_needed = time(NULL); mtev_skiplist_insert(&nc_dns_cache, n); if(needs_lock) DCUNLOCK(); }
static int noit_console_manip_dns_cache(mtev_console_closure_t ncct, int argc, char **argv, mtev_console_state_t *dstate, void *closure) { int i; if(argc == 0) { nc_printf(ncct, "dns_cache what?\n"); return 0; } DCLOCK(); if(closure == NULL) { /* adding */ for(i=0;i<argc;i++) { dns_cache_node *n; n = mtev_skiplist_find(&nc_dns_cache, argv[i], NULL); if(NULL != n) { nc_printf(ncct, " == Already in system ==\n"); nc_print_dns_cache_node(ncct, argv[i], n); } else { nc_printf(ncct, "%s submitted.\n", argv[i]); noit_check_resolver_remind_internal(argv[i], mtev_false); } } } else { for(i=0;i<argc;i++) { dns_cache_node *n; n = mtev_skiplist_find(&nc_dns_cache, argv[i], NULL); if(NULL != n) { if(n->lookup_inflight_v4 || n->lookup_inflight_v6) nc_printf(ncct, "%s is currently resolving and cannot be removed.\n"); else { mtev_skiplist_remove(&nc_dns_cache, argv[i], dns_cache_node_free); nc_printf(ncct, "%s removed.\n", argv[i]); } } else nc_printf(ncct, "%s not in system.\n", argv[i]); } } DCUNLOCK(); return 0; }
static int noit_console_show_dns_cache(mtev_console_closure_t ncct, int argc, char **argv, mtev_console_state_t *dstate, void *closure) { int i; DCLOCK(); if(argc == 0) { mtev_skiplist_node *sn; for(sn = mtev_skiplist_getlist(&nc_dns_cache); sn; mtev_skiplist_next(&nc_dns_cache, &sn)) { dns_cache_node *n = (dns_cache_node *)sn->data; nc_print_dns_cache_node(ncct, n->target, n); } } for(i=0;i<argc;i++) { dns_cache_node *n; n = mtev_skiplist_find(&nc_dns_cache, argv[i], NULL); nc_print_dns_cache_node(ncct, argv[i], n); } DCUNLOCK(); return 0; }
void noit_check_resolver_init() { int cnt; mtev_conf_section_t *servers, *searchdomains; eventer_t e; if(dns_init(NULL, 0) < 0) mtevL(noit_error, "dns initialization failed.\n"); dns_ctx = dns_new(NULL); if(dns_init(dns_ctx, 0) != 0) { mtevL(noit_error, "dns initialization failed.\n"); exit(-1); } /* Optional servers */ servers = mtev_conf_get_sections(NULL, "//resolver//server", &cnt); if(cnt) { int i; char server[128]; dns_add_serv(dns_ctx, NULL); /* reset */ for(i=0;i<cnt;i++) { if(mtev_conf_get_stringbuf(servers[i], "self::node()", server, sizeof(server))) { if(dns_add_serv(dns_ctx, server) < 0) { mtevL(noit_error, "Failed adding DNS server: %s\n", server); } } } free(servers); } searchdomains = mtev_conf_get_sections(NULL, "//resolver//search", &cnt); if(cnt) { int i; char search[128]; dns_add_srch(dns_ctx, NULL); /* reset */ for(i=0;i<cnt;i++) { if(mtev_conf_get_stringbuf(searchdomains[i], "self::node()", search, sizeof(search))) { if(dns_add_srch(dns_ctx, search) < 0) { mtevL(noit_error, "Failed adding DNS search path: %s\n", search); } else if(dns_search_flag) dns_search_flag = 0; /* enable search */ } } free(searchdomains); } if(mtev_conf_get_int(NULL, "//resolver/@ndots", &cnt)) dns_set_opt(dns_ctx, DNS_OPT_NDOTS, cnt); if(mtev_conf_get_int(NULL, "//resolver/@ntries", &cnt)) dns_set_opt(dns_ctx, DNS_OPT_NTRIES, cnt); if(mtev_conf_get_int(NULL, "//resolver/@timeout", &cnt)) dns_set_opt(dns_ctx, DNS_OPT_TIMEOUT, cnt); if(dns_open(dns_ctx) < 0) { mtevL(noit_error, "dns open failed.\n"); exit(-1); } eventer_name_callback("dns_cache_callback", dns_cache_callback); dns_set_tmcbck(dns_ctx, dns_cache_utm_fn, dns_ctx); e = eventer_alloc(); e->mask = EVENTER_READ | EVENTER_EXCEPTION; e->closure = dns_ctx; e->callback = dns_cache_callback; e->fd = dns_sock(dns_ctx); eventer_add(e); mtev_skiplist_init(&nc_dns_cache); mtev_skiplist_set_compare(&nc_dns_cache, name_lookup, name_lookup_k); mtev_skiplist_add_index(&nc_dns_cache, refresh_idx, refresh_idx_k); /* maybe load it from cache */ if(noit_resolver_cache_load_hook_exists()) { struct timeval now; char *key; void *data; int len; gettimeofday(&now, NULL); while(noit_resolver_cache_load_hook_invoke(&key, &data, &len) == MTEV_HOOK_CONTINUE) { dns_cache_node *n; n = calloc(1, sizeof(*n)); if(dns_cache_node_deserialize(n, data, len) >= 0) { n->target = strdup(key); /* if the TTL indicates that it will expire in less than 60 seconds * (including stuff that should have already expired), then fudge * the last_updated time to make it expire some random time within * the next 60 seconds. */ if(n->last_needed > now.tv_sec || n->last_updated > now.tv_sec) break; /* impossible */ n->last_needed = now.tv_sec; if(n->last_updated + n->ttl < now.tv_sec + 60) { int fudge = MIN(60, n->ttl) + 1; n->last_updated = now.tv_sec - n->ttl + (lrand48() % fudge); } DCLOCK(); mtev_skiplist_insert(&nc_dns_cache, n); DCUNLOCK(); n = NULL; } else { mtevL(noit_error, "Failed to deserialize resolver cache record.\n"); } if(n) dns_cache_node_free(n); if(key) free(key); if(data) free(data); } } noit_check_resolver_loop(NULL, 0, NULL, NULL); register_console_dns_cache_commands(); mtev_hash_init(&etc_hosts_cache); noit_check_etc_hosts_cache_refresh(NULL, 0, NULL, NULL); }
void noit_check_resolver_maintain() { time_t now; mtev_skiplist *tlist; mtev_skiplist_node *sn; now = time(NULL); sn = mtev_skiplist_getlist(nc_dns_cache.index); assert(sn); tlist = sn->data; assert(tlist); sn = mtev_skiplist_getlist(tlist); while(sn) { dns_cache_node *n = sn->data; mtev_skiplist_next(tlist, &sn); /* move forward */ /* remove if needed */ if(n->last_updated + n->ttl > now) break; if(n->last_needed + DEFAULT_PURGE_AGE < now && !(n->lookup_inflight_v4 || n->lookup_inflight_v6)) mtev_skiplist_remove(&nc_dns_cache, n->target, dns_cache_node_free); else { int abs; if(!dns_ptodn(n->target, strlen(n->target), n->dn, sizeof(n->dn), &abs)) { blank_update(n); } else { if(!n->lookup_inflight_v4) { n->lookup_inflight_v4 = mtev_true; if(!dns_submit_dn(dns_ctx, n->dn, DNS_C_IN, DNS_T_A, abs | dns_search_flag, NULL, dns_cache_resolve_v4, n)) blank_update_v4(n); else dns_timeouts(dns_ctx, -1, now); } if(!n->lookup_inflight_v6) { n->lookup_inflight_v6 = mtev_true; if(!dns_submit_dn(dns_ctx, n->dn, DNS_C_IN, DNS_T_AAAA, abs | dns_search_flag, NULL, dns_cache_resolve_v6, n)) blank_update_v6(n); else dns_timeouts(dns_ctx, -1, now); } } mtevL(noit_debug, "Firing lookup for '%s'\n", n->target); continue; } } /* If we have a cache implementation */ if(noit_resolver_cache_store_hook_exists()) { /* And that implementation is interested in getting a dump... */ if(noit_resolver_cache_store_hook_invoke(NULL, NULL, 0) == MTEV_HOOK_CONTINUE) { mtev_skiplist_node *sn; /* dump it all */ DCLOCK(); for(sn = mtev_skiplist_getlist(&nc_dns_cache); sn; mtev_skiplist_next(&nc_dns_cache, &sn)) { int sbuffsize; char sbuff[1024]; dns_cache_node *n = (dns_cache_node *)sn->data; sbuffsize = dns_cache_node_serialize(sbuff, sizeof(sbuff), n); if(sbuffsize > 0) noit_resolver_cache_store_hook_invoke(n->target, sbuff, sbuffsize); } DCUNLOCK(); } } }
static void dns_cache_resolve(struct dns_ctx *ctx, void *result, void *data, enum dns_type rtype) { int ttl, acnt, r = dns_status(ctx), idnlen; dns_cache_node *n = data; unsigned char idn[DNS_MAXDN], dn[DNS_MAXDN]; struct dns_parse p; struct dns_rr rr; unsigned nrr; struct in_addr *answers4; struct in6_addr *answers6; const unsigned char *pkt, *cur, *end; if(!result) goto blank; dns_dntodn(n->dn, idn, sizeof(idn)); idnlen = dns_dnlen(idn); pkt = result; end = pkt + r; cur = dns_payload(pkt); dns_getdn(pkt, &cur, end, dn, sizeof(dn)); dns_initparse(&p, NULL, pkt, cur, end); p.dnsp_qcls = 0; p.dnsp_qtyp = 0; nrr = 0; ttl = 0; while((r = dns_nextrr(&p, &rr)) > 0) { int dnlen = dns_dnlen(rr.dnsrr_dn); /* if we aren't searching and the don't match... * or if we are searching and the prefixes don't match... */ if ((dns_search_flag && !dns_dnequal(idn, rr.dnsrr_dn)) || (dns_search_flag == 0 && (idnlen > dnlen || memcmp(idn, rr.dnsrr_dn, idnlen-1)))) continue; if (DNS_C_IN == rr.dnsrr_cls && rtype == rr.dnsrr_typ) ++nrr; else if (rr.dnsrr_typ == DNS_T_CNAME && !nrr) { if (dns_getdn(pkt, &rr.dnsrr_dptr, end, p.dnsp_dnbuf, sizeof(p.dnsp_dnbuf)) <= 0 || rr.dnsrr_dptr != rr.dnsrr_dend) { break; } else { if(rr.dnsrr_ttl > 0 && (ttl == 0 || rr.dnsrr_ttl < ttl)) ttl = rr.dnsrr_ttl; dns_dntodn(p.dnsp_dnbuf, idn, sizeof(idn)); idnlen = dns_dnlen(idn); } } } if(!r && !nrr) goto blank; dns_rewind(&p, NULL); p.dnsp_qcls = DNS_C_IN; p.dnsp_qtyp = rtype; if(rtype == DNS_T_A) answers4 = calloc(nrr, sizeof(*answers4)); else if(rtype == DNS_T_AAAA) answers6 = calloc(nrr, sizeof(*answers6)); acnt = 0; while(dns_nextrr(&p, &rr) && nrr < MAX_RR) { int dnlen = dns_dnlen(rr.dnsrr_dn); if ((dns_search_flag && !dns_dnequal(idn, rr.dnsrr_dn)) || (dns_search_flag == 0 && (idnlen > dnlen || memcmp(idn, rr.dnsrr_dn, idnlen-1)))) continue; if (p.dnsp_rrl && !rr.dnsrr_dn[0] && rr.dnsrr_typ == DNS_T_OPT) continue; if (rtype == rr.dnsrr_typ) { if(rr.dnsrr_ttl > 0 && (ttl == 0 || rr.dnsrr_ttl < ttl)) ttl = rr.dnsrr_ttl; switch(rr.dnsrr_typ) { case DNS_T_A: if(rr.dnsrr_dsz != 4) continue; memcpy(&answers4[acnt++], rr.dnsrr_dptr, rr.dnsrr_dsz); break; case DNS_T_AAAA: if(rr.dnsrr_dsz != 16) continue; memcpy(&answers6[acnt++], rr.dnsrr_dptr, rr.dnsrr_dsz); break; default: break; } } } n->ttl = ttl; if(rtype == DNS_T_A) { if(n->ip4) free(n->ip4); n->ip4_cnt = acnt; n->ip4 = answers4; n->lookup_inflight_v4 = mtev_false; } else if(rtype == DNS_T_AAAA) { if(n->ip6) free(n->ip6); n->ip6_cnt = acnt; n->ip6 = answers6; n->lookup_inflight_v6 = mtev_false; } else { if(result) free(result); return; } DCLOCK(); mtev_skiplist_remove(&nc_dns_cache, n->target, NULL); n->last_updated = time(NULL); mtev_skiplist_insert(&nc_dns_cache, n); DCUNLOCK(); mtevL(noit_debug, "Resolved %s/%s -> %d records\n", n->target, (rtype == DNS_T_AAAA ? "IPv6" : (rtype == DNS_T_A ? "IPv4" : "???")), acnt); if(result) free(result); return; blank: DCLOCK(); if(rtype == DNS_T_A) blank_update_v4(n); if(rtype == DNS_T_AAAA) blank_update_v6(n); DCUNLOCK(); mtevL(noit_debug, "Resolved %s/%s -> blank\n", n->target, (rtype == DNS_T_AAAA ? "IPv6" : (rtype == DNS_T_A ? "IPv4" : "???"))); if(result) free(result); return; }
void wfm_dslash_two( Float *chi0, Float *chi1, Float *u, Float *psi0, Float *psi1, int cb0, int cb1, int dag) { static Float dslash_time=0.; static Float decom_time=0.; static Float recom_time=0.; static Float comm_time=0.; static Float comm_init_time=0.; called++; dslash_time -=DCLOCK(); wfm_scope_assert(0); wfm_scope_assert(1); decom_time -=DCLOCK(); cache_touch(psi0); cache_touch(psi0+4); cache_touch(psi0+8); cache_touch(psi0+12); cache_touch(psi0+16); cache_touch(psi0+20); StaticWilsonPAB[0].decom(psi0,u,cb0,dag); decom_time +=DCLOCK(); comm_init_time -=DCLOCK(); StaticWilsonPAB[0].comm_start(cb0); comm_init_time +=DCLOCK(); decom_time -=DCLOCK(); cache_touch(psi1); cache_touch(psi1+4); cache_touch(psi1+8); cache_touch(psi1+12); cache_touch(psi1+16); cache_touch(psi1+20); StaticWilsonPAB[1].decom(psi1,u,cb1,dag); decom_time +=DCLOCK(); comm_time -=DCLOCK(); StaticWilsonPAB[0].comm_complete(cb0); comm_time +=DCLOCK(); comm_init_time -=DCLOCK(); StaticWilsonPAB[1].comm_start(cb1); comm_init_time +=DCLOCK(); recom_time -=DCLOCK(); cache_touch(StaticWilsonPAB[0].two_spinor); cache_touch(StaticWilsonPAB[0].two_spinor+4); cache_touch(StaticWilsonPAB[0].two_spinor+8); StaticWilsonPAB[0].recon(chi0,u,cb0,dag); recom_time +=DCLOCK(); comm_time -=DCLOCK(); StaticWilsonPAB[1].comm_complete(cb1); comm_time +=DCLOCK(); recom_time -=DCLOCK(); cache_touch(StaticWilsonPAB[1].two_spinor); cache_touch(StaticWilsonPAB[1].two_spinor+4); cache_touch(StaticWilsonPAB[1].two_spinor+8); StaticWilsonPAB[1].recon(chi1,u,cb1,dag); recom_time +=DCLOCK(); dslash_time +=DCLOCK(); #ifdef PROFILE #ifndef UNIFORM_SEED_TESTING if (called%p_int==0){ CPS_NAMESPACE::print_time("wfm_dslash_two","dslash_time",dslash_time/m_num); CPS_NAMESPACE::print_time("wfm_dslash_two","decom_time",decom_time/m_num); CPS_NAMESPACE::print_time("wfm_dslash_two","recom_time",recom_time/m_num); CPS_NAMESPACE::print_time("wfm_dslash_two","comm_init_time",comm_init_time/m_num); CPS_NAMESPACE::print_time("wfm_dslash_two","comm_time",comm_time/m_num); called=0; decom_time=recom_time=comm_time=dslash_time=comm_init_time=0.; } #endif #endif return; }