Leon wrote:
On Mon, 2006-06-26 at 14:24 +0200, Marek Marcola wrote:
OK weirdness going on here. I've added the RAND_load_file() command to
the beginning of my program and it does not make a difference.
With a 1000 threads I get a call to RAND_poll() only with the first
connection and not with subsequent SSL_accept() calls. With 1500 threads
it segfaults inside that one RAND_poll call.
Sorry cant help as I dont know anything about the RAND_xxx() workaround.
I now know that I am overwriting some memory due to the FD_SETSIZE
limit. The best solution for me will be to increase the value and
recompile the kernel. I will keep you guys posted if it does not work.
This limit is per process?
I do not believe the kernel has any problem with super-large fd_set's
being passed to it. I believe the kernel will use whatever size its
given and attempt to access the memory based on the 'maxfd' argument to
select. If the kernel attempts to access illegal memory from userspace
context (which the select() syscall runs in) the select() will return
EFAULT or SIGSEGV the application. So no "recompile the kernel" is needed.
The "ulimit -a" resources are set per process yes. This affect the
allocation of new file descriptors within the kernel. The default for
Fedora and its glibc build is 1024. In order for you to have
descriptors above 1024 you must have already dealt with raising the
ulimit. At that point you run into these sorts of problems with any
auxiliary library your applications call that do IO with select(). So
you may need to audit other things YMMV.
Its purely a userspace issue.
Maybe in rand/rand_unix.c you can replace 'fd_set' with 'my_fd_set',
then at the top of the code put:
#include <sys/select.h>
#define I_WANT_FD_SETSIZE 2048
#ifndef _NFDBITS
#define _NFDBITS 8
#endif
#ifdef __fd_mask
/* probably not perfect for x86_64 */
#define __fd_mask long int __fd_mask
#endif
struct my_fd_set_type {
__fd_mask fds_bits[I_WANT_FD_SETSIZE / __NFDBITS];
};
typedef struct my_fd_set_type my_fd_set;
You need to replace:
fd_set fset;
with
my_fd_set fset;
You need to replace FD_ZERO(&fset) with:
memset(&my_fd_set, 0, sizeof(my_fd_set));
Since the default macro will only clear the bits covering the first 1024
fds.
The try as Marek suggests:
FD_SET(fd, (fd_set *)&my_fd_set;
And with select use:
select(aaa, (fd_set *)&my_fd_set, xxx, yyy, zzz);
It is only the userspace code that allocats storage for fd_set type and
calls FD_ZERO() and FD_SET() that needs to be altered. From there you
can pass around the address of 'my_fd_set' and ultimately use it on the
select() call.
If the stock glibc FD_SET() do not work, you may need to implemnt your
own version of them against your my_fd_set_type. But I dont think this
is the case I think FD_SET() will work but FD_ZERO() wont. Just use
memset() for FD_ZERO().
The above is pretty Linux / glibc specific. You dont need to recompile
anything but the single file rand/rand_unix.c from OpenSSL. It is the
only affected part within OpenSSL AFAIK.
Obviously you may need to audit your application code for the same
requirements.
HTH
Darryl
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users@openssl.org
Automated List Manager [EMAIL PROTECTED]