From 3f6d7576a566e0ad54db88f9066db4dc6f17f1d5 Mon Sep 17 00:00:00 2001
From: Richard Nyberg <rnyberg@murmeldjur.se>
Date: Mon, 14 Nov 2005 20:54:55 +0000
Subject: [PATCH] Use a flag (PF_DO_UNWANT) to indicate that we should send an
 uninterest message when we no longer have any pending requests. This fixes a
 bug where two uniterest messages were sent to a peer that was no longer
 wanted in endgame.

---
 btpd/peer.c | 11 ++++++++++-
 btpd/peer.h |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/btpd/peer.c b/btpd/peer.c
index 85a1666..c81d439 100644
--- a/btpd/peer.c
+++ b/btpd/peer.c
@@ -223,12 +223,16 @@ peer_want(struct peer *p, uint32_t index)
     p->nwant++;
     if (p->nwant == 1) {
 	if (p->nreqs_out == 0) {
+	    assert((p->flags & PF_DO_UNWANT) == 0);
 	    int unsent = 0;
 	    struct nb_link *nl = BTPDQ_LAST(&p->outq, nb_tq);
 	    if (nl != NULL && nl->nb->type == NB_UNINTEREST)
 		unsent = peer_unsend(p, nl);
 	    if (!unsent)
 		peer_send(p, nb_create_interest());
+	} else {
+	    assert((p->flags & PF_DO_UNWANT) != 0);
+	    p->flags &= ~PF_DO_UNWANT;
 	}
 	p->flags |= PF_I_WANT;
     }
@@ -243,6 +247,8 @@ peer_unwant(struct peer *p, uint32_t index)
 	p->flags &= ~PF_I_WANT;
 	if (p->nreqs_out == 0)
 	    peer_send(p, nb_create_uninterest());
+	else
+	    p->flags |= PF_DO_UNWANT;
     }
 }
 
@@ -311,8 +317,11 @@ peer_create_out_compact(struct torrent *tp, const char *compact)
 void
 peer_on_no_reqs(struct peer *p)
 {
-    if (p->nwant == 0)
+    if ((p->flags & PF_DO_UNWANT) != 0) {
+	assert(p->nwant == 0);
+	p->flags &= ~PF_DO_UNWANT;
 	peer_send(p, nb_create_uninterest());
+    }
 }
 
 void
diff --git a/btpd/peer.h b/btpd/peer.h
index 0070182..e288401 100644
--- a/btpd/peer.h
+++ b/btpd/peer.h
@@ -10,6 +10,7 @@
 #define PF_ATTACHED	 0x40
 #define PF_NO_REQUESTS	 0x80
 #define PF_INCOMING	0x100
+#define PF_DO_UNWANT	0x200
 
 #define RATEHISTORY 20
 #define MAXPIECEMSGS 128