diff --git a/test/test-udp-multicast-join.c b/test/test-udp-multicast-join.c index 6399d9c9..6bac072d 100644 --- a/test/test-udp-multicast-join.c +++ b/test/test-udp-multicast-join.c @@ -29,8 +29,12 @@ #define CHECK_HANDLE(handle) \ ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) +#define MULTICAST_ADDR "239.255.0.1" + static uv_udp_t server; static uv_udp_t client; +static uv_udp_send_t req; +static uv_udp_send_t req_ss; static int cl_recv_cb_called; @@ -62,7 +66,26 @@ static void sv_send_cb(uv_udp_send_t* req, int status) { sv_send_cb_called++; - uv_close((uv_handle_t*) req->handle, close_cb); + if (sv_send_cb_called == 2) + uv_close((uv_handle_t*) req->handle, close_cb); +} + + +static int do_send(uv_udp_send_t* send_req) { + uv_buf_t buf; + struct sockaddr_in addr; + + buf = uv_buf_init("PING", 4); + + ASSERT(0 == uv_ip4_addr(MULTICAST_ADDR, TEST_PORT, &addr)); + + /* client sends "PING" */ + return uv_udp_send(send_req, + &client, + &buf, + 1, + (const struct sockaddr*) &addr, + sv_send_cb); } @@ -74,8 +97,6 @@ static void cl_recv_cb(uv_udp_t* handle, CHECK_HANDLE(handle); ASSERT(flags == 0); - cl_recv_cb_called++; - if (nread < 0) { ASSERT(0 && "unexpected error"); } @@ -90,15 +111,32 @@ static void cl_recv_cb(uv_udp_t* handle, ASSERT(nread == 4); ASSERT(!memcmp("PING", buf->base, nread)); - /* we are done with the client handle, we can close it */ - uv_close((uv_handle_t*) &client, close_cb); + cl_recv_cb_called++; + + if (cl_recv_cb_called == 2) { + /* we are done with the server handle, we can close it */ + uv_close((uv_handle_t*) &server, close_cb); + } else { + int r; + char source_addr[64]; + + r = uv_ip4_name((const struct sockaddr_in*)addr, source_addr, sizeof(source_addr)); + ASSERT(r == 0); + + r = uv_udp_set_membership(&server, MULTICAST_ADDR, NULL, UV_LEAVE_GROUP); + ASSERT(r == 0); + + r = uv_udp_set_source_membership(&server, MULTICAST_ADDR, NULL, source_addr, UV_JOIN_GROUP); + ASSERT(r == 0); + + r = do_send(&req_ss); + ASSERT(r == 0); + } } TEST_IMPL(udp_multicast_join) { int r; - uv_udp_send_t req; - uv_buf_t buf; struct sockaddr_in addr; ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); @@ -110,29 +148,19 @@ TEST_IMPL(udp_multicast_join) { ASSERT(r == 0); /* bind to the desired port */ - r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0); + r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0); ASSERT(r == 0); /* join the multicast channel */ - r = uv_udp_set_membership(&client, "239.255.0.1", NULL, UV_JOIN_GROUP); + r = uv_udp_set_membership(&server, MULTICAST_ADDR, NULL, UV_JOIN_GROUP); if (r == UV_ENODEV) RETURN_SKIP("No multicast support."); ASSERT(r == 0); - r = uv_udp_recv_start(&client, alloc_cb, cl_recv_cb); + r = uv_udp_recv_start(&server, alloc_cb, cl_recv_cb); ASSERT(r == 0); - buf = uv_buf_init("PING", 4); - - ASSERT(0 == uv_ip4_addr("239.255.0.1", TEST_PORT, &addr)); - - /* server sends "PING" */ - r = uv_udp_send(&req, - &server, - &buf, - 1, - (const struct sockaddr*) &addr, - sv_send_cb); + r = do_send(&req); ASSERT(r == 0); ASSERT(close_cb_called == 0); @@ -142,8 +170,8 @@ TEST_IMPL(udp_multicast_join) { /* run the loop till all events are processed */ uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(cl_recv_cb_called == 1); - ASSERT(sv_send_cb_called == 1); + ASSERT(cl_recv_cb_called == 2); + ASSERT(sv_send_cb_called == 2); ASSERT(close_cb_called == 2); MAKE_VALGRIND_HAPPY(); diff --git a/test/test-udp-multicast-join6.c b/test/test-udp-multicast-join6.c index 49d253ab..5de27a7f 100644 --- a/test/test-udp-multicast-join6.c +++ b/test/test-udp-multicast-join6.c @@ -45,6 +45,8 @@ static uv_udp_t server; static uv_udp_t client; +static uv_udp_send_t req; +static uv_udp_send_t req_ss; static int cl_recv_cb_called; @@ -76,7 +78,26 @@ static void sv_send_cb(uv_udp_send_t* req, int status) { sv_send_cb_called++; - uv_close((uv_handle_t*) req->handle, close_cb); + if (sv_send_cb_called == 2) + uv_close((uv_handle_t*) req->handle, close_cb); +} + + +static int do_send(uv_udp_send_t* send_req) { + uv_buf_t buf; + struct sockaddr_in6 addr; + + buf = uv_buf_init("PING", 4); + + ASSERT(0 == uv_ip6_addr(MULTICAST_ADDR, TEST_PORT, &addr)); + + /* client sends "PING" */ + return uv_udp_send(send_req, + &client, + &buf, + 1, + (const struct sockaddr*) &addr, + sv_send_cb); } @@ -88,8 +109,6 @@ static void cl_recv_cb(uv_udp_t* handle, CHECK_HANDLE(handle); ASSERT(flags == 0); - cl_recv_cb_called++; - if (nread < 0) { ASSERT(0 && "unexpected error"); } @@ -104,8 +123,27 @@ static void cl_recv_cb(uv_udp_t* handle, ASSERT(nread == 4); ASSERT(!memcmp("PING", buf->base, nread)); - /* we are done with the client handle, we can close it */ - uv_close((uv_handle_t*) &client, close_cb); + cl_recv_cb_called++; + + if (cl_recv_cb_called == 2) { + /* we are done with the server handle, we can close it */ + uv_close((uv_handle_t*) &server, close_cb); + } else { + int r; + char source_addr[64]; + + r = uv_ip6_name((const struct sockaddr_in6*)addr, source_addr, sizeof(source_addr)); + ASSERT(r == 0); + + r = uv_udp_set_membership(&server, MULTICAST_ADDR, INTERFACE_ADDR, UV_LEAVE_GROUP); + ASSERT(r == 0); + + r = uv_udp_set_source_membership(&server, MULTICAST_ADDR, INTERFACE_ADDR, source_addr, UV_JOIN_GROUP); + ASSERT(r == 0); + + r = do_send(&req_ss); + ASSERT(r == 0); + } } @@ -130,8 +168,6 @@ static int can_ipv6_external(void) { TEST_IMPL(udp_multicast_join6) { int r; - uv_udp_send_t req; - uv_buf_t buf; struct sockaddr_in6 addr; if (!can_ipv6_external()) @@ -146,10 +182,10 @@ TEST_IMPL(udp_multicast_join6) { ASSERT(r == 0); /* bind to the desired port */ - r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0); + r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0); ASSERT(r == 0); - r = uv_udp_set_membership(&client, MULTICAST_ADDR, INTERFACE_ADDR, UV_JOIN_GROUP); + r = uv_udp_set_membership(&server, MULTICAST_ADDR, INTERFACE_ADDR, UV_JOIN_GROUP); if (r == UV_ENODEV) { MAKE_VALGRIND_HAPPY(); RETURN_SKIP("No ipv6 multicast route"); @@ -157,20 +193,10 @@ TEST_IMPL(udp_multicast_join6) { ASSERT(r == 0); - r = uv_udp_recv_start(&client, alloc_cb, cl_recv_cb); + r = uv_udp_recv_start(&server, alloc_cb, cl_recv_cb); ASSERT(r == 0); - - buf = uv_buf_init("PING", 4); - - ASSERT(0 == uv_ip6_addr(MULTICAST_ADDR, TEST_PORT, &addr)); - - /* server sends "PING" */ - r = uv_udp_send(&req, - &server, - &buf, - 1, - (const struct sockaddr*) &addr, - sv_send_cb); + + r = do_send(&req); ASSERT(r == 0); ASSERT(close_cb_called == 0); @@ -180,8 +206,8 @@ TEST_IMPL(udp_multicast_join6) { /* run the loop till all events are processed */ uv_run(uv_default_loop(), UV_RUN_DEFAULT); - ASSERT(cl_recv_cb_called == 1); - ASSERT(sv_send_cb_called == 1); + ASSERT(cl_recv_cb_called == 2); + ASSERT(sv_send_cb_called == 2); ASSERT(close_cb_called == 2); MAKE_VALGRIND_HAPPY();