Skip to content
Permalink
22630938cb
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
210 lines (187 sloc) 6.31 KB
import { Packet } from './packet.js';
import { Entity } from './entity.js';
import { Clock } from './clock.js';
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Define Entities
let attacker = new Entity('/static/images/attacker.png', 'attacker', 250,150,100,100);
let nserver = new Entity('/static/images/remote_server.png', 'nserver', 250, 650,100,100);
let router = new Entity('/static/images/router.png', 'router - DDD Filter and Mapping Device', 650, 475, 100,100);
let mserver = new Entity('/static/images/remote_server.png', 'Reflection Server', 1200, 150, 100, 100);
let nat = new Entity('/static/images/router.png', 'NAT Device', 1200, 675, 100,100);
let client = new Entity('/static/images/home_client.png', 'client', 1700, 750, 100, 100);
let entities = [mserver, nserver, client, router, attacker, nat];
for(let entity of entities){
entity.ctx = ctx;
}
// Animate function variables
let packets = new Set();
let animateInstructions = [];
var instructionInd = 0;
var animateFrameReqId;
let running = false;
let entityMap = {'mserver': mserver, 'nserver': nserver, 'client': client, 'attacker': attacker, 'router': router, 'nat': nat};
// Clock object that stores variables that have to do with time
let clock = new Clock();
// Scale = 1 means 1ms in simulation = 1s in realtime. Scale = 10 means 1ms in simulation = 0.1s in realtime
let sliderMap = new Map();
sliderMap[1] = 1;
sliderMap[2] = 2;
sliderMap[3] = 5;
sliderMap[4] = 10;
sliderMap[5] = 20;
export function setAnimateInstructions(instructions){
animateInstructions = instructions;
instructionInd = 0;
packets = new Set();
if(!running){
animateLoop();
}
}
window.stopSimulation = stopSimulation;
function stopSimulation(){
animateInstructions = [];
instructionInd = 0;
packets = new Set();
running = false;
}
window.pauseSimulation = pauseSimulation;
function pauseSimulation(){
window.cancelAnimationFrame(animateFrameReqId);
running = false;
}
window.resumeSimulation = resumeSimulation;
function resumeSimulation(){
if(!running){
animateLoop();
}
}
function animateLoop(){
animateFrameReqId = requestAnimationFrame(animateLoop);
running = true;
// Draw the entities
drawEntities(entities);
// Get slider value and set scale
let sliderVal = document.getElementById('myRange').value; // global speed
let scale = sliderMap[sliderVal];
// Update the position of each of the packets
for(let packet of packets){
let finished = packet.update();
// if the packet is finished being animated, then remove from packets
if(finished){
packets.delete(packet);
}
}
// Update clock variables
clock.update();
// Animating using instructions
if(clock.animateDelta >= 1000 / scale){
if(instructionInd < animateInstructions.length){
let instructions = animateInstructions[instructionInd];
instructionInd++;
// Stack dstPortNum variables
let lastSrc;
let range = 0;
let lastDropSrc;
let dropRange = 0;
// Iterate through instructions for time unit
for(let animateInstruction of instructions){
let instructionType = animateInstruction[0];
if(instructionType == 'transit'){
let instruction = animateInstruction[1];
// Access the fields of the instruction
let source = entityMap[instruction[0]];
let destination = entityMap[instruction[1]];
let packetType = instruction[2];
let dstPortNum = instruction[5]
let totalTime = instruction[6];
// Logic to have packets sent at same time unit at same entity to stack dstPortNums
if(!lastSrc || lastSrc == source){
range += 10;
}
else{
range = 0;
}
lastSrc = source;
let color = getPacketColor(packetType);
let packet = animatePacket(source.x, source.y, destination.x, destination.y, totalTime/ scale, color, 20, dstPortNum);
packet.range = range;
packets.add(packet);
}
else if(instructionType == 'drop'){
let instruction = animateInstruction[1];
let source = entityMap[instruction[0]];
let packetType = instruction[1];
let dstPortNum = instruction[4];
let color = getPacketColor(packetType);
// Logic to have packets sent at same time unit at same entity to stack dstPortNums
if(!lastDropSrc || lastDropSrc == source){
dropRange += 10;
}
else{
dropRange = 0;
}
lastDropSrc = source;
let packet = animatePacket(source.x, source.y, source.x, source.y - 100, 1 / scale, color, 15, dstPortNum);
packet.range = dropRange;
packet.dropped = true;
packets.add(packet);
}
else if(instructionType == 'data'){
let instruction = animateInstruction[1];
let entity = entityMap[instruction[5]];
entity.queueSize = instruction[0];
entity.receivedCounter = instruction[1];
entity.droppedCounter = instruction[2]; // Number of packets dropped
entity.generateCounter = instruction[3];
entity.sentCounter = instruction[4]; // Number of packets successfully sent
}
}
}
clock.animateDelta = 0;
}
}
function drawEntities(entities){
// Draws a list of entities to the canvas
ctx.clearRect(0,0,canvas.width, canvas.height);
for(let entity of entities){
entity.draw();
}
}
function getPacketColor(packetType){
let color = '';
switch(packetType){
case 'SYN':
color = 'green';
break;
case 'ACK':
color = 'yellow';
break;
case 'SYN-ACK':
color = 'blue';
break;
case 'RST':
color = 'purple';
break;
case 'PING':
color = 'pink';
break;
case 'PONG':
color = 'black';
break;
case 'PONG-RST':
color = 'aqua'
}
return color;
}
function animatePacket(x, y, dstX, dstY, totalTime, color, radius, dstPortNum){
// Creates packet that will be animated from x,y to dstX, dstY in totalTime seconds
let fps = 60;
let velocity = {
x: (dstX - x) / totalTime / fps,
y: (dstY - y) / totalTime / fps,
}
return new Packet(x, y, dstX, dstY, radius, color, velocity, ctx, dstPortNum);
}