Destroy unused link after sighup
This commit is contained in:
parent
0abd8a386d
commit
664ebb68a7
1
TODO
1
TODO
@ -1,3 +1,4 @@
|
|||||||
|
- check conn_list usage: esp wrt list_remove and closes
|
||||||
- uid, gid
|
- uid, gid
|
||||||
- keep invites when detached ?
|
- keep invites when detached ?
|
||||||
- allow global (or per net ?) IP filtering
|
- allow global (or per net ?) IP filtering
|
||||||
|
61
src/bip.c
61
src/bip.c
@ -377,7 +377,6 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data)
|
|||||||
l->untrusted_certs = sk_X509_new_null();
|
l->untrusted_certs = sk_X509_new_null();
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#warning "CODEME (user switch..)"
|
|
||||||
l->network = NULL;
|
l->network = NULL;
|
||||||
log_reinit_all(l->log);
|
log_reinit_all(l->log);
|
||||||
}
|
}
|
||||||
@ -497,6 +496,8 @@ static int add_connection(bip_t *bip, struct user *user, list_t *data)
|
|||||||
conf_die("No realname set and no default realname.");
|
conf_die("No realname set and no default realname.");
|
||||||
l->realname = strdup(user->default_realname);
|
l->realname = strdup(user->default_realname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
l->in_use = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -644,6 +645,7 @@ static int add_user(bip_t *bip, list_t *data, struct historical_directives *hds)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u->in_use = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -705,6 +707,61 @@ static int validate_config(bip_t *bip)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clear_marks(bip_t *bip)
|
||||||
|
{
|
||||||
|
list_iterator_t lit;
|
||||||
|
hash_iterator_t hit;
|
||||||
|
|
||||||
|
for (list_it_init(&bip->link_list, &lit); list_it_item(&lit);
|
||||||
|
list_it_next(&lit))
|
||||||
|
((struct link *)list_it_item(&lit))->in_use = 0;
|
||||||
|
for (hash_it_init(&bip->users, &hit); hash_it_item(&hit);
|
||||||
|
hash_it_next(&hit))
|
||||||
|
((struct user *)hash_it_item(&hit))->in_use = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void user_kill(bip_t *bip, struct user *user)
|
||||||
|
{
|
||||||
|
if (!hash_is_empty(&user->connections))
|
||||||
|
fatal("user_kill, user still has connections");
|
||||||
|
free(user->name);
|
||||||
|
free(user->password);
|
||||||
|
MAYFREE(user->default_nick);
|
||||||
|
MAYFREE(user->default_username);
|
||||||
|
MAYFREE(user->default_realname);
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBSSL
|
||||||
|
MAYFREE(ssl_check_store);
|
||||||
|
#endif
|
||||||
|
free(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sweep(bip_t *bip)
|
||||||
|
{
|
||||||
|
list_iterator_t lit;
|
||||||
|
hash_iterator_t hit;
|
||||||
|
|
||||||
|
for (list_it_init(&bip->link_list, &lit); list_it_item(&lit);
|
||||||
|
list_it_next(&lit)) {
|
||||||
|
struct link *l = ((struct link *)list_it_item(&lit));
|
||||||
|
if (!l->in_use) {
|
||||||
|
mylog(LOG_INFO, "Administratively killing %s/%s",
|
||||||
|
l->user->name, l->name);
|
||||||
|
link_kill(bip, l);
|
||||||
|
list_remove_if_exists(&bip->conn_list, l);
|
||||||
|
list_it_remove(&lit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (hash_it_init(&bip->users, &hit); hash_it_item(&hit);
|
||||||
|
hash_it_next(&hit)) {
|
||||||
|
struct user *u = (struct user *)hash_it_item(&hit);
|
||||||
|
if (!u->in_use) {
|
||||||
|
hash_it_remove(&hit);
|
||||||
|
user_kill(bip, u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int fireup(bip_t *bip, FILE *conf)
|
int fireup(bip_t *bip, FILE *conf)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
@ -712,6 +769,7 @@ int fireup(bip_t *bip, FILE *conf)
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
struct historical_directives hds;
|
struct historical_directives hds;
|
||||||
|
|
||||||
|
clear_marks(bip);
|
||||||
parse_conf(conf, &err);
|
parse_conf(conf, &err);
|
||||||
if (err) {
|
if (err) {
|
||||||
free_conf(root_list);
|
free_conf(root_list);
|
||||||
@ -790,6 +848,7 @@ int fireup(bip_t *bip, FILE *conf)
|
|||||||
root_list = NULL;
|
root_list = NULL;
|
||||||
|
|
||||||
validate_config(bip);
|
validate_config(bip);
|
||||||
|
sweep(bip);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
out_conf_error:
|
out_conf_error:
|
||||||
|
39
src/irc.c
39
src/irc.c
@ -1423,11 +1423,6 @@ static void channel_free(struct channel *c)
|
|||||||
if (c->create_ts)
|
if (c->create_ts)
|
||||||
free(c->create_ts);
|
free(c->create_ts);
|
||||||
|
|
||||||
/*
|
|
||||||
char *l;
|
|
||||||
while ((l = (char *)list_remove_first(&c->bans)))
|
|
||||||
free(l);
|
|
||||||
*/
|
|
||||||
hash_iterator_t hi;
|
hash_iterator_t hi;
|
||||||
for (hash_it_init(&c->nicks, &hi); hash_it_item(&hi); hash_it_next(&hi))
|
for (hash_it_init(&c->nicks, &hi); hash_it_item(&hi); hash_it_next(&hi))
|
||||||
nick_free(hash_it_item(&hi));
|
nick_free(hash_it_item(&hi));
|
||||||
@ -1892,7 +1887,6 @@ void server_cleanup(struct link_server *server)
|
|||||||
CONN(server) = NULL;
|
CONN(server) = NULL;
|
||||||
}
|
}
|
||||||
irc_lag_init(server);
|
irc_lag_init(server);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void irc_client_close(struct link_client *ic)
|
void irc_client_close(struct link_client *ic)
|
||||||
@ -1989,10 +1983,21 @@ struct link_server *irc_server_new(struct link *link, connection_t *conn)
|
|||||||
|
|
||||||
void irc_server_free(struct link_server *s)
|
void irc_server_free(struct link_server *s)
|
||||||
{
|
{
|
||||||
|
if (CONN(s))
|
||||||
|
connection_free(CONN(s));
|
||||||
if (s->nick)
|
if (s->nick)
|
||||||
free(s->nick);
|
free(s->nick);
|
||||||
if (s->user_mode)
|
if (s->user_mode)
|
||||||
free(s->user_mode);
|
free(s->user_mode);
|
||||||
|
|
||||||
|
hash_iterator_t hi;
|
||||||
|
for (hash_it_init(&s->channels, &hi); hash_it_item(&hi);
|
||||||
|
hash_it_next(&hi)) {
|
||||||
|
struct channel *chan = hash_it_item(&hi);
|
||||||
|
channel_free(chan);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2413,8 +2418,6 @@ void irc_main(bip_t *bip)
|
|||||||
bip_on_event(bip, conn);
|
bip_on_event(bip, conn);
|
||||||
list_free(ready);
|
list_free(ready);
|
||||||
}
|
}
|
||||||
while (list_remove_first(&bip->link_list))
|
|
||||||
;
|
|
||||||
while (list_remove_first(&bip->connecting_client_list))
|
while (list_remove_first(&bip->connecting_client_list))
|
||||||
;
|
;
|
||||||
return;
|
return;
|
||||||
@ -2431,12 +2434,6 @@ void irc_client_free(struct link_client *cli)
|
|||||||
free(cli);
|
free(cli);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
void irc_server_free(struct link_server *is)
|
|
||||||
{
|
|
||||||
free(is);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
struct link *irc_link_new()
|
struct link *irc_link_new()
|
||||||
{
|
{
|
||||||
struct link *link;
|
struct link *link;
|
||||||
@ -2453,11 +2450,18 @@ struct link *irc_link_new()
|
|||||||
|
|
||||||
void link_kill(bip_t *bip, struct link *link)
|
void link_kill(bip_t *bip, struct link *link)
|
||||||
{
|
{
|
||||||
|
list_remove(&bip->conn_list, CONN(link->l_server));
|
||||||
|
server_cleanup(link->l_server);
|
||||||
|
irc_server_free(link->l_server);
|
||||||
|
while (link->l_clientc) {
|
||||||
|
struct link_client *lc = link->l_clientv[0];
|
||||||
|
list_remove(&bip->conn_list, CONN(lc));
|
||||||
|
unbind_from_link(lc);
|
||||||
|
irc_client_free(lc);
|
||||||
|
}
|
||||||
|
|
||||||
hash_remove(&link->user->connections, link->name);
|
hash_remove(&link->user->connections, link->name);
|
||||||
free(link->name);
|
free(link->name);
|
||||||
irc_close((struct link_any *)link->l_server);
|
|
||||||
while (link->l_clientc)
|
|
||||||
irc_close((struct link_any *)link->l_clientv[0]);
|
|
||||||
log_free(link->log);
|
log_free(link->log);
|
||||||
MAYFREE(link->prev_nick);
|
MAYFREE(link->prev_nick);
|
||||||
MAYFREE(link->cli_nick);
|
MAYFREE(link->cli_nick);
|
||||||
@ -2483,5 +2487,6 @@ void link_kill(bip_t *bip, struct link *link)
|
|||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
sk_X509_free(link->untrusted_certs);
|
sk_X509_free(link->untrusted_certs);
|
||||||
#endif
|
#endif
|
||||||
|
free(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +90,7 @@ struct user {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
hash_t connections;
|
hash_t connections;
|
||||||
|
int in_use; /* for mark and sweep on reload */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct network
|
struct network
|
||||||
@ -157,6 +158,7 @@ struct link {
|
|||||||
int ssl_check_mode;
|
int ssl_check_mode;
|
||||||
STACK_OF(X509) *untrusted_certs;
|
STACK_OF(X509) *untrusted_certs;
|
||||||
#endif
|
#endif
|
||||||
|
int in_use; /* for mark and sweep on reload */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct link_connection {
|
struct link_connection {
|
||||||
|
@ -1171,7 +1171,7 @@ log_t *log_new(struct user *user, char *network)
|
|||||||
fatal("out of memory");
|
fatal("out of memory");
|
||||||
logdata->connected = 0;
|
logdata->connected = 0;
|
||||||
if (!log_all_logs)
|
if (!log_all_logs)
|
||||||
log_all_logs = list_new(NULL);
|
log_all_logs = list_new(list_ptr_cmp);
|
||||||
list_add_last(log_all_logs, logdata);
|
list_add_last(log_all_logs, logdata);
|
||||||
return logdata;
|
return logdata;
|
||||||
}
|
}
|
||||||
@ -1182,12 +1182,16 @@ void log_free(log_t *log)
|
|||||||
logfilegroup_t *lfg;
|
logfilegroup_t *lfg;
|
||||||
logfile_t *lf;
|
logfile_t *lf;
|
||||||
|
|
||||||
|
list_remove(log_all_logs, log);
|
||||||
|
|
||||||
|
free(log->network);
|
||||||
|
free(log->buffer);
|
||||||
|
|
||||||
for (hash_it_init(&log->logfgs, &it); (lfg = hash_it_item(&it));
|
for (hash_it_init(&log->logfgs, &it); (lfg = hash_it_item(&it));
|
||||||
hash_it_next(&it)) {
|
hash_it_next(&it)) {
|
||||||
log_reset(lfg);
|
log_reset(lfg);
|
||||||
if ((lf = list_remove_first(&lfg->file_group)))
|
if ((lf = list_remove_first(&lfg->file_group)))
|
||||||
logfile_free(lf);
|
logfile_free(lf);
|
||||||
free(lf);
|
|
||||||
}
|
}
|
||||||
hash_clean(&log->logfgs);
|
hash_clean(&log->logfgs);
|
||||||
free(log);
|
free(log);
|
||||||
|
89
src/util.c
89
src/util.c
@ -308,28 +308,6 @@ void *list_remove_last(list_t *list)
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
static void *list_remove_item(list_t *l, struct list_item *li)
|
|
||||||
{
|
|
||||||
void *ret = li->ptr;
|
|
||||||
if (!li->prev) {
|
|
||||||
if (l->first != li)
|
|
||||||
fatal("list_remove_item");
|
|
||||||
l->first = li->next;
|
|
||||||
} else
|
|
||||||
li->prev->next = li->next;
|
|
||||||
|
|
||||||
if (!li->next) {
|
|
||||||
if (l->last != li)
|
|
||||||
fatal("list_remove_item");
|
|
||||||
l->last = li->prev;
|
|
||||||
} else
|
|
||||||
li->next->prev = li->prev;
|
|
||||||
free(li);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void *list_remove_if_exists(list_t *list, void *ptr)
|
void *list_remove_if_exists(list_t *list, void *ptr)
|
||||||
{
|
{
|
||||||
list_iterator_t li;
|
list_iterator_t li;
|
||||||
@ -383,12 +361,19 @@ void list_it_init(list_t *list, list_iterator_t *ti)
|
|||||||
{
|
{
|
||||||
ti->list = list;
|
ti->list = list;
|
||||||
ti->cur = list->first;
|
ti->cur = list->first;
|
||||||
|
ti->next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_it_next(list_iterator_t *ti)
|
void list_it_next(list_iterator_t *ti)
|
||||||
{
|
{
|
||||||
if (ti->cur)
|
if (ti->cur) {
|
||||||
|
if (ti->next)
|
||||||
|
fatal("list_it_next: inconsistent interator state");
|
||||||
ti->cur = ti->cur->next;
|
ti->cur = ti->cur->next;
|
||||||
|
} else if (ti->next) {
|
||||||
|
ti->cur = ti->next;
|
||||||
|
ti->next = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *list_it_item(list_iterator_t *ti)
|
void *list_it_item(list_iterator_t *ti)
|
||||||
@ -415,7 +400,8 @@ void *list_it_remove(list_iterator_t *li)
|
|||||||
|
|
||||||
void *ptr = li->cur->ptr;
|
void *ptr = li->cur->ptr;
|
||||||
struct list_item *item = li->cur;
|
struct list_item *item = li->cur;
|
||||||
li->cur = li->cur->next;
|
li->next = li->cur->next;
|
||||||
|
li->cur = NULL;
|
||||||
free(item);
|
free(item);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
@ -555,50 +541,73 @@ void *hash_remove(hash_t *hash, char *key)
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int hash_is_empty(hash_t *h)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
if (!list_is_empty(&h->lists[i]))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void hash_it_init(hash_t *h, hash_iterator_t *hi)
|
void hash_it_init(hash_t *h, hash_iterator_t *hi)
|
||||||
{
|
{
|
||||||
memset(hi, 0, sizeof(hash_iterator_t));
|
memset(hi, 0, sizeof(hash_iterator_t));
|
||||||
hi->hash = h;
|
hi->hash = h;
|
||||||
|
|
||||||
while (list_is_empty(&h->lists[hi->list]) && hi->list < 256)
|
while (hi->list < 256 && list_is_empty(&h->lists[hi->list]))
|
||||||
hi->list++;
|
hi->list++;
|
||||||
if (hi->list < 256)
|
if (hi->list < 256)
|
||||||
hi->cur = h->lists[hi->list].first;
|
list_it_init(&h->lists[hi->list], &hi->lit);
|
||||||
else
|
|
||||||
hi->cur = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hash_it_next(hash_iterator_t *hi)
|
void hash_it_next(hash_iterator_t *hi)
|
||||||
{
|
{
|
||||||
hash_t *hash = hi->hash;
|
list_it_next(&hi->lit);
|
||||||
|
if (!list_it_item(&hi->lit)) {
|
||||||
hi->cur = hi->cur->next;
|
do {
|
||||||
while (!hi->cur) {
|
|
||||||
hi->list++;
|
hi->list++;
|
||||||
if (hi->list == 256) {
|
if (hi->list == 256)
|
||||||
hi->cur = NULL;
|
|
||||||
return;
|
return;
|
||||||
}
|
} while (list_is_empty(&hi->hash->lists[hi->list]));
|
||||||
hi->cur = hash->lists[hi->list].first;
|
list_it_init(&hi->hash->lists[hi->list], &hi->lit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *hash_it_item(hash_iterator_t *h)
|
void *hash_it_item(hash_iterator_t *h)
|
||||||
{
|
{
|
||||||
if (!h->cur)
|
struct hash_item *hi;
|
||||||
|
|
||||||
|
hi = list_it_item(&h->lit);
|
||||||
|
if (!hi)
|
||||||
return NULL;
|
return NULL;
|
||||||
struct hash_item *hi = h->cur->ptr;
|
|
||||||
return hi->item;
|
return hi->item;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *hash_it_key(hash_iterator_t *h)
|
char *hash_it_key(hash_iterator_t *h)
|
||||||
{
|
{
|
||||||
if (!h->cur)
|
struct hash_item *hi;
|
||||||
|
hi = list_it_item(&h->lit);
|
||||||
|
if (!hi)
|
||||||
return NULL;
|
return NULL;
|
||||||
struct hash_item *hi = h->cur->ptr;
|
|
||||||
return hi->key;
|
return hi->key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *hash_it_remove(hash_iterator_t *hi)
|
||||||
|
{
|
||||||
|
struct hash_item *hitem;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
hitem = list_it_remove(&hi->lit);
|
||||||
|
|
||||||
|
ptr = hitem->item;
|
||||||
|
free(hitem->key);
|
||||||
|
free(hitem);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
void hash_dump(hash_t *h)
|
void hash_dump(hash_t *h)
|
||||||
{
|
{
|
||||||
hash_iterator_t it;
|
hash_iterator_t it;
|
||||||
|
@ -35,6 +35,7 @@ void _mylog(int level, char *fmt, va_list ap);
|
|||||||
void fatal(char *fmt, ...);
|
void fatal(char *fmt, ...);
|
||||||
char *timestamp(void);
|
char *timestamp(void);
|
||||||
struct list_item;
|
struct list_item;
|
||||||
|
struct hash_item;
|
||||||
|
|
||||||
typedef struct list {
|
typedef struct list {
|
||||||
struct list_item *first;
|
struct list_item *first;
|
||||||
@ -45,16 +46,17 @@ typedef struct list {
|
|||||||
typedef struct list_iterator {
|
typedef struct list_iterator {
|
||||||
list_t *list;
|
list_t *list;
|
||||||
struct list_item *cur;
|
struct list_item *cur;
|
||||||
|
struct list_item *next;
|
||||||
} list_iterator_t;
|
} list_iterator_t;
|
||||||
|
|
||||||
/* our hash is also a list */
|
|
||||||
typedef struct hash {
|
typedef struct hash {
|
||||||
list_t lists[256];
|
list_t lists[256];
|
||||||
} hash_t;
|
} hash_t;
|
||||||
|
|
||||||
typedef struct hash_iterator {
|
typedef struct hash_iterator {
|
||||||
int list;
|
int list;
|
||||||
struct list_item *cur;
|
list_iterator_t lit;
|
||||||
|
struct hash_item *cur;
|
||||||
hash_t *hash;
|
hash_t *hash;
|
||||||
} hash_iterator_t;
|
} hash_iterator_t;
|
||||||
|
|
||||||
@ -104,10 +106,12 @@ void hash_insert(hash_t *hash, char *key, void *ptr);
|
|||||||
void *hash_get(hash_t *, char *key);
|
void *hash_get(hash_t *, char *key);
|
||||||
void *hash_remove(hash_t *hash, char *key);
|
void *hash_remove(hash_t *hash, char *key);
|
||||||
void *hash_remove_if_exists(hash_t *hash, char *key);
|
void *hash_remove_if_exists(hash_t *hash, char *key);
|
||||||
|
int hash_is_empty(hash_t *h);
|
||||||
void hash_it_init(hash_t *hash, hash_iterator_t *i);
|
void hash_it_init(hash_t *hash, hash_iterator_t *i);
|
||||||
void hash_it_next(hash_iterator_t *hi);
|
void hash_it_next(hash_iterator_t *hi);
|
||||||
void *hash_it_item(hash_iterator_t *h);
|
void *hash_it_item(hash_iterator_t *h);
|
||||||
char *hash_it_key(hash_iterator_t *h);
|
char *hash_it_key(hash_iterator_t *h);
|
||||||
|
void *hash_it_remove(hash_iterator_t *li);
|
||||||
|
|
||||||
int is_valid_nick(char *str);
|
int is_valid_nick(char *str);
|
||||||
int is_valid_username(char *str);
|
int is_valid_username(char *str);
|
||||||
|
Loading…
Reference in New Issue
Block a user