aboutsummaryrefslogtreecommitdiff
path: root/test/test-tcp-bind-error.c
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2020-04-28 20:15:14 +0200
committerJameson Nash <vtjnash@gmail.com>2020-10-27 13:00:59 -0400
commit726af5ebc37af1aafd0b3d2fb563ada53c8f4d06 (patch)
tree91f25b840b95c923235ad43354fddf51e16d3a70 /test/test-tcp-bind-error.c
parent97a903309f79d79496a2a1f95cbcce21bfc2f76e (diff)
downloadlibuv-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.c45
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;