summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xhfsc_shaper.sh298
-rw-r--r--qos_ports.sh25
2 files changed, 205 insertions, 118 deletions
diff --git a/hfsc_shaper.sh b/hfsc_shaper.sh
index 3504c68..2321e7b 100755
--- a/hfsc_shaper.sh
+++ b/hfsc_shaper.sh
@@ -1,7 +1,7 @@
#!/bin/bash
#----------------------------------------------------
# File: hfsc_shaper.sh
-# Version: 0.2
+# Version: 0.3
# Edited: Florian "Bluewind" Pritz <bluewind@xinu.at>
# Author: Maciej BliziƄski, http://automatthias.wordpress.com/
#----------------------------------------------------
@@ -21,151 +21,140 @@
# Uplink and downlink speeds
# Normally use a bit lower values than your real speed, but
# you should experiment a bit
-# downlink is unused
-#DOWNLINK=75000
-UPLINK=7400
+DOWNLINK=100000
+UPLINK=20500
# Device that connects you to the Internet
DEV="extern0"
-# Traffic classes:
-# 1:2 Interactive (SSH, DNS, ACK, Quake)
-# 1:3 Low latency (VoIP)
-# 1:4 Browsing (HTTP, HTTPs)
-# 1:5 Default
-# 1:6 Middle-low priority
-# 1:7 Lowest priority
-
-# Interactive class: SSH Terminal, DNS and gaming (Quake)
-INTERACTIVEPORTS="22 23 53 3389 5900 22222 6667 7000 44400 7776 4949 11030 11239 143 445 25765"
-
-# VoIP telephony
-#VOIPPORTS="5060:5100 10000:11000 5000:5059 8000:8016 5004 1720 1731"
-VOIPPORTS="7977 9987"
# IP addresses of the VoIP phones,
# if none, set VOIPIPS=""
-VOIPIPS=""
+VOIPIPS='';
+DATAIPS='';
+
+source /etc/qos_ports.sh
+# Interactive class: SSH, DNS and gaming (csgo)
+# INTERACTIVEPORTS="22 18765 1200 3478 4379 4380 "
+
+# VoIP / gaming
+#VOIPPORTS="5060:5100 10000:11000 5000:5059 8000:8016 5004 1720 1731"
+# VOIPPORTS="53 27000:27036 "
# WWW, jabber and IRC
-BROWSINGPORTS="80 443 8080 993"
+# BROWSINGPORTS="80 443 8080 "
# Everything unspecified will be here (inbetween Browsing and Data)
# FTP, Mail...
-DATAPORTS="110 25 21 137:139 4662 4664 "
+# DATAPORTS="21 25 110 137:139 143 993 995 4662 4664 27014:27050"
# The lowest priority traffic: eDonkey, Bittorrent, etc.
#P2PPORTS="6881:6999 36892 8333"
-P2PPORTS=""
+# P2PPORTS=""
########################################################################
# CONFIGURATION ENDS HERE
########################################################################
-if [ -z "$DEV" ] ; then
- echo "$0: device not set, aborting."
- exit -1
-fi
+function check_device() {
+ if [ -z "$DEV" ] ; then
+ echo "$0: stop requires a device, aborting."
+ exit -1
+ fi
+}
function stop() {
+ check_device
# Reset everything to a known state (cleared)
- tc qdisc del dev $DEV root &> /dev/null
+ tc qdisc del dev $DEV root &> /dev/null
tc qdisc del dev $DEV ingress &> /dev/null
# Flush and delete tables
iptables -t mangle --delete POSTROUTING -o $DEV -j THESHAPER &> /dev/null
- iptables -t mangle --flush THESHAPER &> /dev/null
+ iptables -t mangle --flush THESHAPER &> /dev/null
iptables -t mangle --delete-chain THESHAPER &> /dev/null
+ echo "Shaping removed on $DEV."
}
function start() {
- #if [ -z "$DOWNLINK" ] ; then
- #echo "$0: start requires a downlink speed, aborting."
- #exit -1
- #fi
+ check_device
+ if [ -z "$DOWNLINK" ] ; then
+ echo "$0: start requires a downlink speed, aborting."
+ exit -1
+ fi
if [ -z "$UPLINK" ] ; then
echo "$0: start requires an uplink speed, aborting."
exit -1
fi
+ # Traffic classes:
+ # 1:2 Low latency (VoIP)
+ # 1:3 Interactive (SSH, DNS, ACK, Quake)
+ # 1:4 Browsing (HTTP, HTTPs)
+ # 1:5 Default
+ # 1:6 Middle-low priority
+ # 1:7 Lowest priority
+
# add HFSC root qdisc
tc qdisc add dev $DEV root handle 1: hfsc default 5
# add main rate limit class
tc class add dev $DEV parent 1: classid 1:1 hfsc \
- sc rate ${UPLINK}kbit ul rate ${UPLINK}kbit
+ sc rate ${UPLINK}kbit ul rate ${UPLINK}kbit
- # Interactive traffic: guarantee full uplink for 50ms, then
- # 5/10 of the uplink
+ # VoIP: guarantee full uplink for 200ms, then 6/10
tc class add dev $DEV parent 1:1 classid 1:2 hfsc \
- sc m1 ${UPLINK}kbit d 50ms m2 $((5*$UPLINK/10))kbit \
- ul rate ${UPLINK}kbit
+ sc m1 ${UPLINK}kbit d 200ms m2 $((6*$UPLINK/10))kbit \
+ ul rate ${UPLINK}kbit
- # VoIP: guarantee full uplink for 200ms, then 3/10
+ # Interactive traffic: guarantee 8/10 uplink for 50ms, then
+ # 5/10 of the uplink
tc class add dev $DEV parent 1:1 classid 1:3 hfsc \
- sc m1 ${UPLINK}kbit d 200ms m2 $((3*$UPLINK/10))kbit \
- ul rate ${UPLINK}kbit
+ sc m1 $((8*$UPLINK/10))kbit d 50ms m2 $((5*$UPLINK/10))kbit \
+ ul rate ${UPLINK}kbit
- # Browsing: guarantee 3/10 uplink for 200ms, then
+ # Browsing: guarantee 2/10 uplink for 200ms, then
# guarantee 1/10
tc class add dev $DEV parent 1:1 classid 1:4 hfsc \
- sc m1 $((3*$UPLINK/10))kbit d 200ms m2 $((1*$UPLINK/10))kbit \
- ul rate ${UPLINK}kbit
+ sc m1 $((2*$UPLINK/10))kbit d 200ms m2 $((1*$UPLINK/10))kbit \
+ ul rate ${UPLINK}kbit
# Default traffic: guarantee 1/10 uplink for 100ms,
- # then guarantee 3/20
+ # then guarantee 1/10
tc class add dev $DEV parent 1:1 classid 1:5 hfsc \
- sc m1 $((1*$UPLINK/10))kbit d 100ms m2 $((3*$UPLINK/20))kbit \
- ul rate ${UPLINK}kbit
+ sc m1 $((1*$UPLINK/10))kbit d 100ms m2 $((1*$UPLINK/10))kbit \
+ ul rate ${UPLINK}kbit
# Middle-low taffic: don't guarantee anything for the first 5 seconds,
# then guarantee 1/10
tc class add dev $DEV parent 1:1 classid 1:6 hfsc \
- sc m1 0 d 5s m2 $((1*$UPLINK/10))kbit \
- ul rate ${UPLINK}kbit
+ sc m1 0 d 5s m2 $((1*$UPLINK/10))kbit \
+ ul rate ${UPLINK}kbit
# Lowest taffic: don't guarantee anything for the first 10 seconds,
# then guarantee 1/20
- #ls m2 $((1*$UPLINK/200))kbit \
tc class add dev $DEV parent 1:1 classid 1:7 hfsc \
- sc m1 0 d 5s m2 10kbit \
- ul rate $((UPLINK-200))kbit
+ sc m1 0 d 10s m2 $((1*$UPLINK/40))kbit \
+ ul rate ${UPLINK}kbit
# add THESHAPER chain to the mangle table in iptables
iptables -t mangle --new-chain THESHAPER
iptables -t mangle --insert POSTROUTING -o $DEV -j THESHAPER
- # Type of service filters (see /etc/iproute2/rt_dsfield)
- iptables -t mangle -A THESHAPER \
- -m tos --tos 0x10 \
- -j CLASSIFY --set-class 1:2
-
- iptables -t mangle -A THESHAPER \
- -m tos --tos 0x08 \
- -j CLASSIFY --set-class 1:7
-
- # To speed up downloads while an upload is going on, put short ACK
- # packets in the interactive class
- iptables -t mangle -A THESHAPER \
- -p tcp \
- -m tcp --tcp-flags FIN,SYN,RST,ACK ACK \
- -m length --length :64 \
- -j CLASSIFY --set-class 1:2
-
- # put large (512+) icmp packets in default category
- iptables -t mangle -A THESHAPER \
- -p icmp \
- -m length --length 512: \
- -j CLASSIFY --set-class 1:5
-
- # small ICMP in the interactive class
- iptables -t mangle -A THESHAPER \
- -p icmp \
- -m length --length :512 \
- -j CLASSIFY --set-class 1:2
-
- setclassbyport() {
+ setclassbyport_udp() {
+ port=$1
+ CLASS=$2
+ iptables -t mangle -A THESHAPER -p udp --sport $port -j CLASSIFY --set-class $CLASS
+ iptables -t mangle -A THESHAPER -p udp --dport $port -j CLASSIFY --set-class $CLASS
+ }
+ setclassbyport_tcp() {
+ port=$1
+ CLASS=$2
+ iptables -t mangle -A THESHAPER -p tcp --sport $port -j CLASSIFY --set-class $CLASS
+ iptables -t mangle -A THESHAPER -p tcp --dport $port -j CLASSIFY --set-class $CLASS
+ }
+ setclassbyport_both() {
port=$1
CLASS=$2
iptables -t mangle -A THESHAPER -p udp --sport $port -j CLASSIFY --set-class $CLASS
@@ -174,44 +163,99 @@ function start() {
iptables -t mangle -A THESHAPER -p tcp --dport $port -j CLASSIFY --set-class $CLASS
}
- for port in $INTERACTIVEPORTS; do setclassbyport $port 1:2; done
- for port in $VOIPPORTS; do setclassbyport $port 1:3; done
- for port in $BROWSINGPORTS; do setclassbyport $port 1:4; done
- for port in $DATAPORTS; do setclassbyport $port 1:6; done
- for port in $P2PPORTS; do setclassbyport $port 1:7; done
+ # for port in $VOIPPORTS; do setclassbyport_udp $port 1:2; done
+ for port in $VOIPPORTS; do setclassbyport_both $port 1:2; done
+ for port in $INTERACTIVEPORTS; do setclassbyport_both $port 1:3; done
+ for port in $BROWSINGPORTS; do setclassbyport_both $port 1:4; done
+ for port in $DATAPORTS; do setclassbyport_tcp $port 1:6; done
+ # for port in $DATAPORTS; do setclassbyport_both $port 1:6; done
+ for port in $P2PPORTS; do setclassbyport_both $port 1:7; done
+
+ if [[ -n "$VOIPIPS" ]]; then
+ echo "enabling ip-based VOIP class 1:2.."
+ for VOIP in $VOIPIPS; do
+ echo " [+] $VOIP"
+ iptables -t mangle -A THESHAPER --src $VOIP -j CLASSIFY --set-class 1:2
+ iptables -t mangle -A THESHAPER --dst $VOIP -j CLASSIFY --set-class 1:2
+ done
+ fi
- for VOIP in $VOIPIPS; do
- iptables -t mangle -A THESHAPER --src $VOIP -j CLASSIFY --set-class 1:3
- iptables -t mangle -A THESHAPER --dst $VOIP -j CLASSIFY --set-class 1:3
- done
+ if [[ -n "$DATAIPS" ]]; then
+ echo "enabling ip-based DATA class 1:7.."
+ for DATAIP in $DATAIPS; do
+ echo " [+] $DATAIP"
+ iptables -t mangle -A THESHAPER --src $DATAIP -j CLASSIFY --set-class 1:7
+ iptables -t mangle -A THESHAPER --dst $DATAIP -j CLASSIFY --set-class 1:7
+ done
+ fi
# put large (1024+) https packets in default category
iptables -t mangle -A THESHAPER \
- -p tcp --dport 443 \
- -m length --length 1024: \
- -j CLASSIFY --set-class 1:6
+ -p tcp --dport 443 \
+ -m length --length 1024: \
+ -j CLASSIFY --set-class 1:5
# put large (1024+) http packets in default category
iptables -t mangle -A THESHAPER \
- -p tcp --dport 80 \
- -m length --length 1024: \
- -j CLASSIFY --set-class 1:6
+ -p tcp --dport 80 \
+ -m length --length 1024: \
+ -j CLASSIFY --set-class 1:5
- # put large (1024+) packets in default category
- #iptables -t mangle -A THESHAPER \
- #-p tcp \
- #-m length --length 1024: \
- #-j CLASSIFY --set-class 1:6
+ iptables -t mangle -A THESHAPER \
+ -p tcp --dport 8080 \
+ -m length --length 1024: \
+ -j CLASSIFY --set-class 1:5
+
+ # Type of service filters (see /etc/iproute2/rt_dsfield)
+ iptables -t mangle -A THESHAPER \
+ -m tos --tos 0x08 \
+ -j CLASSIFY --set-class 1:7
+
+ iptables -t mangle -A THESHAPER \
+ -m tos --tos 0x10 \
+ -j CLASSIFY --set-class 1:2
# put large (1024+) ssh packets in default category
iptables -t mangle -A THESHAPER \
- -p tcp --dport 22 \
- -m length --length 1024: \
- -j CLASSIFY --set-class 1:6
+ -p tcp --dport 22 \
+ -m length --length 1024: \
+ -j CLASSIFY --set-class 1:6
+
+ # put small ssh packets in interactive category. they should be here, but
+ # ssh sets ToS fields for non-interactive sessions to 0x08 and multiplexing
+ # counts as that
+ iptables -t mangle -A THESHAPER \
+ -p tcp --dport 22 \
+ -m length --length :1024 \
+ -j CLASSIFY --set-class 1:2
+
+
+
+ # To speed up downloads while an upload is going on, put short ACK
+ # packets in the interactive class
+ iptables -t mangle -A THESHAPER \
+ -p tcp \
+ -m tcp --tcp-flags FIN,SYN,RST,ACK ACK \
+ -m length --length :64 \
+ -j CLASSIFY --set-class 1:3
+
+
+ # put large (512+) icmp packets in default category
+ iptables -t mangle -A THESHAPER \
+ -p icmp \
+ -m length --length 512: \
+ -j CLASSIFY --set-class 1:5
+
+ # ICMP (ip protocol 1) in the voip class
+ iptables -t mangle -A THESHAPER \
+ -p icmp \
+ -m length --length :512 \
+ -j CLASSIFY --set-class 1:2
+
# put all traffic from user torrent into p2p category (only works for the host this script runs on)
#iptables -t mangle -A THESHAPER \
- #--match owner --uid-owner 169 -j CLASSIFY --set-class 1:7
+ # --match owner --uid-owner 169 -j CLASSIFY --set-class 1:7
# Try to control the incoming traffic as well.
# Set up ingress qdisc
@@ -219,23 +263,41 @@ function start() {
# Filter everything that is coming in too fast
# It's mostly HTTP downloads that keep jamming the downlink, so try to restrict
- # them to 95/100 of the downlink.
+ # them to 90/100 of the downlink.
# FIXME: slows down too much
- #tc filter add dev $DEV parent ffff: protocol ip prio 50 \
- #u32 match ip src 0.0.0.0/0 \
- #match ip protocol 6 0xff \
- #match ip sport 80 0xffff \
- #police rate $((95*${DOWNLINK}/100))kbit \
- #burst 10k drop flowid :1
-
- #tc filter add dev $DEV parent ffff: protocol ip prio 50 \
- #u32 match ip src 0.0.0.0/0 \
- #police rate $((95*${DOWNLINK}/100))kbit \
- #burst $((95*${DOWNLINK}/100*2)) drop flowid :1
+ #tc filter add dev $DEV parent ffff: protocol ip prio 50 \
+ #u32 match ip src 0.0.0.0/0 \
+ #match ip protocol 6 0xff \
+ #match ip sport 80 0xffff \
+ #police rate $((90*${DOWNLINK}/100))kbit \
+ #burst 10k drop flowid :1
+
+ #tc filter add dev $DEV parent ffff: protocol ip prio 50 \
+ #u32 match ip src 0.0.0.0/0 \
+ #police rate $((90*${DOWNLINK}/100))kbit \
+ #burst $((90*${DOWNLINK}/100*2)) drop flowid :1
+
+ #=========== downstream stuff ===========
+ # "${tc_cake}" qdisc del dev $DEV root
+ # "${tc_cake}" qdisc add dev $DEV root cake bandwidth $UPLINK diffserv8
+
+ # "${ip_cake}" link del name dev ifb4$DEV
+ # "${ip_cake}" link add name ifb4$DEV type ifb
+ # "${tc_cake}" qdisc del dev $DEV ingress
+ # "${tc_cake}" qdisc add dev $DEV handle ffff: ingress
+ # "${tc_cake}" qdisc del dev ifb4$DEV root
+ # "${tc_cake}" qdisc add dev ifb4$DEV root cake bandwidth ${DOWNLINK}kbit besteffort
+ # if you dont bring the device up your connection will lock up on the next step.
+ # "${ip_cake}" link set dev ifb4$DEV up
+ # "${tc_cake}" filter add dev $DEV parent ffff: protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb4$DEV
+
+ echo "Shaping added on $DEV."
}
function status() {
+ check_device
+
echo "[qdisc]"
tc -s qdisc show dev $DEV
@@ -249,7 +311,7 @@ function status() {
echo ""
echo "[iptables]"
- iptables -n -t mangle -L THESHAPER -v -x
+ iptables -n -t mangle -L THESHAPER -v -x 2> /dev/null
}
case "$1" in
diff --git a/qos_ports.sh b/qos_ports.sh
new file mode 100644
index 0000000..10ace54
--- /dev/null
+++ b/qos_ports.sh
@@ -0,0 +1,25 @@
+# 1500, 3005, 3101, 28960 = call of duty stuff
+# 3478, 4379, 4380 = steam voip / friend network
+# 5000:5500 = league of legends game traffic
+# 1725, 27000:27031, 27036 = game traffic (cs, tf, ark, portal, ...)
+# 7777, 27900, 28900, 28910, 51014, 60576 = borderlands2 (p2p) ports????
+VOIPPORTS="1500 1725 3005 3101 3478 4379 4380 5000:5500 7777 27000:27031 27036 27900 28900 28910 28960 51014 60576"
+# 22, 18765 = ssh
+# 53 = dns
+# 1200 = steam client
+# 2099, 5222, 5223 = pvp.net
+# 8766 = steam serverbrowser
+# 8088 = league of legends spectator mode
+# 9987 = teamspeak 3
+# 64738 = mumble
+INTERACTIVEPORTS="22 53 1200 2099 5222 5223 8766 8088 9987 18765 64738 143 993 587"
+# 80, 443, 591, 593, 8008 8080, 8081, 8243 8280, 8443, 8888, 9080, 9443= http / web ports
+BROWSINGPORTS="80 443 591 593 8008 8080 8081 8243 8280 8443 8888 9080 9443"
+# 21 = ftp
+# 25, 110, 143, 465, 587, 993, 995 = mail
+# 8393:8400 = league of legends cdn / downloads
+# 8530, 8531 = windows server update services
+# 11371 = openpgp http key server
+# 27014:27054 = steam cdn / downloads
+DATAPORTS="21 25 110 465 995 8393:8400 8530 8531 11371 27014:27054"
+P2PPORTS=""