diff --git a/include/libwebsockets/lws-context-vhost.h b/include/libwebsockets/lws-context-vhost.h index c0c61a0b7..ffb0c8f55 100644 --- a/include/libwebsockets/lws-context-vhost.h +++ b/include/libwebsockets/lws-context-vhost.h @@ -737,6 +737,11 @@ struct lws_context_creation_info { * ss_proxy_bind and the given port */ #endif + int rlimit_nofile; + /**< 0 = inherit the initial ulimit for files / sockets from the startup + * environment. Nonzero = try to set the limit for this process. + */ + /* Add new things just above here ---^ * This is part of the ABI, don't needlessly break compatibility * diff --git a/lib/core/context.c b/lib/core/context.c index ab6470c92..89c2f3a5b 100644 --- a/lib/core/context.c +++ b/lib/core/context.c @@ -30,6 +30,11 @@ static const char *library_version = LWS_LIBRARY_VERSION " " LWS_BUILD_HASH; +#if defined(__linux__) +/* for setrlimit */ +#include +#endif + #if defined(LWS_WITH_NETWORK) /* in ms */ static uint32_t default_backoff_table[] = { 1000, 3000, 9000, 17000 }; @@ -411,6 +416,20 @@ lws_create_context(const struct lws_context_creation_info *info) context->options = info->options; +#if !defined(LWS_PLAT_FREERTOS) && !defined(LWS_PLAT_OPTEE) && !defined(WIN32) + /* + * If asked, try to set the rlimit / ulimit for process sockets / files. + * We read the effective limit in a moment, so we will find out the + * real limit according to system constraints then. + */ + if (info->rlimit_nofile) { + struct rlimit rl; + + rl.rlim_cur = rl.rlim_max = info->rlimit_nofile; + setrlimit(RLIMIT_NOFILE, &rl); + } +#endif + #ifndef LWS_NO_DAEMONIZE if (pid_daemon) { context->started_with_parent = pid_daemon; diff --git a/lib/plat/unix/unix-init.c b/lib/plat/unix/unix-init.c index 72c599597..6abe4c7ba 100644 --- a/lib/plat/unix/unix-init.c +++ b/lib/plat/unix/unix-init.c @@ -126,8 +126,8 @@ lws_plat_init(struct lws_context *context, #endif context->fd_random = fd; if (context->fd_random < 0) { - lwsl_err("Unable to open random device %s %d\n", - SYSTEM_RANDOM_FILEPATH, context->fd_random); + lwsl_err("Unable to open random device %s %d, errno %d\n", + SYSTEM_RANDOM_FILEPATH, context->fd_random, errno); return 1; } diff --git a/lib/roles/http/server/lejp-conf.c b/lib/roles/http/server/lejp-conf.c index 7f1a1e066..e8b951d82 100644 --- a/lib/roles/http/server/lejp-conf.c +++ b/lib/roles/http/server/lejp-conf.c @@ -47,6 +47,7 @@ static const char * const paths_global[] = { "global.default-alpn", "global.ip-limit-ah", "global.ip-limit-wsi", + "global.rlimit-nofile", }; enum lejp_global_paths { @@ -65,6 +66,7 @@ enum lejp_global_paths { LWJPGP_DEFAULT_ALPN, LWJPGP_IP_LIMIT_AH, LWJPGP_IP_LIMIT_WSI, + LWJPGP_FD_LIMIT_PT, }; static const char * const paths_vhosts[] = { @@ -346,6 +348,10 @@ lejp_globals_cb(struct lejp_ctx *ctx, char reason) a->info->ip_limit_wsi = atoi(ctx->buf); return 0; + case LWJPGP_FD_LIMIT_PT: + a->info->rlimit_nofile = atoi(ctx->buf); + return 0; + default: return 0; }