Version 1.0/3.3, 15.09.2009
The shaping of incoming traffic shall be enabled by shaping outgoing control messages (ACK packets).
The natural limitation of current traffic shaping technology is that only outgoing traffic can be shaped ("directly" i.e. in the classical interpretation) and that incoming traffic can be dropped as the only possible influence.
But the need for shaping exists for incoming traffic, too. The obvious example is that big downloads shall not constrain interactive (browsing) and "real time" (chat) traffic. Furthermore several downloads can have different priorities. This possibility is most important for network connections which are shared among people (e.g. in a company).
Formally one cannot control the incoming traffic. But in the real world (particularly for clients) most incoming traffic is the result of outgoing traffic. This is valid even for traffic which was initiated by another system. The initial packet arrives at random but for TCP traffic and many applications of other protocols the incoming traffic is controlled by a part the outgoing. The most important example for traffic which is not controlled is real time UDP data like audio and video.
The receiving system can control the amount of incoming traffic within a certain connection via the combination of window size and amount of ACK-Packets sent. The idea is to define a maximum of allowed traffic per time unit for a session and to defer the ACK packets so that the amount of traffic the partner is allowed to send does not exceed the maximum rate.
This simple variant does not affect code outside the existing traffic shaping code. But it makes sense (at least in certain scenarios) to create some cooperation with the TCP code.
This new feature could be configured as a kind of HTB.
If window size and outgoing data are often sent together (within the same packet) the deferral of the window size update implicates the deferral of outgoing data which may be quite unwanted. This should not be a problem for typical applications in which incoming and outgoing data are related and thus kind of synchronous though. So does the problem not arise in communication where the downstream is clearly bigger than the upstream. In this case most window updates are sent in empty packets. So it would be enough to defer these empty packets and let alone the data packets.
A general solution is possible if the traffic shaping code gets connected to the TCP code. If a session is configured (by filters and the use of a respective qdisc) to be asynchronous then the TCP stack could be configured to seperate the data and window size updates for this session. Instead of creating one packet with data and an updated window size it would create two: one packet with data and the old (small) window size which is not deferred (at least not by this mechanism) and a second packet without data but with the new window size (which gets deferred). This would cause some overhead but would not be necessary in general.
Another approach is to measure the amount of outgoing data in this connection and adapt the window size so that the allowed amount of incoming data is the product of the average window size update and the amount of packets sent. In this case no empty ACK-only packets would be created.
With non-TCP traffic the shaping function can check whether the deferral of outgoing traffic of this "connection" slows down the incoming. Whether this is done should be configurable by qdisc attributes so that the administrator can seperate defferent kinds of non-TCP traffic.
If this works then this kind of traffic can be handled the same way like TCP. If it does not work then the total available incoming bandwidth which is the base for the shaping calulations for each TCP (and similarly acting) session should be lowered by this amount and all session bandwidths should be recalculated.