⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 peer_connection_leech.cc

📁 LibTorrent is a BitTorrent library written in C++ for *nix, with a focus on high performance and goo
💻 CC
📖 第 1 页 / 共 2 页
字号:
// libTorrent - BitTorrent library// Copyright (C) 2005-2006, Jari Sundell//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// // This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.// // You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA//// In addition, as a special exception, the copyright holders give// permission to link the code of portions of this program with the// OpenSSL library under certain conditions as described in each// individual source file, and distribute linked combinations// including the two.//// You must obey the GNU General Public License in all respects for// all of the code used other than OpenSSL.  If you modify file(s)// with this exception, you may extend this exception to your version// of the file(s), but you are not obligated to do so.  If you do not// wish to do so, delete this exception statement from your version.// If you delete this exception statement from all source files in the// program, then also delete it here.//// Contact:  Jari Sundell <jaris@ifi.uio.no>////           Skomakerveien 33//           3185 Skoppum, NORWAY#include "config.h"#include <cstring>#include <sstream>#include "data/content.h"#include "data/chunk_list_node.h"#include "download/chunk_selector.h"#include "download/chunk_statistics.h"#include "download/download_info.h"#include "download/download_main.h"#include "peer_connection_leech.h"namespace torrent {PeerConnectionLeech::~PeerConnectionLeech() {//   if (m_download != NULL && m_down->get_state() != ProtocolRead::READ_BITFIELD)//     m_download->bitfield_counter().dec(m_peerChunks.bitfield()->bitfield());//   priority_queue_erase(&taskScheduler, &m_taskSendChoke);}voidPeerConnectionLeech::initialize_custom() {//   if (m_download->content()->chunks_completed() != 0) {//     m_up->write_bitfield(m_download->content()->bitfield()->size_bytes());//     m_up->buffer()->prepare_end();//     m_up->set_position(0);//     m_up->set_state(ProtocolWrite::WRITE_BITFIELD_HEADER);//   }}voidPeerConnectionLeech::update_interested() {// FIXME:   if (m_download->delegator()->get_select().interested(m_peerChunks.bitfield()->bitfield())) {  // Consider just setting to interested without checking the  // bitfield. The status might change by the time we get unchoked  // anyway.  if (true) {    m_sendInterested = !m_up->interested();    m_up->set_interested(true);  } else {    m_sendInterested = m_up->interested();    m_up->set_interested(false);  }  m_peerChunks.download_cache()->clear();}// Disconnecting connections where both are seeders should be done by// DownloadMain when it finishes the last chunk.voidPeerConnectionLeech::receive_finished_chunk(int32_t index) {  m_peerChunks.have_queue()->push_back(index);  if (download_queue()->has_index(index))    throw internal_error("PeerConnection::sendHave(...) found a request with the same index");}boolPeerConnectionLeech::receive_keepalive() {  if (cachedTime - m_timeLastRead > rak::timer::from_seconds(240))    return false;  // There's no point in adding ourselves to the write poll if the  // buffer is full, as that will already have been taken care of.  if (m_up->get_state() == ProtocolWrite::IDLE &&      m_up->can_write_keepalive()) {    write_insert_poll_safe();    m_up->write_keepalive();  }  m_tryRequest = true;  // Stall pieces when more than one receive_keepalive() has been  // called while a single piece is downloading.  //  // m_downStall is decremented for every successfull download, so it  // should stay at zero or one when downloading at an acceptable  // speed. Thus only when m_downStall >= 2 is the download actually  // stalling.  if (!download_queue()->empty() && m_downStall++ != 0)    download_queue()->stall();  return true;}// We keep the message in the buffer if it is incomplete instead of// keeping the state and remembering the read information. This// shouldn't happen very often compared to full reads.inline boolPeerConnectionLeech::read_message() {  ProtocolBuffer<512>* buf = m_down->buffer();  if (buf->remaining() < 4)    return false;  // Remember the start of the message so we may reset it if we don't  // have the whole message.  ProtocolBuffer<512>::iterator beginning = buf->position();  uint32_t length = buf->read_32();  if (length == 0) {    // Keepalive message.    m_down->set_last_command(ProtocolBase::KEEP_ALIVE);    return true;  } else if (buf->remaining() < 1) {    buf->set_position_itr(beginning);    return false;  } else if (length > (1 << 20)) {    throw network_error("PeerConnectionLeech::read_message() got an invalid message length.");  }      // We do not verify the message length of those with static  // length. A bug in the remote client causing the message start to  // be unsyncronized would in practically all cases be caught with  // the above test.  //  // Those that do in some weird way manage to produce a valid  // command, will not be able to do any damage as malicious  // peer. Those cases should be caught elsewhere in the code.  // Temporary.  m_down->set_last_command((ProtocolBase::Protocol)buf->peek_8());  switch (buf->read_8()) {  case ProtocolBase::CHOKE:    m_down->set_choked(true);    m_peerChunks.download_cache()->disable();    download_queue()->cancel();    m_download->download_throttle()->erase(m_peerChunks.download_throttle());    return true;  case ProtocolBase::UNCHOKE:    if (is_down_choked()) {      write_insert_poll_safe();      m_down->set_choked(false);      m_tryRequest = true;    }    return true;  case ProtocolBase::INTERESTED:    set_remote_interested();    return true;  case ProtocolBase::NOT_INTERESTED:    set_remote_not_interested();    return true;  case ProtocolBase::HAVE:    if (!m_down->can_read_have_body())      break;    read_have_chunk(buf->read_32());    return true;  case ProtocolBase::REQUEST:    if (!m_down->can_read_request_body())      break;    if (!m_up->choked()) {      write_insert_poll_safe();      read_request_piece(m_down->read_request());    } else {      m_down->read_request();    }    return true;  case ProtocolBase::PIECE:    if (!m_down->can_read_piece_body())      break;    if (!down_chunk_start(m_down->read_piece(length - 9))) {      // We don't want this chunk.      if (down_chunk_skip_from_buffer()) {        m_tryRequest = true;        down_chunk_finished();        return true;      } else {        m_down->set_state(ProtocolRead::READ_SKIP_PIECE);        return false;      }          } else {      if (down_chunk_from_buffer()) {        m_tryRequest = true;        down_chunk_finished();        return true;      } else {        m_down->set_state(ProtocolRead::READ_PIECE);        m_download->download_throttle()->insert(m_peerChunks.download_throttle());        return false;      }    }  case ProtocolBase::CANCEL:    if (!m_down->can_read_cancel_body())      break;    read_cancel_piece(m_down->read_request());    return true;  default:    throw network_error("Received unsupported message type.");  }  // We were unsuccessfull in reading the message, need more data.  buf->set_position_itr(beginning);  return false;}voidPeerConnectionLeech::event_read() {  m_timeLastRead = cachedTime;  // Need to make sure ProtocolBuffer::end() is pointing to the end of  // the unread data, and that the unread data starts from the

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -