Reputation: 41
I inherited a C++/Windows project where we have an SNMP extension agent (loaded by SNMP service). Inside the agent, we are creating a simple TCP server to which our client applications connect and provide it with data for SNMP queries/traps etc. This all seems to work fine on Windows Server 2008. However, on Windows Server 2012, the client can no longer connect to the server running inside the agent (in SNMP service). The connect() fails with error 10013.
My server code looks something like this:
fd_set master_set;
fd_set readfds;
SOCKET listener;
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
{
OutputDebugStringA("WSAStartup failed\n");
return -1;
}
FD_ZERO(&master_set);
FD_ZERO(&readfds);
//----------------------
// Create a SOCKET for listening for
// incoming connection requests.
listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listener == INVALID_SOCKET) {
OutputDebugStringA("socket failed with error:\n");
return -1;
}
int reuse_addr = 1;
setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse_addr, sizeof(reuse_addr));
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being bound.
sockaddr_in service = { 0 };
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("127.0.0.1");
service.sin_port = htons(27015);
if (bind(listener, (SOCKADDR *)& service, sizeof(service)) == SOCKET_ERROR)
{
printf("bind failed with error: %d \n", WSAGetLastError());
closesocket(listener);
return -1;
}
if (listen(listener, 5) == SOCKET_ERROR)
{
OutputDebugStringA("listen failed with error\n");
closesocket(listener);
return -1;
}
u_long NonBlock = 1;
if (ioctlsocket(listener, FIONBIO, &NonBlock) == SOCKET_ERROR)
{
OutputDebugStringA("ioctlsocket() failed with error\n");
return -1;
}
FD_SET(listener, &master_set);
timeval timeout;
timeout.tv_sec = 3;
timeout.tv_usec = 0;
printf("Started Server on port %d\n", 27015);
for (;;)
{
readfds = master_set;
int ret = select(0, &readfds, NULL, NULL, &timeout);
if (ret == 0)
{
// Time out // Check if we need to shutdown
continue;
}
if (ret < 0)
{
printf("Error in Socket select\n");
return -1;
}
for (int i = 0; i < readfds.fd_count; i++)
{
SOCKET xfd = readfds.fd_array[i];
if (xfd == listener)
{
// New Connection.
SOCKET new_fd = HandleNewConnection(listener);
if (new_fd == -1)
{
printf("Error Accepting new connection");
continue;
}
FD_SET(new_fd, &master_set);
printf("Accepted new Connection\n");
continue;
}
else
{
if (!HandleIncomingData(xfd))
{
closesocket(xfd);
FD_CLR(xfd, &master_set);
continue;
}
}
}
}
SOCKET HandleNewConnection(SOCKET listener)
{
SOCKET newfd = accept(listener, (sockaddr*)NULL, (int*)NULL);
u_long NonBlock = 1;
ioctlsocket(newfd, FIONBIO, &NonBlock);
return newfd;
}
bool HandleIncomingData(SOCKET fd)
{
char buffer[16] = { 0 };
int recv_bytes = -1;
if ((recv_bytes = recv(fd, buffer, 16, 0)) <= 0)
{
printf("Connection Closed/ Error in Recieving");
return false;
}
printf("recieved %d bytes\n", recv_bytes);
return true;
}
The select continues to timeout every 3 seconds without any connection getting accepted.
Here's all that I have tried (none worked):
For quick tests I am just doing telnet to port 27015.
Upvotes: 0
Views: 3510
Reputation: 1
I could solve it following these steps (found in http://www-01.ibm.com/support/docview.wss?uid=nas7ba16117761f1f93b86257f73000cff77)
Upvotes: 0
Reputation: 41
I solved the problem. The issue was due to Windows Service Hardening which did not allow any TCP communication from snmp service (and extensions). This is enforced even if the firewall is turned off.
https://support.microsoft.com/en-us/kb/2771908
Upvotes: 2