diff options
author | Reyk Floeter <reyk@esdenera.com> | 2015-01-03 21:06:57 +0100 |
---|---|---|
committer | Reyk Floeter <reyk@esdenera.com> | 2015-01-03 21:06:57 +0100 |
commit | 4f5dd228f08c132afdef71c1a5a124595905d8ae (patch) | |
tree | 653146e322b074f6a796a7b247b8113edcc943df /server.c | |
parent | 461ae7b2ed14e4c38ecf78d791138922a6c050f3 (diff) | |
download | httpd-4f5dd228f08c132afdef71c1a5a124595905d8ae.tar.gz httpd-4f5dd228f08c132afdef71c1a5a124595905d8ae.zip |
In the parent, only open a socket once per unique listen statement.
Fixes possible file descriptor exhaustion on configuration load time.
Diffstat (limited to 'server.c')
-rw-r--r-- | server.c | 19 |
1 files changed, 18 insertions, 1 deletions
@@ -101,11 +101,27 @@ server_shutdown(void) int server_privinit(struct server *srv) { + struct server *s; + if (srv->srv_conf.flags & SRVFLAG_LOCATION) return (0); log_debug("%s: adding server %s", __func__, srv->srv_conf.name); + /* + * There's no need to open a new socket if a server with the + * same address already exists. + */ + TAILQ_FOREACH(s, env->sc_servers, srv_entry) { + if (s != srv && s->srv_s != -1 && + s->srv_conf.port == srv->srv_conf.port && + sockaddr_cmp((struct sockaddr *)&s->srv_conf.ss, + (struct sockaddr *)&srv->srv_conf.ss, + s->srv_conf.prefixlen) == 0) + return (0); + } + + /* Open listening socket in the privileged process */ if ((srv->srv_s = server_socket_listen(&srv->srv_conf.ss, srv->srv_conf.port, &srv->srv_conf)) == -1) return (-1); @@ -277,7 +293,8 @@ server_purge(struct server *srv) if (evtimer_initialized(&srv->srv_evt)) evtimer_del(&srv->srv_evt); - close(srv->srv_s); + if (srv->srv_s != -1) + close(srv->srv_s); TAILQ_REMOVE(env->sc_servers, srv, srv_entry); /* cleanup sessions */ |