test: add specific source multicast tests

PR-URL: https://github.com/libuv/libuv/pull/2202
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
Santiago Gimeno 2019-02-21 07:00:46 +01:00
parent 80e931b38c
commit 24e65f776d
No known key found for this signature in database
GPG Key ID: F28C3C8DA33C03BE
2 changed files with 101 additions and 47 deletions

View File

@ -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();

View File

@ -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();