Dan Tumaykin
Dan Tumaykin

Reputation: 1253

close() with SO_LINGER won't send RST

I'm trying to force TCP reset on a connection. The suggested way is to set SO_LINGER to 0 and the call close().

I'm doing exactly that, but the connection remains in ESTABLISHED state. The socket is operating in non blocking mode. The operating system is Raspbian.

The code:

struct linger l;
l.l_onoff = 1;
l.l_linger = 0;

if (setsockopt(server->connection_socket, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) != 0) {
    LOG_E(tcp, "setting SO_LINGER failed");
}

if (close(server->connection_socket) != 0) {
    LOG_E(tcp, "closing socket failed");
}

server->connection_socket = 0;
LOG_I(tcp, "current TCP connection was closed");

Wireshark trace shows no RST as well.

No other threads of the application are performing any operation on that socket.

I can't figure out what is wrong, any suggestion would be much appreciated.


SOLVED

The issue was with file descriptors leaking to children created through system() call. In fact when I listed all TCP socket descriptors with lsof -i tcp, I found out that child processes had opened file descriptor from parent process (even though parent already did not).

The solution was requesting file descriptor to be closed in forked process (right after accept()).

fcntl(server->connection_socket, F_SETFD, FD_CLOEXEC)

Upvotes: 4

Views: 1662

Answers (1)

red0ct
red0ct

Reputation: 5055

In your case you can no longer send and receive data after calling close. Also, after close call the RST will be sent only if the reference counter of socket descriptor becomes 0. Then the connection goes into CLOSED state and data in the receive and the send buffers are discarded.
Probably the answer lies in how you forked a process (as mentioned by EJP in comment). It seems that you didn't close the accepted socket in parent process after calling fork. So the socket reference counter is nonzero and there is no RST immediately after your close.
Such situations are well described by Stevens in UNIX Network Programming.

Upvotes: 2

Related Questions