Skip to content

Commit 7935650

Browse files
committed
sockets add SO_MEMINFO data gathering which allows to check
socket memory consumption and returning those in php friendly map.
1 parent 7061c40 commit 7935650

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

ext/sockets/sockets.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@
5555
# if HAVE_IF_NAMETOINDEX
5656
# include <net/if.h>
5757
# endif
58+
# ifdef SO_MEMINFO
59+
# include <linux/sock_diag.h>
60+
# endif
5861
#endif
5962

6063
#include <stddef.h>
@@ -550,6 +553,9 @@ static PHP_MINIT_FUNCTION(sockets)
550553
#ifdef SO_INCOMING_CPU
551554
REGISTER_LONG_CONSTANT("SO_INCOMING_CPU", SO_INCOMING_CPU, CONST_CS | CONST_PERSISTENT);
552555
#endif
556+
#ifdef SO_MEMINFO
557+
REGISTER_LONG_CONSTANT("SO_MEMINFO", SO_MEMINFO, CONST_CS | CONST_PERSISTENT);
558+
#endif
553559
#ifdef TCP_NODELAY
554560
REGISTER_LONG_CONSTANT("TCP_NODELAY", TCP_NODELAY, CONST_CS | CONST_PERSISTENT);
555561
#endif
@@ -1833,6 +1839,37 @@ PHP_FUNCTION(socket_get_option)
18331839
add_assoc_long(return_value, "sec", tv.tv_sec);
18341840
add_assoc_long(return_value, "usec", tv.tv_usec);
18351841
return;
1842+
#ifdef SO_MEMINFO
1843+
case SO_MEMINFO: {
1844+
uint32_t minfo[SK_MEMINFO_VARS];
1845+
optlen = sizeof(minfo);
1846+
1847+
if (getsockopt(php_sock->bsd_socket, level, optname, (char*)minfo, &optlen) != 0) {
1848+
PHP_SOCKET_ERROR(php_sock, "Unable to retrieve socket option", errno);
1849+
RETURN_FALSE;
1850+
}
1851+
1852+
if (UNEXPECTED(optlen != sizeof(minfo))) {
1853+
// unlikely since the kernel fills up the whole array if getsockopt succeeded
1854+
// but just an extra precaution in case.
1855+
php_error_docref(NULL, E_WARNING, "Unable to retrieve all socket meminfo data");
1856+
RETURN_FALSE;
1857+
}
1858+
1859+
array_init(return_value);
1860+
1861+
add_assoc_long(return_value, "rmem_alloc", minfo[SK_MEMINFO_RMEM_ALLOC]);
1862+
add_assoc_long(return_value, "rcvbuf", minfo[SK_MEMINFO_RCVBUF]);
1863+
add_assoc_long(return_value, "wmem_alloc", minfo[SK_MEMINFO_WMEM_ALLOC]);
1864+
add_assoc_long(return_value, "sndbuf", minfo[SK_MEMINFO_SNDBUF]);
1865+
add_assoc_long(return_value, "fwd_alloc", minfo[SK_MEMINFO_FWD_ALLOC]);
1866+
add_assoc_long(return_value, "wmem_queued", minfo[SK_MEMINFO_WMEM_QUEUED]);
1867+
add_assoc_long(return_value, "optmem", minfo[SK_MEMINFO_OPTMEM]);
1868+
add_assoc_long(return_value, "backlog", minfo[SK_MEMINFO_BACKLOG]);
1869+
add_assoc_long(return_value, "drops", minfo[SK_MEMINFO_DROPS]);
1870+
return;
1871+
}
1872+
#endif
18361873
#ifdef SO_ACCEPTFILTER
18371874
case SO_ACCEPTFILTER: {
18381875

ext/sockets/tests/socket_meminfo.phpt

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
--TEST--
2+
socket_get_option MEMINFO;
3+
--EXTENSIONS--
4+
sockets
5+
--SKIPIF--
6+
<?php
7+
if (getenv("SKIP_ONLINE_TESTS")) die("skip online test");
8+
if (!defined("SO_MEMINFO")) die('skip SO_MEMINFO test');
9+
?>
10+
--FILE--
11+
<?php
12+
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
13+
if (!$server) {
14+
die('Unable to create AF_INET socket [server]');
15+
}
16+
17+
if (!socket_bind($server, '127.0.0.1', 0)) {
18+
die("Unable to bind to 127.0.0.1");
19+
}
20+
21+
if (!socket_listen($server, 2)) {
22+
die('Unable to listen on socket');
23+
}
24+
25+
socket_getsockname($server, $unused, $port);
26+
27+
/* Connect to it */
28+
$client = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
29+
if (!$client) {
30+
die('Unable to create AF_INET socket [client]');
31+
}
32+
if (!socket_connect($client, '127.0.0.1', $port)) {
33+
die('Unable to connect to server socket');
34+
}
35+
36+
/* Accept that connection */
37+
$socket = socket_accept($server);
38+
if (!$socket) {
39+
die('Unable to accept connection');
40+
}
41+
42+
socket_write($client, "SO_MEMINFO\n");
43+
44+
socket_read($socket, strlen("SO_MEMINFO"), PHP_BINARY_READ);
45+
$data = socket_get_option($socket, SOL_SOCKET, SO_MEMINFO);
46+
var_dump($data);
47+
48+
socket_close($client);
49+
socket_close($socket);
50+
socket_close($server);
51+
?>
52+
--EXPECTF--
53+
array(9) {
54+
["rmem_alloc"]=>
55+
int(%d)
56+
["rcvbuf"]=>
57+
int(%d)
58+
["wmem_alloc"]=>
59+
int(%d)
60+
["sndbuf"]=>
61+
int(%d)
62+
["fwd_alloc"]=>
63+
int(%d)
64+
["wmem_queued"]=>
65+
int(%d)
66+
["optmem"]=>
67+
int(%d)
68+
["backlog"]=>
69+
int(%d)
70+
["drops"]=>
71+
int(%d)
72+
}

0 commit comments

Comments
 (0)