this module is a hack.
i wanted bandwidth control for a few virtual hosts, but i did not like
the userland methods -- they were inaccurate and buggy. i wanted to
take advantage of the linux kernel traffic shaping which i was already
using for managing my bandwidth costs. all i needed was a way to "paint"
some packets from the webserver so that the traffic shaper could handle
i chose to abuse the IPTOS bits ("type of service") to do this. userland
is able to select IPTOS bits via setsockopt(2). this gives a communication
channel between the webserver and the traffic shaper, and makes me happy.
and so mod_iptos was born.
i've since learned that IPTOS are being updated/replaced by something
called DIFFSERV... and it sounds cool. but since my hack is in place and
working i haven't been motivated to go the next step with this module.
type-of-service bits in IP packets can be used for such things as
quality-of-service guarantees, or for traffic shaping. this module
allows you to set IP TOS bits on a per-directory basis (it'll also work
for location and files containers of course).
the four (legacy) TOS bits are:
ssh, for example, sets the lowdelay value for interactive ssh sessions
and sets throughput for all other sessions (i.e. for scp).
note that in ancient IP history you were permitted only to set none or
exactly one of those bits. however newer initiatives have attempted to
define this byte in completely different manners. see for example:
i personally find the whole mess rather confusing, and nothing smacks
of being the definitive protocol for use. to make matters worse, many
ISPs treat this byte as per-hop rather than end-to-end, which means that
no matter what you set in the byte it might not make it outside your ISP.
that's all fine -- all i care about is distinguishing requests in some
manner suitable for shaping... and presumably you control all the network
between your webserver and your traffic shaper.
mod_iptos supports two commands:
IPTOSthreshold num_bytes tos_specification
a tos_specification is either one of lowdelay, throughput, reliability,
lowcost, or an integer (leading 0 means octal, leadign 0x means hex).
the integer allows you to follow whatever protocol you want for the
definition of the tos field.
the IPTOS command sets the default IPTOS which applies to all responses.
the IPTOSthreshold lets you specify a number of bytes above which a
(static only) response will be tagged with a different TOS. (i find
this easier than trying to keep up with my users naming large media
files with a zillion extensions.)
to disable an IPTOSthreshold (i.e. in a nested configuration) use
"IPTOSthreshold 0 none".
# default to IPTOS none, but files larger than 5MB are marked
IPTOSthreshold 5000000 throuhgput
# this website is overloaded, put all of its traffic in the lower
# priority throughput bucket
# this website is special -- and we override the global threshold
IPTOSthreshold 0 none
for testing there are really two tools... tcpdump is one way (you need
to specify the -v option to see the TOS field). strace is another
way -- i use this in combination with apache's -X debugging option...
this really only works on a port that has no other traffic.
note that when multiple small responses occur together in one connection
apache may merge the traffic into a single write() to the kernel... and
mod_iptos may change the TOS bits multiple times before that write
occurs... only the last setting actually affects packets. there's nothing
to be done about this really ... so just don't expect to use IPTOS for
any sort of accounting, because it's very lossy. it really just works
well for distinguishing heavy traffic sites.
use with linux traffic shaping:
i refer you to http://www.lartc.org/ ... but, an example config using
HTB and SFQ designed to go with the above example apache config might
look something like this:
# we have 3mbit of bandwidth, and we divide it up into 1mbit
# chunks -- 1mbit for "lowdelay" stuff, 1mbit for "throughput" stuff,
# and 1mbit for everything else.
F="$tc filter add dev eth0 protocol ip parent 1:"
$tc qdisc add dev eth0 root handle 1: htb default 4 r2q 5
$tc class add dev eth0 parent 1: classid 1:1 htb rate 3mbit ceil 3mbit
# the lowdelay bin
$tc class add dev eth0 parent 1:1 classid 1:2 htb rate 1mbit prio 20
$tc qdisc add dev eth0 parent 1:2 handle 2: sfq perturb 10
$F prio 2 u32 match ip tos 0x10 0xff flowid 1:2
# the throughput bin
$tc class add dev eth0 parent 1:1 classid 1:3 htb rate 1mbit prio 40
$tc qdisc add dev eth0 parent 1:3 handle 3: sfq perturb 10
$F prio 2 u32 match ip tos 0x08 0xff flowid 1:3
# the everything else bin
$tc class add dev eth0 parent 1:1 classid 1:4 htb rate 1mbit prio 40
$tc qdisc add dev eth0 parent 1:4 handle 4: sfq perturb 10
$F prio 10 flowid 1:4
Apache/2.4.25 (Debian) Server at arctic.org Port 80