1 // libTorrent - BitTorrent library
2 // Copyright (C) 2005-2011, Jari Sundell
3 //
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.
8 //
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.
13 //
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
17 //
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
22 // including the two.
23 //
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.
31 //
32 // Contact:  Jari Sundell <jaris@ifi.uio.no>
33 //
34 //           Skomakerveien 33
35 //           3185 Skoppum, NORWAY
36 
37 #include "config.h"
38 
39 #define __STDC_FORMAT_MACROS
40 
41 #include <inttypes.h>
42 
43 #include "data/block.h"
44 #include "data/block_list.h"
45 #include "data/chunk_list.h"
46 #include "data/hash_queue.h"
47 #include "data/hash_torrent.h"
48 #include "download/available_list.h"
49 #include "download/chunk_selector.h"
50 #include "download/chunk_statistics.h"
51 #include "download/download_wrapper.h"
52 #include "protocol/peer_connection_base.h"
53 #include "protocol/peer_factory.h"
54 #include "peer/peer_info.h"
55 #include "torrent/download/choke_group.h"
56 #include "torrent/download/choke_queue.h"
57 #include "torrent/download_info.h"
58 #include "torrent/data/file.h"
59 #include "torrent/peer/connection_list.h"
60 #include "torrent/tracker_controller.h"
61 #include "torrent/tracker_list.h"
62 #include "torrent/utils/log.h"
63 
64 #include "exceptions.h"
65 #include "download.h"
66 #include "object.h"
67 #include "throttle.h"
68 #include "tracker_list.h"
69 
70 #define LT_LOG_THIS(log_level, log_fmt, ...)                         \
71   lt_log_print_info(LOG_TORRENT_##log_level, m_ptr->info(), "download", log_fmt, __VA_ARGS__);
72 
73 namespace torrent {
74 
75 const int DownloadInfo::flag_open;
76 const int DownloadInfo::flag_active;
77 const int DownloadInfo::flag_compact;
78 const int DownloadInfo::flag_accepting_new_peers;
79 const int DownloadInfo::flag_accepting_seeders;
80 const int DownloadInfo::flag_private;
81 const int DownloadInfo::flag_meta_download;
82 const int DownloadInfo::flag_pex_enabled;
83 const int DownloadInfo::flag_pex_active;
84 
85 const int DownloadInfo::public_flags;
86 
87 const uint32_t DownloadInfo::unlimited;
88 
info() const89 const DownloadInfo* Download::info() const { return m_ptr->info(); }
data() const90 const download_data* Download::data() const { return m_ptr->data(); }
91 
92 void
open(int flags)93 Download::open(int flags) {
94   if (m_ptr->info()->is_open())
95     return;
96 
97   LT_LOG_THIS(INFO, "Opening torrent: flags:%0x.", flags);
98 
99   // Currently always open with no_create, as start will make sure
100   // they are created. Need to fix this.
101   m_ptr->main()->open(FileList::open_no_create);
102   m_ptr->hash_checker()->hashing_ranges().insert(0, m_ptr->main()->file_list()->size_chunks());
103 
104   // Mark the files by default to be created and resized. The client
105   // should be allowed to pass a flag that will keep the old settings,
106   // although loading resume data should really handle everything
107   // properly.
108   int fileFlags = File::flag_create_queued | File::flag_resize_queued;
109 
110   if (flags & open_enable_fallocate)
111     fileFlags |= File::flag_fallocate;
112 
113   for (FileList::iterator itr = m_ptr->main()->file_list()->begin(), last = m_ptr->main()->file_list()->end(); itr != last; itr++)
114     (*itr)->set_flags(fileFlags);
115 }
116 
117 void
close(int flags)118 Download::close(int flags) {
119   if (m_ptr->info()->is_active())
120     stop(0);
121 
122   LT_LOG_THIS(INFO, "Closing torrent: flags:%0x.", flags);
123   m_ptr->close();
124 }
125 
126 void
start(int flags)127 Download::start(int flags) {
128   DownloadInfo* info = m_ptr->info();
129 
130   if (!m_ptr->hash_checker()->is_checked())
131     throw internal_error("Tried to start an unchecked download.");
132 
133   if (!info->is_open())
134     throw internal_error("Tried to start a closed download.");
135 
136   if (m_ptr->data()->mutable_completed_bitfield()->empty())
137     throw internal_error("Tried to start a download with empty bitfield.");
138 
139   if (info->is_active())
140     return;
141 
142   LT_LOG_THIS(INFO, "Starting torrent: flags:%0x.", flags);
143 
144   m_ptr->data()->verify_wanted_chunks("Download::start(...)");
145 
146 //   file_list()->open(flags);
147 
148   // If the FileList::open_no_create flag was not set, our new
149   // behavior is to create all zero-length files with
150   // flag_queued_create set.
151   file_list()->open(flags & ~FileList::open_no_create);
152 
153   if (m_ptr->connection_type() == CONNECTION_INITIAL_SEED) {
154     if (!m_ptr->main()->start_initial_seeding())
155       set_connection_type(CONNECTION_SEED);
156   }
157 
158   m_ptr->main()->start();
159   m_ptr->main()->tracker_controller()->enable((flags & start_skip_tracker) ? TrackerController::enable_dont_reset_stats : 0);
160 
161   // Reset the uploaded/download baseline when we restart the download
162   // so that broken trackers get the right uploaded ratio.
163   if (!(flags & start_keep_baseline)) {
164     info->set_uploaded_baseline(info->up_rate()->total());
165     info->set_completed_baseline(m_ptr->main()->file_list()->completed_bytes());
166 
167     lt_log_print_info(LOG_TRACKER_INFO, info,
168                       "download", "Setting new baseline on start: uploaded:%" PRIu64 " completed:%" PRIu64 ".",
169                       info->uploaded_baseline(), info->completed_baseline());
170   }
171 
172   if (!(flags & start_skip_tracker))
173     m_ptr->main()->tracker_controller()->send_start_event();
174 }
175 
176 void
stop(int flags)177 Download::stop(int flags) {
178   if (!m_ptr->info()->is_active())
179     return;
180 
181   LT_LOG_THIS(INFO, "Stopping torrent: flags:%0x.", flags);
182 
183   m_ptr->main()->stop();
184 
185   if (!(flags & stop_skip_tracker))
186     m_ptr->main()->tracker_controller()->send_stop_event();
187 
188   m_ptr->main()->tracker_controller()->disable();
189 }
190 
191 bool
hash_check(bool tryQuick)192 Download::hash_check(bool tryQuick) {
193   if (m_ptr->hash_checker()->is_checking())
194     throw internal_error("Download::hash_check(...) called but the hash is already being checked.");
195 
196   if (!m_ptr->info()->is_open() || m_ptr->info()->is_active())
197     throw internal_error("Download::hash_check(...) called on a closed or active download.");
198 
199   if (m_ptr->hash_checker()->is_checked())
200     throw internal_error("Download::hash_check(...) called but already hash checked.");
201 
202   Bitfield* bitfield = m_ptr->data()->mutable_completed_bitfield();
203 
204   LT_LOG_THIS(INFO, "Checking hash: allocated:%i try_quick:%i.", !bitfield->empty(), (int)tryQuick);
205 
206   if (bitfield->empty()) {
207     // The bitfield still hasn't been allocated, so no resume data was
208     // given.
209     bitfield->allocate();
210     bitfield->unset_all();
211 
212     m_ptr->hash_checker()->hashing_ranges().insert(0, m_ptr->main()->file_list()->size_chunks());
213   }
214 
215   m_ptr->main()->file_list()->update_completed();
216 
217   return m_ptr->hash_checker()->start(tryQuick);
218 }
219 
220 // Propably not correct, need to clear content, etc.
221 void
hash_stop()222 Download::hash_stop() {
223   if (!m_ptr->hash_checker()->is_checking())
224     return;
225 
226   LT_LOG_THIS(INFO, "Hashing stopped.", 0);
227 
228   m_ptr->hash_checker()->hashing_ranges().erase(0, m_ptr->hash_checker()->position());
229   m_ptr->hash_queue()->remove(m_ptr->data());
230 
231   m_ptr->hash_checker()->clear();
232 }
233 
234 bool
is_hash_checked() const235 Download::is_hash_checked() const {
236   return m_ptr->hash_checker()->is_checked();
237 }
238 
239 bool
is_hash_checking() const240 Download::is_hash_checking() const {
241   return m_ptr->hash_checker()->is_checking();
242 }
243 
244 void
set_pex_enabled(bool enabled)245 Download::set_pex_enabled(bool enabled) {
246   if (enabled)
247     m_ptr->info()->set_pex_enabled();
248   else
249     m_ptr->info()->unset_flags(DownloadInfo::flag_pex_enabled);
250 }
251 
252 Object*
bencode()253 Download::bencode() {
254   return m_ptr->bencode();
255 }
256 
257 const Object*
bencode() const258 Download::bencode() const {
259   return m_ptr->bencode();
260 }
261 
262 FileList*
file_list() const263 Download::file_list() const {
264   return m_ptr->main()->file_list();
265 }
266 
267 TrackerController*
tracker_controller() const268 Download::tracker_controller() const {
269   return m_ptr->main()->tracker_controller();
270 }
271 
272 TrackerList*
tracker_list() const273 Download::tracker_list() const {
274   return m_ptr->main()->tracker_list();
275 }
276 
277 PeerList*
peer_list()278 Download::peer_list() {
279   return m_ptr->main()->peer_list();
280 }
281 
282 const PeerList*
peer_list() const283 Download::peer_list() const {
284   return m_ptr->main()->peer_list();
285 }
286 
287 const TransferList*
transfer_list() const288 Download::transfer_list() const {
289   return m_ptr->main()->delegator()->transfer_list();
290 }
291 
292 ConnectionList*
connection_list()293 Download::connection_list() {
294   return m_ptr->main()->connection_list();
295 }
296 
297 const ConnectionList*
connection_list() const298 Download::connection_list() const {
299   return m_ptr->main()->connection_list();
300 }
301 
302 uint64_t
bytes_done() const303 Download::bytes_done() const {
304   uint64_t a = 0;
305 
306   Delegator* d = m_ptr->main()->delegator();
307 
308   for (TransferList::const_iterator itr1 = d->transfer_list()->begin(), last1 = d->transfer_list()->end(); itr1 != last1; ++itr1)
309     for (BlockList::const_iterator itr2 = (*itr1)->begin(), last2 = (*itr1)->end(); itr2 != last2; ++itr2)
310       if (itr2->is_finished())
311         a += itr2->piece().length();
312 
313   return a + m_ptr->main()->file_list()->completed_bytes();
314 }
315 
316 uint32_t
chunks_hashed() const317 Download::chunks_hashed() const {
318   return m_ptr->hash_checker()->position();
319 }
320 
321 const uint8_t*
chunks_seen() const322 Download::chunks_seen() const {
323   return !m_ptr->main()->chunk_statistics()->empty() ? &*m_ptr->main()->chunk_statistics()->begin() : NULL;
324 }
325 
326 void
set_chunks_done(uint32_t chunks_done,uint32_t chunks_wanted)327 Download::set_chunks_done(uint32_t chunks_done, uint32_t chunks_wanted) {
328   if (m_ptr->info()->is_open() || !m_ptr->data()->mutable_completed_bitfield()->empty())
329     throw input_error("Download::set_chunks_done(...) Invalid state.");
330 
331   chunks_done   = std::min<uint32_t>(chunks_done,   m_ptr->file_list()->size_chunks());
332   chunks_wanted = std::min<uint32_t>(chunks_wanted, m_ptr->file_list()->size_chunks() - chunks_done);
333 
334   m_ptr->data()->mutable_completed_bitfield()->set_size_set(chunks_done);
335   m_ptr->data()->set_wanted_chunks(chunks_wanted);
336 }
337 
338 void
set_bitfield(bool allSet)339 Download::set_bitfield(bool allSet) {
340   if (m_ptr->hash_checker()->is_checked() || m_ptr->hash_checker()->is_checking())
341     throw input_error("Download::set_bitfield(...) Download in invalid state.");
342 
343   Bitfield* bitfield = m_ptr->data()->mutable_completed_bitfield();
344 
345   bitfield->allocate();
346 
347   if (allSet)
348     bitfield->set_all();
349   else
350     bitfield->unset_all();
351 
352   m_ptr->data()->update_wanted_chunks();
353   m_ptr->hash_checker()->hashing_ranges().clear();
354 }
355 
356 void
set_bitfield(uint8_t * first,uint8_t * last)357 Download::set_bitfield(uint8_t* first, uint8_t* last) {
358   if (m_ptr->hash_checker()->is_checked() || m_ptr->hash_checker()->is_checking())
359     throw input_error("Download::set_bitfield(...) Download in invalid state.");
360 
361   if (std::distance(first, last) != (ptrdiff_t)m_ptr->main()->file_list()->bitfield()->size_bytes())
362     throw input_error("Download::set_bitfield(...) Invalid length.");
363 
364   Bitfield* bitfield = m_ptr->data()->mutable_completed_bitfield();
365 
366   bitfield->allocate();
367   std::memcpy(bitfield->begin(), first, bitfield->size_bytes());
368   bitfield->update();
369 
370   m_ptr->data()->update_wanted_chunks();
371   m_ptr->hash_checker()->hashing_ranges().clear();
372 }
373 
374 void
update_range(int flags,uint32_t first,uint32_t last)375 Download::update_range(int flags, uint32_t first, uint32_t last) {
376   if (m_ptr->hash_checker()->is_checked() ||
377       m_ptr->hash_checker()->is_checking())
378     throw input_error("Download::clear_range(...) Download is hash checked/checking.");
379 
380   if (m_ptr->main()->file_list()->bitfield()->empty())
381     throw input_error("Download::clear_range(...) Bitfield is empty.");
382 
383   if (flags & update_range_recheck)
384     m_ptr->hash_checker()->hashing_ranges().insert(first, last);
385 
386   if (flags & (update_range_clear | update_range_recheck)) {
387     m_ptr->data()->mutable_completed_bitfield()->unset_range(first, last);
388     m_ptr->data()->update_wanted_chunks();
389   }
390 }
391 
392 void
sync_chunks()393 Download::sync_chunks() {
394   m_ptr->main()->chunk_list()->sync_chunks(ChunkList::sync_all | ChunkList::sync_force);
395 }
396 
397 uint32_t
peers_complete() const398 Download::peers_complete() const {
399   return m_ptr->main()->chunk_statistics()->complete();
400 }
401 
402 uint32_t
peers_accounted() const403 Download::peers_accounted() const {
404   return m_ptr->main()->chunk_statistics()->accounted();
405 }
406 
407 uint32_t
peers_currently_unchoked() const408 Download::peers_currently_unchoked() const {
409   return m_ptr->main()->choke_group()->up_queue()->size_unchoked();
410 }
411 
412 uint32_t
peers_currently_interested() const413 Download::peers_currently_interested() const {
414   return m_ptr->main()->choke_group()->up_queue()->size_total();
415 }
416 
417 uint32_t
size_pex() const418 Download::size_pex() const {
419   return m_ptr->main()->info()->size_pex();
420 }
421 
422 uint32_t
max_size_pex() const423 Download::max_size_pex() const {
424   return m_ptr->main()->info()->max_size_pex();
425 }
426 
427 bool
accepting_new_peers() const428 Download::accepting_new_peers() const {
429   return m_ptr->info()->is_accepting_new_peers();
430 }
431 
432 // DEPRECATE
433 uint32_t
uploads_max() const434 Download::uploads_max() const {
435   if (m_ptr->main()->up_group_entry()->max_slots() == DownloadInfo::unlimited)
436     return 0;
437 
438   return m_ptr->main()->up_group_entry()->max_slots();
439 }
440 
441 uint32_t
uploads_min() const442 Download::uploads_min() const {
443   // if (m_ptr->main()->up_group_entry()->min_slots() == DownloadInfo::unlimited)
444   //   return 0;
445 
446   return m_ptr->main()->up_group_entry()->min_slots();
447 }
448 
449 uint32_t
downloads_max() const450 Download::downloads_max() const {
451   if (m_ptr->main()->down_group_entry()->max_slots() == DownloadInfo::unlimited)
452     return 0;
453 
454   return m_ptr->main()->down_group_entry()->max_slots();
455 }
456 
457 uint32_t
downloads_min() const458 Download::downloads_min() const {
459   // if (m_ptr->main()->down_group_entry()->min_slots() == DownloadInfo::unlimited)
460   //   return 0;
461 
462   return m_ptr->main()->down_group_entry()->min_slots();
463 }
464 
465 void
set_upload_throttle(Throttle * t)466 Download::set_upload_throttle(Throttle* t) {
467   if (m_ptr->info()->is_active())
468     throw internal_error("Download::set_upload_throttle() called on active download.");
469 
470   m_ptr->main()->set_upload_throttle(t->throttle_list());
471 }
472 
473 void
set_download_throttle(Throttle * t)474 Download::set_download_throttle(Throttle* t) {
475   if (m_ptr->info()->is_active())
476     throw internal_error("Download::set_download_throttle() called on active download.");
477 
478   m_ptr->main()->set_download_throttle(t->throttle_list());
479 }
480 
481 void
send_completed()482 Download::send_completed() {
483   m_ptr->main()->tracker_controller()->send_completed_event();
484 }
485 
486 void
manual_request(bool force)487 Download::manual_request(bool force) {
488   m_ptr->main()->tracker_controller()->manual_request(force);
489 }
490 
491 void
manual_cancel()492 Download::manual_cancel() {
493   m_ptr->main()->tracker_controller()->close();
494 }
495 
496 // DEPRECATE
497 void
set_uploads_max(uint32_t v)498 Download::set_uploads_max(uint32_t v) {
499   if (v > (1 << 16))
500     throw input_error("Max uploads must be between 0 and 2^16.");
501 
502   // For the moment, treat 0 as unlimited.
503   m_ptr->main()->up_group_entry()->set_max_slots(v == 0 ? DownloadInfo::unlimited : v);
504   m_ptr->main()->choke_group()->up_queue()->balance_entry(m_ptr->main()->up_group_entry());
505 }
506 
507 void
set_uploads_min(uint32_t v)508 Download::set_uploads_min(uint32_t v) {
509   if (v > (1 << 16))
510     throw input_error("Min uploads must be between 0 and 2^16.");
511 
512   // For the moment, treat 0 as unlimited.
513   m_ptr->main()->up_group_entry()->set_min_slots(v);
514   m_ptr->main()->choke_group()->up_queue()->balance_entry(m_ptr->main()->up_group_entry());
515 }
516 
517 void
set_downloads_max(uint32_t v)518 Download::set_downloads_max(uint32_t v) {
519   if (v > (1 << 16))
520     throw input_error("Max downloads must be between 0 and 2^16.");
521 
522   // For the moment, treat 0 as unlimited.
523   m_ptr->main()->down_group_entry()->set_max_slots(v == 0 ? DownloadInfo::unlimited : v);
524   m_ptr->main()->choke_group()->down_queue()->balance_entry(m_ptr->main()->down_group_entry());
525 }
526 
527 void
set_downloads_min(uint32_t v)528 Download::set_downloads_min(uint32_t v) {
529   if (v > (1 << 16))
530     throw input_error("Min downloads must be between 0 and 2^16.");
531 
532   // For the moment, treat 0 as unlimited.
533   m_ptr->main()->down_group_entry()->set_min_slots(v);
534   m_ptr->main()->choke_group()->down_queue()->balance_entry(m_ptr->main()->down_group_entry());
535 }
536 
537 Download::ConnectionType
connection_type() const538 Download::connection_type() const {
539   return (ConnectionType)m_ptr->connection_type();
540 }
541 
542 void
set_connection_type(ConnectionType t)543 Download::set_connection_type(ConnectionType t) {
544   if (m_ptr->info()->is_meta_download()) {
545     m_ptr->main()->connection_list()->slot_new_connection(&createPeerConnectionMetadata);
546     return;
547   }
548 
549   switch (t) {
550   case CONNECTION_LEECH:
551     m_ptr->main()->connection_list()->slot_new_connection(&createPeerConnectionDefault);
552     break;
553   case CONNECTION_SEED:
554     m_ptr->main()->connection_list()->slot_new_connection(&createPeerConnectionSeed);
555     break;
556   case CONNECTION_INITIAL_SEED:
557     if (info()->is_active() && m_ptr->main()->initial_seeding() == NULL)
558       throw input_error("Can't switch to initial seeding: download is active.");
559     m_ptr->main()->connection_list()->slot_new_connection(&createPeerConnectionInitialSeed);
560     break;
561   default:
562     throw input_error("torrent::Download::set_connection_type(...) received an unknown type.");
563   };
564 
565   m_ptr->set_connection_type(t);
566 }
567 
568 Download::HeuristicType
upload_choke_heuristic() const569 Download::upload_choke_heuristic() const {
570   return (Download::HeuristicType)m_ptr->main()->choke_group()->up_queue()->heuristics();
571 }
572 
573 void
set_upload_choke_heuristic(HeuristicType t)574 Download::set_upload_choke_heuristic(HeuristicType t) {
575   if ((choke_queue::heuristics_enum)t >= choke_queue::HEURISTICS_MAX_SIZE)
576     throw input_error("Invalid heuristics value.");
577 
578   m_ptr->main()->choke_group()->up_queue()->set_heuristics((choke_queue::heuristics_enum)t);
579 }
580 
581 Download::HeuristicType
download_choke_heuristic() const582 Download::download_choke_heuristic() const {
583   return (Download::HeuristicType)m_ptr->main()->choke_group()->down_queue()->heuristics();
584 }
585 
586 void
set_download_choke_heuristic(HeuristicType t)587 Download::set_download_choke_heuristic(HeuristicType t) {
588   if ((choke_queue::heuristics_enum)t >= choke_queue::HEURISTICS_MAX_SIZE)
589     throw input_error("Invalid heuristics value.");
590 
591   m_ptr->main()->choke_group()->down_queue()->set_heuristics((choke_queue::heuristics_enum)t);
592 }
593 
594 void
update_priorities()595 Download::update_priorities() {
596   m_ptr->receive_update_priorities();
597 }
598 
599 void
add_peer(const sockaddr * sa,int port)600 Download::add_peer(const sockaddr* sa, int port) {
601   if (m_ptr->info()->is_private())
602     return;
603 
604   rak::socket_address sa_port = *rak::socket_address::cast_from(sa);
605   sa_port.set_port(port);
606   m_ptr->main()->add_peer(sa_port);
607 }
608 
main()609 DownloadMain* Download::main() { return m_ptr->main(); }
610 
611 }
612