diff options
author | cjihrig <cjihrig@gmail.com> | 2019-09-09 13:08:37 -0400 |
---|---|---|
committer | Rich Trott <rtrott@gmail.com> | 2019-09-12 00:49:02 -0700 |
commit | df0e2e3625d1f72e8b04e05ffa13997a51e9f0d7 (patch) | |
tree | 5ef978de762b47bcfc6323c48e7e22b862d6d657 /deps/uv/src/win/udp.c | |
parent | 62e8cc5e61a36ebe1bd913983a452961aa1c9946 (diff) | |
download | android-node-v8-df0e2e3625d1f72e8b04e05ffa13997a51e9f0d7.tar.gz android-node-v8-df0e2e3625d1f72e8b04e05ffa13997a51e9f0d7.tar.bz2 android-node-v8-df0e2e3625d1f72e8b04e05ffa13997a51e9f0d7.zip |
deps: upgrade to libuv 1.32.0
Notable changes:
- `uv_tcp_close_reset()` has been added.
- `uv_udp_set_source_membership()` has been added.
- A double free in `uv_free_cpu_info()` on OpenBSD
has been fixed.
- Defined, but empty environment variables can now
be read on Windows.
- Several improvements to the cmake build process.
- The `EILSEQ` error code is now mapped by libuv.
PR-URL: https://github.com/nodejs/node/pull/29508
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: David Carlier <devnexen@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Beth Griggs <Bethany.Griggs@uk.ibm.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'deps/uv/src/win/udp.c')
-rw-r--r-- | deps/uv/src/win/udp.c | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c index 8aeeab3b46..39fc34d3bf 100644 --- a/deps/uv/src/win/udp.c +++ b/deps/uv/src/win/udp.c @@ -702,6 +702,112 @@ int uv__udp_set_membership6(uv_udp_t* handle, } +static int uv__udp_set_source_membership4(uv_udp_t* handle, + const struct sockaddr_in* multicast_addr, + const char* interface_addr, + const struct sockaddr_in* source_addr, + uv_membership membership) { + struct ip_mreq_source mreq; + int optname; + int err; + + if (handle->flags & UV_HANDLE_IPV6) + 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_), + UV_UDP_REUSEADDR); + if (err) + return uv_translate_sys_error(err); + + memset(&mreq, 0, sizeof(mreq)); + + if (interface_addr != NULL) { + err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr); + if (err) + return err; + } else { + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + } + + mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr; + mreq.imr_sourceaddr.s_addr = source_addr->sin_addr.s_addr; + + if (membership == UV_JOIN_GROUP) + optname = IP_ADD_SOURCE_MEMBERSHIP; + else if (membership == UV_LEAVE_GROUP) + optname = IP_DROP_SOURCE_MEMBERSHIP; + else + return UV_EINVAL; + + if (setsockopt(handle->socket, + IPPROTO_IP, + optname, + (char*) &mreq, + sizeof(mreq)) == SOCKET_ERROR) { + return uv_translate_sys_error(WSAGetLastError()); + } + + return 0; +} + + +int uv__udp_set_source_membership6(uv_udp_t* handle, + const struct sockaddr_in6* multicast_addr, + const char* interface_addr, + const struct sockaddr_in6* source_addr, + uv_membership membership) { + struct group_source_req mreq; + struct sockaddr_in6 addr6; + int optname; + int err; + + if ((handle->flags & UV_HANDLE_BOUND) && !(handle->flags & UV_HANDLE_IPV6)) + return UV_EINVAL; + + 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); + + memset(&mreq, 0, sizeof(mreq)); + + if (interface_addr != NULL) { + err = uv_ip6_addr(interface_addr, 0, &addr6); + if (err) + return err; + mreq.gsr_interface = addr6.sin6_scope_id; + } else { + mreq.gsr_interface = 0; + } + + memcpy(&mreq.gsr_group, multicast_addr, sizeof(mreq.gsr_group)); + memcpy(&mreq.gsr_source, source_addr, sizeof(mreq.gsr_source)); + + if (membership == UV_JOIN_GROUP) + optname = MCAST_JOIN_SOURCE_GROUP; + else if (membership == UV_LEAVE_GROUP) + optname = MCAST_LEAVE_SOURCE_GROUP; + else + return UV_EINVAL; + + if (setsockopt(handle->socket, + IPPROTO_IPV6, + optname, + (char*) &mreq, + sizeof(mreq)) == SOCKET_ERROR) { + return uv_translate_sys_error(WSAGetLastError()); + } + + return 0; +} + + int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr, const char* interface_addr, @@ -718,6 +824,50 @@ int uv_udp_set_membership(uv_udp_t* handle, } +int uv_udp_set_source_membership(uv_udp_t* handle, + const char* multicast_addr, + const char* interface_addr, + const char* source_addr, + uv_membership membership) { + int err; + struct sockaddr_storage mcast_addr; + struct sockaddr_in* mcast_addr4; + struct sockaddr_in6* mcast_addr6; + struct sockaddr_storage src_addr; + struct sockaddr_in* src_addr4; + struct sockaddr_in6* src_addr6; + + mcast_addr4 = (struct sockaddr_in*)&mcast_addr; + mcast_addr6 = (struct sockaddr_in6*)&mcast_addr; + src_addr4 = (struct sockaddr_in*)&src_addr; + src_addr6 = (struct sockaddr_in6*)&src_addr; + + err = uv_ip4_addr(multicast_addr, 0, mcast_addr4); + if (err) { + err = uv_ip6_addr(multicast_addr, 0, mcast_addr6); + if (err) + return err; + err = uv_ip6_addr(source_addr, 0, src_addr6); + if (err) + return err; + return uv__udp_set_source_membership6(handle, + mcast_addr6, + interface_addr, + src_addr6, + membership); + } + + err = uv_ip4_addr(source_addr, 0, src_addr4); + if (err) + return err; + return uv__udp_set_source_membership4(handle, + mcast_addr4, + interface_addr, + src_addr4, + membership); +} + + int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) { struct sockaddr_storage addr_st; struct sockaddr_in* addr4; |