Skip to content

Commit fdc53dc

Browse files
authored
feat: routing through tables (#69)
This PR adds routing table routing.
1 parent 292eb82 commit fdc53dc

File tree

7 files changed

+147
-54
lines changed

7 files changed

+147
-54
lines changed

src/context.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ export class GlobalContext {
1919
initialize(viewport: Viewport) {
2020
this.viewport = viewport;
2121

22-
const baseIp = "192.168.1.0";
23-
const mask = "255.255.255.0";
22+
const baseIp = "10.0.0.0";
23+
const mask = "255.255.255.255";
2424
this.ipGenerator = new IpAddressGenerator(baseIp, mask);
2525
loadFromLocalStorage(this);
2626
}

src/graphics/renderables/device_info.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,11 @@ export class DeviceInfo extends StyledInfo {
7171
}
7272

7373
addRoutingTable(entries: RoutingTableEntry[]) {
74-
const rows = entries.map((entry) => [entry.ip, entry.mask, entry.iface]);
74+
const rows = entries.map((entry) => [
75+
entry.ip,
76+
entry.mask,
77+
`eth${entry.iface}`,
78+
]);
7579

7680
const dynamicTable = createToggleTable(
7781
"Routing Table", // Title

src/types/devices/device.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export enum DeviceType {
3636
export abstract class Device extends Sprite {
3737
readonly id: DeviceId;
3838
readonly viewgraph: ViewGraph;
39-
connections = new Map<number, number>();
39+
connections = new Map<EdgeId, DeviceId>();
4040

4141
highlightMarker: Graphics | null = null; // Marker to indicate selection
4242

@@ -47,7 +47,7 @@ export abstract class Device extends Sprite {
4747
ipMask: IpAddress;
4848

4949
constructor(
50-
id: number,
50+
id: DeviceId,
5151
svg: string,
5252
viewgraph: ViewGraph,
5353
position: Position,

src/types/edge.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11
import { Graphics, Point } from "pixi.js";
2-
import { ViewGraph } from "./graphs/viewgraph";
2+
import { EdgeId, ViewGraph } from "./graphs/viewgraph";
33
import { Device } from "./devices/index"; // Import the Device class
44
import { deselectElement, selectElement } from "./viewportManager";
55
import { RightBar, StyledInfo } from "../graphics/right_bar";
66
import { Colors, ZIndexLevels } from "../utils";
77
import { Packet } from "./packet";
8+
import { DeviceId } from "./graphs/datagraph";
89

910
export interface EdgeEdges {
10-
n1: number;
11-
n2: number;
11+
n1: DeviceId;
12+
n2: DeviceId;
1213
}
1314

1415
export class Edge extends Graphics {
15-
id: number;
16-
connectedNodes: { n1: number; n2: number };
16+
id: EdgeId;
17+
connectedNodes: { n1: DeviceId; n2: DeviceId };
1718
startPos: Point;
1819
endPos: Point;
1920
viewgraph: ViewGraph;
2021
rightbar: RightBar;
2122

2223
constructor(
23-
id: number,
24+
id: EdgeId,
2425
connectedNodes: EdgeEdges,
2526
device1: Device,
2627
device2: Device,
@@ -41,15 +42,15 @@ export class Edge extends Graphics {
4142
this.on("click", () => selectElement(this));
4243
}
4344

44-
nodePosition(nodeId: number): Point | undefined {
45+
nodePosition(nodeId: DeviceId): Point | undefined {
4546
return this.connectedNodes.n1 === nodeId
4647
? this.startPos
4748
: this.connectedNodes.n2 === nodeId
4849
? this.endPos
4950
: undefined;
5051
}
5152

52-
otherEnd(nodeId: number): number | undefined {
53+
otherEnd(nodeId: DeviceId): DeviceId | undefined {
5354
return this.connectedNodes.n1 === nodeId
5455
? this.connectedNodes.n2
5556
: this.connectedNodes.n2 === nodeId

src/types/graphs/datagraph.ts

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ interface RouterGraphNode extends CommonGraphNode {
1919
export interface RoutingTableEntry {
2020
ip: string;
2121
mask: string;
22-
iface: string;
22+
iface: DeviceId;
2323
}
2424

2525
// Typescript type guard
@@ -162,7 +162,7 @@ export class DataGraph {
162162
device1.routingTable.push({
163163
ip: device2.ip.toString(),
164164
mask: device2.mask,
165-
iface: `eth${n2Id}`,
165+
iface: n2Id,
166166
});
167167
}
168168

@@ -173,20 +173,21 @@ export class DataGraph {
173173
device2.routingTable.push({
174174
ip: device1.ip.toString(),
175175
mask: device1.mask,
176-
iface: `eth${n1Id}`,
176+
iface: n1Id,
177177
});
178178
}
179179

180180
console.log(
181181
`Connection created between devices ID: ${n1Id} and ID: ${n2Id}`,
182182
);
183183
this.notifyChanges();
184+
this.regenerateAllRoutingTables();
184185
}
185186

186187
updateDevicePosition(id: DeviceId, newValues: { x?: number; y?: number }) {
187188
const deviceGraphNode = this.devices.get(id);
188189
if (!deviceGraphNode) {
189-
console.warn("Devices id is not registered");
190+
console.warn("Device's id is not registered");
190191
return;
191192
}
192193
this.devices.set(id, { ...deviceGraphNode, ...newValues });
@@ -237,6 +238,7 @@ export class DataGraph {
237238
this.devices.delete(id);
238239
console.log(`Device with ID ${id} and its connections were removed.`);
239240
this.notifyChanges();
241+
this.regenerateAllRoutingTables();
240242
}
241243

242244
// Method to remove a connection (edge) between two devices by their IDs
@@ -270,6 +272,7 @@ export class DataGraph {
270272
`Connection removed between devices ID: ${n1Id} and ID: ${n2Id}`,
271273
);
272274
this.notifyChanges();
275+
this.regenerateAllRoutingTables();
273276
}
274277

275278
subscribeChanges(callback: () => void) {
@@ -279,4 +282,56 @@ export class DataGraph {
279282
notifyChanges() {
280283
this.onChanges.forEach((callback) => callback());
281284
}
285+
286+
regenerateAllRoutingTables() {
287+
console.log("Regenerating all routing tables");
288+
this.devices.forEach((_, id) => this.regenerateRoutingTable(id));
289+
}
290+
291+
regenerateRoutingTable(id: DeviceId) {
292+
const router = this.devices.get(id);
293+
if (!isRouter(router)) {
294+
return;
295+
}
296+
console.log(`Regenerating routing table for ID ${id}`);
297+
const parents = new Map<DeviceId, DeviceId>();
298+
parents.set(id, id);
299+
const queue = Array.from([id]);
300+
while (queue.length > 0) {
301+
const currentId = queue.shift();
302+
const current = this.devices.get(currentId);
303+
if (!isRouter(current)) {
304+
// Don't route packets on hosts
305+
continue;
306+
}
307+
current.connections.forEach((connectedId) => {
308+
if (!parents.has(connectedId)) {
309+
parents.set(connectedId, currentId);
310+
queue.push(connectedId);
311+
}
312+
});
313+
}
314+
315+
console.log(parents);
316+
317+
const table: RoutingTableEntry[] = [];
318+
parents.forEach((currentId, childId) => {
319+
const dstId = childId;
320+
if (dstId === id) {
321+
return;
322+
}
323+
324+
while (currentId !== id) {
325+
const parentId = parents.get(currentId);
326+
childId = currentId;
327+
currentId = parentId;
328+
}
329+
// Here the currentId is the router, and the childId
330+
// is the first step towards dstId
331+
const dst = this.devices.get(dstId);
332+
const entry = { ip: dst.ip, mask: dst.mask, iface: childId };
333+
table.push(entry);
334+
});
335+
router.routingTable = table;
336+
}
282337
}

src/types/graphs/viewgraph.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export class ViewGraph {
2222
private devices: Map<DeviceId, Device> = new Map<DeviceId, Device>();
2323
private edges: Map<EdgeId, Edge> = new Map<EdgeId, Edge>();
2424
private idCounter: EdgeId = 1;
25-
private datagraph: DataGraph;
25+
datagraph: DataGraph;
2626
private layer: Layer;
2727
viewport: Viewport;
2828

@@ -171,7 +171,11 @@ export class ViewGraph {
171171
// Get all connections of a device
172172
getConnections(id: DeviceId): Edge[] {
173173
const device = this.devices.get(id);
174-
return device ? Array.from(this.edges.values()) : [];
174+
return device
175+
? Array.from(device.connections.keys()).map((edgeId) =>
176+
this.edges.get(edgeId),
177+
)
178+
: [];
175179
}
176180

177181
// Get a specific device by its ID

0 commit comments

Comments
 (0)