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 #ifndef LIBTORRENT_DOWNLOAD_MAIN_H
38 #define LIBTORRENT_DOWNLOAD_MAIN_H
39 
40 #include <deque>
41 #include <rak/functional.h>
42 
43 #include "globals.h"
44 
45 #include "delegator.h"
46 
47 #include "data/chunk_handle.h"
48 #include "download/available_list.h"
49 #include "net/data_buffer.h"
50 #include "torrent/download_info.h"
51 #include "torrent/download/group_entry.h"
52 #include "torrent/data/file_list.h"
53 #include "torrent/peer/peer_list.h"
54 
55 namespace torrent {
56 
57 class ChunkList;
58 class ChunkSelector;
59 class ChunkStatistics;
60 
61 class choke_group;
62 class ConnectionList;
63 class DownloadWrapper;
64 class HandshakeManager;
65 class TrackerController;
66 class TrackerList;
67 class DownloadInfo;
68 class ThrottleList;
69 class InitialSeeding;
70 
71 class DownloadMain {
72 public:
73   typedef std::deque<std::pair<rak::timer, uint32_t> > have_queue_type;
74   typedef std::vector<SocketAddressCompact>            pex_list;
75 
76   DownloadMain();
77   ~DownloadMain();
78 
79   void                open(int flags);
80   void                close();
81 
82   void                start();
83   void                stop();
84 
choke_group()85   class choke_group*       choke_group()                              { return m_choke_group; }
c_choke_group()86   const class choke_group* c_choke_group() const                      { return m_choke_group; }
set_choke_group(class choke_group * grp)87   void                set_choke_group(class choke_group* grp)         { m_choke_group = grp; }
88 
tracker_controller()89   TrackerController*  tracker_controller()                       { return m_tracker_controller; }
tracker_list()90   TrackerList*        tracker_list()                             { return m_tracker_list; }
91 
info()92   DownloadInfo*       info()                                     { return m_info; }
93 
94   // Only retrieve writable chunks when the download is active.
chunk_list()95   ChunkList*          chunk_list()                               { return m_chunkList; }
chunk_selector()96   ChunkSelector*      chunk_selector()                           { return m_chunkSelector; }
chunk_statistics()97   ChunkStatistics*    chunk_statistics()                         { return m_chunkStatistics; }
98 
delegator()99   Delegator*          delegator()                                { return &m_delegator; }
100 
have_queue()101   have_queue_type*    have_queue()                               { return &m_haveQueue; }
102 
initial_seeding()103   InitialSeeding*     initial_seeding()                          { return m_initialSeeding; }
104   bool                start_initial_seeding();
105   void                initial_seeding_done(PeerConnectionBase* pcb);
106 
connection_list()107   ConnectionList*     connection_list()                          { return m_connectionList; }
file_list()108   FileList*           file_list()                                { return &m_fileList; }
peer_list()109   PeerList*           peer_list()                                { return &m_peerList; }
110 
111   std::pair<ThrottleList*, ThrottleList*> throttles(const sockaddr* sa);
112 
upload_throttle()113   ThrottleList*       upload_throttle()                          { return m_uploadThrottle; }
set_upload_throttle(ThrottleList * t)114   void                set_upload_throttle(ThrottleList* t)       { m_uploadThrottle = t; }
115 
download_throttle()116   ThrottleList*       download_throttle()                        { return m_downloadThrottle; }
set_download_throttle(ThrottleList * t)117   void                set_download_throttle(ThrottleList* t)     { m_downloadThrottle = t; }
118 
up_group_entry()119   group_entry*        up_group_entry()                           { return &m_up_group_entry; }
down_group_entry()120   group_entry*        down_group_entry()                         { return &m_down_group_entry; }
121 
get_ut_pex(bool initial)122   DataBuffer          get_ut_pex(bool initial)                   { return (initial ? m_ut_pex_initial : m_ut_pex_delta).clone(); }
123 
want_pex_msg()124   bool                want_pex_msg()                             { return m_info->is_pex_active() && m_peerList.available_list()->want_more(); };
125 
126   void                set_metadata_size(size_t s);
127 
128   // Carefull with these.
129   void                setup_delegator();
130   void                setup_tracker();
131 
132   typedef rak::const_mem_fun1<HandshakeManager, uint32_t, DownloadMain*>                   SlotCountHandshakes;
133   typedef rak::mem_fun1<DownloadWrapper, void, ChunkHandle>                                SlotHashCheckAdd;
134 
135   typedef rak::mem_fun2<HandshakeManager, void, const rak::socket_address&, DownloadMain*> slot_start_handshake_type;
136   typedef rak::mem_fun1<HandshakeManager, void, DownloadMain*>                             slot_stop_handshakes_type;
137 
slot_start_handshake(slot_start_handshake_type s)138   void                slot_start_handshake(slot_start_handshake_type s) { m_slotStartHandshake = s; }
slot_stop_handshakes(slot_stop_handshakes_type s)139   void                slot_stop_handshakes(slot_stop_handshakes_type s) { m_slotStopHandshakes = s; }
slot_count_handshakes(SlotCountHandshakes s)140   void                slot_count_handshakes(SlotCountHandshakes s) { m_slotCountHandshakes = s; }
slot_hash_check_add(SlotHashCheckAdd s)141   void                slot_hash_check_add(SlotHashCheckAdd s)      { m_slotHashCheckAdd = s; }
142 
143   void                add_peer(const rak::socket_address& sa);
144 
145   void                receive_connect_peers();
146   void                receive_chunk_done(unsigned int index);
147   void                receive_corrupt_chunk(PeerInfo* peerInfo);
148 
149   void                receive_tracker_success();
150   void                receive_tracker_request();
151 
152   void                receive_do_peer_exchange();
153 
154   void                do_peer_exchange();
155 
156   void                update_endgame();
157 
delay_download_done()158   rak::priority_item& delay_download_done()       { return m_delay_download_done; }
delay_partially_done()159   rak::priority_item& delay_partially_done()      { return m_delay_partially_done; }
delay_partially_restarted()160   rak::priority_item& delay_partially_restarted() { return m_delay_partially_restarted; }
161 
delay_disconnect_peers()162   rak::priority_item& delay_disconnect_peers() { return m_delayDisconnectPeers; }
163 
164 private:
165   // Disable copy ctor and assignment.
166   DownloadMain(const DownloadMain&);
167   void operator = (const DownloadMain&);
168 
169   void                setup_start();
170   void                setup_stop();
171 
172   DownloadInfo*       m_info;
173 
174   TrackerController*  m_tracker_controller;
175   TrackerList*        m_tracker_list;
176 
177   class choke_group*  m_choke_group;
178 
179   group_entry         m_up_group_entry;
180   group_entry         m_down_group_entry;
181 
182   ChunkList*          m_chunkList;
183   ChunkSelector*      m_chunkSelector;
184   ChunkStatistics*    m_chunkStatistics;
185 
186   Delegator           m_delegator;
187   have_queue_type     m_haveQueue;
188   InitialSeeding*     m_initialSeeding;
189 
190   ConnectionList*     m_connectionList;
191   FileList            m_fileList;
192   PeerList            m_peerList;
193 
194   DataBuffer          m_ut_pex_delta;
195   DataBuffer          m_ut_pex_initial;
196   pex_list            m_ut_pex_list;
197 
198   ThrottleList*       m_uploadThrottle;
199   ThrottleList*       m_downloadThrottle;
200 
201   slot_start_handshake_type m_slotStartHandshake;
202   slot_stop_handshakes_type m_slotStopHandshakes;
203 
204   SlotCountHandshakes m_slotCountHandshakes;
205   SlotHashCheckAdd    m_slotHashCheckAdd;
206 
207   rak::priority_item  m_delay_download_done;
208   rak::priority_item  m_delay_partially_done;
209   rak::priority_item  m_delay_partially_restarted;
210 
211   rak::priority_item  m_delayDisconnectPeers;
212   rak::priority_item  m_taskTrackerRequest;
213 };
214 
215 }
216 
217 #endif
218