1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-22 06:09:01 +00:00

Ncat: Implement idle timeout option for listen mode

This patch implements "-i" (idle timeout) option for listen mode.

Signed-off-by: Tomas Hozza <thozza@redhat.com>
This commit is contained in:
david
2013-06-30 06:08:43 +00:00
parent af8c57a1b8
commit 5c4207f009
5 changed files with 58 additions and 7 deletions

View File

@@ -199,6 +199,8 @@ static int ncat_listen_stream(int proto)
{
int rc, i, fds_ready;
fd_set listen_fds;
struct timeval tv;
struct timeval *tvp = NULL;
/* clear out structs */
FD_ZERO(&master_readfds);
@@ -254,6 +256,9 @@ static int ncat_listen_stream(int proto)
init_fdlist(&broadcast_fdlist, o.conn_limit);
if (o.idletimeout > 0)
tvp = &tv;
while (1) {
/* We pass these temporary descriptor sets to fselect, since fselect
modifies the sets it receives. */
@@ -266,11 +271,17 @@ static int ncat_listen_stream(int proto)
if (o.debug > 1 && o.broker)
logdebug("Broker connection count is %d\n", get_conn_count());
fds_ready = fselect(client_fdlist.fdmax + 1, &readfds, &writefds, NULL, NULL);
if (o.idletimeout > 0)
ms_to_timeval(tvp, o.idletimeout);
fds_ready = fselect(client_fdlist.fdmax + 1, &readfds, &writefds, NULL, tvp);
if (o.debug > 1)
logdebug("select returned %d fds ready\n", fds_ready);
if (fds_ready == 0)
bye("Idle timeout expired (%d ms).", o.idletimeout);
/*
* FIXME: optimize this loop to look only at the fds in the fd list,
* doing it this way means that if you have one descriptor that is very
@@ -584,6 +595,8 @@ static int ncat_listen_dgram(int proto)
fd_set read_fds;
union sockaddr_u remotess;
socklen_t sslen = sizeof(remotess.storage);
struct timeval tv;
struct timeval *tvp = NULL;
for (i = 0; i < NUM_LISTEN_ADDRS; i++) {
sockfd[i] = -1;
@@ -618,6 +631,9 @@ static int ncat_listen_dgram(int proto)
add_fd(&listen_fdlist, sockfd[i]);
}
if (o.idletimeout > 0)
tvp = &tv;
while (1) {
int i, j, conn_count, socket_n;
@@ -643,11 +659,17 @@ static int ncat_listen_dgram(int proto)
if (o.debug > 1)
logdebug("selecting, fdmax %d\n", listen_fdlist.fdmax);
fds = listen_fds;
fds_ready = fselect(listen_fdlist.fdmax + 1, &fds, NULL, NULL, NULL);
if (o.idletimeout > 0)
ms_to_timeval(tvp, o.idletimeout);
fds_ready = fselect(listen_fdlist.fdmax + 1, &fds, NULL, NULL, tvp);
if (o.debug > 1)
logdebug("select returned %d fds ready\n", fds_ready);
if (fds_ready == 0)
bye("Idle timeout expired (%d ms).", o.idletimeout);
/*
* Figure out which listening socket got a connection. This loop should
@@ -755,7 +777,13 @@ static int ncat_listen_dgram(int proto)
if (o.debug > 1)
logdebug("udp select'ing\n");
fds_ready = fselect(fdmax + 1, &fds, NULL, NULL, NULL);
if (o.idletimeout > 0)
ms_to_timeval(tvp, o.idletimeout);
fds_ready = fselect(fdmax + 1, &fds, NULL, NULL, tvp);
if (fds_ready == 0)
bye("Idle timeout expired (%d ms).", o.idletimeout);
if (FD_ISSET(STDIN_FILENO, &fds)) {
nbytes = Read(STDIN_FILENO, buf, sizeof(buf));

View File

@@ -822,9 +822,6 @@ static int ncat_listen_mode(void)
if (httpconnect.storage.ss_family != AF_UNSPEC || socksconnect.storage.ss_family != AF_UNSPEC)
bye("Invalid option combination: --proxy and -l.");
if (o.idletimeout != 0)
bye("An idle timeout only works in connect mode.");
if (o.broker && o.cmdexec != NULL)
bye("Invalid option combination: --broker and -e.");

View File

@@ -158,6 +158,8 @@ int ncat_http_server(void)
int listen_socket[NUM_LISTEN_ADDRS];
socklen_t sslen;
union sockaddr_u conn;
struct timeval tv;
struct timeval *tvp = NULL;
#ifndef WIN32
Signal(SIGCHLD, proxyreaper);
@@ -194,6 +196,9 @@ int ncat_http_server(void)
}
if (o.idletimeout > 0)
tvp = &tv;
for (;;) {
fd_set read_fds;
@@ -204,11 +209,18 @@ int ncat_http_server(void)
if (o.debug > 1)
logdebug("selecting, fdmax %d\n", listen_fdlist.fdmax);
read_fds = listen_fds;
int fds_ready = fselect(listen_fdlist.fdmax + 1, &read_fds, NULL, NULL, NULL);
if (o.idletimeout > 0)
ms_to_timeval(tvp, o.idletimeout);
int fds_ready = fselect(listen_fdlist.fdmax + 1, &read_fds, NULL, NULL, tvp);
if (o.debug > 1)
logdebug("select returned %d fds ready\n", fds_ready);
if (fds_ready == 0)
bye("Idle timeout expired (%d ms).", o.idletimeout);
for (i = 0; i <= listen_fdlist.fdmax && fds_ready > 0; i++) {
/* Loop through descriptors until there is something ready */
if (!FD_ISSET(i, &read_fds))

View File

@@ -506,6 +506,17 @@ int allow_access(const union sockaddr_u *su)
return 1;
}
/*
* Fills the given timeval struct with proper
* values based on the given time in milliseconds.
* The pointer to timeval struct must NOT be NULL.
*/
void ms_to_timeval(struct timeval *tv, long ms)
{
tv->tv_sec = ms / 1000;
tv->tv_usec = (ms - (tv->tv_sec * 1000)) * 1000;
}
/*
* ugly code to maintain our list of fds so we can have proper fdmax for
* select(). really this should be generic list code, not this silly bit of

View File

@@ -165,6 +165,9 @@ unsigned char *buildsrcrte(struct in_addr dstaddr, struct in_addr routes[],
int allow_access(const union sockaddr_u *su);
void ms_to_timeval(struct timeval *tv, long ms)
__attribute__ ((nonnull));
struct fdinfo {
int fd;
union sockaddr_u remoteaddr;