From 2a51243efb01a0e27ac022ac279651e7e71526dc Mon Sep 17 00:00:00 2001 From: "Selby, Nicholas Stearns" <nselby3@gatech.edu> Date: Mon, 20 Nov 2017 15:49:03 -0500 Subject: [PATCH] Simulation can send messages to non-neighboring nodes and learn best paths. TODO: incorporate buffer, heartbeat, and disconnect reaction --- sim/manager.js | 142 +++++++++++++++++++++++++++++-------------------- sim/sim.js | 10 ++-- 2 files changed, 91 insertions(+), 61 deletions(-) diff --git a/sim/manager.js b/sim/manager.js index 8b64457..ac6d2e1 100644 --- a/sim/manager.js +++ b/sim/manager.js @@ -13,14 +13,6 @@ function Manager(self) { this.maxBufferSize = 252; this.seenFloods = []; - this.checkBuffer = function() { - console.log(`about to check buffer of node ${self.id}`); - if (this.buffer.length > 0) { - this.handlePacket(this.buffer.shift()); - } -// console.log(`checked buffer of node ${self.id}`); - }; - this.setup = function(numports) { this.numports = numports; this.ports = new Array(numports).fill(-1); @@ -33,7 +25,7 @@ function Manager(self) { }; this.printPorts = function() { -// console.log(this.ports); +// self.log(this.ports); }; this.connect = function(port, id) { @@ -47,7 +39,7 @@ function Manager(self) { self.disconnect(prevId); } -// console.log('im '+ self.id + ' connecting to ' + id); +// self.log('im '+ self.id + ' connecting to ' + id); this.ports[port] = id; self.connect(id); @@ -82,6 +74,15 @@ function Manager(self) { self.log(`got message '${o.name}' on port ${port}: '${o.obj}'`); }; + this.checkBuffer = function() { +// self.log(`about to check buffer of node ${self.id}`); +// self.log(this.buffer); + if (this.buffer.length > 0) { + this.handlePacket(this.buffer.shift()); + } +// self.log(`checked buffer of node ${self.id}`); + }; + this.sendPacket = function(start, dest=-1, hopcount=0, src=self.id, size=0, data=null, port=-1) { var packet = { start: start, @@ -92,12 +93,12 @@ function Manager(self) { data: data, port: port }; - + if (port === -1) { this.handlePacket(packet); return; } - self.log(`checkpoint`); + if (port < this.numports && this.ports[port] >= 0) { self.send(this.ports[port], 'packet', {name: 'packet', obj: packet}); } @@ -109,6 +110,7 @@ function Manager(self) { return; var packet = o.obj; + packet.port = port; if (this.buffer.length < this.maxBufferSize) { this.buffer.push(packet); @@ -121,65 +123,76 @@ function Manager(self) { && packet.src!==self.id // ...or a packet from me && (!this.addr_table[packet.port].dests.hasOwnProperty(packet.src) || this.addr_table[packet.port].dests[packet.src]!==packet.hopcount) ) { // ...and my entry for the source is invalid this.addr_table[packet.port].dests[packet.src] = packet.hopcount; +// self.log(`added ${packet.src} to its LUT under port ${packet.port}`); } if (packet.start === STD) { // Standard Packet if (packet.dest === self.id) { // If I am destination - self.log(`${self.id} got message ${packet.data}`); - const nextPort = getMinCostPort(packet.src); // Pick the port to send ACK based off minimizing cost + const nextPort = this.getMinCostPort(packet.src); // Pick the port to send ACK based off minimizing cost + self.log(`got message ${packet.data}. ACKing port ${nextPort}`); this.sendPacket(ACK, packet.src, 0, self.id, nextPort); } else { packet.hopcount++; // Increment hopcount - const nextPort = getMinCostPort(packet.dest); // Pick the port to send to based off minimizing cost + const nextPort = this.getMinCostPort(packet.dest); // Pick the port to send to based off minimizing cost if (nextPort === -1) { // If LUT does not have dest - for (var p = 0; p < this.numports; p++) { // Flood packet - if (p !== packet.port) + self.log(`flooding message ${packet.data}`); + for (let p = 0; p < this.numports; p++) { // Flood packet + if (p !== packet.port) { this.sendPacket(STF, packet.dest, packet.hopcount, packet.src, packet.size, packet.data, p); + } } } else { // If LUT does have dest, send to that port + self.log(`sending packet ${packet.data}`); this.sendPacket(STD, packet.dest, packet.hopcount, packet.src, packet.size, packet.data, nextPort); } } } else if (packet.start === ACK) { // Acknowledgement if (packet.dest === self.id) { // If I am destination - self.log(`${self.id} got ACK from ${packet.src}`); + self.log(`got ACK from ${packet.src}`); } else { packet.hopcount++; // Increment hopcount - const nextPort = getMinCostPort(packet.dest); // Pick the port to send to based off minimizing cost + const nextPort = this.getMinCostPort(packet.dest); // Pick the port to send to based off minimizing cost if (nextPort === -1) { // If LUT does not have dest - for (var p = 0; p < this.numports; p++) { // Flood ACK + self.log(`flooding ACK`); + for (let p = 0; p < this.numports; p++) { // Flood ACK if (p !== packet.port) this.sendPacket(ACF, packet.dest, packet.hopcount, packet.src, 0, null, p); } } else { // If LUT does have dest, send to that port + self.log(`forwarding ACK`); this.sendPacket(ACK, packet.dest, packet.hopcount, packet.src, 0, null, nextPort); } } } else if (packet.start === STF) { // Standard Flood if (this.addr_table[packet.port].dests.hasOwnProperty(packet.dest)) // If I thought this port could send to destination, remove it delete this.addr_table[packet.port].dests[packet.dest]; // ...if that node had known, it wouldn't have forwarded it as a flood. - if (this.seenFloods.includes(thisFlood)) // If I have seen it before, don't forward + const thisFlood = { // Static information within packet for comparison + dest: packet.dest, + src: packet.src, + data: packet.data + }; + if (this.hasSeen(thisFlood)) { // If I have seen it before, don't forward + self.log(`not forwarding ${packet.data} from port ${packet.port}`); return; + } + this.seenFloods.push(thisFlood); // Remember the packet if (packet.dest === self.id) { // If I am destination - self.log(`${self.id} got message ${packet.data}`); - const nextPort = getMinCostPort(packet.src); // Pick the port to send ACK based off minimizing cost + const nextPort = this.getMinCostPort(packet.src); // Pick the port to send ACK based off minimizing cost + self.log(`got flood ${packet.data} from port ${packet.port}. ACKing ${packet.src} along port ${nextPort}`); this.sendPacket(ACK, packet.src, 0, self.id, nextPort); } else { packet.hopcount++; // Increment hopcount - const thisFlood = { // Static information within packet for comparison - dest: packet.dest, - src: packet.src, - data: packet.data - }; - this.seenFloods.push(thisFlood); // Remember the packet - const nextPort = getMinCostPort(packet.dest); // Pick the port to send to based off minimizing cost + const nextPort = this.getMinCostPort(packet.dest); // Pick the port to send to based off minimizing cost if (nextPort === -1) { // If LUT does not have dest - for (var p = 0; p < this.numports; p++) { // Flood packet - if (p !== packet.port) + self.log(`flooding message ${packet.data} to all ports except ${packet.port}`); + for (let p = 0; p < this.numports; p++) { // Flood packet + if (p !== packet.port) { this.sendPacket(STF, packet.dest, packet.hopcount, packet.src, packet.size, packet.data, p); + } } } else { // If LUT does have dest, send to that port + self.log(`forwarding message ${packet.data}`); this.sendPacket(STD, packet.dest, packet.hopcount, packet.src, packet.size, packet.data, nextPort); } } @@ -187,25 +200,27 @@ function Manager(self) { if (this.addr_table[packet.port].dests.hasOwnProperty(packet.dest)) // If I thought this port could send to destination, remove it delete this.addr_table[packet.port].dests[packet.dest]; // ...if that node had known, it wouldn't have forwarded it as a flood. if (packet.dest === self.id) { // If I am destination - self.log(`${self.id} got ACK from ${packet.src}`); + self.log(`got ACK from ${packet.src}`); } else { packet.hopcount++; // Increment hopcount - const thisFlood = { // Static information within packet for comparison - dest: packet.dest, - src: packet.src, - data: null - }; - if (this.seenFloods.includes(thisFlood)) // If I have seen it before, don't forward - return; - this.seenFloods.push(thisFlood); // Remember the packet +// const thisFlood = { // Static information within packet for comparison +// dest: packet.dest, +// src: packet.src, +// data: null +// }; +// if (this.seenFloods.includes(thisFlood)) // If I have seen it before, don't forward +// return; +// this.seenFloods.push(thisFlood); // Remember the packet - const nextPort = getMinCostPort(packet.dest); // Pick the port to send to based off minimizing cost + const nextPort = this.getMinCostPort(packet.dest); // Pick the port to send to based off minimizing cost if (nextPort === -1) { // If LUT does not have dest - for (var p = 0; p < this.numports; p++) { // Flood ACK + self.log(`flooding ACK`); + for (let p = 0; p < this.numports; p++) { // Flood ACK if (p !== packet.port) this.sendPacket(ACF, packet.dest, packet.hopcount, packet.src, 0, null, p); } } else { // If LUT does have dest, send to that port + self.log(`forwarding ACK`); this.sendPacket(ACK, packet.dest, packet.hopcount, packet.src, 0, null, nextPort); } } @@ -214,26 +229,37 @@ function Manager(self) { } }; + this.getMinCostPort = function(dest) { + var minCost = Infinity; + var minPort = -1; + for (let p = 0; p < this.numports; p++) { + if (this.addr_table[p].dests.hasOwnProperty(dest)) { + var cost = getCost(this.addr_table[p].dests[dest], this.addr_table[p].buff); + if (cost<minCost) { + minCost = cost; + minPort = p; + } + } + } + return minPort; + }; + + this.hasSeen = function(packet) { + for (let p = 0; p < this.seenFloods.length; p++) { + if (this.seenFloods[p].dest === packet.dest + && this.seenFloods[p].src === packet.src + && this.seenFloods[p].data === packet.data) { + return true; + } + } + return false; + }; + self.on('message', this.onReceive, this); self.on('packet', this.onReceivePacket, this); } -function getMinCostPort(dest) { - var minCost = Infinity; - var minPort = -1; - for (var p = 0; p < this.numports; p++) { - if (this.addr_table[p].dests.hasOwnProperty(dest)) { - var cost = getCost(this.addr_table[p].dests[dest], this.addr_table[p].buff); - if (cost<minCost) { - minCost = cost; - minPort = p; - } - } - } - return minPort; -}; - function getCost(hopcount, buffer) { return hopcount + buffer/2; } diff --git a/sim/sim.js b/sim/sim.js index de11ce3..50c7c76 100755 --- a/sim/sim.js +++ b/sim/sim.js @@ -7,8 +7,11 @@ const bufferCheckDelay = 1000; // INITIALIZE NETWORK TOPOLOGY HERE var initTopology = [ - [0], - [1] + [1,2], + [0,3], + [0,4], + [1,4], + [3,2] ]; // Don't touch this code @@ -52,7 +55,8 @@ for (let i = 0; i < initTopology.length; i++) { //disconnect(0, 1, 2, 2, 1700); //send(2, 2, 'You cannot see this cause we are not connected', 2000); //send(2, 0, 'we are friends now', 2500); -sendPacket(0,1,1,"Hello 1!",0); +sendPacket(0,4,1,"Hello Four!",1000); +sendPacket(0,4,1,"I love you, Four!",6000) //Don't add stuff below this: -- GitLab