summaryrefslogtreecommitdiff
path: root/deps/uv/src/unix/udp.c
diff options
context:
space:
mode:
authorcjihrig <cjihrig@gmail.com>2019-09-09 13:08:37 -0400
committerRich Trott <rtrott@gmail.com>2019-09-12 00:49:02 -0700
commitdf0e2e3625d1f72e8b04e05ffa13997a51e9f0d7 (patch)
tree5ef978de762b47bcfc6323c48e7e22b862d6d657 /deps/uv/src/unix/udp.c
parent62e8cc5e61a36ebe1bd913983a452961aa1c9946 (diff)
downloadandroid-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/unix/udp.c')
-rw-r--r--deps/uv/src/unix/udp.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c
index b578e7bc10..dba8eff838 100644
--- a/deps/uv/src/unix/udp.c
+++ b/deps/uv/src/unix/udp.c
@@ -659,6 +659,98 @@ static 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;
+
+ err = uv__udp_maybe_deferred_bind(handle, AF_INET, UV_UDP_REUSEADDR);
+ if (err)
+ return 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->io_watcher.fd,
+ IPPROTO_IP,
+ optname,
+ &mreq,
+ sizeof(mreq))) {
+ return UV__ERR(errno);
+ }
+
+ return 0;
+}
+
+
+static 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;
+
+ err = uv__udp_maybe_deferred_bind(handle, AF_INET6, UV_UDP_REUSEADDR);
+ if (err)
+ return 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->io_watcher.fd,
+ IPPROTO_IPV6,
+ optname,
+ &mreq,
+ sizeof(mreq))) {
+ return UV__ERR(errno);
+ }
+
+ return 0;
+}
+
+
int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
int domain;
int err;
@@ -748,6 +840,51 @@ 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);
+}
+
+
static int uv__setsockopt(uv_udp_t* handle,
int option4,
int option6,