diff --git a/btpd/btpd.c b/btpd/btpd.c index 30c8744..426eab7 100644 --- a/btpd/btpd.c +++ b/btpd/btpd.c @@ -120,6 +120,8 @@ btpd_init(void) BTPDQ_INIT(&btpd.readq); BTPDQ_INIT(&btpd.writeq); + BTPDQ_INIT(&btpd.unattached); + btpd.port = 6881; btpd.obwlim = 0; diff --git a/btpd/btpd.h b/btpd/btpd.h index e5d102d..9356d0a 100644 --- a/btpd/btpd.h +++ b/btpd/btpd.h @@ -50,6 +50,8 @@ struct btpd { struct peer_tq readq; struct peer_tq writeq; + struct peer_tq unattached; + int port; int peer4_sd; int ipc_sd; diff --git a/btpd/peer.c b/btpd/peer.c index 2843b75..9c2dc90 100644 --- a/btpd/peer.c +++ b/btpd/peer.c @@ -25,6 +25,8 @@ peer_kill(struct peer *p) if (p->flags & PF_ATTACHED) cm_on_lost_peer(p); + else + BTPDQ_REMOVE(&btpd.unattached, p, cm_entry); if (p->flags & PF_ON_READQ) BTPDQ_REMOVE(&btpd.readq, p, rq_entry); if (p->flags & PF_ON_WRITEQ) @@ -151,6 +153,7 @@ peer_create_common(int sd) event_set(&p->in_ev, p->sd, EV_READ, net_read_cb, p); event_add(&p->in_ev, NULL); + BTPDQ_INSERT_TAIL(&btpd.unattached, p, cm_entry); btpd.npeers++; return p; } diff --git a/btpd/policy.c b/btpd/policy.c index 8056149..44f0d12 100644 --- a/btpd/policy.c +++ b/btpd/policy.c @@ -318,6 +318,7 @@ cm_on_new_peer(struct peer *peer) tp->npeers++; peer->flags |= PF_ATTACHED; + BTPDQ_REMOVE(&btpd.unattached, peer, cm_entry); if (tp->npeers == 1) { BTPDQ_INSERT_HEAD(&tp->peers, peer, cm_entry); diff --git a/btpd/torrent.c b/btpd/torrent.c index f1fd6f9..5419b59 100644 --- a/btpd/torrent.c +++ b/btpd/torrent.c @@ -156,11 +156,20 @@ torrent_unload(struct torrent *tp) peer = BTPDQ_FIRST(&tp->peers); while (peer != NULL) { struct peer *next = BTPDQ_NEXT(peer, cm_entry); + BTPDQ_REMOVE(&tp->peers, peer, cm_entry); + BTPDQ_INSERT_TAIL(&btpd.unattached, peer, cm_entry); peer->flags &= ~PF_ATTACHED; - peer_kill(peer); peer = next; } + peer = BTPDQ_FIRST(&btpd.unattached); + while (peer != NULL) { + struct peer *next = BTPDQ_NEXT(peer, cm_entry); + if (peer->tp == tp) + peer_kill(peer); + peer = next; + } + piece = BTPDQ_FIRST(&tp->getlst); while (piece != NULL) { struct piece *next = BTPDQ_NEXT(piece, entry);