fix(core): a learned RIP route expires at its time and is announced at once
Java's RIPTable.check marks an expired route only at the router's next beacon, up to some 35 s late. The engine schedules each router's first expiry, marks the route with 16 hops at that time and sends its table at once, as after any change (better than Java where Java only samples, decided 01.10.2026). ripJava's expire story is compared up to the expiry and then checks that R2 marks the route at its time and R1 a cable later. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2047,18 +2047,34 @@ describe('RIP', () => {
|
||||
expect(beacons(withSocket, routerAId)).toEqual(beacons(plain, routerAId));
|
||||
});
|
||||
|
||||
it('marks a learned route unreachable at the first beacon after it expired, and keeps it (Java: RIPTable.check)', () => {
|
||||
it('marks a learned route unreachable when it expires, keeps it, and tells its neighbours at once (Java: at its next beacon)', () => {
|
||||
const engine = ripTopology();
|
||||
engine.handle({ type: 'advance', toMilliseconds: 2_000 });
|
||||
engine.setGlobalPacketLossEnabled(true);
|
||||
const expiry = route(engine, routerAId, '172.16.0.0')!.expiresAtMilliseconds!;
|
||||
engine.handle({ type: 'advance', toMilliseconds: expiry + 1 });
|
||||
engine.handle({ type: 'advance', toMilliseconds: expiry - 1 });
|
||||
expect(route(engine, routerAId, '172.16.0.0')?.metric).toBe(1);
|
||||
const [beacon] = beacons(engine, routerAId) as [number];
|
||||
engine.handle({ type: 'advance', toMilliseconds: beacon - 1 });
|
||||
expect(route(engine, routerAId, '172.16.0.0')?.metric).toBe(1);
|
||||
engine.handle({ type: 'advance', toMilliseconds: beacon });
|
||||
expect(beacon).toBeGreaterThan(expiry);
|
||||
engine.handle({ type: 'advance', toMilliseconds: expiry });
|
||||
expect(route(engine, routerAId, '172.16.0.0')).toMatchObject({ metric: 16, expiresAtMilliseconds: expiry });
|
||||
expect(sentTables(engine, routerAId).at(-1)).toBe(expiry);
|
||||
// The next beacon comes a pause after the message, not at the old time.
|
||||
expect(beacons(engine, routerAId)[0]).toBeGreaterThan(beacon);
|
||||
});
|
||||
|
||||
it('expires each learned route at its own time, also after another expired first', () => {
|
||||
const engine = ripTopology();
|
||||
engine.handle({ type: 'advance', toMilliseconds: 2_000 });
|
||||
const first = fromB(engine, '10.0.0.2\n10.0.0.2\n16\n75000\n198.51.100.0 255.255.255.0 1');
|
||||
engine.handle({ type: 'advance', toMilliseconds: first + 10_000 });
|
||||
const second = fromB(engine, '10.0.0.2\n10.0.0.2\n16\n75000\n203.0.113.0 255.255.255.0 1');
|
||||
engine.setGlobalPacketLossEnabled(true);
|
||||
engine.handle({ type: 'advance', toMilliseconds: second + 75_000 - 1 });
|
||||
expect(route(engine, routerAId, '198.51.100.0')?.metric).toBe(16);
|
||||
expect(route(engine, routerAId, '203.0.113.0')?.metric).toBe(2);
|
||||
engine.handle({ type: 'advance', toMilliseconds: second + 75_000 });
|
||||
expect(route(engine, routerAId, '203.0.113.0')?.metric).toBe(16);
|
||||
});
|
||||
|
||||
it('routes with its table alone: a manual route does not count', () => {
|
||||
|
||||
Reference in New Issue
Block a user