Skip to content
Snippets Groups Projects
Commit 085b66ab authored by Selby, Nicholas Stearns's avatar Selby, Nicholas Stearns
Browse files

Packet handling

parent d0acb5fa
Branches
No related tags found
No related merge requests found
function Manager(self) {
self.manager = this;
const STD = 252;
const ACK = 253;
const STF = 254;
const ACF = 255;
this.ports = [];
this.numports = 0;
this.addr_table = {};
this.buffer = [];
this.maxBufferSize = 252;
this.delay = 100; //ms
this.seenFloods = [];
this.setup = function(numports) {
this.numports = numports;
this.ports = new Array(numports).fill(-1);
for (var p = 0; p < numports; p++) {
this.addr_table[p] = {
dests: {},
buff: 0
};
}
setInterval(this.checkBuffer, this.delay);
};
this.printPorts = function() {
console.log(this.ports);
}
};
this.connect = function(port, id) {
if (!(port < this.numports)) {
if (!(port < this.numports))
return;
}
if (self.id != id) {
if (self.id !== id) {
var prevId = this.ports[port];
if (prevId >= 0) {
self.disconnect(prevId);
......@@ -35,6 +45,7 @@ function Manager(self) {
this.ports[port] = id;
self.connect(id);
}
};
this.disconnect = function(port) {
......@@ -48,7 +59,7 @@ function Manager(self) {
}
this.ports[port] = -1;
}
};
this.send = function(port, msg) {
if (port < this.numports && this.ports[port] >= 0) {
......@@ -58,25 +69,25 @@ function Manager(self) {
this.onReceive = function(from, o) {
var port = this.ports.indexOf(from);
if (port == -1) {
if (port === -1) {
return;
}
self.log(`got message '${o.name}' on port ${port}: '${o.obj}'`);
};
this.sendPacket = function(dest, size, data, edges=0, port=-1, src=self.id, ack=false) {
this.sendPacket = function(start, dest=-1, hopcount=0, src=self.id, size=0, data=null, port=-1) {
var packet = {
ack: ack,
start: start,
dest: dest,
edges: edges,
hopcount: hopcount,
src: src,
size: size,
data: data
data: data,
port: port
};
if (port == -1) {
if (port === -1) {
this.handlePacket(packet);
return;
}
......@@ -88,62 +99,137 @@ function Manager(self) {
this.onReceivePacket = function(from, o) {
var port = this.ports.indexOf(from);
if (port == -1) {
if (port === -1)
return;
}
var packet = o.obj;
if (this.buffer.length < this.maxBufferSize) {
this.buffer.push(packet);
}
};
this.checkBuffer = function() {
if (this.buffer.length > 0) {
let packet = this.buffer.shift();
packet.edges += 1;
this.handlePacket(this.buffer.shift());
}
};
if (!this.addr_table.hasOwnProperty(packet.src)) {
this.addr_table[packet.src] = new Array(numports).fill(Infinity);
this.addr_table[packet.src][port] = packet.edges;
} else {
if (packet.edges < this.addr_table[packet.src][port]) {
this.addr_table[packet.src][port] = packet.edges;
this.handlePacket = function(packet) {
// If LUT does not already have the source address, add the entry
if (packet.start === STD || packet.start === ACK || packet.start === STF || packet.start === ACF) {
if (!this.addr_table[packet.port].dests.hasOwnProperty(packet.src) || this.addr_table[packet.port].dests[packet.src]>packet.hopcount) {
this.addr_table[packet.port].dests[packet.src] = packet.hopcount;
}
}
this.handlePacket(packet);
if (packet.start === STD) { // Standard Packet
if (packet.dest === self.id) { // If I am destination
// Process packet
} else {
packet.hopcount++; // Increment hopcount
const nextPort = 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)
this.sendPacket(STF, packet.dest, packet.hopcount, packet.src, packet.size, packet.data, p);
}
};
this.handlePacket = function(packet) {
if (packet.dest == self.id) {
// we've reached destination! yay!
} else { // If LUT does have dest, send to that port
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
// Process ACK
} else {
if (!this.addr_table.hasOwnProperty(packet.dest)) {
//hasn't seen the destination yet, so flood!
for (var i = 0; i < this.numports; i++) {
this.sendPacket(packet.dest, packet.size, packet.data, packet.edges, i, packet.src, packet.ack);
packet.hopcount++; // Increment hopcount
const nextPort = 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
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
this.sendPacket(ACK, packet.dest, packet.hopcount, packet.src, 0, null, nextPort);
}
}
} else if (packet.start === STF) { // Standard Flood
if (packet.dest === self.id) { // If I am destination
// Process packet
} else {
packet.hopcount++; // Increment hopcount
const thisFlood = { // Static information within packet for comparison
dest: packet.dest,
src: packet.src,
data: packet.data
};
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
if (nextPort === -1) { // If LUT does not have dest
for (var 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
this.sendPacket(STD, packet.dest, packet.hopcount, packet.src, packet.size, packet.data, nextPort);
}
}
} else if (packet.start === ACF) { // ACK Flood
if (packet.dest === self.id) { // If I am destination
// Process packet
} 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
//send on port with minimum distance to destination
var distances = this.addr_table[packet.dest];
var portToSendOn = indexOfMin(distances);
this.sendPacket(packet.dest, packet.size, packet.data, packet.edges, portToSendOn, packet.src, packet.ack);
const nextPort = 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
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
this.sendPacket(ACK, packet.dest, packet.hopcount, packet.src, 0, null, nextPort);
}
}
} else { // Buffer Update
this.addr_table[packet.port].buff = packet.start;
}
};
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;
}
//from https://stackoverflow.com/questions/11301438/return-index-of-greatest-value-in-an-array
function indexOfMin(arr) {
if (arr.length === 0) {
......
function Manager(self) {
self.manager = this;
this.ports = [];
this.numports = 0;
var map = {0:{1:4,2:3},1:{0:4,3:1},2:{0:3,3:1},3:{1:1,2:1}};
var graph = new Graph(map);
const HOP_COUNT = 2;
this.setup = function(numports) {
this.numports = numports;
this.ports = new Array(numports).fill(-1);
};
this.connect = function(port, id) {
if (!(port < this.numports)) {
return;
}
if (self.id != id) {
var prevId = this.ports[port];
if (prevId >= 0) {
self.disconnect(prevId);
}
this.ports[port] = id;
self.connect(id);
}
};
this.disconnect = function(port) {
if (!(port < this.numports)) {
return;
}
var prevId = this.ports[port];
if (prevId >= 0) {
self.disconnect(prevId);
}
this.ports[port] = -1;
}
this.send = function(port, name, msg) {
if (port < this.numports && this.ports[port] >= 0) {
self.send(this.ports[port], 'message', {name: name, obj: msg});
}
};
this.sendTo = function(id, msg) {
var path = graph.findShortestPath(self.id, id);
var nextNode = path[1];
for (var p = 0; p < this.numports; p++) {
if (this.ports[p] === parseInt(nextNode)) {
this.send(p, id, msg);
return;
}
}
}
// Flood Packet: ['F' , HOP COUNT , ORIGINAL SENDER ID , COST 1 , RECIPIENT 1 , COST 2 , RECIPIENT 2 ...]
this.flood = function() {
for (var p = 0; p < this.numports; p++) {
this.send(this.ports[p], 'F', self.id);
}
}
this.onReceive = function(from, o) {
var port = this.ports.indexOf(from);
if (port == -1) {
return;
}
self.log(`got message '${o.name}' on port ${port}: '${o.obj}'`);
if (o.name != self.id) {
this.sendTo(o.name,o.obj);
}
};
self.on('message', this.onReceive, this);
}
module.exports = Manager;
var net = require("./network"),
manager = require('./manager');
const numClients = 4;
const startupDelay = 100;
var clients = [];
for (var i = 0; i < numClients; i++) {
c = new net.Client();
c.use(manager);
clients.push(c);
}
clients[0].init(function() {
this.delay(startupDelay, function() {
this.manager.setup(2);
this.manager.connect(0, 1);
this.manager.connect(1, 2);
});
this.delay(1000, function() {
//this.manager.send(0, 'Special Delivery', 'Surprise!!!');
this.manager.sendTo(3, 'Tell 3 I said I love her.');
});
});
clients[1].init(function() {
this.delay(startupDelay, function() {
this.manager.setup(2);
this.manager.connect(0, 0);
this.manager.connect(1, 3);
});
});
clients[2].init(function() {
this.delay(startupDelay, function() {
this.manager.setup(2);
this.manager.connect(0, 0);
this.manager.connect(1, 3);
});
});
clients[3].init(function() {
this.delay(startupDelay, function() {
this.manager.setup(2);
this.manager.connect(0, 1);
this.manager.connect(1, 2);
});
});
for (var i = 0; i < numClients; i++) {
net.add(1, clients[i]);
}
net.run(100 * 1000); // runs for 100 seconds
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment