about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRichard Nyberg <rnyberg@murmeldjur.se>2005-07-23 21:29:46 +0000
committerRichard Nyberg <rnyberg@murmeldjur.se>2005-07-23 21:29:46 +0000
commitf671c4f9650029e5fb068f7bec804f68eab96408 (patch)
treeb03f3d140dcf987c821fd25fddc226a9551d87fb
parentf65633c5310e69027baa343bedf5ff7b6d02e881 (diff)
downloadbtpd-f671c4f9650029e5fb068f7bec804f68eab96408.tar.gz
btpd-f671c4f9650029e5fb068f7bec804f68eab96408.zip
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.

-rw-r--r--btpd/btpd.c33
-rw-r--r--btpd/btpd.h5
-rw-r--r--btpd/net.c114
-rw-r--r--btpd/net.h10
-rw-r--r--btpd/policy_if.c8
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
@@ -26,49 +26,13 @@ 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)
 {
     struct peer *p = (struct peer *)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);
@@ -76,34 +40,6 @@ net_read_cb(int sd, short type, void *arg)
 }
 
 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)
 {
     struct peer *p = (struct peer *)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;
+    }
 }
 
 /*