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 !
19 responses to “Modified Wondershaper for better VOIP QOS”
Leave a Reply
You must be logged in to post a comment.
[…] imposée par Wondershaper à ma ligne ADSL encombrée une qualité de service suffisante pour que le…, j’ai configuré Asterisk pour le service Freephonie en SIP, j’ai imaginée puis mise […]
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.
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?
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.
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 : 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
what are the kernel/iptabled modules that I have must load?
thanks
Standard kernel configuration should be enough.
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!
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.
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?
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
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 =0x18
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
I’ve modified the opensuse package files which use an /etc/sysconfig/wondershaper for variable definitions…a /etc/init.d/wondershaper for start, stop etc of the service and wshaper.htb which contains your code. I’ve also added the commands “dumpconf” and “qos-status” vs status which systemd intercepts and gives different results….however when doing a qos status I don’t ever see the 1:30 qdisc showing any activity..even when I just finished downloading a torrent via utorrent…it has me perplexed and I’ve checked and rechecked the code. I’ve uploaded my files to http://www.2shared.com/file/LSqj6RW9/wondershaper.html The service DOES seem to improve things..it just only uses 1:10 and 1:20….
qdisc htb 1: root refcnt 2 r2q 10 default 20 direct_packets_stat 0
Sent 498468175 bytes 2293490 pkt (dropped 15, overlimits 331625 requeues 0)
backlog 0b 0p requeues 0
qdisc sfq 10: parent 1:10 limit 127p quantum 1558b depth 127 divisor 1024 perturb 10sec
Sent 3001277 bytes 16082 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc sfq 20: parent 1:20 limit 127p quantum 1558b depth 127 divisor 1024 perturb 10sec
Sent 495466898 bytes 2277408 pkt (dropped 37, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc sfq 30: parent 1:30 limit 127p quantum 1558b depth 127 divisor 1024 perturb 10sec
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc ingress ffff: parent ffff:fff1 —————-
Sent 2661196071 bytes 2675876 pkt (dropped 57623, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
[…] Install wondershaper: “apt-get install wondershaper”. I used the improved version of wondershaper from here: http://serendipity.ruwenzori.net/index.php/2008/06/01/modified-wondershaper-for-better-voip-qos. […]
In case this helps anyone else;
I am running asterisk utilizing IAX2 between sites. I initially downloaded this script in the hopes of reducing the clipping in the audio, and it did help a bit but it wasn’t perfect, despite tuning it as best I could. So I went digging and found this:
$U32rootfilter prio 1 u32 match ip tos 0x68 0xff match ip protocol 0x11 0xff flowid 1:10
Which the comment lead me to believe was for VoIP traffic. However, what’s interesting is that ip protocol is 0x11, which is defined in /etc/protocols as Network Voice Protocol. However, both SIP and IAX2 utilize UDP ( defined in /etc/protocols as 0x17 ).
Armed with this knowledge, I modified the script to change that 0x11 to 0x17 ( in a few different places ). I also turned on asterisk’s ability to add the “ef” ToS to IAX2 traffic. Now, no matter how congested the line becomes, my voice traffic doesn’t stutter.
[…] may have even downloaded this, configured it correctly and run it. If you found the same script I did, then you probably found it did an OK job, but it didn’t solve all of your issues. […]
[…] Install wondershaper: “apt-get install wondershaper”. I used the improved version of wondershaper from here: http://serendipity.ruwenzori.net/index.php/2008/06/01/modified-wondershaper-for-better-voip-qos. […]
[…] Install wondershaper: “apt-get install wondershaper”. I used the improved version of wondershaper from here: http://serendipity.ruwenzori.net/index.php/2008/06/01/modified-wondershaper-for-better-voip-qos. […]