… is far from trivial: you are not on the senders side, and not every protocol (in fact very few) allow rate limiting. Not to speak of limiting the total of multiple connections. Basically you’ll have to accept that the sender is sending the data at it’s own pace.

However, the TCP part of “TCP/IP” is designed in a way that it does a fairly good job at detecting bottlenecks. The basic principle is this: when a packet is received at the destination, a confirmation will be sent back. By adjusting the rate of packets going out to match the rate of incoming “received” message (and to minimize the number of lost packets that need to be resent), TCP/IP connection can adopt to the slowest link in the chain.

This is how incoming traffic shaping works: incoming packets are held back (or even dropped; however holding back packets might also lead to dropped packets somewhere up the stream), which in turn will limit the speed “ACKs” go out, and thus (hopefully) the speed data is pushed down to us.

It’s not perfectly reliable, and by design won’t work well with short-lived connections and non-TCP-traffic. But it can still come in handy.

We have a shared internet connection with 2 mBit. That usually is fine, but our router isn’t very smart. When I’m using up all bandwidth for a longer timeframe (say, apt-get upgrade with new openoffice and tetex), the other users will suffer from a serious performance impact. One of them is often playing games online, and eventually gets kicked out of a game server because of his bad roundtrip times. By limiting my incoming traffic rate, I can hopefully keep the connection useful enough for him. In my tests, it worked pretty good at keeping my bandwidth useage down. The remaining unused bandwidth should allow his game data to pass through without larger extra delays.

Here’s the short script I’m using:

tc qdisc replace dev ethWIFI handle ffff: ingress
tc filter replace dev ethWIFI parent ffff: protocol ip prio 50 \
  u32 match ip src 0.0.0.0/0 police rate 1500kbit \
  burst 10k drop flowid :1
tc qdisc replace dev ethWIFI root tbf \
  rate 1500kbit latency 25ms burst 10k

Don’t forget to adopt it to your needs, you probably havn’t renamed your interface to ethWIFI and might want a different valye than 1500kbit.