Interrupting a connecting windows wsa socket - windows

I was just wondering if it is possible to interrupt call to windows socket "connect" function?
The problem is that my code requires that to be done in a different thread (so GUI thread keeps running). But when the programm is closed there my still be threads calling "connect" that are wating for a WSAETIMEDOUT exception.
Any ideas?
Update/Hint: i cant call close() since i only have a valid handle when connect() returns. the latter one is not the case when using blocking sockets and having a tcp-connect to a firewalled location (for example) :/

If the socket is in blocking mode, the only way to abort connect() call is to close the socket from a different thread context than the one that is calling connect(). connect() will return an error, and the thread can then exit itself normally.
If the socket is in non-blocking or overlapped mode, connect() will return immediately with a WSAEWOULDBLOCK error, and you then have to call select(), WSAAsyncSelect(FD_CONNECT), or WSAEventSelect(FD_CONNECT) to detect when the connection has been established before continuing with your socket work. Since the calling thread is not blocked on connect(), it is free to periodically check for any termination/abort signals from the rest of your code, and if detected then close the socket (if needed) and exit itself normally.
If you write your socket code in non-blocking or overlapped mode, then you do not really need to use a thread. You can do your socket work within the main thread without blocking your UI, then you can just close the socket when needed. It takes a little more work to code that way, but it does work. Or you can continue using a thread. It will keep your socket code separate from your UI code and thus a bit more managable.

Related

systemd socket activation listener end-of-program behaviour

What is the correct behavior on close of a systemd AF_UNIX socket activated daemon.
daemon.socket service file creates the socket, passes it to my daemon, which accept()s new connections. What is supposed to happen when my daemon ends?
The usual is to close() and unlink() the socket. However, that does what it says, and the UNIX socket is no longer available in the FS, even though daemon.socket is still reporting as activated, basically disabling socket re-activation.
How to create a systemd socket restart-able daemon that listen()s on its socket? Is the correct approach to leave the socket open?
After experimentation and reading of relevant manpages and cups code, here is what I know:
There are two modes of functioning :
inetd mode, where systemd accept()s the connection and passes the accepted FD to a newly spawned subprocess. This method is used by default by ssh.socket, whereby every connection spawns a new ssh process.
Non-accepting mode, where the bound socket itself is forwarded to the daemon, which then handles all accept() calls.
per man systemd.socket
A daemon listening on an AF_UNIX socket may,
but does not need to, call close(2) on the received socket before exiting. However, it must not unlink the socket from a file system.
So a received bound socket must not be unlink()ed. On the other hand, even stopping the .socket service doesn't remove the inode. To that effect, the RemoveOnStop= directive exists.
It would appear the "recommended" way is to let systemd create the socket, pass it to the daemon, and in the daemon at most close() it. Once closed, it is of course only closed in the daemon, so the socket is still available in the system. Meaning after a close() the service will be again activated.
Presumably a call to sd_listen_fds() in a still running service would pass the FD anew. I have not tested this.
TLDR: In a systemd socket activated service, don't unlink(), you may close(), RemoveOnStop= also deletes the socket file on stop of the .socket service.

Can Windows Socket #10060 error (WSAETIMEDOUT - An attempt to connect timed out without establishing a connection) be a programming error at all?

