Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Graceful Shutdown Server Socket in Linux

Tags:

c

linux

tcp

I want to be able to stop listening on a server socket in linux and ensure that all connections that are open from a client's point of view are correctly handled and not abruptly closed (ie: receive ECONNRESET).

ie:

sock = create_socket();
listen(sock, non_zero_backlog);
graceful_close(sock);

if thought calling close() and handling already accept'd sockets would be enough but there can be connections that are open in the kernel backlog which will be abruptly closed if you call close() on the server socket.

like image 469
benmmurphy Avatar asked Mar 13 '12 09:03

benmmurphy


2 Answers

The only working way to do that (that I have found) is to:

  1. prevent accept() from adding more clients

  2. have a list of the open sockets somewhere and to wait until they are all properly closed which means:

    • using shutdown() to tell the client that you will no longer work on that socket

    • call read() for a while to make sure that all the client has sent in the meantime has been pulled

    • then using close() to free each client socket.

  3. THEN, you can safely close() the listening socket.

You can (and should) use a timeout to make sure that idle connections will not last forever.

like image 171
Gil Avatar answered Oct 24 '22 08:10

Gil


You are looking at a limitation of the TCP socket API. You can look at ECONNRESET as the socket version of EOF or, you can implement a higher level protocol over TCP which informs the client of an impending disconnection.

However, if you attempt the latter alternative, be aware of the intractable Two Armies Problem which makes graceful shutdown impossible in the general case; this is part of the motivation for the TCP connection reset mechanism as it stands. Even if you could write graceful_close() in a way that worked most of the time, you'd probably still have to deal with ECONNRESET unless the server process can wait forever to receive a graceful_close_ack from the client.

like image 2
msw Avatar answered Oct 24 '22 07:10

msw