1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-10 09:49:05 +00:00

Merged nsock-engines from nmap-exp. This rewrite of the nsock library adds

support for system-specific scalable IO notification facilities without breaking
portability. This initial version comes with an epoll(7)-based engine for Linux
and a select(2)-based fallback engine for all other operating systems.

This required an important refactoring of the library but the external API was
preserved.

The rewrite also tries to bring the coding standards of nmap to nsock.

See http://labs.unix-junkies.org/nsock_engines.html for the details.
This commit is contained in:
henri
2012-01-05 01:08:16 +00:00
parent 15f74d395f
commit 856cd00a17
31 changed files with 4496 additions and 2774 deletions

View File

@@ -1,4 +1,3 @@
/***************************************************************************
* nsock_write.c -- This contains the functions relating to writing to *
* sockets using the nsock parallel socket event library *
@@ -63,21 +62,18 @@
#include <stdarg.h>
#include <errno.h>
nsock_event_id nsock_sendto(nsock_pool ms_pool, nsock_iod ms_iod,
nsock_ev_handler handler, int timeout_msecs,
void *userdata, struct sockaddr *saddr, size_t sslen,
unsigned short port, const char *data, int datalen) {
mspool *nsp = (mspool *) ms_pool;
msiod *nsi = (msiod *) ms_iod;
nsock_event_id nsock_sendto(nsock_pool ms_pool, nsock_iod ms_iod, nsock_ev_handler handler, int timeout_msecs,
void *userdata, struct sockaddr *saddr, size_t sslen, unsigned short port, const char *data, int datalen) {
mspool *nsp = (mspool *)ms_pool;
msiod *nsi = (msiod *)ms_iod;
msevent *nse;
char displaystr[256];
struct sockaddr_in *sin = (struct sockaddr_in *) saddr;
struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
#if HAVE_IPV6
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) saddr;
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)saddr;
#endif
nse = msevent_new(nsp, NSE_TYPE_WRITE, nsi, timeout_msecs, handler,
userdata);
nse = msevent_new(nsp, NSE_TYPE_WRITE, nsi, timeout_msecs, handler, userdata);
assert(nse);
if (sin->sin_family == AF_INET) {
@@ -100,7 +96,7 @@ nsock_event_id nsock_sendto(nsock_pool ms_pool, nsock_iod ms_iod,
nse->iod->peerlen = sslen;
if (datalen < 0)
datalen = (int) strlen(data);
datalen = (int) strlen(data);
if (nsp->tracelevel > 0) {
if (nsp->tracelevel > 1 && datalen < 80) {
@@ -112,11 +108,11 @@ nsock_event_id nsock_sendto(nsock_pool ms_pool, nsock_iod ms_iod,
displaystr[0] = '\0';
}
nsock_trace(nsp, "Sendto request for %d bytes to IOD #%li EID %li [%s:%hu]%s",
datalen, nsi->id, nse->id,
inet_ntop_ez(&nse->writeinfo.dest, nse->writeinfo.destlen), port,
displaystr);
datalen, nsi->id, nse->id,
inet_ntop_ez(&nse->writeinfo.dest, nse->writeinfo.destlen), port,
displaystr);
}
fscat(&nse->iobuf, data, datalen);
nsp_add_event(nsp, nse);
@@ -124,17 +120,18 @@ nsock_event_id nsock_sendto(nsock_pool ms_pool, nsock_iod ms_iod,
return nse->id;
}
/* Write some data to the socket. If the write is not COMPLETED within timeout_msecs , NSE_STATUS_TIMEOUT will be returned. If you are supplying NUL-terminated data, you can optionally pass -1 for datalen and nsock_write will figure out the length itself */
nsock_event_id nsock_write(nsock_pool ms_pool, nsock_iod ms_iod,
nsock_ev_handler handler, int timeout_msecs,
void *userdata, const char *data, int datalen) {
mspool *nsp = (mspool *) ms_pool;
msiod *nsi = (msiod *) ms_iod;
/* Write some data to the socket. If the write is not COMPLETED within
* timeout_msecs , NSE_STATUS_TIMEOUT will be returned. If you are supplying
* NUL-terminated data, you can optionally pass -1 for datalen and nsock_write
* will figure out the length itself */
nsock_event_id nsock_write(nsock_pool ms_pool, nsock_iod ms_iod,
nsock_ev_handler handler, int timeout_msecs, void *userdata, const char *data, int datalen) {
mspool *nsp = (mspool *)ms_pool;
msiod *nsi = (msiod *)ms_iod;
msevent *nse;
char displaystr[256];
nse = msevent_new(nsp, NSE_TYPE_WRITE, nsi, timeout_msecs, handler,
userdata);
nse = msevent_new(nsp, NSE_TYPE_WRITE, nsi, timeout_msecs, handler, userdata);
assert(nse);
nse->writeinfo.dest.ss_family = AF_UNSPEC;
@@ -150,27 +147,25 @@ nsock_event_id nsock_write(nsock_pool ms_pool, nsock_iod ms_iod,
replacenonprintable(displaystr + 2, datalen, '.');
} else displaystr[0] = '\0';
if (nsi->peerlen > 0)
nsock_trace(nsp, "Write request for %d bytes to IOD #%li EID %li [%s:%hu]%s", datalen, nsi->id,
nse->id, inet_ntop_ez(&nsi->peer, nsi->peerlen), nsi_peerport(nsi), displaystr);
else
nsock_trace(nsp, "Write request for %d bytes to IOD #%li EID %li (peer unspecified)%s", datalen,
nsi->id, nse->id, displaystr);
nsock_trace(nsp, "Write request for %d bytes to IOD #%li EID %li [%s:%d]%s", datalen, nsi->id,
nse->id, inet_ntop_ez(&nsi->peer, nsi->peerlen), nsi_peerport(nsi), displaystr);
else
nsock_trace(nsp, "Write request for %d bytes to IOD #%li EID %li (peer unspecified)%s", datalen,
nsi->id, nse->id, displaystr);
}
fscat(&nse->iobuf, data, datalen);
nsp_add_event(nsp, nse);
return nse->id;
}
/* Same as nsock_write except you can use a printf-style format and you can only use this for ASCII strings */
nsock_event_id nsock_printf(nsock_pool ms_pool, nsock_iod ms_iod,
nsock_ev_handler handler, int timeout_msecs,
void *userdata, char *format, ... ) {
mspool *nsp = (mspool *) ms_pool;
msiod *nsi = (msiod *) ms_iod;
nsock_event_id nsock_printf(nsock_pool ms_pool, nsock_iod ms_iod,
nsock_ev_handler handler, int timeout_msecs, void *userdata, char *format, ... ) {
mspool *nsp = (mspool *)ms_pool;
msiod *nsi = (msiod *)ms_iod;
msevent *nse;
char buf[4096];
char *buf2 = NULL;
@@ -178,11 +173,10 @@ nsock_event_id nsock_printf(nsock_pool ms_pool, nsock_iod ms_iod,
int strlength = 0;
char displaystr[256];
va_list ap;
va_list ap;
va_start(ap,format);
nse = msevent_new(nsp, NSE_TYPE_WRITE, nsi, timeout_msecs, handler,
userdata);
nse = msevent_new(nsp, NSE_TYPE_WRITE, nsi, timeout_msecs, handler, userdata);
assert(nse);
res = Vsnprintf(buf, sizeof(buf), format, ap);
@@ -190,12 +184,13 @@ nsock_event_id nsock_printf(nsock_pool ms_pool, nsock_iod ms_iod,
if (res != -1) {
if (res > sizeof(buf)) {
buf2 = (char * ) safe_malloc(res + 16);
buf2 = (char * )safe_malloc(res + 16);
res2 = Vsnprintf(buf2, sizeof(buf), format, ap);
if (res2 == -1 || res2 > res) {
free(buf2);
buf2 = NULL;
} else strlength = res2;
free(buf2);
buf2 = NULL;
} else
strlength = res2;
} else {
buf2 = buf;
strlength = res;
@@ -209,8 +204,8 @@ nsock_event_id nsock_printf(nsock_pool ms_pool, nsock_iod ms_iod,
} else {
if (strlength == 0) {
nse->event_done = 1;
nse->status = NSE_STATUS_SUCCESS;
} else {
nse->status = NSE_STATUS_SUCCESS;
} else {
fscat(&nse->iobuf, buf2, strlength);
}
}
@@ -221,18 +216,19 @@ nsock_event_id nsock_printf(nsock_pool ms_pool, nsock_iod ms_iod,
memcpy(displaystr + 2, buf2, strlength);
displaystr[2 + strlength] = '\0';
replacenonprintable(displaystr + 2, strlength, '.');
} else displaystr[0] = '\0';
} else {
displaystr[0] = '\0';
}
if (nsi->peerlen > 0)
nsock_trace(nsp, "Write request for %d bytes to IOD #%li EID %li [%s:%hu]%s", strlength, nsi->id,
nse->id, inet_ntop_ez(&nsi->peer, nsi->peerlen), nsi_peerport(nsi), displaystr);
else
nsock_trace(nsp, "Write request for %d bytes to IOD #%li EID %li (peer unspecified)%s", strlength,
nsi->id, nse->id, displaystr);
nsock_trace(nsp, "Write request for %d bytes to IOD #%li EID %li [%s:%d]%s", strlength, nsi->id,
nse->id, inet_ntop_ez(&nsi->peer, nsi->peerlen), nsi_peerport(nsi), displaystr);
else
nsock_trace(nsp, "Write request for %d bytes to IOD #%li EID %li (peer unspecified)%s", strlength,
nsi->id, nse->id, displaystr);
}
if (buf2 != buf) {
if (buf2 != buf)
free(buf2);
}
nsp_add_event(nsp, nse);