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:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user