mirror of
https://github.com/php/php-src.git
synced 2024-11-26 19:33:55 +08:00
ext/sockets: Adding TCP_FUNCTION_BLK socket option for FreeBSD.
Allows to select an alternate TCP stack. For example with RACK, a fast loss detection relying on timestamp per packet. While it works system-wide, it can also apply in an individual socket level too. close GH-16842
This commit is contained in:
parent
f44eaac48a
commit
ccda20b8d1
2
NEWS
2
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
5
ext/sockets/sockets_arginfo.h
generated
5
ext/sockets/sockets_arginfo.h
generated
@ -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);
|
||||
|
33
ext/sockets/tests/socket_set_option_tsf.phpt
Normal file
33
ext/sockets/tests/socket_set_option_tsf.phpt
Normal file
@ -0,0 +1,33 @@
|
||||
--TEST--
|
||||
Test if socket_set_option() works, option:TCP_FUNCTION_BLK
|
||||
--EXTENSIONS--
|
||||
sockets
|
||||
--SKIPIF--
|
||||
<?php
|
||||
|
||||
if (!defined("TCP_FUNCTION_BLK")) {
|
||||
die('SKIP on platforms not supporting TCP_FUNCTION_BLK');
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||
|
||||
if (!$socket) {
|
||||
die('Unable to create AF_INET socket [socket]');
|
||||
}
|
||||
socket_set_option( $socket, SOL_TCP, TCP_FUNCTION_BLK, "nochancetoexist");
|
||||
// TCP/RACK and other alternate stacks are not present by default, at least `freebsd` is.
|
||||
var_dump(socket_set_option( $socket, SOL_TCP, TCP_FUNCTION_BLK, "freebsd"));
|
||||
var_dump(socket_get_option( $socket, SOL_TCP, TCP_FUNCTION_BLK));
|
||||
socket_close($socket);
|
||||
?>
|
||||
--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)
|
||||
}
|
Loading…
Reference in New Issue
Block a user