From 69eefb500b9c821715b5d3189368b91cec5744d2 Mon Sep 17 00:00:00 2001 From: Renato Botelho Date: Thu, 10 Dec 2015 18:48:11 -0200 Subject: Ticket #5624: Welcome dpinger! --- src/etc/inc/gwlb.inc | 436 ++++++++++++++++++++++----------------------------- 1 file changed, 185 insertions(+), 251 deletions(-) (limited to 'src/etc/inc/gwlb.inc') diff --git a/src/etc/inc/gwlb.inc b/src/etc/inc/gwlb.inc index 9880cdc..b01d87f 100644 --- a/src/etc/inc/gwlb.inc +++ b/src/etc/inc/gwlb.inc @@ -26,135 +26,136 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - pfSense_BUILDER_BINARIES: /sbin/route /usr/local/sbin/apinger pfSense_MODULE: routing */ require_once("config.inc"); require_once("rrd.inc"); -/* Returns an array of default values used for apinger.conf */ -function return_apinger_defaults() { +/* Returns an array of default values used for dpinger */ +function return_dpinger_defaults() { return array( "latencylow" => "200", "latencyhigh" => "500", "losslow" => "10", "losshigh" => "20", - "interval" => "1", - "down" => "10", - "avg_delay_samples" => "10", - "avg_loss_samples" => "50", - "avg_loss_delay_samples" => "20"); + "interval" => "250", + "loss_interval" => "500", + "time_period" => "25000", + "alert_interval" => "1000"); } -/* - * Creates monitoring configuration file and - * adds appropriate static routes. - */ -function setup_gateways_monitor() { - global $config, $g; +function running_dpinger_processes() { + global $g; - $gateways_arr = return_gateways_array(); - if (!is_array($gateways_arr)) { - log_error("No gateways to monitor. Apinger will not be run."); - killbypid("{$g['varrun_path']}/apinger.pid"); - @unlink("{$g['varrun_path']}/apinger.status"); - return; - } + $pidfiles = glob("{$g['varrun_path']}/dpinger_*.pid"); - $apinger_debug = ""; - if (isset($config['system']['apinger_debug'])) { - $apinger_debug = "debug on"; + $result = array(); + if ($pidfiles === FALSE) { + return $result; } - $apinger_default = return_apinger_defaults(); - $apingerconfig = << $gateway) { + foreach ($gateways_arr as $gwname => $gateway) { /* Do not monitor if such was requested */ if (isset($gateway['monitor_disable'])) { continue; @@ -172,7 +173,7 @@ EOD; continue; } - /* Interface ip is needed since apinger will bind a socket to it. + /* Interface ip is needed since dpinger will bind a socket to it. * However the config GUI should already have checked this and when * PPoE is used the IP address is set to "dynamic". So using is_ipaddrv4 * or is_ipaddrv6 to identify packet type would be wrong, especially as @@ -262,176 +263,111 @@ EOD; } $monitor_ips[] = $gateway['monitor']; - $apingercfg = "target \"{$gateway['monitor']}\" {\n"; - $apingercfg .= " description \"{$name}\"\n"; - $apingercfg .= " srcip \"{$gwifip}\"\n"; - - ## How often the probe should be sent - if (!empty($gateway['interval']) && is_numeric($gateway['interval'])) { - $interval = intval($gateway['interval']); # Restrict to Integer - if ($interval < 1) { - $interval = 1; # Minimum - } - if ($interval != $apinger_default['interval']) { # If not default value - $apingercfg .= " interval " . $interval . "s\n"; - } - } + $gateways_arr[$gwname]['enable_dpinger'] = true; + $gateways_arr[$gwname]['gwifip'] = $gwifip; + } - ## How many replies should be used to compute average delay - ## for controlling "delay" alarms - if (!empty($gateway['avg_delay_samples']) && is_numeric($gateway['avg_delay_samples'])) { - $avg_delay_samples = intval($gateway['avg_delay_samples']); # Restrict to Integer - if ($avg_delay_samples < 1) { - $avg_delay_samples = 1; # Minimum - } - if ($avg_delay_samples != $apinger_default['avg_delay_samples']) { # If not default value - $apingercfg .= " avg_delay_samples " . $avg_delay_samples . "\n"; - } - } + stop_dpinger(); - ## How many probes should be used to compute average loss - if (!empty($gateway['avg_loss_samples']) && is_numeric($gateway['avg_loss_samples'])) { - $avg_loss_samples = intval($gateway['avg_loss_samples']); # Restrict to Integer - if ($avg_loss_samples < 1) { - $avg_loss_samples = 1; # Minimum - } - if ($avg_loss_samples != $apinger_default['avg_loss_samples']) { # If not default value - $apingercfg .= " avg_loss_samples " . $avg_loss_samples . "\n"; - } + /* Start new processes */ + foreach ($gateways_arr as $gateway) { + if (isset($gateway['enable_dpinger'])) { + start_dpinger($gateway); } + } - ## The delay (in samples) after which loss is computed - ## without this delays larger than interval would be treated as loss - if (!empty($gateway['avg_loss_delay_samples']) && is_numeric($gateway['avg_loss_delay_samples'])) { - $avg_loss_delay_samples = intval($gateway['avg_loss_delay_samples']); # Restrict to Integer - if ($avg_loss_delay_samples < 1) { - $avg_loss_delay_samples = 1; # Minimum - } - if ($avg_loss_delay_samples != $apinger_default['avg_loss_delay_samples']) { # If not default value - $apingercfg .= " avg_loss_delay_samples " . $avg_loss_delay_samples . "\n"; - } - } + return 0; +} - $alarms = ""; - $alarmscfg = ""; - $override = false; - if (!empty($gateway['losslow'])) { - $alarmscfg .= "alarm loss \"{$name}loss\" {\n"; - $alarmscfg .= "\tpercent_low {$gateway['losslow']}\n"; - $alarmscfg .= "\tpercent_high {$gateway['losshigh']}\n"; - $alarmscfg .= "}\n"; - $alarms .= "\"{$name}loss\""; - $override = true; - } else { - if ($override == true) { - $alarms .= ","; - } - $alarms .= "\"loss\""; - $override = true; - } - if (!empty($gateway['latencylow'])) { - $alarmscfg .= "alarm delay \"{$name}delay\" {\n"; - $alarmscfg .= "\tdelay_low {$gateway['latencylow']}ms\n"; - $alarmscfg .= "\tdelay_high {$gateway['latencyhigh']}ms\n"; - $alarmscfg .= "}\n"; - if ($override == true) { - $alarms .= ","; - } - $alarms .= "\"{$name}delay\""; - $override = true; - } else { - if ($override == true) { - $alarms .= ","; - } - $alarms .= "\"delay\""; - $override = true; - } - if (!empty($gateway['down'])) { - $alarmscfg .= "alarm down \"{$name}down\" {\n"; - $alarmscfg .= "\ttime {$gateway['down']}s\n"; - $alarmscfg .= "}\n"; - if ($override == true) { - $alarms .= ","; - } - $alarms .= "\"{$name}down\""; - $override = true; - } else { - if ($override == true) { - $alarms .= ","; - } - $alarms .= "\"down\""; - $override = true; - } - if ($override == true) { - $apingercfg .= "\talarms override {$alarms};\n"; - } +function get_dpinger_status($gwname) { + global $g; - if (isset($gateway['force_down'])) { - $apingercfg .= "\tforce_down on\n"; - } + $socket = "{$g['varrun_path']}/dpinger_{$gwname}.sock"; - $apingercfg .= " rrd file \"{$g['vardb_path']}/rrd/{$gateway['name']}-quality.rrd\"\n"; - $apingercfg .= "}\n"; - $apingercfg .= "\n"; + if (!file_exists($socket)) { + log_error("dpinger: status socket {$socket} not found"); + return false; + } - $apingerconfig .= $alarmscfg; - $apingerconfig .= $apingercfg; + $fp = stream_socket_client("unix://{$socket}", $errno, $errstr, 10); + if (!$fp) { + log_error("dpinger: cannot connect to status socket {$socket} - $errstr ($errno)"); + return false; + } - # Create gateway quality RRD with settings more suitable for pfSense graph set, - # since apinger uses default step (300; 5 minutes) and other settings that don't - # match the pfSense gateway quality graph set. - create_gateway_quality_rrd("{$g['vardb_path']}/rrd/{$gateway['name']}-quality.rrd"); + $status = ''; + while (!feof($fp)) { + $status .= fgets($fp, 1024); } - @file_put_contents("{$g['varetc_path']}/apinger.conf", $apingerconfig); - unset($apingerconfig); + fclose($fp); + + $r = array(); + list( + $r['latency_avg'], + $r['latency_stddev'], + $r['loss'], + $r['alarm_on'], + $r['srcip'], + $r['targetip'] + ) = explode(' ', preg_replace('/\n/', '', $status)); - /* Restart apinger process */ - if (isvalidpid("{$g['varrun_path']}/apinger.pid")) { - sigkillbypid("{$g['varrun_path']}/apinger.pid", "HUP"); - } else { - /* start a new apinger process */ - @unlink("{$g['varrun_path']}/apinger.status"); - sleep(1); - mwexec_bg("/usr/local/sbin/apinger -c {$g['varetc_path']}/apinger.conf"); - sleep(1); - sigkillbypid("{$g['varrun_path']}/apinger.pid", "USR1"); + $gateways_arr = return_gateways_array(); + unset($gw); + if (isset($gateways_arr[$gwname])) { + $gw = $gateways_arr[$gwname]; } - return 0; + $r['status'] = "none"; + if (isset($gw) && isset($gw['force_down'])) { + $r['status'] = "force_down"; + } else if ($r['alarm_on'] == 1) { + $r['status'] = "down"; + } else if (isset($gw)) { + if (isset($gw['latencylow']) && + is_numeric($gw['latencylow']) && + ($r['latency_avg'] > $gw['latencylow'])) { + $r['status'] = "delay"; + } else if (isset($gw['losslow']) && + is_numeric($gw['losslow']) && + ($r['loss'] > $gw['losslow'])) { + $r['status'] = "loss"; + } + } + + $r['latency_avg'] = round($r['latency_avg']/1000, 3); + $r['latency_stddev'] = round($r['latency_stddev']/1000, 3); + + return $r; } -/* return the status of the apinger targets as a array */ +/* return the status of the dpinger targets as a array */ function return_gateways_status($byname = false) { global $config, $g; - $apingerstatus = array(); - /* Always get the latest status from apinger */ - if (file_exists("{$g['varrun_path']}/apinger.pid")) { - sigkillbypid("{$g['varrun_path']}/apinger.pid", "USR1"); - } - if (file_exists("{$g['varrun_path']}/apinger.status")) { - $apingerstatus = file("{$g['varrun_path']}/apinger.status"); - } else { - $apingerstatus = array(); - } - + $dpinger_gws = running_dpinger_processes(); $status = array(); - foreach ($apingerstatus as $line) { - $info = explode("|", $line); + + $gateways_arr = return_gateways_array(); + + foreach ($dpinger_gws as $gwname) { + $dpinger_status = get_dpinger_status($gwname); + if ($dpinger_status === false) { + continue; + } + if ($byname == false) { - $target = $info[0]; + $target = $dpinger_status['targetip']; } else { - $target = $info[2]; + $target = $gwname; } $status[$target] = array(); - $status[$target]['monitorip'] = $info[0]; - $status[$target]['srcip'] = $info[1]; - $status[$target]['name'] = $info[2]; - $status[$target]['lastcheck'] = $info[5] ? date('r', $info[5]) : date('r'); - $status[$target]['delay'] = empty($info[6]) ? "0ms" : round($info[6], 1) ."ms" ; - $status[$target]['loss'] = empty($info[7]) ? "0.0%" : round($info[7], 1) . "%"; - $status[$target]['status'] = trim($info[8]); + $status[$target]['monitorip'] = $dpinger_status['targetip']; + $status[$target]['srcip'] = $dpinger_status['srcip']; + $status[$target]['name'] = $gwname; + $status[$target]['delay'] = empty($dpinger_status['latency_avg']) ? "0ms" : $dpinger_status['latency_avg'] ."ms"; + $status[$target]['loss'] = empty($dpinger_status['loss']) ? "0.0%" : round($dpinger_status['loss'], 1) . "%"; + $status[$target]['status'] = $dpinger_status['status']; } /* tack on any gateways that have monitoring disabled @@ -441,7 +377,7 @@ function return_gateways_status($byname = false) { if (!isset($gwitem['monitor_disable'])) { continue; } - if (!is_ipaddr($gwitem['monitorip'])) { + if (!is_ipaddr($gwitem['monitor'])) { $realif = $gwitem['interface']; $tgtip = get_interface_gateway($realif); if (!is_ipaddr($tgtip)) { @@ -449,7 +385,7 @@ function return_gateways_status($byname = false) { } $srcip = find_interface_ip($realif); } else { - $tgtip = $gwitem['monitorip']; + $tgtip = $gwitem['monitor']; $srcip = find_interface_ip($realif); } if ($byname == true) { @@ -462,7 +398,6 @@ function return_gateways_status($byname = false) { if ($target == "none") { $target = $gwitem['name']; $status[$target]['name'] = $gwitem['name']; - $status[$target]['lastcheck'] = date('r'); $status[$target]['delay'] = "0.0ms"; $status[$target]['loss'] = "100.0%"; $status[$target]['status'] = "down"; @@ -470,7 +405,6 @@ function return_gateways_status($byname = false) { $status[$target]['monitorip'] = $tgtip; $status[$target]['srcip'] = $srcip; $status[$target]['name'] = $gwitem['name']; - $status[$target]['lastcheck'] = date('r'); $status[$target]['delay'] = "0.0ms"; $status[$target]['loss'] = "0.0%"; $status[$target]['status'] = "none"; @@ -1249,4 +1183,4 @@ function gateway_is_gwgroup_member($name) { return $members; } -?> \ No newline at end of file +?> -- cgit v1.1