I developed an app for android with the purpose of controlling the daily internet quota assigned to the user and, for this to succeed, I was asked to slow down the internet speed of some apps like facebook, youtube, etc, while maintaining full speed to other apps critical for the device and business purposes. The main reason for this is that, if the user exceeds his daily quota of internet – about 1GB per day – the system should slow down internet speed for some apps while maintaining it for others. The purpose of slowing down some of the apps, is a way of telling the user to stop using them, at least until a new quota of 1GB is assigned to him – usually on demand or the next day.
All the searches related to traffic control lead me to two well known LINUX components: TC and IPTABLES. This is the “official” description of these components:
TC: Traffic control is the name given to the sets of queuing systems and mechanisms by which packets are received and transmitted on a router. This includes deciding which (and whether) packets to accept at what rate on the input of an interface and determining which packets to transmit in what order at what rate on the output of an interface.
IPTABLES: used to set up, maintain, and inspect the tables of IPv4 packet filter rules in the Linux kernel. Several different tables may be defined. Each table contains a number of built-in chains and may also contain user-defined chains. Each chain is a list of rules which can match a set of packets. Each rule specifies what to do with a packet that matches. This is called a `target’, which may be a jump to a user-defined chain in the same table.
In other words, with TC I can create a set of rules that define the “speed” at which bytes (packets) are received on the device and, with iptables I can define which users/processes use the rules defined with TC. This is a rough explanation of my needs and obviously, you can do much more with these components. We’re not event scratching the surface here!
I decided to do a test using the device’s wifi connection and so, this is the TC script I created:
tc qdisc add dev wlan0 root handle 1:0 htb default 30;
tc class add dev wlan0 parent 1:0 classid 1:1 htb rate 20kbit;
tc class add dev wlan0 parent 1:1 classid 1:10 htb rate 20kbit ceil 20kbit;
The above script, basically creates a 20kbit limit on the wlan0 interface and, two classes that I will use with iptables. This 20kbit limit will be similar to a GSM data connection speed: slow and annoying.
Next, I had to get the name of the users associated with the running processes and, do a test with YouTube (one of the apps being blocked) so, to get all the details about YouTube’s process was very easy, just ran this adb shell command:
ps | grep com.google.android.youtube
Which returned the following details:
The string with the value u0_a99 is the user android associated with YouTube’s process. Fortunately, android creates a user for each process or you might say, for each running app.
Creating the iptables script was fairly easy:
iptables -A OUTPUT -o wlan0 -m owner --uid-owner u0_a99 -j CLASSIFY --set-class 1:10
ip6tables -A OUTPUT -o wlan0 -m owner --uid-owner u0_a99 -j CLASSIFY --set-class 1:10
The above commands are very easy to explain. It appends this rule to the OUTPUT chain, the -o wlan0 defines the output wifi interface, the -m owner defines the module being used and it’s options and, the final -j section specifies the target TC class being used 1:10.
I also used ip6tables here because after doing a netstat on the device, all active connections are ip6, here’e the output:
After doing this proof of concept, it was easy to develop a java solution to apply these shell scripts to the running apps.
If you want to know more about iptables, here’s the man page: http://ipset.netfilter.org/iptables.man.html
Traffic control: http://www.tldp.org/HOWTO/html_single/Traffic-Control-HOWTO/