diff --git a/src/connectors/PacketVisConnector.js b/src/connectors/PacketVisConnector.js index 57c1871..5d2d04e 100644 --- a/src/connectors/PacketVisConnector.js +++ b/src/connectors/PacketVisConnector.js @@ -2,90 +2,45 @@ import RpkiClientConnector from "./RpkiClientConnector"; import brembo from "brembo"; import ExternalConnector from './ExternalConnector'; -const defaultHost = "http://rpki.local.packetvis.com/v1/rpki/static/"; -const hosts = [ - defaultHost, - "https://console.rpki-client.org/" -]; const api = "https://api.packetvis.com/v1/rpki/meta/"; + export default class PacketVisConnector extends RpkiClientConnector { constructor(options) { - super({...options, host: defaultHost}); + super({...options}); this.minimumRefreshRateMinutes = 1; this.cacheConnector = new ExternalConnector({}); - - this.selectServer(); - setInterval(this.selectServer, 15 * 60 * 1000); }; - selectServer = () => { - Promise.all(hosts - .map(host => { - return this.axios({ - method: "HEAD", - url: brembo.build(host, {path: ["vrps.json"]}), - responseType: "json" - }) - .then(data => { - - const lastModified = data?.headers["last-modified"] ? new Date(data?.headers["last-modified"]) : null; - - if (!lastModified || new Date().getTime() - lastModified.getTime() > 40 * 60 * 1000) { - return false; - } else { - return host; - } - }) - .catch(() => false); - })) - .then(hosts => hosts.filter(i => !!i)) - .then(availableHosts => { - if (availableHosts.includes(defaultHost)) { - this.host = defaultHost; - } else if (availableHosts[0]){ - console.log("Switching to RPKI server:", availableHosts[0]); - - this.host = availableHosts[0]; - } else { - console.log("Cannot connect to any RPKI data server. Probably a problem with this host."); - } - }); - } - getVRPs = () => { try { - const fs = require('fs'); + const fs = require('fs'); // Load only for node const file = ".cache/vrps.json"; if (fs.existsSync(file)) { const stats = fs.statSync(file); - if (((new Date) - stats.mtime) < 15 * 60 * 1000) { // Newer than 15 min + if (((new Date) - stats.mtime) < 30 * 60 * 1000) { // Newer than 30 min + const payload = JSON.parse(fs.readFileSync(file, 'utf8')); - this.cacheConnector.setVRPs(payload.roas); - this.metadata = { - lastModified: stats.mtime.toISOString(), - buildmachine: payload?.metadata?.buildmachine, - buildtime: payload?.metadata?.buildtime, - elapsedtime: payload?.metadata?.elapsedtime - }; + this.cacheConnector.setVRPs(payload.roas); + this._applyRpkiClientMetadata(payload?.metadata); + this.metadata.lastModified = stats.mtime.toISOString(); return this.cacheConnector.getVRPs(); + } else { + throw new Error("RPKI cache too old .cache/vrps.json"); } - throw new Error("Cache too old, switching to remote"); + } else { + throw new Error("RPKI cache missing .cache/vrps.json"); } - throw new Error("Cache not available, switching to remote"); - } catch (error) { - console.log(error); - return this._getVRPs(); + return Promise.reject(error); } } - getExpiringElements = (vrp, expires, now) => { if (this.metaIndex) { return Promise.resolve(this.metaIndex.getExpiring(vrp, expires, now)); diff --git a/src/connectors/RpkiClientConnector.js b/src/connectors/RpkiClientConnector.js index a38186c..78db341 100644 --- a/src/connectors/RpkiClientConnector.js +++ b/src/connectors/RpkiClientConnector.js @@ -71,6 +71,14 @@ export default class RpkiClientConnector extends Connector { return this._getVRPs(); } + _applyRpkiClientMetadata = (metadata={}) => { + this.metadata = { + buildmachine: metadata?.buildmachine, + buildtime: metadata?.buildtime ? new Date(metadata?.buildtime).toISOString() : null, // used for if-modified-since + elapsedtime: metadata?.elapsedtime + }; + } + _getVRPs = () => { const url = brembo.build(this.host, { path: ["vrps.json"], @@ -80,7 +88,7 @@ export default class RpkiClientConnector extends Connector { }); const headers = {}; - if (this.metadata?.buildtime) { + if (this.metadata?.lastModified) { headers["If-Modified-Since"] = new Date(this.metadata.lastModified).toUTCString(); } @@ -96,12 +104,8 @@ export default class RpkiClientConnector extends Connector { const metadata = data.data?.metadata; const headers = data.headers; - this.metadata = { - lastModified: headers["last-modified"], - buildmachine: metadata?.buildmachine, - buildtime: metadata?.buildtime, // if modified since - elapsedtime: metadata?.elapsedtime - }; + this._applyRpkiClientMetadata(metadata); + this.metadata.lastModified = headers["last-modified"] ? new Date(headers["last-modified"]).toISOString() : null; return roas .map(roa => { diff --git a/src/index.js b/src/index.js index ef46af6..2d814b6 100644 --- a/src/index.js +++ b/src/index.js @@ -180,9 +180,11 @@ class RpkiValidator { this.cacheTimer = setInterval(() => { this.preChachePromise = this.#getValidatedPrefixes(true) - .catch(() => { + .catch(error => { + console.log(error); return false; }); + }, everyMinutes * 60 * 1000); } else { if (this.cacheTimer) { @@ -192,10 +194,7 @@ class RpkiValidator { } if (!this.preChachePromise) { - this.preChachePromise = this.#getValidatedPrefixes() - .catch(() => { - return false; - }); + this.preChachePromise = this.#getValidatedPrefixes(); } return this.preChachePromise; @@ -414,11 +413,17 @@ class RpkiValidator { const now = new Date(); this.#setMetadata({lastAttempt: now}); - const newBuild = this.#connector?.metadata?.buildtime; - const currentBuild = this.#lastMetadata?.buildtime; + const newBuild = this.#connector?.metadata?.buildtime ? Date.parse(this.#connector?.metadata?.buildtime) : null; + const currentBuild = this.#lastMetadata?.buildtime ? Date.parse(this.#lastMetadata?.buildtime) : null; - if (newBuild && currentBuild && Date.parse(newBuild) <= Date.parse(currentBuild)) { - return false; // The new vrp definition is older than the previous one + if (!!newBuild && (now.getTime() - newBuild) > 2 * 60 * 60 * 1000) { + return Promise.reject("The new vrp data is older than 2 hours"); + } else if (newBuild && currentBuild) { + if (newBuild < currentBuild) { + return Promise.reject("The new vrp data is older than the previous one"); + } else if (newBuild === currentBuild) { + return Promise.resolve(true); + } } this.#setMetadata({lastUpdate: now}); @@ -434,9 +439,9 @@ class RpkiValidator { } } - return true; + return Promise.resolve(true); } else { - return false; + return Promise.reject("VRPs not found"); } }); }