summaryrefslogtreecommitdiffstats
path: root/src/etc/inc/gwlb.inc
diff options
context:
space:
mode:
Diffstat (limited to 'src/etc/inc/gwlb.inc')
-rw-r--r--src/etc/inc/gwlb.inc436
1 files changed, 185 insertions, 251 deletions
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 = <<<EOD
-
-# pfSense apinger configuration file. Automatically Generated!
-
-{$apinger_debug}
-
-## User and group the pinger should run as
-user "root"
-group "wheel"
-
-## Mailer to use (default: "/usr/lib/sendmail -t")
-#mailer "/var/qmail/bin/qmail-inject"
-
-## Location of the pid-file (default: "/var/run/apinger.pid")
-pid_file "{$g['varrun_path']}/apinger.pid"
-
-## Format of timestamp (%s macro) (default: "%b %d %H:%M:%S")
-#timestamp_format "%Y%m%d%H%M%S"
+ foreach ($pidfiles as $pidfile) {
+ $result[] = preg_replace('/^dpinger_(\w+)\.pid$/', "$1",
+ basename($pidfile));
+ }
-status {
- ## File where the status information should be written to
- file "{$g['varrun_path']}/apinger.status"
- ## Interval between file updates
- ## when 0 or not set, file is written only when SIGUSR1 is received
- interval 5s
+ return $result;
}
-########################################
-# RRDTool status gathering configuration
-# Interval between RRD updates
-rrd interval 60s;
+/*
+ * Stop one or more dpinger process
+ * default parameter $gwname is '*' that will kill all running sessions
+ * If a gateway name is passed, only this one will be killed
+ */
+function stop_dpinger($gwname = '*') {
+ global $g;
-## These parameters can be overridden in a specific alarm configuration
-alarm default {
- command on "/usr/local/sbin/pfSctl -c 'service reload dyndns %T' -c 'service reload ipsecdns' -c 'service reload openvpn %T' -c 'filter reload' "
- command off "/usr/local/sbin/pfSctl -c 'service reload dyndns %T' -c 'service reload ipsecdns' -c 'service reload openvpn %T' -c 'filter reload' "
- combine 10s
-}
+ $pidfiles = glob("{$g['varrun_path']}/dpinger_{$gwname}.pid");
-## "Down" alarm definition.
-## This alarm will be fired when target doesn't respond for 30 seconds.
-alarm down "down" {
- time {$apinger_default['down']}s
-}
+ if ($pidfiles === FALSE) {
+ return;
+ }
-## "Delay" alarm definition.
-## This alarm will be fired when responses are delayed more than 200ms
-## it will be canceled, when the delay drops below 100ms
-alarm delay "delay" {
- delay_low {$apinger_default['latencylow']}ms
- delay_high {$apinger_default['latencyhigh']}ms
+ foreach ($pidfiles as $pidfile) {
+ if (isvalidpid($pidfile)) {
+ killbypid($pidfile);
+ } else {
+ @unlink($pidfile);
+ }
+ }
}
-## "Loss" alarm definition.
-## This alarm will be fired when packet loss goes over 20%
-## it will be canceled, when the loss drops below 10%
-alarm loss "loss" {
- percent_low {$apinger_default['losslow']}
- percent_high {$apinger_default['losshigh']}
+function start_dpinger($gateway) {
+ global $g;
+
+ $dpinger_defaults = return_dpinger_defaults();
+
+ $pidfile = "{$g['varrun_path']}/dpinger_{$gateway['name']}.pid";
+ $socket = "{$g['varrun_path']}/dpinger_{$gateway['name']}.sock";
+ $alarm_cmd = "{$g['etc_path']}/rc.gateway_alarm {$gateway['name']}";
+
+ $params = "-S "; /* Log warnings via syslog */
+ $params .= "-B {$gateway['gwifip']} "; /* Bind src address */
+ $params .= "-p {$pidfile} "; /* PID filename */
+ $params .= "-U {$socket} "; /* Status Socket */
+ $params .= "-C \"{$alarm_cmd}\" "; /* Command to run on alarm */
+
+ $params .= "-s " .
+ (isset($gateway['interval']) && is_numeric($gateway['interval'])
+ ? $gateway['interval']
+ : $dpinger_defaults['interval']
+ ) . " ";
+
+ $params .= "-l " .
+ (isset($gateway['loss_interval']) && is_numeric($gateway['loos_interval'])
+ ? $gateway['loss_interval']
+ : $dpinger_defaults['loss_interval']
+ ) . " ";
+
+ $params .= "-t " .
+ (isset($gateway['time_period']) && is_numeric($gateway['time_period'])
+ ? $gateway['time_period']
+ : $dpinger_defaults['time_period']
+ ) . " ";
+
+ $params .= "-A " .
+ (isset($gateway['alert_interval']) && is_numeric($gateway['alert_interval'])
+ ? $gateway['alert_interval']
+ : $dpinger_defaults['alert_interval']
+ ) . " ";
+
+ $params .= "-D " .
+ (isset($gateway['latencyhigh']) && is_numeric($gateway['latencyhigh'])
+ ? $gateway['latencyhigh']
+ : $dpinger_defaults['latencyhigh']
+ ) . " ";
+
+ $params .= "-L " .
+ (isset($gateway['losshigh']) && is_numeric($gateway['losshigh'])
+ ? $gateway['losshigh']
+ : $dpinger_defaults['losshigh']
+ ) . " ";
+
+ mwexec_bg("/usr/local/bin/dpinger {$params} {$gateway['monitor']}");
}
-target default {
- ## How often the probe should be sent
- interval {$apinger_default['interval']}s
-
- ## How many replies should be used to compute average delay
- ## for controlling "delay" alarms
- avg_delay_samples {$apinger_default['avg_delay_samples']}
-
- ## How many probes should be used to compute average loss
- avg_loss_samples {$apinger_default['avg_loss_samples']}
-
- ## The delay (in samples) after which loss is computed
- ## without this delays larger than interval would be treated as loss
- avg_loss_delay_samples {$apinger_default['avg_loss_delay_samples']}
-
- ## Names of the alarms that may be generated for the target
- alarms "down","delay","loss"
-
- ## Location of the RRD
- #rrd file "{$g['vardb_path']}/rrd/apinger-%t.rrd"
-}
+/*
+ * Creates monitoring configuration file and
+ * adds appropriate static routes.
+ */
+function setup_gateways_monitor() {
+ global $config, $g;
-EOD;
+ $gateways_arr = return_gateways_array();
+ if (!is_array($gateways_arr)) {
+ log_error("No gateways to monitor. dpinger will not run.");
+ stop_dpinger();
+ return;
+ }
$monitor_ips = array();
- foreach ($gateways_arr as $name => $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
+?>
OpenPOWER on IntegriCloud