How can application recv data with WSA_IO_PENDING? - winapi

I'm making a sniffer using LSP/SPI for specified application. But I cant understand how does this application work with network.
There are no "connect" or WSAConnect calls. I intercept WSPRecv, WSPSend, WSPCloseSocket, but no WSPConnect.
Another strange thing - WSPRecv always returns WSA_IO_PENDING, but hEvent in lpOverlapped is null, lpCompletionRoutine is null too. And no calls to WSPGetOverlappedResult (WSAGetOverlappedResult, GetOverlappedResult) and GetQueuedCompletionStatus (GetQueuedCompletionStatusEx). I hooked all this functions, but no calls at all! How does this application recv data?
Can you help me? How does it work? I have missed something?

A parent process listens for connections. Once a connection is established the parent process launches a new child process to deal with the connection. The child process inherits the handle of the connected socket. The child process communicates over the socket and eventually closes the socket and exits.
If you look at the child process in isolation you will see sends, receives and a final close but no initial connection, just as you describe.
This is a more common model on UNIX but it is sometimes used on Windows.
As for the strange overlapped behaviour, this may be what you see if you look at the internals of a non-blocking socket. Non-blocking sockets are implemented on asynchronous sockets, but I don't know the details.

Related

Design practices in handling websocket communication in golang

I am new to go and trying to learn it by replacing a nodejs server. My nodejs server had the following components:
It received a websocket message from a client. The client would provide a unique ID and a key for the message. The server would process the message based on the key (much like a REST interface would) and return a message to the client with the unique ID so that the client would know
which message the server was responding to.
For some of the messages, the server would spawn an external process (one for each connection). The server would then act as a "client" to the spawned process, sending JSON messages with unique IDs and receiving back data. The server in this instance acts as an intermediary between the spawned process and the client.
On node it was trivial to get this to work generically. I simply added the spawned process to the connection in my "main" and used callbacks in the main. The websocket server module and the module governing the spawned process communication had no direct interaction and were completely generic.
However, while I have a websocket package and a spawn package that work well in go, I haven't been able to figure out a good way to generically create a spawned process per websocket connection. I've thought of passing callbacks and inits but this method seems hackish. I recognize that node and go probably require different strategies in programming but I can't think of a good "go" way of doing this. I welcome any suggestions!
You describe how http protocol works, means request-response. If that all you need you may feel good with just keep-alive connections. Websocket is async in nature, messages aren't assume responses. Use-case is server-send-events for example.
In Go server uses fire-and-forget strategy. It accepts connection, spawns goroutine to handle it, forgets it and listens for a new. Spawned goroutine upgrades connection to websocket and then serves client itself without any intermediary.

IOCP, AcceptEx, overlapped and WSAEINVAL

I have a server that uses IOCPs, sockets and overlapped. Initially everything is just wonderful. The listening socket hands off to a newly created socket using AcceptEx on an IOCP. I can handle thousands of connections just fine.
When the server process falls behind in processing, it will close and disconnect the listening port. When it catches back up, it will reestablish the listening port with a new IOCP.
The issue I have run into is that on after reestablishing the listening port, and a new connection arrives, I attempt to accept using the exact same code path as above. The AcceptEx fails with WSAEINVAL.
I know I have left out some details (and the devil is always in the details, no?) -- but would appreciate assistance on where I should be looking.
If a curious soul would like more information, I'd be happy to supply.
It's hard to guess at what your problem might be given you don't show any source code, but...
There's no need to close the listening socket, simply stop posting new AcceptEx() calls and the server will not be able to accept any new connections.
if you really want to close the listening socket as well then do not close the IOCP and make sure you use the same IOCP when you recreate the listening socket.
I will answer my own question, because I have figured out what the underlying issue was. One thing that was critical to the issue, but was not stated in the problem statement was that the server had sub-processes.
It turns out that while the default behavior in windows is to not have handles inherited by sub-processes, the behavior of winsock is the opposite: handles are inherited by sub-processes unless explicitly set to no-inherit on creation.
Creating sockets with non-inheritable handles solves this problem. I hope that this helps someone out there that runs into this issue.

TCP connections with overlapped I/O

Is it possible to initiate a TCP connection request with overlapped I/O, and cancel it before the connection has been completed in Windows? I need to support at least Windows XP SP2.
ConnectEx allows an overlapped connection attempt.
To cancel this one would need to use CancelIo passing the SOCKET as if it were a HANDLE (it is really). But this must be done from the same thread that called ConnectEx. Managing things so you can achieve that thread specificity is unlikely to be easy.
After XP/2003 (ie. Vista/2008/8/2008R2) you can use CancelIoEx from a different thread (the OVERLAPPED instance is used to fully identify the IO operation).
From here:
overlap
This directory contains a sample server program that uses overlapped
I/O. The sample program uses the AcceptEx function and overlapped I/O
to handle multiple asynchronous connection requests from clients
effectively. The server uses the AcceptEx function to multiplex
different client connections in a single-threaded Win32 application.
Using overlapped I/O allows for greater scalability.

boost pion comet-like httpserver

I'm trying to efficiently implement comet-like functionality using HTTPServer class of boost::pion.
Basically, in my 'handleURI' function, I would like to postpone returning results to the client, until the server is ready to respond (for instance, until another user has sent a message to the first user, to use a simple comet 'hello world' application).
What should I do? Put the state on the stack, and exit silently, without creating a HTTPResponseWriter?
Cheers!
Setup a timeout ASIO event for your connection so that you can reap the connection after 20min or something reasonable like that. I don't know about Boost Pion, but in ASIO you'd want to register a read handler that catches when the connection closes and a timeout handler to alert you for when the connection has actually timed out. Enable TCP keep alives on your socket to detect when the socket should be reaped in the event that it just vanishes (though tcp keep alives aren't a guarantee so don't rely exclusively on them - not all clients support tcp keep alives). As for the timer, check out the following timer example:
https://github.com/sean-/Boost.Examples/blob/master/asio/timer/timer.cc

Handling WSAENETDOWN

I'm new to Winsock programming and I'm trying to learn how to use asynchronous sockets with WSAEventSelect(). I'm a bit unsure on how to handle a WSAENETDOWN error.
What exactly happens when I get a WSAENETDOWN error? Are my sockets and event objects automatically destroyed? What sort of cleanup do I need to do? What is the proper way of handling a WSAENETDOWN error if I'd like to try to reconnect? Is it ok to call connect() again, should I close and recreate my sockets and event objects, or should I call WSACleanup() and start over from scratch?
WSAENETDOWN means that on this socket a network error occured and sending and receiving data is not possible anymore. To handle this error you should close this one socket. There is no need to close other sockets or WASCleanup as other sockets can still be functionable (think about a computer with two network cards where one network is down but the other still functions). The sockets and events are not destroyed automatically.

Resources