PER-PROCESS BANDWIDTH THROTTLE

Murus
Post Reply
hany
Posts: 480
Joined: Wed Dec 10, 2014 5:20 pm

PER-PROCESS BANDWIDTH THROTTLE

Post by hany » Wed Feb 20, 2019 6:24 pm

Today we introduce a new cool (and never seen before on macOS afaik) Scudo feature:

Per-process bandwidth throttling

Each app/process can be set to use a specific dummynet pipe for upload and/or download. So, for example, it is possible to limit Chrome bandwidth and let Safari use full bandwidth. Or, it is possible to throttle down Facetime and Skype video calls bandwidth (as low as 76Kbit/s) to spare bandwidth on you laptop while connected through your iphone's 4g (very) limited data-plan, leaving full bandwidth for all other apps.
This function is ip- and port-agnostic. If an unlimited app and a limited app connect to the same remote IP and port, bandwidth rules will be enforced: the limited app will use only a part of the available bandwidth while the unlimited app will use full bandwidth.
This feature has been introduced in Scudo public beta 3.
Get Scudo 1.0 public beta 3 here:
http://www.murusfirewall.com/forum/view ... 3282#p3282

How Scudo Bandwidth throttling works

MacOS always featured a built-in traffic shaping module: dummynet. It is a kernel-level module used by IPFW (from 10.0 to 10.6) and PF (from 10.7 to 10.14) to limit bandwidth at network layer. Dummynet uses pipes and queues to define traffic shaping rules.
A lot of Mac apps in the past offered the ability to create dummynet rules to tune bandwidth. These include WaterRoof, IceFloor, Murus and many others, including developer tools for macOS. Some app claimed to be able to throttle apps bandwidth independently, but this was not entirely true: bandwidth limits relied on remote port to be effective.
So, for example, to limit Safari download bandwidth an app would create a dummynet rule to limit the download bandwidth for all outbound connections to ports typically used by Safari (that is, 80 and 443). While this effectively throttles down Safari download bandwidth, it also affects *all* other system processes connecting to port 80 and 443. That's a big downside as a lot of apps and background processes use this port for their specific tasks.

Scudo approach is different, that's why we can say that Scudo is the first app for macOS that allows a true per-process bandwidth tuning. Scudo still uses dummynet rules and pipes for that purpose, but in a different way.
Each process binds a local port before connecting to a remote host. This local port will be used as the connection's source port. This port is unique, only a process can bind a local port at a given time. Scudo monitors for local ports and is able to tell which process is binding a local port. When you tell Scudo that a specific process must have a bandwidth limit, and that process fires and makes a connection, Scudo intercepts it, reads its local port (or ports), and dynamically adds dummynet rules to pf dummynet anchor. These rules use only the local port to match traffic, thus they will affect only that process. All connections made by other processes (even to the same IP and port) will not match the dummynet rules, so they will have full bandwidth. They key for this approach to be efficient is the ability of Scudo to dynamically create and remove pf runtime rules without using pfctl or any other shell command. Everything is done using low-level apis and functions in real time. This allows for instant creation or removal of pf rules in a very short time, thus allowing Scudo to efficiently manage bandwidth rules. When a process binds a local port, Scudo instantly creates the corresponding dummynet rule. When the process closes the port, pf rule is immediately removed from runtime. You can list runtime dummynet pf rules using Scudo Runtime Browser -> Network Layer -> pf anchor /scudo.bw





Image

Post Reply