From 434e51f69d2d89b1fedaa7ee48cbc72dcf0b285d Mon Sep 17 00:00:00 2001 From: Bram Matthys Date: Wed, 13 Jan 2016 10:30:07 +0100 Subject: [PATCH] Fix crash when listen block was removed while it had connected clients on that port. Reported by AnGeLoCaDuTo (#4544). There were a few flaws in the code: 1) it should close the listener on /rehash, shouldnt't matter if there are clients or not, 2) then there was a bug where it would properly close the listener but it would be re-opened by add_listener2. Also added a "IRCd no longer listening on .." message if you remove a listen block. --- src/s_bsd.c | 20 +++++++++++++------- src/s_conf.c | 3 ++- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/s_bsd.c b/src/s_bsd.c index 35cf1ac25..7da04df8b 100644 --- a/src/s_bsd.c +++ b/src/s_bsd.c @@ -450,12 +450,20 @@ int add_listener2(ConfigItem_listen *conf) /* * close_listeners * - * Close and free all clients which are marked as having their socket open - * and in a state where they can accept connections. + * Close the listener. Note that this won't *free* the listen block, it + * just makes it so no new clients are accepted (and marks the listener + * as "not bound"). */ void close_listener(ConfigItem_listen *listener) { - fd_close(listener->fd); + if (listener->fd >= 0) + { + ircd_log(LOG_ERROR, "IRCd no longer listening on %s:%d (%s)%s", + listener->ip, listener->port, + listener->ipv6 ? "IPv6" : "IPv4", + listener->options & LISTENER_SSL ? " (SSL)" : ""); + fd_close(listener->fd); + } listener->options &= ~LISTENER_BOUND; listener->fd = -1; @@ -466,14 +474,12 @@ void close_listeners(void) aClient *cptr; ConfigItem_listen *aconf, *aconf_next; - /* - * close all 'extra' listening ports we have - */ + /* close all 'extra' listening ports we have */ for (aconf = conf_listen; aconf != NULL; aconf = aconf_next) { aconf_next = (ConfigItem_listen *) aconf->next; - if (aconf->flag.temporary && (aconf->clients == 0)) + if (aconf->flag.temporary) close_listener(aconf); } } diff --git a/src/s_conf.c b/src/s_conf.c index 0d595edce..c22315bb7 100644 --- a/src/s_conf.c +++ b/src/s_conf.c @@ -8108,7 +8108,8 @@ void start_listeners(void) for (listenptr = conf_listen; listenptr; listenptr = (ConfigItem_listen *) listenptr->next) { - if (!(listenptr->options & LISTENER_BOUND)) + /* Try to bind to any ports that are not yet bound and not marked as temporary */ + if (!(listenptr->options & LISTENER_BOUND) && !listenptr->flag.temporary) { if (add_listener2(listenptr) == -1) {