Modified Wondershaper for better VOIP QOS
Ever since the Linux Advanced Routing & Shaping HOWTO introduced it, I have been a big fan of the Wondershaper, a traffic shaping script that drives Linux‘s class based queuing with stochastic fairness queuing (SFQ) in a pretty effective attempt at maintaining low latency for interactive traffic while at the same time maintaining high throughput. There is even a ‘wondershaper’ Debian package that includes some additional polish. This script is key to the joy of perfectly responsive SSH sessions while peer to peer file sharing traffic saturates the uplink.
Some people have even concluded the resulting quality of service is good enough for voice traffic. But even with the Debian Wondershaper ruling my ADSL link I noticed that SIP and IAX still suffer too much packet loss with the saturating traffic occupying the background. I needed better traffic control.
As usual, being a late adopter I am not the only one to have hit that obstacle, and solutions have already been put forth. After rummaging through various mutations, I found Robert Koch’s version of the Wondershaper for the Asus WL-xxx documented on the Wondershaper package page of the WL-500G wiki to be quite promising. Compared to the standard version it prioritizes VOIP traffic by source port for idiot proof configuration, but also by type of service which is much more flexible and can be used thanks to Asterisk being capable of correctly setting TOS fields. As a bonus, using TOS also makes this version of the script capable of distinction between console interactive SSH traffic and bulk SCP traffic using the same protocol and port. And to top it all, it is based on the better hierarchical token bucket (HTB) discipline which is standard since Linux 2.4.20 while the Debian Wondershaper version uses the more based queuing which used to be the more widespread one.
The first shortcoming I found is that it prioritizes SIP and RTP but not IAX and others which I’ll have to add using the SIP stanzas as templates. The other is that taking lists of low priority ports as arguments could make the command line messy and configuration puzzling for the inexperienced user, so I prefer to have this configuration item as a documented variable allocation inside the script. But those are trifles compared to the new VOIP support, enhanced SSH discrimination and overall upgrade.
Hacking on the script I couldn’t resist reorganizing a few things. I originally intended to provide a diff, but that would be pointless since I ended up touching most of the lines. Also be warned that I do not understand why putting ‘prio 1′ everywhere makes the script work whereas other ‘prio’ values at various places made traffic end up in the wrong class and did not make sense at all. In effect, I think that by putting ‘prio 1′ everywhere I just eschewed the use of priority bands inside the classes, which is just fine with me for the intended use. But this show that my tc fluency is still limited and that there are therefore surely ways to enhance this script. I’ll also welcome feedback – whether it works for you or not.
Anyway – it works ! I had a few VOIP conversations across an IAX trunk with lots of background traffic on the uplink and no perceptible effects on voice quality. Life is good. Now that I have removed the last obstacle to taking full advantage of VOIP at home. Soon all my traffic will be routed through Asterisk and there shall be no more RJ11 nor their French T-sockets alter ego in my home.
Here is my modified wondershaper script in all its glory – contrary to Robert Koch’s version it is a drop-in replacement for Debian’s package. Inheriting from the original Wondershaper it is licensed under the GPL so enjoy, modify and share !
Very nice, Im still using a slightly tweaked original wondershaper but I have almost the exact same needs as you so I will try yours.
The only problem with this is the “policing” at the end: dropping packets is not that efficient and results in uneven speeds. It is now possible with linux to shape incoming traffic and not just police it. I cant remember what the name of the device is that allows it, but if I come up with a better way of doing it I will post it back here.
John Bäckstrand
I have some questions for you….
1) it work on slackware 12.1 Linux version 2.6.24.5-grsec … ?
2) i have a small network about 20 pc, they ar using a lot of torrents, and eat all bandwidth … i want to limit the upload traffic so get rid of torrents traffic, i use htb but torrents eat all bandwidth … some help?
Silviu florian
No reason why it would not work on Slack as long as you have the right programs.
I don’t know enough about torrents to tell exactly what should be done, but as a general rule you can always add some ports to a lower priority band – or if the bandwidth hogs are not so easily identified you can take a whitelist approach with the ports to whom you want to grand priority.
Jean-Marc Liotier
Hi,
i really want to use your updated wondershaper, but i came across some issues. While using original debian package i get it working, but using your drop-in replacement causes no response for
“sudo wondershaper X”
this is my system
uname -a
Linux Ubuntu-client 2.6.24-21-generic #1 SMP Tue
Matej Zabrady
@Matej : you use only one argument – there are three arguments to the script : ‘wondershaper [interface] [download rate] [upload rate]‘
On my systems, I call it from /etc/network/interfaces :
auto eth1
iface eth1 inet dhcp
up /wondershaper eth1 6092 640
Jean-Marc Liotier
what are the kernel/iptabled modules that I have must load?
thanks
Antonio
Standard kernel configuration should be enough.
Longspear
Thanks Jean-Marc,
I’m hoping this works for our network, I’ve just put it in place and we’ll see how it goes. Quality was improved a little with the basic wondershaper, but not as good as it could be…
Also, you may want to add to the top of the comment in the script about the usage for status.
In the original wondershaper you can get the status by issuing ‘wondershaper device’, but in yours, it’s ‘wondershaper device status’…
Just a thought, thanks again!
lucidblue
For lack of an obvious coordination point, it looks like the original Wondershaper has spawned many variations such as mine which is not even based in the original one… So I’m not surprised that such inconsistencies exist. Maybe someone should catch that ball and set up some revision control system to gather a synthesis of the mutations. And then there are the distribution’s idiosyncrasies to deal with.
Jean-Marc Liotier
I am trying to run this wonderful script on my Broadcom BCM6358 ADSL router (with 64M memory) with embedded linux 2.6.8.1, I always get router crash and reboot if executing the following lines:
tc qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10
tc qdisc add dev $DEV parent 1:30 handle 30: sfq perturb 10
But, if I comment out the 3rd one, then it will not crash. Quite strange!
Any idea?
Weihua Jiang
After patching my 2.6.8.1 kernel with this patch http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-08/5595.html, wondershaper no longer cause my router to crash.
However, I still get following warnings and errors:
HTB init, kernel part version 3.17
HTB: quantum of class 10030 is small. Consider r2q change.
RTNETLINK answers: Invalid argument
RTNETLINK answers: Invalid argument
whjiang
Hi
please some body help me to modify this script
http://www.ruwenzori.net/code/wondershaper/wondershaper.jml
To My Needs Which Are
ubuntu 10.04 running asterisk 10 sitting tos =0×18
tos = ef or can sit any value
wireless access point 300kbit/s
10 users having android sip software
there is no switches no routers [in my WLAN]
IS THIS SCRIPT RUNNING IN ENVIRONMENT WITH NO switches and routers
ZAKI SHAN