mirror of
https://github.com/nmap/nmap.git
synced 2026-01-03 13:19:04 +00:00
Make sockets temporarily blocking in ncat_send and ncat_broadcast.
It is possible to send so quickly that we start getting EAGAIN on sends. In listen mode, this means that some sends can get lost. This patch, adapted from one by Alex Weber, makes sockets blocking for the duration of the send. This is not as nice as retrying the send through an event mechanism, but should at least be correct. http://seclists.org/nmap-dev/2012/q3/670 Compare a similar patch in r13552, which applied to --exec mode.
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
# Nmap Changelog ($Id$); -*-text-*-
|
||||
|
||||
o [Ncat] Applied a blocking-socket workaround for a bug that could
|
||||
prevent some sends from working in listen mode. The problem was
|
||||
reported by Jonas Wielicki. [Alex Weber, David Fifield]
|
||||
|
||||
o Protocol scan (-sO) probes for TCP, UDP, and SCTP now go to ports
|
||||
80, 40125, and 80 respectively, instead of being randomly generated
|
||||
or going to the same port as the source port. [David Fifield]
|
||||
|
||||
@@ -291,6 +291,22 @@ int fdinfo_send(struct fdinfo *fdn, const char *buf, size_t size)
|
||||
return send(fdn->fd, buf, size, 0);
|
||||
}
|
||||
|
||||
/* If we are sending a large amount of data, we might momentarily run out of send
|
||||
space and get an EAGAIN when we send. Temporarily convert a socket to
|
||||
blocking more, do the send, and unblock it again. Assumes that the socket was
|
||||
in nonblocking mode to begin with; it has the side effect of leaving the
|
||||
socket nonblocking on return. */
|
||||
static int blocking_fdinfo_send(struct fdinfo *fdn, const char *buf, size_t size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
block_socket(fdn->fd);
|
||||
ret = fdinfo_send(fdn, buf, size);
|
||||
unblock_socket(fdn->fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ncat_send(struct fdinfo *fdn, const char *buf, size_t size)
|
||||
{
|
||||
int n;
|
||||
@@ -298,7 +314,7 @@ int ncat_send(struct fdinfo *fdn, const char *buf, size_t size)
|
||||
if (o.recvonly)
|
||||
return size;
|
||||
|
||||
n = fdinfo_send(fdn, buf, size);
|
||||
n = blocking_fdinfo_send(fdn, buf, size);
|
||||
if (n <= 0)
|
||||
return n;
|
||||
|
||||
@@ -323,7 +339,7 @@ int ncat_broadcast(fd_set *fds, const fd_list_t *fdlist, const char *msg, size_t
|
||||
continue;
|
||||
|
||||
fdn = get_fdinfo(fdlist, i);
|
||||
if (fdinfo_send(fdn, msg, size) <= 0) {
|
||||
if (blocking_fdinfo_send(fdn, msg, size) <= 0) {
|
||||
if (o.debug > 1)
|
||||
logdebug("Error sending to fd %d: %s.\n", i, socket_strerror(socket_errno()));
|
||||
ret = -1;
|
||||
|
||||
Reference in New Issue
Block a user