diff --git a/NEWS b/NEWS index d2b21046b1c..2548403b775 100644 --- a/NEWS +++ b/NEWS @@ -52,6 +52,8 @@ PHP NEWS - Sockets: . Added IPPROTO_ICMP/IPPROTO_ICMPV6 to create raw socket for ICMP usage. (David Carlier) + . Added TCP_FUNCTION_BLK to change the TCP stack algorithm on FreeBSD. + (David Carlier) - Standard: . Fixed crypt() tests on musl when using --with-external-libcrypt diff --git a/UPGRADING b/UPGRADING index 0106d41269b..f379c46cb59 100644 --- a/UPGRADING +++ b/UPGRADING @@ -137,6 +137,7 @@ PHP 8.5 UPGRADE NOTES - Sockets: . IPPROTO_ICMP/IPPROTO_ICMPV6. + . TCP_FUNCTION_BLK (FreeBSD only). ======================================== 11. Changes to INI File Handling diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 48221479a79..08b8d8406da 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -1703,6 +1703,25 @@ PHP_FUNCTION(socket_get_option) } } #endif + +#ifdef TCP_FUNCTION_BLK + case TCP_FUNCTION_BLK: { + + struct tcp_function_set tsf = {0}; + optlen = sizeof(tsf); + + if (getsockopt(php_sock->bsd_socket, level, optname, &tsf, &optlen) != 0) { + PHP_SOCKET_ERROR(php_sock, "Unable to retrieve socket option", errno); + RETURN_FALSE; + } + + array_init(return_value); + + add_assoc_string(return_value, "function_set_name", tsf.function_set_name); + add_assoc_long(return_value, "pcbcnt", tsf.pcbcnt); + return; + } +#endif } } @@ -1915,6 +1934,27 @@ PHP_FUNCTION(socket_set_option) RETURN_TRUE; } #endif + +#ifdef TCP_FUNCTION_BLK + case TCP_FUNCTION_BLK: { + if (Z_TYPE_P(arg4) != IS_STRING) { + php_error_docref(NULL, E_WARNING, "Invalid tcp stack name argument type"); + RETURN_FALSE; + } + struct tcp_function_set tfs = {0}; + strlcpy(tfs.function_set_name, Z_STRVAL_P(arg4), TCP_FUNCTION_NAME_LEN_MAX); + + optlen = sizeof(tfs); + opt_ptr = &tfs; + if (setsockopt(php_sock->bsd_socket, level, optname, opt_ptr, optlen) != 0) { + PHP_SOCKET_ERROR(php_sock, "Unable to set socket option", errno); + RETURN_FALSE; + } + + RETURN_TRUE; + } +#endif + } } diff --git a/ext/sockets/sockets.stub.php b/ext/sockets/sockets.stub.php index b55d36429b4..77efa04b99b 100644 --- a/ext/sockets/sockets.stub.php +++ b/ext/sockets/sockets.stub.php @@ -640,6 +640,13 @@ const TCP_KEEPINTVL = UNKNOWN; */ const TCP_KEEPCNT = UNKNOWN; #endif +#ifdef TCP_FUNCTION_BLK +/** + * @var int + * @cvalue TCP_FUNCTION_BLK + */ +const TCP_FUNCTION_BLK = UNKNOWN; +#endif /** * @var int * @cvalue PHP_NORMAL_READ diff --git a/ext/sockets/sockets_arginfo.h b/ext/sockets/sockets_arginfo.h index abb6e087217..af247a17df1 100644 --- a/ext/sockets/sockets_arginfo.h +++ b/ext/sockets/sockets_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 4fdd210a2de6f3b5df10caf5ac7fefa6aa71926c */ + * Stub hash: 341bf3dfc486ca410cf1e15e1e22b0c60734277b */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_select, 0, 4, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(1, read, IS_ARRAY, 1) @@ -556,6 +556,9 @@ static void register_sockets_symbols(int module_number) #endif #if defined(TCP_KEEPIDLE) REGISTER_LONG_CONSTANT("TCP_KEEPCNT", TCP_KEEPCNT, CONST_PERSISTENT); +#endif +#if defined(TCP_FUNCTION_BLK) + REGISTER_LONG_CONSTANT("TCP_FUNCTION_BLK", TCP_FUNCTION_BLK, CONST_PERSISTENT); #endif REGISTER_LONG_CONSTANT("PHP_NORMAL_READ", PHP_NORMAL_READ, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PHP_BINARY_READ", PHP_BINARY_READ, CONST_PERSISTENT); diff --git a/ext/sockets/tests/socket_set_option_tsf.phpt b/ext/sockets/tests/socket_set_option_tsf.phpt new file mode 100644 index 00000000000..22745fb385c --- /dev/null +++ b/ext/sockets/tests/socket_set_option_tsf.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test if socket_set_option() works, option:TCP_FUNCTION_BLK +--EXTENSIONS-- +sockets +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: socket_set_option(): Unable to set socket option [2]: No such file or directory in %s on line %d +bool(true) +array(2) { + ["function_set_name"]=> + string(7) "freebsd" + ["pcbcnt"]=> + int(%d) +}