mirror of
https://github.com/Cacti/rrdproxy.git
synced 2026-10-30 08:37:05 +09:00
469 lines
22 KiB
PHP
469 lines
22 KiB
PHP
<?php
|
|
/*
|
|
+-------------------------------------------------------------------------+
|
|
| Copyright (C) 2004-2020 The Cacti Group |
|
|
| |
|
|
| This program is free software; you can redistribute it and/or |
|
|
| modify it under the terms of the GNU General Public License |
|
|
| as published by the Free Software Foundation; either version 2 |
|
|
| of the License, or (at your option) any later version. |
|
|
| |
|
|
| This program is distributed in the hope that it will be useful, |
|
|
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
|
| GNU General Public License for more details. |
|
|
+-------------------------------------------------------------------------+
|
|
| Cacti: The Complete RRDTool-based Graphing Solution |
|
|
+-------------------------------------------------------------------------+
|
|
| This code is designed, written, and maintained by the Cacti Group. See |
|
|
| about.php and/or the AUTHORS file for specific developer information. |
|
|
+-------------------------------------------------------------------------+
|
|
| http://www.cacti.net/ |
|
|
+-------------------------------------------------------------------------+
|
|
*/
|
|
|
|
use phpseclib\Crypt\RSA;
|
|
|
|
function interact($socket_client) {
|
|
/*
|
|
Clients using the default port are only allowed to talk to RRDtool directly.
|
|
By using IPC this child process will interact with the main process.
|
|
*/
|
|
global $rrdcached_pid, $rrdp_config, $ipc_socket_parent, $rrdtool_cmds, $rrdtool_custom_cmds;
|
|
global $rrdtool_msr_cmds, $rrdp_status, $rrdtool_env_vars, $rrdp_client_cnn_params;
|
|
global $encryption;
|
|
|
|
if ($rrdcached_pid) {
|
|
putenv('RRDCACHED_ADDRESS=unix:' . realpath('') . '/run/rrdcached.sock');
|
|
}
|
|
|
|
/* switch into the rra directory */
|
|
chdir($rrdp_config['path_rra']);
|
|
|
|
set_time_limit(0);
|
|
|
|
$encryption = true;
|
|
$rrdp_status_backup = $rrdp_status;
|
|
$rrdtool_process = false;
|
|
$client_authenticated = false;
|
|
$end_of_packet = "_EOP_\r\n";
|
|
$end_of_sequence = "_EOT_\r\n";
|
|
|
|
$tv_sec = $rrdp_config['remote_cnn_timeout'];
|
|
|
|
/* avoid zombies */
|
|
socket_set_option($socket_client,SOL_SOCKET, SO_RCVTIMEO, array("sec"=>600, "usec"=>0));
|
|
socket_set_block ($socket_client);
|
|
socket_set_block ($ipc_socket_parent);
|
|
|
|
$real_client_resource_id = rrdp_system__get_resource_id($socket_client);
|
|
$ipc_parent_resource_id = rrdp_system__get_resource_id($ipc_socket_parent);
|
|
|
|
/* enable message encryption */
|
|
$rsa = new RSA();
|
|
|
|
$input = '';
|
|
|
|
while(1) {
|
|
/* setup clients listening to socket for reading */
|
|
$read = array();
|
|
$read[0] = $socket_client;
|
|
$read[1] = $ipc_socket_parent;
|
|
|
|
$ready = socket_select($read, $write, $except, $tv_sec);
|
|
|
|
switch ($err = socket_last_error( )) {
|
|
case 0:
|
|
socket_clear_error();
|
|
|
|
break;
|
|
default:
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'Critical error occurred: ' . $err, 'IPC', SEVERITY_LEVEL_CRITICAL);
|
|
|
|
break 2;
|
|
}
|
|
|
|
if ($ready > 0) {
|
|
foreach($read as $read_socket_index => $read_socket) {
|
|
$socket_resource_id = rrdp_system__get_resource_id($read_socket);
|
|
|
|
if ($socket_resource_id == $real_client_resource_id) {
|
|
/* RRDtool client is talking to us */
|
|
|
|
while(1) {
|
|
$recv = @socket_read($read_socket, 100000, PHP_BINARY_READ );
|
|
|
|
if ($recv === false) {
|
|
/* timeout */
|
|
rrdp_system__socket_write($socket_client, ( ($client_authenticated) ? encrypt(RRD_ERROR . "Timeout", $client_public_key) : RRD_ERROR . "Timeout") . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'Client connection timeout detected', 'IPC', SEVERITY_LEVEL_WARNING);
|
|
$rrdp_status['status'] = 'CLOSEDOWN_BY_TIMEOUT';
|
|
|
|
break 3;
|
|
} elseif ($recv === '') {
|
|
/* socket session dropped by client */
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'Connection dropped by client', 'IPC', SEVERITY_LEVEL_NOTIFICATION);
|
|
$rrdp_status['status'] = 'CLOSEDOWN_BY_CLIENT_DROP';
|
|
|
|
break 3;
|
|
} else {
|
|
$input .= $recv;
|
|
if (strpos($input, $end_of_sequence) !== false ) { //end of one or more transactions detected
|
|
rrdp_system__count('bytes_received', rrdp_system__calc_bytes($input));
|
|
|
|
$transactions = explode($end_of_sequence, $input);
|
|
$input = array_pop($transactions);
|
|
|
|
foreach($transactions as $transaction) {
|
|
if ( !$client_authenticated ) {
|
|
if (strpos($transaction, '-----BEGIN PUBLIC KEY-----') === false) {
|
|
/* authentication failed !!! */
|
|
rrdp_system__socket_write($socket_client, "Authentication failed" . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'Client Authentication failed by invalid key format', 'IPC', SEVERITY_LEVEL_ERROR);
|
|
$rrdp_status['status'] = 'CLOSEDOWN_BY_CLIENT_AUTH';
|
|
|
|
break 4;
|
|
} else {
|
|
$client_public_key = $transaction;
|
|
socket_getpeername($socket_client, $ip);
|
|
$rsa_finger_print = isset($rrdp_config['remote_clients'][$ip]) ? $rrdp_config['remote_clients'][$ip] : 'unknown';
|
|
$rsa->loadKey($client_public_key);
|
|
|
|
if ($rsa_finger_print == $rsa->getPublicKeyFingerprint()) {
|
|
/* registered public key has been received */
|
|
$client_authenticated = true;
|
|
/* send out proxy's public key */
|
|
rrdp_system__socket_write($socket_client, $rrdp_config['encryption']['public_key'] . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'Client Authentication successful', 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
continue;
|
|
} else {
|
|
/* authentication failed !!! */
|
|
rrdp_system__socket_write($socket_client, "Authentication failed" . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'Client Authentication failed by invalid public key', 'IPC', SEVERITY_LEVEL_ERROR);
|
|
$rrdp_status['status'] = 'CLOSEDOWN_BY_CLIENT_AUTH';
|
|
|
|
break 4;
|
|
}
|
|
}
|
|
} else {
|
|
$transaction = decrypt($transaction);
|
|
|
|
if ($transaction === false) {
|
|
rrdp_system__socket_write($socket_client, "Decryption error" . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'Client message decryption failed.', 'IPC', SEVERITY_LEVEL_ERROR);
|
|
$rrdp_status['status'] = 'CLOSEDOWN_BY_DECRYPTION';
|
|
|
|
break 4;
|
|
}
|
|
|
|
if (strpos($transaction, "\x1f\x8b") === 0) {
|
|
$transaction = gzdecode($transaction);
|
|
}
|
|
|
|
/* take care of invalid blanks */
|
|
$transaction = trim($transaction);
|
|
|
|
if (strpos($transaction, ' ') != false) {
|
|
$options = explode(' ', $transaction, 2);
|
|
$cmd = $options[0];
|
|
$cmd_options = $options[1];
|
|
} else {
|
|
$cmd = $transaction;
|
|
$cmd_options = '';
|
|
}
|
|
|
|
/* try to react as similar as possible */
|
|
if (!$cmd) {
|
|
$cmd = 'info';
|
|
}
|
|
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'REQUEST: ' . $cmd . ' ' . $cmd_options , 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
|
|
if ( in_array($cmd, $rrdtool_cmds) === true ) {
|
|
rrdp_system__count('queries_rrdtool_total');
|
|
|
|
/* open a persistent RRDtool pipe only on demand */
|
|
if ($rrdtool_process === false) {
|
|
$rrdtool_process_pipes = rrdtool_pipe_init($rrdp_config);
|
|
$rrdtool_process = $rrdtool_process_pipes[0];
|
|
$rrdtool_pipes = $rrdtool_process_pipes[1];
|
|
}
|
|
|
|
$auto_compression = in_array($cmd, array('xport', 'fetch', 'dump', 'graph', 'graphv', 'updatev ', 'info')) && strpos($cmd_options, '--imgformat=PNG') === false;
|
|
$rrd_exec_status = rrdtool_pipe_execute($cmd . ' ' . $cmd_options . "\r\n", $rrdtool_pipes, $socket_client, $client_public_key, $auto_compression, false, $end_of_sequence);
|
|
|
|
if ($rrd_exec_status === true) {
|
|
rrdp_system__count('queries_rrdtool_valid');
|
|
|
|
/* update local cache by valid RRDtool commands for MSR */
|
|
if (__sizeof($rrdp_config['remote_proxies'])>0 && in_array($cmd , $rrdtool_msr_cmds) === true) {
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'MSR: ' . $cmd . ' ' . $cmd_options , 'MSR', SEVERITY_LEVEL_DEBUG);
|
|
list($mtime,$time) = explode(' ',microtime());
|
|
$offset = $time %10;
|
|
$block = $time - $offset + 10;
|
|
$rrdp_status['msr_commands'][$block][$offset+$mtime . '_' . $socket_resource_id] = $cmd . ' ' . $cmd_options;
|
|
if (__sizeof($rrdp_status['msr_commands'])>1 | $time >= $block) {
|
|
$msr_block = key($rrdp_status['msr_commands']);
|
|
$msr_message['type'] = 'msr';
|
|
$msr_message['msr_commands'][$msr_block] = $rrdp_status['msr_commands'][$msr_block];
|
|
|
|
if (@socket_write( $ipc_socket_parent, serialize($msr_message) . "\r\n")) {
|
|
unset($rrdp_status['msr_commands'][$msr_block]);
|
|
unset($msr_message);
|
|
$rrdp_status = $rrdp_status_backup;
|
|
usleep(10000);
|
|
}
|
|
}
|
|
}
|
|
} elseif ( $rrd_exec_status === null ) {
|
|
/* RRDtool pipe broken */
|
|
rrdp_system__count('rrd_pipe_broken');
|
|
rrdp_system__socket_write($socket_client, encrypt(RRD_ERROR . "RRDTOOL_PIPE_BROKEN", $client_public_key) . $end_of_sequence);
|
|
rrdtool_pipe_close($rrdtool_process);
|
|
$rrdtool_process = false;
|
|
} else {
|
|
/* client tried to execute an invalid or unsupported RRDtool command */
|
|
rrdp_system__count('queries_rrdtool_invalid');
|
|
}
|
|
} elseif ( in_array($cmd, array('exit', 'quit', 'shutdown')) === true ) {
|
|
/* client wants to quit on a regular basis */
|
|
$rrdp_status['status'] = 'CLOSEDOWN_BY_CLIENT_CMD';
|
|
|
|
break 4;
|
|
} elseif (in_array($cmd, $rrdtool_custom_cmds)) {
|
|
$rrdp_exec_status = false;
|
|
$options = explode(' ', $cmd_options);
|
|
|
|
switch ($cmd) {
|
|
case 'setenv':
|
|
if (__sizeof($options) >= 2 && in_array($options[0], $rrdtool_env_vars)) {
|
|
$enviro_var = array_shift($options);
|
|
putenv("'". $enviro_var. "'='" . str_replace("'", '', implode(' ', $options)) . "'");
|
|
rrdp_system__socket_write($socket_client, encrypt(RRD_OK, $client_public_key) . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . RRD_OK, 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
} else {
|
|
rrdp_system__socket_write($socket_client, encrypt(RRD_ERROR . ' % setenv <name> <value>', $client_public_key) . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . RRD_ERROR, 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
}
|
|
|
|
break;
|
|
case 'getenv':
|
|
if (__sizeof($options)== 1 && in_array($options[0], $rrdtool_env_vars)) {
|
|
$output = getenv($options[0]);
|
|
rrdp_system__socket_write($socket_client, encrypt($output . "\n" . RRD_OK, $client_public_key) . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . $output . "\n" . RRD_OK, 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
} else {
|
|
rrdp_system__socket_write($socket_client, encrypt(RRD_ERROR . ' % getenv <name>', $client_public_key) . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . RRD_ERROR, 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
}
|
|
|
|
break;
|
|
case 'setcnn':
|
|
if (__sizeof($options) == 2 && in_array($options[0], $rrdp_client_cnn_params)) {
|
|
if ($options[0] == 'timeout') {
|
|
if ( in_array($options[1], array('null', 'off', 'disabled', '-1')) ) {
|
|
$tv_sec = null;
|
|
rrdp_system__socket_write($socket_client, encrypt("% Timeout disabled.\n" . RRD_OK, $client_public_key) . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . RRD_OK, 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
} elseif (is_numeric($options[1])) {
|
|
$tv_sec = abs($options[1]);
|
|
rrdp_system__socket_write($socket_client, encrypt("% Timeout " . $tv_sec. "s.\n" . RRD_OK, $client_public_key) . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . RRD_OK, 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
} else {
|
|
rrdp_system__socket_write($socket_client, encrypt(RRD_ERROR . ' % Out of range.', $client_public_key) . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . RRD_ERROR, 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
}
|
|
} elseif ($options[0] == 'encryption') {
|
|
if ( in_array($options[1], array('null', 'off', 'disabled', '-1')) ) {
|
|
rrdp_system__socket_write($socket_client, encrypt("% Encryption will be disabled.\n" . RRD_OK, $client_public_key) . $end_of_sequence);
|
|
$encryption = false;
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . RRD_OK, 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
} elseif ( in_array($options[1], array('true', 'on', 'enabled', '1')) ) {
|
|
rrdp_system__socket_write($socket_client, encrypt("% Encryption will be enabled.\n" . RRD_OK, $client_public_key) . $end_of_sequence);
|
|
$encryption = true;
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . RRD_OK, 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
} else {
|
|
rrdp_system__socket_write($socket_client, encrypt(RRD_ERROR . ' % Out of range.', $client_public_key) . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . RRD_ERROR, 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
}
|
|
}
|
|
} else {
|
|
rrdp_system__socket_write($socket_client, encrypt(RRD_ERROR . " % setcnn <parameter> <value>", $client_public_key) . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . RRD_ERROR, 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
}
|
|
|
|
break;
|
|
case 'fc-list':
|
|
$output = shell_exec('fc-list');
|
|
rrdp_system__socket_write($socket_client, encrypt($output . "\n" . RRD_OK, $client_public_key) . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . RRD_OK, 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
|
|
break;
|
|
case 'rrd-list':
|
|
/* scan RRA folder */
|
|
clearstatcache();
|
|
$buffer = '';
|
|
$rra_path_absolute = rtrim($rrdp_config['path_rra'], '/');
|
|
$dir_iterator = new RecursiveDirectoryIterator($rra_path_absolute);
|
|
$iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST);
|
|
|
|
foreach ($iterator as $file) {
|
|
if (substr($file->getPathname(),-3) == 'rrd') {
|
|
$buffer .= str_replace( $rra_path_absolute . '/', '', $file->getPathname()) . ',' . $file->getSize() . ',' . $file->getMTime() . "\r\n";
|
|
}
|
|
}
|
|
|
|
$buffer .= RRD_OK;
|
|
$buffer_length = strlen($buffer);
|
|
$buffer = gzencode($buffer,1);
|
|
$buffer_length_new = strlen($buffer);
|
|
rrdp_system__socket_write( $read_socket, encrypt( $buffer, $client_public_key) . $end_of_sequence );
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . RRD_OK . ', payload: ' . $buffer_length_new . ' Bytes, compression: on , ratio: ' . round(($buffer_length/$buffer_length_new),2) . ' , packets: 1', 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
|
|
break;
|
|
case 'filemtime':
|
|
$rrdp_exec_return = call_user_func_array($cmd, $options);
|
|
rrdp_system__socket_write($socket_client, encrypt( $rrdp_exec_return . "\r\n" . RRD_OK, $client_public_key) . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . $rrdp_exec_return . "\r\n" . RRD_OK, 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
|
|
break;
|
|
case 'file_exists':
|
|
case 'is_dir':
|
|
case 'mkdir':
|
|
$rrdp_exec_status = call_user_func_array($cmd, $options);
|
|
rrdp_system__socket_write($socket_client, encrypt( ($rrdp_exec_status === true) ? RRD_OK : RRD_ERROR , $client_public_key) . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . (($rrdp_exec_status === true) ? RRD_OK : RRD_ERROR), 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
|
|
break;
|
|
case 'archive':
|
|
if (__sizeof($options) == 1 && (substr($options[0],-3) == 'rrd') && file_exists($options[0]) && $rrdp_config['path_rra_archive']) {
|
|
$source_file = $options[0];
|
|
$target_dir = $rrdp_config['path_rra_archive'] . '/' . ltrim(dirname($source_file), './');
|
|
$target_file = $rrdp_config['path_rra_archive'] . '/' . $source_file;
|
|
if (!is_dir($target_dir)) {
|
|
mkdir($target_dir);
|
|
}
|
|
$rrdp_exec_status = rename($source_file, $target_file);
|
|
} else {
|
|
$rrdp_exec_status = false;
|
|
}
|
|
|
|
rrdp_system__socket_write($socket_client, encrypt( (($rrdp_exec_status === true) ? RRD_OK : RRD_ERROR), $client_public_key) . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . (($rrdp_exec_status === true) ? RRD_OK : RRD_ERROR), 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
|
|
break;
|
|
case 'unlink':
|
|
if (__sizeof($options) == 1 && (substr($options[0],-3) == 'rrd') & file_exists($options[0])) {
|
|
$rrdp_exec_status = call_user_func_array($cmd, $options);
|
|
} else {
|
|
$rrdp_exec_status = false;
|
|
}
|
|
|
|
rrdp_system__socket_write($socket_client, encrypt( (($rrdp_exec_status === true) ? RRD_OK : RRD_ERROR), $client_public_key) . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . (($rrdp_exec_status === true) ? RRD_OK : RRD_ERROR), 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
|
|
break;
|
|
case 'removespikes':
|
|
$cmd_options = str_replace('-R=.', '-R=' . $rrdp_config['path_rra'], $cmd_options);
|
|
$rrdp_exec_return = shell_exec( PHP_BINARY . ' -q ' . $rrdp_config['path_cli'] . '/removespikes.php ' . $cmd_options);
|
|
|
|
rrdp_system__socket_write($socket_client, encrypt( $rrdp_exec_return . "\r\n" . RRD_OK, $client_public_key) . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . $rrdp_exec_return . "\r\n" . RRD_OK, 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
|
|
break;
|
|
case 'version':
|
|
rrdp_system__socket_write($socket_client, encrypt( RRDP_VERSION_FULL . "\r\n" . RRD_OK, $client_public_key) . $end_of_sequence);
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'RESPONSE: ' . RRDP_VERSION_FULL . "\r\n" . RRD_OK, 'IPC', SEVERITY_LEVEL_DEBUG);
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/* update local cache for MSR */
|
|
if ($rrdp_exec_status === true ) {
|
|
if ( in_array($cmd , $rrdtool_msr_cmds) === true) {
|
|
list($mtime,$time) = explode(' ',microtime());
|
|
$offset = $time %10;
|
|
$block = $time - $offset + 10;
|
|
$rrdp_status['msr_commands'][$block][$offset+$mtime . '_' . $socket_resource_id] = $cmd . ' ' . $cmd_options;
|
|
if (__sizeof($rrdp_status['msr_commands'])>1 | $time >= $block ) {
|
|
$msr_block = key($rrdp_status['msr_commands']);
|
|
$msr_message['type'] = 'msr';
|
|
$msr_message['msr_commands'][$msr_block] = $rrdp_status['msr_commands'][$msr_block];
|
|
if (@socket_write( $ipc_socket_parent, serialize($msr_message) . "\r\n")) {
|
|
unset($rrdp_status['msr_commands'][$msr_block]);
|
|
unset($msr_message);
|
|
$rrdp_status = $rrdp_status_backup;
|
|
usleep(10000);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
/* kick that client if it does not know how to talk to me */
|
|
__logging(LOGGING_LOCATION_BUFFERED, 'Client is using invalid commands.', 'IPC', SEVERITY_LEVEL_ERROR);
|
|
rrdp_system__socket_write($socket_client, encrypt(RRD_ERROR . " % Invalid input detected", $client_public_key) . $end_of_sequence);
|
|
$rrdp_status['status'] = 'CLOSEDOWN_BY_VIOLATION';
|
|
|
|
break 4;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} elseif ($socket_resource_id == $ipc_parent_resource_id) {
|
|
/* RRDtool proxy is talking to us */
|
|
|
|
while(1) {
|
|
$recv = @socket_read($ipc_socket_parent, 8192, PHP_BINARY_READ );
|
|
|
|
if ($recv === false) {
|
|
/* timeout */
|
|
break;
|
|
} elseif ($recv == '') {
|
|
/* socket session dropped by proxy */
|
|
break;
|
|
} else {
|
|
$input .= $recv;
|
|
|
|
if (substr($input, -1) == "\n") {
|
|
rrdp_system__count('bytes_received', rrdp_system__calc_bytes($input));
|
|
|
|
$status = unserialize(trim($input));
|
|
|
|
if ($status !== false && $status['type']) {
|
|
switch($status['type']) {
|
|
case 'shutdown':
|
|
rrdp_system__socket_write($socket_client, ( ($client_authenticated) ? encrypt(RRD_ERROR . "Shutting down ...", $client_public_key) : RRD_ERROR . "Shutting down ...") . $end_of_sequence);
|
|
socket_close($ipc_socket_parent);
|
|
exit;
|
|
case 'status':
|
|
socket_write( $ipc_socket_parent, "running\r\n");
|
|
break 4;
|
|
default:
|
|
break 3;
|
|
}
|
|
}
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
rrdp_system__socket_write($socket_client, "Timeout" . $end_of_sequence);
|
|
$rrdp_status['status'] = 'CLOSEDOWN_BY_TIMEOUT';
|
|
break 1;
|
|
}
|
|
}
|
|
|
|
if ($rrdtool_process) {
|
|
rrdtool_pipe_close($rrdtool_process);
|
|
}
|
|
|
|
}
|
|
|