1
// libTorrent - BitTorrent library
2
// Copyright (C) 2005-2007, Jari Sundell
4
// This program is free software; you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation; either version 2 of the License, or
7
// (at your option) any later version.
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
14
// You should have received a copy of the GNU General Public License
15
// along with this program; if not, write to the Free Software
16
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
// In addition, as a special exception, the copyright holders give
19
// permission to link the code of portions of this program with the
20
// OpenSSL library under certain conditions as described in each
21
// individual source file, and distribute linked combinations
24
// You must obey the GNU General Public License in all respects for
25
// all of the code used other than OpenSSL. If you modify file(s)
26
// with this exception, you may extend this exception to your version
27
// of the file(s), but you are not obligated to do so. If you do not
28
// wish to do so, delete this exception statement from your version.
29
// If you delete this exception statement from all source files in the
30
// program, then also delete it here.
32
// Contact: Jari Sundell <jaris@ifi.uio.no>
35
// 3185 Skoppum, NORWAY
42
#include "data/chunk_list_node.h"
43
#include "download/choke_manager.h"
44
#include "download/chunk_selector.h"
45
#include "download/chunk_statistics.h"
46
#include "download/download_main.h"
47
#include "torrent/dht_manager.h"
48
#include "torrent/download_info.h"
49
#include "torrent/peer/connection_list.h"
50
#include "torrent/peer/peer_info.h"
52
#include "extensions.h"
53
#include "peer_connection_metadata.h"
57
PeerConnectionMetadata::~PeerConnectionMetadata() {
61
PeerConnectionMetadata::initialize_custom() {
65
PeerConnectionMetadata::update_interested() {
69
PeerConnectionMetadata::receive_keepalive() {
70
if (cachedTime - m_timeLastRead > rak::timer::from_seconds(240))
75
// There's no point in adding ourselves to the write poll if the
76
// buffer is full, as that will already have been taken care of.
77
if (m_up->get_state() == ProtocolWrite::IDLE &&
78
m_up->can_write_keepalive()) {
80
write_insert_poll_safe();
82
ProtocolBuffer<512>::iterator old_end = m_up->buffer()->end();
83
m_up->write_keepalive();
86
m_encryption.encrypt(old_end, m_up->buffer()->end() - old_end);
92
// We keep the message in the buffer if it is incomplete instead of
93
// keeping the state and remembering the read information. This
94
// shouldn't happen very often compared to full reads.
96
PeerConnectionMetadata::read_message() {
97
ProtocolBuffer<512>* buf = m_down->buffer();
99
if (buf->remaining() < 4)
102
// Remember the start of the message so we may reset it if we don't
103
// have the whole message.
104
ProtocolBuffer<512>::iterator beginning = buf->position();
106
uint32_t length = buf->read_32();
109
// Keepalive message.
110
m_down->set_last_command(ProtocolBase::KEEP_ALIVE);
114
} else if (buf->remaining() < 1) {
115
buf->set_position_itr(beginning);
118
} else if (length > (1 << 20)) {
119
throw communication_error("PeerConnection::read_message() got an invalid message length.");
122
m_down->set_last_command((ProtocolBase::Protocol)buf->peek_8());
124
// Ignore most messages, they aren't relevant for a metadata download.
125
switch (buf->read_8()) {
126
case ProtocolBase::CHOKE:
127
case ProtocolBase::UNCHOKE:
128
case ProtocolBase::INTERESTED:
129
case ProtocolBase::NOT_INTERESTED:
132
case ProtocolBase::HAVE:
133
if (!m_down->can_read_have_body())
139
case ProtocolBase::REQUEST:
140
if (!m_down->can_read_request_body())
143
m_down->read_request();
146
case ProtocolBase::PIECE:
147
throw communication_error("Received a piece but the connection is strictly for meta data.");
149
case ProtocolBase::CANCEL:
150
if (!m_down->can_read_cancel_body())
153
m_down->read_request();
156
case ProtocolBase::PORT:
157
if (!m_down->can_read_port_body())
160
manager->dht_manager()->add_node(m_peerInfo->socket_address(), m_down->buffer()->read_16());
163
case ProtocolBase::EXTENSION_PROTOCOL:
164
m_download->info()->signal_network_log().emit("PeerConnectionMetadata::read_message() case ProtocolBase::EXTENSION_PROTOCOL:");
166
if (!m_down->can_read_extension_body())
169
if (m_extensions->is_default()) {
170
m_extensions = new ProtocolExtension();
171
m_extensions->set_info(m_peerInfo, m_download);
175
int extension = m_down->buffer()->read_8();
176
m_extensions->read_start(extension, length - 2, (extension == ProtocolExtension::UT_PEX) && !m_download->want_pex_msg());
177
m_down->set_state(ProtocolRead::READ_EXTENSION);
180
if (!down_extension())
183
m_download->info()->signal_network_log().emit("PeerConnectionMetadata::read_message() case ProtocolBase::EXTENSION_PROTOCOL: finished");
185
// Drop peer if it disabled the metadata extension.
186
if (!m_extensions->is_remote_supported(ProtocolExtension::UT_METADATA))
187
throw close_connection();
189
m_down->set_state(ProtocolRead::IDLE);
191
write_insert_poll_safe();
195
case ProtocolBase::BITFIELD:
196
// Discard the bitfield sent by the peer.
197
m_skipLength = length - 1;
198
m_down->set_state(ProtocolRead::READ_SKIP_PIECE);
202
throw communication_error("Received unsupported message type.");
205
// We were unsuccessfull in reading the message, need more data.
206
buf->set_position_itr(beginning);
211
PeerConnectionMetadata::event_read() {
212
m_timeLastRead = cachedTime;
214
// Need to make sure ProtocolBuffer::end() is pointing to the end of
215
// the unread data, and that the unread data starts from the
216
// beginning of the buffer. Or do we use position? Propably best,
217
// therefor ProtocolBuffer::position() points to the beginning of
224
// We rarely will read zero bytes as the read of 64 bytes will
225
// almost always either not fill up or it will require additional
228
// Only loop when end hits 64.
231
switch (m_down->get_state()) {
232
case ProtocolRead::IDLE:
233
if (m_down->buffer()->size_end() < read_size) {
234
unsigned int length = read_stream_throws(m_down->buffer()->end(), read_size - m_down->buffer()->size_end());
235
m_down->throttle()->node_used_unthrottled(length);
238
m_encryption.decrypt(m_down->buffer()->end(), length);
240
m_down->buffer()->move_end(length);
243
while (read_message());
245
if (m_down->buffer()->size_end() == read_size) {
246
m_down->buffer()->move_unused();
249
m_down->buffer()->move_unused();
253
case ProtocolRead::READ_EXTENSION:
254
if (!down_extension())
257
// Drop peer if it disabled the metadata extension.
258
if (!m_extensions->is_remote_supported(ProtocolExtension::UT_METADATA))
259
throw close_connection();
261
m_download->info()->signal_network_log().emit("PeerConnectionMetadata::event_read() case ProtocolRead::READ_EXTENSION:");
263
m_down->set_state(ProtocolRead::IDLE);
265
write_insert_poll_safe();
268
// Actually skipping the bitfield.
269
// We never receive normal piece messages anyway.
270
case ProtocolRead::READ_SKIP_PIECE:
271
if (!read_skip_bitfield())
274
m_down->set_state(ProtocolRead::IDLE);
278
throw internal_error("PeerConnection::event_read() wrong state.");
281
// Figure out how to get rid of the shouldLoop boolean.
284
// Exception handlers:
286
} catch (close_connection& e) {
287
m_download->connection_list()->erase(this, 0);
289
} catch (blocked_connection& e) {
290
m_download->info()->signal_network_log().emit("Momentarily blocked read connection.");
291
m_download->connection_list()->erase(this, 0);
293
} catch (network_error& e) {
294
m_download->connection_list()->erase(this, 0);
296
} catch (storage_error& e) {
297
m_download->info()->signal_storage_error().emit(e.what());
298
m_download->connection_list()->erase(this, 0);
300
} catch (base_error& e) {
302
s << "Connection read fd(" << get_fd().get_fd() << ',' << m_down->get_state() << ',' << m_down->last_command() << ") \"" << e.what() << '"';
304
throw internal_error(s.str());
309
PeerConnectionMetadata::fill_write_buffer() {
310
ProtocolBuffer<512>::iterator old_end = m_up->buffer()->end();
313
m_tryRequest = try_request_metadata_pieces();
315
if (m_sendPEXMask && m_up->can_write_extension() &&
316
send_pex_message()) {
317
// Don't do anything else if send_pex_message() succeeded.
319
} else if (m_extensions->has_pending_message() && m_up->can_write_extension() &&
320
send_ext_message()) {
325
m_encryption.encrypt(old_end, m_up->buffer()->end() - old_end);
329
PeerConnectionMetadata::event_write() {
334
switch (m_up->get_state()) {
335
case ProtocolWrite::IDLE:
339
if (m_up->buffer()->remaining() == 0) {
340
manager->poll()->remove_write(this);
344
m_up->set_state(ProtocolWrite::MSG);
346
case ProtocolWrite::MSG:
347
if (!m_up->buffer()->consume(m_up->throttle()->node_used_unthrottled(write_stream_throws(m_up->buffer()->position(),
348
m_up->buffer()->remaining()))))
351
m_up->buffer()->reset();
353
if (m_up->last_command() != ProtocolBase::EXTENSION_PROTOCOL) {
354
m_up->set_state(ProtocolWrite::IDLE);
358
m_up->set_state(ProtocolWrite::WRITE_EXTENSION);
360
case ProtocolWrite::WRITE_EXTENSION:
364
m_up->set_state(ProtocolWrite::IDLE);
368
throw internal_error("PeerConnection::event_write() wrong state.");
373
} catch (close_connection& e) {
374
m_download->connection_list()->erase(this, 0);
376
} catch (blocked_connection& e) {
377
m_download->info()->signal_network_log().emit("Momentarily blocked write connection.");
378
m_download->connection_list()->erase(this, 0);
380
} catch (network_error& e) {
381
m_download->connection_list()->erase(this, 0);
383
} catch (storage_error& e) {
384
m_download->info()->signal_storage_error().emit(e.what());
385
m_download->connection_list()->erase(this, 0);
387
} catch (base_error& e) {
389
s << "Connection write fd(" << get_fd().get_fd() << ',' << m_up->get_state() << ',' << m_up->last_command() << ") \"" << e.what() << '"';
391
throw internal_error(s.str());
396
PeerConnectionMetadata::read_skip_bitfield() {
397
if (m_down->buffer()->remaining()) {
398
uint32_t length = std::min(m_skipLength, (uint32_t)m_down->buffer()->remaining());
399
m_down->buffer()->consume(length);
400
m_skipLength -= length;
404
uint32_t length = std::min(m_skipLength, (uint32_t)null_buffer_size);
405
length = read_stream_throws(m_nullBuffer, length);
408
m_skipLength -= length;
411
return !m_skipLength;
414
// Same as the PCB code, but only one at a time and with the extension protocol.
416
PeerConnectionMetadata::try_request_metadata_pieces() {
417
if (m_download->file_list()->chunk_size() == 1 || !m_extensions->is_remote_supported(ProtocolExtension::UT_METADATA))
420
if (download_queue()->queued_empty())
423
uint32_t pipeSize = download_queue()->calculate_pipe_size(m_peerChunks.download_throttle()->rate()->rate());
425
// Don't start requesting if we can't do it in large enough chunks.
426
if (download_queue()->queued_size() >= (pipeSize + 10) / 2)
430
// if (!download_queue()->queued_size() < pipeSize || !m_up->can_write_extension() ||
431
if (!m_up->can_write_extension() || m_extensions->has_pending_message())
434
const Piece* p = download_queue()->delegate();
439
if (!m_download->file_list()->is_valid_piece(*p) || !m_peerChunks.bitfield()->get(p->index()))
440
throw internal_error("PeerConnectionMetadata::try_request_metadata_pieces() tried to use an invalid piece.");
442
// return m_extensions->request_metadata_piece(p);
445
if (m_extensions->request_metadata_piece(p)) {
446
m_download->info()->signal_network_log().emit("PeerConnectionMetadata::try_request_metadata_pieces() succeded.");
449
m_download->info()->signal_network_log().emit("PeerConnectionMetadata::try_request_metadata_pieces() failed.");
455
PeerConnectionMetadata::receive_metadata_piece(uint32_t piece, const char* data, uint32_t length) {
457
// Length is not set in a reject message.
458
length = ProtocolExtension::metadata_piece_size;
460
if ((piece << ProtocolExtension::metadata_piece_shift) + ProtocolExtension::metadata_piece_size >= m_download->file_list()->size_bytes())
461
length = m_download->file_list()->chunk_size() % ProtocolExtension::metadata_piece_size;
463
m_tryRequest = false;
464
read_cancel_piece(Piece(0, piece << ProtocolExtension::metadata_piece_shift, length));
466
m_download->info()->signal_network_log().emit("PeerConnectionMetadata::receive_metadata_piece reject.");
470
if (!down_chunk_start(Piece(0, piece << ProtocolExtension::metadata_piece_shift, length))) {
471
m_download->info()->signal_network_log().emit("PeerConnectionMetadata::receive_metadata_piece skip.");
472
down_chunk_skip_process(data, length);
474
m_download->info()->signal_network_log().emit("PeerConnectionMetadata::receive_metadata_piece process.");
475
down_chunk_process(data, length);
478
if (!m_downloadQueue.transfer()->is_finished())
479
throw internal_error("PeerConnectionMetadata::receive_metadata_piece did not have complete piece.");
482
down_chunk_finished();