Show
Ignore:
Timestamp:
05/05/08 15:16:26 (4 years ago)
Author:
rakshasa
Message:

* Initial seeding support added. Patch by Josef Drexler.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/libtorrent/src/protocol/peer_connection_leech.cc

    r1043 r1058  
    5151 
    5252#include "extensions.h" 
     53#include "initial_seed.h" 
    5354#include "peer_connection_leech.h" 
    5455 
     
    6667void 
    6768PeerConnection<type>::initialize_custom() { 
     69  if (type == Download::CONNECTION_INITIAL_SEED) { 
     70    if (m_download->initial_seeding() == NULL) { 
     71      // Can't throw close_connection or network_error here, we're still 
     72      // initializing. So close the socket and let that kill it later. 
     73      get_fd().close(); 
     74      return; 
     75    } 
     76 
     77    m_download->initial_seeding()->new_peer(this); 
     78  } 
    6879//   if (m_download->content()->chunks_completed() != 0) { 
    6980//     m_up->write_bitfield(m_download->file_list()->bitfield()->size_bytes()); 
     
    7889void 
    7990PeerConnection<type>::update_interested() { 
    80   if (type == Download::CONNECTION_SEED) 
     91  if (type != Download::CONNECTION_LEECH) 
    8192    return; 
    8293 
     
    118129  } 
    119130 
    120   if (type == Download::CONNECTION_SEED) 
     131  if (type != Download::CONNECTION_LEECH) 
    121132    return true; 
    122133 
     
    193204  switch (buf->read_8()) { 
    194205  case ProtocolBase::CHOKE: 
    195     if (type == Download::CONNECTION_SEED) 
     206    if (type != Download::CONNECTION_LEECH) 
    196207      return true; 
    197208 
     
    213224 
    214225  case ProtocolBase::UNCHOKE: 
    215     if (type == Download::CONNECTION_SEED) 
     226    if (type != Download::CONNECTION_LEECH) 
    216227      return true; 
    217228 
     
    259270 
    260271  case ProtocolBase::PIECE: 
    261     if (type == Download::CONNECTION_SEED) 
     272    if (type != Download::CONNECTION_LEECH) 
    262273      throw communication_error("Received a piece but the connection is strictly for seeding."); 
    263274 
     
    382393 
    383394      case ProtocolRead::READ_PIECE: 
    384         if (type == Download::CONNECTION_SEED) 
     395        if (type != Download::CONNECTION_LEECH) 
    385396          return; 
    386397 
     
    402413 
    403414      case ProtocolRead::READ_SKIP_PIECE: 
    404         if (type == Download::CONNECTION_SEED) 
     415        if (type != Download::CONNECTION_LEECH) 
    405416          return; 
    406417 
     
    490501  // request has been received while uninterested. The problem arises 
    491502  // as they send unchoke before receiving interested. 
    492   if (type != Download::CONNECTION_SEED && m_sendInterested && m_up->can_write_interested()) { 
     503  if (type == Download::CONNECTION_LEECH && m_sendInterested && m_up->can_write_interested()) { 
    493504    m_up->write_interested(m_downInterested); 
    494505    m_sendInterested = false; 
    495506  } 
    496507 
    497   if (type != Download::CONNECTION_SEED && m_tryRequest) { 
     508  if (type == Download::CONNECTION_LEECH && m_tryRequest) { 
    498509    if (!(m_tryRequest = !should_request()) && 
    499510        !(m_tryRequest = try_request_pieces()) && 
     
    509520  DownloadMain::have_queue_type* haveQueue = m_download->have_queue(); 
    510521 
    511   if (type != Download::CONNECTION_SEED &&  
     522  if (type == Download::CONNECTION_LEECH &&  
    512523      !haveQueue->empty() && 
    513524      m_peerChunks.have_timer() <= haveQueue->front().first && 
     
    523534  } 
    524535 
    525   while (type != Download::CONNECTION_SEED && !m_peerChunks.cancel_queue()->empty() && m_up->can_write_cancel()) { 
     536  if (type == Download::CONNECTION_INITIAL_SEED && m_up->can_write_have()) 
     537    offer_chunk(); 
     538 
     539  while (type == Download::CONNECTION_LEECH && !m_peerChunks.cancel_queue()->empty() && m_up->can_write_cancel()) { 
    526540    m_up->write_cancel(m_peerChunks.cancel_queue()->front()); 
    527541    m_peerChunks.cancel_queue()->pop_front(); 
     
    534548  } else if (!m_upChoke.choked() && 
    535549             !m_peerChunks.upload_queue()->empty() && 
    536              m_up->can_write_piece()) { 
     550             m_up->can_write_piece() && 
     551             (type != Download::CONNECTION_INITIAL_SEED || should_upload())) { 
    537552    write_prepare_piece(); 
    538553  } 
     
    639654  m_download->chunk_statistics()->received_have_chunk(&m_peerChunks, index, m_download->file_list()->chunk_size()); 
    640655 
     656  if (type == Download::CONNECTION_INITIAL_SEED) 
     657    m_download->initial_seeding()->chunk_seen(index, this); 
     658 
     659  // Disconnect seeds when we are seeding (but not for initial seeding 
     660  // so that we keep accurate chunk statistics until that is done). 
    641661  if (m_peerChunks.bitfield()->is_all_set()) { 
    642     if (type == Download::CONNECTION_SEED || m_download->file_list()->is_done()) 
     662    if (type == Download::CONNECTION_SEED ||  
     663        (type != Download::CONNECTION_INITIAL_SEED && m_download->file_list()->is_done())) 
    643664      throw close_connection(); 
    644665 
     
    646667  } 
    647668 
    648   if (type == Download::CONNECTION_SEED || m_download->file_list()->is_done()) 
     669  if (type != Download::CONNECTION_LEECH || m_download->file_list()->is_done()) 
    649670    return; 
    650671 
     
    677698} 
    678699 
    679 // Explicit instatiation of the member functions and vtable. 
     700template<> 
     701void 
     702PeerConnection<Download::CONNECTION_INITIAL_SEED>::offer_chunk() { 
     703  // If bytes left to send in this chunk minus bytes about to be sent is zero, 
     704  // assume the peer will have got the chunk completely. In that case we may 
     705  // get another one to offer if not enough other peers are interested even 
     706  // if the peer would otherwise still be blocked. 
     707  uint32_t bytesLeft = m_data.bytesLeft; 
     708  if (!m_peerChunks.upload_queue()->empty() && m_peerChunks.upload_queue()->front().index() == m_data.lastIndex) 
     709    bytesLeft -= m_peerChunks.upload_queue()->front().length(); 
     710 
     711  uint32_t index = m_download->initial_seeding()->chunk_offer(this, bytesLeft == 0 ? m_data.lastIndex : InitialSeeding::no_offer); 
     712 
     713  if (index == InitialSeeding::no_offer || index == m_data.lastIndex) 
     714    return; 
     715 
     716  m_up->write_have(index); 
     717  m_data.lastIndex = index; 
     718  m_data.bytesLeft = m_download->file_list()->chunk_index_size(index); 
     719} 
     720 
     721template<> 
     722bool 
     723PeerConnection<Download::CONNECTION_INITIAL_SEED>::should_upload() { 
     724  // For initial seeding, check if chunk is well seeded now, and if so 
     725  // remove it from the queue to better use our bandwidth on rare chunks. 
     726  while (!m_peerChunks.upload_queue()->empty() && 
     727         !m_download->initial_seeding()->should_upload(m_peerChunks.upload_queue()->front().index())) 
     728    m_peerChunks.upload_queue()->pop_front(); 
     729 
     730  // If queue ends up empty, choke peer to let it know that it 
     731  // shouldn't wait for the cancelled pieces to be sent. 
     732  if (m_peerChunks.upload_queue()->empty()) { 
     733    m_download->upload_choke_manager()->set_not_queued(this, &m_upChoke); 
     734    m_download->upload_choke_manager()->set_queued(this, &m_upChoke); 
     735 
     736  // If we're sending the chunk we last offered, adjust bytes left in it. 
     737  } else if (m_peerChunks.upload_queue()->front().index() == m_data.lastIndex) { 
     738    m_data.bytesLeft -= m_peerChunks.upload_queue()->front().length(); 
     739 
     740    if (!m_data.bytesLeft) 
     741      m_data.lastIndex = InitialSeeding::no_offer; 
     742  } 
     743 
     744  return !m_peerChunks.upload_queue()->empty(); 
     745} 
     746 
     747// Explicit instantiation of the member functions and vtable. 
    680748template class PeerConnection<Download::CONNECTION_LEECH>; 
    681749template class PeerConnection<Download::CONNECTION_SEED>; 
    682  
    683 } 
     750template class PeerConnection<Download::CONNECTION_INITIAL_SEED>; 
     751 
     752}