diff --git a/CHANGELOG.md b/CHANGELOG.md
index 290b44d..d91c0dc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,10 +6,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## 1.2.0 - 2023-06-26
+### Fixed
+- PR https://github.com/hybula/lookingglass/pull/21 thanks to @JKJameson.
+- Issue #20 thanks to @amirgilan for reporting.
+
+### Added
+- Latency feature (by default disabled).
+
## 1.1.3 - 2023-03-01
### Fixed
-- Issue #12 with https://github.com/hybula/lookingglass/pull/14 thanks to @MarcHagen
-- Issue #13 with https://github.com/hybula/lookingglass/pull/15 thanks to @MarcHagen
+- Issue #12 with https://github.com/hybula/lookingglass/pull/14 thanks to @MarcHagen.
+- Issue #13 with https://github.com/hybula/lookingglass/pull/15 thanks to @MarcHagen.
## 1.1.2 - 2023-01-05
### Fixed
diff --git a/LookingGlass.php b/LookingGlass.php
index 1c0ae45..cf32239 100644
--- a/LookingGlass.php
+++ b/LookingGlass.php
@@ -1,4 +1,6 @@
-update($str);
- echo '---' . PHP_EOL . $parser->__toString() . PHP_EOL . str_pad('', 4096) . PHP_EOL;
+ echo '---'.PHP_EOL.$parser->__toString().PHP_EOL.str_pad('', 4096).PHP_EOL;
// flush output buffering
@ob_flush();
flush();
continue;
- }
- // correct output for traceroute
+ } // correct output for traceroute
elseif ($type === 'traceroute') {
if ($match < 10 && preg_match('/^[0-9] /', $str, $string)) {
- $str = preg_replace('/^[0-9] /', ' ' . $string[0], $str);
+ $str = preg_replace('/^[0-9] /', ' '.$string[0], $str);
$match++;
}
// check for consecutive failed hops
@@ -304,9 +359,9 @@ private static function procExecute(string $cmd, string $host, int $failCount =
$fail++;
if ($lastFail !== 'start'
&& ($traceCount - 1) === $lastFail
- && $fail >= $failCount
+ && $fail >= $failCount
) {
- echo str_pad($str . '
-- Traceroute timed out --
', 4096, ' ', STR_PAD_RIGHT);
+ echo str_pad($str.'
-- Traceroute timed out --
', 4096, ' ', STR_PAD_RIGHT);
break;
}
$lastFail = $traceCount;
@@ -315,7 +370,7 @@ private static function procExecute(string $cmd, string $host, int $failCount =
}
// pad string for live output
- echo str_pad($str . '
', 4096, ' ', STR_PAD_RIGHT);
+ echo str_pad($str.'
', 4096, ' ', STR_PAD_RIGHT);
// flush output buffering
@ob_flush();
@@ -345,7 +400,7 @@ private static function procExecute(string $cmd, string $host, int $failCount =
// kill remaining processes
foreach ($pids as $pid) {
if (is_numeric($pid)) {
- posix_kill((int) $pid, 9);
+ posix_kill((int)$pid, 9);
}
}
}
@@ -353,6 +408,66 @@ private static function procExecute(string $cmd, string $host, int $failCount =
}
return true;
}
+
+ public static function getLatency(): float
+ {
+ $getLatency = self::getLatencyFromSs(self::detectIpAddress());
+ if (isset($getLatency[0])) {
+ return round((float)$getLatency[0]['latency']);
+ } else {
+ return 0.00;
+ }
+ }
+
+ /**
+ * This uses the command 'ss' in order to find out latency.
+ * A clever way coded by @ayyylias, so please keep credits and do not just steal.
+ *
+ * @param string $ip The command to execute.
+ * @return array Returns an array with results.
+ */
+ private static function getLatencyFromSs(string $ip): array
+ {
+ $lines = shell_exec('/usr/sbin/ss -Hti state established');
+ $ss = [];
+ $i = 0;
+ $j = 0;
+ foreach (explode(PHP_EOL, $lines) as $line) {
+ if ($i > 1) {
+ $i = 0;
+ $j++;
+ }
+ if ($line !== '') {
+ @$ss[$j] .= $line;
+ $i++;
+ }
+ }
+ $output = [];
+ foreach ($ss as $socket) {
+ $socket = preg_replace('!\s+!', ' ', $socket);
+ $explodedsocket = explode(' ', $socket);
+ preg_match('/\d+\.\d+\.\d+\.\d+/', $explodedsocket[2], $temp);
+ if (!isset($temp[0])) {
+ continue;
+ }
+ $sock['local'] = $temp[0];
+ preg_match('/\d+\.\d+\.\d+\.\d+/', $explodedsocket[3], $temp);
+ $sock['remote'] = $temp[0];
+ preg_match('/segs_out:(\d+)/', $socket, $temp);
+ $sock['segs_out'] = $temp[1];
+ preg_match('/segs_in:(\d+)/', $socket, $temp);
+ $sock['segs_in'] = $temp[1];
+ preg_match_all('/rtt:(\d+\.\d+)\/(\d+\.\d+)/', $socket, $temp);
+ $sock['latency'] = $temp[1][0];
+ $sock['jitter'] = $temp[2][0];
+ preg_match_all('/retrans:\d+\/(\d+)/', $socket, $temp);
+ $sock['retransmissions'] = (isset($temp[1][0]) ? $temp[1][0] : 0);
+ if ($sock['remote'] == $ip) {
+ $output[] = $sock;
+ }
+ }
+ return $output;
+ }
}
class Hop
@@ -423,10 +538,10 @@ public function __toString(): string
$hop->recieved = count($hop->timings);
if (count($hop->timings)) {
- $hop->last = $hop->timings[count($hop->timings) - 1];
- $hop->best = $hop->timings[0];
+ $hop->last = $hop->timings[count($hop->timings) - 1];
+ $hop->best = $hop->timings[0];
$hop->worst = $hop->timings[0];
- $hop->avg = array_sum($hop->timings) / count($hop->timings);
+ $hop->avg = array_sum($hop->timings) / count($hop->timings);
}
if (count($hop->timings) > 1) {
@@ -434,7 +549,6 @@ public function __toString(): string
}
foreach ($hop->timings as $time) {
-
if ($hop->best > $time) {
$hop->best = $time;
}
@@ -483,10 +597,10 @@ public function update($rawMtrInput)
return;
}
- $rawHop = new RawHop();
+ $rawHop = new RawHop();
$rawHop->dataType = $things[0];
- $rawHop->idx = (int)$things[1];
- $rawHop->value = $things[2];
+ $rawHop->idx = (int)$things[1];
+ $rawHop->value = $things[2];
if ($this->hopCount < $rawHop->idx + 1) {
$this->hopCount = $rawHop->idx + 1;
@@ -496,12 +610,12 @@ public function update($rawMtrInput)
$this->hopsCollection[$rawHop->idx] = new Hop();
}
- $hop = $this->hopsCollection[$rawHop->idx];
+ $hop = $this->hopsCollection[$rawHop->idx];
$hop->idx = $rawHop->idx;
switch ($rawHop->dataType) {
case 'h':
- $hop->ips[] = $rawHop->value;
- $hop->hosts[] = gethostbyaddr($rawHop->value) ? : null;
+ $hop->ips[] = $rawHop->value;
+ $hop->hosts[] = gethostbyaddr($rawHop->value) ?: null;
break;
case 'd':
//Not entirely sure if multiple IPs. Better use -n in mtr and resolve later in summarize.
@@ -523,13 +637,13 @@ public function update($rawMtrInput)
private function filterLastDupeHop()
{
// filter dupe last hop
- $finalIdx = 0;
+ $finalIdx = 0;
$previousIp = '';
foreach ($this->hopsCollection as $key => $hop) {
if (count($hop->ips) && $hop->ips[0] !== $previousIp) {
$previousIp = $hop->ips[0];
- $finalIdx = $key + 1;
+ $finalIdx = $key + 1;
}
}
diff --git a/backend.php b/backend.php
index 58badd5..ce3fb4f 100644
--- a/backend.php
+++ b/backend.php
@@ -19,6 +19,8 @@
LookingGlass::validateConfig();
LookingGlass::startSession();
+header('X-Accel-Buffering: no');
+
if (isset($_SESSION[LookingGlass::SESSION_TARGET_HOST]) &&
isset($_SESSION[LookingGlass::SESSION_TARGET_METHOD]) &&
isset($_SESSION[LookingGlass::SESSION_CALL_BACKEND])
diff --git a/config.dist.php b/config.dist.php
index aaa9fd6..0215e72 100644
--- a/config.dist.php
+++ b/config.dist.php
@@ -9,6 +9,9 @@
// Define the URL where the logo points to;
const LG_LOGO_URL = 'https://github.com/hybula/lookingglass/';
+// Enable the latency check feature;
+const LG_CHECK_LATENCY = false;
+
// Define a custom CSS file which can be used to style the LG, set false to disable, else point to the CSS file;
const LG_CSS_OVERRIDES = false;
// Define