X-Git-Url: https://git.harvie.cz/?p=svn%2FPrometheus-QoS%2F.git;a=blobdiff_plain;f=prometheus.c;h=dea239a2e9366b429790ce9389f976486fe23a03;hp=20a7603d7b4f7f776d96ca48a5a366c5792ccb72;hb=a25842fafee4469c8acbacd673fc4c905bcab3f9;hpb=ca6f7e80f4ce05259df01ec965beb7a4907b8540 diff --git a/prometheus.c b/prometheus.c index 20a7603..dea239a 100644 --- a/prometheus.c +++ b/prometheus.c @@ -1,12 +1,13 @@ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -/* Prometheus QoS - you can "steal fire" from your ISP *//* "fair-per-IP" quality of service (QoS) utility */ +/* 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-2013 Michael Polak, Arachne Aerospace */ /* iptables-restore support Copyright(C) 2007-2008 ludva */ /* Credit: CZFree.Net,Martin Devera,Netdave,Aquarius,Gandalf */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -/* Modified by: xChaos, 20130124 +/* Modified by: xChaos, 20131119 ludva, 20080415 Prometheus QoS is free software; you can redistribute it and/or @@ -28,7 +29,7 @@ #include "cll1-0.6.2.h" #include "ipstruct.h" -const char *version = "0.8.3-i"; +const char *version = "0.8.3-j"; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Versions: 0.8.3 is development release, 0.8.4 will be "stable" */ @@ -117,10 +118,6 @@ int magic_treshold = 8; /* reduce ceil by X*magic_treshhold kbps (hard shapi int keywordcount = 0; int class_count = 0; int ip_count = 0; -/* not yet implemented: -int fixed_packets = 0; maximum number of pps per IP address (not class!) -int packet_limit = 5; maximum number of pps to htn CEIL, not rate !!! -*/ FILE *log_file = NULL; char *kwd = "via-prometheus"; /* /etc/hosts comment, eg. #qos-64-128 */ @@ -131,10 +128,13 @@ const int idxtable_treshold2 = 12; /* this is no longer configurable */ const int idxtable_bitmask1 = 3; /* this is no longer configurable */ const int idxtable_bitmask2 = 3; /* this is no longer configurable */ -struct IP *ips = NULL, *ip, *sharedip; +struct IP *ips = NULL, *networks = NULL, *ip, *sharedip; struct Group *groups = NULL, *group; struct Keyword *keyword, *defaultkeyword=NULL, *keywords=NULL; +#define FREE_CLASS 3 +#define OVERLIMIT_CLASS 4 + void help(void); /* implemented in help.c */ @@ -153,6 +153,10 @@ void write_json_traffic(char *json); void write_htmlandlogs(char *html, char *d, int total, int just_preview); /* implemented in htmlandlogs.c */ +void analyse_topology(char *traceroute); +/* implemented in networks.c */ + + const char *tr_odd_even(void) { row_odd_even = 1 - row_odd_even; @@ -336,10 +340,10 @@ void get_config(char *config_filename) /* leaf discipline for keywords */ for_each(keyword,keywords) { - if(!strcmpi(keyword->leaf_discipline, "")) - { - keyword->leaf_discipline = qos_leaf; - } + if(!strcmpi(keyword->leaf_discipline, "")) + { + keyword->leaf_discipline = qos_leaf; + } } if(strcmpi(cnf, "mark")) @@ -464,13 +468,16 @@ program int i=0; /* just plain old Fortran style integer :-) */ FILE *f=NULL; /* everything is just stream of bytes... */ char *str, *ptr, *d; /* LET A$=B$ :-) */ - char *substring; + char *substring, *limit_pkts; int parent = 1; + int just_networks = FALSE; int just_flush = FALSE; /* deactivates all previous actions */ int nodelay = FALSE; int just_preview = FALSE; /* preview - generate just stats */ int start_shaping = FALSE; /* apply FUP - requires classmap file */ + int stop_shaping = FALSE; /* lift FUP - requires classmap file */ + int reduce_ceil = 0; /* allow only rate+(ceil-rate)/2, /4, etc. */ int just_logs = FALSE; /* just parse logs */ int run = FALSE; int total = 0; @@ -493,9 +500,13 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); argument("-f") { run=TRUE; just_flush=TRUE; } argument("-9") { run=TRUE; just_flush=9; } argument("-p") { run=TRUE; just_preview=TRUE; } + argument("-q") { run=TRUE; just_preview=TRUE; stop_shaping=TRUE; } + argument("-2") { run=TRUE; just_preview=TRUE; reduce_ceil=2; } + argument("-4") { run=TRUE; just_preview=TRUE; reduce_ceil=4; } argument("-s") { run=TRUE; just_preview=TRUE; start_shaping=TRUE; } argument("-r") { run=TRUE; } argument("-n") { run=TRUE; nodelay=TRUE; } + argument("-a") { run=TRUE; just_networks=TRUE; } argument("-l") { just_logs=TRUE; } argument("-m") { just_logs=TRUE; } argument("-y") { just_logs=TRUE; } @@ -530,7 +541,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); if(althosts) { - hosts=althosts; + hosts = althosts; } if(just_flush<9) @@ -549,26 +560,33 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); } /*-----------------------------------------------------------------*/ - printf("Parsing class defintion file %s ...\n", hosts); + /* cll1.h - let's allocate brand new character buffer... */ /*-----------------------------------------------------------------*/ - parse_hosts(hosts); + string(str, STRLEN); + string(limit_pkts, STRLEN); /*-----------------------------------------------------------------*/ - /* cll1.h - let's allocate brand new character buffer... */ + printf("Parsing class defintion file %s ...\n", hosts); /*-----------------------------------------------------------------*/ - string(str,STRLEN); + parse_hosts(hosts); + if(just_networks) + { + analyse_topology("/usr/sbin/traceroute -n -m 10 -w 2 %s.%d"); + exit(-1); + } /*-----------------------------------------------------------------*/ puts("Resolving shared connections ..."); /*-----------------------------------------------------------------*/ - for_each(ip,ips) if(ip->sharing) + for_each(ip, ips) if(ip->sharing) { - for_each(sharedip,ips) if(eq(sharedip->name,ip->sharing)) + for_each(sharedip, ips) if(eq(sharedip->name, ip->sharing)) { - sharedip->traffic+=ip->traffic; - ip->traffic=0; - ip->mark=sharedip->mark; - ip->lmsid=sharedip->lmsid; + sharedip->traffic += ip->traffic; + ip->traffic = 0; + ip->mark = sharedip->mark; + ip->lmsid = sharedip->lmsid; + ip->pps_limit = sharedip->pps_limit; /* no other way to do this */ break; } if(not sharedip) @@ -654,6 +672,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); sprintf(str,"-A FORWARD -d %s -o %s -j ACCEPT", qos_free_zone, wan); iptables_save_line(str, FALSE); /* this is currently supported only for IPv4 */ +/* if(qos_proxy) { iptables_save_line(":post_noproxy - [0:0]", FALSE); @@ -666,10 +685,12 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); chain="post_noproxy"; } + else { - chain="POSTROUTING"; - } +*/ + chain = "POSTROUTING"; +// } sprintf(str,"-A %s -s %s -o %s -j ACCEPT", chain, qos_free_zone, lan); iptables_save_line(str, FALSE); @@ -976,7 +997,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); if(just_preview) { - if(start_shaping) + if(start_shaping || stop_shaping || reduce_ceil) { printf("Reading %s and applying Fair Use Policy rules ... \n", classmap); parse(classmap) @@ -989,9 +1010,21 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); if_exists(ip,ips,eq(ip->addr,_)) { ip->mark=atoi(ptr); - if(ip->max < ip->desired) /* apply FUP limit immediately.... */ + if(ip->max < ip->desired || stop_shaping || reduce_ceil) /* apply or disable FUP limit immediately.... */ { - printf("Applying limit for %-22s %-16s %04d ", ip->name, ip->addr, ip->mark); + if(stop_shaping) + { + ip->max = ip->desired; + printf("Removing limit for %-22s %-16s %04d ", ip->name, ip->addr, ip->mark); + } + else + { + printf("Applying limit for %-22s %-16s %04d ", ip->name, ip->addr, ip->mark); + if(reduce_ceil) + { + ip->max = ip->min + (ip->desired-ip->min)/reduce_ceil; + } + } 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); @@ -1012,6 +1045,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); perror(classmap); puts("Warning - classmap file not fund, just generating preview ..."); start_shaping=FALSE; + stop_shaping=FALSE; } done; /* ugly macro end */ } @@ -1039,6 +1073,15 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); { swchar='s'; } + else if(reduce_ceil) + { + swchar='0'+reduce_ceil; /* -2, -4 */ + } + else if(stop_shaping) + { + swchar='q'; + } + printf("Statistics preview generated (-%c switch) - now exiting ...\n", swchar); exit(0); } @@ -1090,23 +1133,45 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); chain_postrouting="POSTROUTING"; } + /* packet limits - this will be optional in future */ + if(ip->pps_limit) + { + sprintf(limit_pkts, "-m limit --limit %d/s --limit-burst %d ", + ip->pps_limit, ip->pps_limit); + } + else + { + *limit_pkts = 0; + } + #ifdef DEBUG - printf("%-22s %-16s %04d ", ip->name, ip->addr, ip->mark); + printf("%-22s %-16s %04d %d/s\n", ip->name, ip->addr, ip->mark, ip->pps_limit); #endif - /* -------------------------------------------------------- mark download */ - + /* -------------------------------------------------------- mark download */ sprintf(str, "-A %s -d %s/%d -o %s -j %s%d", - chain_postrouting, ip->addr, 32*(1+ip->v6), lan, mark_iptables, ip->mark); - /* -m limit --limit 1/s */ + chain_postrouting, ip->addr, 32*(1+ip->v6), + lan, mark_iptables, ip->mark); iptables_save_line(str, ip->v6); +/* if(qos_proxy) { 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); + chain_postrouting, proxy_ip, proxy_port, ip->addr, + 32*(1+ip->v6), 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); + 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), + 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); @@ -1117,6 +1182,15 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); chain_forward, ip->addr, 32*(1+ip->v6), 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); + 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); + 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); iptables_save_line(str, ip->v6); @@ -1129,7 +1203,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); #endif sprintf(str, "%s class add 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); + tc, lan, ip->group, ip->mark, ip->min, ip->max, burst, ip->prio); safe_run(str); if(strcmpi(ip->keyword->leaf_discipline, "none")) @@ -1207,23 +1281,25 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); final_chain = "ACCEPT"; } +/* if(qos_proxy) { if(free_min) { sprintf(str, "-A %s -s %s -p tcp --sport %d -o %s -j %s%d", chain_postrouting,proxy_ip,proxy_port,lan,mark_iptables, 3); - iptables_save_line(str, FALSE); /* only for IPv4 */ + iptables_save_line(str, FALSE); // only for IPv4 } sprintf(str, "-A %s -s %s -p tcp --sport %d -o %s -j %s", chain_postrouting,proxy_ip,proxy_port,lan,final_chain); - iptables_save_line(str, FALSE); /* only for IPv4 */ + iptables_save_line(str, FALSE); // only for IPv4 } +*/ if(free_min) { sprintf(str, "-A %s -o %s -j %s%d", - chain_postrouting, lan, mark_iptables, 3); + chain_postrouting, lan, mark_iptables, FREE_CLASS); iptables_save_line(str, FALSE); /* only for IPv4 */ } @@ -1237,7 +1313,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); if(free_min) { - sprintf(str,"-A %s -o %s -j %s%d", chain_forward, wan, mark_iptables, 3); + sprintf(str,"-A %s -o %s -j %s%d", chain_forward, wan, mark_iptables, FREE_CLASS); iptables_save_line(str, FALSE); /* only for IPv4 */ } @@ -1252,28 +1328,38 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); if(free_min) /* allocate free bandwith if it is not zero... */ { /*-----------------------------------------------------------------*/ - puts("Generating free bandwith classes ..."); + puts("Generating free bandwith class ..."); /*-----------------------------------------------------------------*/ - sprintf(str, "%s class add dev %s parent 1:%d classid 1:3 htb rate %dkbit ceil %dkbit burst %dk prio %d", - tc, lan, parent, free_min, free_max,burst, lowest_priority); + sprintf(str, "%s class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit burst %dk prio %d", + tc, lan, parent, FREE_CLASS, free_min, free_max,burst, lowest_priority); safe_run(str); - sprintf(str, "%s class add dev %s parent 1:%d classid 1:3 htb rate %dkbit ceil %dkbit burst %dk prio %d", - tc, wan, parent, free_min, free_max, burst, lowest_priority); + sprintf(str, "%s class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit burst %dk prio %d", + tc, wan, parent, FREE_CLASS, free_min, free_max, burst, lowest_priority); safe_run(str); /* tc SFQ */ if(strcmpi(qos_leaf, "none")) { - sprintf(str,"%s qdisc add dev %s parent 1:3 handle 3 %s", tc, lan, qos_leaf); + sprintf(str,"%s qdisc add dev %s parent 1:%d handle %d %s", tc, lan, FREE_CLASS, FREE_CLASS, qos_leaf); safe_run(str); - sprintf(str,"%s qdisc add dev %s parent 1:3 handle 3 %s", tc, wan, qos_leaf); + sprintf(str,"%s qdisc add dev %s parent 1:%d handle %d %s", tc, wan, FREE_CLASS, FREE_CLASS, qos_leaf); safe_run(str); } /* tc handle 1 fw flowid */ - sprintf(str,"%s filter add dev %s parent 1:0 protocol ip handle 3 fw flowid 1:3", tc, lan); + sprintf(str,"%s filter add dev %s parent 1:0 protocol ip handle %d fw flowid 1:%d", tc, lan, FREE_CLASS, FREE_CLASS); + safe_run(str); + + sprintf(str,"%s filter add dev %s parent 1:0 protocol ip handle %d fw flowid 1:%d", tc, wan, FREE_CLASS, FREE_CLASS); safe_run(str); - sprintf(str,"%s filter add dev %s parent 1:0 protocol ip handle 3 fw flowid 1:3", tc, wan); + /*-----------------------------------------------------------------*/ + puts("Generating bandwith class for overlimit packets..."); + /*-----------------------------------------------------------------*/ + sprintf(str, "%s class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit burst %dk prio %d", + tc, lan, parent, OVERLIMIT_CLASS, 1024, 4096, burst, lowest_priority); + safe_run(str); + sprintf(str, "%s class add dev %s parent 1:%d classid 1:%d htb rate %dkbit ceil %dkbit burst %dk prio %d", + tc, wan, parent, OVERLIMIT_CLASS, 1024, 4096, burst, lowest_priority); safe_run(str); } printf("Total IP count: %d\n", i);