1 #ifndef LIBTORRENT_TRACKER_H
2 #define LIBTORRENT_TRACKER_H
3
4 #include <string>
5 #include <inttypes.h>
6 #include <torrent/common.h>
7
8 namespace torrent {
9
10 class AddressList;
11 class TrackerList;
12
13 class LIBTORRENT_EXPORT Tracker {
14 public:
15 friend class TrackerList;
16
17 typedef enum {
18 TRACKER_NONE,
19 TRACKER_HTTP,
20 TRACKER_UDP,
21 TRACKER_DHT,
22 } Type;
23
24 enum tracker_event {
25 EVENT_NONE,
26 EVENT_COMPLETED,
27 EVENT_STARTED,
28 EVENT_STOPPED,
29 EVENT_SCRAPE
30 };
31
32 static const int flag_enabled = 0x1;
33 static const int flag_extra_tracker = 0x2;
34 static const int flag_can_scrape = 0x4;
35
36 static const int max_flag_size = 0x10;
37 static const int mask_base_flags = 0x10 - 1;
38
~Tracker()39 virtual ~Tracker() {}
40
flags()41 int flags() const { return m_flags; }
42
is_enabled()43 bool is_enabled() const { return (m_flags & flag_enabled); }
is_extra_tracker()44 bool is_extra_tracker() const { return (m_flags & flag_extra_tracker); }
is_in_use()45 bool is_in_use() const { return is_enabled() && m_success_counter != 0; }
46
can_scrape()47 bool can_scrape() const { return (m_flags & flag_can_scrape); }
48
49 virtual bool is_busy() const = 0;
is_busy_not_scrape()50 bool is_busy_not_scrape() const { return m_latest_event != EVENT_SCRAPE && is_busy(); }
is_usable()51 virtual bool is_usable() const { return is_enabled(); }
52
53 bool can_request_state() const;
54
55 void enable();
56 void disable();
57
parent()58 TrackerList* parent() { return m_parent; }
59
group()60 uint32_t group() const { return m_group; }
61 virtual Type type() const = 0;
62
url()63 const std::string& url() const { return m_url; }
set_url(const std::string & url)64 void set_url(const std::string& url) { m_url = url; }
65
tracker_id()66 const std::string& tracker_id() const { return m_tracker_id; }
set_tracker_id(const std::string & id)67 void set_tracker_id(const std::string& id) { m_tracker_id = id; }
68
normal_interval()69 uint32_t normal_interval() const { return m_normal_interval; }
min_interval()70 uint32_t min_interval() const { return m_min_interval; }
71
latest_event()72 int latest_event() const { return m_latest_event; }
latest_new_peers()73 uint32_t latest_new_peers() const { return m_latest_new_peers; }
latest_sum_peers()74 uint32_t latest_sum_peers() const { return m_latest_sum_peers; }
75
76 uint32_t success_time_next() const;
success_time_last()77 uint32_t success_time_last() const { return m_success_time_last; }
success_counter()78 uint32_t success_counter() const { return m_success_counter; }
79
80 uint32_t failed_time_next() const;
failed_time_last()81 uint32_t failed_time_last() const { return m_failed_time_last; }
failed_counter()82 uint32_t failed_counter() const { return m_failed_counter; }
83
activity_time_last()84 uint32_t activity_time_last() const { return failed_counter() ? m_failed_time_last : m_success_time_last; }
activity_time_next()85 uint32_t activity_time_next() const { return failed_counter() ? failed_time_next() : success_time_next(); }
86
scrape_time_last()87 uint32_t scrape_time_last() const { return m_scrape_time_last; }
scrape_counter()88 uint32_t scrape_counter() const { return m_scrape_counter; }
89
scrape_complete()90 uint32_t scrape_complete() const { return m_scrape_complete; }
scrape_incomplete()91 uint32_t scrape_incomplete() const { return m_scrape_incomplete; }
scrape_downloaded()92 uint32_t scrape_downloaded() const { return m_scrape_downloaded; }
93
get_status(char * buffer,int length)94 virtual void get_status(char* buffer, int length) { buffer[0] = 0; }
95
96 static std::string scrape_url_from(std::string url);
97
98 protected:
99 Tracker(TrackerList* parent, const std::string& url, int flags = 0);
100 Tracker(const Tracker& t);
101 void operator = (const Tracker& t);
102
103 virtual void send_state(int state) = 0;
104 virtual void send_scrape();
105 virtual void close() = 0;
106 virtual void disown() = 0;
107
108 // Safeguard to catch bugs that lead to hammering of trackers.
109 void inc_request_counter();
110
111 void clear_stats();
112
set_group(uint32_t v)113 void set_group(uint32_t v) { m_group = v; }
114
set_normal_interval(int v)115 void set_normal_interval(int v) { m_normal_interval = std::min(std::max(600, v), 8 * 3600); }
set_min_interval(int v)116 void set_min_interval(int v) { m_min_interval = std::min(std::max(300, v), 4 * 3600); }
117
118 int m_flags;
119
120 TrackerList* m_parent;
121 uint32_t m_group;
122
123 std::string m_url;
124 std::string m_tracker_id;
125
126 uint32_t m_normal_interval;
127 uint32_t m_min_interval;
128
129 int m_latest_event;
130 uint32_t m_latest_new_peers;
131 uint32_t m_latest_sum_peers;
132
133 uint32_t m_success_time_last;
134 uint32_t m_success_counter;
135
136 uint32_t m_failed_time_last;
137 uint32_t m_failed_counter;
138
139 uint32_t m_scrape_time_last;
140 uint32_t m_scrape_counter;
141
142 uint32_t m_scrape_complete;
143 uint32_t m_scrape_incomplete;
144 uint32_t m_scrape_downloaded;
145
146 // Timing of the last request, and a counter for how many requests
147 // there's been in the recent past.
148 uint32_t m_request_time_last;
149 uint32_t m_request_counter;
150 };
151
152 inline bool
can_request_state()153 Tracker::can_request_state() const {
154 return !(is_busy() && latest_event() != EVENT_SCRAPE) && is_usable();
155 }
156
157 }
158
159 #endif
160