Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

An API for TCP timeouts #1415

Closed
LinuxJedi opened this issue Aug 12, 2014 · 6 comments
Closed

An API for TCP timeouts #1415

LinuxJedi opened this issue Aug 12, 2014 · 6 comments

Comments

@LinuxJedi
Copy link

It would be nice to have an API for TCP timeouts. If for example you are doing a TCP connect with UV_RUN_DEFAULT in Linux you will hit a ETIMEDOUT after around 2 minutes.

I realise typical use case would be to run in UV_RUN_NOWAIT and have a timer for timeout but there are cases where you would not want to do this.

@saghul
Copy link
Contributor

saghul commented Aug 12, 2014

You mean connect timeouts? Those could be implemented at the application level, if we supported canceling uv_connect_t requests.

@LinuxJedi
Copy link
Author

Yes, I mean connect timeouts in this context (although read/write timeouts in UV_RUN_DEFAULT could equally apply).

I agree this can done at the application level for less than 2 minutes, that isn't too hard. You even have a test case in the code showing how to do it (test-tcp-connect-timeout.c).

What I'm saying is the OS socket layer is cancelling the connection at 2 minutes.

For my application I want to set a timeout for 10 minutes using methods similar to test-tcp-connect-timeout.c. But ETIMEDOUT will occur after 2 minutes.

I believe the cause is: http://stackoverflow.com/questions/8471577/linux-tcp-connect-failure-with-etimedout

Other applications I use (such as MySQL) aren't hit with this timeout but unfortunately I don't know enough low-level socket programming to understand why.

To try this for yourself to connecting to port 81 of www.google.com using uv_tcp_connect and UV_RUN_DEFAULT.

@LinuxJedi
Copy link
Author

OK, done some research into this.

Basically with MySQL as my example, they are doing a blocking connect, in which case the standard socket level timeouts apply.

Libuv with UV_RUN_DEFAULT is doing a non-blocking connect and an epoll_wait with infinite timeout. the syn/ack retries are what causes the timeout. The only solution I have found is using setsockopt() to set TCP_SYNCNT to a higher number, setting it to 7 is about 4 minutes for example.

Unfortunately this solution is not portable beyond Linux and I haven't even begun to test the behaviour of other operating systems.

Suggested solutions:

  1. if this affects other people, investigate with other operating systems and the solutions to those. Set the equivalent of TCP_SYNCNT so that the expected behaviour of epoll_wait with an infinite timeout happens.
    or:
  2. document this behaviour to help future people who may trip on it.

@saghul
Copy link
Contributor

saghul commented Aug 13, 2014

Hi @LinuxJedi,

I think documentation is the only way to "solve" this. libuv always uses sockets in non-blocking mode, regardless of the mode the loop is run on. Now, if all you have in the loop is a TCP handle trying to connect somewhere, then the loop will block for i/o for an infinite amount of time. If you would add a timer for X seconds then the loop would block for that amount of time (since it's the only timer).

We could modify uv_cancel to allow it to cancel uv_connect requests, but that can only happen before libuv actually calls connect() (once the socket becomes readable), after that uv_cancel would return false and do nothing.

I don't know if there is some system wide setting affecting this, which is of course platform dependent. AFAIS here: http://stackoverflow.com/questions/8471577/linux-tcp-connect-failure-with-etimedout the timeout is not just one value, it's a result of a linear and then a exponential backoff, at least in Linux, and TBH I have no idea if there is a way to affect it with a setsockopt which refers to time, rather than number of SYNs, which is very low-level.

I'll leave this open for a while, maybe someone knows the answer to this... :-)

@LinuxJedi
Copy link
Author

Agreed, in the mean time I'll work on a fix for my code in the one scenario where I'm using UV_RUN_DEFAULT on connect :)

@saghul
Copy link
Contributor

saghul commented Aug 18, 2014

Closing then!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants