It is the commonest home LAN range there is, so on an ordinary workstation the lab's private segment and the machine's own network are the same addresses. The scenario routes an egress machine explicitly and marks the rest unreachable, so nothing leaked — but that guard was carrying the whole weight of a collision nobody chose, and a guard is a bad place for that. 10.99.1.0/24 is still RFC 1918, so the bed still models a home LAN behind an access point. It is simply far from what this kind of machine already has: 192.168.1 is the LAN, 172.16-31 and 192.168.16-95 are container bridges, and 10.10/10.42/10.208 are a tunnel, the mesh overlay and the virtualisation daemon. Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
61 lines
2.4 KiB
TypeScript
61 lines
2.4 KiB
TypeScript
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { duplicateAddresses, describeConflicts } from "../src/lifecycle/invariants.ts";
|
|
|
|
/**
|
|
* The fault this defends against, in the shape it actually occurred: two gateways declared
|
|
* with the same public address became two router containers, both holding it on one segment.
|
|
*/
|
|
|
|
test("two machines holding one address on one segment is a conflict", () => {
|
|
const conflicts = duplicateAddresses([
|
|
{ machine: "gw-home", segment: "isp-home", address: "198.51.100.7/24" },
|
|
{ machine: "gw-devices", segment: "isp-home", address: "198.51.100.7/24" },
|
|
{ machine: "transit", segment: "isp-home", address: "198.51.100.254/24" },
|
|
]);
|
|
assert.equal(conflicts.length, 1);
|
|
assert.equal(conflicts[0]?.address, "198.51.100.7");
|
|
assert.deepEqual(conflicts[0]?.machines, ["gw-devices", "gw-home"]);
|
|
assert.match(describeConflicts(conflicts), /198\.51\.100\.7 is held by gw-devices and gw-home/);
|
|
});
|
|
|
|
test("the same address on different segments is NOT a conflict", () => {
|
|
// Every private network has its own `.1`. Reporting that would make the check useless.
|
|
assert.deepEqual(
|
|
duplicateAddresses([
|
|
{ machine: "gw-a", segment: "home", address: "10.99.1.1/24" },
|
|
{ machine: "gw-b", segment: "cafe", address: "10.99.1.1/24" },
|
|
]),
|
|
[],
|
|
);
|
|
});
|
|
|
|
test("one machine holding an address twice is not two machines", () => {
|
|
// A machine multi-homed onto the same segment, or an address read back from two places.
|
|
assert.deepEqual(
|
|
duplicateAddresses([
|
|
{ machine: "gw", segment: "isp", address: "198.51.100.7/24" },
|
|
{ machine: "gw", segment: "isp", address: "198.51.100.7" },
|
|
]),
|
|
[],
|
|
);
|
|
});
|
|
|
|
test("the prefix length is not part of the address", () => {
|
|
// The same address declared /24 in one place and /16 in another is still one address.
|
|
const conflicts = duplicateAddresses([
|
|
{ machine: "a", segment: "isp", address: "198.51.100.7/24" },
|
|
{ machine: "b", segment: "isp", address: "198.51.100.7/16" },
|
|
]);
|
|
assert.equal(conflicts.length, 1);
|
|
});
|
|
|
|
test("both families are checked", () => {
|
|
const conflicts = duplicateAddresses([
|
|
{ machine: "a", segment: "isp", address: "2001:db8:b::7/48" },
|
|
{ machine: "b", segment: "isp", address: "2001:db8:b::7/48" },
|
|
]);
|
|
assert.equal(conflicts.length, 1);
|
|
assert.equal(conflicts[0]?.address, "2001:db8:b::7");
|
|
});
|