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