Create multiple listening sockets - c++

I'm using winsocks and I am coding an IDS/Honeypot, this is just a small section of it, because at the moment I want the server to listen on multiple sockets (7) and accept the connections, but I've tried to dynamically create the sockets with an array (and the listener etc) but I am still having trouble - I've tried it multiple ways but so far, all I've managed to do is get it working successfully on ONE socket, and LISTEN to all sockets, but not accept them.
So, this was my last attempt but not sure, maybe I need to use threads or declare the sockets differently?
So far, in this small test code, I want:
Initialize server
listen on all 7 ports (1111,2222 ...etc)
Accept an incoming connection on ANY of them
display both messages on client/server
drop the connection
and continue
It's a little sloppy I know, but here is the code so far and I think you can see where I am going with it:
#include <iostream>
#include <winsock2.h>
#include <string>
#pragma comment(lib, "ws2_32.lib")
int main()
{
std::cout<<"Honeypot server [test #1] by Dreamwalker"<<std::endl;
WSADATA wsa;
SOCKET s[7] , new_socket[7];
struct sockaddr_in server , client;
int c, port[7] = {1111,2222,3333,4444,5555,6666,7777};
char *message;
std::cout<<"\nInitialising Winsock and other components...";
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
std::cout<<"Failed. Error Code :"<<WSAGetLastError()<<std::endl;
return 1;
}
//!IMPORTANT: create multiple new sockets on different ports
int i = 0;
for( i = 0; i < 7; i++)
{
//Create socket
if((s[i] = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
{
std::cout<<"Could not create socket : "<< WSAGetLastError()<<std::endl;
}
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( port[i] );
//Bind
if( bind(s[i] ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
{
std::cout<<"Bind failed with error code : "<< WSAGetLastError()<<std::endl;
}
/*!ALL CREATION CHECKING DONE, now create multiple sockets on the server
and listen for connections*/
c = sizeof(struct sockaddr_in);
listen(s[i] , SOMAXCONN);
}
///ALL INITIALIZED
std::cout<<"DONE!"<<std::endl;
//Listen/accept incoming connections
std::cout<<"Now listening for connections"<<std::endl;
new_socket[i] = accept(s[i] , (struct sockaddr *)&client, &c);
if (new_socket[i] == INVALID_SOCKET)
{
std::cout<<"accept failed with error code : "<< WSAGetLastError()<<std::endl;
}
//Accepted connection
else{
std::cout<<"Someone has connected to this machine!"<<std::endl;
message = "Hello Client , I have received your connection.\n";
send(new_socket[i] , message , strlen(message) , 0);
closesocket(s[i]);
}
std::cout<<"FINISHED"<<std::endl;
WSACleanup();
getchar();
return 0;
}
And now it's throwing a runtime error as well:
WSAENOTSOCK
10038
Socket operation on nonsocket.
An operation was attempted on something that is not a socket. Either the socket handle parameter did not reference a valid socket,
or for select, a member of an fd_set was not valid.
Which (including debugging) indicates that the socket isn't declared properly when creating on an array, advice?

You code to create/bind/listen is all good. Then:
new_socket[i] = accept(s[i] , (struct sockaddr *)&client, &c);
Firstly, by the time this runs you're outside the loop, and i is 7 which is past the end of the array of sockets, which is why you get the not-a-socket error.
Secondly, accept() is a blocking call, so you can't just call accept() on all the sockets from the same thread the way you did for listen. You need to either have a separate thread block in accept() for each of the ports, or find out which one has a client connection attempt in progress using e.g. select (or epoll - does Windows have that?), then accept() a client on that specific socket (but then you've still got to either create a thread to handle the client read/recvs and write/sends or use select/epoll to find out when there's input ready to read, or more space in output buffers for transmission). There's also a race condition to be wary of if you use select/epoll - a listening socket might signal readiness for accepting a client connection, but by the time you call accept() that connection attempt's failed and forgotten, then if the listening socket hasn't been set to non-blocking mode it'll hang there waiting for another client to connect to that specific socket. IMHO, this is a case where threading is actually easier.
I think it's more "Windowsy" to use IO Completion Ports (you might want to Google), but AFAIK they're totally unportable. Winsock's not an exact match for BSD sockets, but the porting or dual-support effort's small.

Related

C++ Winsock Accept Memory leak/Resource Leak

I have written a small test tcp listener. Said listener listens over port 28328 and works fantastic, expect for the huge resource/memory leak that happens every single time a client connects to it.
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
SOCKET Socket = INVALID_SOCKET;
bool TestServer()
{
WSADATA wsaData = { 0 };
if (WSAStartup(MAKEWORD(2, 2), &wsaData))
return false;
sockaddr_in addr = { 0 };
Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
int Enable = 1;
setsockopt(Socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&Enable, sizeof(int));
addr.sin_family = AF_INET;
addr.sin_port = htons(28328);
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(Socket, (sockaddr*)&addr, sizeof(sockaddr)))
return false;
if (listen(Socket, 50))
return false;
return true;
}
void Dolisten()
{
if (TestServer())
{
sockaddr_in addr = { 0 };
SOCKET Client_Socket = 0;
int Lenght = sizeof(addr);
for (;;)
{
Client_Socket = INVALID_SOCKET;
Client_Socket = accept(Socket, (struct sockaddr *)&addr, &Lenght);
if (Client_Socket == INVALID_SOCKET)
continue;
printf("Client Connected %X\n", Client_Socket);
shutdown(Client_Socket, 2);
closesocket(Client_Socket);
}
}
}
int main(int argc, char* argv[])
{
Dolisten();
WSACleanup();
return 0;
}
While the original listener is much bigger than this and probably has a lot more problems which I haven't gotten to yet, as of right now this my biggest issue.
I assume that the issue occurs as a result of accepting of the socket and it not closing properly which then leaks to a handle leak. I base this on the fact that when I looked at task manager and other tools that monitor a process I can see the handle count increasing at the same rate as my connection happen.
Note:
1) By the looks of it the leak happens on the Non-Paged Memory.
2) This same snippet of code if compiled and used in a linux environment will not yield the same memory/resource leak.
3) I have compiled and tested this code on multiple windows machines and the same problem occurs.
4) (EDIT) I did see a couple of people with this exact problem posting on some of the MSDN forums and VS forums but all they were told to do was submit a ticket.
There's no memory leak in the application you have shown.
Due to the way TCP/IP works, resources associated with closed connections can not be freed immediately. Packets may arrive out of order or be retransmitted after the connection has been closed. So even after a call to closesocket the actual OS socket remains open for a predefined amount of time (usually 2-3 minutes, can be adjusted with TcpTimedWaitDelay).
If you run netstat -an, you'll see a bunch of connections in CLOSE_WAIT or TIME_WAIT state:
TCP 127.0.0.1:28328 127.0.0.1:56508 TIME_WAIT
TCP 127.0.0.1:28328 127.0.0.1:56510 TIME_WAIT
TCP 127.0.0.1:28328 127.0.0.1:56512 TIME_WAIT
TCP 127.0.0.1:28328 127.0.0.1:56514 TIME_WAIT
TCP 127.0.0.1:28328 127.0.0.1:56516 TIME_WAIT
. . .
Of course (kernel) memory is needed to store these temporary states.
In addition, the TCP port number from the ephemeral range cannot be reused immediately, which means the rate at which you can open/close connections is quite limited.
The non-paged-pool is a kernel resource, and relates to memory which can not be paged by the operating system, and is a scarce resource. So keeping an eye on it, is a good thing.
The fact it is in kernel, means the memory is not directly in your control. It may be that the memory relates to un-sent, un-processed packets, which case the resource is the responsibility of your program indirectly.
Check for the handle leak - where that is coming from. Application Verifier Microsoft : Application Verifier download can help identify the call stacks which are leaking memory and handles.

