I,m working on an embedded linux kernel 2.6 device and need to know if previously established socket is still valid or not,Also I can not do this with usual send function and check the returned value,because if I send to the invalid socket descriptor,my application will crash and linux will shut down my process.Is there any other function/suggestion for this ?
EDIT:
There are an installed app manager in device and when I try to send to socket descriptor which is not refer to the open socket,app manager will end my application,then if i close a socket connection and try to write to it,my application will be turned off by lower level app-manager.Also I'm using TCP sockets,WBr.
I think this question is either misstated or based on false premises. There is no sense of "invalidity" which a socket could come to have asynchronously by the action of another process/host. The closest thing is probably the other end of the socket being closed, which does not invalidate your socket, but it does cause subsequent writes to your socket to result in an EPIPE error and SIGPIPE signal if not blocked. SIGPIPE in turn terminates your process by default. If that's your problem, the easiest way to avoid it is to block SIGPIPE with sigprocmask/pthread_sigmask, or ignore it with signal(SIGPIPE, SIG_IGN).
Related
In TCP we say one side of the connection performs an "active close" and the other side performs a "passive close".
In terms of the Linux sockets API, how do you differentiate the active close and the passive close?
For example, suppose we have two connected Linux TCP sockets, A and P, that have exchanged information over the application-level protocol and they are both aware that it is time to close their sockets (neither expect to send or receive any more data to or from each other).
We want socket A to perform the active close, and for P to be the passive close.
There are a few things A and P could do. For example:
call shutdown(SHUT_WR)
call recv and expect to get 0 back
call close.
something else
What combination of these things and in what order should A do?... and what combination of these things and in what order should P do?
In terms of the Linux sockets API, how do you differentiate the active
close and the passive close?
The 'active' close is simply whichever side of the socket sends a FIN or RST packet first, typically by calling close().
What combination of these things and in what order should A do?... and
what combination of these things and in what order should P do?
In practice, most of this is application- and application-protocol specific. I will describe the minimum/typical requirement to answer your question, but your mileage may vary depending on what you are specifically trying to accomplish.
You may first call shutdown() on Socket A if you want to terminate communication in one direction or the other (or both) on Socket A. From your description, both programs already know they're done, perhaps due to application protocol messages, so this may not be necessary.
You must call close() on Socket A in order to close the socket and release the file descriptor.
On Socket P, you simply keep reading until recv() returns 0, and then you must call close() to close the socket and release the file descriptor.
For further reading, there are a number of good tutorials out there, and Beej's Guide to Network Programming is quite popular.
Active open is when you issue connect(2) explicitly to make a connection to a remote site. The call blocks until you get the socket opened on the other side (except if you issued O_NONBLOCK fcntl(2) call before calling connect(2).
Passive open is when you have a socket listen(2)ing on a connection and you have not yet issued an accept(2) system call. The accept(2) call normally blocks until you have a completely open connection and gives you a socket descriptor to communicate over it, or gives you inmediately a socket descriptor if the connection handshake has already finished when you issue the accept(2) syscall (this is a passive open). The limit in the number of passively open connections the kernel can accept on your behalf while you prepare yourself to make the accept(2) system call is what is called the listen(2) value.
Active close is what happens when you explicitly call shutdown(2) or close(2) system calls. As with passive open, there's nothing you can do to make a passive close (it's something that happens behind the scenes, product of other side's actions). You detect a passive close when the socket generates an end of file condition (this is, read(2) always returns 0 bytes on reading) meaning the other end has done a shutdown(2) (or close(2)) and the connection is half (or full) closed. When you explicitly shutdown(2) or close(2) your side, it's an active close.
NOTE
if the other end does an explicit close(2) and you continue writing on the socket, you'll get an error due to the impossibility of sending that data (in this case we can talk about a passive close(2) ---one that has occured without any explicit action from our side) but the other end can do a half close calling shutdown(2). This makes the tcp to send a FIN segment only and conserves the socket descriptor to allow the thread to receive any pending data in transit or not yet sent. Only when it receives and acknowledges the other end's FIN segment will it signal you that no more data remains in transit.
I have a client application communicating with a QEMU process through a QMP Unix domain socket. Sometimes after the client calls close() on the socket connection, 'netstat -ap unix' still shows it in CONNECTED state. I do check the return value of the close() call and it returns successfully with a value of 0, but the connection still seems to be lingering.
Since QMP doesn't really support multiple connections on its socket, all the subsequent calls to connect to the socket fail since they wait indefinitely for the lingering connection to be closed.
Is there a way to make sure from the code that the socket is really closed, and is there a way to force the socket to close?
It could be that the file descriptor has been duped, forked, or leaked.
Call shutdown(sock, SHUT_RDWR) on it to close the connection for sure before closeing.
Have you tried closing the socket from the other end? It's asynchronous, but it gives both sides a chance to ensure socket closure.
You can send a close command through to the listener on the other end and have it recycle the socket. When the socket gets closed, you should end up getting a SIGPIPE. Catch the SIGPIPE and close your end of the socket. If you end up with an EPIPE doing that, then ignore it. That just means you were already notified of the socket closure.
You could just try SO_LINGER via setsockopt(2) option with a timeout of 0. This way, when you close the socket is forcibly closed, sending a RST instead of going into the FIN/ACK closing behavior.
The purpose of the SO_LINGER option is to control how the socket is shut down when the function close(2) is called. This option applies only to connection-oriented protocols such as TCP.
The default behavior of the kernel is to allow the close(2) function to return immediately to the caller. Any unsent TCP/IP data will be transmitted and delivered if possible, but no guarantee is made. Because the close(2) call returns control immediately to the caller, the application has no way of knowing whether the last bit of data was actually delivered.
The SO_LINGER option can be enabled on the socket, to cause the application to block in the close(2) call until all final data is delivered to the remote end. Furthermore, this assures the caller that both ends have acknowledged a normal socket shutdown. Failing this, the indicated option timeout occurs and an error is returned to the calling application.
One final scenario can be applied, by use of different SO_LINGER option values. If the calling application wants to abort communications immediately, appropriate values can be set in the linger structure. Then, a call to close(2) will initiate an abort of the communication link, discarding all pending data and immediately close the socket.
I'm writing an epoll-based network server in C. When I create my socket to listen for incoming connections, I make it non-blocking using fcntl. Similarly when incoming connections arrive from clients, I make their sockets non-blocking before doing anything with them, and likewise for outgoing connections' sockets.
Sometimes my server gets a SIGPIPE -- I think this is when I try to write to a client connection that has been closed by the client. This seems strange to me; I thought that with non-blocking sockets instead of a SIGPIPE I should get an -1 back from the call to write and ECONNRESET in errno.
Is there something I'm missing? Or is it just normal to get both a SIGPIPE and an error code even with non-blocking sockets (meaning that I should explicitly ignore the signal with signal(SIGPIPE, SIG_IGN) in my setup)?
Yes, this is normal. If you write to a socket (non-blocking or not) where the other end has closed the connection, you will get a SIGPIPE or (if you are blocking the SIGPIPE signal) an error return (-1) with errno set to EPIPE.
From the man page for write:
EPIPE: fd is connected to a pipe or socket whose reading end is closed. When this happens the writing process will also receive
a SIGPIPE signal. (Thus, the write return value is seen only if the program catches, blocks or ignores this signal.)
The POSIX standard is here: http://pubs.opengroup.org/onlinepubs/009695399/functions/write.html and says:
[EPIPE] An attempt is made to write to a pipe or FIFO that is not open for reading by any process, or that only has one end open. A SIGPIPE signal shall also be sent to the thread.
The SIGPIPE is normal. Another option beside setting signal handler solely for this purpose is to use flag MSG_NOSIGNAL whenever you send.
I'm working with some code that needs to be safe against killing the caller due to SIGPIPE, but the only socket writes it's performing are going to datagram sockets (both UDP and Unix domain datagram sockets). Do I need to worry about SIGPIPE? I'm using connect on the socket, but preliminary testing (on Linux) showed that I just get ECONNREFUSED on send if there's nobody listening on the Unix domain socket. Not sure what happens with UDP.
I can wrap the whole thing in hacks to get rid of SIGPIPE, but if it's a non-issue I'd rather save the overhead and keep the code complexity down.
The answer is in the specification for send:
[EPIPE] The socket is shut down for writing, or the socket is connection-mode and is no longer connected. In the latter case, and if the socket is of type SOCK_STREAM or SOCK_SEQPACKET and the MSG_NOSIGNAL flag is not set, the SIGPIPE signal is generated to the calling thread.
http://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html
Thus, no, writes to datagram sockets do not generate SIGPIPE or an EPIPE error.
The open group is one thing, and Apple is another.
It is definitely possible to get a SIGPIPE on iOS when writing to a dead UDP socket, as some of my crash logs revealed lately.
iOS tends to close UDP sockets while the app is in the background, writing to these sockets can pop a SIGPIPE.
From my crash log (courtesy of testflightapp):
Exception Latest Victim Occurrences
SIGPIPE
2 libsystem_c.dylib 0x32df47ec _sigtramp + 48
3 instant talk 0x0005b10e -[IPRSNetDatagramSocket send:size:to:] (iprs_iphone_net.m:671)...
Don't recall this happening on Linux, Solaris or Windows - though I never tried to close a socket and then write to it.
According to man 2 write on my Debian box,
EPIPE: fd is connected to a pipe or socket whose reading end is closed. When this happens the writing process will also receive a SIGPIPE signal. (Thus, the write
return value is seen only if the program catches, blocks or ignores this signal.)
It appears that it is possible to get SIGPIPE when writing to a socket, but it's not clear whether it can happen for UDP sockets specifically.
Can a socket be closed from another thread when a send / recv on the same socket is going on?
Suppose one thread is in blocking recv call and another thread closes the same socket, will the thread in the recv call know this and come out safely?
I would like to know if the behavior will differ between different OS / Platforms. If yes, how will it behave in Solaris?
In linux closing a socket won't wake up recv(). Also, as #jxh says:
If a thread is blocked on recv() or send() when the socket is closed
by a different thread, the blocked thread will receive an error.
However, it is difficult to detect the correct remedial action after
receiving the error. This is because the file descriptor number
associated with the socket may have been picked up by yet a different
thread, and the blocked thread has now been woken up on an error for a
"valid" socket. In such a case, the woken up thread should not call
close() itself.
The woken up thread will need some way to differentiate whether the
error was generated by the connection (e.g. a network error) that
requires it to call close(), or if the error was generated by a
different thread having called close() on it, in which case it should
just error out without doing anything further to the socket.
So the best way to avoid both problems is to call shutdown() instead of close(). shutdown() will make the file descriptor still available, so won't be allocated by another descriptor, also will wake up recv() with an error and the thread with the recv() call can close the socket the normal way, like a normal error happened.
I don't know Solaris network stack implementation but I'll throw out my theory/explanation of why it should be safe.
Thread A enters some blocking system call, say read(2), for this given socket. There's no data in socket receive buffer, so thread A is taken off the processor an put onto wait queue for this socket. No network stack events are initiated here, connection state (assuming TCP) has not changed.
Thread B issues close(2) on the socket. While kernel socket structure should be locked while thread B is accessing it, no other thread is holding that lock (thread A released the lock when it was put to sleep-wait). Assuming there's no outstanding data in the socket send buffer, a FIN packet is sent and the connection enters the FIN WAIT 1 state (again I assume TCP here, see connection state diagram)
I'm guessing that socket connection state change would generate a wakeup for all threads blocked on given socket. That is thread A would enter a runnable state and discover that connection is closing. The wait might be re-entered if the other side has not sent its own FIN, or the system call would return with eof otherwise.
In any case, internal kernel structures will be protected from inappropriate concurrent access. This does not mean it's a good idea to do socket I/O from multiple threads. I would advise to look into non-blocking sockets, state machines, and frameworks like libevent.
For me, shutdown() socket from another thread do the job in Linux
If a thread is blocked on recv() or send() when the socket is closed by a different thread, the blocked thread will receive an error. However, it is difficult to detect the correct remedial action after receiving the error. This is because the file descriptor number associated with the socket may have been picked up by yet a different thread, and the blocked thread has now been woken up on an error for a "valid" socket. In such a case, the woken up thread should not call close() itself.
The woken up thread will need some way to differentiate whether the error was generated by the connection (e.g. a network error) that requires it to call close(), or if the error was generated by a different thread having called close() on it, in which case it should just error out without doing anything further to the socket.
Yes, it is ok to close the socket from another thread. Any blocked/busy threads that are using that socket will report a suitable error.