libbind / FD_SETSIZE question (on Windows)
Stefan Puiu
stefanpuiu at itcnetworks.ro
Wed Dec 15 15:29:59 UTC 2004
Hello,
first of all, this is a question regarding libbind code; if this is not
the right place to ask, please point me to the right list.
we are using libbind 8.2.7 for an app that needs to do DDNS updates
(however, the code I'm talking about is still there in 8.4.5). Our app
calls res_nsendsigned(), which in turn calls res_nsend(), for sending
some updates. However, on Windows, after some stress testing,
res_nsendsigned() would begin to return error, setting the errno
(actually, the value returned by WSAGetLastError()) to 10038, which is
WSAENOTSOCK. From what I could make out of the source, this error code
is set in lib/resolv/res_send.c from the libbind code, in the send_dg()
function (this one seems to get called, favouring UDP over TCP as
expected). In BIND 8.4.5, the code looks like this (line numbers on the
left):
770 if (EXT(statp).nssocks[ns] == -1) {
771 EXT(statp).nssocks[ns] = socket(nsap->sa_family,
SOCK_DGRAM, 0);
772 if (EXT(statp).nssocks[ns] > highestFD) {
773 res_nclose(statp);
774 errno = ENOTSOCK;
775 }
highestFD is FD_SETSIZE-1, which, on Windows, seems to be equal to
16383. However, I'm having a hard time understanding why somebody would
want to limit the range of values returned by socket() that are
considered "valid" - unless they'd expect socket() to return the first
available free descriptor. On Windows, if you create 20.000 sockets,
then close them all, then try creating a new one, the descriptor that is
returned to you doesn't seem to be the lowest available, but the next
after the one returned by the last socket() call - we've observed this
behaviour with a simple test program. So, if at a certain point a socket
with fd 16383 is created, then most likely all subsequent calls to
send_dg() will fail, because socket() will return a value too big, even
though there wouldn't be 16383 descriptors actually open. If FD_SETSIZE
is supposed to limit the number of open descriptors, this piece of code
doesn't seem to achieve it; it breaks libbind apps running on Windows
instead.
What I'm asking is: why is FD_SETSIZE needed? And of how much use is
this in the aforementioned situation? Is there a way to work around this
problem (like using some other function in libbind for sending packets)?
More information about the bind-users
mailing list