Exemple #1
0
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);
}
Exemple #2
0
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));
}
Exemple #3
0
void at_shutdown(void *arg)
{
    ati ti = (ati)arg;

    xhash_walk(ti->session__list, &_at_shutdown, (void*)ti);
    xhash_free(ti->session__list);
}
Exemple #4
0
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 */
}
Exemple #5
0
/*
 * 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;
}
Exemple #6
0
void user_table_unload(router_t r) {

    if(r->users != NULL)
        xhash_free(r->users);
    r->users = NULL;

    return;
}
Exemple #7
0
void entity_free(entity_t* entity)
{
	if (entity) {
		xfree(entity->name);
		xfree(entity->type);
		xhash_free(entity->data);
		list_destroy(entity->nodes);
	}
}
Exemple #8
0
/** cleanup */
void config_free(config_t c)
{
    xhash_walk(c->hash, _config_reaper, NULL);

    xhash_free(c->hash);

    nad_free(c->nad);

    free(c);
}
Exemple #9
0
/** 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;
}
Exemple #10
0
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);
}
Exemple #11
0
/* 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;
}
Exemple #12
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;
}
Exemple #13
0
/*
 * 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;
}
Exemple #14
0
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);
}
Exemple #15
0
/* 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;
}
Exemple #16
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;
}
Exemple #17
0
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;
}
Exemple #18
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;
}
Exemple #19
0
static void teardown(void)
{
	xhash_free(g_ht);
}