From aa7b62efd976eacf9c55150631a08ceec91a5cd1 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Tue, 28 Apr 2020 17:57:25 +0200 Subject: [PATCH] win: make uv_udp_init_ex() accept UV_UDP_RECVMMSG Commit 5736658b ("udp: add flag to enable recvmmsg(2) explicitly") added the flag but didn't update the validation logic in src/win/udp.c. This commit moves the validation logic to src/uv-common.c. The flag is now accepted as a no-op on Windows. Fixes: https://github.com/libuv/libuv/issues/2806 PR-URL: https://github.com/libuv/libuv/pull/2809 Reviewed-By: Bartosz Sosnowski Reviewed-By: Colin Ihrig Reviewed-By: Santiago Gimeno --- src/unix/udp.c | 25 ++++--------------------- src/uv-common.c | 30 ++++++++++++++++++++++++++++++ src/uv-common.h | 5 +++++ src/win/udp.c | 20 ++++---------------- test/test-udp-options.c | 2 +- 5 files changed, 44 insertions(+), 38 deletions(-) diff --git a/src/unix/udp.c b/src/unix/udp.c index 3aa11c5b..bc6a23d8 100644 --- a/src/unix/udp.c +++ b/src/unix/udp.c @@ -944,22 +944,13 @@ static int uv__udp_set_source_membership6(uv_udp_t* handle, #endif -int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) { - int domain; +int uv__udp_init_ex(uv_loop_t* loop, + uv_udp_t* handle, + unsigned flags, + int domain) { int err; - int extra_flags; int fd; - /* Use the lower 8 bits for the domain */ - domain = flags & 0xFF; - if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC) - return UV_EINVAL; - - /* Use the higher bits for extra flags */ - extra_flags = flags & ~0xFF; - if (extra_flags & ~UV_UDP_RECVMMSG) - return UV_EINVAL; - if (domain != AF_UNSPEC) { err = uv__socket(domain, SOCK_DGRAM, 0); if (err < 0) @@ -978,18 +969,10 @@ int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) { QUEUE_INIT(&handle->write_queue); QUEUE_INIT(&handle->write_completed_queue); - if (extra_flags & UV_UDP_RECVMMSG) - handle->flags |= UV_HANDLE_UDP_RECVMMSG; - return 0; } -int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) { - return uv_udp_init_ex(loop, handle, AF_UNSPEC); -} - - int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) { int err; diff --git a/src/uv-common.c b/src/uv-common.c index f69a2c1d..a25d6aae 100644 --- a/src/uv-common.c +++ b/src/uv-common.c @@ -293,6 +293,36 @@ int uv_tcp_bind(uv_tcp_t* handle, } +int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned flags) { + unsigned extra_flags; + int domain; + int rc; + + /* Use the lower 8 bits for the domain. */ + domain = flags & 0xFF; + if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC) + return UV_EINVAL; + + /* Use the higher bits for extra flags. */ + extra_flags = flags & ~0xFF; + if (extra_flags & ~UV_UDP_RECVMMSG) + return UV_EINVAL; + + rc = uv__udp_init_ex(loop, handle, flags, domain); + + if (rc == 0) + if (extra_flags & UV_UDP_RECVMMSG) + handle->flags |= UV_HANDLE_UDP_RECVMMSG; + + return rc; +} + + +int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) { + return uv_udp_init_ex(loop, handle, AF_UNSPEC); +} + + int uv_udp_bind(uv_udp_t* handle, const struct sockaddr* addr, unsigned int flags) { diff --git a/src/uv-common.h b/src/uv-common.h index 28cc852c..0b0f5f86 100644 --- a/src/uv-common.h +++ b/src/uv-common.h @@ -139,6 +139,11 @@ int uv__tcp_connect(uv_connect_t* req, unsigned int addrlen, uv_connect_cb cb); +int uv__udp_init_ex(uv_loop_t* loop, + uv_udp_t* handle, + unsigned flags, + int domain); + int uv__udp_bind(uv_udp_t* handle, const struct sockaddr* addr, unsigned int addrlen, diff --git a/src/win/udp.c b/src/win/udp.c index 3daa55f6..508ed37f 100644 --- a/src/win/udp.c +++ b/src/win/udp.c @@ -125,17 +125,10 @@ static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket, } -int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) { - int domain; - - /* Use the lower 8 bits for the domain */ - domain = flags & 0xFF; - if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC) - return UV_EINVAL; - - if (flags & ~0xFF) - return UV_EINVAL; - +int uv__udp_init_ex(uv_loop_t* loop, + uv_udp_t* handle, + unsigned flags, + int domain) { uv__handle_init(loop, (uv_handle_t*) handle, UV_UDP); handle->socket = INVALID_SOCKET; handle->reqs_pending = 0; @@ -174,11 +167,6 @@ int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) { } -int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) { - return uv_udp_init_ex(loop, handle, AF_UNSPEC); -} - - void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) { uv_udp_recv_stop(handle); closesocket(handle->socket); diff --git a/test/test-udp-options.c b/test/test-udp-options.c index d8c9d68d..70f415ec 100644 --- a/test/test-udp-options.c +++ b/test/test-udp-options.c @@ -133,7 +133,7 @@ TEST_IMPL(udp_no_autobind) { uv_close((uv_handle_t*) &h, NULL); /* Test a non-lazily initialized socket. */ - ASSERT(0 == uv_udp_init_ex(loop, &h2, AF_INET)); + ASSERT(0 == uv_udp_init_ex(loop, &h2, AF_INET | UV_UDP_RECVMMSG)); ASSERT(0 == uv_udp_set_multicast_ttl(&h2, 32)); ASSERT(0 == uv_udp_set_broadcast(&h2, 1));