diff --git a/NEWS b/NEWS index e3c32a4e1648b..7e9381866da56 100644 --- a/NEWS +++ b/NEWS @@ -56,6 +56,10 @@ PHP NEWS . Soap::__setCookie() when cookie name is a digit is now not stored and represented as a string anymore but a int. (David Carlier) +- Sockets: + . Added the TCP_USER_TIMEOUT constant for Linux to set the maximum time in milliseconds + transmitted data can remain unacknowledged. (James Lucas) + - SPL: . DirectoryIterator key can now work better with filesystem supporting larger directory indexing. (David Carlier) diff --git a/UPGRADING b/UPGRADING index 4e511d094797e..b83312b6ade7d 100644 --- a/UPGRADING +++ b/UPGRADING @@ -90,6 +90,9 @@ PHP 8.6 UPGRADE NOTES 10. New Global Constants ======================================== +- Sockets: + . TCP_USER_TIMEOUT (Linux only). + ======================================== 11. Changes to INI File Handling ======================================== diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 4a9332498c3cc..109b5e35ad604 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -1773,7 +1773,7 @@ PHP_FUNCTION(socket_sendto) RETURN_THROWS(); } - memset(&sll, 0, sizeof(sll)); + memset(&sll, 0, sizeof(sll)); sll.sll_family = AF_PACKET; sll.sll_ifindex = port; @@ -2329,6 +2329,22 @@ PHP_FUNCTION(socket_set_option) } #endif +#if defined(TCP_USER_TIMEOUT) + case TCP_USER_TIMEOUT: { + ov = zval_get_long(arg4); + + // TCP_USER_TIMEOUT unsigned int + if (ov < 0 || ov > UINT_MAX) { + zend_argument_value_error(4, "must be of between 0 and %u", UINT_MAX); + RETURN_THROWS(); + } + + optlen = sizeof(ov); + opt_ptr = &ov; + break; + } +#endif + #if defined(UDP_SEGMENT) case UDP_SEGMENT: { ov = zval_get_long(arg4); diff --git a/ext/sockets/sockets.stub.php b/ext/sockets/sockets.stub.php index 3df9b598a1e8f..04fb702807e0a 100644 --- a/ext/sockets/sockets.stub.php +++ b/ext/sockets/sockets.stub.php @@ -602,6 +602,13 @@ */ const TCP_SYNCNT = UNKNOWN; #endif +#ifdef TCP_USER_TIMEOUT +/** + * @var int + * @cvalue TCP_USER_TIMEOUT + */ +const TCP_USER_TIMEOUT = UNKNOWN; +#endif #ifdef SO_ZEROCOPY /** * @var int diff --git a/ext/sockets/sockets_arginfo.h b/ext/sockets/sockets_arginfo.h index edfc344ff8cc0..0145d01252881 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: f754368e28f6e45bf3a63a403e49f5659c29d2c6 */ + * Stub hash: 038081ca7bb98076d4b559d93b4c9300acc47160 */ 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) @@ -527,6 +527,9 @@ static void register_sockets_symbols(int module_number) #if defined(TCP_SYNCNT) REGISTER_LONG_CONSTANT("TCP_SYNCNT", TCP_SYNCNT, CONST_PERSISTENT); #endif +#if defined(TCP_USER_TIMEOUT) + REGISTER_LONG_CONSTANT("TCP_USER_TIMEOUT", TCP_USER_TIMEOUT, CONST_PERSISTENT); +#endif #if defined(SO_ZEROCOPY) REGISTER_LONG_CONSTANT("SO_ZEROCOPY", SO_ZEROCOPY, CONST_PERSISTENT); #endif diff --git a/ext/sockets/tests/socket_setoption_tcpusertimeout.phpt b/ext/sockets/tests/socket_setoption_tcpusertimeout.phpt new file mode 100644 index 0000000000000..2cd2b4d28ff22 --- /dev/null +++ b/ext/sockets/tests/socket_setoption_tcpusertimeout.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test if socket_set_option() works, option:TCP_USER_TIMEOUT +--EXTENSIONS-- +sockets +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} + +$timeout = 200; +$retval_2 = socket_set_option($socket, SOL_TCP, TCP_USER_TIMEOUT, $timeout); +$retval_3 = socket_get_option($socket, SOL_TCP, TCP_USER_TIMEOUT); +var_dump($retval_2); +var_dump($retval_3 === $timeout); +socket_close($socket); +?> +--EXPECTF-- +socket_setopt(): Argument #4 ($value) must be of between 0 and %d +bool(true) +bool(true)