improved Routing
This commit is contained in:
		
							parent
							
								
									45a8851e2a
								
							
						
					
					
						commit
						f988c79e2f
					
				@ -8,7 +8,7 @@ using tink.CoreApi;
 | 
			
		||||
 | 
			
		||||
@:structInit typedef Route = {
 | 
			
		||||
	interf:INetworkInterface,
 | 
			
		||||
	rep: NetworkID,
 | 
			
		||||
	rep:NetworkID,
 | 
			
		||||
	cost:Int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -21,13 +21,13 @@ class 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>;
 | 
			
		||||
 | 
			
		||||
	private final onNewNeigborTrigger:SignalTrigger<NetworkID> = Signal.trigger();
 | 
			
		||||
	private final routingTable:Map<NetworkID, Route> = new Map();
 | 
			
		||||
	private var routeUpdateInQueue: Bool = false;
 | 
			
		||||
	private var routeUpdateInQueue:Bool = false;
 | 
			
		||||
 | 
			
		||||
	@:allow(kernel.Init)
 | 
			
		||||
	private function new() {
 | 
			
		||||
@ -36,38 +36,35 @@ class Routing {
 | 
			
		||||
 | 
			
		||||
	@:allow(kernel.Init)
 | 
			
		||||
	private function init() {
 | 
			
		||||
		routingTable.set(Net.instance.networkID,{interf: Loopback.instance,cost:0,rep:Net.instance.networkID});
 | 
			
		||||
		for (modem in Peripheral.instance.getModems()) {
 | 
			
		||||
			modem.send(Net.BRODCAST_PORT, Net.instance.networkID, newRoutDiscoverPackage());
 | 
			
		||||
		}
 | 
			
		||||
		routingTable.set(Net.instance.networkID, {interf: Loopback.instance, cost: 0, rep: Net.instance.networkID});
 | 
			
		||||
		brodcastRoutingTable();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		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() {
 | 
			
		||||
		if (this.routeUpdateInQueue){
 | 
			
		||||
		if (this.routeUpdateInQueue) {
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.routeUpdateInQueue = true;
 | 
			
		||||
 | 
			
		||||
		new Timer(UPDATE_WAIT_TIME,()->{
 | 
			
		||||
			brodcastUpdatedRoutes();
 | 
			
		||||
		new Timer(UPDATE_WAIT_TIME, () -> {
 | 
			
		||||
			brodcastRoutingTable();
 | 
			
		||||
			this.routeUpdateInQueue = false;
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private function brodcastUpdatedRoutes() {
 | 
			
		||||
		var pack: Package = {
 | 
			
		||||
			type: RouteDiscoverUpdate(genRouteList()),
 | 
			
		||||
			toID: Net.BRODCAST_PORT,
 | 
			
		||||
			msgID: null,
 | 
			
		||||
			fromID: Net.instance.networkID,
 | 
			
		||||
			data: null,
 | 
			
		||||
			ttl: 0, // Prevent forwarding
 | 
			
		||||
		};
 | 
			
		||||
	/**
 | 
			
		||||
		Brodcast the current routing table to all peers.
 | 
			
		||||
	**/
 | 
			
		||||
	private function brodcastRoutingTable() {
 | 
			
		||||
		var pack = newRoutDiscoverPackage();
 | 
			
		||||
 | 
			
		||||
		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)
 | 
			
		||||
	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):
 | 
			
		||||
				for (route in routes) {
 | 
			
		||||
					addPossibleRoute(route.id,interf,route.cost,pack.fromID);
 | 
			
		||||
					addPossibleRoute(route.id, interf, route.cost, pack.fromID);
 | 
			
		||||
				}
 | 
			
		||||
				false;
 | 
			
		||||
			case RouteDiscover(routes):
 | 
			
		||||
				for (route in routes) {
 | 
			
		||||
					addPossibleRoute(route.id,interf,route.cost,pack.fromID);
 | 
			
		||||
					addPossibleRoute(route.id, interf, route.cost, pack.fromID);
 | 
			
		||||
				}
 | 
			
		||||
				true;
 | 
			
		||||
			case RouteDiscoverUpdate(routes):
 | 
			
		||||
				for (route in routes) {
 | 
			
		||||
					addPossibleRoute(route.id,interf,route.cost,pack.fromID);
 | 
			
		||||
					addPossibleRoute(route.id, interf, route.cost, pack.fromID);
 | 
			
		||||
				}
 | 
			
		||||
				false;
 | 
			
		||||
			default:
 | 
			
		||||
@ -99,7 +96,7 @@ class Routing {
 | 
			
		||||
				false;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		if (!shouldRespond){
 | 
			
		||||
		if (!shouldRespond) {
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -113,12 +110,15 @@ class Routing {
 | 
			
		||||
			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}> = [];
 | 
			
		||||
		for (k => v in this.routingTable){
 | 
			
		||||
	/**
 | 
			
		||||
		Generate a list of routes to send to a peer based on the current routing table.
 | 
			
		||||
	**/
 | 
			
		||||
	private function genRouteList():Array<{id:NetworkID, cost:Int}> {
 | 
			
		||||
		var routes:Array<{id:NetworkID, cost:Int}> = [];
 | 
			
		||||
		for (k => v in this.routingTable) {
 | 
			
		||||
			routes.push({
 | 
			
		||||
				id: k,
 | 
			
		||||
				cost: v.cost
 | 
			
		||||
@ -144,36 +144,36 @@ class Routing {
 | 
			
		||||
		Called when a route to a client has been disoverd.
 | 
			
		||||
		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) {
 | 
			
		||||
		if (toID == Net.instance.networkID){
 | 
			
		||||
	private function addPossibleRoute(toID:Int, interf:INetworkInterface, cost:Int, rep:NetworkID) {
 | 
			
		||||
		if (toID == Net.instance.networkID) {
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var fullCost = cost+interf.getBaseRoutingCost();
 | 
			
		||||
		var fullCost = cost + interf.getBaseRoutingCost();
 | 
			
		||||
 | 
			
		||||
		if (this.routingTable.exists(toID)){
 | 
			
		||||
			if (this.routingTable[toID].cost > fullCost){
 | 
			
		||||
				this.routingTable[toID] = {interf:interf,cost:cost + interf.getBaseRoutingCost(),rep: rep};
 | 
			
		||||
		if (this.routingTable.exists(toID)) {
 | 
			
		||||
			if (this.routingTable[toID].cost > fullCost) {
 | 
			
		||||
				this.routingTable[toID] = {interf: interf, cost: cost + interf.getBaseRoutingCost(), rep: rep};
 | 
			
		||||
				this.prepareRouteUpdate();
 | 
			
		||||
			}
 | 
			
		||||
		}else{
 | 
			
		||||
			this.routingTable[toID] = {interf:interf,cost:cost + interf.getBaseRoutingCost(),rep: rep};
 | 
			
		||||
		} else {
 | 
			
		||||
			this.routingTable[toID] = {interf: interf, cost: cost + interf.getBaseRoutingCost(), rep: rep};
 | 
			
		||||
			this.onNewNeigborTrigger.trigger(toID);
 | 
			
		||||
			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) {
 | 
			
		||||
			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;
 | 
			
		||||
		}else{
 | 
			
		||||
			return {interf: route.interf,rep: route.rep};
 | 
			
		||||
		} else {
 | 
			
		||||
			return {interf: route.interf, rep: route.rep};
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user