unix, windows: be consistent when binding implictly in UDP
Only these functions will trigger an implicit binding of a UDP handle: - uv_udp_send - uv_udp_recv_start - uv_udp_set_membership All other functions will return UV_EBADF in case the socket was not bound. Note: currently the socket is created and bound at the same time. This may change in the future.
This commit is contained in:
parent
fa0e1e5071
commit
386d2141e4
@ -629,7 +629,6 @@ int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
|
||||
}
|
||||
|
||||
int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) {
|
||||
int err;
|
||||
struct sockaddr_storage addr_st;
|
||||
struct sockaddr_in* addr4;
|
||||
struct sockaddr_in6* addr6;
|
||||
@ -655,9 +654,6 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
|
||||
}
|
||||
|
||||
if (addr_st.ss_family == AF_INET) {
|
||||
err = uv__udp_maybe_deferred_bind(handle, AF_INET, UV_UDP_REUSEADDR);
|
||||
if (err)
|
||||
return err;
|
||||
if (setsockopt(handle->io_watcher.fd,
|
||||
IPPROTO_IP,
|
||||
IP_MULTICAST_IF,
|
||||
@ -666,9 +662,6 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
|
||||
return -errno;
|
||||
}
|
||||
} else if (addr_st.ss_family == AF_INET6) {
|
||||
err = uv__udp_maybe_deferred_bind(handle, AF_INET6, UV_UDP_REUSEADDR);
|
||||
if (err)
|
||||
return err;
|
||||
if (setsockopt(handle->io_watcher.fd,
|
||||
IPPROTO_IPV6,
|
||||
IPV6_MULTICAST_IF,
|
||||
|
||||
@ -662,7 +662,6 @@ int uv_udp_set_membership(uv_udp_t* handle,
|
||||
|
||||
|
||||
int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) {
|
||||
int err;
|
||||
struct sockaddr_storage addr_st;
|
||||
struct sockaddr_in* addr4;
|
||||
struct sockaddr_in6* addr6;
|
||||
@ -687,13 +686,10 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
if (!(handle->flags & UV_HANDLE_BOUND))
|
||||
return UV_EBADF;
|
||||
|
||||
if (addr_st.ss_family == AF_INET) {
|
||||
err = uv_udp_maybe_bind(handle,
|
||||
(const struct sockaddr*) &uv_addr_ip4_any_,
|
||||
sizeof(uv_addr_ip4_any_),
|
||||
UV_UDP_REUSEADDR);
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
if (setsockopt(handle->socket,
|
||||
IPPROTO_IP,
|
||||
IP_MULTICAST_IF,
|
||||
@ -702,12 +698,6 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
|
||||
return uv_translate_sys_error(WSAGetLastError());
|
||||
}
|
||||
} else if (addr_st.ss_family == AF_INET6) {
|
||||
err = uv_udp_maybe_bind(handle,
|
||||
(const struct sockaddr*) &uv_addr_ip6_any_,
|
||||
sizeof(uv_addr_ip6_any_),
|
||||
UV_UDP_REUSEADDR);
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
if (setsockopt(handle->socket,
|
||||
IPPROTO_IPV6,
|
||||
IPV6_MULTICAST_IF,
|
||||
@ -726,15 +716,9 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
|
||||
|
||||
int uv_udp_set_broadcast(uv_udp_t* handle, int value) {
|
||||
BOOL optval = (BOOL) value;
|
||||
int err;
|
||||
|
||||
/* If the socket is unbound, bind to inaddr_any. */
|
||||
err = uv_udp_maybe_bind(handle,
|
||||
(const struct sockaddr*) &uv_addr_ip4_any_,
|
||||
sizeof(uv_addr_ip4_any_),
|
||||
0);
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
if (!(handle->flags & UV_HANDLE_BOUND))
|
||||
return UV_EBADF;
|
||||
|
||||
if (setsockopt(handle->socket,
|
||||
SOL_SOCKET,
|
||||
@ -774,19 +758,13 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
|
||||
#define SOCKOPT_SETTER(name, option4, option6, validate) \
|
||||
int uv_udp_set_##name(uv_udp_t* handle, int value) { \
|
||||
DWORD optval = (DWORD) value; \
|
||||
int err; \
|
||||
\
|
||||
if (!(validate(value))) { \
|
||||
return UV_EINVAL; \
|
||||
} \
|
||||
\
|
||||
/* If the socket is unbound, bind to inaddr_any. */ \
|
||||
err = uv_udp_maybe_bind(handle, \
|
||||
(const struct sockaddr*) &uv_addr_ip4_any_, \
|
||||
sizeof(uv_addr_ip4_any_), \
|
||||
0); \
|
||||
if (err) \
|
||||
return uv_translate_sys_error(err); \
|
||||
if (!(handle->flags & UV_HANDLE_BOUND)) \
|
||||
return UV_EBADF; \
|
||||
\
|
||||
if (!(handle->flags & UV_HANDLE_IPV6)) { \
|
||||
/* Set IPv4 socket option */ \
|
||||
|
||||
@ -93,6 +93,7 @@ TEST_DECLARE (udp_dgram_too_big)
|
||||
TEST_DECLARE (udp_dual_stack)
|
||||
TEST_DECLARE (udp_ipv6_only)
|
||||
TEST_DECLARE (udp_options)
|
||||
TEST_DECLARE (udp_no_autobind)
|
||||
TEST_DECLARE (udp_open)
|
||||
TEST_DECLARE (pipe_bind_error_addrinuse)
|
||||
TEST_DECLARE (pipe_bind_error_addrnotavail)
|
||||
@ -363,6 +364,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (udp_dual_stack)
|
||||
TEST_ENTRY (udp_ipv6_only)
|
||||
TEST_ENTRY (udp_options)
|
||||
TEST_ENTRY (udp_no_autobind)
|
||||
TEST_ENTRY (udp_multicast_interface)
|
||||
TEST_ENTRY (udp_multicast_interface6)
|
||||
TEST_ENTRY (udp_multicast_join)
|
||||
|
||||
@ -86,3 +86,25 @@ TEST_IMPL(udp_options) {
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(udp_no_autobind) {
|
||||
uv_loop_t* loop;
|
||||
uv_udp_t h;
|
||||
|
||||
loop = uv_default_loop();
|
||||
|
||||
ASSERT(0 == uv_udp_init(loop, &h));
|
||||
ASSERT(UV_EBADF == uv_udp_set_multicast_ttl(&h, 32));
|
||||
ASSERT(UV_EBADF == uv_udp_set_broadcast(&h, 1));
|
||||
ASSERT(UV_EBADF == uv_udp_set_ttl(&h, 1));
|
||||
ASSERT(UV_EBADF == uv_udp_set_multicast_loop(&h, 1));
|
||||
ASSERT(UV_EBADF == uv_udp_set_multicast_interface(&h, "0.0.0.0"));
|
||||
|
||||
uv_close((uv_handle_t*) &h, NULL);
|
||||
|
||||
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user