about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--btpd/main.c4
-rw-r--r--btpd/net.c59
-rw-r--r--btpd/opts.c1
-rw-r--r--btpd/opts.h1
-rw-r--r--btpd/peer.c22
-rw-r--r--btpd/peer.h9
-rw-r--r--btpd/policy_choke.c10
-rw-r--r--btpd/policy_if.c8
8 files changed, 64 insertions, 50 deletions
diff --git a/btpd/main.c b/btpd/main.c
index d9f57a2..4e914b4 100644
--- a/btpd/main.c
+++ b/btpd/main.c
@@ -118,7 +118,6 @@ 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 },
     { "help",	no_argument,		&longval,	5 },
@@ -150,9 +149,6 @@ main(int argc, char **argv)
 	    case 2:
 		net_bw_limit_out = atoi(optarg) * 1024;
 		break;
-	    case 6:
-		net_bw_hz = atoi(optarg);
-		break;
 	    default:
 		usage();
 	    }
diff --git a/btpd/net.c b/btpd/net.c
index 2eb57cf..a8cca89 100644
--- a/btpd/net.c
+++ b/btpd/net.c
@@ -101,7 +101,7 @@ net_write(struct peer *p, unsigned long wmax)
 	    peer_sent(p, nl->nb);
 	    if (nl->nb->type == NB_TORRENTDATA) {
 		p->tp->uploaded += bufdelta;
-		p->rate_from_me[btpd_seconds % RATEHISTORY] += bufdelta;
+		p->count_up += bufdelta;
 	    }
 	    bcount -= bufdelta;
 	    BTPDQ_REMOVE(&p->outq, nl, entry);
@@ -112,7 +112,7 @@ net_write(struct peer *p, unsigned long wmax)
 	} else {
 	    if (nl->nb->type == NB_TORRENTDATA) {
 		p->tp->uploaded += bcount;
-		p->rate_from_me[btpd_seconds % RATEHISTORY] += bcount;
+		p->count_up += bcount;
 	    }
 	    p->outq_off +=  bcount;
 	    bcount = 0;
@@ -221,7 +221,7 @@ net_progress(struct peer *p, size_t length)
 {
     if (p->net.state == BTP_MSGBODY && p->net.msg_num == MSG_PIECE) {
 	p->tp->downloaded += length;
-	p->rate_to_me[btpd_seconds % RATEHISTORY] += length;
+	p->count_dwn += length;
     }
 }
 
@@ -435,14 +435,37 @@ net_connection_cb(int sd, short type, void *arg)
     btpd_log(BTPD_L_CONN, "got connection.\n");
 }
 
-void
-add_bw_timer(void)
+#define RATEHISTORY 20
+
+long
+compute_rate_sub(long rate)
 {
-    long wait = 1000000 / net_bw_hz;
-    struct timeval now;
-    gettimeofday(&now, NULL);
-    wait = wait - now.tv_usec % wait;
-    evtimer_add(&m_bw_timer, (& (struct timeval) { 0, wait}));
+    if (rate > 256 * RATEHISTORY)
+	return rate / RATEHISTORY;
+    else
+	return 256;
+}
+
+static void
+compute_peer_rates(void) {
+    struct torrent *tp;
+    BTPDQ_FOREACH(tp, btpd_get_torrents(), entry) {
+	struct peer *p;
+	BTPDQ_FOREACH(p, &tp->peers, p_entry) {
+	    if (p->count_up > 0 || peer_active_up(p)) {
+		p->rate_up += p->count_up - compute_rate_sub(p->rate_up);
+		if (p->rate_up < 0)
+		    p->rate_up = 0;
+		p->count_up = 0;
+	    }
+	    if (p->count_dwn > 0 || peer_active_down(p)) {
+		p->rate_dwn += p->count_dwn - compute_rate_sub(p->rate_dwn);
+		if (p->rate_dwn < 0)
+		    p->rate_dwn = 0;
+		p->count_dwn = 0;
+	    }
+	}
+    }
 }
 
 void
@@ -450,8 +473,12 @@ net_bw_cb(int sd, short type, void *arg)
 {
     struct peer *p;
 
-    m_bw_bytes_out = net_bw_limit_out / net_bw_hz;
-    m_bw_bytes_in = net_bw_limit_in / net_bw_hz;
+    evtimer_add(&m_bw_timer, (& (struct timeval) { 1, 0 }));
+
+    compute_peer_rates();
+
+    m_bw_bytes_out = net_bw_limit_out;
+    m_bw_bytes_in = net_bw_limit_in;
 
     if (net_bw_limit_in > 0) {
 	while ((p = BTPDQ_FIRST(&net_bw_readq)) != NULL && m_bw_bytes_in > 0) {
@@ -480,7 +507,6 @@ net_bw_cb(int sd, short type, void *arg)
 	    net_write(p, 0);
 	}
     }
-    add_bw_timer();
 }
 
 void
@@ -519,8 +545,8 @@ net_write_cb(int sd, short type, void *arg)
 void
 net_init(void)
 {
-    m_bw_bytes_out = net_bw_limit_out / net_bw_hz;
-    m_bw_bytes_in = net_bw_limit_in / net_bw_hz;
+    m_bw_bytes_out = net_bw_limit_out;
+    m_bw_bytes_in = net_bw_limit_in;
 
     int nfiles = getdtablesize();
     if (nfiles <= 20)
@@ -553,6 +579,5 @@ net_init(void)
     event_add(&m_net_incoming, NULL);
 
     evtimer_set(&m_bw_timer, net_bw_cb, NULL);
-    if (net_bw_limit_out > 0 || net_bw_limit_in > 0)
-	add_bw_timer();
+    evtimer_add(&m_bw_timer, (& (struct timeval) { 1, 0 }));
 }
