How to RST a socket using libuv

272 views
Skip to first unread message

Darren Smith

unread,
Feb 7, 2017, 1:48:37 AM2/7/17
to libuv
Hi

I am using libuv for a server application.  When the server needs to close a client connection that has not hand-shaked correctly, I would like to reset the TCP connection rather than calling close() - this is to prevent having many sockets in the TIME_WAIT on the server side.

I've looked at the libuv headers; there doesnt' seem any utility methods for reseting a uv_tcp_t object (e.g., naively I was hoping for a reset(...) call); nor is there any helper method for setting LINGER, although some socket options do have utility methods, eg uv_tcp_nodelay & uv_tcp_keepalive.

I'm curious as to why some socket options have an API but others don't.    For my requirement to reset a tcp connection, am I correct in there not being direct libuv support, or have I missed something?  In which case I suppose I can just call setsockopt directly on the fd.

Thanks,

Darren


Ben Noordhuis

unread,
Feb 7, 2017, 7:28:27 AM2/7/17
to li...@googlegroups.com
Hi Darren,

Libuv indeed has no direct support for configuring SO_LINGER. What is
it you ultimately want to accomplish?

1. Sending a TCP RST instead of a FIN to the remote peer? I don't
think there is a portable (or even a non-portable but reliable) way of
doing that. A zero SO_LINGER is not guaranteed to always result in a
RST.

2. Control how in-flight data is handled by close()? See [0] for a
comprehensive overview of SO_LINGER's many intricacies, in particular
the section about non-blocking sockets. To summarize: SO_LINGER is
likely not the answer, you probably want uv_shutdown().

3. Stop sockets from ending up in TIME_WAIT state? You cannot in
general ([1] is the shortest explanation I was able to find, [2] the
most comprehensive one) but if there was a portable and reliable way
of controlling its duration, it would make sense to add that to libuv.
I'm not aware of any that meet both the 'portable' and 'reliable'
criteria, though.

Hope that helps,

Ben

[0] https://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable
[1] http://superuser.com/questions/173535/what-are-close-wait-and-time-wait-states/173542#173542
[2] http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html

Darren Smith

unread,
Feb 7, 2017, 2:55:56 PM2/7/17
to libuv
Hi Ben,

Thanks for the detailed reply. 

Ultimately what I'm trying to accomplish is to minimise the occurrences of TIME_WAIT socket states on the server, and so to do that, I have to get the client to call the close().

Currently this is achieved by the server sending a disconnect application message to the client, which will react by calling close().  However there is always the case of an uncooperative client to consider, i.e., one which does not call close(), and instead keeps the connection open.  In such cases the server, after some time delay, will cause close(); but now it ends up with the TIME_WAIT.  So I'm trying to find a route around that TIME_WAIT case.  So I thought a server side reset could work, i.e. only perform reset if a client has failed to call close(), and it does seem to work on my linux box, but perhaps this relies too much on variable features of the TCP stack.

Darren



Ben Noordhuis

unread,
Feb 7, 2017, 5:18:48 PM2/7/17
to li...@googlegroups.com
Hi Darren, I believe what you want can for the most part be accomplished by:

1. first calling uv_shutdown(), then
2. waiting a few milliseconds to read any outstanding data and receive
the EOF (in case of a cooperating client), and
3. finish by calling uv_close().

You probably cannot completely avoid TIME_WAIT that way, though. A
client that simply stops replying at the TCP level because of (e.g.) a
network error could still get stuck in that state. I think in that
specific case it would make sense to set SO_LINGER to zero before
closing the socket.

If you want to pursue this, can you file an issue in the bug tracker?
Reply all
Reply to author
Forward
0 new messages