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