From 7ad4177396917b00224423aa29ff6c16b38f46e7 Mon Sep 17 00:00:00 2001 From: Tianling Shen Date: Tue, 23 Mar 2021 18:25:01 +0800 Subject: [PATCH] luci-app-qos-gargoyle: import from core This is only available for this branch. Signed-off-by: Tianling Shen --- package/ctcgfw/luci-app-qos-gargoyle/Makefile | 22 ++ .../luasrc/controller/qos_gargoyle.lua | 100 ++++++ .../model/cbi/qos_gargoyle/download.lua | 166 +++++++++ .../model/cbi/qos_gargoyle/download_class.lua | 61 ++++ .../model/cbi/qos_gargoyle/download_rule.lua | 87 +++++ .../luasrc/model/cbi/qos_gargoyle/global.lua | 123 +++++++ .../luasrc/model/cbi/qos_gargoyle/upload.lua | 160 +++++++++ .../model/cbi/qos_gargoyle/upload_class.lua | 52 +++ .../model/cbi/qos_gargoyle/upload_rule.lua | 87 +++++ .../luasrc/model/qos_gargoyle.lua | 31 ++ .../luasrc/view/qos_gargoyle/list_view.htm | 97 +++++ .../view/qos_gargoyle/troubleshooting.htm | 52 +++ .../po/zh-cn/qos-gargoyle.po | 334 ++++++++++++++++++ .../etc/uci-defaults/40_luci-qos_gargoyle | 11 + 14 files changed, 1383 insertions(+) create mode 100644 package/ctcgfw/luci-app-qos-gargoyle/Makefile create mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/controller/qos_gargoyle.lua create mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download.lua create mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download_class.lua create mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download_rule.lua create mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/global.lua create mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload.lua create mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload_class.lua create mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload_rule.lua create mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/qos_gargoyle.lua create mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/view/qos_gargoyle/list_view.htm create mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/view/qos_gargoyle/troubleshooting.htm create mode 100644 package/ctcgfw/luci-app-qos-gargoyle/po/zh-cn/qos-gargoyle.po create mode 100755 package/ctcgfw/luci-app-qos-gargoyle/root/etc/uci-defaults/40_luci-qos_gargoyle diff --git a/package/ctcgfw/luci-app-qos-gargoyle/Makefile b/package/ctcgfw/luci-app-qos-gargoyle/Makefile new file mode 100644 index 0000000000..f0187a81a6 --- /dev/null +++ b/package/ctcgfw/luci-app-qos-gargoyle/Makefile @@ -0,0 +1,22 @@ +# +# Copyright (C) 2017 Xingwang Liao +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-qos-gargoyle +PKG_VERSION:=1.3.6 +PKG_RELEASE:=1 + +PKG_LICENSE:=Apache-2.0 +PKG_MAINTAINER:=Xingwang Liao + +LUCI_TITLE:=LuCI Support for Gargoyle QoS +LUCI_DEPENDS:=+qos-gargoyle +LUCI_PKGARCH:=all + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/controller/qos_gargoyle.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/controller/qos_gargoyle.lua new file mode 100644 index 0000000000..5b9ca56c5f --- /dev/null +++ b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/controller/qos_gargoyle.lua @@ -0,0 +1,100 @@ +-- Copyright 2017 Xingwang Liao +-- Licensed to the public under the Apache License 2.0. + +module("luci.controller.qos_gargoyle", package.seeall) + +local util = require "luci.util" +local http = require "luci.http" + +function index() + if not nixio.fs.access("/etc/config/qos_gargoyle") then + return + end + + entry({"admin", "network", "qos_gargoyle"}, + firstchild(), _("Gargoyle QoS"), 60) + + entry({"admin", "network", "qos_gargoyle", "global"}, + cbi("qos_gargoyle/global"), _("Global Settings"), 10) + + entry({"admin", "network", "qos_gargoyle", "upload"}, + cbi("qos_gargoyle/upload"), _("Upload Settings"), 20) + + entry({"admin", "network", "qos_gargoyle", "upload", "class"}, + cbi("qos_gargoyle/upload_class")).leaf = true + + entry({"admin", "network", "qos_gargoyle", "upload", "rule"}, + cbi("qos_gargoyle/upload_rule")).leaf = true + + entry({"admin", "network", "qos_gargoyle", "download"}, + cbi("qos_gargoyle/download"), _("Download Settings"), 30) + + entry({"admin", "network", "qos_gargoyle", "download", "class"}, + cbi("qos_gargoyle/download_class")).leaf = true + + entry({"admin", "network", "qos_gargoyle", "download", "rule"}, + cbi("qos_gargoyle/download_rule")).leaf = true + + entry({"admin", "network", "qos_gargoyle", "troubleshooting"}, + template("qos_gargoyle/troubleshooting"), _("Troubleshooting"), 40) + + entry({"admin", "network", "qos_gargoyle", "troubleshooting", "data"}, + call("action_troubleshooting_data")) + + entry({"admin", "network", "qos_gargoyle", "load_data"}, + call("action_load_data")).leaf = true +end + +function action_troubleshooting_data() + local uci = require "luci.model.uci".cursor() + local i18n = require "luci.i18n" + + local data = {} + + local monenabled = uci:get("qos_gargoyle", "download", "qos_monenabled") or "false" + + local show_data = util.trim(util.exec("/etc/init.d/qos_gargoyle show 2>/dev/null")) + if show_data == "" then + show_data = i18n.translate("No data found") + end + + data.show = show_data + + local mon_data + if monenabled == "true" then + mon_data = util.trim(util.exec("cat /tmp/qosmon.status 2>/dev/null")) + + if mon_data == "" then + mon_data = i18n.translate("No data found") + end + else + mon_data = i18n.translate("\"Active Congestion Control\" not enabled") + end + + data.mon = mon_data + + http.prepare_content("application/json") + http.write_json(data) +end + +function action_load_data(type) + local device + if type == "download" then + device = "imq0" + elseif type == "upload" then + local qos = require "luci.model.qos_gargoyle" + local wan = qos.get_wan() + device = wan and wan:ifname() or "" + end + + if device then + local data + if device ~= "" then + data = util.exec("tc -s class show dev %s 2>/dev/null" % device) + end + http.prepare_content("text/plain") + http.write(data or "") + else + http.status(500, "Bad address") + end +end diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download.lua new file mode 100644 index 0000000000..a165178874 --- /dev/null +++ b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download.lua @@ -0,0 +1,166 @@ +-- Copyright 2017 Xingwang Liao +-- Licensed to the public under the Apache License 2.0. + +local wa = require "luci.tools.webadmin" +local uci = require "luci.model.uci".cursor() +local dsp = require "luci.dispatcher" +local http = require "luci.http" +local qos = require "luci.model.qos_gargoyle" + +local m, class_s, rule_s, o +local download_classes = {} +local qos_gargoyle = "qos_gargoyle" + +uci:foreach(qos_gargoyle, "download_class", function(s) + local class_alias = s.name + if class_alias then + download_classes[#download_classes + 1] = {name = s[".name"], alias = class_alias} + end +end) + +m = Map(qos_gargoyle, translate("Download Settings")) +m.template = "qos_gargoyle/list_view" + +class_s = m:section(TypedSection, "download_class", translate("Service Classes"), + translate("Each service class is specified by four parameters: percent bandwidth at capacity, " + .. "realtime bandwidth and maximum bandwidth and the minimimze round trip time flag.")) +class_s.anonymous = true +class_s.addremove = true +class_s.template = "cbi/tblsection" +class_s.extedit = dsp.build_url("admin/network/qos_gargoyle/download/class/%s") +class_s.create = function(...) + local sid = TypedSection.create(...) + if sid then + m.uci:save(qos_gargoyle) + http.redirect(class_s.extedit % sid) + return + end +end + +o = class_s:option(DummyValue, "name", translate("Class Name")) +o.cfgvalue = function(...) + return Value.cfgvalue(...) or translate("None") +end + +o = class_s:option(DummyValue, "percent_bandwidth", translate("Percent Bandwidth At Capacity")) +o.cfgvalue = function(...) + local v = tonumber(Value.cfgvalue(...)) + if v and v > 0 then + return "%d %%" % v + end + return translate("Not set") +end + +o = class_s:option(DummyValue, "min_bandwidth", "%s (kbps)" % translate("Minimum Bandwidth")) +o.cfgvalue = function(...) + local v = tonumber(Value.cfgvalue(...)) + return v or translate("Zero") +end + +o = class_s:option(DummyValue, "max_bandwidth", "%s (kbps)" % translate("Maximum Bandwidth")) +o.cfgvalue = function(...) + local v = tonumber(Value.cfgvalue(...)) + return v or translate("Unlimited") +end + +o = class_s:option(DummyValue, "minRTT", translate("Minimize RTT")) +o.cfgvalue = function(...) + local v = Value.cfgvalue(...) + return v and translate(v) or translate("No") +end + +o = class_s:option(DummyValue, "_ld", "%s (kbps)" % translate("Load")) +o.rawhtml = true +o.value = "*" + +rule_s = m:section(TypedSection, "download_rule", translate("Classification Rules"), + translate("Packets are tested against the rules in the order specified -- rules toward the top " + .. "have priority. As soon as a packet matches a rule it is classified, and the rest of the rules " + .. "are ignored. The order of the rules can be altered using the arrow controls.") + ) +rule_s.addremove = true +rule_s.sortable = true +rule_s.anonymous = true +rule_s.template = "cbi/tblsection" +rule_s.extedit = dsp.build_url("admin/network/qos_gargoyle/download/rule/%s") +rule_s.create = function(...) + local sid = TypedSection.create(...) + if sid then + m.uci:save(qos_gargoyle) + http.redirect(rule_s.extedit % sid) + return + end +end + +o = rule_s:option(ListValue, "class", translate("Service Class")) +for _, s in ipairs(download_classes) do o:value(s.name, s.alias) end + +o = rule_s:option(Value, "proto", translate("Transport Protocol")) +o:value("", translate("All")) +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("icmp", "ICMP") +o:value("gre", "GRE") +o.size = "10" +o.cfgvalue = function(...) + local v = Value.cfgvalue(...) + return v and v:upper() or "" +end +o.write = function(self, section, value) + Value.write(self, section, value:lower()) +end + +o = rule_s:option(Value, "source", translate("Source IP(s)")) +o:value("", translate("All")) +wa.cbi_add_knownips(o) +o.datatype = "ipmask4" + +o = rule_s:option(Value, "srcport", translate("Source Port(s)")) +o:value("", translate("All")) +o.datatype = "or(port, portrange)" + +o = rule_s:option(Value, "destination", translate("Destination IP(s)")) +o:value("", translate("All")) +wa.cbi_add_knownips(o) +o.datatype = "ipmask4" + +o = rule_s:option(Value, "dstport", translate("Destination Port(s)")) +o:value("", translate("All")) +o.datatype = "or(port, portrange)" + +o = rule_s:option(DummyValue, "min_pkt_size", translate("Minimum Packet Length")) +o.cfgvalue = function(...) + local v = tonumber(Value.cfgvalue(...)) + if v and v > 0 then + return wa.byte_format(v) + end + return translate("Not set") +end + +o = rule_s:option(DummyValue, "max_pkt_size", translate("Maximum Packet Length")) +o.cfgvalue = function(...) + local v = tonumber(Value.cfgvalue(...)) + if v and v > 0 then + return wa.byte_format(v) + end + return translate("Not set") +end + +o = rule_s:option(DummyValue, "connbytes_kb", translate("Connection Bytes Reach")) +o.cfgvalue = function(...) + local v = tonumber(Value.cfgvalue(...)) + if v and v > 0 then + return wa.byte_format(v * 1024) + end + return translate("Not set") +end + +if qos.has_ndpi() then + o = rule_s:option(DummyValue, "ndpi", translate("DPI Protocol")) + o.cfgvalue = function(...) + local v = Value.cfgvalue(...) + return v and v:upper() or translate("All") + end +end + +return m diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download_class.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download_class.lua new file mode 100644 index 0000000000..c26cb78301 --- /dev/null +++ b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download_class.lua @@ -0,0 +1,61 @@ +-- Copyright 2017 Xingwang Liao +-- Licensed to the public under the Apache License 2.0. + +local m, s, o +local sid = arg[1] +local qos_gargoyle = "qos_gargoyle" + +m = Map(qos_gargoyle, translate("Edit Download Service Class")) +m.redirect = luci.dispatcher.build_url("admin/network/qos_gargoyle/download") + +if m.uci:get(qos_gargoyle, sid) ~= "download_class" then + luci.http.redirect(m.redirect) + return +end + +s = m:section(NamedSection, sid, "download_class") +s.anonymous = true +s.addremove = false + +o = s:option(Value, "name", translate("Service Class Name")) +o.rmempty = false + +o = s:option(Value, "percent_bandwidth", translate("Percent Bandwidth At Capacity"), + translate("The percentage of the total available bandwidth that should be allocated to this class " + .. "when all available bandwidth is being used. If unused bandwidth is available, more can (and " + .. "will) be allocated. The percentages can be configured to equal more (or less) than 100, but " + .. "when the settings are applied the percentages will be adjusted proportionally so that they " + .. "add to 100. This setting only comes into effect when the WAN link is saturated.")) +o.datatype = "range(1, 100)" +o.rmempty = false + +o = s:option(Value, "min_bandwidth", translate("Minimum Bandwidth"), + translate("The minimum service this class will be allocated when the link is at capacity. Classes " + .. "which specify minimum service are known as realtime classes by the active congestion " + .. "controller. Streaming video, VoIP and interactive online gaming are all examples of " + .. "applications that must have a minimum bandwith to function. To determine what to enter use " + .. "the application on an unloaded LAN and observe how much bandwidth it uses. Then enter a " + .. "number only slightly higher than this into this field. QoS will satisfiy the minimum service " + .. "of all classes first before allocating to other waiting classes so be careful to use minimum " + .. "bandwidths sparingly.")) +o:value("0", translate("Zero")) +o.datatype = "uinteger" +o.default = "0" + +o = s:option(Value, "max_bandwidth", translate("Maximum Bandwidth"), + translate("The maximum amount of bandwidth this class will be allocated in kbit/s. Even if unused " + .. "bandwidth is available, this service class will never be permitted to use more than this " + .. "amount of bandwidth.")) +o:value("", translate("Unlimited")) +o.datatype = "uinteger" + +o = s:option(Flag, "minRTT", translate("Minimize RTT"), + translate("Indicates to the active congestion controller that you wish to minimize round trip " + .. "times (RTT) when this class is active. Use this setting for online gaming or VoIP " + .. "applications that need low round trip times (ping times). Minimizing RTT comes at the expense " + .. "of efficient WAN throughput so while these class are active your WAN throughput will decline " + .. "(usually around 20%).")) +o.enabled = "Yes" +o.disabled = "No" + +return m diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download_rule.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download_rule.lua new file mode 100644 index 0000000000..cbc970e2f0 --- /dev/null +++ b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download_rule.lua @@ -0,0 +1,87 @@ +-- Copyright 2017 Xingwang Liao +-- Licensed to the public under the Apache License 2.0. + +local wa = require "luci.tools.webadmin" +local uci = require "luci.model.uci".cursor() +local qos = require "luci.model.qos_gargoyle" + +local m, s, o +local sid = arg[1] +local download_classes = {} +local qos_gargoyle = "qos_gargoyle" + +uci:foreach(qos_gargoyle, "download_class", function(s) + local class_alias = s.name + if class_alias then + download_classes[#download_classes + 1] = {name = s[".name"], alias = class_alias} + end +end) + +m = Map(qos_gargoyle, translate("Edit Download Classification Rule")) +m.redirect = luci.dispatcher.build_url("admin/network/qos_gargoyle/download") + +if m.uci:get(qos_gargoyle, sid) ~= "download_rule" then + luci.http.redirect(m.redirect) + return +end + +s = m:section(NamedSection, sid, "download_rule") +s.anonymous = true +s.addremove = false + +o = s:option(ListValue, "class", translate("Service Class")) +for _, s in ipairs(download_classes) do o:value(s.name, s.alias) end + +o = s:option(Value, "proto", translate("Transport Protocol")) +o:value("", translate("All")) +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("icmp", "ICMP") +o:value("gre", "GRE") +o.write = function(self, section, value) + Value.write(self, section, value:lower()) +end + +o = s:option(Value, "source", translate("Source IP(s)"), + translate("Packet's source ip, can optionally have /[mask] after it (see -s option in iptables " + .. "man page).")) +o:value("", translate("All")) +wa.cbi_add_knownips(o) +o.datatype = "ipmask4" + +o = s:option(Value, "srcport", translate("Source Port(s)"), + translate("Packet's source port, can be a range (eg. 80-90).")) +o:value("", translate("All")) +o.datatype = "or(port, portrange)" + +o = s:option(Value, "destination", translate("Destination IP(s)"), + translate("Packet's destination ip, can optionally have /[mask] after it (see -d option in " + .. "iptables man page).")) +o:value("", translate("All")) +wa.cbi_add_knownips(o) +o.datatype = "ipmask4" + +o = s:option(Value, "dstport", translate("Destination Port(s)"), + translate("Packet's destination port, can be a range (eg. 80-90).")) +o:value("", translate("All")) +o.datatype = "or(port, portrange)" + +o = s:option(Value, "min_pkt_size", translate("Minimum Packet Length"), + translate("Packet's minimum size (in bytes).")) +o.datatype = "range(1, 1500)" + +o = s:option(Value, "max_pkt_size", translate("Maximum Packet Length"), + translate("Packet's maximum size (in bytes).")) +o.datatype = "range(1, 1500)" + +o = s:option(Value, "connbytes_kb", translate("Connection Bytes Reach"), + translate("The total size of data transmitted since the establishment of the link (in kBytes).")) +o.datatype = "range(0, 4194303)" + +if qos.has_ndpi() then + o = s:option(ListValue, "ndpi", translate("DPI Protocol")) + o:value("", translate("All")) + qos.cbi_add_dpi_protocols(o) +end + +return m diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/global.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/global.lua new file mode 100644 index 0000000000..f718631f6a --- /dev/null +++ b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/global.lua @@ -0,0 +1,123 @@ +-- Copyright 2017 Xingwang Liao +-- Licensed to the public under the Apache License 2.0. + +local sys = require "luci.sys" +local uci = require "luci.model.uci".cursor() +local net = require "luci.model.network".init() +local qos = require "luci.model.qos_gargoyle" + +local m, s, o +local upload_classes = {} +local download_classes = {} +local qos_gargoyle = "qos_gargoyle" + +local function qos_enabled() + return sys.init.enabled(qos_gargoyle) +end + +uci:foreach(qos_gargoyle, "upload_class", function(s) + local class_alias = s.name + if class_alias then + upload_classes[#upload_classes + 1] = {name = s[".name"], alias = class_alias} + end +end) + +uci:foreach(qos_gargoyle, "download_class", function(s) + local class_alias = s.name + if class_alias then + download_classes[#download_classes + 1] = {name = s[".name"], alias = class_alias} + end +end) + +m = Map(qos_gargoyle, translate("Gargoyle QoS"), + translate("Quality of Service (QoS) provides a way to control how available bandwidth is " + .. "allocated.")) + +s = m:section(SimpleSection, translate("Global Settings")) +s.anonymous = true + +o = s:option(Button, "_switch", nil, translate("QoS Switch")) +o.render = function(self, section, scope) + if qos_enabled() then + self.title = translate("Disable QoS") + self.inputstyle = "reset" + else + self.title = translate("Enable QoS") + self.inputstyle = "apply" + end + Button.render(self, section, scope) +end +o.write = function(...) + if qos_enabled() then + sys.init.stop(qos_gargoyle) + sys.init.disable(qos_gargoyle) + else + sys.init.enable(qos_gargoyle) + sys.init.start(qos_gargoyle) + end +end + +s = m:section(NamedSection, "upload", "upload", translate("Upload Settings")) +s.anonymous = true + +o = s:option(ListValue, "default_class", translate("Default Service Class"), + translate("Specifie how packets that do not match any rule should be classified.")) +for _, s in ipairs(upload_classes) do o:value(s.name, s.alias) end + +o = s:option(Value, "total_bandwidth", translate("Total Upload Bandwidth"), + translate("Should be set to around 98% of your available upload bandwidth. Entering a number " + .. "which is too high will result in QoS not meeting its class requirements. Entering a number " + .. "which is too low will needlessly penalize your upload speed. You should use a speed test " + .. "program (with QoS off) to determine available upload bandwidth. Note that bandwidth is " + .. "specified in kbps, leave blank to disable update QoS. There are 8 kilobits per kilobyte.")) +o.datatype = "uinteger" + +s = m:section(NamedSection, "download", "download", translate("Download Settings")) +s.anonymous = true + +o = s:option(ListValue, "default_class", translate("Default Service Class"), + translate("Specifie how packets that do not match any rule should be classified.")) +for _, s in ipairs(download_classes) do o:value(s.name, s.alias) end + +o = s:option(Value, "total_bandwidth", translate("Total Download Bandwidth"), + translate("Specifying correctly is crucial to making QoS work. Note that bandwidth is specified " + .. "in kbps, leave blank to disable download QoS. There are 8 kilobits per kilobyte.")) +o.datatype = "uinteger" + +o = s:option(Flag, "qos_monenabled", translate("Enable Active Congestion Control"), + translate("

