Index: libtorrent/src/protocol/handshake_manager.cc =================================================================== --- libtorrent/src/protocol/handshake_manager.cc (revision 1060) +++ libtorrent/src/protocol/handshake_manager.cc (working copy) @@ -208,13 +208,13 @@ e_none, &download->info()->hash()); + pcb->peer_chunks()->set_have_timer(handshake->initialized_time()); + if (handshake->unread_size() != 0) { if (handshake->unread_size() > PeerConnectionBase::ProtocolRead::buffer_size) throw internal_error("HandshakeManager::receive_succeeded(...) Unread data won't fit PCB's read buffer."); pcb->push_unread(handshake->unread_data(), handshake->unread_size()); - pcb->peer_chunks()->set_have_timer(handshake->initialized_time()); - pcb->event_read(); } Index: libtorrent/src/protocol/handshake.cc =================================================================== --- libtorrent/src/protocol/handshake.cc (revision 1060) +++ libtorrent/src/protocol/handshake.cc (working copy) @@ -86,8 +86,6 @@ m_uploadThrottle(manager->upload_throttle()->throttle_list()), m_downloadThrottle(manager->download_throttle()->throttle_list()), - m_initializedTime(cachedTime), - m_readDone(false), m_writeDone(false), @@ -524,6 +522,13 @@ if (m_peerInfo->supports_extensions()) write_extension_handshake(); + // Replay HAVE messages we receive after starting to send the bitfield. + // This avoids replaying HAVEs for pieces received between starting the + // handshake and now (e.g. when connecting takes longer). Ideally we + // should make a snapshot of the bitfield here in case it changes while + // we're sending it (if it can't be sent in one write() call). + m_initializedTime = cachedTime; + // The download is just starting so we're not sending any // bitfield. Pretend we wrote it already. if (m_download->file_list()->bitfield()->is_all_unset() || m_download->initial_seeding() != NULL) {