Client connects to server but server does not think client has connected in C++

I have a C++ program, using mpi, that follows a typical client server model. Each mpi instance of the client connects to a corresponding mpi instance of the server. This has worked relatively well until I have had to do some testing with added latency (1 second of added latency to be precise).
Problem:
Sometimes one of the server processes do not think the client has connected but the client thinks it has connected. i.e. After using gdb, the server is waiting at accept() but the client has continued on past connect(). Thus, it appears the client thinks it has connected when the server does not think it has connected.
My best guess is that I need to set an sock-option somewhere, however talking to fellow programmers and googling has not yielded any helpful results.
EDIT:
There are two sets of MPI processes (so two different calls to mpirun), the accept() and connect() calls are for the sockets, which are between the two sets of MPI processes. It is openmpi.
The code (from someone else's code, actually) [reduced]:
Client (connect code): (m_socket is the actual socket)
if (-1 == m_socket)
{
perror("cannot create socket");
exit(EXIT_FAILURE);
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
res = inet_pton(AF_INET, host_ip, &addr.sin_addr);
if (0 > res)
{
perror("error: first parameter is not a valid address family");
close(m_socket);
exit(EXIT_FAILURE);
}
else if (0 == res)
{
perror("error: second parameter does not contain valid IP address");
close(m_socket);
exit(EXIT_FAILURE);
}
//backoff
for (int sec = 1; sec < 20000; sec++ )
{
int ret;
if (0 == (ret = connect(m_socket, (struct sockaddr *)&addr, sizeof(addr))))
{
return;
}
sleep(1);
close(m_socket);
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
}
perror("connect failed");
close(m_socket);
exit(EXIT_FAILURE);
Server: (m_socket is the actual socket)
int socket = ::accept(m_socket, NULL, NULL);
if(socket < 0)
{
fprintf(stderr, "accept() failed: %s\n", strerror(errno));
close(m_socket);
exit(EXIT_FAILURE);
}
It looks like you're trying to do your connect/accept manually rather than with MPI. You might take a look at the example on Deino (http://mpi.deino.net/mpi_functions/MPI_Comm_accept.html) if you're trying to use MPI for your connections.
Alternatively, you might just need to look at a more general tutorial (some available here: http://www.mcs.anl.gov/research/projects/mpi/tutorial/) of MPI to get a feel for how communication works. Most of the time and application doesn't use Connect/Accept to communicate, but uses MPI Communicators to set up communication mechanisms between processes. It's a different model (SPMD as opposed to MPMD).

C or C++ with libevent/libev: monitor a unix socket

I'm trying to monitor a unix socket ("/tmp/mysocket").
I can do this fine in Node.js: it raises an event when 1) a socket is bound, 2) someone connects to the socket, 3) data is sent to the socket and 4) the socket is disconnected.
I'm trying to now do this in C/C++: I want to monitor "/tmp/mysocket" for the above events. I've looked at libevent (which I'd preferably like to use), but see that it requires an IP:port. Is there any way to monitor unix sockets?
Or can anyone suggest another C/C++ solution?
You could monitor a UNIX domain socket just like a regular file, since it can be operated like a file, e.g. in libev,
struct sockaddr_un address;
memset(&address, 0, sizeof(address));
address.sun_family = AF_LOCAL;
strcpy(address.sun_path, "/tmp/mysocket");
bind(socket, (struct sockaddr*)(&address), sizeof(address));
listen(socket, 5);
// now listen if someone has connected to the socket.
// we use 'ev_io' since the 'socket' can be treated as a file descriptor.
struct ev_io* io = malloc(sizeof(ev_io));
ev_io_init(io, accept_cb, socket, EV_READ);
ev_io_start(loop, io);
...
void accept_cb(struct ev_loop* loop, struct ev_io* io, int r)
{
// someone has connected. we accept the child.
struct sockaddr_un client_address;
socklen_t client_address_len = sizeof(client_address);
int client_fd = accept(socket, (sockaddr*)(&client_address),
&client_address_len);
// 'read' / 'recv' from client_fd here.
// or use another 'ev_io' for async read.
}
libevent should be similar.

Socket send recv functions

I have created a socket using the following lines of code.
Now i change the value of the socket i get like this
m_Socket++;
Even now the send recv socket functions succeeds without throwing SOCKET_ERROR.
I expect that it must throw error.
Am i doing something wrong.
struct sockaddr_in ServerSock; // Socket address structure to bind the Port Number to listen to
char *localIP ;
SOCKET SocServer;
//To Set up the sockaddr structure
ServerSock.sin_family = AF_INET;
ServerSock.sin_addr.s_addr = INADDR_ANY;
ServerSock.sin_port = htons(pLantronics->m_wRIPortNo);
// To Create a socket for listening on wPortNumber
if(( SocServer = socket( AF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET )
{
return FALSE;
}
//To bind the socket with wPortNumber
if(bind(SocServer,(sockaddr*)&ServerSock,sizeof(ServerSock))!=0)
{
return FALSE;
}
// To Listen for the connection on wPortNumber
if(listen(SocServer,SOMAXCONN)!=0)
{
return FALSE;
}
// Structure to get the IP Address of the connecting Entity
sockaddr_in insock;
int insocklen=sizeof(insock);
//To accept the Incoming connection on the wPortNumber
pLantronics->m_Socket=accept(SocServer,(struct sockaddr*)&insock,&insocklen);
if(pLantronics->m_Socket == INVALID_SOCKET)
{
shutdown(SocServer, 2 );
closesocket(SocServer );
return FALSE;
}
// To make socket non-blocking
DWORD dwNonBlocking = 1;
if(ioctlsocket( pLantronics->m_Socket, FIONBIO, &dwNonBlocking ))
{
shutdown(pLantronics->m_Socket, 2);
closesocket(pLantronics->m_Socket);
return FALSE;
}
pLantronics->m_sModemName = inet_ntoa(insock.sin_addr);
Now i do
m_Socket++;//change to some other number ideally expecting send recv to fail.
Even now the send recv socket functions succeeds without throwing SOCKET_ERROR.
I expect that it must throw error.
Am i doing something wrong.
It's because of the peculiar nature of Windows handles -- when created they are divisible by four and when used their two lowest bits are ignored. Incrementing a handle by one will make m_Socket refer to the same socket as before (only when you increment by four will the function return an error -- unless there is another handle with that value open).
You should not probe for open handles in this manner. While there are other ways to enumerate open handles, you shouldn't use them. Do not depend on the system to keep track of your handles -- track them yourself.

Same socket getting created

I have this piece of code where a server socket is created and is set to listen on a particular port number say 5005. Now once the accept socket function returns the socket that gets created is copied into the m_Socket variable and finally i shutdown the server socket named SocServer which was created locally.
Now my question
Is it possible that the SocServer(created initially) and m_Socket(copied when accept returns) get the same number say 1500.
struct sockaddr_in ServerSock; // Socket address structure to bind the Port Number to listen to
char *localIP ;
SOCKET SocServer;
//To Set up the sockaddr structure
ServerSock.sin_family = AF_INET;
ServerSock.sin_addr.s_addr = INADDR_ANY
ServerSock.sin_port = htons(PortNumber);//port number of 5005
// To Create a socket for listening on PortNumber
if(( SocServer = socket( AF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET )
{
return FALSE;
}
//To bind the socket with wPortNumber
if(bind(SocServer,(sockaddr*)&ServerSock,sizeof(ServerSock))!=0)
{
return FALSE;
}
// To Listen for the connection on wPortNumber
if(listen(SocServer,SOMAXCONN)!=0)
{
return FALSE;
}
// Structure to get the IP Address of the connecting Entity
sockaddr_in insock;
int insocklen=sizeof(insock);
//To accept the Incoming connection on the wPortNumber
m_Socket=accept(SocServer,(struct sockaddr*)&insock,&insocklen);
//delete the server socket
if(SocServer != INVALID_SOCKET)
{
//To close and shutdown the Socserver
shutdown(SocServer, 2 );
closesocket(SocServer);
}
is it possible that Socserver and m_socket are the same because
as per my code the socket connection is established and for some other reason it gets closed and in TCPView it shows established for a while and then no connection at all.
Note: This happens only in some machines and is not reproducible always. Can any other network related issue be the cause.
Are you certain that the client who is connecting to your server did not close the connection? Also, you did not provide any function which uses the m_Socket so i cannot tell you if there is any problem while handling the incoming connection. I do not think that m_socket and SocServer may end up the same.
In this code:
m_Socket=accept(SocServer,(struct sockaddr*)&insock,&insocklen);
if(SocServer != INVALID_SOCKET)
why do you call accept() with what may apparently be a bad socket? And do you test the value you get back from accept() anywhere?