On Tue, Nov 11, 2008 at 9:54 PM, Deron Meranda <[EMAIL PROTECTED]> wrote:
[...]

It won't cope well with arbitrary integers, when they, due to severe
software glitches or pure malice, end up in integers intended to carry
socket handles around. So the only fool-proof way I could come up with
is some extra bounds checking before letting those numbers at FD_SET
et al and select() itself.

... with an extra note for WinSock/WinSock2 users, i.e. [almost]
everyone on Win32/Win64: here an fd_set is not a set of flags, one for
each handle, as you'd find on most UNIX/Linux boxes, but here fd_set
is actually a struct with two members: a count and a handle array. As
you call FD_SET(), each handle is appended into the array (upping the
fill count by 1). Remember that WinSock handles are HANDLE type, i.e.
basically pointers, contrasting with UNIX' 'int' handles - yet you can
cast WinSock HANDLE's to 'int' and back again without losing your
bowels. Some believe this was meant to be, by design. I hope so.

Anyway, if you need to check if a given handle might be allowed near
FD_SET(), select() et al, *first* you'll need to FD_ZERO() the fd_set,
then you can use this sort of code:


/* [i_a] apr/2007 */
int sock_maybe_in_fdset(fd_set * set, int sock)
{
  int i;

  if(sock < 0)
    return FALSE;

  /* if set isn't filled up yet, this socket might fit in there. */
  if(set->fd_count < FD_SETSIZE)
    return TRUE;
  /* otherwise it MUST be in there */
  for(i = 0; i < set->fd_count; i++)
  {
    if(set->fd_array[i] == sock)
      return TRUE;
  }

  return FALSE;
}


and an example of its use:



int tl_selectr(int sock, long int timeout)
{
  fd_set readfds, exceptfds;

  FD_ZERO(&readfds);
  FD_ZERO(&exceptfds);

  /*
     FD_SET will crash if you pass it sock = -1, for example.
   */
  if(!sock_maybe_in_fdset(&readfds, sock))
  {
    errno = EINVAL;
    xperror("tl_selectr:FD_SETSIZE: b0rk"); /* barf hairball... */
    return -1;
  }

  /* sock has been fully bounds-checked; we're free to use it now: */
  FD_SET(sock, &readfds);
  FD_SET(sock, &exceptfds);

 ...

      rv = select(sock + 1, &readfds, NULL, &exceptfds, toutptr);

      diag(FD_ISSET(sock, &readfds), rv);
...


---------

The 'sock+1' in the select() is to appease the UNIXes, who need it to
know this way how many bits (flags) you might have set in those
fd_sets (assuming 'sock' is the handle with the highest numeric value
of them all) and UNIXes have a much simpler sock_maybe_in_fdset()
implementation as well:

int sock_maybe_in_fdset(fd_set * set, int sock)
{
  return (sock >= 0 && sock < FD_SETSIZE);
}


The above is working in publicly available code: the open source pavuk
web spider. The same trick has been applied by me in several
proprietary software pieces, including embedded setups. The names may
be different, the concept is the always the same.


The sysconf(_SC_OPEN_MAX) is nice, but since I've found that
FD_SETSIZE is always the smallest of both, where-ever I went (and the
only one driving the size of the actual fd_set type at that), I'll
stick with that #define. (I am happy to hear this empirical bit of
info from someone else as well, at least if I understood it right.)



In ultra-rare cases, I have tweaked and recompiled kernels to create
systems which could handle far more sockets than just the meager ;-)
usual defaults (1K, 4K) but one should do that kind of thing only when
you know **exactly** what you are doing and that includes tweaking the
FD_SETSIZE in the system header files as well, or it'ld be a job done
half. So FD_SETSIZE it is. I've found it on [Open]VMS, all the UNIXes
I visited to date (AIX, Sun, IRIX, HP/UX, ...), various Linux and BSD
flavors, several embedded TCP/IP stacks and even Microsoft Windows.

If only Microsoft hadn't been using their own HANDLE pointers, we
would have had it real easy.


HTH


-- 
Met vriendelijke groeten / Best regards,

Ger Hobbelt

--------------------------------------------------
web:    http://www.hobbelt.com/
        http://www.hebbut.net/
mail:   [EMAIL PROTECTED]
mobile: +31-6-11 120 978
--------------------------------------------------
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to