Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions webapp/lib/traceroutecont.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func GetTracerouteByTimeHandler(w http.ResponseWriter, r *http.Request, active b
returnError(w, err)
return
}
// log.Debug("Requested data:", "tracerouteResults", tracerouteResults)
log.Debug("Requested data:", "tracerouteResults", tracerouteResults)

tracerouteJSON, err := json.Marshal(tracerouteResults)
if CheckError(err) {
Expand All @@ -156,7 +156,6 @@ func GetTracerouteByTimeHandler(w http.ResponseWriter, r *http.Request, active b
jsonBuf = append(jsonBuf, json...)
jsonBuf = append(jsonBuf, []byte(`}`)...)

//log.Debug(string(jsonBuf))
// ensure % if any, is escaped correctly before writing to printf formatter
fmt.Fprintf(w, strings.Replace(string(jsonBuf), "%", "%%", -1))
}
16 changes: 16 additions & 0 deletions webapp/tests/asviz/bwtester-d.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"graph": [
{
"Inserted": 1562683731800,
"ActualDuration": 5041,
"CSBandwidth": 80000,
"CSThroughput": 80000,
"SCBandwidth": 80000,
"SCThroughput": 80000,
"Error": "",
"Path": "Hops: [1-ff00:0:111 103>4094 1-ff00:0:112] Mtu: 1450",
"Log": "t=2019-07-09T10:48:46-0400 lvl=dbug msg=\"Path selection algorithm choice\" path=\"Hops: [1-ff00:0:111 103>4094 1-ff00:0:112] Mtu: 1450\" score=0.993\nt=2019-07-09T10:48:46-0400 lvl=dbug msg=\"Registered with dispatcher\" addr=\"1-ff00:0:111,[127.0.0.1]:30001 (UDP)\"\nClient DC \tNext Hop [127.0.0.74]:31070\tServer Host [127.0.0.2]:30101\nt=2019-07-09T10:48:46-0400 lvl=dbug msg=\"Registered with dispatcher\" addr=\"1-ff00:0:111,[127.0.0.1]:30002 (UDP)\"\n\nTest parameters:\nclientDCAddr -> serverDCAddr 1-ff00:0:111,[127.0.0.1]:30002 (UDP) -> 1-ff00:0:112,[127.0.0.2]:30101 (UDP)\nclient->server: 3 seconds, 1000 bytes, 30 packets\nserver->client: 3 seconds, 1000 bytes, 30 packets\n\nS->C results\nAttempted bandwidth: 80000 bps / 0.08 Mbps\nAchieved bandwidth: 80000 bps / 0.08 Mbps\nLoss rate: 0 %\nInterarrival time variance: 23ms, average interarrival time: 103ms\nInterarrival time min: 82ms, interarrival time max: 127ms\nWe need to sleep for 2 seconds before we can get the results\n\nC->S results\nAttempted bandwidth: 80000 bps / 0.08 Mbps\nAchieved bandwidth: 80000 bps / 0.08 Mbps\nLoss rate: 0 %\nInterarrival time variance: 23ms, average interarrival time: 103ms\nInterarrival time min: 82ms, interarrival time max: 126ms\n"
}
],
"active": false
}
15 changes: 15 additions & 0 deletions webapp/tests/asviz/echo-d.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"graph": [
{
"Inserted": 1562683883823,
"ActualDuration": 263,
"ResponseTime": 13.352,
"RunTime": 226.525,
"PktLoss": 0,
"CmdOutput": "Using path:\n Hops: [1-ff00:0:111 103>4094 1-ff00:0:112] Mtu: 1450\n104 bytes from 1-ff00:0:112,[127.0.0.2] scmp_seq=0 time=13.352ms\n\n--- 1-ff00:0:112,[[127.0.0.2]] statistics ---\n1 packets transmitted, 1 received, 0% packet loss, time 226.525ms\n",
"Path": "Hops: [1-ff00:0:111 103>4094 1-ff00:0:112] Mtu: 1450",
"Error": ""
}
],
"active": false
}
54 changes: 54 additions & 0 deletions webapp/tests/asviz/traceroute-d.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"graph": [
{
"Inserted": 1570192000394,
"ActualDuration": 35,
"TrHops": [
{
"HopIa": "1-ff00:0:111",
"HopAddr": "127.0.0.17",
"IntfID": 41,
"RespTime1": 0.558,
"RespTime2": 0.439,
"RespTime3": 0.41
},
{
"HopIa": "1-ff00:0:110",
"HopAddr": "127.0.0.9",
"IntfID": 1,
"RespTime1": 0.577,
"RespTime2": 0.597,
"RespTime3": 0.601
},
{
"HopIa": "1-ff00:0:110",
"HopAddr": "127.0.0.10",
"IntfID": 2,
"RespTime1": 0.797,
"RespTime2": 0.666,
"RespTime3": 0.771
},
{
"HopIa": "1-ff00:0:112",
"HopAddr": "127.0.0.25",
"IntfID": 1,
"RespTime1": 1.18,
"RespTime2": 1.922,
"RespTime3": 1.322
},
{
"HopIa": "1-ff00:0:112",
"HopAddr": "127.0.0.2",
"IntfID": -1,
"RespTime1": 1.107,
"RespTime2": 0.899,
"RespTime3": 0.835
}
],
"CmdOutput": "Available paths to 1-ff00:0:112\n[ 0] Hops: [1-ff00:0:111 41>1 1-ff00:0:110 2>1 1-ff00:0:112] Mtu: 1280\nChoose path: Using path:\n Hops: [1-ff00:0:111 41>1 1-ff00:0:110 2>1 1-ff00:0:112] Mtu: 1280\n0 1-ff00:0:111,[127.0.0.17] IfID=41 558µs 439µs 410µs\n1 1-ff00:0:110,[127.0.0.9] IfID=1 577µs 597µs 601µs\n2 1-ff00:0:110,[127.0.0.10] IfID=2 797µs 666µs 771µs\n3 1-ff00:0:112,[127.0.0.25] IfID=1 1.18ms 1.922ms 1.322ms\n4 1-ff00:0:112,[127.0.0.2] 1.107ms 899µs 835µs\n",
"Error": "",
"Path": "Hops: [1-ff00:0:111 41>1 1-ff00:0:110 2>1 1-ff00:0:112] Mtu: 1280"
}
],
"active": false
}
10 changes: 10 additions & 0 deletions webapp/web/static/css/style-viz.css
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,21 @@ ul.tree li.open>ul {
ul.tree li a {
color: black;
text-decoration: none;
}

.path-text {
color: white;
padding-left: 5px; /* background shape */
padding-right: 5px; /* background shape */
border-radius: 10px; /* background shape */
}

.latency-text {
color: purple;
position: absolute;
right: 0;
}

ul.tree li a:before {
height: 1em;
padding: 0 .1em;
Expand Down
23 changes: 20 additions & 3 deletions webapp/web/static/js/asviz.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ function setPaths(type, idx, open) {
} else if (type == 'UP') {
addSegments(resUp, idx, num, colorSegUp, type);
} else if (type == 'PATH') {
addPaths(resPath, idx, num, colorPaths, type);
// use min(best) for inter AS as it will be more accurate for length
var latencies = getPathLatencyLast(formatPathString(resPath, idx,
type));
addPaths(resPath, idx, num, colorPaths, type, latencies);
}
self.segType = type;
self.segNum = idx;
Expand Down Expand Up @@ -108,12 +111,26 @@ function formatPathString(res, idx, type) {
return path;
}

function formatPathStringAll(res, type) {
var paths = "";
for (var i = 0; i < res.if_lists.length; i++) {
var path = formatPathString(res, i, type);
if (path != "") {
if (i > 0) {
paths += ",";
}
paths += formatPathString(res, i, type);
}
}
return paths;
}

/*
* Adds D3 forwarding path links with arrows and a title to paths graph.
*/
function addPaths(res, idx, num, color, type) {
function addPaths(res, idx, num, color, type, latencies) {
if (graphPath) {
drawPath(res, idx, color);
drawPath(res, idx, color, latencies);
if (res.if_lists[idx].expTime) {
drawTitle(type + ' ' + num, color, res.if_lists[idx].expTime);
} else {
Expand Down
172 changes: 155 additions & 17 deletions webapp/web/static/js/tab-paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var iaLabels;
var iaLocations = [];
var iaGeoLoc;
var g = {};
var jPathColors = [];
var jPathsAvailable = {};

function setupDebug(src, dst) {
var src = $('#ia_cli').val();
Expand All @@ -40,14 +40,104 @@ function path_colors(n) {
}

function getPathColor(hops) {
var idx = jPathColors.indexOf(hops + '');
if (idx < 0) {
if (!jPathsAvailable[hops]) {
return cMissingPath;
} else {
return path_colors(idx);
return jPathsAvailable[hops].color;
}
}

/**
* Updates statistics.
*/
function updateStats(fStat, oldStat) {
var newStat = {}
newStat.Last = fStat;
newStat.Num = oldStat ? (oldStat.Num + 1) : 1;
newStat.Avg = oldStat ? (((oldStat.Avg * oldStat.Num) + fStat) / newStat.Num)
: fStat;
newStat.Min = oldStat ? Math.min(fStat, oldStat.Min) : fStat;
newStat.Max = oldStat ? Math.max(fStat, oldStat.Max) : fStat;
return newStat;
}

function getPathLatencyLast(hops) {
return getPathLatency(hops, false);
}

function getPathLatencyAvg(hops) {
return getPathLatency(hops, true);
}

function formatLatency(lat) {
// ignore 1ms negative margin of error
if (lat > -1 && lat < 0) {
return 0;
} else {
return parseFloat(lat).toFixed(0);
}
}

/**
* Returns array of interface and full path latency stats.
*/
function getPathLatency(hops, avg) {
var path = {};
if (jPathsAvailable[hops]) {
path = jPathsAvailable[hops];
}
var latencies = [];
for (var i = 0; i < path.interfaces.length; i++) {
if (path.interfaces[i].latency) {
latencies.push(avg ? path.interfaces[i].latency.Last
: path.interfaces[i].latency.Avg);
} else {
latencies.push(undefined);
}
}
if (path.latency) {
latencies.push(avg ? path.latency.Last : path.latency.Avg);
} else {
latencies.push(undefined);
}
return latencies;
}

function setEchoLatency(hops, latency) {
var path = {};
if (jPathsAvailable[hops]) {
path = jPathsAvailable[hops];
}
path.latency = updateStats(latency, path.latency);
jPathsAvailable[hops] = path;
return path;
}

function setTracerouteLatency(hops, interfaces) {
var path = {};
if (jPathsAvailable[hops]) {
path = jPathsAvailable[hops];
}
for (var i = 0; i < interfaces.length; i++) {
var if_ = interfaces[i];
if (i < interfaces.length - 1) {
path.interfaces[i].addr = if_.HopAddr;
path.interfaces[i].latency = updateStats(if_.RespTime1,
path.interfaces[i].latency);
path.interfaces[i].latency = updateStats(if_.RespTime2,
path.interfaces[i].latency);
path.interfaces[i].latency = updateStats(if_.RespTime3,
path.interfaces[i].latency);
} else {
path.latency = updateStats(if_.RespTime1, path.latency);
path.latency = updateStats(if_.RespTime2, path.latency);
path.latency = updateStats(if_.RespTime3, path.latency);
}
}
jPathsAvailable[hops] = path;
return path;
}

function isConfigComplete(data, textStatus, jqXHR) {
console.log(JSON.stringify(data));
g['nodes_xml_url'] = data.nodes_xml_url;
Expand Down Expand Up @@ -390,11 +480,18 @@ function get_path_html(paths, csegs, usegs, dsegs, show_segs) {
if_ = ent.Path.Interfaces;
var hops = if_.length / 2;

var style = "style='background-color: "
+ getPathColor(formatPathJson(paths, parseInt(p))) + "; '";
html += "<li seg-type='PATH' seg-num=" + p + "><a " + style
+ " href='#'>PATH " + (parseInt(p) + 1)
+ "</a> <span class='badge'>" + hops + "</span>";
var pathStr = formatPathJson(paths, parseInt(p));
var latencies = getPathLatencyLast(pathStr);
var latencyPath = latencies[latencies.length - 1];
var latPathStr = latencyPath ? formatLatency(latencyPath) : '';
var aStyle = "style='background-color:" + getPathColor(pathStr) + ";'";
html += "<li seg-type='PATH' seg-num=" + p + " path='" + pathStr
+ "'><a class='path-text' " + aStyle
+ " href='#'><span style='color: white;'>PATH "
+ (parseInt(p) + 1) + "</span></a> <span class='badge'>" + hops
+ "</span> <span id='path-lat-" + p
+ "' class='latency-text' style='font-weight: bold;'>"
+ latPathStr + "</span>";
exp.setUTCSeconds(ent.Path.ExpTime);
html += "<ul>";
html += "<li><a href='#'>Mtu: " + ent.Path.Mtu + "</a>";
Expand All @@ -410,8 +507,10 @@ function get_path_html(paths, csegs, usegs, dsegs, show_segs) {
html += "<li><a href='#'>Expiration: " + exp.toLocaleDateString() + " "
+ exp.toLocaleTimeString() + "</a>";
for (i in if_) {
var latIfStr = latencies[i] ? formatLatency(latencies[i]) : '';
html += "<li><a href='#'>" + iaRaw2Read(if_[i].RawIsdas) + " ("
+ if_[i].IfID + ")</a>";
+ if_[i].IfID + ")</a> <span id='path-lat-" + p + "-" + i
+ "' class='latency-text' >" + latIfStr + "</span>";
}
html += "</ul>";
}
Expand Down Expand Up @@ -676,6 +775,39 @@ function get_nonseg_links(paths, lType) {
return hops;
}

function addAvailablePaths(paths) {
Object.keys(jPathsAvailable).forEach(function(key) {
jPathsAvailable[key].listIdx = undefined; // reset
});
if (!paths) {
return;
}
for (var idx = 0; idx < paths.length; idx++) {
var hops = formatPathJson(paths, idx, 'PATH');
if (!jPathsAvailable[hops]) {
jPathsAvailable[hops] = {};
}
// update path preserving old values
var path = jPathsAvailable[hops];
var pathLen = Object.keys(jPathsAvailable).length;
path.interfaces = [];
var ifs = paths[idx].Entry.Path.Interfaces;
for (var i = 0; i < ifs.length; i++) {
var if_ = {};
if_.ifid = ifs[i].IfID;
if_.isdas = iaRaw2Read(ifs[i].RawIsdas);
path.interfaces.push(if_);
}
path.expTime = paths[idx].Entry.Path.ExpTime;
path.mtu = paths[idx].Entry.Path.Mtu;
if (!path.color) {
path.color = path_colors(pathLen - 1);
}
path.listIdx = idx;
jPathsAvailable[hops] = path;
}
}

function requestPaths() {
// make sure to get path topo after IAs are loaded
var form_data = $('#command-form').serializeArray();
Expand All @@ -699,12 +831,7 @@ function requestPaths() {
resDown = resSegs.down_segments;

// store incoming paths
for (var idx = 0; idx < resPath.if_lists.length; idx++) {
var hops = formatPathString(resPath, idx, 'PATH');
if (!jPathColors.includes(hops)) {
jPathColors.push(hops);
}
}
addAvailablePaths(data.paths);

jTopo = get_json_path_links(resPath, resCore, resUp, resDown);
$('#path-info').html(
Expand All @@ -717,7 +844,18 @@ function requestPaths() {

// setup path config based on defaults loaded
setupDebug();
ajaxConfig();

// request config/paths if none exists
if (!iaLabels || !iaGeoLoc || !iaLocations) {
ajaxConfig(); // ajaxConfig => loadPathData
} else {
loadPathData(g.src, g.dst);
}

// auto survey latency if none exists
if (!$('#path-lat-0').text()) {
surveyEchoBackground();
}

// path info label switches
$('#switch_as_names').change(function() {
Expand Down
Loading