/* Prometheus QoS - you can "steal fire" from your ISP */\r
/* "fair-per-IP" quality of service (QoS) utility */\r
/* requires Linux 2.4.x or 2.6.x with HTB support */\r
-/* Copyright(C) 2005-2014 Michael Polak, Arachne Aerospace */\r
+/* Copyright(C) 2005-2015 Michael Polak, Arachne Aerospace */\r
/* iptables-restore support Copyright(C) 2007-2008 ludva */\r
/* Credit: CZFree.Net,Martin Devera,Netdave,Aquarius,Gandalf */\r
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
\r
-/* Modified by: xChaos, 20140812\r
+/* Modified by: xChaos, 20150331\r
ludva, 20080415\r
\r
Prometheus QoS is free software; you can redistribute it and/or\r
#include "cll1-0.6.2.h"\r
#include "ipstruct.h"\r
\r
-const char *version = "0.8.5-b";\r
+const char *version = "0.8.5-c";\r
\r
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
/* Versions: 0.8.3 is development release, 0.8.4 will be "stable" */\r
/* Warning: unofficial Github mirror is not supported by author! */\r
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
\r
-const char *stats_html_signature = "<span class=\"small\">Statistics generated by Prometheus QoS version %s<br />GPL+Copyright(C)2005-2014 Michael Polak, <a target=\"_blank\" href=\"http://www.arachne.cz/\">Arachne Labs</a></span>\n";\r
+const char *stats_html_signature = "<span class=\"small\">Statistics generated by Prometheus QoS version %s<br />GPL+Copyright(C)2005-2015 Michael Polak, <a target=\"_blank\" href=\"http://www.arachne.cz/\">Arachne Labs</a></span>\n";\r
\r
#define STRLEN 512\r
#undef DEBUG\r
void analyse_topology(char *traceroute);\r
/* implemented in networks.c */\r
\r
+char *parse_datafile_line(char *str);\r
+/* implemented in utils.c */\r
+\r
+time_t get_mtime(const char *path);\r
+/* implemented in utils.c */\r
\r
const char *tr_odd_even(void)\r
{\r
keyword->reserve_min = 8; /* bonus for nominal HTB rate bandwidth (in kbps) */\r
keyword->reserve_max = 0; /* malus for nominal HTB ceil (in kbps) */\r
keyword->default_prio = highest_priority+1;\r
+ keyword->download_aggregation = keyword->upload_aggregation = 0; /* disable by default */\r
keyword->html_color = "000000";\r
keyword->ip_count = 0;\r
keyword->leaf_discipline = "";\r
keyword->allowed_avgmtu = 0;\r
+ keyword->download_aggregation = keyword->upload_aggregation = 1;\r
\r
push(keyword, keywords);\r
if(!defaultkeyword)\r
{\r
char *tmptr=_; /* <---- l+1 ----> */\r
_+=l+1; /* via-prometheus-asymetry-ratio, etc. */\r
- ioption("asymetry-ratio", keyword->asymetry_ratio);\r
+ foption("asymetry-ratio", keyword->asymetry_ratio);\r
ioption("asymetry-treshold", keyword->asymetry_fixed);\r
ioption("magic-relative-limit", keyword->data_limit);\r
ioption("magic-relative-prio", keyword->data_prio);\r
ioption("htb-default-prio", keyword->default_prio);\r
ioption("htb-rate-bonus", keyword->reserve_min);\r
ioption("htb-ceil-malus", keyword->reserve_max);\r
+ ioption("download-aggregation", keyword->download_aggregation);\r
+ ioption("upload-aggregation", keyword->upload_aggregation);\r
option("leaf-discipline", keyword->leaf_discipline);\r
option("html-color", keyword->html_color);\r
ioption("allowed-avgmtu" ,keyword->allowed_avgmtu);\r
free(restor);\r
}\r
\r
-char *parse_datafile_line(char *str)\r
-{\r
- char *ptr = strchr(str,' ');\r
- if(!ptr)\r
- {\r
- ptr = strchr(str,'\t');\r
- }\r
-\r
- if(ptr)\r
- {\r
- *ptr = 0;\r
- ptr++;\r
- while(*ptr == ' ' || *ptr == '\t')\r
- {\r
- ptr++;\r
- }\r
- return ptr;\r
- } \r
- else \r
- {\r
- return NULL;\r
- }\r
-}\r
+/**/\r
\r
+char *parse_datafile_line(char *str);\r
+time_t get_mtime(const char *path);\r
\r
/*-----------------------------------------------------------------*/\r
/* Are you looking for int main(int argc, char **argv) ? :-)) */\r
\r
printf("\n\\r
Prometheus QoS - \"fair-per-IP\" Quality of Service setup utility.\n\\r
-Version %s - Copyright (C)2005-2013 Michael Polak, Arachne Labs\n\\r
+Version %s - Copyright (C)2005-2015 Michael Polak, Arachne Labs\n\\r
iptables-restore & burst tunning & classify modification by Ludva\n\\r
Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version);\r
\r
for_each(sharedip, ips) if(eq(sharedip->name, ip->sharing))\r
{\r
sharedip->traffic += ip->traffic;\r
+ sharedip->traffic_down += ip->direct;\r
+ sharedip->traffic_up += ip->upload;\r
ip->traffic = 0;\r
ip->mark = sharedip->mark; \r
ip->lmsid = sharedip->lmsid;\r
ip->pps_limit = sharedip->pps_limit; /* no other way to do this */\r
+\r
+ /* Ugly hack: append IPv4 addresses of sharedip to IPv6 uplinks */\r
+ ptr = strchr(ip->addr, '+');\r
+ if(ptr && ptr-ip->addr > 1 && !sharedip->v6)\r
+ {\r
+ *(--ptr) = 0;\r
+ concatenate(ip->addr, sharedip->addr, ptr);\r
+ ip->name = ip->addr = ptr;\r
+ ptr = strchr(ip->addr, '.');\r
+ while(ptr && *ptr)\r
+ {\r
+ *ptr = ':';\r
+ ptr = strchr(ptr, '.');\r
+ }\r
+ ip->mask += 64;\r
+ }\r
+\r
break;\r
}\r
if(not sharedip)\r
{\r
if(start_shaping || stop_shaping || reduce_ceil)\r
{\r
- printf("Reading %s and applying Fair Use Policy rules ... \n", classmap);\r
+ time_t how_much_seconds = time(NULL) - get_mtime(classmap); /* sice start of daily aggregation session */\r
+ printf("Reading %s (%ld seconds old) and applying Fair Use Policy and Aggregation rules... \n", classmap, how_much_seconds);\r
+ \r
parse(classmap)\r
{\r
ptr=strchr(_,' ');\r
ptr++;\r
if_exists(ip,ips,eq(ip->addr,_))\r
{\r
- ip->mark=atoi(ptr);\r
- if(ip->max < ip->desired || stop_shaping || reduce_ceil) /* apply or disable FUP limit immediately.... */\r
+ int unshape_this_ip = stop_shaping;\r
+ long avg_mbps_down = ip->traffic_down * 8 / how_much_seconds; \r
+ long avg_mbps_up = ip->traffic_up * 8 / how_much_seconds;\r
+ int min_mbps = ip->min>>10;\r
+ int agreg = 1, print_stats = 1;\r
+ \r
+ if(min_mbps < 1)\r
{\r
- if(stop_shaping)\r
+ min_mbps = 1;\r
+ }\r
+ \r
+ if(ip->keyword->download_aggregation)\r
+ {\r
+ if(min_mbps <= avg_mbps_down)\r
+ {\r
+ unshape_this_ip = 0;\r
+ agreg = (int)((float)(avg_mbps_down+1)/min_mbps+.5);\r
+ ip->max /= agreg;\r
+ printf("Download aggregation 1:%d for %s (min: %lu Mbps avg: %ld Mbps)\n", agreg, ip->name, min_mbps, avg_mbps_down);\r
+ }\r
+ else\r
+ {\r
+ unshape_this_ip = 1;\r
+ }\r
+ }\r
+ else if(ip->keyword->upload_aggregation)\r
+ {\r
+ if(min_mbps <= avg_mbps_up)\r
+ {\r
+ unshape_this_ip = 0;\r
+ agreg = (int)((float)(avg_mbps_up+1)/min_mbps+.5);\r
+ ip->max /= agreg;\r
+ printf("Upload aggregation 1:%d for %s: (min: %lu Mbps avg: %ld Mbps)\n", agreg, ip->name, min_mbps, avg_mbps_up);\r
+ }\r
+ else\r
+ {\r
+ unshape_this_ip = 1;\r
+ }\r
+ }\r
+ ip->aggregated = agreg; \r
+ ip->mark = atoi(ptr);\r
+ if(ip->max < ip->desired || unshape_this_ip || reduce_ceil) /* apply or disable FUP limit immediately.... */\r
+ {\r
+ if(unshape_this_ip)\r
{\r
ip->max = ip->desired;\r
- printf("Removing limit for %-22s %-16s %04d ", ip->name, ip->addr, ip->mark); \r
+ if(stop_shaping) /* all limits removed, but not printed with -s (start_shaping) switch */\r
+ {\r
+ printf("Removing limit for %s (%s) ", ip->name, ip->addr);\r
+ }\r
+ else\r
+ {\r
+ print_stats = 0;\r
+ }\r
}\r
else\r
{\r
- printf("Applying limit for %-22s %-16s %04d ", ip->name, ip->addr, ip->mark);\r
+ printf("Applying limit for %s (%s) ", ip->name, ip->addr);\r
if(reduce_ceil)\r
{\r
ip->max = ip->min + (ip->desired-ip->min)/reduce_ceil;\r
}\r
+ else if(ip->max < ip->min)\r
+ {\r
+ ip->max = ip->min;\r
+ } \r
+ }\r
+ if(print_stats)\r
+ {\r
+ printf("(down: %dk-%dk wants %dk, ", ip->min, ip->max, ip->desired);\r
}\r
- printf("(down: %dk-%dk ", ip->min, ip->max); \r
sprintf(str, "%s class change dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit burst %dk prio %d", \r
tc, lan, ip->group, ip->mark,ip->min,ip->max, burst, ip->prio);\r
safe_run(str);\r
- printf("up: %dk-%dk)\n", (int)((ip->min/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed), \r
- (int)((ip->max/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed));\r
+ if(print_stats)\r
+ {\r
+ printf("up: %dk-%dk wants %dk)\n", (int)((ip->min/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed), \r
+ (int)((ip->desired/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed),\r
+ (int)((ip->desired/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed));\r
+ }\r
sprintf(str,"%s class change dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit burst %dk prio %d",\r
tc, wan, ip->group, ip->mark,\r
(int)((ip->min/ip->keyword->asymetry_ratio)-ip->keyword->asymetry_fixed),\r
\r
/* -------------------------------------------------------- mark download */ \r
sprintf(str, "-A %s -d %s/%d -o %s -j %s%d",\r
- chain_postrouting, ip->addr, 32*(1+ip->v6),\r
+ chain_postrouting, ip->addr, ip->mask,\r
lan, mark_iptables, ip->mark);\r
iptables_save_line(str, ip->v6);\r
\r
{\r
sprintf(str, "-A %s -s %s -p tcp --sport %d -d %s/%d -o %s -j %s%d",\r
chain_postrouting, proxy_ip, proxy_port, ip->addr,\r
- 32*(1+ip->v6), lan, mark_iptables, ip->mark);\r
+ ip->mask, lan, mark_iptables, ip->mark);\r
iptables_save_line(str, ip->v6);\r
}\r
*/\r
sprintf(str, "-A %s -d %s/%d -o %s %s-j ACCEPT",\r
- chain_postrouting, ip->addr, 32*(1+ip->v6), lan, limit_pkts);\r
+ chain_postrouting, ip->addr, ip->mask, lan, limit_pkts);\r
iptables_save_line(str, ip->v6);\r
\r
/* classify overlimit packets to separate overlimit class */\r
sprintf(str, "-A %s -d %s/%d -o %s -j %s%d",\r
- chain_postrouting, ip->addr, 32*(1+ip->v6),\r
+ chain_postrouting, ip->addr, ip->mask,\r
lan, mark_iptables, OVERLIMIT_CLASS);\r
iptables_save_line(str, ip->v6);\r
\r
sprintf(str, "-A %s -d %s/%d -o %s -j ACCEPT",\r
- chain_postrouting, ip->addr, 32*(1+ip->v6), lan);\r
+ chain_postrouting, ip->addr, ip->mask, lan);\r
iptables_save_line(str, ip->v6);\r
\r
/* -------------------------------------------------------- mark upload */\r
sprintf(str, "-A %s -s %s/%d -o %s -j %s%d", \r
- chain_forward, ip->addr, 32*(1+ip->v6), wan, mark_iptables, ip->mark);\r
+ chain_forward, ip->addr, ip->mask, wan, mark_iptables, ip->mark);\r
iptables_save_line(str, ip->v6);\r
\r
sprintf(str, "-A %s -s %s/%d -o %s %s-j ACCEPT",\r
- chain_forward, ip->addr, 32*(1+ip->v6), wan, limit_pkts);\r
+ chain_forward, ip->addr, ip->mask, wan, limit_pkts);\r
iptables_save_line(str, ip->v6);\r
\r
/* classify overlimit packets to separate overlimit class */\r
sprintf(str, "-A %s -s %s/%d -o %s -j %s%d", \r
- chain_forward, ip->addr, 32*(1+ip->v6), wan, mark_iptables, OVERLIMIT_CLASS);\r
+ chain_forward, ip->addr, ip->mask, wan, mark_iptables, OVERLIMIT_CLASS);\r
iptables_save_line(str, ip->v6);\r
\r
sprintf(str, "-A %s -s %s/%d -o %s -j ACCEPT",\r
- chain_forward, ip->addr, 32*(1+ip->v6), wan);\r
+ chain_forward, ip->addr, ip->mask, wan);\r
iptables_save_line(str, ip->v6);\r
\r
if(ip->min)\r