fix(netflow): сохранить неизвестные координаты RIPE без ложных нулей

This commit is contained in:
Denozordec committed 2026-10-11 16:28:54 +07:00
1 parent af66faaae4
commit c718654bc7
10 files changed
+330 -18

No files matched your search

@@ -220,3 +220,40 @@ resetRipeCacheForTests()
assert.equal(lookupRipeCached("2606:4700:4700::1111"), null, "Invalidation clears IPv6 indexes")
console.log("traffic-flow-ripe.test.ts: ok (including IPv6 indexes and database pause/resume)")
for (const { name, location, expected } of [
{ name: "normal", location: { country: "US", latitude: 37.4, longitude: -122.1 }, expected: [37.4, -122.1] },
{ name: "equator", location: { country: "BR", latitude: 0, longitude: -50 }, expected: [0, -50] },
{ name: "meridian", location: { country: "GB", latitude: 51, longitude: 0 }, expected: [51, 0] },
{ name: "explicit zero", location: { country: "GH", latitude: 0, longitude: 0 }, expected: [0, 0] },
{ name: "unknown placeholder", location: { country: "?", latitude: 0, longitude: 0 }, expected: [null, null] },
{ name: "missing country placeholder", location: { latitude: 0, longitude: 0 }, expected: [null, null] },
{ name: "unknown country real coordinates", location: { country: "?", latitude: 1, longitude: 2 }, expected: [1, 2] },
{ name: "missing coordinates", location: { country: "US" }, expected: [null, null] },
{ name: "null coordinates", location: { country: "US", latitude: null, longitude: null }, expected: [null, null] },
{ name: "empty strings", location: { country: "US", latitude: "", longitude: "" }, expected: [null, null] },
{ name: "boolean", location: { country: "US", latitude: false, longitude: false }, expected: [null, null] },
{ name: "numeric strings", location: { country: "US", latitude: "0", longitude: "0" }, expected: [null, null] },
{ name: "partial", location: { country: "US", latitude: 37 }, expected: [null, null] },
{ name: "invalid latitude", location: { country: "US", latitude: 91, longitude: 1 }, expected: [null, null] },
{ name: "invalid longitude", location: { country: "US", latitude: 1, longitude: -181 }, expected: [null, null] },
{ name: "boundary", location: { country: "US", latitude: -90, longitude: 180 }, expected: [-90, 180] },
]) {
resetRipeCacheForTests()
disableRipePersistForTests()
setRipeFetchForTests(async input => {
const url = String(input)
const body = url.includes("network-info") ? { data: { prefix: "8.8.8.0/24", asns: [15169] } }
: url.includes("maxmind-geo-lite") ? { data: { located_resources: [{ locations: [location] }] } }
: { data: { holder: "GOOGLE, US" } }
return new Response(JSON.stringify(body), { status: 200 })
})
enqueueRipeMisses(["8.8.8.8"])
await flushRipeQueueForTests()
const result = lookupRipeCached("8.8.8.8")
assert.equal(result?.ok, true, name)
assert.equal(result?.asn, 15169, name)
assert.deepEqual([result?.lat, result?.lng], expected, name)
if (location.country === "?" || !("country" in location)) assert.equal(result?.country, "US", "ASN country fallback is independent of coordinate validity")
}
console.log("traffic-flow-ripe.test.ts: coordinate provenance cases passed")
+9 -5
View File
@@ -383,18 +383,22 @@ function pickGeo(data: unknown): { country: string; lat: number | null; lng: num
const d = data as {
data?: {
located_resources?: Array<{
locations?: Array<{ country?: string; latitude?: number; longitude?: number }>
locations?: Array<{ country?: string; latitude?: unknown; longitude?: unknown }>
}>
}
}
const loc = d?.data?.located_resources?.[0]?.locations?.[0]
const country = resolveRipeCountry(String(loc?.country ?? ""), 0, "")
const lat = loc?.latitude == null ? null : Number(loc.latitude)
const lng = loc?.longitude == null ? null : Number(loc.longitude)
const coordinate = (value: unknown, limit: number) => typeof value === "number" && Number.isFinite(value) && Math.abs(value) <= limit ? value : null
const lat = coordinate(loc?.latitude, 90)
const lng = coordinate(loc?.longitude, 180)
// RIPE can return unknown country + 0/0 as a placeholder. ASN country fallback
// must not turn that placeholder into a confirmed map location.
const located = lat !== null && lng !== null && (Boolean(country) || lat !== 0 || lng !== 0)
return {
country: country || "—",
lat: Number.isFinite(lat) ? lat : null,
lng: Number.isFinite(lng) ? lng : null,
lat: located ? lat : null,
lng: located ? lng : null,
}
}