#!/bin/bash
# ultimatePM.sh for news.chsoft.biz
# Wonder Shaper v1.1a
# Heavily modified again 3 Apr 04
# Heavily modified by JK 8 Nov 2002 and named /usr/sbin/ultimate.sh
# Please read the README before filling out these values.
# Set the following values to somewhat less than your actual download
# and uplink speed in kilobits. Also set the device that is to be shaped.
# Start with 50%, increase until high latency returns, reduce...
# kilobits/8 = Kbytes
# Example: DOWNLINK=800
# It makes very little sense to drop packets already received:
DOWNLINK=4000 # ingress police
# Start with 50%, increase until high latency returns, reduce...
# Example: UPLINK=220
UPLINK=1350 # HTB shape outgoing
# Example: DEV=ppp0
DEV=eth1
ATJ="68.171.136.0/24" # andthatsjazz
CHS="66.209.101.192/29" # skypipeline (chsoft.biz)
ISW1="207.178.128.0/24" # iswest
ISW2="216.166.71.0/24" # iswest
ISW3="216.196.105.0/24" # iswest (giganews)
UNS1="63.223.5.0/24" # usenetserver (west = nntp2)
UNS2="64.154.60.0/24" # usenetserver
###### EXPLANATION
# See 'downlink' at the end of this script for information about incoming
# packets. All of this except for that refers to queueing outgoing packets.
#
# Most of what is sent goes out on a randomly selected high SOURCE port
# ('sport') to a specific DESTINATION port ('dport'). For example, an http
# request is sent with 'dport' = 80 and 'sport' = random. Therefore, 'sport'
# specifications are rarely applicable. The port number is located in the
# packet header and is specified thus:
# "u32 match ip dport PORT# 0xffff" or "u32 match ip sport PORT# 0xffff"
#
# Since shaping means quequeing OUTGOING packets, your IP Address(es) are
# SOURCEs ('src') and the remote machine's IP Address(es) are DESTINATIONs
# ('dst') - so, as with 'sport', 'src' specifications are rarely applicable.
# The IP Address is located in the packet header and is specified thus:
# "u32 match ip src IP-ADDRESS" or "u32 match ip dst IP-ADDRESS"
#
# Read the HOWTO "All the filtering commands you will normally need" for
# protocol information (TCP, UDP, ICMP, GRE, IPSEC). Also see the TOS and
# ICMP sections below.
######
# Ports:
# LoPrioSPORT ('sport')
# Set this to source ports that should have low priority. If you have
# an unimportant webserver on your traffic, set this to 80.
# (some ports ) 0 20 21 22 23 25 53 80 113 119 873
# (and what they are:) FTPd FTPc SSH SMTP DNS HTTP IDENT NNTP Rsync
LoPrioSPORT="21 23 67 68 79 135 137 138 139 445 901 1026 1027 1028 1029 5018"
# HiPrioSPORT ('sport')
# *** Make sure no LoPrioSPORTs are duplicated here! ***
# Port 80 is the second instance of rsync, not HTTP
# Port 1234 is nntp proxy to iswest for duron
# These are services I provide to outside users (even though iptables shows
# these with me as the dest and these as DPTs):
#HiPrioSPORT="22 53 80 113 119 123 873 1234"
HiPrioSPORT="22 53 113 119 123 1234"
# LoPrioDPORT ('dport')
# Set this to destination ports that should have low priority.
# FTP commands, SMTP:
LoPrioDPORT="21 23 67 68 79 135 137 138 139 445 901 1026 1027 1028 1029 5018"
# HiPrioDPORT ('dport')
# *** Make sure no LoPrioDPORTs are duplicated here! ***
# Port 1234 is nntp proxy to iswest for duron
HiPrioDPORT="22 53 113 119 123 873 1234"
# Sometimes you may notice low priority OUTGOING traffic slowing down
# important traffic. In that case, the following options may help you:
# Low priority specifications:
# IPs / Netmasks:
# LoPrioCIDR_Src ('src')
# Set this to hosts or netmasks in your network that should have low priority.
# Low priority OUTGOING traffic. You can leave this blank if you want.
# Low priority source netmasks:
LoPrioCIDR_Src=""
# High priority specifications:
# IPs / Netmasks:
# See EXPLANATION above; these do not need to be here.
# 20 Sep 04 removed $ATJ from AM but not from PM
HiPrioCIDR_Src="$ATJ $ISW1 $ISW2 $ISW3 $UNS1"
# LoPrioCIDR_Dst ('dst')
# Set this to hosts or netmasks on the internet that should have low priority.
# Low priority destination netmasks:
# (This list comes from ftp.xfer and 'tellnews dns_show', plus my experience):
#ex LoPrioCIDR_Dst="24.0.0.0/8 64.0.0.0/8 65.0.0.0/8 80.0.0.0/8 213.0.0.0/8 217.0.0.0/8 221.0.0.0/8"
LoPrioCIDR_Dst="221.0.0.0/8"
# high priority destination netmasks ('dst'):
# 20 Sep 04 removed $ATJ from AM but not from PM
HiPrioCIDR_Dst="$ATJ $ISW1 $ISW2 $ISW3 $UNS1"
if [ "$1" = "status" ]; then
tc -s qdisc ls dev $DEV
tc -s class ls dev $DEV
exit
fi
# clean existing down- and uplink qdiscs, hide errors
tc qdisc del dev $DEV root 2> /dev/null > /dev/null
tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null
modprobe -r sch_htb
modprobe -r sch_ingress
modprobe -r sch_esfq
modprobe -r cls_u32
if [ "$1" = "stop" ]; then
exit
fi
###### uplink
# Install root HTB, point default traffic to 1:30:
tc qdisc add dev $DEV root handle 1: htb default 30
# Shape everything at $UPLINK speed - this prevents huge queues in your
# DSL modem which destroy latency:
tc class add dev $DEV parent 1: classid 1:1 htb rate ${UPLINK}kbit burst 6k
# High prio (interactive) class 1:10:
tc class add dev $DEV parent 1:1 classid 1:10 htb rate ${UPLINK}kbit \
burst 6k quantum 1514 prio 1
# Accelerated class 1:20 - the HIPRIO stuff:
tc class add dev $DEV parent 1:1 classid 1:20 htb rate $[96*$UPLINK/100]kbit \
ceil $[98*$UPLINK/100]kbit burst 5k quantum 1514 prio 2
# Bulk & default class 1:30 - gets a low priority:
tc class add dev $DEV parent 1:1 classid 1:30 htb rate $[65*$UPLINK/100]kbit \
ceil $[95*$UPLINK/100]kbit burst 5k quantum 1514 prio 3
# Penalized class 1:40 - the LOPRIO stuff gets the lowest rate:
# "23 thru 31 *$UPLINK/100" results in "quantum of class 10040 is small" and a
# lower burst does not help, so I set quantum manually:
tc class add dev $DEV parent 1:1 classid 1:40 htb rate $[10*$UPLINK/100]kbit \
ceil $[20*$UPLINK/100]kbit burst 1k quantum 1514 prio 4
# Some get Stochastic Fairness:
#tc qdisc add dev $DEV parent 1:10 handle 10: esfq limit 64 depth 64 divisor 10 hash classic perturb 20
tc qdisc add dev $DEV parent 1:20 handle 20: esfq limit 64 depth 64 divisor 10 hash classic perturb 99
tc qdisc add dev $DEV parent 1:30 handle 30: esfq limit 64 depth 64 divisor 10 hash classic perturb 20
tc qdisc add dev $DEV parent 1:40 handle 40: esfq limit 64 depth 64 divisor 10 hash classic perturb 20
###### Accelerate (interactive) the following:
# To speed up downloads while an upload is going on, put ACK packets in
# the interactive class 1:10:
# IP header length 0x5 (32 bit words)
# IP total length 0x34 (ACK + 12 bytes of TCP options)
# TCP ACK set (bit 5, offset 33)
## Match ACK on all TCP packets with the ACK bit set:
## Caveat!: This matches packets up to 64K bytes. Don't do it; match small.
#tc filter add dev $DEV parent 1: protocol ip prio 5 u32 \
# match ip protocol 6 0xff \
# match u8 0x10 0xff at 33 \
# flowid 1:10
# Match TCP packets smaller than 128 bytes:
# Because of the mask, can only match powers of 2 (32, 64, 128...)
# 0xfff8 - 8
# 0xfff0 - 16
# 0xffe0 - 32
# 0xffc0 - 64
# 0xff80 - 128
# Remarked out ACK, normally 5th line: match u8 0x10 0xff at 33 \
# "match u8 0x05 0x0f at 0" makes sure the IP header is 20 bytes.
tc filter add dev $DEV parent 1: protocol ip prio 5 u32 \
match ip protocol 6 0xff \
match u8 0x05 0x0f at 0 \
match u16 0x0000 0xff80 at 2 \
flowid 1:10
# Some traffic is preferred, so in our class 1:20:
for a in $HiPrioCIDR_Src; do
tc filter add dev $DEV parent 1: protocol ip prio 5 u32 \
match ip src $a flowid 1:20
done
for a in $HiPrioCIDR_Dst; do
tc filter add dev $DEV parent 1: protocol ip prio 5 u32 \
match ip dst $a flowid 1:20
done
for a in $HiPrioDPORT; do
tc filter add dev $DEV parent 1: protocol ip prio 5 u32 \
match ip dport $a 0xffff flowid 1:20
done
for a in $HiPrioSPORT; do
tc filter add dev $DEV parent 1: protocol ip prio 5 u32 \
match ip sport $a 0xffff flowid 1:20
done
###### Give these short shrift:
# Penalized traffic suffers a worse fate in our slowest class 1:40:
for a in $LoPrioDPORT; do
tc filter add dev $DEV parent 1: protocol ip prio 5 u32 \
match ip dport $a 0xffff flowid 1:40
done
for a in $LoPrioSPORT; do
tc filter add dev $DEV parent 1: protocol ip prio 5 u32 \
match ip sport $a 0xffff flowid 1:40
done
for a in $LoPrioCIDR_Src; do
tc filter add dev $DEV parent 1: protocol ip prio 5 u32 \
match ip src $a flowid 1:40
done
for a in $LoPrioCIDR_Dst; do
tc filter add dev $DEV parent 1: protocol ip prio 5 u32 \
match ip dst $a flowid 1:40
done
if [ -f /etc/firewall/shitlist ]; then
while read SLIST; do
SLIST=$(echo "$SLIST" | awk '{print $1}')
tc filter add dev $DEV parent 1: protocol ip prio 5 u32 \
match ip dst $SLIST flowid 1:40
done