Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implemented WSA* calls for Windows.
  • Loading branch information
RoliSoft committed Oct 4, 2015
1 parent 83b7a21 commit 783052b
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 23 deletions.
76 changes: 54 additions & 22 deletions tcpscanner.cpp
@@ -1,5 +1,6 @@
#include "tcpscanner.h"
#include <boost/lexical_cast.hpp>
#include <iostream>

using namespace std;
using namespace boost;
Expand Down Expand Up @@ -111,12 +112,23 @@ void TcpScanner::initSocket(Service* service)
u_long mode = 1;
ioctlsocket(sock, FIONBIO, &mode);

// allocate file descriptor set
// set up the OS's choice of signaling for non-blocking sockets

#if Windows

WSAEVENT evt = WSACreateEvent();
WSAEventSelect(sock, evt, FD_WRITE);
WSAResetEvent(evt);
data->event = evt;

#elif Linux

data->fdset = new fd_set();
FD_ZERO(data->fdset);
FD_SET(sock, data->fdset);

#endif

// start non-blocking connection process

connect(sock, reinterpret_cast<struct sockaddr*>(info->ai_addr), info->ai_addrlen);
Expand All @@ -129,49 +141,57 @@ void TcpScanner::pollSocket(Service* service, bool last)
return;
}

TIMEVAL tv = { 0, 0 };
auto data = reinterpret_cast<TcpScanData*>(service->data);

// check if socket is writable, which basically means the connection was successful
#if Windows

// for some reason, Linux requires the first parameter to be counterintuitively socket+1, while Windows doesn't
// time spent searching for this error: ~1.5 hours
// check if the event was signalled

select(
data->socket
#if Linux
+ 1
#endif
, nullptr, data->fdset, nullptr, &tv
);
auto sigr = WSAWaitForMultipleEvents(1, &data->event, false, 0, false);
auto serr = WSAGetLastError();

// check if the writable flag is set
// the return value 258 is not documented in MSDN, however this
// is what seems to be returned in case of errors

auto isOpen = FD_ISSET(data->socket, data->fdset);
if (sigr == 258 && serr != WSAEWOULDBLOCK)
{
service->alive = false;
service->reason = AR_IcmpUnreachable;
}
else if (sigr == 0)
{
service->alive = true;
}

#if Linux
if (isOpen)
#elif Linux

// check if socket is writable

TIMEVAL tv = { 0, 0 };
select(data->socket + 1, nullptr, data->fdset, nullptr, &tv);

if (FD_ISSET(data->socket, data->fdset))
{
// yet again Linux decided to troll me. all select() requests will become "writable", and you have
// to check if there was an error or not, to actually determine if the connect() was successful
// since it seems writability bit will be set on connection refused errors,
// check if this is a legit instance of writable socket or an error

int serr;
socklen_t slen = sizeof(serr);
getsockopt(data->socket, SOL_SOCKET, SO_ERROR, &serr, &slen);
isOpen = serr == 0;

service->alive = serr == 0;

if (serr == ECONNREFUSED)
{
service->reason = AR_IcmpUnreachable;
}
}
#endif

service->alive = isOpen == 1;
#endif

// mark service accordingly

if (isOpen)
if (service->alive)
{
service->reason = AR_InProgress2;
readBanner(service, last);
Expand All @@ -185,8 +205,10 @@ void TcpScanner::pollSocket(Service* service, bool last)
}
else if (service->reason == AR_InProgress)
{
#if Linux
FD_ZERO(data->fdset);
FD_SET(data->socket, data->fdset);
#endif
return;
}
}
Expand All @@ -197,7 +219,12 @@ void TcpScanner::pollSocket(Service* service, bool last)

closesocket(data->socket);

#if Windows
WSACloseEvent(data->event);
#elif Linux
delete data->fdset;
#endif

delete data;
}

Expand Down Expand Up @@ -245,7 +272,12 @@ void TcpScanner::readBanner(Service* service, bool last)
shutdown(data->socket, SD_BOTH);
closesocket(data->socket);

#if Windows
WSACloseEvent(data->event);
#elif Linux
delete data->fdset;
#endif

delete data;
}

Expand Down
13 changes: 12 additions & 1 deletion tcpscanner.h
Expand Up @@ -13,11 +13,22 @@ struct TcpScanData
*/
SOCKET socket;

#if Windows

/*!
* File descriptor set for writability.
* Event object to be signalled on connection.
*/
WSAEVENT event;

#elif Linux

/*!
* File descriptor set to determine writability.
*/
fd_set* fdset;

#endif

};

/*!
Expand Down

0 comments on commit 783052b

Please sign in to comment.