#!/bin/sh # # SuperShaper-SOHO 1.2 # # Bandwidth shaper for SOHO DSL connection. # # Copyright (C) Robin Smidsrød September 24 2004 # License details can be found on www.smidsrod.no # # Please consider donating if you find this script helpful. # Contact information available on www.smidsrod.no. # # If you need help setting up this script, or have other # problems related to Linux networking, I'm available # for contracting. Contact me at robin@smidsrod.no or see # contact information on www.smidsrod.no. # # This script is designed to shape your upstream bandwidth to # minimize latency for interactive applications like SSH and making # sure P2P applications doesn't saturate your upstream. Standard surfing/mail # software is also given priority over P2P to make them snappy. # VoIP is given maximum priority (SIP/RTP) (only surpassed by TCP ACKs) to make # sure IP telephony doesn't suffer even on a very congested link. # # Ingress filtering is not applied at all, since it would have little # effect on the final result. Let's stick to egress which works. # # This script needs iproute2 (tc) and HTB/SFQ netfilter schedulers (linux kernel >=2.4.20) # This script has been verified to work out of the box on IPCop-1.3.0_fixes9, # which is the preferred deployment platform. # # Please verify the ports for P2P software if they're non-standard. # # Queue classes are set up to handle this kind of traffic in prioritized order: # # 10: TCP/ACK # 20: VoIP (sip tos 0x68/rtp tos 0xb8) # 30: tos_minimum_delay 0x10 / tos_maximum_reliability 0x04 # 40: ICMP/DNS/Shoutcast/tos_minimum_cost 0x02/IMAP/SMTP/POP3/HTTP/FTP/Usenet/SSH/tos_maximum_throughput 0x08 # 50: P2P (BitTorrent/eMule/DirectConnect/Kazaa/Gnutella) # 60: default / bulk traffic # # Change these values to reflect your own setup # Your outbound interface DEV=eth1 # Your upstream capacity in kbit #UPLINK_REAL=704 UPLINK_REAL=551 # DSL modems usually have large queues. That breaks latency. Set this as high as your DSL # modem can handle without queuing packets itself. This value is in percent. # I usually saturate the upstream with traffic/uploads and use iptraf to measure the outbound traffic # on the interface to determine when the shaping takes effect. If iptraf reports higher bandwidth than # your calculated bandwidth (see UPLINK below) you modem is probably still queuing packets. This can # only be set by trial an error, but 90% is probably a good ballpark number. UPLINK_PERCENT=90 # Calculate actual max bandwidth UPLINK=$[UPLINK_PERCENT*UPLINK_REAL/100] # Set how much bandwidth to use for each class UPLINK_10_R=$UPLINK UPLINK_20_R=$UPLINK UPLINK_30_R=$UPLINK UPLINK_40_R=$[9*UPLINK/10] UPLINK_50_R=$[1*UPLINK/10] UPLINK_60_R=$[5*UPLINK/10] # The same as above, but here you set the ceiling, ie. how much a class is allowed to borrow from another UPLINK_10_C=$UPLINK UPLINK_20_C=$UPLINK UPLINK_30_C=$UPLINK UPLINK_40_C=$[9*UPLINK/10] UPLINK_50_C=$[5*UPLINK/10] UPLINK_60_C=$[8*UPLINK/10] # DirectConnection port # In newer versions of DC++ there is no default. # Please set your port used in DC++ here. PORT_DC=20000 # Additional BitTorrent port # The standard BitTorrent port is already defined. PORT_BT=50000 # Additional ED2K ports # The standard ED2K and Kademelia ports are already defined. PORT_ED2K_TCP=30000 PORT_ED2K_UDP=40000 # Set full path to TC command, unless it's in PATH TC=tc ################### Nothing to change below this line unless you're adventurous ############### # Remove existing qdisc $TC qdisc del dev $DEV root 2>&1 >/dev/null ################### QUEUE DISCIPLINES # Add root qdisc $TC qdisc add dev $DEV root handle 1: htb default 60 # Add master qdisc $TC class add dev $DEV parent 1: classid 1:1 htb rate ${UPLINK}kbit # Add prio 0 queue (highest) $TC class add dev $DEV parent 1:1 classid 1:10 htb rate ${UPLINK_10_R}kbit ceil ${UPLINK_10_C}kbit prio 0 $TC qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10 # Add prio 1 queue $TC class add dev $DEV parent 1:1 classid 1:20 htb rate ${UPLINK_20_R}kbit ceil ${UPLINK_20_C}kbit prio 1 $TC qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10 # Add prio 2 queue $TC class add dev $DEV parent 1:1 classid 1:30 htb rate ${UPLINK_30_R}kbit ceil ${UPLINK_30_C}kbit prio 2 $TC qdisc add dev $DEV parent 1:30 handle 30: sfq perturb 10 # Add prio 3 queue $TC class add dev $DEV parent 1:1 classid 1:40 htb rate ${UPLINK_40_R}kbit ceil ${UPLINK_40_C}kbit prio 3 $TC qdisc add dev $DEV parent 1:40 handle 40: sfq perturb 10 # Add prio 4 queue (lowest) $TC class add dev $DEV parent 1:1 classid 1:50 htb rate ${UPLINK_50_R}kbit ceil ${UPLINK_50_C}kbit prio 4 $TC qdisc add dev $DEV parent 1:50 handle 50: sfq perturb 10 # Add prio 5 queue (default queue) $TC class add dev $DEV parent 1:1 classid 1:60 htb rate ${UPLINK_60_R}kbit ceil ${UPLINK_60_C}kbit prio 5 $TC qdisc add dev $DEV parent 1:60 handle 60: sfq perturb 10 ################### FILTERS # CLASS 10: TCP/ACK $TC filter add dev $DEV protocol ip parent 1: prio 1 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 \ match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 flowid 1:10 # CLASS 20: VoIP (prio 1) (SIP/skinny packets) $TC filter add dev $DEV parent 1: protocol ip prio 1 u32 match ip tos 0x68 0xff flowid 1:20 $TC filter add dev $DEV parent 1: protocol ip prio 1 u32 match ip tos 0x58 0xff flowid 1:20 $TC filter add dev $DEV parent 1: protocol ip prio 1 u32 match ip tos 0x28 0xff flowid 1:20 $TC filter add dev $DEV parent 1: protocol ip prio 1 u32 match ip tos 0x38 0xff flowid 1:20 $TC filter add dev $DEV parent 1: protocol ip prio 1 u32 match ip sport 5060 0xffff flowid 1:20 # CLASS 20: VideoConferencing (prio 1) (SquidCam) $TC filter add dev $DEV parent 1: protocol ip prio 1 u32 match ip sport 16967 0xffff flowid 1:20 $TC filter add dev $DEV parent 1: protocol ip prio 1 u32 match ip sport 16968 0xffff flowid 1:20 $TC filter add dev $DEV parent 1: protocol ip prio 1 u32 match ip sport 16969 0xffff flowid 1:20 # CLASS 20: VoIP (prio 2) (RTP data) $TC filter add dev $DEV parent 1: protocol ip prio 2 u32 match ip tos 0xb8 0xff flowid 1:20 $TC filter add dev $DEV parent 1: protocol ip prio 2 u32 match ip sport 16384 0xffff flowid 1:20 # CLASS 30: IP TOS 0x10 (prio 1) (minimum delay) $TC filter add dev $DEV parent 1: protocol ip prio 1 u32 match ip tos 0x10 0xff flowid 1:30 # CLASS 30: IP TOS 0x04 (prio 2) (maximum reliability) $TC filter add dev $DEV parent 1: protocol ip prio 2 u32 match ip tos 0x04 0xff flowid 1:30 # CLASS 30: World Of Warcraft (prio 3) (TCP/3724 and TCP/6112) $TC filter add dev $DEV parent 1: protocol ip prio 3 u32 match ip dport 3724 0xffff flowid 1:30 $TC filter add dev $DEV parent 1: protocol ip prio 3 u32 match ip dport 6112 0xffff flowid 1:30 # CLASS 40: ICMP (prio 1) $TC filter add dev $DEV parent 1: protocol ip prio 1 u32 match ip protocol 1 0xff flowid 1:40 # CLASS 40: DNS (prio 2) $TC filter add dev $DEV parent 1: protocol ip prio 2 u32 match ip dport 53 0xffff flowid 1:40 # CLASS 40: Shoutcast (prio 3) $TC filter add dev $DEV parent 1: protocol ip prio 3 u32 match ip dport 8000 0xffff flowid 1:40 # CLASS 40: IP TOS 0x02 (prio 4) (minimum cost) $TC filter add dev $DEV parent 1: protocol ip prio 4 u32 match ip tos 0x02 0xff flowid 1:40 # CLASS 40: IMAP (prio 5) (with and without SSL) $TC filter add dev $DEV parent 1: protocol ip prio 5 u32 match ip dport 143 0xffff flowid 1:40 $TC filter add dev $DEV parent 1: protocol ip prio 5 u32 match ip dport 220 0xffff flowid 1:40 $TC filter add dev $DEV parent 1: protocol ip prio 5 u32 match ip dport 993 0xffff flowid 1:40 # CLASS 40: SMTP (prio 6) (with and without SSL) $TC filter add dev $DEV parent 1: protocol ip prio 6 u32 match ip dport 25 0xffff flowid 1:40 $TC filter add dev $DEV parent 1: protocol ip prio 6 u32 match ip dport 465 0xffff flowid 1:40 # CLASS 40: POP (prio 7) (with and without SSL) $TC filter add dev $DEV parent 1: protocol ip prio 7 u32 match ip dport 106 0xffff flowid 1:40 $TC filter add dev $DEV parent 1: protocol ip prio 7 u32 match ip dport 109 0xffff flowid 1:40 $TC filter add dev $DEV parent 1: protocol ip prio 7 u32 match ip dport 110 0xffff flowid 1:40 $TC filter add dev $DEV parent 1: protocol ip prio 7 u32 match ip dport 995 0xffff flowid 1:40 $TC filter add dev $DEV parent 1: protocol ip prio 7 u32 match ip dport 1109 0xffff flowid 1:40 # CLASS 40: HTTP (prio 8) (with and without SSL) $TC filter add dev $DEV parent 1: protocol ip prio 8 u32 match ip dport 80 0xffff flowid 1:40 $TC filter add dev $DEV parent 1: protocol ip prio 8 u32 match ip dport 443 0xffff flowid 1:40 # CLASS 40: FTP (prio 9) (with and without SSL) $TC filter add dev $DEV parent 1: protocol ip prio 9 u32 match ip dport 20 0xffff flowid 1:40 $TC filter add dev $DEV parent 1: protocol ip prio 9 u32 match ip dport 21 0xffff flowid 1:40 $TC filter add dev $DEV parent 1: protocol ip prio 9 u32 match ip dport 115 0xffff flowid 1:40 $TC filter add dev $DEV parent 1: protocol ip prio 9 u32 match ip dport 2431 0xffff flowid 1:40 $TC filter add dev $DEV parent 1: protocol ip prio 9 u32 match ip dport 2433 0xffff flowid 1:40 # CLASS 40: Usenet (prio 10) $TC filter add dev $DEV parent 1: protocol ip prio 10 u32 match ip dport 119 0xffff flowid 1:40 # CLASS 40: SSH (prio 11) (without tos bit set, caters for buggy clients like PuTTY and ssh.com windows client) $TC filter add dev $DEV parent 1: protocol ip prio 11 u32 match ip dport 22 0xffff mat ip tos 0x00 0xff flowid 1:40 # CLASS 40: IP TOS 0x08 (prio 12) (maximum throughput) $TC filter add dev $DEV parent 1: protocol ip prio 12 u32 match ip tos 0x08 0xff flowid 1:40 # CLASS 40: HTTP outbound (prio 13) $TC filter add dev $DEV parent 1: protocol ip prio 13 u32 match ip sport 80 0xffff flowid 1:40 # CLASS 50: BitTorrent (prio 1) $TC filter add dev $DEV parent 1: protocol ip prio 1 u32 match ip sport 6881 0xffff flowid 1:50 $TC filter add dev $DEV parent 1: protocol ip prio 1 u32 match ip sport $PORT_BT 0xffff flowid 1:50 # CLASS 50: eMule (prio 2) $TC filter add dev $DEV parent 1: protocol ip prio 2 u32 match ip sport 4661 0xffff flowid 1:50 # eMule TCP $TC filter add dev $DEV parent 1: protocol ip prio 2 u32 match ip sport 4662 0xffff flowid 1:50 # eMule TCP $TC filter add dev $DEV parent 1: protocol ip prio 2 u32 match ip sport 4663 0xffff flowid 1:50 # eMule TCP $TC filter add dev $DEV parent 1: protocol ip prio 2 u32 match ip sport 4672 0xffff flowid 1:50 # eMule UDP $TC filter add dev $DEV parent 1: protocol ip prio 2 u32 match ip sport 4711 0xffff flowid 1:50 # eMule Webserver $TC filter add dev $DEV parent 1: protocol ip prio 2 u32 match ip sport 5768 0xffff flowid 1:50 # Overnet $TC filter add dev $DEV parent 1: protocol ip prio 2 u32 match ip sport $PORT_ED2K_TCP 0xffff flowid 1:50 # eMule TCP - custom $TC filter add dev $DEV parent 1: protocol ip prio 2 u32 match ip sport $PORT_ED2K_UDP 0xffff flowid 1:50 # eMule UDP - custom # CLASS 50: DirectConnect (prio 3) $TC filter add dev $DEV parent 1: protocol ip prio 3 u32 match ip dport 411 0xffff flowid 1:50 # Hub connection $TC filter add dev $DEV parent 1: protocol ip prio 3 u32 match ip sport 1412 0xffff flowid 1:50 # Default transfer/search port $TC filter add dev $DEV parent 1: protocol ip prio 3 u32 match ip sport $PORT_DC 0xffff flowid 1:50 # Custom transfer/search port # CLASS 50: Kazaa (prio 4) $TC filter add dev $DEV parent 1: protocol ip prio 4 u32 match ip sport 6699 0xffff flowid 1:50 # CLASS 50: Gnutella (prio 5) $TC filter add dev $DEV parent 1: protocol ip prio 5 u32 match ip sport 6346 0xffff flowid 1:50 ################### PRINT OUT SETTINGS # Report settings echo "************************* QDISC ******************************" $TC qdisc show dev $DEV echo "************************* CLASS ******************************" $TC class show dev $DEV # Disabled cause output is quite cryptic, anyone now a more readable way to report this? #echo "************************* FILTER *****************************" #$TC filter show dev $DEV