I have Delphi application that uses Indy HTTP components (that uses Windows socket). And from time to time I am receiving #10060 socket error (WSAETIMEDOUT - An attempt to connect timed out without establishing a connection) upon execution of Indy procedure:
CheckForSocketError(IdWinsock2.Connect(ASocket, #LAddr, SizeOf(LAddr)));
...
connect : TconnectProc;
...
TconnectProc = function ( const s: TSocket; const name: PSockAddr; const namelen: Integer): Integer; stdcall;
Actually all this is just wrap around Windows connect function https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect that gives error and message WSAETIMEDOUT. So - my question is - can this be programming error at all? Even if I have server running on the other computer and even that server has trouble serving request, even in such cases the low level connect should execute normally, if the server can not serve the GET/POST request, then, of course, the errors should be but those errors should spring in only during execution of other Socket functions not in the connect function, isn't so?
I am trying to solve my problem https://serverfault.com/questions/973648/is-it-possible-that-unencrypted-traffic-can-cause-windows-socket-10057-10060?noredirect=1#comment1266907_973648 and now I am seeking whats happening in my code.
My server side code is very simple - it is just TIdHttpServer component with implemented (I provide event name only here):
MyForm.IdHTTPServerCommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
So - what can be worng with my implemention, what can lead to the appearance of WSAETIMEDOUT for connect? Yes, my procedure can be long sometimes, but it for years it returned the answer sucessfully and there were no communication errors. And I guess, that connect function can even not depend (does not use/raise) OnCommandGet event, so, I have no control how the server side handles socket connect function from the client?
It may be possible that this is connected with TCP (not HTTP) keepalive, maybe some Windows updates have reduced client-side settings of Windows TCP keepalive for the clients and now this manifests as such error.
Indy TCP clients, like TIdHTTP, have a public ConnectTimeout property, which is set to 0 (infinite) by default. If no timeout is specified, a hard-coded 2 minute timeout is used if the client's TIdTCPClient.Connect() method is called in the main UI thread and TIdAntiFreeze is active, otherwise no timeout is used.
If a timeout is used, Indy calls Winsock's connect() function in a worker thread and waits for that thread to terminate. If Indy's timeout elapses, the socket is closed to abort the connect(), and then EIdConnectTimeout is raised to the caller. If connect() exits before Indy's timeout elapses, an exception is raised to the caller only if connect() failed.
If no timeout is used, Indy calls Winsock's connect() directly, waits for it to exit on its own accord, and then raises an exception only if failed.
So, the ONLY way you can get a WSATIMEDOUT error from Indy when it is calling Winsock's connect() function is if Winsock itself timed out internally before Indy's own timeout elapses. That does not necessarily indicate a problem in your code. It just means that the Host you are trying to connect to is simply not reachable at that moment in time. If the server were reachable, but could not accept your connection, you would get a different error, such as WSAECONNREFUSED.
If your server is behind a firewall or router, make sure it is not blocking connections from reaching your server. Try running a packet sniffer on the server machine, such as WireShark, and make sure the 3-way TCP handshake from TIdHTTP is reaching the server machine correctly.

Shut down a UDP Server receiving requests

I made a UDP server class and my program creates a process (running in the background). It is a command line utility, and so running 'udpserver.exe start' would bind the socket and begin a blocking recvfrom() call inside a for(;;) loop.
What is the best way to safely and 'gracefully' stop the server?
I was thinking about 'udpserver.exe stop' would send a udp msg such as 'stop' and the ongoing process from 'udpserver.exe start' would recognize this msg, break from the loop, and clean up (closesocket/wsacleanup).
Also, is just killing the process not a good idea?
Why are you running the UDP server as an external process instead of as a worker thread inside of your main program? That would make it a lot easier to manage the server. Simple close the socket, which will abort a blocked recvfrom(), thus allowing the thread to terminate itself.
But if you must run the UDP server in an external process, personally I would just kill that process, quick and simple. But if you really want to be graceful about it, you could make the server program handle CTRL-BREAK via SetConsoleCtrlHandler() so it knows when it needs to close its socket, stopping recvfrom(). Then you can have the main program spawn the server program via CreateProcess() with the CREATE_NEW_PROCESS_GROUP flag to get a group ID that can then be used to send CTRL-BREAK to the server process via GenerateConsoleCtrlEvent() when needed.

How to close Winsock UDP socket hard?

I need to close UDP socket which has unsent data immediately.
There is SO_LINGER parameter for TCP sockets but I didn't find out anything for UDP.
It's on Windows.
Thanks in advance.
Update 0:
I give background of this question. I have application 1st thread opens/binds/closes socket, 2nd thread sends datagrams to it.
In some cases after closing the socket (errorcode = 0) bind function returns errorcode 10048 "Address already in use". I found out after close() execution port is still used (via netstat command). Maybe I ask incorrect question and the reason of such behavior is something else?
For all application purposes once your send() returns, the packet is "sent". There's no send-buffer like in TCP, and you have no control over the NIC packet queue. Normal close() is all you need.
Edit 0:
#EJP, here's a quote from UNP for you (Section 2.11 "UDP Output"):
This time, we show the socket send buffer as a dashed box bacause it
doesn't really exist. A UDP socket has a send buffer size (which we
can change with the SO_SNDBUF socket option, Section 7.5), but this
is simply an upper limit on the maximum-sized UDP datagram that can
be written to the socket. If an application writes a datagram larget
than the socket send buffer size, EMSGSIZE is returned. Since UDP is
unreliable, it does not need tp keep a copy of the application's data
and does not need an actual send buffer. (The application data is
normally copied into a kernel buffer of some form as it passes down
the protocol stack, but this copy is discarded by the datalink layer
after the data is transmitted.)
This is what I meant in my answer - you have no control over the send buffer - , so "for all application purposes" it does not exist.
I was having this problem with a windows UDP socket as well. After hours of trying everything I finally found my problem was that I was calling socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) on the main thread to create the socket, calling bind(...) and recvfrom() on a worker thread, then after closing the worker thread I called closesocket(...) on the main thread. None of the functions returned an error but tor some reason, doing this leaves the UDP address/port combination in use (so a future call to bind() triggers error 10048 WSAEADDRINUSE and netstat -abot -p UDP also shows the port still in use until the whole application is closed). The solution was to move socket(...) and closesocket(...) calls into the worker thread.
Other than weird issues like the case above, there is normally no way that a UDP server socket can be left open after calling closesocket() on it. Microsoft explains that there is no connection maintained with a UDP socket and no need to call shutdown() or any other function. Usually the reason a TCP socket is left open after calling closesocket() is that it wasn't disconnected gracefully and it's waiting for about 4 minutes in TCP_WAIT state for possible additional data to come in before it actually closes. In the case above, netstat showed the UDP socket never closed until the application was closed even if I waited 30+ minutes.
If you're using a wrapper around winsock like the .NET framework, I've also read some features like setting up async callbacks can leave a UDP socket bound open if you don't clean up the callbacks correctly, but I don't think there are any such features in the win32 winsock API that can cause that.
Just close it. There's nothing in UDP that says that pending data will be sent, unlike TCP.

Does a socket shutdown call from another thread always make blocking recv() threads wake up?

I can't find much documentation to say whether this is supposed to happen or not:
Some thread opens a TCP (or other stream) socket
Thread 1 starts a blocking recv()
Thread 2 calls shutdown() on the socket with SHUT_RDWR (or SHUT_RD I think)
Thread 1 is now "woken up" from its blocking call, and returns zero, as it would if the other party closed its socket.
This behaviour appears on modern Linux and FreeBSD systems. I haven't tested it with any others.
A comment on a Microsoft MSDN help page here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms740481%28v=vs.85%29.aspx suggests that this behaviour is "responsible" in Windows; it also states that this is "not currently the case" but this may be out of date.
Is this behaviour specified anywhere? Can I rely on it?
I don't think you can rely on it. shutdown() initiales socket shutdown, but the details depend on particular circumstances. Some protocols may indeed close connection and socket immediately which would wake up processes sleeping on that socket. In other cases, shutdown just kicks protocol state machine into action, but it would take some time until it would get to the point where it would make sense to wake up anyone. For instance, established TCP connection would have to transition through few states until it reaches CLOSED state. You will eventually wake up, but you can't rely on it happening right away.

Resources