X-Git-Url: http://git.harvie.cz/?p=svn%2FPrometheus-QoS%2F.git;a=blobdiff_plain;f=prometheus.c;h=279da9b75d28b4fd245b28ed4e6165eaae86fc91;hp=48384a6a16fa639279e85ef70a0e50f51ce06364;hb=06733b885c35e5bf83505d064c55ccdda848ac01;hpb=d7357b63c9942c72481993bdb9632861c1d83a55 diff --git a/prometheus.c b/prometheus.c index 48384a6..279da9b 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, 20131118 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" */ @@ -83,6 +84,7 @@ char *mark = "MARK"; char *mark_iptables = "MARK --set-mark "; int dry_run = FALSE; /* preview - use puts() instead of system() */ char *iptablespreamble = "*mangle\n:PREROUTING ACCEPT [0:0]\n:POSTROUTING ACCEPT [0:0]\n:INPUT ACCEPT [0:0]\n:OUTPUT ACCEPT [0:0]\n:FORWARD ACCEPT [0:0]"; +char *ip6preamble = "-A FORWARD -p ipv6-icmp -j ACCEPT\n-A POSTROUTING -p ipv6-icmp -j ACCEPT\n-A FORWARD -s fe80::/10 -j ACCEPT\n-A FORWARD -d ff00::/8 -j ACCEPT\n-A POSTROUTING -s fe80::/10 -j ACCEPT\n-A POSTROUTING -d ff00::/8 -j ACCEPT"; FILE *iptables_file = NULL; FILE *ip6tables_file = NULL; int enable_credit = TRUE; /* enable credit file */ @@ -116,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 */ @@ -130,7 +128,7 @@ 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; @@ -152,6 +150,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; @@ -335,10 +337,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")) @@ -463,13 +465,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; @@ -492,9 +497,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; } @@ -529,7 +538,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); if(althosts) { - hosts=althosts; + hosts = althosts; } if(just_flush<9) @@ -548,26 +557,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) @@ -619,6 +635,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); exit(-1); } iptables_save_line(iptablespreamble, TRUE); + iptables_save_line(ip6preamble, TRUE); } run_iptables_restore(); @@ -628,8 +645,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); { perror(cmdlog); exit(-1); - } - + } sprintf(str,"%s qdisc del dev %s root 2>/dev/null",tc,lan); safe_run(str); @@ -643,6 +659,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); { ip6tables_file=fopen(ip6tablesfile,"w"); iptables_save_line(iptablespreamble, TRUE); + iptables_save_line(ip6preamble, TRUE); } if(qos_free_zone && *qos_free_zone!='0') /* this is currently supported only for IPv4 */ @@ -974,7 +991,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) @@ -987,9 +1004,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); @@ -1010,6 +1039,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 */ } @@ -1037,6 +1067,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); } @@ -1046,7 +1085,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); printf("%-22s %-15s mark\n","name","ip"); #endif - printf("Writing %s ... ", classmap); + printf("Writing %s", classmap); f = fopen(classmap, "w"); if(f < 0) { @@ -1054,7 +1093,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); } /*-----------------------------------------------------------------*/ - puts("Generating iptables and tc classes ... "); + printf(" + generating iptables and tc classes ... "); /*-----------------------------------------------------------------*/ for_each(ip, ips) if(ip->mark > 0) /* works only for IPv4 so far */ @@ -1088,26 +1127,36 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); chain_postrouting="POSTROUTING"; } + /* packet limits - this will be optional in future, hardcoded for now */ + if(ip->pps_limit) + { + sprintf(limit_pkts, "-m limit --limit %d/s ", 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 -j ACCEPT", - chain_postrouting, ip->addr, 32*(1+ip->v6), lan); + 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); /* -------------------------------------------------------- mark upload */ @@ -1115,8 +1164,8 @@ 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 -j ACCEPT", - chain_forward, ip->addr, 32*(1+ip->v6), wan); + 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); if(ip->min) @@ -1127,7 +1176,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"))