From f247c33ce95dce4aef1cfb7d29bac4b7d4be23f1 Mon Sep 17 00:00:00 2001 From: Bas Schouten Date: Tue, 7 May 2024 13:11:20 +0100 Subject: [PATCH] Add ability to limit outbound traffic and change bandwidth sliders to be non-linear. --- html/index.html | 41 ++++++++++++++------ html/pithrottler.css | 27 +++++++++++++ html/pithrottler.js | 71 +++++++++++++++++++++++----------- pithrottler.js | 92 +++++++++++++++++++++++++++++++------------- 4 files changed, 171 insertions(+), 60 deletions(-) diff --git a/html/index.html b/html/index.html index ff3a317..7758feb 100644 --- a/html/index.html +++ b/html/index.html @@ -10,18 +10,35 @@

PiThrottler Control

-
- Latency
- 0 ms -
-
- Packet Loss
- 0 % -
-
- Throughput Limitation (0 for unlimited)
- 0 kb/s -
+ + + + + + + + + + + + + + +
InboundOutbound
Latency + 0 ms + + 0 ms +
Packet Loss + 0 % + + 0 % +
Throughput Limit (0=unlimited) + 0 kb/s + + 0 kb/s +
+
+
diff --git a/html/pithrottler.css b/html/pithrottler.css index ce0aabe..31d89bb 100644 --- a/html/pithrottler.css +++ b/html/pithrottler.css @@ -8,6 +8,29 @@ body { font-family:Arial; } +table { + margin:auto; + text-align:left; +} + +th { + text-align:center; +} + +tr { + height:30px; +} + +td:first-child { + text-align:right; +} + +td { + padding-left:5px; + padding-right:5px; + min-width:270px; +} + select, button { width: 160px; height: 30px; @@ -18,6 +41,10 @@ select, button { color: #1c87c9; } +.slider { + width:180px; +} + select:hover, button:hover { background-color:#303030; } diff --git a/html/pithrottler.js b/html/pithrottler.js index 4f03904..5d55a9e 100644 --- a/html/pithrottler.js +++ b/html/pithrottler.js @@ -1,37 +1,58 @@ const presets = { Unlimited: { label: "Unlimited", - latency: 0, - ploss: 0, - throughput: 0 + latencyin: 0, + plossin: 0, + throughputdown: 0, + latencyout: 0, + plossout: 0, + throughputup: 0 }, F4G: { label: "4G Fast", - latency: 30, - ploss: 0, - throughput: 20000 + latencyin: 30, + plossin: 0, + throughputdown: 20000, + latencyout: 30, + plossout: 0, + throughputup: 20000 }, S4G: { label: "4G Slow", - latency: 150, - ploss: 1, - throughput: 10000 + latencyin: 75, + plossin: 1, + throughputdown: 10000, + latencyout: 75, + plossout: 1, + throughputup: 10000 }, F3G: { label: "3G Fast", - latency: 110, - ploss: 0, - throughput: 5000 + latencyin: 55, + plossin: 0, + throughputdown: 5000, + latencyout: 55, + plossout: 0, + throughputup: 5000 }, S3G: { label: "3G Slow", - latency: 200, - ploss: 3, - throughput: 1000 + latencyin: 100, + plossin: 3, + throughputdown: 1000, + latencyout: 100, + plossout: 3, + throughputup: 1000 } }; function saveSettings() { - fetch("/set?latency=" + document.getElementById("latencyRange").value + "&ploss=" + document.getElementById("plossRange").value + "&throughput=" + document.getElementById("tpRange").value); + fetch("/set?latencyin=" + + document.getElementById("latencyinRange").value + "&latencyout=" + + document.getElementById("latencyoutRange").value + "&plossin=" + + document.getElementById("plossinRange").value + "&plossout=" + + document.getElementById("plossoutRange").value + "&throughputdown=" + + Math.pow(document.getElementById("tpdownRange").value, 2) + "&throughputup=" + + Math.pow(document.getElementById("tpupRange").value, 2)); } async function checkForUpdates() { @@ -61,10 +82,16 @@ function loadPresets() { function changePreset() { var preset = document.getElementById("preset").value; - document.getElementById("latencyRange").value = presets[preset].latency; - document.getElementById("latency").innerHTML = presets[preset].latency; - document.getElementById("plossRange").value = presets[preset].ploss; - document.getElementById("ploss").innerHTML = presets[preset].ploss; - document.getElementById("tpRange").value = presets[preset].throughput; - document.getElementById("tp").innerHTML = presets[preset].throughput; + document.getElementById("latencyinRange").value = presets[preset].latencyin; + document.getElementById("latencyin").innerHTML = presets[preset].latencyin; + document.getElementById("plossinRange").value = presets[preset].plossin; + document.getElementById("plossin").innerHTML = presets[preset].plossin; + document.getElementById("tpdownRange").value = Math.sqrt(presets[preset].throughputdown); + document.getElementById("tpdown").innerHTML = presets[preset].throughputdown; + document.getElementById("latencyoutRange").value = presets[preset].latencyout; + document.getElementById("latencyout").innerHTML = presets[preset].latencyout; + document.getElementById("plossoutRange").value = presets[preset].plossout; + document.getElementById("plossout").innerHTML = presets[preset].plossout; + document.getElementById("tpupRange").value = Math.sqrt(presets[preset].throughputup); + document.getElementById("tpup").innerHTML = presets[preset].throughputup; } \ No newline at end of file diff --git a/pithrottler.js b/pithrottler.js index 0890e13..fcb68e4 100644 --- a/pithrottler.js +++ b/pithrottler.js @@ -41,56 +41,96 @@ const app = (req, res) => { if (req.url.startsWith("/set")) { let searchParams = new URL("http://localhost:2121" + req.url).searchParams; - var latency = searchParams.get("latency"); - var ploss = searchParams.get("ploss"); - var throughput = searchParams.get("throughput"); - - if (!latency) { - latency = 0; + var latencyin = searchParams.get("latencyin"); + var latencyout = searchParams.get("latencyout"); + var plossin = searchParams.get("plossin"); + var plossout = searchParams.get("plossout"); + var throughputdown = searchParams.get("throughputdown"); + var throughputup = searchParams.get("throughputup"); + + if (!latencyin) { + latencyin = 0; + } + if (!latencyout) { + latencyout = 0; + } + if (!plossin) { + plossin = 0; } - if (!ploss) { - ploss = 0; + if (!plossout) { + plossout = 0; } - if (!throughput) { - throughput = 0; + if (!throughputdown) { + throughputdown = 0; + } + if (!throughputup) { + throughputup = 0; } res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.setHeader('Access-Control-Allow-Origin', '*'); - res.end("Setting parameters, latency: " + latency + " ms, packet loss: " + ploss + "%, Throughput: " + throughput + " kbit/s"); + res.end("Setting parameters, latency in: " + latencyin + " ms, out: " + latencyout + " ms, packet loss in: " + plossin + "%, out: " + plossout + "%, Throughput in: " + throughputdown + " kbit/s, out: " + throughputup); exec("sudo tc qdisc del dev wlan0 root"); exec("sudo tc qdisc del dev wlan0 root"); + exec("sudo tc qdisc del dev eth0 root"); + + let currentParentIn = "root"; + let currentParentOut = "root"; - if (latency > 0 || ploss > 0) { + if (latencyin > 0 || plossin > 0) { let command = "sudo tc qdisc add dev wlan0 root handle 30: netem"; - if (latency > 0) { - command += " delay " + latency + "ms"; + if (latencyin > 0) { + command += " delay " + latencyin + "ms"; } - if (ploss > 0) { - command += " loss " + ploss + "%"; + if (plossin > 0) { + command += " loss " + plossin + "%"; } exec(command); - console.log("Setting lattency and packet loss"); + console.log("Setting inbound lattency and packet loss"); + + currentParentIn = "parent 30:1"; } - if (throughput > 0) { - let command = "sudo tc qdisc add dev wlan0 "; + if (latencyout > 0 || plossout > 0) { + let command = "sudo tc qdisc add dev eth0 root handle 50: netem"; - if (latency > 0 || ploss > 0) { - command += "parent 30:1"; - } else { - command += "root"; + if (latencyout > 0) { + command += " delay " + latencyout + "ms"; + } + if (plossout > 0) { + command += " loss " + plossout + "%"; } - command += " tbf rate " + throughput + "kbit burst 32kbit latency 500ms"; exec(command); - console.log("Setting bandwidth limitation"); + console.log("Setting outbound latency and packet loss"); + + currentParentOut = "parent 50:1"; } - + + if (throughputdown > 0) { + let command = "sudo tc qdisc add dev wlan0 " + currentParentIn + " handle 40:"; + + currentParentIn = "parent 40:1"; + + command += " tbf rate " + throughputdown + "kbit burst 32kbit latency 500ms"; + exec(command); + console.log("Setting down bandwidth limitation"); + } + + if (throughputup > 0) { + let command = "sudo tc qdisc add dev eth0 " + currentParentOut + " handle 60:"; + + currentParentOut = "parent 60:1"; + + command += " tbf rate " + throughputup + "kbit burst 32kbit latency 500ms"; + exec(command); + console.log("Setting up bandwidth limitation"); + } + return; } -- 2.47.3