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_POLICY_HPP_INCLUDED
00034 #define TORRENT_POLICY_HPP_INCLUDED
00035
00036 #include <algorithm>
00037 #include <vector>
00038
00039 #ifdef _MSC_VER
00040 #pragma warning(push, 1)
00041 #endif
00042
00043 #include <boost/date_time/posix_time/posix_time.hpp>
00044
00045 #ifdef _MSC_VER
00046 #pragma warning(pop)
00047 #endif
00048
00049 #include "libtorrent/peer.hpp"
00050 #include "libtorrent/piece_picker.hpp"
00051 #include "libtorrent/socket.hpp"
00052 #include "libtorrent/size_type.hpp"
00053 #include "libtorrent/invariant_check.hpp"
00054 #include "libtorrent/config.hpp"
00055
00056 namespace libtorrent
00057 {
00058
00059 class torrent;
00060 class peer_connection;
00061
00062 enum
00063 {
00064
00065 min_request_queue = 2,
00066
00067
00068
00069 free_upload_amount = 4 * 16 * 1024
00070 };
00071
00072 void request_a_block(
00073 torrent& t
00074 , peer_connection& c
00075 , std::vector<peer_connection*> ignore = std::vector<peer_connection*>());
00076
00077 class TORRENT_EXPORT policy
00078 {
00079 public:
00080
00081 policy(torrent* t);
00082
00083
00084
00085 void pulse();
00086
00087
00088
00089 void peer_from_tracker(const tcp::endpoint& remote, const peer_id& pid);
00090
00091
00092 void new_connection(peer_connection& c);
00093
00094
00095
00096
00097 void peer_failed(peer_connection const& c);
00098
00099
00100 void connection_closed(const peer_connection& c);
00101
00102
00103
00104 void ban_peer(const peer_connection& c);
00105
00106
00107 void peer_is_interesting(peer_connection& c);
00108
00109 void piece_finished(int index, bool successfully_verified);
00110
00111 void block_finished(peer_connection& c, piece_block b);
00112
00113
00114 void choked(peer_connection& c);
00115
00116
00117 void unchoked(peer_connection& c);
00118
00119
00120 void interested(peer_connection& c);
00121
00122
00123 void not_interested(peer_connection& c);
00124
00125 #ifndef NDEBUG
00126 bool has_connection(const peer_connection* p);
00127
00128 void check_invariant() const;
00129 #endif
00130
00131 struct peer
00132 {
00133 enum connection_type { not_connectable,connectable };
00134
00135 peer(const tcp::endpoint& ip, connection_type t);
00136
00137 size_type total_download() const;
00138 size_type total_upload() const;
00139
00140
00141
00142
00143
00144 tcp::endpoint ip;
00145 connection_type type;
00146
00147
00148
00149 boost::posix_time::ptime last_optimistically_unchoked;
00150
00151
00152
00153 boost::posix_time::ptime connected;
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 size_type prev_amount_upload;
00165 size_type prev_amount_download;
00166
00167
00168 bool banned;
00169
00170
00171
00172 peer_connection* connection;
00173 };
00174
00175 int num_peers() const
00176 {
00177 return m_peers.size();
00178 }
00179
00180 int num_uploads() const
00181 {
00182 return m_num_unchoked;
00183 }
00184
00185 typedef std::vector<peer>::iterator iterator;
00186 iterator begin_peer() { return m_peers.begin(); }
00187 iterator end_peer() { return m_peers.end(); }
00188
00189 private:
00190
00191 bool unchoke_one_peer();
00192 void choke_one_peer();
00193 peer* find_choke_candidate();
00194 peer* find_unchoke_candidate();
00195
00196
00197
00198 bool seed_unchoke_one_peer();
00199 void seed_choke_one_peer();
00200 peer* find_seed_choke_candidate();
00201 peer* find_seed_unchoke_candidate();
00202
00203 bool connect_peer(peer *);
00204 bool connect_one_peer();
00205 bool disconnect_one_peer();
00206 peer* find_disconnect_candidate();
00207 peer* find_connect_candidate();
00208
00209
00210
00211 struct old_disconnected_peer
00212 {
00213 bool operator()(const peer& p)
00214 {
00215 using namespace boost::posix_time;
00216
00217 ptime not_tried_yet(boost::gregorian::date(1970,boost::gregorian::Jan,1));
00218
00219
00220 return p.connection == 0
00221 && p.connected != not_tried_yet
00222 && second_clock::universal_time() - p.connected > minutes(30);
00223 }
00224 };
00225
00226
00227 std::vector<peer> m_peers;
00228
00229 torrent* m_torrent;
00230
00231
00232
00233 int m_num_unchoked;
00234
00235
00236
00237 size_type m_available_free_upload;
00238
00239
00240
00241
00242 boost::posix_time::ptime m_last_optimistic_disconnect;
00243 };
00244
00245 }
00246
00247 #endif // TORRENT_POLICY_HPP_INCLUDED
00248