Skip to content

Commit a193427

Browse files
committedJun 30, 2022
Adds TCP_CONGESTION socket option for Linux/FreeBSD.
Closes #8824.
1 parent f26f6d9 commit a193427

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed
 

‎NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ PHP NEWS
77
IP-relative calls and jumps.
88
(Su Tao, Wang Xue, Chen Hu, Lizhen Lizhen, Dmitry)
99

10+
- Sockets:
11+
. Added TCP_CONGESTION socket option. (David Carlier)
12+
1013
- Zip:
1114

1215
. Implement fseek for zip stream when possible with libzip 1.9.1. (Remi)

‎ext/sockets/sockets.c

+45
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,9 @@ static PHP_MINIT_FUNCTION(sockets)
627627
REGISTER_LONG_CONSTANT("SKF_AD_MAX", SKF_AD_MAX, CONST_CS | CONST_PERSISTENT);
628628
#endif
629629

630+
#ifdef TCP_CONGESTION
631+
REGISTER_LONG_CONSTANT("TCP_CONGESTION", TCP_CONGESTION, CONST_CS | CONST_PERSISTENT);
632+
#endif
630633
#ifdef TCP_NODELAY
631634
REGISTER_LONG_CONSTANT("TCP_NODELAY", TCP_NODELAY, CONST_CS | CONST_PERSISTENT);
632635
#endif
@@ -1883,6 +1886,26 @@ PHP_FUNCTION(socket_get_option)
18831886
}
18841887
#endif
18851888

1889+
if (level == IPPROTO_TCP) {
1890+
switch (optname) {
1891+
#ifdef TCP_CONGESTION
1892+
case TCP_CONGESTION: {
1893+
char name[16];
1894+
optlen = sizeof(name);
1895+
if (getsockopt(php_sock->bsd_socket, level, optname, name, &optlen) != 0) {
1896+
PHP_SOCKET_ERROR(php_sock, "Unable to retrieve socket option", errno);
1897+
RETURN_FALSE;
1898+
} else {
1899+
array_init(return_value);
1900+
1901+
add_assoc_string(return_value, "name", name);
1902+
return;
1903+
}
1904+
}
1905+
#endif
1906+
}
1907+
}
1908+
18861909
if (level == SOL_SOCKET) {
18871910
switch (optname) {
18881911
case SO_LINGER:
@@ -2040,6 +2063,28 @@ PHP_FUNCTION(socket_set_option)
20402063
}
20412064
#endif
20422065

2066+
if (level == IPPROTO_TCP) {
2067+
switch (optname) {
2068+
#ifdef TCP_CONGESTION
2069+
case TCP_CONGESTION: {
2070+
if (Z_TYPE_P(arg4) == IS_STRING) {
2071+
opt_ptr = Z_STRVAL_P(arg4);
2072+
optlen = Z_STRLEN_P(arg4);
2073+
} else {
2074+
opt_ptr = "";
2075+
optlen = 0;
2076+
}
2077+
if (setsockopt(php_sock->bsd_socket, level, optname, opt_ptr, optlen) != 0) {
2078+
PHP_SOCKET_ERROR(php_sock, "Unable to set socket option", errno);
2079+
RETURN_FALSE;
2080+
}
2081+
2082+
RETURN_TRUE;
2083+
}
2084+
#endif
2085+
}
2086+
}
2087+
20432088
switch (optname) {
20442089
case SO_LINGER: {
20452090
const char l_onoff_key[] = "l_onoff";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
Test TCP_CONGESTION constant with allowed algos for unprivileged accounts.
3+
--EXTENSIONS--
4+
sockets
5+
--SKIPIF--
6+
<?php
7+
if (!defined('TCP_CONGESTION')) {
8+
die('skip TCP_CONGESTION test');
9+
}
10+
--FILE--
11+
<?php
12+
13+
if (str_contains(PHP_OS, 'Linux')) {
14+
$algo = 'cubic';
15+
} else {
16+
$algo = 'newreno';
17+
}
18+
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
19+
if (!$socket) die ("socket failed");
20+
$r = socket_get_option($socket, SOL_TCP, TCP_CONGESTION);
21+
echo "current tcp congestion algo " . $r['name'] . "\n";
22+
var_dump(socket_set_option($socket, SOL_TCP, TCP_CONGESTION, $algo));
23+
$r = socket_get_option($socket, SOL_TCP, TCP_CONGESTION);
24+
echo "new tcp congestion algo " . $r['name'];
25+
?>
26+
--EXPECTF--
27+
current tcp congestion algo %s
28+
bool(true)
29+
new tcp congestion algo %s

0 commit comments

Comments
 (0)
Please sign in to comment.