diff --git a/README.md b/README.md index b4a6eb2..5ce29ab 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ # TrafficToll -NetLimiter-like traffic shaping for Linux +NetLimiter-like bandwidth limiting and QoS for Linux # Description -TrafficToll allows you to limit download and upload bandwidth globally -(per interface) and per process, even during the process' runtime. +TrafficToll allows you to limit download and upload bandwidth globally (per interface) +and per process, even during the process' runtime. Additionally it also allows you to +make use of QoS traffic prioritization for different processes. -The configuration can be easily adjusted and new limits applied at any -point, as opposed to similar tools which either can only apply fixed -global limits to the interface, certain ports, or require you to start -the process through them (and thus restart the target process to change -the limits). +The configuration can be easily adjusted and new limits and priorities applied at any +point, as opposed to similar tools which either can only apply fixed global limits to +the interface, certain ports, or require you to start the process through them (and thus +restart the target process to change the limits). # Usage `# tt device config` @@ -26,48 +26,128 @@ Currently TrafficToll works based on a YAML configuration file. The configuratio is best explained by example: ```YAML -# Global limits -download: 500kbps -upload: 100kbps +# The rate limits for the specified interface. Specifying these values is useful for two +# things: 1) you want to limit the used bandwidth for the entire interface or 2) you +# want to make use of traffic prioritization. -# Matched process limits +# If you want to 1) limit the used bandwidth for the entire interface, simply specify +# values below your actual speed: the traffic will be shaped in such a way, that it does +# not exceed the specified numbers. + +# If you want to 2) make use of the traffic prioritization feature, these values must be +# as close as possible to your real speed: if they are too low, traffic prioritization +# will work, but you are losing part of your bandwidth; if they are too high, traffic +# prioritization won't work as well as it could. I recommend you use some internet speed +# test you can find online to get an approximation for the correct values. + +# If you don't want to do 1) or 2), you can omit these values. Bandwidth limiting per +# application will still work, just traffic prioritization won't work as well or +# entirely. +download: 5mbps +upload: 1mbps + + +# A list of processes you want to match and their respective settings processes: + # You can name the process what you want, it is only used to identify it on the CLI + # output + "Path of Exile": + # Adjust the traffic priority to 0 (highest possible, higher integers mean _lower_ + # priority) to prevent lag and high pings in the game even when we create heavy + # traffic otherwise. If these priorities are omitted, they will default to 0: the + # same priority for all the traffic on the interface. As soon as you explicitly + # specify a priority for a process, the other traffic on the interface will get a + # lower priority, so will other processes where you did not explicitly specify + # another priority. In this case "Path of Exile" traffic will have a priority of 0, + # the highest, and the interface traffic and other processes will have a priority of + # 1. + download-priority: 0 + upload-priority: 0 + + # Download and upload rate limits can be entirely omitted if you don't want to apply + # any, in this case traffic will only be prioritized like specified. + #download: + #upload: + + # The match section. A process is selected when all predicates in the match section + # match. Every attribute psutil.Process + # (https://psutil.readthedocs.io/en/latest/index.html#psutil.Process) provides on + # Linux can be matched on, using regular expressions. Integer attributes will be + # treated as strings and list attributes will be joined using a space before + # matching. If you want to, you can also specify a regular expression with an OR + # operator and match many processes which will all share the specified bandwidth + # limit or traffic priority. + # If you do not see a line starting with "Shaping traffic for..." with your process + # name in it, while it is clearly causing traffic, your match section is failing. + # Please make sure it works correctly. + match: + - name: "PathOfExile_x64" + Vivaldi: - download: 100kbps + # Additionally specify fixed bandwidth limits for the browser. Setting bandwidth + # limits higher than the interface limits will not work. Different processes + # borrow available traffic from the interface limits using their specified priority. + download: 2500kbps + upload: 500kbps + + # Explicitly set a lower download and upload priority to Path of Exile so our + # browsing does not cause the game's ping to spike. This would have happened + # automatically if we omitted it, because we specified a priority for "Path of + # Exile" -- we are just doing it here for clarity. + download-priority: 1 + upload-priority: 1 match: - exe: /opt/vivaldi/vivaldi-bin Discord: - download: 300kbps + # Set Discord's traffic priority to the lowest: this means if we create traffic via + # either "Path of Exile" or "Vivaldi" it will get priority and Discord's latency and + # traffic will slow down accordingly + download-priority: 2 + upload-priority: 2 + + # Additionally specify fixed bandwidth limits for Discord. Please note that just + # because we specified 50% of the interface bandwidth for "Vivaldi" and "Discord" + # each, does not mean "Path of Exile" or other processes will be starved for + # traffic: Because we omitted download and upload limits for "Path of Exile" 100% of + # the interface rate is automatically assumed for that process, in this case + # 5mbps/1mbps. Additionally, because "Path of Exile" has a higher priority than + # either of the two, in the extreme case that Vivaldi and Discord utilize their + # bandwidth limits fully (and thus the entire interface's speed), "Path of Exile" + # traffic will get priority and traffic for Vivaldi and Discord will be + # appropriately reduced. + download: 2500kbps + upload: 500kbps - # This won't work, the specified upload exceeds the global upload, it will - # be 100kb/s max - upload: 200kbps match: - exe: /opt/discord/Discord JDownloader 2: - # JDownloader 2 obviously has its own traffic shaping, this is just here as - # an example to show that matching on something else than the executable's - # path is possible download: 300kbps + # The download-priority and upload-priority if omitted while another process + # explicitly specifies them will automatically be the lowest: in this case 2, the + # same as "Discord", our lowest priority process. + + # JDownloader 2 obviously has its own bandwidth limiting, this is just here as an + # example to show that matching on something else than the executable's name and + # path is possible match: - cmdline: .* JDownloader.jar ``` -Units can be specified in all formats that `tc` supports, namely: bit -(with and without suffix), kbit, mbit, gbit, tbit, bps, kbps, mbps, -gbps, tbps. To specify in IEC units, replace the SI prefix (k-, m-, g-, -t-) with IEC prefix (ki-, mi-, gi- and ti-) respectively. +Units can be specified in all formats that `tc` supports, namely: bit (with and without +suffix), kbit, mbit, gbit, tbit, bps, kbps, mbps, gbps, tbps. To specify in IEC units, +replace the SI prefix (k-, m-, g-, t-) with IEC prefix (ki-, mi-, gi- and ti-) +respectively. -All limits can be omitted, in which case obviously no limiting will be -applied. A process is selected when all predicates in the match section -match. Every attribute [`psutil.Process`](https://psutil.readthedocs.io/en/latest/index.html#psutil.Process) +All limits and priorities can be omitted, in which case obviously no traffic shaping +will be applied. A process is selected when all predicates in the match section match. +Every attribute +[`psutil.Process`](https://psutil.readthedocs.io/en/latest/index.html#psutil.Process) provides on Linux can be matched on, using regular expressions. -When you terminate `tt` using Ctrl+C all changes to the traffic -scheduling will be reverted, allowing you to easily update the config -and apply new limits. +When you terminate `tt` using Ctrl+C all changes to the traffic scheduling will be +reverted, allowing you to easily update the config and apply new limits. # Installation `$ pip install traffictoll` @@ -77,4 +157,4 @@ and apply new limits. # Screenshots Because a picture is always nice, even for CLI applications: -![](https://i.imgur.com/EsOla66.png) +![](https://i.imgur.com/a3U5Zdt.png) diff --git a/example.yaml b/example.yaml index 33f92d7..a3d7455 100644 --- a/example.yaml +++ b/example.yaml @@ -1,41 +1,107 @@ -# Global limits -download: 500kbps -upload: 100kbps +# The rate limits for the specified interface. Specifying these values is useful for two +# things: 1) you want to limit the used bandwidth for the entire interface or 2) you +# want to make use of traffic prioritization. -# Matched process limits +# If you want to 1) limit the used bandwidth for the entire interface, simply specify +# values below your actual speed: the traffic will be shaped in such a way, that it does +# not exceed the specified numbers. + +# If you want to 2) make use of the traffic prioritization feature, these values must be +# as close as possible to your real speed: if they are too low, traffic prioritization +# will work, but you are losing part of your bandwidth; if they are too high, traffic +# prioritization won't work as well as it could. I recommend you use some internet speed +# test you can find online to get an approximation for the correct values. + +# If you don't want to do 1) or 2), you can omit these values. Bandwidth limiting per +# application will still work, just traffic prioritization won't work as well or +# entirely. +download: 5mbps +upload: 1mbps + + +# A list of processes you want to match and their respective settings processes: - # Assign the game "Path of Exile" the highest traffic priority, the rest (matched and - # unmatched processes) will get a lower priority automatically. This will keep its - # latency low even when other processes cause a huge amount of traffic (think: - # downloading etc.) + # You can name the process what you want, it is only used to identify it on the CLI + # output "Path of Exile": + # Adjust the traffic priority to 0 (highest possible, higher integers mean _lower_ + # priority) to prevent lag and high pings in the game even when we create heavy + # traffic otherwise. If these priorities are omitted, they will default to 0: the + # same priority for all the traffic on the interface. As soon as you explicitly + # specify a priority for a process, the other traffic on the interface will get a + # lower priority, so will other processes where you did not explicitly specify + # another priority. In this case "Path of Exile" traffic will have a priority of 0, + # the highest, and the interface traffic and other processes will have a priority of + # 1. download-priority: 0 upload-priority: 0 + + # Download and upload rate limits can be entirely omitted if you don't want to apply + # any, in this case traffic will only be prioritized like specified. + #download: + #upload: + + # The match section. A process is selected when all predicates in the match section + # match. Every attribute psutil.Process + # (https://psutil.readthedocs.io/en/latest/index.html#psutil.Process) provides on + # Linux can be matched on, using regular expressions. Integer attributes will be + # treated as strings and list attributes will be joined using a space before + # matching. If you want to, you can also specify a regular expression with an OR + # operator and match many processes which will all share the specified bandwidth + # limit or traffic priority. + # If you do not see a line starting with "Shaping traffic for..." with your process + # name in it, while it is clearly causing traffic, your match section is failing. + # Please make sure it works correctly. match: - name: "PathOfExile_x64" Vivaldi: - match: - - exe: /opt/vivaldi/vivaldi-bin + # Additionally specify fixed bandwidth limits for the browser. Setting bandwidth + # limits higher than the interface limits will not work. Different processes + # borrow available traffic from the interface limits using their specified priority. + download: 2500kbps + upload: 500kbps - wget: - download: 300kbps + # Explicitly set a lower download and upload priority to Path of Exile so our + # browsing does not cause the game's ping to spike. This would have happened + # automatically if we omitted it, because we specified a priority for "Path of + # Exile" -- we are just doing it here for clarity. + download-priority: 1 + upload-priority: 1 match: - - exe: /usr/bin/wget + - exe: /opt/vivaldi/vivaldi-bin Discord: - download: 300kbps + # Set Discord's traffic priority to the lowest: this means if we create traffic via + # either "Path of Exile" or "Vivaldi" it will get priority and Discord's latency and + # traffic will slow down accordingly + download-priority: 2 + upload-priority: 2 + + # Additionally specify fixed bandwidth limits for Discord. Please note that just + # because we specified 50% of the interface bandwidth for "Vivaldi" and "Discord" + # each, does not mean "Path of Exile" or other processes will be starved for + # traffic: Because we omitted download and upload limits for "Path of Exile" 100% of + # the interface rate is automatically assumed for that process, in this case + # 5mbps/1mbps. Additionally, because "Path of Exile" has a higher priority than + # either of the two, in the extreme case that Vivaldi and Discord utilize their + # bandwidth limits fully (and thus the entire interface's speed), "Path of Exile" + # traffic will get priority and traffic for Vivaldi and Discord will be + # appropriately reduced. + download: 2500kbps + upload: 500kbps - # This won't work, the specified upload exceeds the global upload, it will - # be 100kb/s max - upload: 200kbps match: - exe: /opt/discord/Discord JDownloader 2: - # JDownloader 2 obviously has its own traffic shaping, this is just here as - # an example to show that matching on something else than the executable's - # path is possible download: 300kbps + # The download-priority and upload-priority if omitted while another process + # explicitly specifies them will automatically be the lowest: in this case 2, the + # same as "Discord", our lowest priority process. + + # JDownloader 2 obviously has its own bandwidth limiting, this is just here as an + # example to show that matching on something else than the executable's name and + # path is possible match: - cmdline: .* JDownloader.jar diff --git a/pyproject.toml b/pyproject.toml index 0391f73..8e51772 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,15 +1,15 @@ [tool.poetry] name = "TrafficToll" version = "1.1.0" -description = "NetLimiter-like traffic shaping for Linux" +description = "NetLimiter-like bandwidth limiting and QoS for Linux" authors = ["cryzed "] license='GPLv3' readme='README.md' homepage='https://github.com/cryzed/TrafficToll' repository='https://github.com/cryzed/TrafficToll' -keywords=['traffic', 'traffic control', 'tc', 'netlimiter'] -include=['LICENSE'] +keywords=['traffic', 'traffic control', 'traffic shaping', 'tc', 'netlimiter', 'qos'] +include=['LICENSE', 'example.yaml'] [tool.poetry.scripts] tt = 'traffictoll.__main__:main'