The active congestion control (ACC) observes your download activity and " + .. "automatically adjusts your download link limit to maintain proper QoS performance. ACC " + .. "automatically compensates for changes in your ISP's download speed and the demand from your " + .. "network adjusting the link speed to the highest speed possible which will maintain proper QoS " + .. "function. The effective range of this control is between 15% and 100% of the total download " + .. "bandwidth you entered above.

") .. + translate("

While ACC does not adjust your upload link speed you must enable and properly " + .. "configure your upload QoS for it to function properly.

") + ) +o.enabled = "true" +o.disabled = "false" + +o = s:option(Value, "ptarget_ip", translate("Use Non-standard Ping Target"), + translate("The segment of network between your router and the ping target is where congestion is " + .. "controlled. By monitoring the round trip ping times to the target congestion is detected. By " + .. "default ACC uses your WAN gateway as the ping target. If you know that congestion on your " + .. "link will occur in a different segment then you can enter an alternate ping target. Leave " + .. "empty to use the default settings.")) +o:depends("qos_monenabled", "true") +local wan = qos.get_wan() +if wan then o:value(wan:gwaddr()) end +o.datatype = "ipaddr" + +o = s:option(Value, "pinglimit", translate("Manual Ping Limit"), + translate("Round trip ping times are compared against the ping limits. ACC controls the link " + .. "limit to maintain ping times under the appropriate limit. By default ACC attempts to " + .. "automatically select appropriate target ping limits for you based on the link speeds you " + .. "entered and the performance of your link it measures during initialization. You cannot change " + .. "the target ping time for the minRTT mode but by entering a manual time you can control the " + .. "target ping time of the active mode. The time you enter becomes the increase in the target " + .. "ping time between minRTT and active mode. Leave empty to use the default settings.")) +o:depends("qos_monenabled", "true") +o:value("Auto", translate("Auto")) +o.datatype = "or('Auto', range(10, 250))" + +return m diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload.lua new file mode 100644 index 0000000000..a5f86927ef --- /dev/null +++ b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload.lua @@ -0,0 +1,160 @@ +-- Copyright 2017 Xingwang Liao +-- Licensed to the public under the Apache License 2.0. + +local wa = require "luci.tools.webadmin" +local uci = require "luci.model.uci".cursor() +local dsp = require "luci.dispatcher" +local http = require "luci.http" +local qos = require "luci.model.qos_gargoyle" + +local m, class_s, rule_s, o +local upload_classes = {} +local qos_gargoyle = "qos_gargoyle" + +uci:foreach(qos_gargoyle, "upload_class", function(s) + local class_alias = s.name + if class_alias then + upload_classes[#upload_classes + 1] = {name = s[".name"], alias = class_alias} + end +end) + +m = Map(qos_gargoyle, translate("Upload Settings")) +m.template = "qos_gargoyle/list_view" + +class_s = m:section(TypedSection, "upload_class", translate("Service Classes"), + translate("Each upload service class is specified by three parameters: percent bandwidth at " + .. "capacity, minimum bandwidth and maximum bandwidth.")) +class_s.anonymous = true +class_s.addremove = true +class_s.template = "cbi/tblsection" +class_s.extedit = dsp.build_url("admin/network/qos_gargoyle/upload/class/%s") +class_s.create = function(...) + local sid = TypedSection.create(...) + if sid then + m.uci:save(qos_gargoyle) + http.redirect(class_s.extedit % sid) + return + end +end + +o = class_s:option(DummyValue, "name", translate("Class Name")) +o.cfgvalue = function(...) + return Value.cfgvalue(...) or translate("None") +end + +o = class_s:option(DummyValue, "percent_bandwidth", translate("Percent Bandwidth At Capacity")) +o.cfgvalue = function(...) + local v = tonumber(Value.cfgvalue(...)) + if v and v > 0 then + return "%d %%" % v + end + return translate("Not set") +end + +o = class_s:option(DummyValue, "min_bandwidth", "%s (kbps)" % translate("Minimum Bandwidth")) +o.cfgvalue = function(...) + local v = tonumber(Value.cfgvalue(...)) + return v or translate("Zero") +end + +o = class_s:option(DummyValue, "max_bandwidth", "%s (kbps)" % translate("Maximum Bandwidth")) +o.cfgvalue = function(...) + local v = tonumber(Value.cfgvalue(...)) + return v or translate("Unlimited") +end + +o = class_s:option(DummyValue, "_ld", "%s (kbps)" % translate("Load")) +o.rawhtml = true +o.value = "*" + +rule_s = m:section(TypedSection, "upload_rule",translate("Classification Rules"), + translate("Packets are tested against the rules in the order specified -- rules toward the top " + .. "have priority. As soon as a packet matches a rule it is classified, and the rest of the rules " + .. "are ignored. The order of the rules can be altered using the arrow controls.") +) +rule_s.addremove = true +rule_s.sortable = true +rule_s.anonymous = true +rule_s.template = "cbi/tblsection" +rule_s.extedit = dsp.build_url("admin/network/qos_gargoyle/upload/rule/%s") +rule_s.create = function(...) + local sid = TypedSection.create(...) + if sid then + m.uci:save(qos_gargoyle) + http.redirect(rule_s.extedit % sid) + return + end +end + +o = rule_s:option(ListValue, "class", translate("Service Class")) +for _, s in ipairs(upload_classes) do o:value(s.name, s.alias) end + +o = rule_s:option(Value, "proto", translate("Transport Protocol")) +o:value("", translate("All")) +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("icmp", "ICMP") +o:value("gre", "GRE") +o.size = "10" +o.cfgvalue = function(...) + local v = Value.cfgvalue(...) + return v and v:upper() or "" +end +o.write = function(self, section, value) + Value.write(self, section, value:lower()) +end + +o = rule_s:option(Value, "source", translate("Source IP(s)")) +o:value("", translate("All")) +wa.cbi_add_knownips(o) +o.datatype = "ipmask4" + +o = rule_s:option(Value, "srcport", translate("Source Port(s)")) +o:value("", translate("All")) +o.datatype = "or(port, portrange)" + +o = rule_s:option(Value, "destination", translate("Destination IP(s)")) +o:value("", translate("All")) +wa.cbi_add_knownips(o) +o.datatype = "ipmask4" + +o = rule_s:option(Value, "dstport", translate("Destination Port(s)")) +o:value("", translate("All")) +o.datatype = "or(port, portrange)" + +o = rule_s:option(DummyValue, "min_pkt_size", translate("Minimum Packet Length")) +o.cfgvalue = function(...) + local v = tonumber(Value.cfgvalue(...)) + if v and v > 0 then + return wa.byte_format(v) + end + return translate("Not set") +end + +o = rule_s:option(DummyValue, "max_pkt_size", translate("Maximum Packet Length")) +o.cfgvalue = function(...) + local v = tonumber(Value.cfgvalue(...)) + if v and v > 0 then + return wa.byte_format(v) + end + return translate("Not set") +end + +o = rule_s:option(DummyValue, "connbytes_kb", translate("Connection Bytes Reach")) +o.cfgvalue = function(...) + local v = tonumber(Value.cfgvalue(...)) + if v and v > 0 then + return wa.byte_format(v * 1024) + end + return translate("Not set") +end + +if qos.has_ndpi() then + o = rule_s:option(DummyValue, "ndpi", translate("DPI Protocol")) + o.cfgvalue = function(...) + local v = Value.cfgvalue(...) + return v and v:upper() or translate("All") + end +end + +return m diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload_class.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload_class.lua new file mode 100644 index 0000000000..9739b9794b --- /dev/null +++ b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload_class.lua @@ -0,0 +1,52 @@ +-- Copyright 2017 Xingwang Liao +-- Licensed to the public under the Apache License 2.0. + +local m, s, o +local sid = arg[1] +local qos_gargoyle = "qos_gargoyle" + +m = Map(qos_gargoyle, translate("Edit Upload Service Class")) +m.redirect = luci.dispatcher.build_url("admin/network/qos_gargoyle/upload") + +if m.uci:get(qos_gargoyle, sid) ~= "upload_class" then + luci.http.redirect(m.redirect) + return +end + +s = m:section(NamedSection, sid, "upload_class") +s.anonymous = true +s.addremove = false + +o = s:option(Value, "name", translate("Service Class Name")) +o.rmempty = false + +o = s:option(Value, "percent_bandwidth", translate("Percent Bandwidth At Capacity"), + translate("The percentage of the total available bandwidth that should be allocated to this class " + .. "when all available bandwidth is being used. If unused bandwidth is available, more can (and " + .. "will) be allocated. The percentages can be configured to equal more (or less) than 100, but " + .. "when the settings are applied the percentages will be adjusted proportionally so that they " + .. "add to 100. This setting only comes into effect when the WAN link is saturated.")) +o.datatype = "range(1, 100)" +o.rmempty = false + +o = s:option(Value, "min_bandwidth", translate("Minimum Bandwidth"), + translate("The minimum service this class will be allocated when the link is at capacity. Classes " + .. "which specify minimum service are known as realtime classes by the active congestion " + .. "controller. Streaming video, VoIP and interactive online gaming are all examples of " + .. "applications that must have a minimum bandwith to function. To determine what to enter use " + .. "the application on an unloaded LAN and observe how much bandwidth it uses. Then enter a " + .. "number only slightly higher than this into this field. QoS will satisfiy the minimum service " + .. "of all classes first before allocating to other waiting classes so be careful to use minimum " + .. "bandwidths sparingly.")) +o:value("0", translate("Zero")) +o.datatype = "uinteger" +o.default = "0" + +o = s:option(Value, "max_bandwidth", translate("Maximum Bandwidth"), + translate("The maximum amount of bandwidth this class will be allocated in kbit/s. Even if unused " + .. "bandwidth is available, this service class will never be permitted to use more than this " + .. "amount of bandwidth.")) +o:value("", translate("Unlimited")) +o.datatype = "uinteger" + +return m diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload_rule.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload_rule.lua new file mode 100644 index 0000000000..8abcac35d9 --- /dev/null +++ b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload_rule.lua @@ -0,0 +1,87 @@ +-- Copyright 2017 Xingwang Liao +-- Licensed to the public under the Apache License 2.0. + +local wa = require "luci.tools.webadmin" +local uci = require "luci.model.uci".cursor() +local qos = require "luci.model.qos_gargoyle" + +local m, s, o +local sid = arg[1] +local upload_classes = {} +local qos_gargoyle = "qos_gargoyle" + +uci:foreach(qos_gargoyle, "upload_class", function(s) + local class_alias = s.name + if class_alias then + upload_classes[#upload_classes + 1] = {name = s[".name"], alias = class_alias} + end +end) + +m = Map(qos_gargoyle, translate("Edit Upload Classification Rule")) +m.redirect = luci.dispatcher.build_url("admin/network/qos_gargoyle/upload") + +if m.uci:get(qos_gargoyle, sid) ~= "upload_rule" then + luci.http.redirect(m.redirect) + return +end + +s = m:section(NamedSection, sid, "upload_rule") +s.anonymous = true +s.addremove = false + +o = s:option(ListValue, "class", translate("Service Class")) +for _, s in ipairs(upload_classes) do o:value(s.name, s.alias) end + +o = s:option(Value, "proto", translate("Transport Protocol")) +o:value("", translate("All")) +o:value("tcp", "TCP") +o:value("udp", "UDP") +o:value("icmp", "ICMP") +o:value("gre", "GRE") +o.write = function(self, section, value) + Value.write(self, section, value:lower()) +end + +o = s:option(Value, "source", translate("Source IP(s)"), + translate("Packet's source ip, can optionally have /[mask] after it (see -s option in iptables " + .. "man page).")) +o:value("", translate("All")) +wa.cbi_add_knownips(o) +o.datatype = "ipmask4" + +o = s:option(Value, "srcport", translate("Source Port(s)"), + translate("Packet's source port, can be a range (eg. 80-90).")) +o:value("", translate("All")) +o.datatype = "or(port, portrange)" + +o = s:option(Value, "destination", translate("Destination IP(s)"), + translate("Packet's destination ip, can optionally have /[mask] after it (see -d option in " + .. "iptables man page).")) +o:value("", translate("All")) +wa.cbi_add_knownips(o) +o.datatype = "ipmask4" + +o = s:option(Value, "dstport", translate("Destination Port(s)"), + translate("Packet's destination port, can be a range (eg. 80-90).")) +o:value("", translate("All")) +o.datatype = "or(port, portrange)" + +o = s:option(Value, "min_pkt_size", translate("Minimum Packet Length"), + translate("Packet's minimum size (in bytes).")) +o.datatype = "range(1, 1500)" + +o = s:option(Value, "max_pkt_size", translate("Maximum Packet Length"), + translate("Packet's maximum size (in bytes).")) +o.datatype = "range(1, 1500)" + +o = s:option(Value, "connbytes_kb", translate("Connection Bytes Reach"), + translate("The total size of data transmitted since the establishment of the link (in kBytes).")) +o.datatype = "range(0, 4194303)" + +if qos.has_ndpi() then + o = s:option(ListValue, "ndpi", translate("DPI Protocol")) + o:value("", translate("All")) + qos.cbi_add_dpi_protocols(o) +end + +return m diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/qos_gargoyle.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/qos_gargoyle.lua new file mode 100644 index 0000000000..b0113f1872 --- /dev/null +++ b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/qos_gargoyle.lua @@ -0,0 +1,31 @@ +-- Copyright 2017 Xingwang Liao +-- Licensed to the public under the Apache License 2.0. + +module("luci.model.qos_gargoyle", package.seeall) + +function has_ndpi() + return luci.sys.call("lsmod | cut -d ' ' -f1 | grep -q 'xt_ndpi'") == 0 +end + +function cbi_add_dpi_protocols(field) + local util = require "luci.util" + + local dpi_protocols = {} + + for line in util.execi("iptables -m ndpi --help 2>/dev/null | grep '^--'") do + local _, _, protocol, name = line:find("%-%-([^%s]+) Match for ([^%s]+)") + + if protocol and name then + dpi_protocols[protocol] = name + end + end + + for p, n in util.kspairs(dpi_protocols) do + field:value(p, n) + end +end + +function get_wan() + local net = require "luci.model.network".init() + return net:get_wannet() +end diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/view/qos_gargoyle/list_view.htm b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/view/qos_gargoyle/list_view.htm new file mode 100644 index 0000000000..87d3994de2 --- /dev/null +++ b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/view/qos_gargoyle/list_view.htm @@ -0,0 +1,97 @@ +<%# + Copyright 2017 Xingwang Liao + Licensed to the public under the Apache License 2.0. +-%> + +<% + local dsp = require "luci.dispatcher" + local request = dsp.context.path + local leaf = request[#request] +-%> + + + +<%+cbi/map%> + + diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/view/qos_gargoyle/troubleshooting.htm b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/view/qos_gargoyle/troubleshooting.htm new file mode 100644 index 0000000000..17197850e8 --- /dev/null +++ b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/view/qos_gargoyle/troubleshooting.htm @@ -0,0 +1,52 @@ +<%# + Copyright 2017 Xingwang Liao + Licensed to the public under the Apache License 2.0. +-%> + +<% css = [[ + + #troubleshoot_text { + padding: 20px; + text-align: left; + } + #troubleshoot_text pre { + word-break: break-all; + margin: 0; + } + .description { + background-color: #33CCFF; + } + +]] +-%> + +<%+header%> + + + + +
+
+ <%:Troubleshooting Data%> +
<%:Loading%><%:Collecting data...%>
+
+
+ +<%+footer%> diff --git a/package/ctcgfw/luci-app-qos-gargoyle/po/zh-cn/qos-gargoyle.po b/package/ctcgfw/luci-app-qos-gargoyle/po/zh-cn/qos-gargoyle.po new file mode 100644 index 0000000000..4b1d10624a --- /dev/null +++ b/package/ctcgfw/luci-app-qos-gargoyle/po/zh-cn/qos-gargoyle.po @@ -0,0 +1,334 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8\n" + +msgid "\"Active Congestion Control\" not enabled" +msgstr "“主动拥塞控制”未启用" + +msgid "" +"

