#!/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