Esempio n. 1
0
static int
check_test_sweeper(eventer_t e, int mask, void *closure,
                   struct timeval *now) {
  int left = 0;
  noit_skiplist_node *iter = NULL;
  sweeper_event = NULL;
  iter = noit_skiplist_getlist(&in_progress);
  while(iter) {
    struct check_test_closure *cl = iter->data;
    /* advance here, we might delete */
    noit_skiplist_next(&in_progress,&iter);
    if(NOIT_CHECK_DISABLED(cl->check)) {
      if(NOIT_CHECK_SHOULD_RESOLVE(cl->check))
        noit_check_resolve(cl->check);
      if(NOIT_CHECK_RESOLVED(cl->check)) {
        noit_module_t *m = noit_module_lookup(cl->check->module);
        cl->check->flags &= ~NP_DISABLED;
        if(NOIT_CHECK_SHOULD_RESOLVE(cl->check))
          noitL(nldeb, "translated to %s\n", cl->check->target_ip);
        if(m) m->initiate_check(m, cl->check, 1, NULL);
      }
      left++;
    }
    else if(NOIT_CHECK_RUNNING(cl->check)) left++;
    else
      noit_skiplist_remove(&in_progress, cl->restc,
                           (noit_freefunc_t)rest_test_check_result);
  }

  if(left) check_test_schedule_sweeper();
  return 0;
}
static void blank_update_v6(dns_cache_node *n) {
  int i;
  for(i=0;i<n->ip6_cnt;i++) if(n->ip6[i]) free(n->ip6[i]);
  if(n->ip6) free(n->ip6);
  n->ip6 = NULL;
  n->ip6_cnt = 0;
  noit_skiplist_remove(&nc_dns_cache, n->target, NULL);
  n->last_updated = time(NULL);
  n->ttl = DEFAULT_FAILED_TTL;
  n->lookup_inflight_v6 = noit_false;
  noit_skiplist_insert(&nc_dns_cache, n);
}
Esempio n. 3
0
static int
rest_test_check_err(noit_http_rest_closure_t *restc,
                    int npats, char **pats) {
  noit_http_response *res = noit_http_session_response(restc->http_ctx);
  noit_skiplist_remove(&in_progress, restc,
                       (noit_freefunc_t)rest_test_check_result);
  if(noit_http_response_complete(res) != noit_true) {
    noit_http_response_standard(restc->http_ctx, 500, "ERROR", "text/html");
    noit_http_response_end(restc->http_ctx);
  }
  return 0;
}
Esempio n. 4
0
void
noit_check_transient_remove_feed(noit_check_t *check, const char *feed) {
  if(!check->feeds) return;
  if(feed) {
    noitL(noit_debug, "check %s`%s @ %dms removing 1 of %d feeds: %s.\n",
          check->target, check->name, check->period, check->feeds->size, feed);
    noit_skiplist_remove(check->feeds, feed, free);
  }
  if(check->feeds->size == 0) {
    char uuid_str[UUID_STR_LEN + 1];
    uuid_unparse_lower(check->checkid, uuid_str);
    noitL(noit_debug, "Unwatching %s@%d\n", uuid_str, check->period);
    noit_skiplist_remove(&watchlist, check, NULL);
    noit_skiplist_destroy(check->feeds, free);
    free(check->feeds);
    check->feeds = NULL;
    if(check->flags & NP_TRANSIENT) {
      noitL(noit_debug, "check %s`%s @ %dms has no more listeners.\n",
            check->target, check->name, check->period);
      check->flags |= NP_KILLED;
    }
  }
}
void noit_check_resolver_maintain() {
  time_t now;
  noit_skiplist *tlist;
  noit_skiplist_node *sn;

  now = time(NULL);
  sn = noit_skiplist_getlist(nc_dns_cache.index);
  tlist = sn->data;
  sn = noit_skiplist_getlist(tlist);
  while(sn) {
    dns_cache_node *n = sn->data;
    noit_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))
      noit_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 = noit_true;
          if(!dns_submit_dn(dns_ctx, n->dn, DNS_C_IN, DNS_T_A,
                            abs | DNS_NOSRCH, 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 = noit_true;
          if(!dns_submit_dn(dns_ctx, n->dn, DNS_C_IN, DNS_T_AAAA,
                            abs | DNS_NOSRCH, NULL, dns_cache_resolve_v6, n))
            blank_update_v6(n);
          else
            dns_timeouts(dns_ctx, -1, now);
        }
      }
      noitL(noit_debug, "Firing lookup for '%s'\n", n->target);
      continue;
    }
  }
}
Esempio n. 6
0
int
noit_poller_deschedule(uuid_t in) {
  void *vcheck;
  noit_check_t *checker;
  if(noit_hash_retrieve(&polls,
                        (char *)in, UUID_SIZE,
                        &vcheck) == 0) {
    return -1;
  }
  checker = (noit_check_t *)vcheck;
  checker->flags |= (NP_DISABLED|NP_KILLED);

  noit_skiplist_remove(&polls_by_name, checker, NULL);
  noit_hash_delete(&polls, (char *)in, UUID_SIZE, NULL, NULL);

  noit_poller_free_check(checker);
  return 0;
}
static int
noit_console_manip_dns_cache(noit_console_closure_t ncct,
                             int argc, char **argv,
                             noit_console_state_t *dstate,
                             void *closure) {
  int i;
  if(argc == 0) {
    nc_printf(ncct, "dns_cache what?\n");
    return 0;
  }
  if(closure == NULL) {
    /* adding */
    for(i=0;i<argc;i++) {
      dns_cache_node *n;
      if(NULL != (n = noit_skiplist_find(&nc_dns_cache, argv[i], NULL))) {
        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(argv[i]);
      }
    }
  }
  else {
    for(i=0;i<argc;i++) {
      dns_cache_node *n;
      if(NULL != (n = noit_skiplist_find(&nc_dns_cache, argv[i], NULL))) {
        if(n->lookup_inflight_v4 || n->lookup_inflight_v6)
          nc_printf(ncct, "%s is currently resolving and cannot be removed.\n");
        else {
          noit_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]);
    }
  }
  return 0;
}
static void dns_cache_resolve(struct dns_ctx *ctx, void *result, void *data,
                              enum dns_type rtype) {
  int i, ttl, acnt, r = dns_status(ctx);
  dns_cache_node *n = data;
  unsigned char idn[DNS_MAXDN], dn[DNS_MAXDN];
  struct dns_parse p;
  struct dns_rr rr;
  unsigned nrr;
  char **answers;
  const unsigned char *pkt, *cur, *end;

  if(!result) goto blank;

  dns_dntodn(n->dn, idn, sizeof(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) {
    if (!dns_dnequal(idn, rr.dnsrr_dn)) 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));
      }
    }
  }
  if(!r && !nrr) goto blank;

  dns_rewind(&p, NULL);
  p.dnsp_qcls = DNS_C_IN;
  p.dnsp_qtyp = rtype;
  answers = calloc(nrr, sizeof(*answers));
  acnt = 0;
  while(dns_nextrr(&p, &rr) && nrr < MAX_RR) {
    char buff[INET6_ADDRSTRLEN];
    if (!dns_dnequal(idn, rr.dnsrr_dn)) 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;
          inet_ntop(AF_INET, rr.dnsrr_dptr, buff, sizeof(buff));
          answers[acnt++] = strdup(buff);
          break;
        case DNS_T_AAAA:
          if(rr.dnsrr_dsz != 16) continue;
          inet_ntop(AF_INET6, rr.dnsrr_dptr, buff, sizeof(buff));
          answers[acnt++] = strdup(buff);
          break;
        default:
          break;
      }
    }
  }

  n->ttl = ttl;
  if(rtype == DNS_T_A) {
    for(i=0;i<n->ip4_cnt;i++) if(n->ip4[i]) free(n->ip4[i]);
    if(n->ip4) free(n->ip4);
    n->ip4_cnt = acnt;
    n->ip4 = answers;
    n->lookup_inflight_v4 = noit_false;
  }
  else if(rtype == DNS_T_AAAA) {
    for(i=0;i<n->ip6_cnt;i++) if(n->ip6[i]) free(n->ip6[i]);
    if(n->ip6) free(n->ip6);
    n->ip6_cnt = acnt;
    n->ip6 = answers;
    n->lookup_inflight_v6 = noit_false;
  }
  noit_skiplist_remove(&nc_dns_cache, n->target, NULL);
  n->last_updated = time(NULL);
  noit_skiplist_insert(&nc_dns_cache, n);
  noitL(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:
  if(rtype == DNS_T_A) blank_update_v4(n);
  if(rtype == DNS_T_AAAA) blank_update_v6(n);
  noitL(noit_debug, "Resolved %s/%s -> blank\n", n->target,
        (rtype == DNS_T_AAAA ? "IPv6" : (rtype == DNS_T_A ? "IPv4" : "???")));
  if(result) free(result);
  return;
}
Esempio n. 9
0
int
noit_check_update(noit_check_t *new_check,
                  const char *target,
                  const char *name,
                  const char *filterset,
                  noit_hash_table *config,
                  u_int32_t period,
                  u_int32_t timeout,
                  const char *oncheck,
                  int flags) {
  int8_t family;
  int rv;
  int mask = NP_DISABLED | NP_UNCONFIG;
  union {
    struct in_addr addr4;
    struct in6_addr addr6;
  } a;


  family = AF_INET;
  rv = inet_pton(family, target, &a);
  if(rv != 1) {
    family = AF_INET6;
    rv = inet_pton(family, target, &a);
    if(rv != 1) {
      noitL(noit_stderr, "Cannot translate '%s' to IP\n", target);
      memset(&a, 0, sizeof(a));
      flags |= (NP_UNCONFIG | NP_DISABLED);
    }
  }

  new_check->generation = __config_load_generation;
  new_check->target_family = family;
  memcpy(&new_check->target_addr, &a, sizeof(a));
  if(new_check->target) free(new_check->target);
  new_check->target = strdup(target);
  if(new_check->name) free(new_check->name);
  new_check->name = name ? strdup(name): NULL;
  if(new_check->filterset) free(new_check->filterset);
  new_check->filterset = filterset ? strdup(filterset): NULL;

  if(config != NULL) {
    noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
    const char *k;
    int klen;
    void *data;
    if(new_check->config) noit_hash_delete_all(new_check->config, free, free);
    else new_check->config = calloc(1, sizeof(*new_check->config));
    while(noit_hash_next(config, &iter, &k, &klen, &data)) {
      noit_hash_store(new_check->config, strdup(k), klen, strdup((char *)data));
    }
  }
  if(new_check->oncheck) free(new_check->oncheck);
  new_check->oncheck = oncheck ? strdup(oncheck) : NULL;
  new_check->period = period;
  new_check->timeout = timeout;

  /* Unset what could be set.. then set what should be set */
  new_check->flags = (new_check->flags & ~mask) | flags;

  if(!(new_check->flags & NP_TRANSIENT)) {
    /* This remove could fail -- no big deal */
    noit_skiplist_remove(&polls_by_name, new_check, NULL);

    /* This insert could fail.. which means we have a conflict on
     * target`name.  That should result in the check being disabled. */
    if(!noit_skiplist_insert(&polls_by_name, new_check)) {
      noitL(noit_stderr, "Check %s`%s disabled due to naming conflict\n",
            new_check->target, new_check->name);
      new_check->flags |= NP_DISABLED;
    }
  }
  noit_check_log_check(new_check);
  return 0;
}