Docker images / prepare-release (push) Successful in 8s
Docker images / backend-image (push) Failing after 1m31s
Docker images / frontend-image (push) Successful in 2m36s
Docker images / notify-webhook (push) Skipped
Docker images / updater-image (push) Successful in 42s
Docker images / publish-release (push) Skipped
Считать payload отдельно от overlay GRE/ESP и mesh; вкладка Пути и KPI Wire из счётчиков iface. Co-authored-by: Cursor <cursoragent@cursor.com>
205 lines
6.7 KiB
TypeScript
205 lines
6.7 KiB
TypeScript
import assert from "node:assert/strict"
|
|
import { parseFlowPacket, protoName, resetFlowTemplatesForTests, templateExporterCountForTests } from "./traffic-flow-parse.js"
|
|
import { allocateOverlayAddress, FLOW_TARGET_SRC_AUTO, usablePublicHost } from "./traffic-flow-overlay.js"
|
|
|
|
function netflowV5One(): Buffer {
|
|
const buf = Buffer.alloc(24 + 48)
|
|
buf.writeUInt16BE(5, 0)
|
|
buf.writeUInt16BE(1, 2)
|
|
buf[24] = 10; buf[25] = 1; buf[26] = 1; buf[27] = 8
|
|
buf[28] = 8; buf[29] = 8; buf[30] = 8; buf[31] = 8
|
|
buf.writeUInt16BE(1, 24 + 12)
|
|
buf.writeUInt32BE(10, 24 + 16)
|
|
buf.writeUInt32BE(1500, 24 + 20)
|
|
buf.writeUInt16BE(443, 24 + 32)
|
|
buf.writeUInt16BE(443, 24 + 34)
|
|
buf.writeUInt8(6, 24 + 38)
|
|
return buf
|
|
}
|
|
|
|
resetFlowTemplatesForTests()
|
|
const flows = parseFlowPacket(netflowV5One(), "10.255.254.5")
|
|
assert.equal(flows.length, 1)
|
|
assert.equal(flows[0]?.src, "10.1.1.8")
|
|
assert.equal(flows[0]?.dst, "8.8.8.8")
|
|
assert.equal(flows[0]?.proto, 6)
|
|
assert.equal(flows[0]?.bytes, 1500)
|
|
assert.equal(flows[0]?.inIface, "1")
|
|
assert.equal(protoName(6), "TCP")
|
|
assert.equal(parseFlowPacket(Buffer.from([0, 1]), "1.1.1.1").length, 0)
|
|
|
|
const taken = new Set(["10.255.254.2"])
|
|
assert.equal(allocateOverlayAddress("10.255.254.0/24", "10.255.254.1", 1, taken), "10.255.254.3")
|
|
assert.equal(allocateOverlayAddress("10.255.254.0/24", "10.255.254.1", 2, new Set()), "10.255.254.3")
|
|
|
|
assert.equal(usablePublicHost("localhost:8000"), "")
|
|
assert.equal(usablePublicHost("127.0.0.1"), "")
|
|
assert.equal(usablePublicHost("192.168.1.10"), "")
|
|
assert.equal(usablePublicHost("mm.example.com:443"), "mm.example.com")
|
|
assert.equal(usablePublicHost("203.0.113.10"), "203.0.113.10")
|
|
assert.equal(FLOW_TARGET_SRC_AUTO, "0.0.0.0")
|
|
|
|
resetFlowTemplatesForTests()
|
|
{
|
|
const tpl = Buffer.alloc(16 + 16 + 20)
|
|
tpl.writeUInt16BE(10, 0)
|
|
tpl.writeUInt16BE(tpl.length, 2)
|
|
tpl.writeUInt16BE(2, 16)
|
|
tpl.writeUInt16BE(16, 18)
|
|
tpl.writeUInt16BE(256, 20)
|
|
tpl.writeUInt16BE(2, 22)
|
|
tpl.writeUInt16BE(8, 24)
|
|
tpl.writeUInt16BE(4, 26)
|
|
tpl.writeUInt16BE(12, 28)
|
|
tpl.writeUInt16BE(4, 30)
|
|
const data = Buffer.alloc(16 + 12)
|
|
data.writeUInt16BE(10, 0)
|
|
data.writeUInt16BE(data.length, 2)
|
|
data.writeUInt16BE(256, 16)
|
|
data.writeUInt16BE(12, 18)
|
|
data[20] = 10; data[21] = 1; data[22] = 1; data[23] = 8
|
|
data[24] = 8; data[25] = 8; data[26] = 8; data[27] = 8
|
|
const fromTpl = parseFlowPacket(tpl, "172.18.0.2")
|
|
assert.equal(fromTpl.length, 0)
|
|
const fromData = parseFlowPacket(data, "172.18.0.2")
|
|
assert.equal(fromData.length, 1)
|
|
assert.equal(fromData[0]?.src, "10.1.1.8")
|
|
assert.equal(fromData[0]?.dst, "8.8.8.8")
|
|
}
|
|
|
|
resetFlowTemplatesForTests()
|
|
{
|
|
const tpl = Buffer.alloc(16 + 24)
|
|
tpl.writeUInt16BE(10, 0)
|
|
tpl.writeUInt16BE(tpl.length, 2)
|
|
tpl.writeUInt16BE(2, 16)
|
|
tpl.writeUInt16BE(24, 18)
|
|
tpl.writeUInt16BE(256, 20)
|
|
tpl.writeUInt16BE(4, 22)
|
|
tpl.writeUInt16BE(8, 24)
|
|
tpl.writeUInt16BE(4, 26)
|
|
tpl.writeUInt16BE(12, 28)
|
|
tpl.writeUInt16BE(4, 30)
|
|
tpl.writeUInt16BE(10, 32)
|
|
tpl.writeUInt16BE(4, 34)
|
|
tpl.writeUInt16BE(82, 36)
|
|
tpl.writeUInt16BE(6, 38)
|
|
const data = Buffer.alloc(16 + 22)
|
|
data.writeUInt16BE(10, 0)
|
|
data.writeUInt16BE(data.length, 2)
|
|
data.writeUInt16BE(256, 16)
|
|
data.writeUInt16BE(22, 18)
|
|
data[20] = 10; data[21] = 1; data[22] = 1; data[23] = 8
|
|
data[24] = 8; data[25] = 8; data[26] = 8; data[27] = 8
|
|
data.writeUInt32BE(13, 28)
|
|
data.write("ether1", 32)
|
|
parseFlowPacket(tpl, "10.255.254.3")
|
|
const named = parseFlowPacket(data, "10.255.254.3")
|
|
assert.equal(named.length, 1)
|
|
assert.equal(named[0]?.inIface, "13")
|
|
assert.equal(named[0]?.src, "10.1.1.8")
|
|
}
|
|
|
|
resetFlowTemplatesForTests()
|
|
{
|
|
const tpl = Buffer.alloc(16 + 20)
|
|
tpl.writeUInt16BE(10, 0)
|
|
tpl.writeUInt16BE(tpl.length, 2)
|
|
tpl.writeUInt16BE(2, 16)
|
|
tpl.writeUInt16BE(20, 18)
|
|
tpl.writeUInt16BE(256, 20)
|
|
tpl.writeUInt16BE(3, 22)
|
|
tpl.writeUInt16BE(8, 24)
|
|
tpl.writeUInt16BE(4, 26)
|
|
tpl.writeUInt16BE(12, 28)
|
|
tpl.writeUInt16BE(4, 30)
|
|
tpl.writeUInt16BE(82, 32)
|
|
tpl.writeUInt16BE(6, 34)
|
|
const data = Buffer.alloc(16 + 18)
|
|
data.writeUInt16BE(10, 0)
|
|
data.writeUInt16BE(data.length, 2)
|
|
data.writeUInt16BE(256, 16)
|
|
data.writeUInt16BE(18, 18)
|
|
data[20] = 10; data[21] = 1; data[22] = 1; data[23] = 8
|
|
data[24] = 8; data[25] = 8; data[26] = 8; data[27] = 8
|
|
data.write("ether1", 28)
|
|
parseFlowPacket(tpl, "10.255.254.4")
|
|
const namedOnly = parseFlowPacket(data, "10.255.254.4")
|
|
assert.equal(namedOnly[0]?.inIface, "ether1")
|
|
}
|
|
|
|
resetFlowTemplatesForTests()
|
|
{
|
|
const fieldSpecs: Array<[number, number]> = [
|
|
[8, 4],
|
|
[12, 4],
|
|
[10, 4],
|
|
[14, 4],
|
|
[15, 4],
|
|
[152, 8],
|
|
[153, 8],
|
|
[1, 4],
|
|
]
|
|
const tplSetLen = 4 + 4 + fieldSpecs.length * 4
|
|
const tpl = Buffer.alloc(16 + tplSetLen)
|
|
tpl.writeUInt16BE(10, 0)
|
|
tpl.writeUInt16BE(tpl.length, 2)
|
|
tpl.writeUInt16BE(2, 16)
|
|
tpl.writeUInt16BE(tplSetLen, 18)
|
|
tpl.writeUInt16BE(256, 20)
|
|
tpl.writeUInt16BE(fieldSpecs.length, 22)
|
|
let off = 24
|
|
for (const [type, len] of fieldSpecs) {
|
|
tpl.writeUInt16BE(type, off)
|
|
tpl.writeUInt16BE(len, off + 2)
|
|
off += 4
|
|
}
|
|
const recLen = fieldSpecs.reduce((n, [, len]) => n + len, 0)
|
|
const data = Buffer.alloc(16 + 4 + recLen)
|
|
data.writeUInt16BE(10, 0)
|
|
data.writeUInt16BE(data.length, 2)
|
|
data.writeUInt16BE(256, 16)
|
|
data.writeUInt16BE(4 + recLen, 18)
|
|
let d = 20
|
|
data[d] = 10; data[d + 1] = 100; data[d + 2] = 1; data[d + 3] = 17; d += 4
|
|
data[d] = 173; data[d + 1] = 194; data[d + 2] = 160; data[d + 3] = 163; d += 4
|
|
data.writeUInt32BE(13, d); d += 4
|
|
data.writeUInt32BE(42, d); d += 4
|
|
data[d] = 198; data[d + 1] = 51; data[d + 2] = 100; data[d + 3] = 1; d += 4
|
|
data.writeBigUInt64BE(1_700_000_000_000n, d); d += 8
|
|
data.writeBigUInt64BE(1_700_000_060_000n, d); d += 8
|
|
data.writeUInt32BE(1500, d)
|
|
parseFlowPacket(tpl, "10.255.254.5")
|
|
const extra = parseFlowPacket(data, "10.255.254.5")
|
|
assert.equal(extra.length, 1)
|
|
assert.equal(extra[0]?.src, "10.100.1.17")
|
|
assert.equal(extra[0]?.dst, "173.194.160.163")
|
|
assert.equal(extra[0]?.inIface, "13")
|
|
assert.equal(extra[0]?.outIface, "42")
|
|
assert.equal(extra[0]?.nextHop, "198.51.100.1")
|
|
assert.equal(extra[0]?.flowStartMs, 1_700_000_000_000)
|
|
assert.equal(extra[0]?.flowEndMs, 1_700_000_060_000)
|
|
assert.equal(extra[0]?.bytes, 1500)
|
|
}
|
|
|
|
resetFlowTemplatesForTests()
|
|
{
|
|
const tpl = Buffer.alloc(16 + 16 + 20)
|
|
tpl.writeUInt16BE(10, 0)
|
|
tpl.writeUInt16BE(tpl.length, 2)
|
|
tpl.writeUInt16BE(2, 16)
|
|
tpl.writeUInt16BE(16, 18)
|
|
tpl.writeUInt16BE(256, 20)
|
|
tpl.writeUInt16BE(2, 22)
|
|
tpl.writeUInt16BE(8, 24)
|
|
tpl.writeUInt16BE(4, 26)
|
|
tpl.writeUInt16BE(12, 28)
|
|
tpl.writeUInt16BE(4, 30)
|
|
for (let i = 0; i < 260; i++) {
|
|
parseFlowPacket(tpl, `203.0.${Math.floor(i / 250)}.${i % 250}`)
|
|
}
|
|
assert.ok(templateExporterCountForTests() <= 256)
|
|
}
|
|
|
|
console.log("traffic-flow-parse.test.ts: ok")
|