diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2020-04-28 20:15:14 +0200 |
---|---|---|
committer | Jameson Nash <vtjnash@gmail.com> | 2020-10-27 13:00:59 -0400 |
commit | 726af5ebc37af1aafd0b3d2fb563ada53c8f4d06 (patch) | |
tree | 91f25b840b95c923235ad43354fddf51e16d3a70 /test/test-tcp-bind-error.c | |
parent | 97a903309f79d79496a2a1f95cbcce21bfc2f76e (diff) | |
download | libuv-726af5ebc37af1aafd0b3d2fb563ada53c8f4d06.tar.gz libuv-726af5ebc37af1aafd0b3d2fb563ada53c8f4d06.zip |
unix: report bind error in uv_tcp_connect()
Fix a bug where libuv forgets about EADDRINUSE errors reported earlier:
uv_tcp_bind() + uv_tcp_connect() seemingly succeed but the socket isn't
actually bound to the requested address.
This bug goes back to at least 2011 if indeed it ever worked at all.
PR-URL: https://github.com/libuv/libuv/pull/2218
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Jameson Nash <vtjnash@gmail.com>
Diffstat (limited to 'test/test-tcp-bind-error.c')
-rw-r--r-- | test/test-tcp-bind-error.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/test/test-tcp-bind-error.c b/test/test-tcp-bind-error.c index f95efd9f..29ed21e1 100644 --- a/test/test-tcp-bind-error.c +++ b/test/test-tcp-bind-error.c @@ -25,6 +25,7 @@ #include <stdlib.h> +static int connect_cb_called = 0; static int close_cb_called = 0; @@ -34,7 +35,49 @@ static void close_cb(uv_handle_t* handle) { } -TEST_IMPL(tcp_bind_error_addrinuse) { +static void connect_cb(uv_connect_t* req, int status) { + ASSERT(status == UV_EADDRINUSE); + uv_close((uv_handle_t*) req->handle, close_cb); + connect_cb_called++; +} + + +TEST_IMPL(tcp_bind_error_addrinuse_connect) { + struct sockaddr_in addr; + int addrlen; + uv_connect_t req; + uv_tcp_t conn; + + /* 127.0.0.1:<TEST_PORT> is already taken by tcp4_echo_server running in + * another process. uv_tcp_bind() and uv_tcp_connect() should still succeed + * (greatest common denominator across platforms) but the connect callback + * should receive an UV_EADDRINUSE error. + */ + ASSERT(0 == uv_tcp_init(uv_default_loop(), &conn)); + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + ASSERT(0 == uv_tcp_bind(&conn, (const struct sockaddr*) &addr, 0)); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT + 1, &addr)); + ASSERT(0 == uv_tcp_connect(&req, + &conn, + (const struct sockaddr*) &addr, + connect_cb)); + + addrlen = sizeof(addr); + ASSERT(UV_EADDRINUSE == uv_tcp_getsockname(&conn, + (struct sockaddr*) &addr, + &addrlen)); + + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(connect_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_bind_error_addrinuse_listen) { struct sockaddr_in addr; uv_tcp_t server1, server2; int r; |