diff options
| -rw-r--r-- | configure.ng | 2 | ||||
| -rw-r--r-- | contrib/ngircd.logcheck | 1 | ||||
| -rw-r--r-- | src/ngircd/conf.c | 50 | ||||
| -rw-r--r-- | src/ngircd/defines.h | 5 |
4 files changed, 57 insertions, 1 deletions
diff --git a/configure.ng b/configure.ng index f6c70e5d..ec7b6c35 100644 --- a/configure.ng +++ b/configure.ng @@ -192,6 +192,7 @@ AC_CHECK_HEADERS_ONCE([ \ stdbool.h \ stddef.h \ stdint.h \ + sys/resource.h \ varargs.h \ ]) @@ -274,6 +275,7 @@ AC_CHECK_FUNCS_ONCE([ getnameinfo \ inet_aton \ setgroups \ + setrlimit \ sigaction \ sigprocmask \ snprintf \ diff --git a/contrib/ngircd.logcheck b/contrib/ngircd.logcheck index 1224551f..905162d6 100644 --- a/contrib/ngircd.logcheck +++ b/contrib/ngircd.logcheck @@ -12,6 +12,7 @@ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ ngircd\[[0-9]+\]: Deleted ".*" \(".*"\) from G-Line list \(expired\)\.$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ ngircd\[[0-9]+\]: Enabled link compression \(zlib\) on connection [0-9]+\.$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ ngircd\[[0-9]+\]: Establishing connection for ".*" to ".*:[0-9]+" \(.*\), socket [0-9]+ \.\.\.$ +^\w{3} [ :0-9]{11} [._[:alnum:]-]+ ngircd\[[0-9]+\]: File descriptor limit is [0-9]+; "MaxConnections" is (not set|set to [0-9]+)\.$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ ngircd\[[0-9]+\]: Got (valid server|unchecked peer) certificate: .*\.$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ ngircd\[[0-9]+\]: Got signal "(Hangup|Terminated)" \.\.\.$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ ngircd\[[0-9]+\]: Got valid OPER for ".*" from ".*", user is an IRC operator now\.$ diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c index 441b8f67..e4cd8963 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -35,6 +35,10 @@ #include <dirent.h> #include <netdb.h> +#ifdef HAVE_SYS_RESOURCE_H +# include <sys/resource.h> +#endif + #include "ngircd.h" #include "conn.h" #include "channel.h" @@ -2108,6 +2112,10 @@ Validate_Config(bool Configtest, bool Rehash) struct hostent *h; bool config_valid = true; char *ptr; +#ifdef HAVE_SETRLIMIT + struct rlimit rlim; + long fd_lim_old; +#endif /* Emit a warning when the config file is not a full path name */ if (NGIRCd_ConfFile[0] && NGIRCd_ConfFile[0] != '/') { @@ -2197,6 +2205,48 @@ Validate_Config(bool Configtest, bool Rehash) "Maximum penalty increase ('MaxPenaltyTime') is set to %ld, this is not recommended!", Conf_MaxPenaltyTime); +#ifdef HAVE_SETRLIMIT + if(getrlimit(RLIMIT_NOFILE, &rlim) == 0) { + LogDebug("Current file descriptor limit is %ld, maximum %ld. \"MaxConnections\" is %ld.", + (long)rlim.rlim_cur, (long)rlim.rlim_max, + Conf_MaxConnections); + fd_lim_old = rlim.rlim_cur; + /* Don't request "infinite" file descriptors, use a limit! */ + if (rlim.rlim_max != RLIM_INFINITY && rlim.rlim_max < MAX_FD_LIMIT) + rlim.rlim_cur = rlim.rlim_max; + else + rlim.rlim_cur = MAX_FD_LIMIT; + if ((long)rlim.rlim_cur != fd_lim_old) { + /* Try to adjust the current file descriptor limit: */ + LogDebug("Trying to upgrade \"soft\" file descriptor limit: %ld -> %ld ...", + fd_lim_old, (long)rlim.rlim_cur); + if(setrlimit(RLIMIT_NOFILE, &rlim) != 0) + Config_Error(LOG_ERR, "Failed to adjust file descriptor limit from %ld to %ld: %s", + fd_lim_old, (long)rlim.rlim_cur, + strerror(errno)); + } + /* Check the (updated?) file descriptor limit: */ + getrlimit(RLIMIT_NOFILE, &rlim); + if (rlim.rlim_cur != RLIM_INFINITY + && (long)rlim.rlim_cur <= (long)Conf_MaxConnections) { + Config_Error(LOG_WARNING, + "Current file descriptor limit (%ld) is not higher than configured \"MaxConnections\" (%ld)!", + (long)rlim.rlim_cur, Conf_MaxConnections); + } else if (!Configtest) { + if (Conf_MaxConnections > 0) + Log(LOG_INFO, + "File descriptor limit is %ld; \"MaxConnections\" is set to %ld.", + (long)rlim.rlim_cur, Conf_MaxConnections); + else + Log(LOG_INFO, + "File descriptor limit is %ld; \"MaxConnections\" is not set.", + (long)rlim.rlim_cur); + } + } else + Config_Error(LOG_ERR, "Failed to get file descriptor limit: %s", + strerror(errno)); +#endif + servers = servers_once = 0; for (i = 0; i < MAX_SERVERS; i++) { if (Conf_Server[i].name[0]) { diff --git a/src/ngircd/defines.h b/src/ngircd/defines.h index 0b44a5b4..e3df44b9 100644 --- a/src/ngircd/defines.h +++ b/src/ngircd/defines.h @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2024 Alexander Barton (alex@barton.de) and Contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -64,6 +64,9 @@ /** Size of buffer for PAM service name. */ #define MAX_PAM_SERVICE_NAME_LEN 64 +/** Maximum number of file descriptors to request. */ +#define MAX_FD_LIMIT 100000 + /* Hard-coded (default) options */ |