Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to make a hard/abortive close on a TCP connection?

when a tcp client establishes a tcp connection with my TCP server, after it sends several packets, I want to make a hard/abortive close on this TCP connection, how to do it in linux C?

the hard/abortive close here means the tcp server will send a RST immediately to the client. No FIN/ACK at all.

thanks!

like image 396
misteryes Avatar asked Jun 02 '13 23:06

misteryes


2 Answers

From Socket man page

SO_LINGER Sets or gets the SO_LINGER option. The argument is a linger structure.

struct linger {
    int l_onoff;    /* linger active */
    int l_linger;   /* how many seconds to linger for */
};

When enabled, a close(2) or shutdown(2) will not return until all queued messages for the socket have been successfully sent or the linger timeout has been reached. Otherwise, the call returns immediately and the closing is done in the background. When the socket is closed as part of exit(2), it always lingers in the background.

Another settings :

The effect of an setsockopt(..., SO_LINGER,...) depends on what the values in the linger structure (the third parameter passed to setsockopt()) are:

Case 1: linger->l_onoff is zero (linger->l_linger has no meaning): This is the default.

On close(), the underlying stack attempts to gracefully shutdown the connection after ensuring all unsent data is sent. In the case of connection-oriented protocols such as TCP, the stack also ensures that sent data is acknowledged by the peer. The stack will perform the above-mentioned graceful shutdown in the background (after the call to close() returns), regardless of whether the socket is blocking or non-blocking.

Case 2: linger->l_onoff is non-zero and linger->l_linger is zero:

A close() returns immediately. The underlying stack discards any unsent data, and, in the case of connection-oriented protocols such as TCP, sends a RST (reset) to the peer (this is termed a hard or abortive close). All subsequent attempts by the peer's application to read()/recv() data will result in an ECONNRESET.

Case 3: linger->l_onoff is non-zero and linger->l_linger is non-zero:

A close() will either block (if a blocking socket) or fail with EWOULDBLOCK (if non-blocking) until a graceful shutdown completes or the time specified in linger->l_linger elapses (time-out). Upon time-out the stack behaves as in case 2 above.

like image 93
a.m. Avatar answered Nov 14 '22 20:11

a.m.


You should set the SO_LINGER socket option with timeout 0 and call close(). If there's any pending data to send it is lost and an RST is sent instead of FIN.

Reference: http://alas.matf.bg.ac.rs/manuals/lspe/snode=105.html

like image 20
Joni Avatar answered Nov 14 '22 20:11

Joni