static int dns_module_init(noit_module_t *self) { const struct dns_nameval *nv; struct dns_ctx *pctx; int i; pthread_mutex_init(&dns_ctx_store_lock, NULL); pthread_mutex_init(&active_events_lock, NULL); /* HASH the rr types */ for(i=0, nv = dns_type_index(i); nv->name; nv = dns_type_index(++i)) noit_hash_store(&dns_rtypes, nv->name, strlen(nv->name), (void *)nv); /* HASH the class types */ for(i=0, nv = dns_class_index(i); nv->name; nv = dns_class_index(++i)) noit_hash_store(&dns_ctypes, nv->name, strlen(nv->name), (void *)nv); noit_check_interpolate_register_oper_fn("inaddrarpa", dns_interpolate_inaddr_arpa); noit_check_interpolate_register_oper_fn("reverseip", dns_interpolate_reverse_ip); if (dns_init(NULL, 0) < 0 || (pctx = dns_new(NULL)) == NULL) { noitL(nlerr, "Unable to initialize dns subsystem\n"); return -1; } dns_free(pctx); if(dns_ctx_alloc(NULL, 0) == NULL) { noitL(nlerr, "Error setting up default dns resolver context.\n"); return -1; } return 0; }
void noit_lua_init_dns() { int i; const struct dns_nameval *nv; struct dns_ctx *pctx; /* HASH the rr types */ for(i=0, nv = dns_type_index(i); nv->name; nv = dns_type_index(++i)) noit_hash_store(&dns_rtypes, nv->name, strlen(nv->name), (void *)nv); /* HASH the class types */ for(i=0, nv = dns_class_index(i); nv->name; nv = dns_class_index(++i)) noit_hash_store(&dns_ctypes, nv->name, strlen(nv->name), (void *)nv); eventer_name_callback("lua/dns_eventer", noit_lua_dns_eventer); eventer_name_callback("lua/dns_timeouts", noit_lua_dns_timeouts); if (dns_init(NULL, 0) < 0 || (pctx = dns_new(NULL)) == NULL) { noitL(noit_error, "Unable to initialize dns subsystem\n"); } else dns_free(pctx); }
static int dns_module_init(noit_module_t *self) { const struct dns_nameval *nv; struct dns_ctx *pctx; int i; const char *config_val; dns_mod_config_t *conf; conf = noit_module_get_userdata(self); pthread_mutex_init(&dns_ctx_store_lock, NULL); pthread_mutex_init(&active_events_lock, NULL); conf->contexts = DEFAULT_MAX_CONTEXTS; if(noit_hash_retr_str(conf->options, "contexts", strlen("contexts"), (const char**)&config_val)) { conf->contexts = atoi(config_val); if (conf->contexts <= 0) conf->contexts = DEFAULT_MAX_CONTEXTS; } /* HASH the rr types */ for(i=0, nv = dns_type_index(i); nv->name; nv = dns_type_index(++i)) noit_hash_store(&dns_rtypes, nv->name, strlen(nv->name), (void *)nv); /* HASH the class types */ for(i=0, nv = dns_class_index(i); nv->name; nv = dns_class_index(++i)) noit_hash_store(&dns_ctypes, nv->name, strlen(nv->name), (void *)nv); noit_check_interpolate_register_oper_fn("inaddrarpa", dns_interpolate_inaddr_arpa); noit_check_interpolate_register_oper_fn("reverseip", dns_interpolate_reverse_ip); if (dns_init(NULL, 0) < 0 || (pctx = dns_new(NULL)) == NULL) { noitL(nlerr, "Unable to initialize dns subsystem\n"); return -1; } dns_free(pctx); if(dns_module_dns_ctx_alloc(self, NULL, 0) == NULL) { noitL(nlerr, "Error setting up default dns resolver context.\n"); return -1; } register_console_dns_commands(); return 0; }
noit_log_stream_t noit_log_stream_new_on_fd(const char *name, int fd, noit_hash_table *config) { char *lsname; noit_log_stream_t ls; ls = calloc(1, sizeof(*ls)); ls->name = strdup(name); ls->ops = &posix_logio_ops; ls->op_ctx = (void *)(vpsized_int)fd; ls->enabled = 1; ls->config = config; ls->lock = calloc(1, sizeof(*ls->lock)); noit_log_init_rwlock(ls); /* This double strdup of ls->name is needed, look for the next one * for an explanation. */ lsname = strdup(ls->name); if(noit_hash_store(&noit_loggers, lsname, strlen(ls->name), ls) == 0) { free(lsname); free(ls->name); free(ls); return NULL; } return ls; }
void noit_control_dispatch_delegate(eventer_func_t listener_dispatch, u_int32_t cmd, eventer_func_t delegate_dispatch) { u_int32_t *cmd_copy; eventer_func_t *handler_copy; void *vdelegation_table; noit_hash_table *delegation_table; if(!noit_hash_retrieve(&listener_commands, (char *)&listener_dispatch, sizeof(listener_dispatch), &vdelegation_table)) { delegation_table = calloc(1, sizeof(*delegation_table)); handler_copy = malloc(sizeof(*handler_copy)); *handler_copy = listener_dispatch; noit_hash_store(&listener_commands, (char *)handler_copy, sizeof(*handler_copy), delegation_table); } else delegation_table = (noit_hash_table *)vdelegation_table; cmd_copy = malloc(sizeof(*cmd_copy)); *cmd_copy = cmd; handler_copy = malloc(sizeof(*handler_copy)); *handler_copy = delegate_dispatch; noit_hash_replace(delegation_table, (char *)cmd_copy, sizeof(*cmd_copy), handler_copy, free, free); }
int noit_poller_schedule(const char *target, const char *module, const char *name, const char *filterset, noit_hash_table *config, u_int32_t period, u_int32_t timeout, const char *oncheck, int flags, uuid_t in, uuid_t out) { noit_check_t *new_check; new_check = calloc(1, sizeof(*new_check)); if(!new_check) return -1; /* The module and the UUID can never be changed */ new_check->module = strdup(module); if(uuid_is_null(in)) uuid_generate(new_check->checkid); else uuid_copy(new_check->checkid, in); noit_check_update(new_check, target, name, filterset, config, period, timeout, oncheck, flags); assert(noit_hash_store(&polls, (char *)new_check->checkid, UUID_SIZE, new_check)); uuid_copy(out, new_check->checkid); return 0; }
noit_log_stream_t noit_log_stream_new(const char *name, const char *type, const char *path, void *ctx, noit_hash_table *config) { noit_log_stream_t ls, saved; struct _noit_log_stream tmpbuf; void *vops = NULL; ls = calloc(1, sizeof(*ls)); ls->name = strdup(name); ls->path = path ? strdup(path) : NULL; ls->type = type ? strdup(type) : NULL; ls->enabled = 1; ls->config = config; if(!type) ls->ops = NULL; else if(noit_hash_retrieve(&noit_logops, type, strlen(type), &vops)) ls->ops = vops; else goto freebail; if(ls->ops && ls->ops->openop(ls)) goto freebail; saved = noit_log_stream_find(name); if(saved) { pthread_rwlock_t *lock = saved->lock; memcpy(&tmpbuf, saved, sizeof(*saved)); memcpy(saved, ls, sizeof(*saved)); memcpy(ls, &tmpbuf, sizeof(*saved)); saved->lock = lock; ls->lock = NULL; noit_log_stream_free(ls); ls = saved; } else { /* We strdup the name *again*. We'going to kansas city shuffle the * ls later (see memcpy above). However, if don't strdup, then the * noit_log_stream_free up there will sweep our key right our from * under us. */ if(noit_hash_store(&noit_loggers, strdup(ls->name), strlen(ls->name), ls) == 0) goto freebail; ls->lock = calloc(1, sizeof(*ls->lock)); noit_log_init_rwlock(ls); } /* This is for things that don't open on paths */ if(ctx) ls->op_ctx = ctx; return ls; freebail: fprintf(stderr, "Failed to instantiate logger(%s,%s,%s)\n", name, type ? type : "[null]", path ? path : "[null]"); free(ls->name); if(ls->path) free(ls->path); if(ls->type) free(ls->type); free(ls); return NULL; }
noit_log_stream_t noit_log_stream_new_on_fd(const char *name, int fd, noit_hash_table *config) { char *lsname; noit_log_stream_t ls; asynch_log_ctx *actx; ls = calloc(1, sizeof(*ls)); actx = calloc(1, sizeof(*actx)); actx->name = "posix"; actx->write = posix_logio_asynch_write; actx->userdata = (void *)(vpsized_int)fd; ls->name = strdup(name); ls->ops = &posix_logio_ops; ls->op_ctx = actx; ls->flags |= NOIT_LOG_STREAM_ENABLED; ls->config = config; ls->lock = calloc(1, sizeof(*ls->lock)); noit_log_init_rwlock(ls); /* This double strdup of ls->name is needed, look for the next one * for an explanation. */ lsname = strdup(ls->name); if(noit_hash_store(&noit_loggers, lsname, strlen(ls->name), ls) == 0) { free(lsname); free(ls->name); free(ls); free(actx); return NULL; } return ls; }
static void __activate_ci(struct dns_check_info *ci) { struct dns_check_info **holder; holder = calloc(1, sizeof(*holder)); *holder = ci; pthread_mutex_lock(&active_events_lock); assert(noit_hash_store(&active_events, (void *)holder, sizeof(*holder), ci)); pthread_mutex_unlock(&active_events_lock); }
void noit_capabilities_add_feature(const char *feature, const char *version) { feature = strdup(feature); if(version) version = strdup(version); if(!noit_hash_store(&features, feature, strlen(feature), (void *)version)) noitL(noit_error, "Feature conflict! %s version %s\n", feature, version ? version : "unpecified"); }
void noit_lua_check_register_event(noit_lua_check_info_t *ci, eventer_t e) { eventer_t *eptr; eptr = calloc(1, sizeof(*eptr)); memcpy(eptr, &e, sizeof(*eptr)); if(!ci->events) ci->events = calloc(1, sizeof(*ci->events)); assert(noit_hash_store(ci->events, (const char *)eptr, sizeof(*eptr), eptr)); }
void noit_console_conf_checks_init() { int i; for(i=0;i<sizeof(valid_attrs)/sizeof(*valid_attrs);i++) { noit_hash_store(&check_attrs, valid_attrs[i].name, strlen(valid_attrs[i].name), &valid_attrs[i]); } register_console_config_check_commands(); }
jlog_feed_stats_t * noit_jlog_feed_stats(const char *sub) { void *vs = NULL; jlog_feed_stats_t *s = NULL; if(noit_hash_retrieve(&feed_stats, sub, strlen(sub), &vs)) return (jlog_feed_stats_t *)vs; s = calloc(1, sizeof(*s)); s->feed_name = strdup(sub); noit_hash_store(&feed_stats, s->feed_name, strlen(s->feed_name), s); return s; }
static dns_ctx_handle_t *dns_ctx_alloc(const char *ns, int port) { void *vh; dns_ctx_handle_t *h = NULL; pthread_mutex_lock(&dns_ctx_store_lock); if(ns == NULL && default_ctx_handle != NULL) { /* special case -- default context */ h = default_ctx_handle; noit_atomic_inc32(&h->refcnt); goto bail; } if(ns && noit_hash_retrieve(&dns_ctx_store, ns, strlen(ns), &vh)) { h = (dns_ctx_handle_t *)vh; noit_atomic_inc32(&h->refcnt); } else { int failed = 0; h = calloc(1, sizeof(*h)); h->ns = ns ? strdup(ns) : NULL; h->ctx = dns_new(NULL); if(dns_init(h->ctx, 0) != 0) failed++; if(ns) { if(dns_add_serv(h->ctx, NULL) < 0) failed++; if(dns_add_serv(h->ctx, ns) < 0) failed++; } if(port && port != DNS_PORT) { dns_set_opt(h->ctx, DNS_OPT_PORT, port); } if(dns_open(h->ctx) < 0) failed++; if(failed) { noitL(nlerr, "dns_open failed\n"); free(h->ns); free(h); h = NULL; goto bail; } dns_set_tmcbck(h->ctx, eventer_dns_utm_fn, h); h->e = eventer_alloc(); h->e->mask = EVENTER_READ | EVENTER_EXCEPTION; h->e->closure = h; h->e->callback = dns_eventer_callback; h->e->fd = dns_sock(h->ctx); eventer_add(h->e); h->refcnt = 1; if(!ns) default_ctx_handle = h; else noit_hash_store(&dns_ctx_store, h->ns, strlen(h->ns), h); } bail: pthread_mutex_unlock(&dns_ctx_store_lock); return h; }
noit_lua_check_info_t * get_ci(lua_State *L) { noit_lua_check_info_t *ci; lua_module_closure_t *lmc; void *v = NULL; if(noit_hash_retrieve(&noit_coros, (const char *)&L, sizeof(L), &v)) return (noit_lua_check_info_t *)v; ci = calloc(1, sizeof(*ci)); ci->coro_state = L; lua_getglobal(L, "noit_internal_lmc");; ci->lmc = lua_touserdata(L, lua_gettop(L)); lua_pop(L, 1); noitL(noit_error, "lmc -> %p\n", ci->lmc); noit_hash_store(&noit_coros, (const char *)&ci->coro_state, sizeof(ci->coro_state), ci); return ci; }
int noit_http_rest_register_auth(const char *method, const char *base, const char *expr, rest_request_handler f, rest_authorize_func_t auth) { void *vcont; struct rule_container *cont; struct rest_url_dispatcher *rule; const char *error; int erroffset; pcre *pcre_expr; int blen = strlen(base); /* base must end in a /, 'cause I said so */ if(blen == 0 || base[blen-1] != '/') return -1; pcre_expr = pcre_compile(expr, 0, &error, &erroffset, NULL); if(!pcre_expr) { noitL(noit_error, "Error in rest expr(%s) '%s'@%d: %s\n", base, expr, erroffset, error); return -1; } rule = calloc(1, sizeof(*rule)); rule->method = strdup(method); rule->expression = pcre_expr; rule->extra = pcre_study(rule->expression, 0, &error); rule->handler = f; rule->auth = auth; /* Make sure we have a container */ if(!noit_hash_retrieve(&dispatch_points, base, strlen(base), &vcont)) { cont = calloc(1, sizeof(*cont)); cont->base = strdup(base); noit_hash_store(&dispatch_points, cont->base, strlen(cont->base), cont); } else cont = vcont; /* Append the rule */ if(cont->rules_endptr) { cont->rules_endptr->next = rule; cont->rules_endptr = cont->rules_endptr->next; } else cont->rules = cont->rules_endptr = rule; return 0; }
struct target_session * _get_target_session(noit_module_t *self, char *target) { void *vts; struct target_session *ts; snmp_mod_config_t *conf; conf = noit_module_get_userdata(self); if(!noit_hash_retrieve(&conf->target_sessions, target, strlen(target), &vts)) { ts = calloc(1, sizeof(*ts)); ts->self = self; ts->fd = -1; ts->refcnt = 0; ts->target = strdup(target); ts->in_table = 1; noit_hash_store(&conf->target_sessions, ts->target, strlen(ts->target), ts); vts = ts; } return (struct target_session *)vts; }
struct target_session * _get_target_session(noit_module_t *self, char *target, int version) { char key[128]; void *vts; struct target_session *ts; snmp_mod_config_t *conf; conf = noit_module_get_userdata(self); snprintf(key, sizeof(key), "%s:v%d", target, version); if(!noit_hash_retrieve(&conf->target_sessions, key, strlen(key), &vts)) { ts = calloc(1, sizeof(*ts)); ts->self = self; ts->version = version; ts->fd = -1; ts->refcnt = 0; ts->target = strdup(target); ts->key = strdup(key); ts->in_table = 1; noit_hash_store(&conf->target_sessions, ts->key, strlen(ts->key), ts); vts = ts; } return (struct target_session *)vts; }
static int storage_node_quick_lookup(const char *uuid_str, const char *remote_cn, int *sid_out, int *storagenode_id_out, const char **remote_cn_out, const char **fqdn_out, const char **dsn_out) { /* only called from the main thread -- no safety issues */ void *vstr; const char *actual_remote_cn = NULL; if(remote_cn) actual_remote_cn = remote_cn; uuid_t id; uuid_parse((char *)uuid_str, id); if(noit_hash_retrieve(&uuid_map, (const char *)id, UUID_SIZE, &vstr)) { char *str = (char *)vstr; if(remote_cn && strcmp(str, remote_cn)) { /* replace with new remote */ void *key = malloc(UUID_SIZE); memcpy(key, id, UUID_SIZE); actual_remote_cn = strdup(remote_cn); noit_hash_replace(&uuid_map, key, UUID_SIZE, (void *)actual_remote_cn, free, free); } } else if(remote_cn) { void *key = malloc(UUID_SIZE); memcpy(key, id, UUID_SIZE); noit_hash_store(&uuid_map, key, UUID_SIZE, strdup(remote_cn)); } if(!actual_remote_cn) actual_remote_cn = "[[null]]"; if(sid_out) *sid_out = 0; if(storagenode_id_out) *storagenode_id_out = 0; if(remote_cn_out) *remote_cn_out = actual_remote_cn; if(fqdn_out) *fqdn_out = ""; if(dsn_out) *dsn_out = ""; return 0; }
static int external_invoke(noit_module_t *self, noit_check_t *check, noit_check_t *cause) { struct timeval when, p_int; external_closure_t *ecl; struct check_info *ci = (struct check_info *)check->closure; eventer_t newe; external_data_t *data; noit_hash_table check_attrs_hash = NOIT_HASH_EMPTY; int i, klen; noit_hash_iter iter = NOIT_HASH_ITER_ZERO; const char *name, *value; char interp_fmt[4096], interp_buff[4096]; data = noit_module_get_userdata(self); check->flags |= NP_RUNNING; noitL(data->nldeb, "external_invoke(%p,%s)\n", self, check->target); /* remove a timeout if we still have one -- we should unless someone * has set a lower timeout than the period. */ if(ci->timeout_event) { eventer_remove(ci->timeout_event); free(ci->timeout_event->closure); eventer_free(ci->timeout_event); ci->timeout_event = NULL; } check_info_clean(ci); gettimeofday(&when, NULL); memcpy(&check->last_fire_time, &when, sizeof(when)); /* Setup all our check bits */ ci->check_no = noit_atomic_inc64(&data->check_no_seq); ci->check = check; /* We might want to extract metrics */ if(noit_hash_retr_str(check->config, "output_extract", strlen("output_extract"), &value) != 0) { const char *error; int erroffset; ci->matcher = pcre_compile(value, 0, &error, &erroffset, NULL); if(!ci->matcher) { noitL(data->nlerr, "external pcre /%s/ failed @ %d: %s\n", value, erroffset, error); } } noit_check_make_attrs(check, &check_attrs_hash); /* Count the args */ i = 1; while(1) { char argname[10]; snprintf(argname, sizeof(argname), "arg%d", i); if(noit_hash_retr_str(check->config, argname, strlen(argname), &value) == 0) break; i++; } ci->argcnt = i + 1; /* path, arg0, (i-1 more args) */ ci->arglens = calloc(ci->argcnt, sizeof(*ci->arglens)); ci->args = calloc(ci->argcnt, sizeof(*ci->args)); /* Make the command */ if(noit_hash_retr_str(check->config, "command", strlen("command"), &value) == 0) { value = "/bin/true"; } ci->args[0] = strdup(value); ci->arglens[0] = strlen(ci->args[0]) + 1; i = 0; while(1) { char argname[10]; snprintf(argname, sizeof(argname), "arg%d", i); if(noit_hash_retr_str(check->config, argname, strlen(argname), &value) == 0) { if(i == 0) { /* if we don't have arg0, make it last element of path */ char *cp = ci->args[0] + strlen(ci->args[0]); while(cp > ci->args[0] && *(cp-1) != '/') cp--; value = cp; } else break; /* if we don't have argn, we're done */ } noit_check_interpolate(interp_buff, sizeof(interp_buff), value, &check_attrs_hash, check->config); ci->args[i+1] = strdup(interp_buff); ci->arglens[i+1] = strlen(ci->args[i+1]) + 1; i++; } /* Make the environment */ memset(&iter, 0, sizeof(iter)); ci->envcnt = 0; while(noit_hash_next_str(check->config, &iter, &name, &klen, &value)) if(!strncasecmp(name, "env_", 4)) ci->envcnt++; memset(&iter, 0, sizeof(iter)); ci->envlens = calloc(ci->envcnt, sizeof(*ci->envlens)); ci->envs = calloc(ci->envcnt, sizeof(*ci->envs)); ci->envcnt = 0; while(noit_hash_next_str(check->config, &iter, &name, &klen, &value)) if(!strncasecmp(name, "env_", 4)) { snprintf(interp_fmt, sizeof(interp_fmt), "%s=%s", name+4, value); noit_check_interpolate(interp_buff, sizeof(interp_buff), interp_fmt, &check_attrs_hash, check->config); ci->envs[ci->envcnt] = strdup(interp_buff); ci->envlens[ci->envcnt] = strlen(ci->envs[ci->envcnt]) + 1; ci->envcnt++; } noit_hash_destroy(&check_attrs_hash, NULL, NULL); noit_hash_store(&data->external_checks, (const char *)&ci->check_no, sizeof(ci->check_no), ci); /* Setup a timeout */ newe = eventer_alloc(); newe->mask = EVENTER_TIMER; gettimeofday(&when, NULL); p_int.tv_sec = check->timeout / 1000; p_int.tv_usec = (check->timeout % 1000) * 1000; add_timeval(when, p_int, &newe->whence); ecl = calloc(1, sizeof(*ecl)); ecl->self = self; ecl->check = check; newe->closure = ecl; newe->callback = external_timeout; eventer_add(newe); ci->timeout_event = newe; /* Setup push */ newe = eventer_alloc(); newe->mask = EVENTER_ASYNCH; add_timeval(when, p_int, &newe->whence); ecl = calloc(1, sizeof(*ecl)); ecl->self = self; ecl->check = check; newe->closure = ecl; newe->callback = external_enqueue; eventer_add(newe); return 0; }
static dns_ctx_handle_t *dns_module_dns_ctx_alloc(noit_module_t *self, const char *ns, int port) { void *vh; char *hk = NULL; dns_mod_config_t *conf = noit_module_get_userdata(self); int randkey = random() % conf->contexts; dns_ctx_handle_t *h = NULL; if(ns && *ns == '\0') ns = NULL; pthread_mutex_lock(&dns_ctx_store_lock); if(ns == NULL && default_ctx_handle != NULL) { /* special case -- default context */ h = default_ctx_handle; dns_module_dns_ctx_acquire(h); goto bail; } if (ns != NULL) { int len = snprintf(NULL, 0, "%s:%d:%d", ns, port, randkey); hk = (char *)malloc(len+1); snprintf(hk, len+1, "%s:%d:%d", ns, port, randkey); } if(ns && noit_hash_retrieve(&dns_ctx_store, hk, strlen(hk), &vh)) { h = (dns_ctx_handle_t *)vh; dns_module_dns_ctx_acquire(h); free(hk); } else { int failed = 0; h = calloc(1, sizeof(*h)); h->ns = ns ? strdup(ns) : NULL; h->ctx = dns_new(NULL); if(dns_init(h->ctx, 0) != 0) { noitL(nlerr, "dns_init failed\n"); failed++; } dns_set_dbgfn(h->ctx, dns_debug_wrap); if(ns) { if(dns_add_serv(h->ctx, NULL) < 0) { noitL(nlerr, "dns_add_serv(NULL) failed\n"); failed++; } if(dns_add_serv(h->ctx, ns) < 0) { noitL(nlerr, "dns_add_serv(%s) failed\n", ns); failed++; } } if(port && port != DNS_PORT) { dns_set_opt(h->ctx, DNS_OPT_PORT, port); } if(dns_open(h->ctx) < 0) { noitL(nlerr, "dns_open failed\n"); failed++; } if(failed) { free(h->ns); dns_free(h->ctx); free(h); free(hk); h = NULL; goto bail; } h->hkey = hk; dns_set_tmcbck(h->ctx, dns_module_eventer_dns_utm_fn, h); h->e = eventer_alloc(); h->e->mask = EVENTER_READ | EVENTER_EXCEPTION; h->e->closure = h; h->e->callback = dns_module_eventer_callback; h->e->fd = dns_sock(h->ctx); eventer_add(h->e); h->refcnt = 1; if(!ns) default_ctx_handle = h; else noit_hash_store(&dns_ctx_store, h->hkey, strlen(h->hkey), h); } bail: pthread_mutex_unlock(&dns_ctx_store_lock); return h; }
int stratcon_line_to_javascript(noit_http_session_ctx *ctx, char *in_buff, u_int32_t *inc_id) { char buffer[1024]; char *scp, *ecp, *token, *buff; int i, len, cnt; const char *v, *cb = NULL; noit_hash_table json = NOIT_HASH_EMPTY; noit_http_request *req = noit_http_session_request(ctx); char s_inc_id[42]; char **outrows = NULL; cb = noit_http_request_querystring(req, "cb"); for(v = cb; v && *v; v++) if(!((*v >= '0' && *v <= '9') || (*v >= 'a' && *v <= 'z') || (*v >= 'A' && *v <= 'Z') || (*v == '_') || (*v == '.'))) { cb = NULL; break; } if(!cb) cb = "window.parent.plot_iframe_data"; #define BAIL_HTTP_WRITE do { \ if(outrows) { \ for(i=0;i<cnt;i++) if(outrows[i]) free(outrows[i]); \ free(outrows); \ } \ noit_hash_destroy(&json, NULL, free); \ noitL(noit_error, "javascript emit failed: %s:%s:%d\n", \ __FILE__, __FUNCTION__, __LINE__); \ return -1; \ } while(0) #define PROCESS_NEXT_FIELD(t,l) do { \ if(!*scp) goto bad_row; \ ecp = strchr(scp, '\t'); \ if(!ecp) goto bad_row; \ t = scp; \ l = (ecp-scp); \ scp = ecp + 1; \ } while(0) #define PROCESS_LAST_FIELD(t,l) do { \ if(!*scp) ecp = scp; \ else { \ ecp = scp + strlen(scp); /* Puts us at the '\0' */ \ if(*(ecp-1) == '\n') ecp--; /* We back up on letter if we ended in \n */ \ } \ t = scp; \ l = (ecp-scp); \ } while(0) noitL(noit_error, "recv(%s)\n", in_buff); if(in_buff[0] == 'B' && in_buff[1] != '\0' && in_buff[2] == '\t') { cnt = noit_check_log_b_to_sm(in_buff, strlen(in_buff), &outrows); } else { cnt = 1; outrows = malloc(sizeof(*outrows)); outrows[0] = strdup(in_buff); } for(i=0; i<cnt; i++) { buff = outrows[i]; if(!buff) continue; noitL(noit_error, "recv_xlt(%s)\n", buff); scp = buff; PROCESS_NEXT_FIELD(token,len); /* Skip the leader */ if(buff[1] == '\t' && (buff[0] == 'M' || buff[0] == 'S')) { char target[256], module[256], name[256], uuid_str[UUID_STR_LEN+1]; noit_http_request *req = noit_http_session_request(ctx); noit_hash_table *qs; noit_hash_iter iter = NOIT_HASH_ITER_ZERO; const char *key; int klen, i=0; void *vval; char type[2] = { '\0', '\0' }; type[0] = buff[0]; #define ra_write(a,b) if(noit_http_response_append(ctx, a, b) == noit_false) BAIL_HTTP_WRITE snprintf(s_inc_id, sizeof(s_inc_id), "script-%08x", (*inc_id)++); snprintf(buffer, sizeof(buffer), "<script id=\"%s\">%s({", s_inc_id, cb); ra_write(buffer, strlen(buffer)); qs = noit_http_request_querystring_table(req); while(noit_hash_next(qs, &iter, &key, &klen, &vval)) { if(!strcmp(key, "cb")) continue; noit_hash_store(&json, key, klen, strdup(vval ?(char *)vval : "true")); } /* Time */ noit_hash_store(&json, "script_id", 9, strdup(s_inc_id)); noit_hash_store(&json, "type", 4, strdup(type)); PROCESS_NEXT_FIELD(token,len); noit_hash_store(&json, "time", 4, noit__strndup(token, len)); /* UUID */ PROCESS_NEXT_FIELD(token,len); noit_check_extended_id_split(token, len, target, sizeof(target), module, sizeof(module), name, sizeof(name), uuid_str, sizeof(uuid_str)); if(*uuid_str) noit_hash_store(&json, "id", 2, noit__strndup(uuid_str, strlen(uuid_str))); if(*target) noit_hash_store(&json, "check_target", 12, noit__strndup(target, strlen(target))); if(*module) noit_hash_store(&json, "check_module", 12, noit__strndup(module, strlen(module))); if(*name) noit_hash_store(&json, "check_name", 10, noit__strndup(name, strlen(name))); if(buff[0] == 'M') { /* name */ PROCESS_NEXT_FIELD(token,len); noit_hash_store(&json, "metric_name", 11, noit__strndup(token, len)); /* type */ PROCESS_NEXT_FIELD(token,len); noit_hash_store(&json, "metric_type", 11, noit__strndup(token, len)); /* value */ PROCESS_LAST_FIELD(token,len); /* value */ noit_hash_store(&json, "value", 5, noit__strndup(token, len)); } else if(buff[0] == 'S') { /* state */ PROCESS_NEXT_FIELD(token,len); noit_hash_store(&json, "check_state", 11, noit__strndup(token, len)); /* availability */ PROCESS_NEXT_FIELD(token,len); noit_hash_store(&json, "check_availability", 18, noit__strndup(token, len)); /* duration */ PROCESS_NEXT_FIELD(token,len); noit_hash_store(&json, "check_duration_ms", 17, noit__strndup(token, len)); /* status */ PROCESS_LAST_FIELD(token,len); noit_hash_store(&json, "status_message", 14, noit__strndup(token, len)); } memset(&iter, 0, sizeof(iter)); while(noit_hash_next(&json, &iter, &key, &klen, &vval)) { char *val = (char *)vval; if(i++) ra_write(",", 1); ra_write("\"", 1); ra_write(key, klen); ra_write("\":\"", 3); while(*val) { if(*val == '\"' || *val == '\\') { ra_write((char *)"\\", 1); } if(isprint(*val)) { ra_write((char *)val, 1); } else { char od[5]; snprintf(od, sizeof(od), "\\%03o", *((unsigned char *)val)); ra_write(od, strlen(od)); } val++; } ra_write("\"", 1); } snprintf(buffer, sizeof(buffer), "});</script>\n"); ra_write(buffer, strlen(buffer)); if(noit_http_response_flush(ctx, noit_false) == noit_false) BAIL_HTTP_WRITE; } noit_hash_destroy(&json, NULL, free); memset(&json, 0, sizeof(json)); } if(outrows) { for(i=0;i<cnt;i++) if(outrows[i]) free(outrows[i]); free(outrows); } return 0; bad_row: BAIL_HTTP_WRITE; }
static void add_check(struct check_info *c) { noit_hash_store(&active_checks, (char *)&c->reqid, sizeof(c->reqid), c); }
void noit_register_logops(const char *name, logops_t *ops) { noit_hash_store(&noit_logops, strdup(name), strlen(name), ops); }
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; }
int stratcon_line_to_javascript(noit_http_session_ctx *ctx, char *buff, u_int32_t inc_id) { char buffer[1024]; char *scp, *ecp, *token; int len; void *vcb; const char *v, *cb = NULL; noit_hash_table json = NOIT_HASH_EMPTY; char s_inc_id[42]; snprintf(s_inc_id, sizeof(s_inc_id), "script-%08x", inc_id); if(noit_hash_retrieve(&ctx->req.querystring, "cb", strlen("cb"), &vcb)) cb = vcb; for(v = cb; v && *v; v++) if(!((*v >= '0' && *v <= '9') || (*v >= 'a' && *v <= 'z') || (*v >= 'A' && *v <= 'Z') || (*v == '_') || (*v == '.'))) { cb = NULL; break; } if(!cb) cb = "window.parent.plot_iframe_data"; #define BAIL_HTTP_WRITE do { \ noit_hash_destroy(&json, NULL, free); \ noitL(noit_error, "javascript emit failed: %s:%s:%d\n", \ __FILE__, __FUNCTION__, __LINE__); \ return -1; \ } while(0) #define PROCESS_NEXT_FIELD(t,l) do { \ if(!*scp) goto bad_row; \ ecp = strchr(scp, '\t'); \ if(!ecp) goto bad_row; \ t = scp; \ l = (ecp-scp); \ scp = ecp + 1; \ } while(0) #define PROCESS_LAST_FIELD(t,l) do { \ if(!*scp) ecp = scp; \ else { \ ecp = scp + strlen(scp); /* Puts us at the '\0' */ \ if(*(ecp-1) == '\n') ecp--; /* We back up on letter if we ended in \n */ \ } \ t = scp; \ l = (ecp-scp); \ } while(0) scp = buff; PROCESS_NEXT_FIELD(token,len); /* Skip the leader */ if(buff[0] == 'M') { noit_hash_iter iter = NOIT_HASH_ITER_ZERO; const char *key; int klen, i=0; void *vval; #define ra_write(a,b) if(noit_http_response_append(ctx, a, b) == noit_false) BAIL_HTTP_WRITE snprintf(buffer, sizeof(buffer), "<script id=\"%s\">%s({", s_inc_id, cb); ra_write(buffer, strlen(buffer)); while(noit_hash_next(&ctx->req.querystring, &iter, &key, &klen, &vval)) { if(!strcmp(key, "cb")) continue; noit_hash_store(&json, key, klen, strdup(vval ?(char *)vval : "true")); } /* Time */ noit_hash_store(&json, "script_id", 9, strdup(s_inc_id)); noit_hash_store(&json, "type", 4, strdup("M")); PROCESS_NEXT_FIELD(token,len); noit_hash_store(&json, "time", 4, noit__strndup(token, len)); /* UUID */ PROCESS_NEXT_FIELD(token,len); noit_hash_store(&json, "id", 2, noit__strndup(token, len)); /* name */ PROCESS_NEXT_FIELD(token,len); noit_hash_store(&json, "metric_name", 11, noit__strndup(token, len)); /* type */ PROCESS_NEXT_FIELD(token,len); noit_hash_store(&json, "metric_type", 11, noit__strndup(token, len)); /* value */ PROCESS_LAST_FIELD(token,len); /* value */ noit_hash_store(&json, "value", 5, noit__strndup(token, len)); memset(&iter, 0, sizeof(iter)); while(noit_hash_next(&json, &iter, &key, &klen, &vval)) { char *val = (char *)vval; if(i++) ra_write(",", 1); ra_write("'", 1); ra_write(key, klen); ra_write("':\"", 3); while(*val) { if(*val == '\"' || *val == '\\') { ra_write((char *)"\\", 1); } if(isprint(*val)) { ra_write((char *)val, 1); } else { char od[5]; snprintf(od, sizeof(od), "\\%03o", *((unsigned char *)val)); ra_write(od, strlen(od)); } val++; } ra_write("\"", 1); } snprintf(buffer, sizeof(buffer), "});</script>\n"); ra_write(buffer, strlen(buffer)); if(noit_http_response_flush(ctx, noit_false) == noit_false) BAIL_HTTP_WRITE; } noit_hash_destroy(&json, NULL, free); return 0; bad_row: BAIL_HTTP_WRITE; }
static interim_journal_t * interim_journal_get(struct sockaddr *remote, const char *remote_cn_in, int storagenode_id, const char *fqdn_in) { void *vhash, *vij; noit_hash_table *working_set; interim_journal_t *ij; struct timeval now; char jpath[PATH_MAX]; char remote_str[128]; const char *remote_cn = remote_cn_in ? remote_cn_in : "default"; const char *fqdn = fqdn_in ? fqdn_in : "default"; noit_convert_sockaddr_to_buff(remote_str, sizeof(remote_str), remote); if(!*remote_str) strlcpy(remote_str, "default", sizeof(remote_str)); /* Lookup the working set */ if(!noit_hash_retrieve(&working_sets, remote_cn, strlen(remote_cn), &vhash)) { working_set = calloc(1, sizeof(*working_set)); noit_hash_store(&working_sets, strdup(remote_cn), strlen(remote_cn), working_set); } else working_set = vhash; /* Lookup the interim journal within the working set */ if(!noit_hash_retrieve(working_set, fqdn, strlen(fqdn), &vij)) { ij = calloc(1, sizeof(*ij)); gettimeofday(&now, NULL); snprintf(jpath, sizeof(jpath), "%s/%s/%s/%d/%08x%08x.tmp", basejpath, remote_str, remote_cn, storagenode_id, (unsigned int)now.tv_sec, (unsigned int)now.tv_usec); ij->remote_str = strdup(remote_str); ij->remote_cn = strdup(remote_cn); ij->fqdn = fqdn_in ? strdup(fqdn_in) : NULL; ij->storagenode_id = storagenode_id; ij->filename = strdup(jpath); ij->fd = open(ij->filename, O_RDWR | O_CREAT | O_EXCL, 0640); if(ij->fd < 0 && errno == ENOENT) { if(mkdir_for_file(ij->filename, 0750)) { noitL(noit_error, "Failed to create dir for '%s': %s\n", ij->filename, strerror(errno)); exit(-1); } ij->fd = open(ij->filename, O_RDWR | O_CREAT | O_EXCL, 0640); } if(ij->fd < 0 && errno == EEXIST) { /* This can only occur if we crash after before checkpointing */ unlink(ij->filename); ij->fd = open(ij->filename, O_RDWR | O_CREAT | O_EXCL, 0640); } if(ij->fd < 0) { noitL(noit_error, "Failed to open interim journal '%s': %s\n", ij->filename, strerror(errno)); exit(-1); } noit_hash_store(working_set, strdup(fqdn), strlen(fqdn), ij); } else ij = vij; return ij; }