Forwarding and TTL
This commit is contained in:
		
							parent
							
								
									d65b06a9b4
								
							
						
					
					
						commit
						eb43c51e50
					
				@ -22,6 +22,7 @@ class Net {
 | 
				
			|||||||
	public static var instance:Net;
 | 
						public static var instance:Net;
 | 
				
			||||||
	public static inline final BRODCAST_PORT:Int = 65533;
 | 
						public static inline final BRODCAST_PORT:Int = 65533;
 | 
				
			||||||
	public static inline final MESSAGE_TIMEOUT:Int = 3;
 | 
						public static inline final MESSAGE_TIMEOUT:Int = 3;
 | 
				
			||||||
 | 
						public static inline final DEFAULT_TTL:Int = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public final networkID:NetworkID = OS.getComputerID();
 | 
						public final networkID:NetworkID = OS.getComputerID();
 | 
				
			||||||
	private final responseBus:Map<Int, Callback<Package>> = new Map();
 | 
						private final responseBus:Map<Int, Callback<Package>> = new Map();
 | 
				
			||||||
@ -48,18 +49,23 @@ class Net {
 | 
				
			|||||||
		Called when a new package comes in.
 | 
							Called when a new package comes in.
 | 
				
			||||||
	**/
 | 
						**/
 | 
				
			||||||
	private function handle(pack:Package,interf: INetworkInterface) {
 | 
						private function handle(pack:Package,interf: INetworkInterface) {
 | 
				
			||||||
		switch pack.type {
 | 
							if (pack.toID == this.networkID || pack.toID == Net.BRODCAST_PORT){
 | 
				
			||||||
			case Data(_) | DataNoResponse(_):
 | 
								switch pack.type {
 | 
				
			||||||
				// Let a local proccess handle it
 | 
									case Data(_) | DataNoResponse(_):
 | 
				
			||||||
				routeToProto(pack);
 | 
										// Let a local proccess handle it
 | 
				
			||||||
			case Response:
 | 
										routeToProto(pack);
 | 
				
			||||||
				// Got a response to a send message. Invoke the callback
 | 
									case Response:
 | 
				
			||||||
				if (responseBus.exists(pack.msgID)) {
 | 
										// Got a response to a send message. Invoke the callback
 | 
				
			||||||
					responseBus[pack.msgID].invoke(pack);
 | 
										if (responseBus.exists(pack.msgID)) {
 | 
				
			||||||
				}
 | 
											responseBus[pack.msgID].invoke(pack);
 | 
				
			||||||
			case RouteDiscover(_) | RouteDiscoverResponse(_):
 | 
										}
 | 
				
			||||||
				// Delegate to Routing
 | 
									case RouteDiscover(_) | RouteDiscoverResponse(_):
 | 
				
			||||||
				Routing.instance.handleRoutePackage(pack,interf);
 | 
										// Delegate to Routing
 | 
				
			||||||
 | 
										Routing.instance.handleRoutePackage(pack,interf);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}else{
 | 
				
			||||||
 | 
								// New message received but its not ment for us. Forward if possible.
 | 
				
			||||||
 | 
								forwardPackage(pack);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -76,12 +82,26 @@ class Net {
 | 
				
			|||||||
			fromID: networkID,
 | 
								fromID: networkID,
 | 
				
			||||||
			msgID: generateMessageID(),
 | 
								msgID: generateMessageID(),
 | 
				
			||||||
			type: DataNoResponse(proto),
 | 
								type: DataNoResponse(proto),
 | 
				
			||||||
			data: data
 | 
								data: data,
 | 
				
			||||||
 | 
								ttl: Net.DEFAULT_TTL,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		sendRaw(pack);
 | 
							sendRaw(pack);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private function forwardPackage(pack: Package) {
 | 
				
			||||||
 | 
							if (pack.ttl == 0){
 | 
				
			||||||
 | 
								// Drop package
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							pack.ttl--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (sendRaw(pack)){
 | 
				
			||||||
 | 
								// Cant forward
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function respondTo(pack:Package, data:Dynamic) {
 | 
						public function respondTo(pack:Package, data:Dynamic) {
 | 
				
			||||||
		if (pack.type.match(DataNoResponse(_))) {
 | 
							if (pack.type.match(DataNoResponse(_))) {
 | 
				
			||||||
			Log.warn("Responed to a no response package. Ignoring");
 | 
								Log.warn("Responed to a no response package. Ignoring");
 | 
				
			||||||
@ -97,16 +117,17 @@ class Net {
 | 
				
			|||||||
		Send to package to the localy register handler based on the proto
 | 
							Send to package to the localy register handler based on the proto
 | 
				
			||||||
	**/
 | 
						**/
 | 
				
			||||||
	private function routeToProto(pack:Package) {
 | 
						private function routeToProto(pack:Package) {
 | 
				
			||||||
		var proto:String = switch pack.type {
 | 
							var proto = switch pack.type {
 | 
				
			||||||
			case Data(proto):
 | 
								case Data(proto):
 | 
				
			||||||
				proto;
 | 
									proto;
 | 
				
			||||||
			case DataNoResponse(proto):
 | 
								case DataNoResponse(proto):
 | 
				
			||||||
				proto;
 | 
									proto;
 | 
				
			||||||
			case _:
 | 
								default:
 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!protoHandlers.exists(proto) && protoHandlers[proto] != null) {
 | 
							if (!protoHandlers.exists(proto)) {
 | 
				
			||||||
 | 
								Log.warn("Trying to route package to proto: \"" + proto + "\" but nothing was register");
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -115,24 +136,30 @@ class Net {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
		Just send the package to the right modem.
 | 
							Just send the package to the right modem.
 | 
				
			||||||
 | 
							Returns true if message was send
 | 
				
			||||||
	**/
 | 
						**/
 | 
				
			||||||
	private function sendRaw(pack:Package) {
 | 
						private function sendRaw(pack:Package): Bool {
 | 
				
			||||||
 | 
							var route = Routing.instance.getRouteToID(pack.toID);
 | 
				
			||||||
 | 
							if (route == null){
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Routing.instance.getIterfaceToId(pack.toID).send(pack.toID,pack.fromID,pack);
 | 
							route.interf.send(route.rep,this.networkID,pack);
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
		Send a message and wait for a response.
 | 
							Send a message and wait for a response.
 | 
				
			||||||
	**/
 | 
						**/
 | 
				
			||||||
	public function sendAndAwait(dest:NetworkID, proto:String, data:Dynamic):Promise<Package> {
 | 
						public function sendAndAwait(dest:NetworkID, proto:String, data:Dynamic):Promise<Package> {
 | 
				
			||||||
 | 
					 | 
				
			||||||
		return new Promise<Package>((resolve, reject) -> {
 | 
							return new Promise<Package>((resolve, reject) -> {
 | 
				
			||||||
			var pack:Package = {
 | 
								var pack:Package = {
 | 
				
			||||||
				toID: dest,
 | 
									toID: dest,
 | 
				
			||||||
				fromID: networkID,
 | 
									fromID: networkID,
 | 
				
			||||||
				msgID: generateMessageID(),
 | 
									msgID: generateMessageID(),
 | 
				
			||||||
				type: Data(proto),
 | 
									type: Data(proto),
 | 
				
			||||||
				data: data
 | 
									data: data,
 | 
				
			||||||
 | 
									ttl: Net.DEFAULT_TTL,
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var timeout:Timer = null;
 | 
								var timeout:Timer = null;
 | 
				
			||||||
@ -149,7 +176,9 @@ class Net {
 | 
				
			|||||||
				reject(new Error(InternalError,"Message timeout"));
 | 
									reject(new Error(InternalError,"Message timeout"));
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sendRaw(pack);
 | 
								if (!sendRaw(pack)){
 | 
				
			||||||
 | 
									reject(new Error("ID unreachable"));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// No callback link for you
 | 
								// No callback link for you
 | 
				
			||||||
			return null;
 | 
								return null;
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,7 @@ enum PackageTypes {
 | 
				
			|||||||
	public final msgID:Int;
 | 
						public final msgID:Int;
 | 
				
			||||||
	public final type:PackageTypes;
 | 
						public final type:PackageTypes;
 | 
				
			||||||
	public final data:Dynamic;
 | 
						public final data:Dynamic;
 | 
				
			||||||
 | 
						public var ttl: Int;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
		Parse package from an `modem_message` event.
 | 
							Parse package from an `modem_message` event.
 | 
				
			||||||
@ -32,6 +33,7 @@ enum PackageTypes {
 | 
				
			|||||||
			msgID: payload.msgID,
 | 
								msgID: payload.msgID,
 | 
				
			||||||
			type: payload.type,
 | 
								type: payload.type,
 | 
				
			||||||
			data: payload.data,
 | 
								data: payload.data,
 | 
				
			||||||
 | 
								ttl: payload.ttl,
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -44,7 +46,8 @@ enum PackageTypes {
 | 
				
			|||||||
			fromID: toID,
 | 
								fromID: toID,
 | 
				
			||||||
			msgID: msgID,
 | 
								msgID: msgID,
 | 
				
			||||||
			type: Response,
 | 
								type: Response,
 | 
				
			||||||
			data: newData
 | 
								data: newData,
 | 
				
			||||||
 | 
								ttl: Net.DEFAULT_TTL,
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,7 @@ import kernel.net.Package.NetworkID;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@:structInit typedef Route = {
 | 
					@:structInit typedef Route = {
 | 
				
			||||||
	interf:INetworkInterface,
 | 
						interf:INetworkInterface,
 | 
				
			||||||
 | 
						rep: NetworkID,
 | 
				
			||||||
	cost:Int
 | 
						cost:Int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -33,7 +34,7 @@ class Routing {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	@:allow(kernel.Init)
 | 
						@:allow(kernel.Init)
 | 
				
			||||||
	private function init() {
 | 
						private function init() {
 | 
				
			||||||
		routingTable.set(Net.instance.networkID,{interf: Loopback.instance,cost:0});
 | 
							routingTable.set(Net.instance.networkID,{interf: Loopback.instance,cost:0,rep:Net.instance.networkID});
 | 
				
			||||||
		for (modem in Peripheral.instance.getModems()) {
 | 
							for (modem in Peripheral.instance.getModems()) {
 | 
				
			||||||
			modem.send(Net.BRODCAST_PORT, Net.instance.networkID, newRoutDiscoverPackage());
 | 
								modem.send(Net.BRODCAST_PORT, Net.instance.networkID, newRoutDiscoverPackage());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -43,17 +44,17 @@ class Routing {
 | 
				
			|||||||
		Handle incomming packages that involve route discovery.
 | 
							Handle incomming packages that involve route discovery.
 | 
				
			||||||
	**/
 | 
						**/
 | 
				
			||||||
	public function handleRoutePackage(pack:Package, interf:INetworkInterface):Void {
 | 
						public function handleRoutePackage(pack:Package, interf:INetworkInterface):Void {
 | 
				
			||||||
		addPossibleRoute(pack.fromID,interf,0);
 | 
							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);
 | 
										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);
 | 
										addPossibleRoute(route.id,interf,route.cost,pack.fromID);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				true;
 | 
									true;
 | 
				
			||||||
			default:
 | 
								default:
 | 
				
			||||||
@ -71,7 +72,8 @@ class Routing {
 | 
				
			|||||||
			fromID: Net.instance.networkID,
 | 
								fromID: Net.instance.networkID,
 | 
				
			||||||
			msgID: null,
 | 
								msgID: null,
 | 
				
			||||||
			type: RouteDiscoverResponse(genRouteList()),
 | 
								type: RouteDiscoverResponse(genRouteList()),
 | 
				
			||||||
			data: null
 | 
								data: null,
 | 
				
			||||||
 | 
								ttl: 0, // Prevent forwarding
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		interf.send(response.toID,Net.instance.networkID,response);
 | 
							interf.send(response.toID,Net.instance.networkID,response);
 | 
				
			||||||
@ -95,6 +97,7 @@ class Routing {
 | 
				
			|||||||
			msgID: null,
 | 
								msgID: null,
 | 
				
			||||||
			fromID: Net.instance.networkID,
 | 
								fromID: Net.instance.networkID,
 | 
				
			||||||
			data: null,
 | 
								data: null,
 | 
				
			||||||
 | 
								ttl: 0, // Prevent forwarding
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return pack;
 | 
							return pack;
 | 
				
			||||||
@ -104,7 +107,7 @@ 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) {
 | 
						private function addPossibleRoute(toID:Int, interf:INetworkInterface, cost:Int, rep: NetworkID) {
 | 
				
			||||||
		if (toID == Net.instance.networkID){
 | 
							if (toID == Net.instance.networkID){
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -114,20 +117,26 @@ class Routing {
 | 
				
			|||||||
		if (this.routingTable.exists(toID)){
 | 
							if (this.routingTable.exists(toID)){
 | 
				
			||||||
			if (this.routingTable[toID].cost > fullCost){
 | 
								if (this.routingTable[toID].cost > fullCost){
 | 
				
			||||||
				Log.info("Better route: " + toID + " -> " + interf.name() + ":$"+fullCost);
 | 
									Log.info("Better route: " + toID + " -> " + interf.name() + ":$"+fullCost);
 | 
				
			||||||
				this.routingTable[toID] = {interf:interf,cost:cost + interf.getBaseRoutingCost()};
 | 
									this.routingTable[toID] = {interf:interf,cost:cost + interf.getBaseRoutingCost(),rep: rep};
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}else{
 | 
							}else{
 | 
				
			||||||
			this.routingTable[toID] = {interf:interf,cost:cost + interf.getBaseRoutingCost()};
 | 
								this.routingTable[toID] = {interf:interf,cost:cost + interf.getBaseRoutingCost(),rep: rep};
 | 
				
			||||||
			Log.info("New route: " + toID + " -> " + interf.name() + ":$"+fullCost);
 | 
								Log.info("New route: " + toID + " -> " + interf.name() + ":$"+fullCost);
 | 
				
			||||||
			this.onNewNeigborTrigger.trigger(toID);
 | 
								this.onNewNeigborTrigger.trigger(toID);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function getIterfaceToId(networkID:NetworkID):INetworkInterface {
 | 
						public function getRouteToID(networkID:NetworkID):{interf: INetworkInterface, rep: NetworkID} {
 | 
				
			||||||
		if (networkID == Net.instance.networkID) {
 | 
							if (networkID == Net.instance.networkID) {
 | 
				
			||||||
			return Loopback.instance;
 | 
								return {interf: Loopback.instance,rep: Net.instance.networkID};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return null;
 | 
							var route = this.routingTable[networkID];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (route == null){
 | 
				
			||||||
 | 
								return null;
 | 
				
			||||||
 | 
							}else{
 | 
				
			||||||
 | 
								return {interf: route.interf,rep: route.rep};
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -26,6 +26,7 @@ class Modem implements INetworkInterface implements IPeripheral {
 | 
				
			|||||||
					msgID: params.message.msgID,
 | 
										msgID: params.message.msgID,
 | 
				
			||||||
					type: params.message.type,
 | 
										type: params.message.type,
 | 
				
			||||||
					data: params.message.data,
 | 
										data: params.message.data,
 | 
				
			||||||
 | 
										ttl: params.message.ttl,
 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				this.onMessageTrigger.trigger(pack);
 | 
									this.onMessageTrigger.trigger(pack);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user