Esempio n. 1
0
static int dns_module_invoke_timeouts(eventer_t e, int mask, void *closure,
                                      struct timeval *now) {
  dns_ctx_handle_t *h = closure;
  dns_timeouts(h->ctx, 0, now->tv_sec);
  dns_module_dns_ctx_release(h);
  return 0;
}
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. 3
0
static int noit_lua_dns_lookup(lua_State *L) {
  dns_lookup_ctx_t *dlc, **holder;
  const char *c, *query = "", *ctype = "IN", *rtype = "A";
  char *ctype_up, *rtype_up, *d;
  void *vnv_pair;
  noit_lua_check_info_t *ci;

  ci = get_ci(L);
  assert(ci);

  holder = (dns_lookup_ctx_t **)lua_touserdata(L, lua_upvalueindex(1));
  if(holder != lua_touserdata(L,1))
    luaL_error(L, "Must be called as method\n");
  dlc = *holder;

  if(lua_gettop(L) > 1) query = lua_tostring(L, 2);
  if(lua_gettop(L) > 2) rtype = lua_tostring(L, 3);
  if(lua_gettop(L) > 3) ctype = lua_tostring(L, 4);

  ctype_up = alloca(strlen(ctype)+1);
  for(d = ctype_up, c = ctype; *c; d++, c++) *d = toupper(*c);
  *d = '\0';
  rtype_up = alloca(strlen(rtype)+1);
  for(d = rtype_up, c = rtype; *c; d++, c++) *d = toupper(*c);
  *d = '\0';

  if(!noit_hash_retrieve(&dns_ctypes, ctype_up, strlen(ctype_up), &vnv_pair))
    dlc->error = strdup("bad class");
  else
    dlc->query_ctype = ((struct dns_nameval *)vnv_pair)->val;

  if(!noit_hash_retrieve(&dns_rtypes, rtype_up, strlen(rtype_up), &vnv_pair)) 
    dlc->error = strdup("bad rr type");
  else
    dlc->query_rtype = ((struct dns_nameval *)vnv_pair)->val;

  dlc->active = 1;
  noit_atomic_inc32(&dlc->refcnt);
  if(!dlc->error) {
    int abs;
    if(!dns_ptodn(query, strlen(query), dlc->dn, sizeof(dlc->dn), &abs) ||
       !dns_submit_dn(dlc->h->ctx, dlc->dn, dlc->query_ctype, dlc->query_rtype,
                      abs | DNS_NOSRCH, NULL, dns_cb, dlc)) {
      dlc->error = strdup("submission error");
      noit_atomic_dec32(&dlc->refcnt);
    }
    else {
      struct timeval now;
      gettimeofday(&now, NULL);
      dns_timeouts(dlc->h->ctx, -1, now.tv_sec);
    }
  }
  if(dlc->error) {
    dlc->active = 0;
    luaL_error(L, "dns: %s\n", dlc->error);
  }
  return noit_lua_yield(ci, 0);
}
Esempio n. 4
0
/*
 * DNS timeout callback
 */
static void
resolv_timeout_cb(struct ev_loop *loop, struct ev_timer *w, int revents)
{
    struct dns_ctx *ctx = (struct dns_ctx *)w->data;

    if (revents & EV_TIMER) {
        dns_timeouts(ctx, 30, ev_now(loop));
    }
}
Esempio n. 5
0
/*
 * Wrapper for client callback we provide to udns
 */
static void
dns_query_cb(struct dns_ctx *ctx, struct dns_rr_a4 *result, void *data) {
    struct ResolvQuery *cb_data = (struct ResolvQuery *)data;
    struct Address *address = NULL;

    if (result == NULL) {
        info("resolv: %s\n", dns_strerror(dns_status(ctx)));
    } else if (result->dnsa4_nrr > 0) {
        struct sockaddr_in sa = {
            .sin_family = AF_INET,
            .sin_port = 0,
            .sin_addr = result->dnsa4_addr[0],
        };

        address = new_address_sa((struct sockaddr *)&sa, sizeof(sa));
        if (address == NULL)
            err("Failed to allocate memory for DNS query result address");
    }

    cb_data->client_cb(address, cb_data->client_cb_data);

    cb_data->client_free_cb(cb_data->client_cb_data);
    free(cb_data);
    free(result);
    free(address);
}

/*
 * DNS timeout callback
 */
static void
resolv_timeout_cb(struct ev_loop *loop, struct ev_timer *w, int revents) {
    struct dns_ctx *ctx = (struct dns_ctx *)w->data;

    dns_timeouts(ctx, 30, ev_now(loop));
}

/*
 * Callback to setup DNS timeout callback
 */
