fix: resolve AS names via RIPE Stat AS overview API
This commit is contained in:
parent
405bfd01c7
commit
967a0a827b
40
server.js
40
server.js
@ -92,6 +92,24 @@ function fetchRPKIPerPrefix(asn, prefix) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function resolveASNames(asnList) {
|
||||||
|
const names = {};
|
||||||
|
const batchSize = 10;
|
||||||
|
for (let i = 0; i < asnList.length; i += batchSize) {
|
||||||
|
const batch = asnList.slice(i, i + batchSize);
|
||||||
|
const results = await Promise.all(
|
||||||
|
batch.map((asn) =>
|
||||||
|
fetchJSON("https://stat.ripe.net/data/as-overview/data.json?resource=AS" + asn)
|
||||||
|
.then((r) => ({ asn, name: r?.data?.holder || "" }))
|
||||||
|
.catch(() => ({ asn, name: "" }))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
results.forEach((r) => { names[r.asn] = r.name; });
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
const server = http.createServer(async (req, res) => {
|
const server = http.createServer(async (req, res) => {
|
||||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||||
res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
|
res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
|
||||||
@ -180,11 +198,19 @@ const server = http.createServer(async (req, res) => {
|
|||||||
const leftNeighbours = neighbours.filter((n) => n.type === "left");
|
const leftNeighbours = neighbours.filter((n) => n.type === "left");
|
||||||
leftNeighbours.forEach((n) => upstreamSet.add(n.asn));
|
leftNeighbours.forEach((n) => upstreamSet.add(n.asn));
|
||||||
|
|
||||||
const detectedProviders = [...upstreamSet].map((asn) => {
|
let detectedProviders = [...upstreamSet].map((asn) => {
|
||||||
const nb = leftNeighbours.find((n) => n.asn === asn);
|
const nb = leftNeighbours.find((n) => n.asn === asn);
|
||||||
return { asn, name: nb && nb.as_name ? nb.as_name : "" };
|
return { asn, name: nb && nb.as_name ? nb.as_name : "" };
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Batch-resolve AS names from RIPE Stat AS overview API
|
||||||
|
const providerASNs = detectedProviders.map((p) => p.asn);
|
||||||
|
const resolvedNames = await resolveASNames(providerASNs);
|
||||||
|
detectedProviders = detectedProviders.map((p) => ({
|
||||||
|
...p,
|
||||||
|
name: resolvedNames[p.asn] || p.name || "",
|
||||||
|
}));
|
||||||
|
|
||||||
// Check RIPE DB for ASPA references
|
// Check RIPE DB for ASPA references
|
||||||
let aspaObjectExists = false;
|
let aspaObjectExists = false;
|
||||||
try {
|
try {
|
||||||
@ -216,7 +242,7 @@ const server = http.createServer(async (req, res) => {
|
|||||||
"# AFI: ipv4, ipv6\n" +
|
"# AFI: ipv4, ipv6\n" +
|
||||||
"#\n" +
|
"#\n" +
|
||||||
"# Detected providers from BGP path analysis:\n" +
|
"# Detected providers from BGP path analysis:\n" +
|
||||||
detectedProviders.map((p) => "# AS" + p.asn + " (" + p.name + ")").join("\n");
|
detectedProviders.map((p) => "# AS" + p.asn + (p.name ? " (" + p.name + ")" : "")).join("\n");
|
||||||
|
|
||||||
// Sample path analysis
|
// Sample path analysis
|
||||||
const samplePaths = asPaths.slice(0, 10).map((p) => {
|
const samplePaths = asPaths.slice(0, 10).map((p) => {
|
||||||
@ -451,17 +477,21 @@ const server = http.createServer(async (req, res) => {
|
|||||||
const rpkiTotal = rpkiStatuses.length;
|
const rpkiTotal = rpkiStatuses.length;
|
||||||
const rpkiCoverage = rpkiTotal > 0 ? Math.round((rpkiValid / rpkiTotal) * 100) : 0;
|
const rpkiCoverage = rpkiTotal > 0 ? Math.round((rpkiValid / rpkiTotal) * 100) : 0;
|
||||||
|
|
||||||
|
// Resolve AS names for neighbours that have empty as_name
|
||||||
|
const neighboursNeedingNames = neighbours.filter((n) => !n.as_name).map((n) => n.asn);
|
||||||
|
const neighbourNames = neighboursNeedingNames.length > 0 ? await resolveASNames(neighboursNeedingNames) : {};
|
||||||
|
|
||||||
const upstreams = neighbours
|
const upstreams = neighbours
|
||||||
.filter((n) => n.type === "left")
|
.filter((n) => n.type === "left")
|
||||||
.map((n) => ({ asn: n.asn, name: n.as_name || "AS" + n.asn, power: n.power || 0 }))
|
.map((n) => ({ asn: n.asn, name: n.as_name || neighbourNames[n.asn] || "", power: n.power || 0 }))
|
||||||
.sort((a, b) => b.power - a.power);
|
.sort((a, b) => b.power - a.power);
|
||||||
const downstreams = neighbours
|
const downstreams = neighbours
|
||||||
.filter((n) => n.type === "right")
|
.filter((n) => n.type === "right")
|
||||||
.map((n) => ({ asn: n.asn, name: n.as_name || "AS" + n.asn, power: n.power || 0 }))
|
.map((n) => ({ asn: n.asn, name: n.as_name || neighbourNames[n.asn] || "", power: n.power || 0 }))
|
||||||
.sort((a, b) => b.power - a.power);
|
.sort((a, b) => b.power - a.power);
|
||||||
const peers = neighbours
|
const peers = neighbours
|
||||||
.filter((n) => n.type === "uncertain" || n.type === "peer")
|
.filter((n) => n.type === "uncertain" || n.type === "peer")
|
||||||
.map((n) => ({ asn: n.asn, name: n.as_name || "AS" + n.asn, power: n.power || 0 }))
|
.map((n) => ({ asn: n.asn, name: n.as_name || neighbourNames[n.asn] || "", power: n.power || 0 }))
|
||||||
.sort((a, b) => b.power - a.power);
|
.sort((a, b) => b.power - a.power);
|
||||||
|
|
||||||
let rir = "";
|
let rir = "";
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user