Nmap Development mailing list archives

Re: NPing running out of sockets


From: David Fifield <david () bamsoftware com>
Date: Sat, 16 Oct 2010 10:43:09 -0700

On Sat, Oct 16, 2010 at 03:12:24PM +0200, Luis MartinGarcia. wrote:
On 10/15/2010 10:33 PM, David Fifield wrote:

+#ifndef MACOSX
+    #define MAX_IODS 1000  /**< Max number of IODs open at the same time */
+#else
+    #define MAX_IODS 250
+#endif
    
Why does this work, Luis?

That's a good question. The thing is that for unprivileged modes
(TCP-connect and UDP-unpriv), Nping needs to use one socket per probe.
It probably doesn't need that many sockets for the UDP case, as you
pointed out before (that's why I said the patch is only temporary), but
it does need them for the TCP connection attempts. What is also true is
that Nping cannot just allocate space for unlimited socket/IOD
structures or have unlimited descriptors opened. I tried to solved this
problem by having an array of nsock descriptors of length "MAX_IODS"
where the return value of nsi_new() could be stored. What happens is
that when Nping has opened MAX_IODS descriptors, Nping just takes the
oldest IOD, closes the descriptor, and uses that position of the array
to hold a new IOD.

For example, in ProbeMode.cc::probe_tcpconnect_event_handler() you can
see the following:

        if( packetno>MAX_IODS ){
            nsi_delete(fds[packetno%MAX_IODS], NSOCK_PENDING_SILENT);
        }
        /* Create new IOD for connects */
        if ((fds[packetno%MAX_IODS] = nsi_new(nsp, NULL)) == NULL)
            outFatal(QT_3, "tcpconnect_event_handler(): Failed to create
new nsock_iod.\n");


So why does the #define MAX_IODS 250 work? Because on MACOSX,
unprivileged user processes may only have 256 open files by default,
while on Linux that number is 1024. So when 250 descriptors have been
opened, the oldest one is closed and the process never exceeds the
limit. I chose MAX_IODS values smaller than the limit to be on the safe
side because processes already start with at least 3 opened descriptors,
the echo mode may request additional iods, a "read payload from a file"
feature may be implemented at some point, etc.

Does this sound reasonable? I think it's OK at least for TCP-connect but
it may not be the best choice for UDP. Do you think we can/should start
using the new unconnected UDP sockets functionality in nsock?

Yeah, this looks good. It's better if you can ask the system for the
limit instead of basing it on a heuristic like MACOSX. The function
max_sd in tcpip.cc shows how to get the open descriptor limit. In
ConnectScanInfo::ConnectScanInfo in scan_engine.cc, I found that you
have to be at least 5 fewer than the limit on OS X.

If this works for UDP as well, it's fine. Using an unconnected socket
might be easier because you only need one of them, but you don't have to
do that if the current system works well.

David Fifield
_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://seclists.org/nmap-dev/


Current thread: