Forwarding and TTL

This commit is contained in:
Djeeberjr 2022-03-01 16:59:53 +01:00
parent d65b06a9b4
commit eb43c51e50
4 changed files with 75 additions and 33 deletions

View File

@ -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,6 +49,7 @@ 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) {
if (pack.toID == this.networkID || pack.toID == Net.BRODCAST_PORT){
switch pack.type { switch pack.type {
case Data(_) | DataNoResponse(_): case Data(_) | DataNoResponse(_):
// Let a local proccess handle it // Let a local proccess handle it
@ -61,6 +63,10 @@ class Net {
// Delegate to Routing // Delegate to Routing
Routing.instance.handleRoutePackage(pack,interf); Routing.instance.handleRoutePackage(pack,interf);
} }
}else{
// New message received but its not ment for us. Forward if possible.
forwardPackage(pack);
}
} }
private function generateMessageID():Int { private function generateMessageID():Int {
@ -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;

View File

@ -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,
}; };
} }

View File

@ -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};
} }
var route = this.routingTable[networkID];
if (route == null){
return null; return null;
}else{
return {interf: route.interf,rep: route.rep};
}
} }
} }

View File

@ -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);