surf speed os x.. ... n_mac_os_x

Mac Geekery - Traffic Shaping in Mac OS X</a>
By codepoet » Posted on December 18, 2005 - 1:38am

As a result of a previous question I was informed that Tiger finally has dummynet support in the kernel. What this means to you is that now you can do traffic shaping with no additional software.

Here's how the idea works: you create several pipes that have a set bandwidth and other properties for all packets that get filed into them; you then add queues to those pipes that determine what priority certain requests will get in that pipe; then you add actual firewall rules to identify packets and file them into queues.

So let's say you create a pipe with 1Mbit/s of allowed traffic. Within this you would setup three queues: one for high-priority services like incoming mail, DNS requests, and such; one for medium priority services like web and FTP; then one for low-priority services like file sharing and other network "noise". With this setup you would, on a saturated pipe have a large amount of traffic coming in and going out for web and FTP, giving it priority over the noise, and when someone wanted to talk about mail or DNS those would have a higher chance of getting handled quickly. It's a good boost in chance, but keep in mind that traffic shaping is not Quality of Service (QoS). Traffic shaping introduces delays in lower-priority packets so that higher-priority packets get in faster, but it offers no advanced logic or guarantees on delivery. If you want QoS, use either a userspace filter that does this or another kernel (like Linux) that has this built-in. For home and moderate server use, shaping is more than acceptable.

Okay, some demonstrations are in order here. Let's take a typical example, such as the one from the question given, and say that you're on DSL and your upload is 384k (this is mine) and you want email uploads to only take up 300k of that so you can actually do other things. So, we create a pipe with a 300kbit/s limit for all traffic I send to it:

The hash symbol means you'll need to be root.

# ipfw pipe 1 config bw 300kbit/s

We have a pipe now. Now we need to setup some queues for priority in this pipe. Because we set the pipe to be lower than the actual upload bandwidth, any traffic that isn't caught by this will go through on that extra 84kbit/s of bandwidth, so we don't need a queue for this example as nothing will be sharing this pipe; we only need one rule to catch this traffic:

# ipfw add pipe 1 dst-port smtp

This catches inbound SMTP traffic, too, if you run an SMTP server. But, of course, that's the point: we don't want mail to take over.

Now, of course, if you wanted to limit POP/IMAP traffic to the same queue, you could:

# ipfw add pipe 1 dst-port pop3
# ipfw add pipe 1 dst-port pop3s
# ipfw add pipe 1 dst-port imap
# ipfw add pipe 1 dst-port imaps

Now every mail-related transaction will be filed into the limited pipe causing the system to have some leftover upstream bandwidth for browsing.

Of course, within this one could see some problems. Sending a large mail will not affect web browsing, but would affect mail retrieval since they're in the same pipe, so we need a queue for incoming and one for outgoing so that there's some control over that share of bandwidth. You could do this with multiple pipes, but then you're cutting out a swath of bandwidth for incoming that outbound can't use (presuming you make two 150k pipes).

So, one would do this:

# ipfw pipe 1 config bw 300kbit/s
# ipfw queue 1 config pipe 1 weight 50
# ipfw queue 2 config pipe 1 weight 50

Now we have an equal weight between the two services. You can go from 1 to 100 on the weights if you like, but for this I'd like an even traffic stream on each. When one is finished, the other will get the full pipe. So, we add the rules in:

# ipfw add queue 1 dst-port smtp
# ipfw add queue 2 dst-port pop3
# ipfw add queue 2 dst-port pop3s
# ipfw add queue 2 dst-port imap
# ipfw add queue 2 dst-port imaps

All inbound mail goes through queue 2 and all outbound mail goes through queue 1. Each is given a high chance of getting half the bandwidth allotted to pipe 1.

You can, obviously, have a lot of fun with this, but there's also some serious fun to be had. Web designers: ever wonder what it's like to load your site at 56k, or 33, 28, 14, or even 9600? Do this:

# ipfw pipe 1 config bw 56kbit/s
# ipfw add pipe 1 dst-port http

Now browse the web like a modem user. This, obviously, only works for sites served on port 80, but it does work. For the record, MG should be very usable on a modem. Smiling

If you've had fun playing, or locked yourself out at some point, just flush the rules:

# ipfw flush

All of this requires Mac OS X 10.4 or a FreeBSD with dummynet support. Anything else will laugh at you and order Yanni CDs from Amazon and send them to all of your friends for Christmas right before erasing the data on your computer in a spectacular flash of light that will blind you and your progeny. Best not to try. Specifically, it'll either error out or appear to work and drop packets. The Yanni fate might be worse, so don't risk it.