On asymmetric Internet links like DSL and often Cable, a big upload that consumes all of the available upstream bandwidth can render the link almost unusable by producing a huge backlog in the DSL/Cable modem's buffer, thus increasing the delay to several seconds. Because ACK packets (TCP acknowledgments) for received data are delayed or even lost as well, download speed drops, too.
This problem can be solved by prioritizing these ACK packets, so they will be sent out before any other upload packets. Here's how to do it with m0n0wall:
First of all, you need m0n0wall pb24 or later. Start by adding a new pipe to the traffic shaper. This is necessary because we need to move the upstream queue into m0n0wall (where the order in which packets are sent out can be changed while packets are in the queue) rather than the DSL/Cable modem. Once the packets are in the DSL/Cable modem's output queue, there's no way of having ACK packets sent out immediately anymore. Therefore, it is very important to set that pipe's bandwidth to a value that is slightly below the effective upstream bandwidth of your Internet link. Don't forget that e.g. 128 kbps ADSL line speed is only about 100 kbps effective. If you set this value too high, your modem buffer will still become full and prioritization will accomplish nothing.
When you have added that pipe, add two queues linked to that pipe with different weights, e.g. one queue with weight = 10 and one with weight = 1. The first queue becomes your high priority queue.
Now it's time to add rules that classify upstream traffic into one of these two queues. There are loads of possibilities, e.g. prioritizing by TCP/UDP port, but for now we'll focus on IP packet length and TCP flags. Add a new traffic shaper rule, link it to the first (high-priority) queue, interface = WAN, protocol = TCP, source = any, destination = any, direction = out, IP packet length 0-80, TCP flags: ACK = set, everything else = don't care. It is not sufficient to classify packets into the high-priority queue based on the ACK flag only, because (big) upstream TCP data packets can have the ACK flag set as well. 0-80 is just an example to get you started. Save the rule, and add another one below it, linked to the second (low priority) queue, interface = WAN, protocol = any, source = any, destination = any, direction = out. Enable the traffic shaper if necessary, apply the changes - that's it. Here are a few points to remember:
make sure no upstream Internet traffic can bypass the pipe
despite ACK prioritization, the delay will still go up, as it is not possible to stop sending a big packet mid-way. For example, a full-size (1500 bytes) packet at 100 kbps will take 120 ms
if you want to be able to surf the web while performing a large upload, you'll also have to prioritize HTTP upstream traffic (i.e. destination port = 80) - otherwise, TCP SYN packets (for connection establishment) to web servers will not get prioritized, and there will be a big initial delay until a connection is established. Prioritizing DNS packets is a good idea as well.
If you want to find out what prioritization does for you, add a rule to classify outgoing ICMP packets into the high-priority queue and try pinging some Internet host while you're uploading - once with the traffic shaper on, and once off. There should be a huge difference in response times.