static int example_initiate(noit_module_t *self, noit_check_t *check, noit_check_t *cause) { struct example_check_info *ci = check->closure; const char *limit = "0"; struct timeval now, diff; BAIL_ON_RUNNING_CHECK(check); check->flags |= NP_RUNNING; mtev_hash_retrieve(check->config, "limit", strlen("limit"), (void **)&limit); ci->limit = atoi(limit); mtev_gettimeofday(&now, NULL); sub_timeval(now, check->last_fire_time, &diff); noit_stats_set_whence(check, &now); noit_stats_set_duration(check, diff.tv_sec * 1000 + diff.tv_usec / 1000); noit_stats_set_available(check, NP_AVAILABLE); noit_stats_set_status(check, "hello world"); if(ci->limit) { int value = (int)(lrand48() % ci->limit); noit_stats_set_metric(check, "random", METRIC_INT32, &value); noit_stats_set_state(check, NP_GOOD); } else { noit_stats_set_metric(check, "random", METRIC_INT32, NULL); noit_stats_set_state(check, NP_BAD); } noit_check_set_stats(check); check->flags &= ~NP_RUNNING; return 0; }
static int selfcheck_initiate(noit_module_t *self, noit_check_t *check, noit_check_t *cause) { selfcheck_info_t *ci = check->closure; struct timeval __now; /* We cannot be running */ BAIL_ON_RUNNING_CHECK(check); check->flags |= NP_RUNNING; ci->self = self; ci->check = check; ci->timed_out = 1; noit_check_make_attrs(check, &ci->attrs); gettimeofday(&__now, NULL); memcpy(&check->last_fire_time, &__now, sizeof(__now)); /* Register a handler for the worker */ noit_check_run_full_asynch(check, selfcheck_log_size); return 0; }
static int test_abort_initiate(noit_module_t *self, noit_check_t *check, noit_check_t *cause) { test_abort_check_info_t *ci = check->closure; struct timeval __now; const char *v; noitL(nlerr, "test_abort_initiate\n"); /* We cannot be running */ BAIL_ON_RUNNING_CHECK(check); check->flags |= NP_RUNNING; ci->self = self; ci->check = check; ci->timeout = 30; if(noit_hash_retr_str(check->config, "sleep", strlen("sleep"), &v)) { ci->timeout = atof(v); } ci->ignore_signals = 0; if(noit_hash_retr_str(check->config, "ignore_signals", strlen("ignore_signals"), &v)) { if(!strcmp(v, "true")) ci->ignore_signals = 1; } ci->timed_out = 1; ci->method = 0; if(noit_hash_retr_str(check->config, "method", strlen("method"), &v)) { if(!strcmp(v, "evil")) ci->method = EVENTER_EVIL_BRUTAL; else if(!strcmp(v, "deferred")) ci->method = EVENTER_CANCEL_DEFERRED; else if(!strcmp(v, "asynch")) ci->method = EVENTER_CANCEL_ASYNCH; } gettimeofday(&__now, NULL); memcpy(&check->last_fire_time, &__now, sizeof(__now)); /* Register a handler for the worker */ noit_check_run_full_asynch_opts(check, test_abort_drive_session, ci->method); return 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; }
static int ssh2_initiate(noit_module_t *self, noit_check_t *check, noit_check_t *cause) { ssh2_check_info_t *ci = check->closure; struct timeval p_int, __now; int fd = -1, rv = -1; eventer_t e; union { struct sockaddr_in sin; struct sockaddr_in6 sin6; } sockaddr; socklen_t sockaddr_len; unsigned short ssh_port = DEFAULT_SSH_PORT; const char *port_str = NULL; /* We cannot be running */ BAIL_ON_RUNNING_CHECK(check); check->flags |= NP_RUNNING; ci->self = self; ci->check = check; ci->timed_out = 1; if(ci->timeout_event) { eventer_remove(ci->timeout_event); free(ci->timeout_event->closure); eventer_free(ci->timeout_event); ci->timeout_event = NULL; } gettimeofday(&__now, NULL); memcpy(&check->last_fire_time, &__now, sizeof(__now)); if(check->target_ip[0] == '\0') { ci->error = strdup("name resolution failure"); goto fail; } /* Open a socket */ fd = socket(check->target_family, NE_SOCK_CLOEXEC|SOCK_STREAM, 0); if(fd < 0) goto fail; /* Make it non-blocking */ if(eventer_set_fd_nonblocking(fd)) goto fail; if(noit_hash_retr_str(check->config, "port", strlen("port"), &port_str)) { ssh_port = (unsigned short)atoi(port_str); } #define config_method(a) do { \ const char *v; \ if(noit_hash_retr_str(check->config, "method_" #a, strlen("method_" #a), \ &v)) \ ci->methods.a = strdup(v); \ } while(0) config_method(kex); config_method(hostkey); config_method(crypt_cs); config_method(crypt_sc); config_method(mac_cs); config_method(mac_sc); config_method(comp_cs); config_method(comp_sc); memset(&sockaddr, 0, sizeof(sockaddr)); sockaddr.sin6.sin6_family = check->target_family; if(check->target_family == AF_INET) { memcpy(&sockaddr.sin.sin_addr, &check->target_addr.addr, sizeof(sockaddr.sin.sin_addr)); sockaddr.sin.sin_port = htons(ssh_port); sockaddr_len = sizeof(sockaddr.sin); } else { memcpy(&sockaddr.sin6.sin6_addr, &check->target_addr.addr6, sizeof(sockaddr.sin6.sin6_addr)); sockaddr.sin6.sin6_port = htons(ssh_port); sockaddr_len = sizeof(sockaddr.sin6); } /* Initiate a connection */ rv = connect(fd, (struct sockaddr *)&sockaddr, sockaddr_len); if(rv == -1 && errno != EINPROGRESS) goto fail; /* Register a handler for connection completion */ e = eventer_alloc(); e->fd = fd; e->mask = EVENTER_READ | EVENTER_WRITE | EVENTER_EXCEPTION; e->callback = ssh2_connect_complete; e->closure = ci; ci->synch_fd_event = e; eventer_add(e); e = eventer_alloc(); e->mask = EVENTER_TIMER; e->callback = ssh2_connect_timeout; e->closure = ci; memcpy(&e->whence, &__now, sizeof(__now)); p_int.tv_sec = check->timeout / 1000; p_int.tv_usec = (check->timeout % 1000) * 1000; add_timeval(e->whence, p_int, &e->whence); ci->timeout_event = e; eventer_add(e); return 0; fail: if(fd >= 0) close(fd); ssh2_log_results(ci->self, ci->check); ssh2_cleanup(ci->self, ci->check); check->flags &= ~NP_RUNNING; return -1; }