diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 8398e004d0b6c..25f422b3f35bb 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -55,6 +55,9 @@ # if HAVE_IF_NAMETOINDEX # include # endif +# ifdef SO_MEMINFO +# include +# endif #endif #include @@ -550,6 +553,9 @@ static PHP_MINIT_FUNCTION(sockets) #ifdef SO_INCOMING_CPU REGISTER_LONG_CONSTANT("SO_INCOMING_CPU", SO_INCOMING_CPU, CONST_CS | CONST_PERSISTENT); #endif +#ifdef SO_MEMINFO + REGISTER_LONG_CONSTANT("SO_MEMINFO", SO_MEMINFO, CONST_CS | CONST_PERSISTENT); +#endif #ifdef TCP_NODELAY REGISTER_LONG_CONSTANT("TCP_NODELAY", TCP_NODELAY, CONST_CS | CONST_PERSISTENT); #endif @@ -1833,6 +1839,37 @@ PHP_FUNCTION(socket_get_option) add_assoc_long(return_value, "sec", tv.tv_sec); add_assoc_long(return_value, "usec", tv.tv_usec); return; +#ifdef SO_MEMINFO + case SO_MEMINFO: { + uint32_t minfo[SK_MEMINFO_VARS]; + optlen = sizeof(minfo); + + if (getsockopt(php_sock->bsd_socket, level, optname, (char*)minfo, &optlen) != 0) { + PHP_SOCKET_ERROR(php_sock, "Unable to retrieve socket option", errno); + RETURN_FALSE; + } + + if (UNEXPECTED(optlen != sizeof(minfo))) { + // unlikely since the kernel fills up the whole array if getsockopt succeeded + // but just an extra precaution in case. + php_error_docref(NULL, E_WARNING, "Unable to retrieve all socket meminfo data"); + RETURN_FALSE; + } + + array_init(return_value); + + add_assoc_long(return_value, "rmem_alloc", minfo[SK_MEMINFO_RMEM_ALLOC]); + add_assoc_long(return_value, "rcvbuf", minfo[SK_MEMINFO_RCVBUF]); + add_assoc_long(return_value, "wmem_alloc", minfo[SK_MEMINFO_WMEM_ALLOC]); + add_assoc_long(return_value, "sndbuf", minfo[SK_MEMINFO_SNDBUF]); + add_assoc_long(return_value, "fwd_alloc", minfo[SK_MEMINFO_FWD_ALLOC]); + add_assoc_long(return_value, "wmem_queued", minfo[SK_MEMINFO_WMEM_QUEUED]); + add_assoc_long(return_value, "optmem", minfo[SK_MEMINFO_OPTMEM]); + add_assoc_long(return_value, "backlog", minfo[SK_MEMINFO_BACKLOG]); + add_assoc_long(return_value, "drops", minfo[SK_MEMINFO_DROPS]); + return; + } +#endif #ifdef SO_ACCEPTFILTER case SO_ACCEPTFILTER: { diff --git a/ext/sockets/tests/socket_meminfo.phpt b/ext/sockets/tests/socket_meminfo.phpt new file mode 100644 index 0000000000000..924e263cf96cf --- /dev/null +++ b/ext/sockets/tests/socket_meminfo.phpt @@ -0,0 +1,71 @@ +--TEST-- +socket_get_option MEMINFO; +--EXTENSIONS-- +sockets +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +array(9) { + ["rmem_alloc"]=> + int(%d) + ["rcvbuf"]=> + int(%d) + ["wmem_alloc"]=> + int(%d) + ["sndbuf"]=> + int(%d) + ["fwd_alloc"]=> + int(%d) + ["wmem_queued"]=> + int(%d) + ["optmem"]=> + int(%d) + ["backlog"]=> + int(%d) + ["drops"]=> + int(%d) +}