Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting a TCP reset with Linux sockets

Tags:

c

linux

tcp

sockets

When one end of a TCP link disconnects, it sends a reset (RST) message to the other end. I want to be able to receive this in the application layer.

In my code, I use a select() call to receive input from potentially multiple sources, including a TCP connection. I've seen that when the select() shows that there is data ready to read on the connection, and then a read() call returns 0 bytes read, that happened after a RST was sent over TCP. (I understand recv() works similarly to read().)

Does read() return 0 bytes (after select()) on a TCP connection only if the connection was reset? Does it ever return 0 bytes in any other cases?

I remember a while ago using a particular ethernet device on the other end of the connection, and this Linux end was receiving 0 bytes after a select(), but not for a connection reset, but rather mid-way through some data streaming. I confirmed in Wireshark that the packet received had 0 data bytes. Is this a bug, or like the question above, is it valid to have this behaviour? I can't remember which device it was, as it was a few years back, but it was using a Windows driver.

like image 711
Jetski S-type Avatar asked May 22 '15 08:05

Jetski S-type


People also ask

How do I check my TCP RST?

While analyzing the packet capture select the RST packet and right-click and select Conversation filter and then select TCP. This will filter the packets for the selected conversation only and make it easy to troubleshoot. From the packet capture, the client sends the SYN for TCP handshake and gets RST from the server.

How do I know if a TCP socket is closed?

You could check if the socket is still connected by trying to write to the file descriptor for each socket. Then if the return value of the write is -1 or if errno = EPIPE, you know that socket has been closed.

What causes TCP connection resets?

An application gets a connection reset by peer error when it has an established TCP connection with a peer across the network, and that peer unexpectedly closes the connection on the far end.


1 Answers

When one end of a TCP link disconnects, it sends a reset (RST) message to the other end.

Not normally.

I want to be able to receive this in the application layer.

You will.

I've seen that when the select() shows that there is data ready to read on the connection, and then a read() call returns 0 bytes read, that happened after a RST was sent over TCP.

No.

Does read() return 0 bytes (after select()) on a TCP connection only if the connection was reset?

Never if the connection was reset. It returns -1 with errno == ECONNRESET in that case.

Does it ever return 0 bytes in any other cases?

It returns zero if and only if a FIN was received, i.e. the peer closed the connection, or shutdown his socket for output.

like image 111
user207421 Avatar answered Oct 16 '22 00:10

user207421