improved Routing

This commit is contained in:
Djeeberjr 2022-12-19 21:25:39 +01:00
parent 45a8851e2a
commit f988c79e2f

View File

@ -8,7 +8,7 @@ using tink.CoreApi;
@:structInit typedef Route = { @:structInit typedef Route = {
interf:INetworkInterface, interf:INetworkInterface,
rep: NetworkID, rep:NetworkID,
cost:Int cost:Int
} }
@ -21,13 +21,13 @@ class Routing {
**/ **/
public static var instance:Routing; public static var instance:Routing;
public static inline final UPDATE_WAIT_TIME:Float = 3; public static inline final UPDATE_WAIT_TIME:Float = 1;
public final onNewNeigbor:Signal<Int>; public final onNewNeigbor:Signal<Int>;
private final onNewNeigborTrigger:SignalTrigger<NetworkID> = Signal.trigger(); private final onNewNeigborTrigger:SignalTrigger<NetworkID> = Signal.trigger();
private final routingTable:Map<NetworkID, Route> = new Map(); private final routingTable:Map<NetworkID, Route> = new Map();
private var routeUpdateInQueue: Bool = false; private var routeUpdateInQueue:Bool = false;
@:allow(kernel.Init) @:allow(kernel.Init)
private function new() { private function new() {
@ -36,38 +36,35 @@ class Routing {
@:allow(kernel.Init) @:allow(kernel.Init)
private function init() { private function init() {
routingTable.set(Net.instance.networkID,{interf: Loopback.instance,cost:0,rep:Net.instance.networkID}); routingTable.set(Net.instance.networkID, {interf: Loopback.instance, cost: 0, rep: Net.instance.networkID});
for (modem in Peripheral.instance.getModems()) { brodcastRoutingTable();
modem.send(Net.BRODCAST_PORT, Net.instance.networkID, newRoutDiscoverPackage());
}
} }
/**
Prepares an brodcast of the current routing table. If a brodcast is already in queue it will be ignored.
After UPDATE_WAIT_TIME seconds the routing table will be brodcasted. This is done to prevent spamming the network.
**/
private function prepareRouteUpdate() { private function prepareRouteUpdate() {
if (this.routeUpdateInQueue){ if (this.routeUpdateInQueue) {
return; return;
} }
this.routeUpdateInQueue = true; this.routeUpdateInQueue = true;
new Timer(UPDATE_WAIT_TIME,()->{ new Timer(UPDATE_WAIT_TIME, () -> {
brodcastUpdatedRoutes(); brodcastRoutingTable();
this.routeUpdateInQueue = false; this.routeUpdateInQueue = false;
}); });
} }
private function brodcastUpdatedRoutes() { /**
var pack: Package = { Brodcast the current routing table to all peers.
type: RouteDiscoverUpdate(genRouteList()), **/
toID: Net.BRODCAST_PORT, private function brodcastRoutingTable() {
msgID: null, var pack = newRoutDiscoverPackage();
fromID: Net.instance.networkID,
data: null,
ttl: 0, // Prevent forwarding
};
for (modem in Peripheral.instance.getModems()) { for (modem in Peripheral.instance.getModems()) {
modem.send(Net.BRODCAST_PORT, Net.instance.networkID, pack);
modem.send(Net.BRODCAST_PORT, Net.instance.networkID,pack);
} }
} }
@ -76,22 +73,22 @@ class Routing {
**/ **/
@:allow(kernel.net.Net) @:allow(kernel.net.Net)
private function handleRoutePackage(pack:Package, interf:INetworkInterface):Void { private function handleRoutePackage(pack:Package, interf:INetworkInterface):Void {
addPossibleRoute(pack.fromID,interf,0,pack.fromID); addPossibleRoute(pack.fromID, interf, 0, pack.fromID);
var shouldRespond: Bool = switch pack.type { var shouldRespond:Bool = switch pack.type {
case RouteDiscoverResponse(routes): case RouteDiscoverResponse(routes):
for (route in routes) { for (route in routes) {
addPossibleRoute(route.id,interf,route.cost,pack.fromID); addPossibleRoute(route.id, interf, route.cost, pack.fromID);
} }
false; false;
case RouteDiscover(routes): case RouteDiscover(routes):
for (route in routes) { for (route in routes) {
addPossibleRoute(route.id,interf,route.cost,pack.fromID); addPossibleRoute(route.id, interf, route.cost, pack.fromID);
} }
true; true;
case RouteDiscoverUpdate(routes): case RouteDiscoverUpdate(routes):
for (route in routes) { for (route in routes) {
addPossibleRoute(route.id,interf,route.cost,pack.fromID); addPossibleRoute(route.id, interf, route.cost, pack.fromID);
} }
false; false;
default: default:
@ -99,7 +96,7 @@ class Routing {
false; false;
}; };
if (!shouldRespond){ if (!shouldRespond) {
return; return;
} }
@ -113,12 +110,15 @@ class Routing {
ttl: 0, // Prevent forwarding ttl: 0, // Prevent forwarding
} }
interf.send(response.toID,Net.instance.networkID,response); interf.send(response.toID, Net.instance.networkID, response);
} }
private function genRouteList(): Array<{id:NetworkID,cost:Int}> { /**
var routes: Array<{id:NetworkID,cost:Int}> = []; Generate a list of routes to send to a peer based on the current routing table.
for (k => v in this.routingTable){ **/
private function genRouteList():Array<{id:NetworkID, cost:Int}> {
var routes:Array<{id:NetworkID, cost:Int}> = [];
for (k => v in this.routingTable) {
routes.push({ routes.push({
id: k, id: k,
cost: v.cost cost: v.cost
@ -144,36 +144,36 @@ class Routing {
Called when a route to a client has been disoverd. Called when a route to a client has been disoverd.
Its possible to be called multiple times with the same id but different addr. Its possible to be called multiple times with the same id but different addr.
**/ **/
private function addPossibleRoute(toID:Int, interf:INetworkInterface, cost:Int, rep: NetworkID) { private function addPossibleRoute(toID:Int, interf:INetworkInterface, cost:Int, rep:NetworkID) {
if (toID == Net.instance.networkID){ if (toID == Net.instance.networkID) {
return; return;
} }
var fullCost = cost+interf.getBaseRoutingCost(); var fullCost = cost + interf.getBaseRoutingCost();
if (this.routingTable.exists(toID)){ if (this.routingTable.exists(toID)) {
if (this.routingTable[toID].cost > fullCost){ if (this.routingTable[toID].cost > fullCost) {
this.routingTable[toID] = {interf:interf,cost:cost + interf.getBaseRoutingCost(),rep: rep}; this.routingTable[toID] = {interf: interf, cost: cost + interf.getBaseRoutingCost(), rep: rep};
this.prepareRouteUpdate(); this.prepareRouteUpdate();
} }
}else{ } else {
this.routingTable[toID] = {interf:interf,cost:cost + interf.getBaseRoutingCost(),rep: rep}; this.routingTable[toID] = {interf: interf, cost: cost + interf.getBaseRoutingCost(), rep: rep};
this.onNewNeigborTrigger.trigger(toID); this.onNewNeigborTrigger.trigger(toID);
this.prepareRouteUpdate(); this.prepareRouteUpdate();
} }
} }
public function getRouteToID(networkID:NetworkID):{interf: INetworkInterface, rep: NetworkID} { public function getRouteToID(networkID:NetworkID):{interf:INetworkInterface, rep:NetworkID} {
if (networkID == Net.instance.networkID) { if (networkID == Net.instance.networkID) {
return {interf: Loopback.instance,rep: Net.instance.networkID}; return {interf: Loopback.instance, rep: Net.instance.networkID};
} }
var route = this.routingTable[networkID]; var route:Null<Route> = this.routingTable[networkID];
if (route == null){ if (route == null) {
return null; return null;
}else{ } else {
return {interf: route.interf,rep: route.rep}; return {interf: route.interf, rep: route.rep};
} }
} }