From 4156d5b9604b1695441ccef9b93c1e0ae38bd999 Mon Sep 17 00:00:00 2001 From: stefan Date: Mon, 22 Mar 2021 20:44:16 +0100 Subject: [PATCH] Add 'bufferbloat.sh' Initial commit --- bufferbloat.sh | 212 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 bufferbloat.sh diff --git a/bufferbloat.sh b/bufferbloat.sh new file mode 100644 index 0000000..fc35e0d --- /dev/null +++ b/bufferbloat.sh @@ -0,0 +1,212 @@ +#!/bin/sh + +# Display bandwidth for our WAN interface, measure for 10 Seconds, then it quits: +# Relevent line: Total Send Rate -> Last 10 Seconds +# Relevant line: Total receive rate -> Last 10 Seconds +#iftop -i igb0 -n -N -b -t -p -s 10 + +# Get DL bw last 10 seconds +# iftop -i igb0 -n -N -b -t -p -s 10 | grep "Total receive rate" | xargs echo | cut -d " " -f5 + +# Get DL bw last 2 seconds +# iftop -i igb0 -n -N -b -t -p -s 10 | grep "Total receive rate" | xargs echo | cut -d " " -f4 + +# Get the average ping to 1.1.1.1 in ms +#ping -t 10 -q 1.1.1.1 | cut -d "/" -s -f5 + +# Idea: If average ping is >200ms, reduce current download bandwidth by 10% +# Repeat until ping is OK or lower limit reached +# If average Ping <50ms -> Increase Bandwidth by 10% until upper limit reached + + +# maximum allowed ping in ms +pingMax=200 +# optimal ping in ms +pingOpt=50 +# maximum possible download bandwidth in Mbit/s +downloadBWMax=80 +downloadBWMaxBits=$(units -o "%0.f" -t "${downloadBWMax} megabit" "bits") +# minimum allowed Download Bandwidth +downloadBWMin=5 +downloadBWMinBits=$(units -o "%0.f" -t "${downloadBWMin} megabit" "bits") +# downloadPipe as in opnsense: ipfw pipe show +downloadPipe=10000 +uploadPipe=10001 +# maxmimum possible upload bandwidth in Mbit/s +uploadBWMax=20 +uploadBWMaxBits=$(units -o "%0.f" -t "${uploadBWMax} megabit" "bits") +# minimum allowed upload Bandwidth +uploadBWMin=2 +uploadBWMinBits=$(units -o "%0.f" -t "${uploadBWMin} megabit" "bits") + +# private vars +avgping=1 +avgDownloadBW10sInBits=1 +avgUploadBW10sInBits=1 + + +resetDownloadBandwidth() { + # resets the Download Bandwith to the maximum value + echo "Resetting download bandwith limit to $downloadBWMax MBit/s" + ipfw pipe "$downloadPipe" config bw "${downloadBWMax}Mbit" +} + +resetUploadBandwidth() { + # resets the Upload Bandwith to the maximum value + echo "Resetting upload bandwith limit to $uploadBWMax MBit/s" + ipfw pipe "$uploadPipe" config bw "${uploadBWMax}Mbit" +} + +decreaseDownloadBandwidth() { + # currently used Bandwidth limit in Mbit/s + currentBW=$(ipfw pipe show | grep "${downloadPipe}:" | xargs echo | cut -d " " -f2) + currentBWInBits=$(units -o "%0.f" -t "${currentBW} megabit" "bits") + echo "The current download BW limit in bits is $currentBWInBits and in Mbit/s $currentBW " + + # decrease current average Bandwidth by 10% + # newBW=$(echo "$avgDownloadBW10sInBits * 0.9" | bc) + # decrease currently set Bandwidth by 10% + newBW=$(echo "$currentBWInBits * 0.9" | bc) + + newBWMbit=$(units -o "%0.f" -t "${newBW} bits" "megabit") + + echo "The average BW in the last 10s was $avgDownloadBW10s new BW would be $newBWMbit Mbit/s" + + if [ 1 -eq "$(echo "${newBW} < ${downloadBWMinBits}" | bc)" ] + then + echo "Setting current Download Bandwidth to the minimum allowed Bandwidth $downloadBWMin" + ipfw pipe "$downloadPipe" config bw "${downloadBWMin}Mbit" + else + echo "Decreasing current avg Download Bandwidth by 10%, setting it to $newBW Bits/s" + echo "Decreasing current avg Download Bandwidth by 10%, setting it to $newBWMbit MBit/s" + ipfw pipe "$downloadPipe" config bw "${newBWMbit}Mbit" + fi +} + +decreaseUploadBandwidth() { + # currently used Bandwidth limit in Mbit/s + currentBW=$(ipfw pipe show | grep "${uploadPipe}:" | xargs echo | cut -d " " -f2) + currentBWInBits=$(units -o "%0.f" -t "${currentBW} megabit" "bits") + echo "The current upload BW limit in bits is $currentBWInBits and in Mbit/s $currentBW " + + # decrease current average Bandwidth by 10% + # newBW=$(echo "$avgUploadBW10sInBits * 0.9" | bc) + # decrease currently set Bandwidth by 10% + newBW=$(echo "$currentBWInBits * 0.9" | bc) + + newBWMbit=$(units -o "%0.f" -t "${newBW} bits" "megabit") + + echo "The average BW in the last 10s was $avgUploadBW10sInBits new BW would be $newBWMbit Mbit/s" + + if [ 1 -eq "$(echo "${newBW} < ${uploadBWMinBits}" | bc)" ] + then + echo "Setting current Upload Bandwidth to the minimum allowed Bandwidth $uploadBWMin" + ipfw pipe "$uploadPipe" config bw "${uploadBWMin}Mbit" + else + echo "Decreasing current avg Upload Bandwidth by 10%, setting it to $newBW Bits/s" + echo "Decreasing current avg Upload Bandwidth by 10%, setting it to $newBWMbit MBit/s" + ipfw pipe "$uploadPipe" config bw "${newBWMbit}Mbit" + fi +} + +increaseDownloadBandwidth() { + # currently used Bandwidth limit in Mbit/s + currentBW=$(ipfw pipe show | grep "${downloadPipe}:" | xargs echo | cut -d " " -f2) + currentBWInBits=$(units -o "%0.f" -t "${currentBW} megabit" "bits") + echo "The current download BW in bits is $currentBWInBits and in Mbit/s $currentBW " + + # increase current average Bandwidth by 10% + # newBW=$(echo "$avgDownloadBW10sInBits * 1.1" | bc) + # increase currently set Bandwidth by 10% + newBW=$(echo "$currentBWInBits * 1.1" | bc) + + newBWMbit=$(units -o "%0.f" -t "${newBW} bits" "megabit") + + echo "The average BW in the last 10s was $avgDownloadBW10s new BW would be $newBWMbit Mbit/s" + + if [ 1 -eq "$(echo "${newBW} > ${downloadBWMaxBits}" | bc)" ] + then + echo "Setting current Download Bandwidth to the maximum allowed Bandwidth $downloadBWMax" + ipfw pipe "$downloadPipe" config bw "${downloadBWMax}Mbit" + else + echo "Increasing current avg Download Bandwidth by 10%, setting it to $newBW Bits/s" + echo "Increasing current avg Download Bandwidth by 10%, setting it to $newBWMbit MBit/s" + ipfw pipe "$downloadPipe" config bw "${newBWMbit}Mbit" + fi +} + +increaseUploadBandwidth() { + # currently used Bandwidth limit in Mbit/s + currentBW=$(ipfw pipe show | grep "${uploadPipe}:" | xargs echo | cut -d " " -f2) + currentBWInBits=$(units -o "%0.f" -t "${currentBW} megabit" "bits") + echo "The current upload BW in bits is $currentBWInBits and in Mbit/s $currentBW " + + # increase current average Bandwidth by 10% + # newBW=$(echo "$avgUploadBW10sInBits * 1.1" | bc) + # increase currently set Bandwidth by 10% + newBW=$(echo "$currentBWInBits * 1.1" | bc) + + newBWMbit=$(units -o "%0.f" -t "${newBW} bits" "megabit") + + if [ 1 -eq "$(echo "${newBWMbit} == ${currentBW}" | bc)" ] + then + echo "Forcing increment by 1MBit" + newBWMbit=$(echo "${newBWMbit} + 1" | bc) + fi + + echo "The average upload BW in the last 10s was $avgUploadBW10sInBits new BW would be $newBWMbit Mbit/s" + + if [ 1 -eq "$(echo "${newBW} > ${uploadBWMaxBits}" | bc)" ] + then + echo "Setting current Upload Bandwidth to the maximum allowed Bandwidth $uploadBWMax" + ipfw pipe "$uploadPipe" config bw "${uploadBWMax}Mbit" + else + echo "Increasing current avg Upload Bandwidth by 10%, setting it to $newBW Bits/s" + echo "Increasing current avg Upload Bandwidth by 10%, setting it to $newBWMbit MBit/s" + ipfw pipe "$uploadPipe" config bw "${newBWMbit}Mbit" + fi +} + +while true +do + echo "Pinging vps02 for average latency" + avgping=$(ping -t 10 -q 51.254.48.251 | cut -d "/" -s -f5) + echo "Average ping is $avgping" + + #bwLast10s=$(iftop -i igb0 -n -N -b -t -p -s 10) + #avgDownloadBW10s=$(echo "$bwLast10s" | grep "Total receive rate" | xargs echo | cut -d " " -f5) + #avgUploadBW10s=$(echo "$bwLast10s" | grep "Total send rate" | xargs echo | cut -d " " -f5) + #echo "The average Download in the last 10 seconds is $avgDownloadBW10s" + #echo "The average Upload in the last 10 seconds is $avgUploadBW10s" + + #avgDownloadBW10s=$(echo "$avgDownloadBW10s"| sed "s/B/ bit/g" | sed "s/Kb/ kilobit/g" | sed "s/Mb/ megabit/g" | sed "s/Gb/ gigabit/g") + #avgUploadBW10s=$(echo "$avgUploadBW10s"| sed "s/B/ bit/g" | sed "s/Kb/ kilobit/g" | sed "s/Mb/ megabit/g" | sed "s/Gb/ gigabit/g") + #echo "The average Download in the last 10 seconds is $avgDownloadBW10s" + #echo "The average Upload in the last 10 seconds is $avgUploadBW10s" + + #avgDownloadBW10sInBits=$(units -o "%0.f" -t "$avgDownloadBW10s" "bits") + #avgUploadBW10sInBits=$(units -o "%0.f" -t "$avgUploadBW10s" "bits") + #echo "The average Download in BITS in the last 10 seconds is $avgDownloadBW10sInBits" + #echo "The average Upload in BITS in the last 10 seconds is $avgUploadBW10sInBits" + + # if the average ping is higher than the maximum allowed ping, decrease bandwidth + if [ 1 -eq "$(echo "${avgping} > ${pingMax}" | bc)" ] + then + echo "ping is too high ${avgping}" + decreaseDownloadBandwidth + decreaseUploadBandwidth + fi + + # if the average ping is below optimal, increase bandwidth + if [ 1 -eq "$(echo "${avgping} < ${pingOpt}" | bc)" ] + then + echo "ping is optimal ${avgping}" + increaseDownloadBandwidth + increaseUploadBandwidth + fi + + + echo "Sleeping for a minute" + sleep 5 +done +