mirror of
https://github.com/DeNNiiInc/Web-Page-Performance-Test.git
synced 2026-04-17 20:05:58 +00:00
V2 Feature overhaul and improvements
This commit is contained in:
81
lib/diagnostics/traceroute.js
Normal file
81
lib/diagnostics/traceroute.js
Normal file
@@ -0,0 +1,81 @@
|
||||
const { exec } = require('child_process');
|
||||
const dns = require('dns');
|
||||
|
||||
/**
|
||||
* Executes a traceroute to the specified host.
|
||||
* @param {string} host - The hostname or IP to trace.
|
||||
* @returns {Promise<string>} - The raw stdout output of the traceroute command.
|
||||
*/
|
||||
function runTraceroute(host) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Basic validation to prevent command injection
|
||||
if (!/^[a-zA-Z0-9.-]+$/.test(host)) {
|
||||
return reject(new Error('Invalid hostname format.'));
|
||||
}
|
||||
|
||||
// Resolve domain to ensure it exists before running system command (optional safety)
|
||||
dns.lookup(host, (err) => {
|
||||
if (err) return reject(new Error(`Could not resolve host: ${host}`));
|
||||
|
||||
// Detect platform
|
||||
const isWin = process.platform === 'win32';
|
||||
const command = isWin ? `tracert -d -h 20 ${host}` : `traceroute -n -m 20 ${host}`;
|
||||
|
||||
exec(command, { timeout: 60000 }, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
// Traceroute might return error code if it doesn't reach dest, but stdout is valuable
|
||||
if (stdout) resolve(stdout);
|
||||
else reject(error || stderr);
|
||||
} else {
|
||||
resolve(stdout);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const geoip = require('geoip-lite');
|
||||
|
||||
/**
|
||||
* Parses traceroute output and adds geolocation data.
|
||||
* @param {string} output - Raw traceroute output.
|
||||
* @returns {Array} - Array of hop objects with IP, RTT, and Location.
|
||||
*/
|
||||
function parseAndLocate(output) {
|
||||
const lines = output.split('\n');
|
||||
const hops = [];
|
||||
|
||||
// Regex to match lines like: " 1 192.168.1.1 2.5 ms"
|
||||
// Linux: 1 _gateway (10.0.2.2) 0.224 ms 0.180 ms 0.120 ms
|
||||
// Windows: 1 <1 ms <1 ms <1 ms 192.168.1.1
|
||||
const ipRegex = /\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/;
|
||||
|
||||
lines.forEach(line => {
|
||||
const match = line.match(ipRegex);
|
||||
if (match) {
|
||||
const ip = match[0];
|
||||
const geo = geoip.lookup(ip);
|
||||
|
||||
hops.push({
|
||||
raw: line.trim(),
|
||||
ip: ip,
|
||||
lat: geo ? geo.ll[0] : null,
|
||||
lon: geo ? geo.ll[1] : null,
|
||||
city: geo ? geo.city : null,
|
||||
country: geo ? geo.country : null
|
||||
});
|
||||
}
|
||||
});
|
||||
return hops;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes traceroute and returns structured data.
|
||||
*/
|
||||
async function traceAndLocate(host) {
|
||||
const rawOutput = await runTraceroute(host);
|
||||
const hops = parseAndLocate(rawOutput);
|
||||
return { raw: rawOutput, hops };
|
||||
}
|
||||
|
||||
module.exports = { runTraceroute, traceAndLocate };
|
||||
Reference in New Issue
Block a user