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