From aa31f523a3ac6f4038d8215809527d005eb34f84 Mon Sep 17 00:00:00 2001 From: Richard Nyberg Date: Fri, 29 Jul 2005 10:07:18 +0000 Subject: Queue the bitfield for sending after the handshake is completed. This fixes a bug where peer could miss pieces btpd got while the peer was in handshake. Also, btpd now sends multiple have messages instead of a bitfield when it's better to do so. --- TODO | 1 - btpd/net.c | 26 +++++++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/TODO b/TODO index a2d91e6..caca5d2 100644 --- a/TODO +++ b/TODO @@ -15,6 +15,5 @@ General code cleanup, esp. the cli Improve build scripts Intelligent logging Better handling of unresponsive trackers -Send multiple have messages instead of bitfield, when it's better Bitfields could be handled as a whole in policy.c. Other temporarily or permanently forgotten things... diff --git a/btpd/net.c b/btpd/net.c index 924668d..3c3fc2f 100644 --- a/btpd/net.c +++ b/btpd/net.c @@ -298,6 +298,23 @@ net_send_have(struct peer *p, uint32_t index) net_send(p, out); } +void +net_send_multihave(struct peer *p) +{ + struct torrent *tp = p->tp; + struct iob_link *out; + out = malloc_liob(9 * tp->have_npieces); + for (uint32_t i = 0, count = 0; count have_npieces; i++) { + if (has_bit(tp->piece_field, i)) { + net_write32(out->iob.buf + count * 9, 5); + out->iob.buf[count * 9 + 4] = MSG_HAVE; + net_write32(out->iob.buf + count * 9 + 5, i); + count++; + } + } + net_send(p, out); +} + void net_send_onesized(struct peer *p, char type) { @@ -357,9 +374,6 @@ net_send_shake(struct peer *p) bcopy(p->tp->meta.info_hash, out->iob.buf + 28, 20); bcopy(btpd.peer_id, out->iob.buf + 48, 20); net_send(p, out); - - if (p->tp->have_npieces > 0) - net_send_bitfield(p); } static void @@ -730,6 +744,12 @@ net_shake_read(struct peer *p, unsigned long rmax) p->piece_field = btpd_calloc(1, (int)ceil(p->tp->meta.npieces / 8.0)); cm_on_new_peer(p); net_generic_reader(p); + if (p->tp->have_npieces > 0) { + if (p->tp->have_npieces * 9 < 5 + ceil(p->tp->meta.npieces / 8.0)) + net_send_multihave(p); + else + net_send_bitfield(p); + } } else event_add(&p->in_ev, NULL); -- cgit 1.4.1