libmicrohttpd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [libmicrohttpd] Sockets on Windows


From: Christian Grothoff
Subject: Re: [libmicrohttpd] Sockets on Windows
Date: Fri, 8 Jan 2010 16:58:48 +0100
User-agent: KMail/1.12.4 (Linux/2.6.31-1-amd64; KDE/4.3.4; x86_64; ; )

On Thursday 07 January 2010 23:36:12 Michael Lenaghan wrote:
> >> Christian, the following code (from MHD_start_daemon_va) is wrong for
> >> Windows:
> >
> > That's already fixed in SVN, thanks anyway for pointing it out.
> 
> These are still wrong:
> 
> In MHD_accept_connection:
> 
>   s = ACCEPT (daemon->socket_fd, addr, &addrlen);
>   if ((s < 0) || (addrlen <= 0)) {
>     ...
>   }
> 
> In MHD_start_daemon_va:
> 
>     socket_fd = SOCKET (PF_INET, SOCK_STREAM, 0);
>   if (socket_fd < 0) {
>     ...
>   }
> 
> Ideally you should test against INVALID_SOCKET. You can also test
> against "-1"--but then you'd be relying on an implicit signed/unsigned
> conversion.
> 
> >>  * You should check the total number of sockets being select()ed
> >> against FD_SETSIZE
> >
> > I think that should be checked anytime FD_SET() & friends are called, no?
> 
> In theory, yes; otherwise FD_SET() will fail silently if you add too
> many sockets to the set. But there's more to it than that. In the
> default config the maximum number of connections is constrained by
> FD_SETSIZE:
> 
> #define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE -4
> 
> So you'd only see that condition--ie, too many sockets for select--if
> someone increases max connections beyond FD_SETSIZE. Of course, at
> that point you have a problem waiting in the wings.

Not the only case.  You could also have an application using MHD that runs 
with the default but opens other files at the side (likely, in fact).  Then you 
might get socket numbers (!) >= FD_SETSIZE but the total number of connections 
(!) is still <= MHD_MAX_CONNECTIONS_DEFAULT.  So we need that check to avoid 
accessing memory out of bounds even if the maximum number of connections is 
less than FD_SETSIZE.
 
> I think you have two choices. You can constrain max connections to
> FD_SETSIZE on Windows--or you can allow it to grow beyond FD_SETSIZE.
> If you constrain it you never have to worry about checking the count.
> If you allow it to grow then you should define your own fd_set struct
> on the fly and size it either to the number of connections or to the
> number of max connections. (If you use your own FD_* routines Windows
> doesn't care how big the array is as long as the count of slots inside
> the fd_set struct is set correctly.)
> 
> On Windows FD_SETSIZE defaults to 64. Some people might think that's a
> bit small. There's a tradeoff in making it too big, though: if you
> selected on, say, 64 sockets you have to scan through 64 slots to find
> each socket after the call to select(). So it's an O(n^2) operation
> right in your innermost loop.

Also not entirely true; it's O(n), and the number of slots the app scans 
through is exactly the number of open connections, not FD_SETSIZE.  Similarly, 
the OS only scans from 0 to max where max it the largest socket number (which 
will be most likely very close to the number of open connections).
 
> Obviously, select() on Windows is not what you'd use if you were
> worried about heavy load--so I think constraining max connections
> would be reasonable.
 
As I mentioned above, this does not work.

Best,

Christian
-- 
http://grothoff.org/christian/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]