static void
dns_timer_setup_cb(struct dns_ctx *ctx, int timeout, void *data) {
    struct ev_loop *loop = (struct ev_loop *)data;

    if (ev_is_active(&resolv_timeout_watcher))
        ev_timer_stop(loop, &resolv_timeout_watcher);

    if (ctx != NULL && timeout >= 0) {
        ev_timer_set(&resolv_timeout_watcher, timeout, 0.0);
        ev_timer_start(loop, &resolv_timeout_watcher);
    }
}
Esempio n. 6
0
static void dns_timeout_cb (EV_P_ ev_timer *w, int revents)
{
    ev_now_update(EV_A);
    ev_tstamp now = ev_now(EV_A );
    int next = dns_timeouts(NULL, -1, now);

    if (next > 0) {
        w->repeat = next;
        ev_timer_again (EV_A_ w);
    } else {
        w->repeat = 1;
        ev_timer_again (EV_A_ w);
    }
}
Esempio n. 7
0
/*@null@*/
static PyObject*
Resolver_timeouts (Resolver *self, PyObject *args) {
    time_t now = 0;
    int wait = 0, maxwait = 0;

    if (!PyArg_ParseTuple(args, "i|l", &maxwait, &now)) {
        PyErr_SetString(PyExc_TypeError, "Resolver.timeouts(maxwait, now=0) takes 2 int arguments: maxwait and current timestamp.");
        return NULL;
    }

    wait = dns_timeouts(self->ctx, maxwait, now);

    return Py_BuildValue("i", wait);
}
Esempio n. 8
0
static void waitdns(struct ipcheck *ipc) {
  struct timeval tv;
  fd_set fds;
  int c;
  int fd = dns_sock(NULL);
  time_t now = 0;
  FD_ZERO(&fds);
  while((c = dns_timeouts(NULL, -1, now)) > 0) {
    FD_SET(fd, &fds);
    tv.tv_sec = c;
    tv.tv_usec = 0;
    c = select(fd+1, &fds, NULL, NULL, &tv);
    now = time(NULL);
    if (c > 0)
      dns_ioevent(NULL, now);
    if (stopfirst && ipc->listed)
      break;
  }
}
Esempio n. 9
0
void ape_gethostbyname(char *name, void (*callback)(char *, void *, acetables *), void *data, acetables *g_ape)
{
   
    struct in_addr addr;
	struct query *q;
    unsigned char dn[DNS_MAXDN];
	int abs = 0;
	enum dns_type l_qtyp = 0;

    if (dns_pton(AF_INET, name, &addr) > 0) {
		/* We have an IP */
		callback(xstrdup(name), data, g_ape);
		return;
    } else if (!dns_ptodn(name, strlen(name), dn, sizeof(dn), &abs)) {
		/* We have an invalid domain name */
		return;
	} else {
		l_qtyp = DNS_T_A;
	}
	
	q = query_new(name, dn, l_qtyp);
	
	q->data = data;
	q->callback = callback;
	q->g_ape = g_ape;
	
	if (abs) {
		abs = DNS_NOSRCH;
	}
    if (!dns_submit_dn(NULL, dn, qcls, l_qtyp, abs, 0, dnscb, q)) {
		query_free(q);
		return;
	}
	
	dns_timeouts(NULL, -1, 0);
}
Esempio n. 10
0
static int dns_invoke_timeouts(eventer_t e, int mask, void *closure,
                               struct timeval *now) {
  struct dns_ctx *ctx = closure;
  dns_timeouts(ctx, 0, now->tv_sec);
  return 0;
}
Esempio n. 11
0
static int dns_check_send(noit_module_t *self, noit_check_t *check,
                          noit_check_t *cause) {
  void *vnv_pair = NULL;
  struct dns_nameval *nv_pair;
  eventer_t newe;
  struct timeval p_int, now;
  struct dns_check_info *ci = check->closure;
  const char *config_val;
  const char *rtype = NULL;
  const char *nameserver = NULL;
  int port = 0;
  const char *port_str = NULL;
  const char *want_sort = NULL;
  const char *ctype = "IN";
  const char *query = NULL;
  char interpolated_nameserver[1024];
  char interpolated_query[1024];
  noit_hash_table check_attrs_hash = NOIT_HASH_EMPTY;

  BAIL_ON_RUNNING_CHECK(check);

  gettimeofday(&now, NULL);
  memcpy(&check->last_fire_time, &now, sizeof(now));
  ci->current.state = NP_BAD;
  ci->current.available = NP_UNAVAILABLE;
  ci->timed_out = 1;
  ci->nrr = 0;
  ci->sort = 1;

  if(!strcmp(check->name, "in-addr.arpa") ||
     (strlen(check->name) >= sizeof("::in-addr.arpa") - 1 &&
      !strcmp(check->name + strlen(check->name) - sizeof("::in-addr.arpa") + 1,
              "::in-addr.arpa"))) {
    /* in-addr.arpa defaults:
     *   nameserver to NULL
     *   rtype to PTR
     *   query to %[:inaddrarpa:target]
     */
    nameserver = NULL;
    rtype = "PTR";
    query = "%[:inaddrarpa:target_ip]";
  }
  else {
    nameserver = "%[target_ip]";
    rtype = "A";
    query = "%[name]";
  }

  if(noit_hash_retr_str(check->config, "port", strlen("port"),
                        &port_str)) {
    port = atoi(port_str);
  }

#define CONFIG_OVERRIDE(a) \
  if(noit_hash_retr_str(check->config, #a, strlen(#a), \
                        &config_val) && \
     strlen(config_val) > 0) \
    a = config_val
  CONFIG_OVERRIDE(ctype);
  CONFIG_OVERRIDE(nameserver);
  CONFIG_OVERRIDE(rtype);
  CONFIG_OVERRIDE(query);
  CONFIG_OVERRIDE(want_sort);
  if(nameserver && !strcmp(nameserver, "default")) nameserver = NULL;
  if(want_sort && strcasecmp(want_sort, "on") && strcasecmp(want_sort, "true"))
    ci->sort = 0;

  noit_check_make_attrs(check, &check_attrs_hash);

  if(nameserver) {
    noit_check_interpolate(interpolated_nameserver,
                           sizeof(interpolated_nameserver),
                           nameserver,
                           &check_attrs_hash, check->config);
    nameserver = interpolated_nameserver;
  }
  if(query) {
    noit_check_interpolate(interpolated_query,
                           sizeof(interpolated_query),
                           query,
                           &check_attrs_hash, check->config);
    query = interpolated_query;
  }
  noit_hash_destroy(&check_attrs_hash, NULL, NULL);

  check->flags |= NP_RUNNING;
  noitL(nldeb, "dns_check_send(%p,%s,%s,%s,%s,%s)\n",
        self, check->target, nameserver ? nameserver : "default",
        query ? query : "null", ctype, rtype);

  __activate_ci(ci);
  /* If this ci has a handle and it isn't the one we need,
   * we should release it
   */
  if(ci->h &&
     ((ci->h->ns == NULL && nameserver != NULL) ||
      (ci->h->ns != NULL && nameserver == NULL) ||
      (ci->h->ns && strcmp(ci->h->ns, nameserver)))) {
    dns_ctx_release(ci->h);
    ci->h = NULL;
  }
  /* use the cached one, unless we don't have one */
  if(!ci->h) ci->h = dns_ctx_alloc(nameserver, port);
  if(!ci->h) ci->error = strdup("bad nameserver");

  /* Lookup out class */
  if(!noit_hash_retrieve(&dns_ctypes, ctype, strlen(ctype),
                         &vnv_pair)) {
    if(ci->error) free(ci->error);
    ci->error = strdup("bad class");
  }
  else {
    nv_pair = (struct dns_nameval *)vnv_pair;
    ci->query_ctype = nv_pair->val;
  }
  /* Lookup out rr type */
  if(!noit_hash_retrieve(&dns_rtypes, rtype, strlen(rtype),
                         &vnv_pair)) {
    if(ci->error) free(ci->error);
    ci->error = strdup("bad rr type");
  }
  else {
    nv_pair = (struct dns_nameval *)vnv_pair;
    ci->query_rtype = nv_pair->val;
  }

  if(!ci->error) {
    /* Submit the query */
    int abs;
    if(!dns_ptodn(query, strlen(query), ci->dn, sizeof(ci->dn), &abs) ||
       !dns_submit_dn(ci->h->ctx, ci->dn, ci->query_ctype, ci->query_rtype,
                      abs | DNS_NOSRCH, NULL, dns_cb, ci)) {
      ci->error = strdup("submission error");
    }
    else {
      dns_timeouts(ci->h->ctx, -1, now.tv_sec);
    }
  }

  /* we could have completed by now... if so, we've nothing to do */

  if(!__isactive_ci(ci)) return 0;

  if(ci->error) {
    /* Errors here are easy, fail and avoid scheduling a timeout */
    ci->check->flags &= ~NP_RUNNING;
    dns_check_log_results(ci);
    __deactivate_ci(ci);
    return 0;
  }

  newe = eventer_alloc();
  newe->mask = EVENTER_TIMER;
  gettimeofday(&now, NULL);
  p_int.tv_sec = check->timeout / 1000;
  p_int.tv_usec = (check->timeout % 1000) * 1000;
  add_timeval(now, p_int, &newe->whence);
  newe->closure = ci;
  newe->callback = dns_check_timeout;
  ci->timeout_event = newe;
  eventer_add(newe);

  return 0;
}
Esempio n. 12
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();
    }
  }
}
Esempio n. 13
0
static int noit_lua_dns_timeouts(eventer_t e, int mask, void *closure,
                                 struct timeval *now) {
  dns_ctx_handle_t *h = closure;
  dns_timeouts(h->ctx, 0, now->tv_sec);
  return 0;
}
Esempio n. 14
0
static void ape_dns_timeout(void *params, int *last)
{
	dns_timeouts(NULL, -1, 0);
}