00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef TORRENT_TRACKER_MANAGER_HPP_INCLUDED
00034 #define TORRENT_TRACKER_MANAGER_HPP_INCLUDED
00035
00036 #include <vector>
00037 #include <string>
00038 #include <utility>
00039 #include <ctime>
00040
00041 #ifdef _MSC_VER
00042 #pragma warning(push, 1)
00043 #endif
00044
00045 #include <boost/shared_ptr.hpp>
00046 #include <boost/date_time/posix_time/posix_time.hpp>
00047 #include <boost/cstdint.hpp>
00048 #include <boost/weak_ptr.hpp>
00049 #include <boost/intrusive_ptr.hpp>
00050 #include <boost/thread/mutex.hpp>
00051 #include <boost/thread/recursive_mutex.hpp>
00052 #include <boost/tuple/tuple.hpp>
00053
00054 #ifdef _MSC_VER
00055 #pragma warning(pop)
00056 #endif
00057
00058 #include "libtorrent/socket.hpp"
00059 #include "libtorrent/entry.hpp"
00060 #include "libtorrent/session_settings.hpp"
00061 #include "libtorrent/peer_id.hpp"
00062 #include "libtorrent/peer.hpp"
00063 #include "libtorrent/config.hpp"
00064
00065 namespace libtorrent
00066 {
00067 struct request_callback;
00068 class tracker_manager;
00069 struct timeout_handler;
00070 struct tracker_connection;
00071
00072
00073 TORRENT_EXPORT std::string base64encode(const std::string& s);
00074
00075
00076 TORRENT_EXPORT int gzip_header(const char* buf, int size);
00077
00078 TORRENT_EXPORT boost::tuple<std::string, std::string, int, std::string>
00079 parse_url_components(std::string url);
00080
00081 struct TORRENT_EXPORT tracker_request
00082 {
00083 tracker_request()
00084 : kind(announce_request)
00085 , web_downloaded(0)
00086 , event(none)
00087 , key(0)
00088 , num_want(0)
00089 {}
00090
00091 enum
00092 {
00093 announce_request,
00094 scrape_request
00095 } kind;
00096
00097 enum event_t
00098 {
00099 none,
00100 completed,
00101 started,
00102 stopped
00103 };
00104
00105 sha1_hash info_hash;
00106 peer_id pid;
00107 size_type downloaded;
00108 size_type uploaded;
00109 size_type left;
00110 size_type web_downloaded;
00111 unsigned short listen_port;
00112 event_t event;
00113 std::string url;
00114 int key;
00115 int num_want;
00116 };
00117
00118 struct TORRENT_EXPORT request_callback
00119 {
00120 friend class tracker_manager;
00121 request_callback(): m_manager(0) {}
00122 virtual ~request_callback() {}
00123 virtual void tracker_warning(std::string const& msg) = 0;
00124 virtual void tracker_response(
00125 tracker_request const&
00126 , std::vector<peer_entry>& peers
00127 , int interval
00128 , int complete
00129 , int incomplete) = 0;
00130 virtual void tracker_request_timed_out(
00131 tracker_request const&) = 0;
00132 virtual void tracker_request_error(
00133 tracker_request const&
00134 , int response_code
00135 , const std::string& description) = 0;
00136
00137 tcp::endpoint m_tracker_address;
00138
00139 #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
00140 virtual void debug_log(const std::string& line) = 0;
00141 #endif
00142 private:
00143 tracker_manager* m_manager;
00144 };
00145
00146 TORRENT_EXPORT bool inflate_gzip(
00147 std::vector<char>& buffer
00148 , tracker_request const& req
00149 , request_callback* requester
00150 , int maximum_tracker_response_length);
00151
00152 TORRENT_EXPORT void intrusive_ptr_add_ref(timeout_handler const*);
00153 TORRENT_EXPORT void intrusive_ptr_release(timeout_handler const*);
00154
00155 struct TORRENT_EXPORT timeout_handler
00156 : boost::noncopyable
00157 {
00158 friend void intrusive_ptr_add_ref(timeout_handler const*);
00159 friend void intrusive_ptr_release(timeout_handler const*);
00160
00161 timeout_handler(asio::strand& str);
00162
00163 void set_timeout(int completion_timeout, int read_timeout);
00164 void restart_read_timeout();
00165 void cancel();
00166
00167 virtual void on_timeout() = 0;
00168 virtual ~timeout_handler() {}
00169
00170 private:
00171
00172 void timeout_callback(asio::error_code const&);
00173
00174 boost::intrusive_ptr<timeout_handler> self()
00175 { return boost::intrusive_ptr<timeout_handler>(this); }
00176
00177 asio::strand& m_strand;
00178
00179
00180 boost::posix_time::ptime m_start_time;
00181
00182 boost::posix_time::ptime m_read_time;
00183
00184 asio::deadline_timer m_timeout;
00185
00186 int m_completion_timeout;
00187 int m_read_timeout;
00188
00189 typedef boost::mutex mutex_t;
00190 mutable mutex_t m_mutex;
00191 mutable int m_refs;
00192 };
00193
00194 struct TORRENT_EXPORT tracker_connection
00195 : timeout_handler
00196 {
00197 tracker_connection(tracker_manager& man
00198 , tracker_request req
00199 , asio::strand& str
00200 , address bind_interface
00201 , boost::weak_ptr<request_callback> r);
00202
00203 request_callback& requester();
00204 virtual ~tracker_connection() {}
00205
00206 tracker_request const& tracker_req() const { return m_req; }
00207 bool has_requester() const { return !m_requester.expired(); }
00208
00209 void fail(int code, char const* msg);
00210 void fail_timeout();
00211 void close();
00212 address const& bind_interface() const { return m_bind_interface; }
00213
00214 protected:
00215 boost::weak_ptr<request_callback> m_requester;
00216 private:
00217 address m_bind_interface;
00218 tracker_manager& m_man;
00219 const tracker_request m_req;
00220 };
00221
00222 class TORRENT_EXPORT tracker_manager: boost::noncopyable
00223 {
00224 public:
00225
00226 tracker_manager(const session_settings& s)
00227 : m_settings(s) {}
00228
00229 void queue_request(
00230 asio::strand& str
00231 , tracker_request r
00232 , std::string const& auth
00233 , address bind_infc
00234 , boost::weak_ptr<request_callback> c
00235 = boost::weak_ptr<request_callback>());
00236 void abort_all_requests();
00237
00238 void remove_request(tracker_connection const*);
00239 bool empty() const;
00240
00241 private:
00242
00243 typedef boost::recursive_mutex mutex_t;
00244 mutable mutex_t m_mutex;
00245
00246 typedef std::list<boost::intrusive_ptr<tracker_connection> >
00247 tracker_connections_t;
00248 tracker_connections_t m_connections;
00249 session_settings const& m_settings;
00250 };
00251 }
00252
00253 #endif // TORRENT_TRACKER_MANAGER_HPP_INCLUDED
00254