diff --git a/include/uv.h b/include/uv.h index f4093ff762..629435274e 100644 --- a/include/uv.h +++ b/include/uv.h @@ -632,6 +632,20 @@ UV_EXTERN int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr, const char* interface_addr, uv_membership membership); +/* + * Set IP multicast loop flag. Makes multicast packets loop back to + * local sockets. + * + * Arguments: + * handle UDP handle. Should have been initialized with + * `uv_udp_init`. + * on 1 for on, 0 for off + * + * Returns: + * 0 on success, -1 on error. + */ +UV_EXTERN int uv_udp_set_multicast_loop(uv_udp_t* handle, int on); + /* * Set the multicast ttl * diff --git a/src/unix/udp.c b/src/unix/udp.c index 26e5f42d60..3e5de92948 100644 --- a/src/unix/udp.c +++ b/src/unix/udp.c @@ -509,37 +509,25 @@ int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr, return 0; } -int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) { - if (setsockopt(handle->fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof ttl) == -1) { - uv__set_sys_error(handle->loop, errno); - return -1; - } - return 0; -} - -int uv_udp_set_broadcast(uv_udp_t* handle, int on) { - if (setsockopt(handle->fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof on) == -1) { - uv__set_sys_error(handle->loop, errno); - return -1; +#define X(name, level, option) \ + int uv_udp_set_##name(uv_udp_t* handle, int flag) { \ + if (setsockopt(handle->fd, level, option, &flag, sizeof(flag))) { \ + uv__set_sys_error(handle->loop, errno); \ + return -1; \ + } \ + return 0; \ } - return 0; -} - - -int uv_udp_set_ttl(uv_udp_t* handle, int ttl) { - if (setsockopt(handle->fd, IPPROTO_IP, IP_TTL, &ttl, sizeof ttl)) { - uv__set_sys_error(handle->loop, errno); - return -1; - } +X(multicast_loop, IPPROTO_IP, IP_MULTICAST_LOOP) +X(multicast_ttl, IPPROTO_IP, IP_MULTICAST_TTL) +X(broadcast, SOL_SOCKET, SO_BROADCAST) +X(ttl, IPPROTO_IP, IP_TTL) - return 0; -} +#undef X -int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, - int* namelen) { +int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen) { socklen_t socklen; int saved_errno; int rv = 0; diff --git a/src/win/udp.c b/src/win/udp.c index 359dce0a9b..0a9990a5b7 100644 --- a/src/win/udp.c +++ b/src/win/udp.c @@ -579,6 +579,12 @@ void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle, } +int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) { + uv__set_artificial_error(handle->loop, UV_ENOSYS); + return -1; +} + + int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) { if (setsockopt(handle->socket, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl, sizeof ttl) == -1) {