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_TRACKER_LIST_H
38 #define LIBTORRENT_TRACKER_LIST_H
39
40 #include <algorithm>
41 #include <string>
42 #include <vector>
43 #include <torrent/common.h>
44 #include lt_tr1_functional
45
46 namespace torrent {
47
48 class AddressList;
49 class DownloadInfo;
50 class DownloadWrapper;
51 class Tracker;
52
53 // The tracker list will contain a list of tracker, divided into
54 // subgroups. Each group must be randomized before we start. When
55 // starting the tracker request, always start from the beginning and
56 // iterate if the request failed. Upon request success move the
57 // tracker to the beginning of the subgroup and start from the
58 // beginning of the whole list.
59
60 class LIBTORRENT_EXPORT TrackerList : private std::vector<Tracker*> {
61 public:
62 friend class DownloadWrapper;
63
64 typedef std::vector<Tracker*> base_type;
65 typedef AddressList address_list;
66
67 typedef std::function<void (Tracker*)> slot_tracker;
68 typedef std::function<void (Tracker*, const std::string&)> slot_string;
69 typedef std::function<uint32_t (Tracker*, AddressList*)> slot_address_list;
70
71 using base_type::value_type;
72
73 using base_type::iterator;
74 using base_type::const_iterator;
75 using base_type::reverse_iterator;
76 using base_type::const_reverse_iterator;
77 using base_type::size;
78 using base_type::empty;
79
80 using base_type::begin;
81 using base_type::end;
82 using base_type::rbegin;
83 using base_type::rend;
84 using base_type::front;
85 using base_type::back;
86
87 using base_type::at;
88 using base_type::operator[];
89
90 TrackerList();
91
92 bool has_active() const;
93 bool has_active_not_scrape() const;
94 bool has_active_in_group(uint32_t group) const;
95 bool has_active_not_scrape_in_group(uint32_t group) const;
96 bool has_usable() const;
97
98 unsigned int count_active() const;
99 unsigned int count_usable() const;
100
close_all()101 void close_all() { close_all_excluding(0); }
102 void close_all_excluding(int event_bitmap);
103
104 void disown_all_including(int event_bitmap);
105
106 void clear();
107 void clear_stats();
108
109 iterator insert(unsigned int group, Tracker* tracker);
110 void insert_url(unsigned int group, const std::string& url, bool extra_tracker = false);
111
112 void send_state(Tracker* tracker, int new_event);
113 void send_state_idx(unsigned idx, int new_event);
114 void send_state_itr(iterator itr, int new_event);
115
116 void send_scrape(Tracker* tracker);
117
info()118 DownloadInfo* info() { return m_info; }
state()119 int state() { return m_state; }
120
key()121 uint32_t key() const { return m_key; }
set_key(uint32_t key)122 void set_key(uint32_t key) { m_key = key; }
123
numwant()124 int32_t numwant() const { return m_numwant; }
set_numwant(int32_t n)125 void set_numwant(int32_t n) { m_numwant = n; }
126
find(Tracker * tb)127 iterator find(Tracker* tb) { return std::find(begin(), end(), tb); }
128 iterator find_url(const std::string& url);
129
130 iterator find_usable(iterator itr);
131 const_iterator find_usable(const_iterator itr) const;
132
133 iterator find_next_to_request(iterator itr);
134
135 iterator begin_group(unsigned int group);
136 const_iterator begin_group(unsigned int group) const;
end_group(unsigned int group)137 iterator end_group(unsigned int group) { return begin_group(group + 1); }
end_group(unsigned int group)138 const_iterator end_group(unsigned int group) const { return begin_group(group + 1); }
139
140 size_type size_group() const;
141 void cycle_group(unsigned int group);
142
143 iterator promote(iterator itr);
144 void randomize_group_entries();
145
146 void receive_success(Tracker* tb, AddressList* l);
147 void receive_failed(Tracker* tb, const std::string& msg);
148
149 void receive_scrape_success(Tracker* tb);
150 void receive_scrape_failed(Tracker* tb, const std::string& msg);
151
152 // Used by libtorrent internally.
slot_success()153 slot_address_list& slot_success() { return m_slot_success; }
slot_failure()154 slot_string& slot_failure() { return m_slot_failed; }
155
slot_scrape_success()156 slot_tracker& slot_scrape_success() { return m_slot_scrape_success; }
slot_scrape_failure()157 slot_string& slot_scrape_failure() { return m_slot_scrape_failed; }
158
slot_tracker_enabled()159 slot_tracker& slot_tracker_enabled() { return m_slot_tracker_enabled; }
slot_tracker_disabled()160 slot_tracker& slot_tracker_disabled() { return m_slot_tracker_disabled; }
161
162 protected:
set_info(DownloadInfo * info)163 void set_info(DownloadInfo* info) { m_info = info; }
164
set_state(int s)165 void set_state(int s) { m_state = s; }
166
167 private:
168 TrackerList(const TrackerList&) LIBTORRENT_NO_EXPORT;
169 void operator = (const TrackerList&) LIBTORRENT_NO_EXPORT;
170
171 DownloadInfo* m_info;
172 int m_state;
173
174 uint32_t m_key;
175 int32_t m_numwant;
176
177 slot_address_list m_slot_success;
178 slot_string m_slot_failed;
179
180 slot_tracker m_slot_scrape_success;
181 slot_string m_slot_scrape_failed;
182
183 slot_tracker m_slot_tracker_enabled;
184 slot_tracker m_slot_tracker_disabled;
185 };
186
187 inline void
send_state_idx(unsigned idx,int new_event)188 TrackerList::send_state_idx(unsigned idx, int new_event) {
189 send_state(at(idx), new_event);
190 }
191
192 inline void
send_state_itr(iterator itr,int new_event)193 TrackerList::send_state_itr(iterator itr, int new_event) {
194 if (itr == end())
195 return;
196
197 send_state(*itr, new_event);
198 }
199
200 }
201
202 #endif
203