about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRichard Nyberg <rnyberg@murmeldjur.se>2006-08-06 09:18:01 +0000
committerRichard Nyberg <rnyberg@murmeldjur.se>2006-08-06 09:18:01 +0000
commit1f4ef6cb15485a56c4a37ce6ac93fd40a8de684d (patch)
tree4a2b40de6c346185d694d92d569df1e7a120667c
parente0877d2870b7ff9186828fbb84d7f6a28df3a2bb (diff)
downloadbtpd-1f4ef6cb15485a56c4a37ce6ac93fd40a8de684d.tar.gz
btpd-1f4ef6cb15485a56c4a37ce6ac93fd40a8de684d.zip
Reduce the number of HAVE messages sent by only sending them to peers missing
the piece. Remove seeder peers when our download is finished and remove peers
who doesn't show any interest for a long time when we're seeding.

-rw-r--r--btpd/download.c12
-rw-r--r--btpd/net_types.h1
-rw-r--r--btpd/peer.c25
3 files changed, 29 insertions, 9 deletions
diff --git a/btpd/download.c b/btpd/download.c
index 2bb62fc..9ef54be 100644
--- a/btpd/download.c
+++ b/btpd/download.c
@@ -79,14 +79,17 @@ dl_on_choke(struct peer *p)
 void
 dl_on_ok_piece(struct net *n, uint32_t piece)
 {
-    struct peer *p;
+    struct peer *p, *next;
     struct piece *pc = dl_find_piece(n, piece);
 
     btpd_log(BTPD_L_POL, "Got piece: %u.\n", pc->index);
 
     struct net_buf *have = nb_create_have(pc->index);
+    nb_hold(have);
     BTPDQ_FOREACH(p, &n->peers, p_entry)
-        peer_send(p, have);
+        if (!peer_has(p, pc->index))
+            peer_send(p, have);
+    nb_drop(have);
 
     if (n->endgame)
         BTPDQ_FOREACH(p, &n->peers, p_entry)
@@ -100,8 +103,11 @@ dl_on_ok_piece(struct net *n, uint32_t piece)
         btpd_log(BTPD_L_BTPD, "Finished downloading '%s'.\n",
             torrent_name(n->tp));
         tr_complete(n->tp);
-        BTPDQ_FOREACH(p, &n->peers, p_entry)
+        BTPDQ_FOREACH_MUTABLE(p, &n->peers, p_entry, next) {
             assert(p->nwant == 0);
+            if (peer_full(p))
+                peer_kill(p);
+        }
     }
 }
 
diff --git a/btpd/net_types.h b/btpd/net_types.h
index b444eea..9ade854 100644
--- a/btpd/net_types.h
+++ b/btpd/net_types.h
@@ -63,6 +63,7 @@ struct peer {
 
     long t_created;
     long t_wantwrite;
+    long t_nointerest;
 
     struct {
         uint32_t msg_len;
diff --git a/btpd/peer.c b/btpd/peer.c
index 7ce486d..c8f60dc 100644
--- a/btpd/peer.c
+++ b/btpd/peer.c
@@ -250,6 +250,7 @@ peer_unwant(struct peer *p, uint32_t index)
     p->nwant--;
     if (p->nwant == 0) {
         p->flags &= ~PF_I_WANT;
+        p->t_nointerest = btpd_seconds;
         if (p->nreqs_out == 0)
             peer_send(p, nb_create_uninterest());
         else
@@ -265,6 +266,7 @@ peer_create_common(int sd)
     p->sd = sd;
     p->flags = PF_I_CHOKE | PF_P_CHOKE;
     p->t_created = btpd_seconds;
+    p->t_nointerest = btpd_seconds;
     BTPDQ_INIT(&p->my_reqs);
     BTPDQ_INIT(&p->outq);
 
@@ -416,6 +418,7 @@ peer_on_uninterest(struct peer *p)
         return;
     else {
         p->flags &= ~PF_P_WANT;
+        p->t_nointerest = btpd_seconds;
         ul_on_uninterest(p);
     }
 }
@@ -512,13 +515,23 @@ peer_on_cancel(struct peer *p, uint32_t index, uint32_t begin,
 void
 peer_on_tick(struct peer *p)
 {
-    if ((p->flags & PF_ATTACHED) == 0 && btpd_seconds - p->t_created >= 60) {
-        btpd_log(BTPD_L_CONN, "hand shake timed out.\n");
-        peer_kill(p);
-    } else if (!BTPDQ_EMPTY(&p->outq) && btpd_seconds - p->t_wantwrite >= 60) {
-        btpd_log(BTPD_L_CONN, "write attempt timed out.\n");
-        peer_kill(p);
+    if (p->flags & PF_ATTACHED) {
+        if (!BTPDQ_EMPTY(&p->outq) && btpd_seconds - p->t_wantwrite >= 60) {
+            btpd_log(BTPD_L_CONN, "write attempt timed out.\n");
+            goto kill;
+        }
+        if ((cm_full(p->n->tp) && !(p->flags & PF_P_WANT) &&
+                btpd_seconds - p->t_nointerest >= 600)) {
+            btpd_log(BTPD_L_CONN, "no interest for 10 minutes.\n");
+            goto kill;
+        }
+    } else if (btpd_seconds - p->t_created >= 60) {
+            btpd_log(BTPD_L_CONN, "hand shake timed out.\n");
+            goto kill;
     }
+    return;
+kill:
+    peer_kill(p);
 }
 
 int