The active congestion control (ACC) observes your download activity and " +"automatically adjusts your download link limit to maintain proper QoS " +"performance. ACC automatically compensates for changes in your ISP's " +"download speed and the demand from your network adjusting the link speed to " +"the highest speed possible which will maintain proper QoS function. The " +"effective range of this control is between 15% and 100% of the total " +"download bandwidth you entered above.

" +msgstr "" +"

主动拥塞控制系统(ACC)观察你的下载活动并自动调整你的下载链接限制以保持适" +"当的 QoS 性能。ACC 自动调整 QoS 功能以补偿来自你 ISP 的下载速度变化及来自你网" +"络链接速度的调整需求,使速度最大化。这个控制的有效范围在你上面输入的下载总带" +"宽的 15% 至 100% 之间。

" + +msgid "" +"

While ACC does not adjust your upload link speed you must enable and " +"properly configure your upload QoS for it to function properly.

" +msgstr "" +"

虽然 ACC 不调整你的上传链路速度,但你必须启用并正确配置你的上传 QoS 带宽以" +"使该功能正常工作。

" + +msgid "All" +msgstr "全部" + +msgid "Auto" +msgstr "自动" + +msgid "Class Name" +msgstr "类型名称" + +msgid "Classification Rules" +msgstr "分类规则" + +msgid "Collecting data..." +msgstr "正在收集数据..." + +msgid "Connection Bytes Reach" +msgstr "连接流量达到" + +msgid "DPI Protocol" +msgstr "DPI 协议" + +msgid "Default Service Class" +msgstr "默认服务类型" + +msgid "Destination IP(s)" +msgstr "目标 IP" + +msgid "Destination Port(s)" +msgstr "目标端口" + +msgid "Disable QoS" +msgstr "禁用 QoS" + +msgid "Download Settings" +msgstr "下载设置" + +msgid "" +"Each service class is specified by four parameters: percent bandwidth at " +"capacity, realtime bandwidth and maximum bandwidth and the minimimze round " +"trip time flag." +msgstr "" +"每个下载服务类型由四个参数指定:带宽占用百分比、最小保证带宽、最大带宽和最小" +"往返延时标志。" + +msgid "" +"Each upload service class is specified by three parameters: percent " +"bandwidth at capacity, minimum bandwidth and maximum bandwidth." +msgstr "每个上传服务类型由三个参数指定:带宽占用百分比、最小带宽和最大带宽。" + +msgid "Edit Download Classification Rule" +msgstr "编辑下载分类规则" + +msgid "Edit Download Service Class" +msgstr "编辑下载服务类型" + +msgid "Edit Upload Classification Rule" +msgstr "编辑上传分类规则" + +msgid "Edit Upload Service Class" +msgstr "编辑上传服务类型" + +msgid "Enable Active Congestion Control" +msgstr "启用主动拥塞控制" + +msgid "Enable QoS" +msgstr "启用 QoS" + +msgid "Error collecting troubleshooting information" +msgstr "收集故障排查信息失败" + +msgid "Gargoyle QoS" +msgstr "石像鬼 QoS" + +msgid "Global Settings" +msgstr "全局设置" + +msgid "" +"Indicates to the active congestion controller that you wish to minimize " +"round trip times (RTT) when this class is active. Use this setting for " +"online gaming or VoIP applications that need low round trip times (ping " +"times). Minimizing RTT comes at the expense of efficient WAN throughput so " +"while these class are active your WAN throughput will decline (usually " +"around 20%)." +msgstr "" +"告诉主动拥塞控制器你希望该服务类型启用时尽量减少往返延时(RTT)。该设置一般用" +"在 VoIP 或在线游戏这类需要低延时(Ping 值)的应用上。减小往返延时(RTT)会带" +"来WAN有效吞吐量的额外花销,所以当这些服务类型启用时你的 WAN 吞吐量将下降(通" +"常在20%左右)" + +msgid "Load" +msgstr "负载" + +msgid "Loading" +msgstr "正在加载" + +msgid "Manual Ping Limit" +msgstr "手动 Ping 限制" + +msgid "Maximum Bandwidth" +msgstr "最大带宽" + +msgid "Maximum Packet Length" +msgstr "最大数据包长度" + +msgid "Minimize RTT" +msgstr "最小往返延时" + +msgid "Minimum Bandwidth" +msgstr "最小带宽" + +msgid "Minimum Packet Length" +msgstr "最小数据包长度" + +msgid "No" +msgstr "否" + +msgid "No data found" +msgstr "无数据" + +msgid "None" +msgstr "无" + +msgid "Not set" +msgstr "未设置" + +msgid "" +"Packet's destination ip, can optionally have /[mask] after it (see -d option " +"in iptables man page)." +msgstr "" +"数据包的目标 IP,可以在后面加子网掩码(/[mask],请看 iptables 的 -d 参数说" +"明)" + +msgid "Packet's destination port, can be a range (eg. 80-90)." +msgstr "数据包的目标端口,可以是一个范围(例如:80-90)" + +msgid "Packet's maximum size (in bytes)." +msgstr "数据包的最大大小(单位:bytes)" + +msgid "Packet's minimum size (in bytes)." +msgstr "数据包的最小大小(单位:bytes)" + +msgid "" +"Packet's source ip, can optionally have /[mask] after it (see -s option in " +"iptables man page)." +msgstr "" +"数据包的源 IP,可以在后面加子网掩码(/[mask],请看 iptables 的 -s 参数说明)" + +msgid "Packet's source port, can be a range (eg. 80-90)." +msgstr "数据包的源端口,可以是一个范围(例如:80-90)" + +msgid "" +"Packets are tested against the rules in the order specified -- rules toward " +"the top have priority. As soon as a packet matches a rule it is classified, " +"and the rest of the rules are ignored. The order of the rules can be altered " +"using the arrow controls." +msgstr "" +"数据包将按规则中指定的顺序进行匹配 —— 靠上的规则优先进行匹配。一旦数据包匹配" +"一条规则那它将被归类,并且其余的规则将被忽略。使用上下箭头可调整规则的顺序。" + +msgid "Percent Bandwidth At Capacity" +msgstr "带宽占用百分比" + +msgid "QoS Switch" +msgstr "QoS 开关" + +msgid "" +"Quality of Service (QoS) provides a way to control how available bandwidth " +"is allocated." +msgstr "QoS 可以用来分配和控制可用带宽。" + +msgid "" +"Round trip ping times are compared against the ping limits. ACC controls the " +"link limit to maintain ping times under the appropriate limit. By default " +"ACC attempts to automatically select appropriate target ping limits for you " +"based on the link speeds you entered and the performance of your link it " +"measures during initialization. You cannot change the target ping time for " +"the minRTT mode but by entering a manual time you can control the target " +"ping time of the active mode. The time you enter becomes the increase in the " +"target ping time between minRTT and active mode. Leave empty to use the " +"default settings." +msgstr "" +"Ping 延时会与 Ping 限制进行比较。ACC 控制链路限制以保持 Ping 延时在适当范围。" +"默认情况下,ACC 会自动根据你输入的链接适当为你选择适当的 Ping 限制。如果你想" +"尝试不同的 Ping 限制,你可以在这里输入一个时间值。输入高的时间值将导致更高的 " +"Ping 限制,低的时间值会有更低的限制。留空则将由 ACC 自动控制。" + +msgid "Service Class" +msgstr "服务类型" + +msgid "Service Class Name" +msgstr "服务类型名称" + +msgid "Service Classes" +msgstr "服务类型" + +msgid "" +"Should be set to around 98% of your available upload bandwidth. Entering a " +"number which is too high will result in QoS not meeting its class " +"requirements. Entering a number which is too low will needlessly penalize " +"your upload speed. You should use a speed test program (with QoS off) to " +"determine available upload bandwidth. Note that bandwidth is specified in " +"kbps, leave blank to disable update QoS. There are 8 kilobits per kilobyte." +msgstr "" +"应被设置为你可用上传带宽的 98% 左右。输入数值太高将导致 QoS 不能匹配服务类型" +"的要求。输入数值太低将造成不必要的上传速度限制。你应当在 QoS 关闭的情况下使用" +"测速程序以确定可用的上传带宽。带宽以 kbps 为单位,留空以禁用上传 QoS。" +"(1KByte/s=8Kbps)" + +msgid "Source IP(s)" +msgstr "源 IP" + +msgid "Source Port(s)" +msgstr "源端口" + +msgid "Specifie how packets that do not match any rule should be classified." +msgstr "指定当数据包不匹配任何规则时将被如何归类。" + +msgid "" +"Specifying correctly is crucial to making QoS work. Note that bandwidth is " +"specified in kbps, leave blank to disable download QoS. There are 8 kilobits " +"per kilobyte." +msgstr "" +"正确设置对于 QoS 的工作至关重要。带宽以 kbps 为单位,留空以禁用下载 QoS。" +"(1KByte/s=8Kbps)" + +msgid "" +"The maximum amount of bandwidth this class will be allocated in kbit/s. Even " +"if unused bandwidth is available, this service class will never be permitted " +"to use more than this amount of bandwidth." +msgstr "" +"该服务类型可被分配的带宽最大值(以 kbit/s 为单位)。即使存在未使用带宽,该服" +"务类型也将永远不被允许使用超过此量的带宽。" + +msgid "" +"The minimum service this class will be allocated when the link is at " +"capacity. Classes which specify minimum service are known as realtime " +"classes by the active congestion controller. Streaming video, VoIP and " +"interactive online gaming are all examples of applications that must have a " +"minimum bandwith to function. To determine what to enter use the application " +"on an unloaded LAN and observe how much bandwidth it uses. Then enter a " +"number only slightly higher than this into this field. QoS will satisfiy the " +"minimum service of all classes first before allocating to other waiting " +"classes so be careful to use minimum bandwidths sparingly." +msgstr "" +"将被分配用于该服务类型的最低链路带宽容量。指定了最小带宽的服务类型会被主动拥" +"塞控制器看作实时类应用。例如视频流、VoIP 和在线互动游戏都应该设置最小带宽。要" +"确定需要多少最小带宽,可以在一个没有负载的局域网中使用应用程序并观察它使用了" +"多少带宽。然后输入一个略高于这个值的数字到字段中。在分配剩余带宽到其它服务类" +"型前,QoS 将优先满足所有服务类型的最小带宽要求,所以要谨慎地使用最小带宽。" + +msgid "" +"The percentage of the total available bandwidth that should be allocated to " +"this class when all available bandwidth is being used. If unused bandwidth " +"is available, more can (and will) be allocated. The percentages can be " +"configured to equal more (or less) than 100, but when the settings are " +"applied the percentages will be adjusted proportionally so that they add to " +"100. This setting only comes into effect when the WAN link is saturated." +msgstr "" +"当所有可用带宽被占满后该服务类型占据总带宽的百分比。如果带宽未用完,该服务类" +"型会被分配更多带宽。该百分比值可被设置为等于、大于或小于 100,但当设置被应用" +"时,百分比值将会被按比例调整以便使它们加起来等于 100。该设置只在 WAN 端链路饱" +"和时才生效。(PS:WAN 端链路饱和即带宽被占用完)" + +msgid "" +"The segment of network between your router and the ping target is where " +"congestion is controlled. By monitoring the round trip ping times to the " +"target congestion is detected. By default ACC uses your WAN gateway as the " +"ping target. If you know that congestion on your link will occur in a " +"different segment then you can enter an alternate ping target. Leave empty " +"to use the default settings." +msgstr "" +"在路由器和 Ping 目标之间的网络部分是拥塞控制的地方。拥塞通过监视和目标间的 " +"Ping 延时来检测。默认情况下 ACC 使用你的 WAN 网关作为 Ping 的目标。假如你知道" +"拥塞会在你链路的不同段发生,你可用输入一个备用的 Ping 目标。留空则将由ACC 自" +"动控制。" + +msgid "" +"The total size of data transmitted since the establishment of the link (in " +"kBytes)." +msgstr "自连接建立以来,传输的数据总量(单位:kBytes)" + +msgid "Total Download Bandwidth" +msgstr "下载总带宽" + +msgid "Total Upload Bandwidth" +msgstr "上传总带宽" + +msgid "Transport Protocol" +msgstr "协议" + +msgid "Troubleshooting" +msgstr "故障排除" + +msgid "Troubleshooting Data" +msgstr "故障排除数据" + +msgid "Unlimited" +msgstr "不限制" + +msgid "Upload Settings" +msgstr "上传设置" + +msgid "Use Non-standard Ping Target" +msgstr "使用自定义 Ping 目标" + +msgid "Zero" +msgstr "零" diff --git a/package/ctcgfw/luci-app-qos-gargoyle/root/etc/uci-defaults/40_luci-qos_gargoyle b/package/ctcgfw/luci-app-qos-gargoyle/root/etc/uci-defaults/40_luci-qos_gargoyle new file mode 100755 index 0000000000..675fd39fc3 --- /dev/null +++ b/package/ctcgfw/luci-app-qos-gargoyle/root/etc/uci-defaults/40_luci-qos_gargoyle @@ -0,0 +1,11 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@qos_gargoyle[-1] + add ucitrack qos_gargoyle + set ucitrack.@qos_gargoyle[-1].init=qos_gargoyle + commit ucitrack +EOF + +rm -rf /tmp/luci-modulecache /tmp/luci-indexcache +exit 0