void storage_free(storage_t st) { /* close down drivers */ xhash_walk(st->drivers, _st_driver_reaper, NULL); xhash_free(st->drivers); xhash_free(st->types); free(st); }
static void _s2s_dns_expiry(s2s_t s2s) { time_t now; char *key; dnscache_t dns = NULL; dnsres_t res = NULL; union xhashv xhv; now = time(NULL); /* dnscache timeouts */ if(xhash_iter_first(s2s->dnscache)) do { xhv.dns_val = &dns; xhash_iter_get(s2s->dnscache, (const char **) &key, NULL, xhv.val); if (dns && !dns->pending && now > dns->expiry) { log_debug(ZONE, "expiring DNS cache for %s", dns->name); xhash_iter_zap(s2s->dnscache); xhash_free(dns->results); if (dns->query != NULL) { if (dns->query->query != NULL) dns_cancel(NULL, dns->query->query); xhash_free(dns->query->hosts); xhash_free(dns->query->results); free(dns->query->name); free(dns->query); } free(dns); } else if (dns == NULL) { xhash_iter_zap(s2s->dnscache); } } while(xhash_iter_next(s2s->dnscache)); if(xhash_iter_first(s2s->dns_bad)) do { xhv.dnsres_val = &res; xhash_iter_get(s2s->dns_bad, (const char **) &key, NULL, xhv.val); if (res && now > res->expiry) { log_debug(ZONE, "expiring DNS bad host %s", res->key); xhash_iter_zap(s2s->dns_bad); free(res->key); free(res); } else if (res == NULL) { xhash_iter_zap(s2s->dns_bad); } } while(xhash_iter_next(s2s->dns_bad)); }
void at_shutdown(void *arg) { ati ti = (ati)arg; xhash_walk(ti->session__list, &_at_shutdown, (void*)ti); xhash_free(ti->session__list); }
void dnsrv_shutdown(void *arg) { dns_io di=(dns_io)arg; xhash_free(di->packet_table); /* spawn a thread that get's forked, and wait for it since it sets up the fd's */ }
/* * init_node_conf - initialize the node configuration tables and values. * this should be called before creating any node or configuration * entries. * RET 0 if no error, otherwise an error code */ extern int init_node_conf (void) { last_node_update = time (NULL); int i; struct node_record *node_ptr; node_ptr = node_record_table_ptr; for (i = 0; i < node_record_count; i++, node_ptr++) purge_node_rec(node_ptr); node_record_count = 0; xfree(node_record_table_ptr); xhash_free(node_hash_table); if (config_list) /* delete defunct configuration entries */ (void) _delete_config_record (); else { config_list = list_create (_list_delete_config); active_feature_list = list_create (_list_delete_feature); avail_feature_list = list_create (_list_delete_feature); front_end_list = list_create (destroy_frontend); } return SLURM_SUCCESS; }
void user_table_unload(router_t r) { if(r->users != NULL) xhash_free(r->users); r->users = NULL; return; }
void entity_free(entity_t* entity) { if (entity) { xfree(entity->name); xfree(entity->type); xhash_free(entity->data); list_destroy(entity->nodes); } }
/** cleanup */ void config_free(config_t c) { xhash_walk(c->hash, _config_reaper, NULL); xhash_free(c->hash); nad_free(c->nad); free(c); }
/** free the roster */ static void _roster_free(user_t user) { if(user->roster == NULL) return; log_debug(ZONE, "freeing roster for %s", jid_user(user->jid)); xhash_walk(user->roster, _roster_free_walker, NULL); xhash_free(user->roster); user->roster = NULL; }
END_TEST START_TEST(test_count) { xhash_t* ht = g_ht; hashable_t a[4] = {{"0", 0}, {"1", 1}, {"2", 2}, {"3", 3}}; fail_unless(xhash_count(ht) == g_hashableslen, "invalid count (fixture table)"); ht = xhash_init(hashable_identify, NULL, NULL, 0); xhash_add(ht, a); xhash_add(ht, a+1); xhash_add(ht, a+2); xhash_add(ht, a+3); fail_unless(xhash_count(ht) == 4, "invalid count (fresh table)"); xhash_free(ht); }
/* node_fini2 - free memory associated with node records (except bitmaps) */ extern void node_fini2 (void) { int i; struct node_record *node_ptr; if (config_list) { FREE_NULL_LIST(config_list); FREE_NULL_LIST(front_end_list); } xhash_free(node_hash_table); node_ptr = node_record_table_ptr; for (i = 0; i < node_record_count; i++, node_ptr++) purge_node_rec(node_ptr); xfree(node_record_table_ptr); node_record_count = 0; }
/** unload aci table */ void aci_unload(xht aci) { aci_user_t list, user; /* free list of users for each acl*/ if(xhash_iter_first(aci)) do { xhash_iter_get(aci, NULL, NULL, (void *) &list); while (list != NULL) { user = list; list = list->next; free(user->name); free(user); } } while(xhash_iter_next(aci)); xhash_free(aci); return; }
/* * rehash_node - build a hash table of the node_record entries. * NOTE: using xhash implementation */ extern void rehash_node (void) { int i; struct node_record *node_ptr = node_record_table_ptr; xhash_free (node_hash_table); node_hash_table = xhash_init(node_record_hash_identity, NULL, NULL, 0); for (i = 0; i < node_record_count; i++, node_ptr++) { if ((node_ptr->name == NULL) || (node_ptr->name[0] == '\0')) continue; /* vestigial record */ xhash_add(node_hash_table, node_ptr); } #if _DEBUG _dump_hash(); #endif return; }
END_TEST START_TEST(test_add) { xhash_t* ht = NULL; hashable_t a[4] = {{"0", 0}, {"1", 1}, {"2", 2}, {"3", 3}}; int i, len = sizeof(a)/sizeof(a[0]); char buffer[255]; ht = xhash_init(hashable_identify, NULL, NULL, 0); fail_unless(xhash_add(NULL, a) == NULL, "invalid cases not null"); fail_unless(xhash_add(ht, NULL) == NULL, "invalid cases not null"); fail_unless(xhash_add(ht, a) != NULL, "xhash_add failed"); fail_unless(xhash_add(ht, a+1) != NULL, "xhash_add failed"); fail_unless(xhash_add(ht, a+2) != NULL, "xhash_add failed"); fail_unless(xhash_add(ht, a+3) != NULL, "xhash_add failed"); for (i = 0; i < len; ++i) { snprintf(buffer, sizeof(buffer), "%d", i); fail_unless(xhash_get(ht, buffer) == (a + i), "bad hashable item returned"); } xhash_free(ht); }
/* node_fini2 - free memory associated with node records (except bitmaps) */ extern void node_fini2 (void) { int i; struct node_record *node_ptr; if (config_list) { list_destroy(config_list); config_list = NULL; list_destroy(feature_list); feature_list = NULL; list_destroy(front_end_list); front_end_list = NULL; } xhash_free(node_hash_table); node_ptr = node_record_table_ptr; for (i = 0; i < node_record_count; i++, node_ptr++) purge_node_rec(node_ptr); xfree(node_record_table_ptr); node_record_count = 0; }
static void _s2s_time_checks(s2s_t s2s) { conn_t conn; time_t now; char *rkey, *key; int keylen; jqueue_t q; dnscache_t dns; char *c; int c_len; union xhashv xhv; now = time(NULL); /* queue expiry */ if(s2s->check_queue > 0) { if(xhash_iter_first(s2s->outq)) do { xhv.jq_val = &q; xhash_iter_get(s2s->outq, (const char **) &rkey, &keylen, xhv.val); log_debug(ZONE, "running time checks for %.*s", keylen, rkey); c = memchr(rkey, '/', keylen); c++; c_len = keylen - (c - rkey); /* dns lookup timeout check first */ dns = xhash_getx(s2s->dnscache, c, c_len); if(dns != NULL && dns->pending) { log_debug(ZONE, "dns lookup pending for %.*s", c_len, c); if(now > dns->init_time + s2s->check_queue) { log_write(s2s->log, LOG_NOTICE, "dns lookup for %.*s timed out", c_len, c); /* bounce queue */ out_bounce_route_queue(s2s, rkey, keylen, stanza_err_REMOTE_SERVER_NOT_FOUND); /* expire pending dns entry */ xhash_zap(s2s->dnscache, dns->name); xhash_free(dns->results); if (dns->query != NULL) { if (dns->query->query != NULL) dns_cancel(NULL, dns->query->query); xhash_free(dns->query->hosts); xhash_free(dns->query->results); free(dns->query->name); free(dns->query); } free(dns); } continue; } /* get the conn */ conn = xhash_getx(s2s->out_dest, c, c_len); if(conn == NULL) { if(jqueue_size(q) > 0) { /* no pending conn? perhaps it failed? */ log_debug(ZONE, "no pending connection for %.*s, bouncing %i packets in queue", c_len, c, jqueue_size(q)); /* bounce queue */ out_bounce_route_queue(s2s, rkey, keylen, stanza_err_REMOTE_SERVER_TIMEOUT); } continue; } /* connect timeout check */ if(!conn->online && now > conn->init_time + s2s->check_queue) { dnsres_t bad; char *ipport; log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] connection to %s timed out", conn->fd->fd, conn->ip, conn->port, c); if (s2s->dns_bad_timeout > 0) { /* mark this host as bad */ ipport = dns_make_ipport(conn->ip, conn->port); bad = xhash_get(s2s->dns_bad, ipport); if (bad == NULL) { bad = (dnsres_t) calloc(1, sizeof(struct dnsres_st)); bad->key = ipport; xhash_put(s2s->dns_bad, ipport, bad); } else { free(ipport); } bad->expiry = time(NULL) + s2s->dns_bad_timeout; } /* close connection as per XMPP/RFC3920 */ /* the close function will retry or bounce the queue */ sx_close(conn->s); } } while(xhash_iter_next(s2s->outq)); } /* expiry of connected routes in conn_INPROGRESS state */ if(s2s->check_queue > 0) { /* outgoing connections */ if(s2s->out_reuse) { if(xhash_iter_first(s2s->out_host)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->out_host, (const char **) &key, &keylen, xhv.val); log_debug(ZONE, "checking dialback state for outgoing conn %.*s", keylen, key); if (_s2s_check_conn_routes(s2s, conn, "outgoing")) { log_debug(ZONE, "checking pending verify requests for outgoing conn %.*s", keylen, key); if (conn->verify > 0 && now > conn->last_verify + s2s->check_queue) { log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] dialback verify request timed out", conn->fd->fd, conn->ip, conn->port); sx_error(conn->s, stream_err_CONNECTION_TIMEOUT, "dialback verify request timed out"); sx_close(conn->s); } } } while(xhash_iter_next(s2s->out_host)); } else { if(xhash_iter_first(s2s->out_dest)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->out_dest, (const char **) &key, &keylen, xhv.val); log_debug(ZONE, "checking dialback state for outgoing conn %s (%s)", conn->dkey, conn->key); if (_s2s_check_conn_routes(s2s, conn, "outgoing")) { log_debug(ZONE, "checking pending verify requests for outgoing conn %s (%s)", conn->dkey, conn->key); if (conn->verify > 0 && now > conn->last_verify + s2s->check_queue) { log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] dialback verify request timed out", conn->fd->fd, conn->ip, conn->port); sx_error(conn->s, stream_err_CONNECTION_TIMEOUT, "dialback verify request timed out"); sx_close(conn->s); } } } while(xhash_iter_next(s2s->out_dest)); } /* incoming open streams */ if(xhash_iter_first(s2s->in)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->in, (const char **) &key, &keylen, xhv.val); log_debug(ZONE, "checking dialback state for incoming conn %.*s", keylen, key); if (_s2s_check_conn_routes(s2s, conn, "incoming")) /* if the connection is still valid, check that dialbacks have been initiated */ if(!xhash_count(conn->states) && now > conn->init_time + s2s->check_queue) { log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] no dialback started", conn->fd->fd, conn->ip, conn->port); sx_error(conn->s, stream_err_CONNECTION_TIMEOUT, "no dialback initiated"); sx_close(conn->s); } } while(xhash_iter_next(s2s->in)); /* incoming open connections (not yet streams) */ if(xhash_iter_first(s2s->in_accept)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->in_accept, (const char **) &key, &keylen, xhv.val); log_debug(ZONE, "checking stream connection state for incoming conn %i", conn->fd->fd); if(!conn->online && now > conn->init_time + s2s->check_queue) { log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] stream initiation timed out", conn->fd->fd, conn->ip, conn->port); sx_close(conn->s); } } while(xhash_iter_next(s2s->in_accept)); } /* keepalives */ if(s2s->out_reuse) { if(xhash_iter_first(s2s->out_host)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->out_host, NULL, NULL, xhv.val); if(s2s->check_keepalive > 0 && conn->last_activity > 0 && now > conn->last_activity + s2s->check_keepalive && conn->s->state >= state_STREAM) { log_debug(ZONE, "sending keepalive for %d", conn->fd->fd); sx_raw_write(conn->s, " ", 1); } } while(xhash_iter_next(s2s->out_host)); } else { if(xhash_iter_first(s2s->out_dest)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->out_dest, NULL, NULL, xhv.val); if(s2s->check_keepalive > 0 && conn->last_activity > 0 && now > conn->last_activity + s2s->check_keepalive && conn->s->state >= state_STREAM) { log_debug(ZONE, "sending keepalive for %d", conn->fd->fd); sx_raw_write(conn->s, " ", 1); } } while(xhash_iter_next(s2s->out_dest)); } /* idle timeouts - disconnect connections through which no packets have been sent for <idle> seconds */ if(s2s->check_idle > 0) { /* outgoing connections */ if(s2s->out_reuse) { if(xhash_iter_first(s2s->out_host)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->out_host, (const char **) &key, &keylen, xhv.val); log_debug(ZONE, "checking idle state for %.*s", keylen, key); if (conn->last_packet > 0 && now > conn->last_packet + s2s->check_idle && conn->s->state >= state_STREAM) { log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] idle timeout", conn->fd->fd, conn->ip, conn->port); sx_close(conn->s); } } while(xhash_iter_next(s2s->out_host)); } else { if(xhash_iter_first(s2s->out_dest)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->out_dest, (const char **) &key, &keylen, xhv.val); log_debug(ZONE, "checking idle state for %s (%s)", conn->dkey, conn->key); if (conn->last_packet > 0 && now > conn->last_packet + s2s->check_idle && conn->s->state >= state_STREAM) { log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] idle timeout", conn->fd->fd, conn->ip, conn->port); sx_close(conn->s); } } while(xhash_iter_next(s2s->out_dest)); } /* incoming connections */ if(xhash_iter_first(s2s->in)) do { xhv.conn_val = &conn; xhash_iter_get(s2s->in, (const char **) &key, &keylen, xhv.val); log_debug(ZONE, "checking idle state for %.*s", keylen, key); if (conn->last_packet > 0 && now > conn->last_packet + s2s->check_idle && conn->s->state >= state_STREAM) { log_write(s2s->log, LOG_NOTICE, "[%d] [%s, port=%d] idle timeout", conn->fd->fd, conn->ip, conn->port); sx_close(conn->s); } } while(xhash_iter_next(s2s->in)); } return; }
int router_mio_callback(mio_t m, mio_action_t a, mio_fd_t fd, void *data, void *arg) { component_t comp = (component_t) arg; router_t r = (router_t) arg; struct sockaddr_storage sa; socklen_t namelen = sizeof(sa); int port, nbytes; switch(a) { case action_READ: log_debug(ZONE, "read action on fd %d", fd->fd); /* they did something */ comp->last_activity = time(NULL); ioctl(fd->fd, FIONREAD, &nbytes); if(nbytes == 0) { sx_kill(comp->s); return 0; } return sx_can_read(comp->s); case action_WRITE: log_debug(ZONE, "write action on fd %d", fd->fd); /* update activity timestamp */ comp->last_activity = time(NULL); return sx_can_write(comp->s); case action_CLOSE: log_debug(ZONE, "close action on fd %d", fd->fd); r = comp->r; log_write(r->log, LOG_NOTICE, "[%s, port=%d] disconnect", comp->ip, comp->port); /* unbind names */ xhash_walk(comp->routes, _router_route_unbind_walker, (void *) comp); /* deregister component */ xhash_zap(r->components, comp->ipport); xhash_free(comp->routes); if(comp->tq != NULL) /* !!! bounce packets */ jqueue_free(comp->tq); rate_free(comp->rate); jqueue_push(comp->r->dead, (void *) comp->s, 0); free(comp); break; case action_ACCEPT: log_debug(ZONE, "accept action on fd %d", fd->fd); getpeername(fd->fd, (struct sockaddr *) &sa, &namelen); port = j_inet_getport(&sa); log_write(r->log, LOG_NOTICE, "[%s, port=%d] connect", (char *) data, port); if(_router_accept_check(r, fd, (char *) data) != 0) return 1; comp = (component_t) calloc(1, sizeof(struct component_st)); comp->r = r; comp->fd = fd; snprintf(comp->ip, INET6_ADDRSTRLEN, "%s", (char *) data); comp->port = port; snprintf(comp->ipport, INET6_ADDRSTRLEN + 6, "%s:%d", comp->ip, comp->port); comp->s = sx_new(r->sx_env, fd->fd, _router_sx_callback, (void *) comp); mio_app(m, fd, router_mio_callback, (void *) comp); if(r->byte_rate_total != 0) comp->rate = rate_new(r->byte_rate_total, r->byte_rate_seconds, r->byte_rate_wait); comp->routes = xhash_new(51); /* register component */ log_debug(ZONE, "new component (%p) \"%s\"", comp, comp->ipport); xhash_put(r->components, comp->ipport, (void *) comp); #ifdef HAVE_SSL sx_server_init(comp->s, SX_SSL_STARTTLS_OFFER | SX_SASL_OFFER); #else sx_server_init(comp->s, SX_SASL_OFFER); #endif break; } return 0; }
int user_table_load(router_t r) { const char *userfile; FILE *f; long size; char *buf; nad_t nad; int nusers, user, name, secret; log_debug(ZONE, "loading user table"); if(r->users != NULL) xhash_free(r->users); r->users = xhash_new(51); userfile = config_get_one(r->config, "local.users", 0); if(userfile == NULL) userfile = CONFIG_DIR "/router-users.xml"; f = fopen(userfile, "rb"); if(f == NULL) { log_write(r->log, LOG_ERR, "couldn't open user table file %s: %s", userfile, strerror(errno)); return 1; } fseek(f, 0, SEEK_END); size = ftell(f); if(size < 0) { log_write(r->log, LOG_ERR, "couldn't seek user table file %s: %s", userfile, strerror(errno)); fclose(f); return 1; } if(size == 0) { log_write(r->log, LOG_ERR, "empty user table file %s", userfile); fclose(f); return 1; } fseek(f, 0, SEEK_SET); buf = (char *) malloc(sizeof(char) * size); if (fread(buf, 1, size, f) != size || ferror(f)) { log_write(r->log, LOG_ERR, "couldn't read from user table file: %s", strerror(errno)); free(buf); fclose(f); return 1; } fclose(f); nad = nad_parse(buf, size); if(nad == NULL) { log_write(r->log, LOG_ERR, "couldn't parse user table"); free(buf); return 1; } free(buf); nusers = 0; user = nad_find_elem(nad, 0, -1, "user", 1); while(user >= 0) { name = nad_find_elem(nad, user, -1, "name", 1); secret = nad_find_elem(nad, user, -1, "secret", 1); if(name < 0 || secret < 0 || NAD_CDATA_L(nad, name) <= 0 || NAD_CDATA_L(nad, secret) <= 0) { log_write(r->log, LOG_ERR, "malformed user entry in user table file, skipping"); continue; } log_debug(ZONE, "remembering user '%.*s'", NAD_CDATA_L(nad, name), NAD_CDATA(nad, name)); xhash_put(r->users, pstrdupx(xhash_pool(r->users), NAD_CDATA(nad, name), NAD_CDATA_L(nad, name)), pstrdupx(xhash_pool(r->users), NAD_CDATA(nad, secret), NAD_CDATA_L(nad, secret))); nusers++; user = nad_find_elem(nad, user, -1, "user", 0); } nad_free(nad); log_write(r->log, LOG_NOTICE, "loaded user table (%d users)", nusers); r->users_load = time(NULL); return 0; }
static void teardown(void) { xhash_free(g_ht); }