diff --git a/btpd/opts.c b/btpd/opts.c
index e72daf9..780228f 100644
--- a/btpd/opts.c
+++ b/btpd/opts.c
@@ -10,5 +10,4 @@ uint32_t btpd_logmask =  BTPD_L_BTPD | BTPD_L_ERROR;
 unsigned net_max_peers;
 unsigned net_bw_limit_in;
 unsigned net_bw_limit_out;
-short net_bw_hz = 8;
 int net_port = 6881;
diff --git a/btpd/opts.h b/btpd/opts.h
index c24b13b..d2d6460 100644
--- a/btpd/opts.h
+++ b/btpd/opts.h
@@ -4,5 +4,4 @@ extern uint32_t btpd_logmask;
 extern unsigned net_max_peers;
 extern unsigned net_bw_limit_in;
 extern unsigned net_bw_limit_out;
-extern short net_bw_hz;
 extern int net_port;
diff --git a/btpd/peer.c b/btpd/peer.c
index ff16f92..74bf7e8 100644
--- a/btpd/peer.c
+++ b/btpd/peer.c
@@ -9,15 +9,6 @@
 
 #include "btpd.h"
 
-unsigned long
-peer_get_rate(unsigned long *rates)
-{
-    unsigned long ret = 0;
-    for (int i = 0; i < RATEHISTORY; i++)
-	ret += rates[i];
-    return ret;
-}
-
 void
 peer_kill(struct peer *p)
 {
@@ -525,3 +516,16 @@ peer_leech_ok(struct peer *p)
 {
     return (p->flags & (PF_I_WANT|PF_P_CHOKE)) == PF_I_WANT;
 }
+
+int
+peer_active_down(struct peer *p)
+{
+    return peer_leech_ok(p) || p->nreqs_out > 0;
+}
+
+int
+peer_active_up(struct peer *p)
+{
+    return (p->flags & (PF_P_WANT|PF_I_CHOKE)) == PF_P_WANT
+	|| p->npiece_msgs > 0;
+}
diff --git a/btpd/peer.h b/btpd/peer.h
index 36d7fe8..a25c73b 100644
--- a/btpd/peer.h
+++ b/btpd/peer.h
@@ -12,7 +12,6 @@
 #define PF_INCOMING	0x100
 #define PF_DO_UNWANT	0x200
 
-#define RATEHISTORY 20
 #define MAXPIECEMSGS 128
 #define MAXPIPEDREQUESTS 10
 
@@ -47,8 +46,8 @@ struct peer {
     struct event in_ev;
     struct event out_ev;
 
-    unsigned long rate_to_me[RATEHISTORY];
-    unsigned long rate_from_me[RATEHISTORY];
+    long rate_up, rate_dwn;
+    long count_up, count_dwn;
 
     struct {
         uint32_t msg_len;
@@ -83,8 +82,6 @@ void peer_cancel(struct peer *p, struct block_request *req,
 
 int peer_requested(struct peer *p, struct block *blk);
 
-unsigned long peer_get_rate(unsigned long *rates);
-
 void peer_create_in(int sd);
 void peer_create_out(struct torrent *tp, const uint8_t *id,
     const char *ip, int port);
@@ -107,6 +104,8 @@ void peer_on_request(struct peer *p, uint32_t index, uint32_t begin,
 void peer_on_cancel(struct peer *p, uint32_t index, uint32_t begin,
     uint32_t length);
 
+int peer_active_down(struct peer *p);
+int peer_active_up(struct peer *p);
 int peer_chokes(struct peer *p);
 int peer_wanted(struct peer *p);
 int peer_laden(struct peer *p);
diff --git a/btpd/policy_choke.c b/btpd/policy_choke.c
index 310b8aa..6da3ae3 100644
--- a/btpd/policy_choke.c
+++ b/btpd/policy_choke.c
@@ -1,7 +1,7 @@
 #include "btpd.h"
 
 static int
-rate_cmp(unsigned long rate1, unsigned long rate2)
+rate_cmp(long rate1, long rate2)
 {
     if (rate1 < rate2)
 	return -1;
@@ -14,16 +14,16 @@ rate_cmp(unsigned long rate1, unsigned long rate2)
 static int
 dwnrate_cmp(const void *p1, const void *p2)
 {
-    unsigned long rate1 = peer_get_rate((*(struct peer **)p1)->rate_to_me);
-    unsigned long rate2 = peer_get_rate((*(struct peer **)p2)->rate_to_me);
+    long rate1 = (*(struct peer **)p1)->rate_dwn;
+    long rate2 = (*(struct peer **)p2)->rate_dwn;
     return rate_cmp(rate1, rate2);
 }
 
 static int
 uprate_cmp(const void *p1, const void *p2)
 {
-    unsigned long rate1 = peer_get_rate((*(struct peer **)p1)->rate_from_me);
-    unsigned long rate2 = peer_get_rate((*(struct peer **)p2)->rate_from_me);
+    long rate1 = (*(struct peer **)p1)->rate_up;
+    long rate2 = (*(struct peer **)p2)->rate_up;
     return rate_cmp(rate1, rate2);
 }
 
diff --git a/btpd/policy_if.c b/btpd/policy_if.c
index a550b2e..164e2a3 100644
--- a/btpd/policy_if.c
+++ b/btpd/policy_if.c
@@ -15,14 +15,6 @@ dl_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, p_entry) {
-	p->rate_to_me[ri] = 0;
-	p->rate_from_me[ri] = 0;
-    }
 }
 
 /*