diff --git a/ext/sockets/multicast.c b/ext/sockets/multicast.c index f331fd177ebfd..909c0743b4db6 100644 --- a/ext/sockets/multicast.c +++ b/ext/sockets/multicast.c @@ -262,8 +262,12 @@ int php_do_setsockopt_ip_mcast(php_socket *php_sock, struct in_addr if_addr; void *opt_ptr; socklen_t optlen; - unsigned char ipv4_mcast_ttl_lback; + int ip_mcast_loop_back; + int ip_mcast_hops; int retval; +#if IP_MULTICAST_LOOP != IPV6_MULTICAST_LOOP + unsigned char ip_mcast_ttl; +#endif switch (optname) { case PHP_MCAST_JOIN_GROUP: @@ -274,101 +278,62 @@ int php_do_setsockopt_ip_mcast(php_socket *php_sock, case PHP_MCAST_JOIN_SOURCE_GROUP: case PHP_MCAST_LEAVE_SOURCE_GROUP: #endif - if (php_do_mcast_opt(php_sock, level, optname, arg4) == FAILURE) { - return FAILURE; - } else { - return SUCCESS; - } + return php_do_mcast_opt(php_sock, level, optname, arg4); case IP_MULTICAST_IF: +/* On MacOS and Windows those have the same values */ +#if IP_MULTICAST_LOOP != IPV6_MULTICAST_LOOP + case IPV6_MULTICAST_IF: +#endif if (php_get_if_index_from_zval(arg4, &if_index) == FAILURE) { return FAILURE; } - if (php_if_index_to_addr4(if_index, php_sock, &if_addr) == FAILURE) { - return FAILURE; + if (optname == IP_MULTICAST_IF) { + if (php_if_index_to_addr4(if_index, php_sock, &if_addr) == FAILURE) { + return FAILURE; + } + opt_ptr = &if_addr; + optlen = sizeof(if_addr); + } else { + opt_ptr = &if_index; + optlen = sizeof(if_index); } - opt_ptr = &if_addr; - optlen = sizeof(if_addr); goto dosockopt; case IP_MULTICAST_LOOP: - ipv4_mcast_ttl_lback = (unsigned char) zval_is_true(arg4); - goto ipv4_loop_ttl; +/* On MacOS and Windows those have the same values */ +#if IP_MULTICAST_LOOP != IPV6_MULTICAST_LOOP + case IPV6_MULTICAST_LOOP: +#endif + ip_mcast_loop_back = zval_is_true(arg4); + opt_ptr = &ip_mcast_loop_back; + optlen = sizeof(ip_mcast_loop_back); + goto dosockopt; +/* On MacOS and Windows those have the same values */ +#if IP_MULTICAST_TTL != IPV6_MULTICAST_HOPS case IP_MULTICAST_TTL: convert_to_long(arg4); if (Z_LVAL_P(arg4) < 0L || Z_LVAL_P(arg4) > 255L) { zend_argument_value_error(4, "must be between 0 and 255"); return FAILURE; } - ipv4_mcast_ttl_lback = (unsigned char) Z_LVAL_P(arg4); -ipv4_loop_ttl: - opt_ptr = &ipv4_mcast_ttl_lback; - optlen = sizeof(ipv4_mcast_ttl_lback); + ip_mcast_ttl = (unsigned char) Z_LVAL_P(arg4); + opt_ptr = &ip_mcast_ttl; + optlen = sizeof(ip_mcast_ttl); goto dosockopt; - } - - return 1; - -dosockopt: - retval = setsockopt(php_sock->bsd_socket, level, optname, opt_ptr, optlen); - if (retval != 0) { - PHP_SOCKET_ERROR(php_sock, "Unable to set socket option", errno); - return FAILURE; - } - - return SUCCESS; -} - -int php_do_setsockopt_ipv6_mcast(php_socket *php_sock, - int level, - int optname, - zval *arg4) -{ - unsigned int if_index; - void *opt_ptr; - socklen_t optlen; - int ov; - int retval; - - switch (optname) { - case PHP_MCAST_JOIN_GROUP: - case PHP_MCAST_LEAVE_GROUP: -#ifdef HAS_MCAST_EXT - case PHP_MCAST_BLOCK_SOURCE: - case PHP_MCAST_UNBLOCK_SOURCE: - case PHP_MCAST_JOIN_SOURCE_GROUP: - case PHP_MCAST_LEAVE_SOURCE_GROUP: #endif - if (php_do_mcast_opt(php_sock, level, optname, arg4) == FAILURE) { - return FAILURE; - } else { - return SUCCESS; - } - case IPV6_MULTICAST_IF: - if (php_get_if_index_from_zval(arg4, &if_index) == FAILURE) { - return FAILURE; - } - - opt_ptr = &if_index; - optlen = sizeof(if_index); - goto dosockopt; - - case IPV6_MULTICAST_LOOP: - ov = (int) zval_is_true(arg4); - goto ipv6_loop_hops; case IPV6_MULTICAST_HOPS: convert_to_long(arg4); if (Z_LVAL_P(arg4) < -1L || Z_LVAL_P(arg4) > 255L) { zend_argument_value_error(4, "must be between -1 and 255"); return FAILURE; } - ov = (int) Z_LVAL_P(arg4); -ipv6_loop_hops: - opt_ptr = &ov; - optlen = sizeof(ov); + ip_mcast_hops = (int) Z_LVAL_P(arg4); + opt_ptr = &ip_mcast_hops; + optlen = sizeof(ip_mcast_hops); goto dosockopt; } diff --git a/ext/sockets/multicast.h b/ext/sockets/multicast.h index f2232921c6b93..0e94a8ab5ae84 100644 --- a/ext/sockets/multicast.h +++ b/ext/sockets/multicast.h @@ -47,11 +47,6 @@ int php_do_setsockopt_ip_mcast(php_socket *php_sock, int optname, zval *arg4); -int php_do_setsockopt_ipv6_mcast(php_socket *php_sock, - int level, - int optname, - zval *arg4); - zend_result php_if_index_to_addr4( unsigned if_index, php_socket *php_sock, diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 82634cc8f3e54..ec9fc2b591cb3 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -2031,28 +2031,24 @@ PHP_FUNCTION(socket_set_option) set_errno(0); -#define HANDLE_SUBCALL(res) \ - do { \ - if (res == 1) { goto default_case; } \ - else if (res == SUCCESS) { RETURN_TRUE; } \ - else { RETURN_FALSE; } \ - } while (0) - - - if (level == IPPROTO_IP) { + if ( + level == IPPROTO_IP +#ifdef HAVE_IPV6 + || level == IPPROTO_IPV6 +#endif + ) { int res = php_do_setsockopt_ip_mcast(php_sock, level, optname, arg4); - HANDLE_SUBCALL(res); - } - #ifdef HAVE_IPV6 - else if (level == IPPROTO_IPV6) { - int res = php_do_setsockopt_ipv6_mcast(php_sock, level, optname, arg4); - if (res == 1) { + /* If option is unknown for IPv6 */ + if (level == IPPROTO_IPV6 && res == 1) { res = php_do_setsockopt_ipv6_rfc3542(php_sock, level, optname, arg4); } - HANDLE_SUBCALL(res); - } #endif + if (res == 1) { + goto default_case; + } + RETURN_BOOL(res == SUCCESS); + } if (level == IPPROTO_TCP) { switch (optname) {