示例#1
0
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;
}
示例#2
0
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();
}
示例#3
0
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;
}
示例#4
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;
}
示例#5
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);
}
示例#6
0
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();
    }
  }
}
示例#7
0
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;
}
示例#8
0
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;
}