Hi, On Sun, Mar 7, 2021 at 11:31 AM Gert Doering <g...@greenie.muc.de> wrote:
> If --mlock is used, the amount of memory OpenVPN can use is guarded > by the RLIMIT_MEMLOCK value (see mlockall(2)). The OS default for this > is usually 64 Kbyte, which is enough for OpenVPN to initialize, but > as soon as the first TLS handshake comes it, OpenVPN will crash due > to "ouf of memory", and might even end up in a crash loop. > > Steady-state OpenVPN requires between 8 MB and 30-50 MB (servers with > many concurrent clients) of memory. > > So: with this patch, we check if getrlimit() is available, and if yes, > log the amount of mlock'able memory. If the amount is below 20 MB, > which is an arbitrary value "large enough for most smaller deployments", > we abort. > This is required only if privileges are dropped, isn't it? Could be made conditional on o->username is set. > Trac: #1390 > > Signed-off-by: Gert Doering <g...@greenie.muc.de> > --- > configure.ac | 2 +- > doc/man-sections/generic-options.rst | 6 ++++++ > src/openvpn/platform.c | 18 ++++++++++++++++++ > src/openvpn/platform.h | 4 ++++ > 4 files changed, 29 insertions(+), 1 deletion(-) > > diff --git a/configure.ac b/configure.ac > index 1ab8fe59..c65df3e2 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -645,7 +645,7 @@ AC_FUNC_FORK > > AC_CHECK_FUNCS([ \ > daemon chroot getpwnam setuid nice system getpid dup dup2 \ > - getpass syslog openlog mlockall getgrnam setgid \ > + getpass syslog openlog mlockall getrlimit getgrnam setgid \ > setgroups stat flock readv writev time gettimeofday \ > ctime memset vsnprintf strdup \ > setsid chdir putenv getpeername unlink \ > diff --git a/doc/man-sections/generic-options.rst > b/doc/man-sections/generic-options.rst > index d5f08839..0a7d3caf 100644 > --- a/doc/man-sections/generic-options.rst > +++ b/doc/man-sections/generic-options.rst > @@ -237,6 +237,12 @@ which mode OpenVPN is configured as. > likely fail. The limit can be increased using ulimit or systemd > directives depending on how OpenVPN is started. > > + If the platform has the getrlimit(2) system call, OpenVPN will check > + for the amount of mlock-able memory before calling mlockall(2), and white space at end of line > > + abort if less than 20 Mb are available. 20 Mb is somewhat arbitrary - > Mb -> MB > + it is enough for a moderately-sized OpenVPN deployment, but the memory > + usage will go beyond that if the number of concurrent clients is high. > + > --nice n > Change process priority after initialization (``n`` greater than 0 is > lower priority, ``n`` less than zero is higher priority). > diff --git a/src/openvpn/platform.c b/src/openvpn/platform.c > index ef688c23..67a69748 100644 > --- a/src/openvpn/platform.c > +++ b/src/openvpn/platform.c > @@ -193,6 +193,24 @@ void > platform_mlockall(bool print_msg) > { > #ifdef HAVE_MLOCKALL > + > +#ifdef HAVE_GETRLIMIT > + struct rlimit rl; > + if (getrlimit(RLIMIT_MEMLOCK,&rl)<0) > spaces after "," and around "<" :) > + { > + msg(M_WARN | M_ERRNO, "WARNING: getrlimit(RLIMIT_MEMLOCK) > failed"); > + } > + else > + { > + msg(M_INFO, "mlock: MEMLOCK limit: soft=%ldkb, hard=%dkb", > %dkb --> %ldkb > + ((long int) rl.rlim_cur)/1024, ((long int) rl.rlim_max)/1024); > Some may argue that our style is to put space around "/" > + if (rl.rlim_cur < 20*1024*1024) > + { > + msg(M_FATAL, "mlock: RLIMIT_MEMLOCK < 20 MByte, increase > limit"); > Mbyte -> MB or megabytes > + } > + } > +#endif > + > if (mlockall(MCL_CURRENT | MCL_FUTURE)) > { > msg(M_WARN | M_ERRNO, "WARNING: mlockall call failed"); > diff --git a/src/openvpn/platform.h b/src/openvpn/platform.h > index 01f3200c..02c23e38 100644 > --- a/src/openvpn/platform.h > +++ b/src/openvpn/platform.h > @@ -48,6 +48,10 @@ > #include <stdio.h> > #endif > > +#ifdef HAVE_GETRLIMIT > +#include <sys/resource.h> > +#endif > + > #include "basic.h" > #include "buffer.h" > Selva
_______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel