Add IAX Ping for all servers for healthcheck

This commit is contained in:
Christopher Cookman 2026-06-24 04:39:17 -06:00
parent f850288796
commit 409a12ea89
3 changed files with 73 additions and 2 deletions

View file

@ -23,6 +23,7 @@ const crypto = require("crypto")
const dns = require("dns");
const app = express();
const port = process.env.SERVER_PORT || 3000;
const iaxping = require("iaxping");
const invalidBlocks = [
// Emergency number prefixes (112, 911, 999, 110, 117, 119, 113, 191, 111)
@ -1050,6 +1051,69 @@ app.get("/api/healthcheck", (req, res) => {
});
});
// Periodic healthcheck on routes (iax ping every server every 5 minutes)
let persistentHealthCheckData;
function healthCheck() {
return new Promise((resolve, reject) => {
let healthCheckData = {};
pool.getConnection().then(conn => {
conn.query('SELECT * FROM routes').then((rows) => {
let count = 0;
for (const row of rows) {
const host = row.server;
const port = row.port;
const block = row.block_start;
iaxping({ host, port }).then((pingResult) => {
// Good ping
healthCheckData[block] = { online: true, ping: pingResult.rttMs, timestamp: Date.now() };
}).catch((pingErr) => {
switch (pingErr.code) {
case "ERR_POKE_TIMEOUT":
healthCheckData[block] = { online: false, ping: null, timestamp: Date.now(), error: "Timeout" };
break;
case "ENOTFOUND":
healthCheckData[block] = { online: false, ping: null, timestamp: Date.now(), error: "Host not found (DNS)" };
break;
default:
healthCheckData[block] = { online: false, ping: null, timestamp: Date.now(), error: pingErr.message };
break;
}
}).finally(() => {
count++;
if (count === rows.length) {
conn.release();
persistentHealthCheckData = healthCheckData;
resolve(healthCheckData);
}
});
}
}).catch(err => {
console.error('Error getting routes for health check:', err);
conn.release();
reject(err);
});
}).catch(err => {
console.error('Error getting connection for health check:', err);
reject(err);
});
});
};
setInterval(healthCheck, 300000); // Run every 5 minutes
app.get("/api/servers", (req, res) => {
if (!persistentHealthCheckData) {
healthCheck().then((data) => {
res.json(data);
}).catch(err => {
console.error('Error running health check:', err);
res.status(500).json({ error: 'Internal server error' });
});
} else {
res.json(persistentHealthCheckData);
}
});
// logCall function (caller, callee)
const logCall = (caller, callee, srcIp = "none_given", success, reason = "none_given") => {
pool.getConnection().then(conn => {

6
package-lock.json generated
View file

@ -15,6 +15,7 @@
"escape-html": "^1.0.3",
"express": "^4.21.2",
"express-session": "^1.18.1",
"iaxping": "github:ChrisChrome/IAXPing.js",
"mariadb": "^3.4.0",
"session-file-store": "^1.5.0"
}
@ -868,6 +869,11 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/iaxping": {
"version": "1.0.0",
"resolved": "git+ssh://git@github.com/ChrisChrome/IAXPing.js.git#105e669e5916cecc30273c9e4aa1f7bc47440f52",
"license": "GPL-3.0-only"
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",

View file

@ -16,6 +16,7 @@
"escape-html": "^1.0.3",
"express": "^4.21.2",
"express-session": "^1.18.1",
"iaxping": "github:ChrisChrome/IAXPing.js",
"mariadb": "^3.4.0",
"session-file-store": "^1.5.0"
}