From f671c4f9650029e5fb068f7bec804f68eab96408 Mon Sep 17 00:00:00 2001 From: Richard Nyberg Date: Sat, 23 Jul 2005 21:29:46 +0000 Subject: [PATCH] Use the old simpler bandwidth limiter, but run it at a configurable rate. Let the default be 8 hz for now. Removed a try at time correction. I don't really think it'll matter and there was a potential bug if the clock went backwards. Removed net_by_second. Let the peer bandwidth calculation be handled in cm_by_second. --- btpd/btpd.c | 33 +++++++++----- btpd/btpd.h | 5 ++- btpd/net.c | 114 +++++++++++++++++------------------------------ btpd/net.h | 10 +---- btpd/policy_if.c | 8 ++++ 5 files changed, 73 insertions(+), 97 deletions(-) diff --git a/btpd/btpd.c b/btpd/btpd.c index 55b2b24..9890c4a 100644 --- a/btpd/btpd.c +++ b/btpd/btpd.c @@ -116,7 +116,6 @@ btpd_init(void) btpd.ntorrents = 0; BTPDQ_INIT(&btpd.cm_list); - BTPDQ_INIT(&btpd.bwq); BTPDQ_INIT(&btpd.readq); BTPDQ_INIT(&btpd.writeq); @@ -124,6 +123,7 @@ btpd_init(void) btpd.port = 6881; + btpd.bw_hz = 8; btpd.obwlim = 0; btpd.ibwlim = 0; btpd.obw_left = 0; @@ -187,20 +187,13 @@ static void heartbeat_cb(int sd, short type, void *arg) { struct torrent *tp; - struct timeval begin, end, wadj; - gettimeofday(&begin, NULL); btpd.seconds++; BTPDQ_FOREACH(tp, &btpd.cm_list, entry) cm_by_second(tp); - net_by_second(); - - gettimeofday(&end, NULL); - timersub(&end, &begin, &wadj); - evtimer_add(&btpd.heartbeat, - (& (struct timeval) { 0, 1000000 - wadj.tv_usec })); + evtimer_add(&btpd.heartbeat, (& (struct timeval) { 0, 1000000 })); } static void @@ -210,6 +203,10 @@ usage() "\n" "Options:\n" "\n" + "--bw-hz n\n" + "\tRun the bandwidth limiter at n hz.\n" + "\tDefault is 8 hz.\n" + "\n" "--bw-in n\n" "\tLimit incoming BitTorrent traffic to n kB/s.\n" "\tDefault is 0 which means unlimited.\n" @@ -242,6 +239,7 @@ static int longval = 0; static struct option longopts[] = { { "port", required_argument, NULL, 'p' }, + { "bw-hz", required_argument, &longval, 6 }, { "bw-in", required_argument, &longval, 1 }, { "bw-out", required_argument, &longval, 2 }, { "logfile", required_argument, &longval, 3 }, @@ -272,11 +270,9 @@ main(int argc, char **argv) switch (longval) { case 1: btpd.ibwlim = atoi(optarg) * 1024; - btpd.ibw_left = btpd.ibwlim; break; case 2: btpd.obwlim = atoi(optarg) * 1024; - btpd.obw_left = btpd.obwlim; break; case 3: logfile = optarg; @@ -289,6 +285,12 @@ main(int argc, char **argv) break; case 5: usage(); + case 6: + btpd.bw_hz = atoi(optarg); + if (btpd.bw_hz <= 0 || btpd.bw_hz > 100) + btpd_err("I will only accept bw limiter hz " + "between 1 and 100.\n"); + break; default: usage(); } @@ -370,7 +372,6 @@ main(int argc, char **argv) setlinebuf(stdout); setlinebuf(stderr); - event_init(); signal(SIGPIPE, SIG_IGN); @@ -393,6 +394,14 @@ main(int argc, char **argv) net_connection_cb, &btpd); event_add(&btpd.accept4, NULL); + evtimer_set(&btpd.bwlim, net_bw_cb, NULL); + if (btpd.obwlim > 0 || btpd.ibwlim > 0) { + btpd.ibw_left = btpd.ibwlim / btpd.bw_hz; + btpd.obw_left = btpd.obwlim / btpd.bw_hz; + evtimer_add(&btpd.bwlim, + (& (struct timeval) { 0, 1000000 / btpd.bw_hz })); + } + error = event_dispatch(); btpd_err("Returned from dispatch. Error = %d.\n", error); diff --git a/btpd/btpd.h b/btpd/btpd.h index 9356d0a..86b1614 100644 --- a/btpd/btpd.h +++ b/btpd/btpd.h @@ -46,7 +46,6 @@ struct btpd { unsigned ntorrents; struct torrent_tq cm_list; - struct bwlim_tq bwq; struct peer_tq readq; struct peer_tq writeq; @@ -56,9 +55,11 @@ struct btpd { int peer4_sd; int ipc_sd; + unsigned bw_hz; unsigned long obwlim, ibwlim; unsigned long ibw_left, obw_left; - + struct event bwlim; + unsigned npeers; unsigned maxpeers; diff --git a/btpd/net.c b/btpd/net.c index 34d0cf1..f3037b8 100644 --- a/btpd/net.c +++ b/btpd/net.c @@ -25,34 +25,6 @@ static unsigned long net_write(struct peer *p, unsigned long wmax); -void -net_bw_read_cb(int sd, short type, void *arg) -{ - struct peer *p; - struct bwlim *bw = arg; - - btpd.ibw_left += bw->count; - assert(btpd.ibw_left <= btpd.ibwlim); - - unsigned long count = 0; - - while ((p = BTPDQ_FIRST(&btpd.readq)) != NULL && btpd.ibw_left - count > 0) { - BTPDQ_REMOVE(&btpd.readq, p, rq_entry); - p->flags &= ~PF_ON_READQ; - count += p->reader->read(p, btpd.ibw_left - count); - } - btpd.ibw_left -= count; - - BTPDQ_REMOVE(&btpd.bwq, bw, entry); - if (count == 0) - free(bw); - else { - bw->count = count; - event_add(&bw->timer, (& (struct timeval) { 1, 0 })); - BTPDQ_INSERT_TAIL(&btpd.bwq, bw, entry); - } -} - void net_read_cb(int sd, short type, void *arg) { @@ -60,49 +32,13 @@ net_read_cb(int sd, short type, void *arg) if (btpd.ibwlim == 0) { p->reader->read(p, 0); } else if (btpd.ibw_left > 0) { - unsigned long nread = p->reader->read(p, btpd.ibw_left); - if (nread > 0) { - struct bwlim *bw = btpd_calloc(1, sizeof(*bw)); - evtimer_set(&bw->timer, net_bw_read_cb, bw); - evtimer_add(&bw->timer, (& (struct timeval) { 1, 0 })); - bw->count = nread; - btpd.ibw_left -= nread; - BTPDQ_INSERT_TAIL(&btpd.bwq, bw, entry); - } + btpd.ibw_left -= p->reader->read(p, btpd.ibw_left); } else { p->flags |= PF_ON_READQ; BTPDQ_INSERT_TAIL(&btpd.readq, p, rq_entry); } } -void -net_bw_write_cb(int sd, short type, void *arg) -{ - struct peer *p; - struct bwlim *bw = arg; - - btpd.obw_left += bw->count; - assert(btpd.obw_left <= btpd.obwlim); - - unsigned long count = 0; - - while ((p = BTPDQ_FIRST(&btpd.writeq)) != NULL && btpd.obw_left - count > 0) { - BTPDQ_REMOVE(&btpd.writeq, p, wq_entry); - p->flags &= ~PF_ON_WRITEQ; - count += net_write(p, btpd.obw_left - count); - } - btpd.obw_left -= count; - - BTPDQ_REMOVE(&btpd.bwq, bw, entry); - if (count == 0) - free(bw); - else { - bw->count = count; - event_add(&bw->timer, (& (struct timeval) { 1, 0 })); - BTPDQ_INSERT_TAIL(&btpd.bwq, bw, entry); - } -} - void net_write_cb(int sd, short type, void *arg) { @@ -115,15 +51,7 @@ net_write_cb(int sd, short type, void *arg) if (btpd.obwlim == 0) { net_write(p, 0); } else if (btpd.obw_left > 0) { - unsigned long nw = net_write(p, btpd.obw_left); - if (nw > 0) { - struct bwlim *bw = btpd_calloc(1, sizeof(*bw)); - evtimer_set(&bw->timer, net_bw_write_cb, bw); - evtimer_add(&bw->timer, (& (struct timeval) { 1, 0 })); - bw->count = nw; - btpd.obw_left -= nw; - BTPDQ_INSERT_TAIL(&btpd.bwq, bw, entry); - } + btpd.obw_left -= net_write(p, btpd.obw_left); } else { p->flags |= PF_ON_WRITEQ; BTPDQ_INSERT_TAIL(&btpd.writeq, p, wq_entry); @@ -917,3 +845,41 @@ net_by_second(void) } } } + +void +net_bw_cb(int sd, short type, void *arg) +{ + struct peer *p; + + btpd.obw_left = btpd.obwlim / btpd.bw_hz; + btpd.ibw_left = btpd.ibwlim / btpd.bw_hz; + + if (btpd.ibwlim > 0) { + while ((p = BTPDQ_FIRST(&btpd.readq)) != NULL && btpd.ibw_left > 0) { + BTPDQ_REMOVE(&btpd.readq, p, rq_entry); + p->flags &= ~PF_ON_READQ; + btpd.ibw_left -= p->reader->read(p, btpd.ibw_left); + } + } else { + while ((p = BTPDQ_FIRST(&btpd.readq)) != NULL) { + BTPDQ_REMOVE(&btpd.readq, p, rq_entry); + p->flags &= ~PF_ON_READQ; + p->reader->read(p, 0); + } + } + + if (btpd.obwlim) { + while ((p = BTPDQ_FIRST(&btpd.writeq)) != NULL && btpd.obw_left > 0) { + BTPDQ_REMOVE(&btpd.writeq, p, wq_entry); + p->flags &= ~PF_ON_WRITEQ; + btpd.obw_left -= net_write(p, btpd.obw_left); + } + } else { + while ((p = BTPDQ_FIRST(&btpd.writeq)) != NULL) { + BTPDQ_REMOVE(&btpd.writeq, p, wq_entry); + p->flags &= ~PF_ON_WRITEQ; + net_write(p, 0); + } + } + event_add(&btpd.bwlim, (& (struct timeval) { 0, 1000000 / btpd.bw_hz })); +} diff --git a/btpd/net.h b/btpd/net.h index bc27999..1c5ab9e 100644 --- a/btpd/net.h +++ b/btpd/net.h @@ -11,14 +11,6 @@ #define MSG_PIECE 7 #define MSG_CANCEL 8 -struct bwlim { - unsigned long count; - struct event timer; - BTPDQ_ENTRY(bwlim) entry; -}; - -BTPDQ_HEAD(bwlim_tq, bwlim); - struct iob_link { int upload; BTPDQ_ENTRY(iob_link) entry; @@ -82,7 +74,7 @@ struct piece_req { BTPDQ_HEAD(piece_req_tq, piece_req); void net_connection_cb(int sd, short type, void *arg); -void net_by_second(void); +void net_bw_cb(int sd, short type, void *arg); struct peer; diff --git a/btpd/policy_if.c b/btpd/policy_if.c index f31bb1d..7aeadaa 100644 --- a/btpd/policy_if.c +++ b/btpd/policy_if.c @@ -15,6 +15,14 @@ cm_by_second(struct torrent *tp) if (btpd.seconds == tp->choke_time) choke_alg(tp); + + struct peer *p; + int ri = btpd.seconds % RATEHISTORY; + + BTPDQ_FOREACH(p, &tp->peers, cm_entry) { + p->rate_to_me[ri] = 0; + p->rate_from_me[ri] = 0; + } } /*