excluded mapped_storage from build
[libtorrent.git] / src / policy.cpp
blob06990d45a77c77b3e57a7fbca3905504562b0fa7
1 /*
3 Copyright (c) 2003, Arvid Norberg
4 All rights reserved.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the distribution.
15 * Neither the name of the author nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
33 #include "libtorrent/pch.hpp"
35 #include <iostream>
37 #ifdef _MSC_VER
38 #pragma warning(push, 1)
39 #endif
41 #include <boost/bind.hpp>
42 #include <boost/utility.hpp>
44 #ifdef _MSC_VER
45 #pragma warning(pop)
46 #endif
48 #include "libtorrent/peer_connection.hpp"
49 #include "libtorrent/web_peer_connection.hpp"
50 #include "libtorrent/policy.hpp"
51 #include "libtorrent/torrent.hpp"
52 #include "libtorrent/socket.hpp"
53 #include "libtorrent/alert_types.hpp"
54 #include "libtorrent/invariant_check.hpp"
55 #include "libtorrent/time.hpp"
56 #include "libtorrent/aux_/session_impl.hpp"
57 #include "libtorrent/piece_picker.hpp"
59 #ifndef NDEBUG
60 #include "libtorrent/bt_peer_connection.hpp"
61 #endif
63 namespace libtorrent
65 class peer_connection;
68 using boost::bind;
70 namespace
72 using namespace libtorrent;
74 size_type collect_free_download(
75 torrent::peer_iterator start
76 , torrent::peer_iterator end)
78 size_type accumulator = 0;
79 for (torrent::peer_iterator i = start; i != end; ++i)
81 // if the peer is interested in us, it means it may
82 // want to trade it's surplus uploads for downloads itself
83 // (and we should not consider it free). If the share diff is
84 // negative, there's no free download to get from this peer.
85 size_type diff = (*i)->share_diff();
86 TORRENT_ASSERT(diff < (std::numeric_limits<size_type>::max)());
87 if ((*i)->is_peer_interested() || diff <= 0)
88 continue;
90 TORRENT_ASSERT(diff > 0);
91 (*i)->add_free_upload(-diff);
92 accumulator += diff;
93 TORRENT_ASSERT(accumulator > 0);
95 TORRENT_ASSERT(accumulator >= 0);
96 return accumulator;
100 // returns the amount of free upload left after
101 // it has been distributed to the peers
102 size_type distribute_free_upload(
103 torrent::peer_iterator start
104 , torrent::peer_iterator end
105 , size_type free_upload)
107 if (free_upload <= 0) return free_upload;
108 int num_peers = 0;
109 size_type total_diff = 0;
110 for (torrent::peer_iterator i = start; i != end; ++i)
112 size_type d = (*i)->share_diff();
113 TORRENT_ASSERT(d < (std::numeric_limits<size_type>::max)());
114 total_diff += d;
115 if (!(*i)->is_peer_interested() || (*i)->share_diff() >= 0) continue;
116 ++num_peers;
119 if (num_peers == 0) return free_upload;
120 size_type upload_share;
121 if (total_diff >= 0)
123 upload_share = (std::min)(free_upload, total_diff) / num_peers;
125 else
127 upload_share = (free_upload + total_diff) / num_peers;
129 if (upload_share < 0) return free_upload;
131 for (torrent::peer_iterator i = start; i != end; ++i)
133 peer_connection* p = *i;
134 if (!p->is_peer_interested() || p->share_diff() >= 0) continue;
135 p->add_free_upload(upload_share);
136 free_upload -= upload_share;
138 return free_upload;
141 struct match_peer_endpoint
143 match_peer_endpoint(tcp::endpoint const& ep)
144 : m_ep(ep)
147 bool operator()(std::pair<const address, policy::peer> const& p) const
148 { return p.second.addr == m_ep.address() && p.second.port == m_ep.port(); }
150 tcp::endpoint const& m_ep;
153 #ifndef NDEBUG
154 struct match_peer_connection
156 match_peer_connection(peer_connection const& c)
157 : m_conn(c)
160 bool operator()(std::pair<const address, policy::peer> const& p) const
162 return p.second.connection == &m_conn
163 || (p.second.ip() == m_conn.remote()
164 && p.second.type == policy::peer::connectable);
167 peer_connection const& m_conn;
169 #endif
173 namespace libtorrent
175 // the case where ignore_peer is motivated is if two peers
176 // have only one piece that we don't have, and it's the
177 // same piece for both peers. Then they might get into an
178 // infinite loop, fighting to request the same blocks.
179 void request_a_block(torrent& t, peer_connection& c)
181 if (t.is_seed()) return;
183 TORRENT_ASSERT(t.valid_metadata());
184 TORRENT_ASSERT(c.peer_info_struct() != 0 || !dynamic_cast<bt_peer_connection*>(&c));
185 int num_requests = c.desired_queue_size()
186 - (int)c.download_queue().size()
187 - (int)c.request_queue().size();
189 #ifdef TORRENT_VERBOSE_LOGGING
190 (*c.m_logger) << time_now_string() << " PIECE_PICKER [ req: " << num_requests << " ]\n";
191 #endif
192 TORRENT_ASSERT(c.desired_queue_size() > 0);
193 // if our request queue is already full, we
194 // don't have to make any new requests yet
195 if (num_requests <= 0) return;
197 piece_picker& p = t.picker();
198 std::vector<piece_block> interesting_pieces;
199 interesting_pieces.reserve(100);
201 int prefer_whole_pieces = c.prefer_whole_pieces();
203 bool rarest_first = t.num_have() >= t.settings().initial_picker_threshold;
205 if (prefer_whole_pieces == 0)
207 prefer_whole_pieces = c.statistics().download_payload_rate()
208 * t.settings().whole_pieces_threshold
209 > t.torrent_file().piece_length() ? 1 : 0;
212 // if we prefer whole pieces, the piece picker will pick at least
213 // the number of blocks we want, but it will try to make the picked
214 // blocks be from whole pieces, possibly by returning more blocks
215 // than we requested.
216 #ifndef NDEBUG
217 error_code ec;
218 TORRENT_ASSERT(c.remote() == c.get_socket()->remote_endpoint(ec) || ec);
219 #endif
221 piece_picker::piece_state_t state;
222 peer_connection::peer_speed_t speed = c.peer_speed();
223 if (speed == peer_connection::fast) state = piece_picker::fast;
224 else if (speed == peer_connection::medium) state = piece_picker::medium;
225 else state = piece_picker::slow;
227 // this vector is filled with the interesting pieces
228 // that some other peer is currently downloading
229 // we should then compare this peer's download speed
230 // with the other's, to see if we should abort another
231 // peer_connection in favour of this one
232 std::vector<piece_block> busy_pieces;
233 busy_pieces.reserve(num_requests);
235 std::vector<int> const& suggested = c.suggested_pieces();
236 bitfield const& bits = c.get_bitfield();
238 if (c.has_peer_choked())
240 // if we are choked we can only pick pieces from the
241 // allowed fast set. The allowed fast set is sorted
242 // in ascending priority order
243 std::vector<int> const& allowed_fast = c.allowed_fast();
245 // build a bitmask with only the allowed pieces in it
246 bitfield mask(c.get_bitfield().size(), false);
247 for (std::vector<int>::const_iterator i = allowed_fast.begin()
248 , end(allowed_fast.end()); i != end; ++i)
249 if (bits[*i]) mask.set_bit(*i);
251 p.pick_pieces(mask, interesting_pieces
252 , num_requests, prefer_whole_pieces, c.peer_info_struct()
253 , state, rarest_first, c.on_parole(), suggested);
255 else
257 // picks the interesting pieces from this peer
258 // the integer is the number of pieces that
259 // should be guaranteed to be available for download
260 // (if num_requests is too big, too many pieces are
261 // picked and cpu-time is wasted)
262 // the last argument is if we should prefer whole pieces
263 // for this peer. If we're downloading one piece in 20 seconds
264 // then use this mode.
265 p.pick_pieces(bits, interesting_pieces
266 , num_requests, prefer_whole_pieces, c.peer_info_struct()
267 , state, rarest_first, c.on_parole(), suggested);
270 #ifdef TORRENT_VERBOSE_LOGGING
271 (*c.m_logger) << time_now_string() << " PIECE_PICKER [ php: " << prefer_whole_pieces
272 << " picked: " << interesting_pieces.size() << " ]\n";
273 #endif
274 std::deque<pending_block> const& dq = c.download_queue();
275 std::deque<piece_block> const& rq = c.request_queue();
276 for (std::vector<piece_block>::iterator i = interesting_pieces.begin();
277 i != interesting_pieces.end(); ++i)
279 if (prefer_whole_pieces == 0 && num_requests <= 0) break;
281 if (p.is_requested(*i))
283 if (num_requests <= 0) break;
284 // don't request pieces we already have in our request queue
285 if (std::find_if(dq.begin(), dq.end(), has_block(*i)) != dq.end()
286 || std::find(rq.begin(), rq.end(), *i) != rq.end())
287 continue;
289 TORRENT_ASSERT(p.num_peers(*i) > 0);
290 busy_pieces.push_back(*i);
291 continue;
294 TORRENT_ASSERT(p.num_peers(*i) == 0);
295 // ok, we found a piece that's not being downloaded
296 // by somebody else. request it from this peer
297 // and return
298 c.add_request(*i);
299 TORRENT_ASSERT(p.num_peers(*i) == 1);
300 TORRENT_ASSERT(p.is_requested(*i));
301 num_requests--;
304 if (busy_pieces.empty() || num_requests <= 0)
306 // in this case, we could not find any blocks
307 // that was free. If we couldn't find any busy
308 // blocks as well, we cannot download anything
309 // more from this peer.
310 return;
313 // if all blocks has the same number of peers on them
314 // we want to pick a random block
315 std::random_shuffle(busy_pieces.begin(), busy_pieces.end());
317 // find the block with the fewest requests to it
318 std::vector<piece_block>::iterator i = std::min_element(
319 busy_pieces.begin(), busy_pieces.end()
320 , bind(&piece_picker::num_peers, boost::cref(p), _1) <
321 bind(&piece_picker::num_peers, boost::cref(p), _2));
322 #ifndef NDEBUG
323 piece_picker::downloading_piece st;
324 p.piece_info(i->piece_index, st);
325 TORRENT_ASSERT(st.requested + st.finished + st.writing == p.blocks_in_piece(i->piece_index));
326 #endif
327 TORRENT_ASSERT(p.is_requested(*i));
328 TORRENT_ASSERT(p.num_peers(*i) > 0);
329 c.add_request(*i);
332 policy::policy(torrent* t)
333 : m_round_robin(m_peers.end())
334 , m_torrent(t)
335 , m_available_free_upload(0)
336 , m_num_connect_candidates(0)
337 , m_num_seeds(0)
338 { TORRENT_ASSERT(t); }
340 // disconnects and removes all peers that are now filtered
341 void policy::ip_filter_updated()
343 aux::session_impl& ses = m_torrent->session();
344 piece_picker* p = 0;
345 if (m_torrent->has_picker())
346 p = &m_torrent->picker();
347 for (iterator i = m_peers.begin()
348 , end(m_peers.end()); i != end;)
350 if ((ses.m_ip_filter.access(i->second.addr) & ip_filter::blocked) == 0)
352 ++i;
353 continue;
356 if (i->second.connection)
358 i->second.connection->disconnect("peer banned by IP filter");
359 if (ses.m_alerts.should_post<peer_blocked_alert>())
360 ses.m_alerts.post_alert(peer_blocked_alert(i->second.addr));
361 TORRENT_ASSERT(i->second.connection == 0
362 || i->second.connection->peer_info_struct() == 0);
364 else
366 if (ses.m_alerts.should_post<peer_blocked_alert>())
367 ses.m_alerts.post_alert(peer_blocked_alert(i->second.addr));
369 erase_peer(i++);
373 // any peer that is erased from m_peers will be
374 // erased through this function. This way we can make
375 // sure that any references to the peer are removed
376 // as well, such as in the piece picker.
377 void policy::erase_peer(iterator i)
379 if (m_torrent->has_picker())
380 m_torrent->picker().clear_peer(&i->second);
381 if (i->second.seed) --m_num_seeds;
382 if (is_connect_candidate(i->second, m_torrent->is_finished()))
383 --m_num_connect_candidates;
384 if (m_round_robin == i) ++m_round_robin;
386 m_peers.erase(i);
389 bool policy::is_connect_candidate(peer const& p, bool finished)
391 if (p.connection
392 || p.banned
393 || p.type == peer::not_connectable
394 || (p.seed && finished)
395 || p.failcount >= m_torrent->settings().max_failcount)
396 return false;
398 aux::session_impl& ses = m_torrent->session();
399 if (ses.m_port_filter.access(p.port) & port_filter::blocked)
400 return false;
401 return true;
404 policy::iterator policy::find_connect_candidate()
406 // too expensive
407 // INVARIANT_CHECK;
409 ptime now = time_now();
410 iterator candidate = m_peers.end();
412 int min_reconnect_time = m_torrent->settings().min_reconnect_time;
413 bool finished = m_torrent->is_finished();
414 address external_ip = m_torrent->session().external_address();
416 // don't bias any particular peers when seeding
417 if (finished || external_ip == address())
419 // set external_ip to a random value, to
420 // radomize which peers we prefer
421 address_v4::bytes_type bytes;
422 std::generate(bytes.begin(), bytes.end(), &std::rand);
423 external_ip = address_v4(bytes);
426 if (m_round_robin == m_peers.end()) m_round_robin = m_peers.begin();
428 #ifndef TORRENT_DISABLE_DHT
429 bool pinged = false;
430 #endif
432 for (int iterations = (std::min)(int(m_peers.size()), 300);
433 iterations > 0; --iterations)
435 if (m_round_robin == m_peers.end()) m_round_robin = m_peers.begin();
437 peer& pe = m_round_robin->second;
438 iterator current = m_round_robin;
440 #ifndef TORRENT_DISABLE_DHT
441 // try to send a DHT ping to this peer
442 // as well, to figure out if it supports
443 // DHT (uTorrent and BitComet doesn't
444 // advertise support)
445 if (!pinged && !pe.added_to_dht)
447 udp::endpoint node(pe.addr, pe.port);
448 m_torrent->session().add_dht_node(node);
449 pe.added_to_dht = true;
450 pinged = true;
452 #endif
453 // if the number of peers is growing large
454 // we need to start weeding.
455 // don't remove peers we're connected to
456 // don't remove peers we've never even tried
457 // don't remove banned peers unless they're 2
458 // hours old. They should remain banned for
459 // at least that long
460 // don't remove peers that we still can try again
461 if (pe.connection == 0
462 && pe.connected != min_time()
463 && (!pe.banned || now - pe.connected > hours(2))
464 && !is_connect_candidate(pe, finished)
465 && m_peers.size() >= m_torrent->settings().max_peerlist_size * 0.9)
467 erase_peer(m_round_robin++);
468 continue;
471 ++m_round_robin;
473 if (!is_connect_candidate(pe, finished)) continue;
475 if (candidate != m_peers.end()
476 && !compare_peer(candidate->second, pe, external_ip)) continue;
478 if (now - pe.connected <
479 seconds((pe.failcount + 1) * min_reconnect_time))
480 continue;
482 candidate = current;
485 #if defined TORRENT_LOGGING || defined TORRENT_VERBOSE_LOGGING
486 if (candidate != m_peers.end())
488 (*m_torrent->session().m_logger) << time_now_string()
489 << " *** FOUND CONNECTION CANDIDATE ["
490 " ip: " << candidate->second.ip() <<
491 " d: " << cidr_distance(external_ip, candidate->second.addr) <<
492 " external: " << external_ip <<
493 " t: " << total_seconds(time_now() - candidate->second.connected) <<
494 " ]\n";
496 #endif
498 return candidate;
501 void policy::pulse()
503 INVARIANT_CHECK;
505 // ------------------------
506 // upload shift
507 // ------------------------
509 // this part will shift downloads
510 // from peers that are seeds and peers
511 // that don't want to download from us
512 // to peers that cannot upload anything
513 // to us. The shifting will make sure
514 // that the torrent's share ratio
515 // will be maintained
517 // if the share ratio is 0 (infinite)
518 // m_available_free_upload isn't used
519 // because it isn't necessary
520 if (m_torrent->ratio() != 0.f)
522 // accumulate all the free download we get
523 // and add it to the available free upload
524 m_available_free_upload
525 += collect_free_download(
526 m_torrent->begin()
527 , m_torrent->end());
529 // distribute the free upload among the peers
530 m_available_free_upload = distribute_free_upload(
531 m_torrent->begin()
532 , m_torrent->end()
533 , m_available_free_upload);
537 bool policy::new_connection(peer_connection& c)
539 TORRENT_ASSERT(!c.is_local());
541 // INVARIANT_CHECK;
543 // if the connection comes from the tracker,
544 // it's probably just a NAT-check. Ignore the
545 // num connections constraint then.
547 // TODO: only allow _one_ connection to use this
548 // override at a time
549 error_code ec;
550 TORRENT_ASSERT(c.remote() == c.get_socket()->remote_endpoint(ec) || ec);
552 aux::session_impl& ses = m_torrent->session();
554 if (m_torrent->num_peers() >= m_torrent->max_connections()
555 && ses.num_connections() >= ses.max_connections()
556 && c.remote().address() != m_torrent->current_tracker().address())
558 c.disconnect("too many connections, refusing incoming connection");
559 return false;
562 #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
563 if (c.remote().address() == m_torrent->current_tracker().address())
565 m_torrent->debug_log("overriding connection limit for tracker NAT-check");
567 #endif
569 iterator i;
571 if (m_torrent->settings().allow_multiple_connections_per_ip)
573 tcp::endpoint remote = c.remote();
574 std::pair<iterator, iterator> range = m_peers.equal_range(remote.address());
575 i = std::find_if(range.first, range.second, match_peer_endpoint(remote));
577 if (i == range.second) i = m_peers.end();
579 else
581 i = m_peers.find(c.remote().address());
584 if (i != m_peers.end())
586 if (i->second.banned)
588 c.disconnect("ip address banned, closing");
589 return false;
592 if (i->second.connection != 0)
594 boost::shared_ptr<socket_type> other_socket
595 = i->second.connection->get_socket();
596 boost::shared_ptr<socket_type> this_socket
597 = c.get_socket();
599 error_code ec1;
600 error_code ec2;
601 bool self_connection =
602 other_socket->remote_endpoint(ec2) == this_socket->local_endpoint(ec1)
603 || other_socket->local_endpoint(ec2) == this_socket->remote_endpoint(ec1);
605 if (ec1)
607 c.disconnect(ec1.message().c_str());
608 return false;
611 if (self_connection)
613 c.disconnect("connected to ourselves", 1);
614 i->second.connection->disconnect("connected to ourselves", 1);
615 return false;
618 TORRENT_ASSERT(i->second.connection != &c);
619 // the new connection is a local (outgoing) connection
620 // or the current one is already connected
621 if (ec2)
623 i->second.connection->disconnect(ec2.message().c_str());
625 else if (!i->second.connection->is_connecting() || c.is_local())
627 c.disconnect("duplicate connection, closing");
628 return false;
630 else
632 #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
633 m_torrent->debug_log("duplicate connection. existing connection"
634 " is connecting and this connection is incoming. closing existing "
635 "connection in favour of this one");
636 #endif
637 i->second.connection->disconnect("incoming duplicate connection "
638 "with higher priority, closing");
642 if (m_num_connect_candidates > 0)
643 --m_num_connect_candidates;
645 else
647 // we don't have any info about this peer.
648 // add a new entry
649 error_code ec;
650 TORRENT_ASSERT(c.remote() == c.get_socket()->remote_endpoint(ec) || ec);
652 if (int(m_peers.size()) >= m_torrent->settings().max_peerlist_size)
654 c.disconnect("peer list size exceeded, refusing incoming connection");
655 return false;
658 peer p(c.remote(), peer::not_connectable, 0);
659 i = m_peers.insert(std::make_pair(c.remote().address(), p));
660 #ifndef TORRENT_DISABLE_GEO_IP
661 int as = ses.as_for_ip(c.remote().address());
662 #ifndef NDEBUG
663 i->second.inet_as_num = as;
664 #endif
665 i->second.inet_as = ses.lookup_as(as);
666 #endif
669 c.set_peer_info(&i->second);
670 TORRENT_ASSERT(i->second.connection == 0);
671 c.add_stat(i->second.prev_amount_download, i->second.prev_amount_upload);
672 i->second.prev_amount_download = 0;
673 i->second.prev_amount_upload = 0;
674 i->second.connection = &c;
675 TORRENT_ASSERT(i->second.connection);
676 if (!c.fast_reconnect())
677 i->second.connected = time_now();
678 return true;
681 bool policy::update_peer_port(int port, policy::peer* p, int src)
683 TORRENT_ASSERT(p != 0);
684 TORRENT_ASSERT(p->connection);
686 if (p->port == port) return true;
688 if (m_torrent->settings().allow_multiple_connections_per_ip)
690 tcp::endpoint remote(p->addr, port);
691 std::pair<iterator, iterator> range = m_peers.equal_range(remote.address());
692 iterator i = std::find_if(range.first, range.second
693 , match_peer_endpoint(remote));
694 if (i != m_peers.end())
696 policy::peer& pp = i->second;
697 if (pp.connection)
699 p->connection->disconnect("duplicate connection");
700 return false;
702 erase_peer(i);
705 else
707 TORRENT_ASSERT(m_peers.count(p->addr) == 1);
709 bool was_conn_cand = is_connect_candidate(*p, m_torrent->is_finished());
710 p->port = port;
711 p->source |= src;
713 if (was_conn_cand != is_connect_candidate(*p, m_torrent->is_finished()))
715 m_num_connect_candidates += was_conn_cand ? -1 : 1;
716 if (m_num_connect_candidates < 0) m_num_connect_candidates = 0;
718 return true;
721 bool policy::has_peer(policy::peer const* p) const
723 // find p in m_peers
724 for (std::multimap<address, peer>::const_iterator i = m_peers.begin()
725 , end(m_peers.end()); i != end; ++i)
727 if (&i->second == p) return true;
729 return false;
732 policy::peer* policy::peer_from_tracker(tcp::endpoint const& remote, peer_id const& pid
733 , int src, char flags)
735 // way too expensive
736 //INVARIANT_CHECK;
738 // just ignore the obviously invalid entries
739 if (remote.address() == address() || remote.port() == 0)
740 return 0;
742 aux::session_impl& ses = m_torrent->session();
744 port_filter const& pf = ses.m_port_filter;
745 if (pf.access(remote.port()) & port_filter::blocked)
747 if (ses.m_alerts.should_post<peer_blocked_alert>())
748 ses.m_alerts.post_alert(peer_blocked_alert(remote.address()));
749 return 0;
752 iterator i;
754 if (m_torrent->settings().allow_multiple_connections_per_ip)
756 std::pair<iterator, iterator> range = m_peers.equal_range(remote.address());
757 i = std::find_if(range.first, range.second, match_peer_endpoint(remote));
758 if (i == range.second) i = m_peers.end();
760 else
762 i = m_peers.find(remote.address());
765 if (i == m_peers.end())
767 // if the IP is blocked, don't add it
768 if (ses.m_ip_filter.access(remote.address()) & ip_filter::blocked)
770 if (ses.m_alerts.should_post<peer_blocked_alert>())
772 ses.m_alerts.post_alert(peer_blocked_alert(remote.address()));
774 return 0;
777 if (int(m_peers.size()) >= m_torrent->settings().max_peerlist_size)
778 return 0;
780 // we don't have any info about this peer.
781 // add a new entry
782 i = m_peers.insert(std::make_pair(remote.address()
783 , peer(remote, peer::connectable, src)));
784 #ifndef TORRENT_DISABLE_ENCRYPTION
785 if (flags & 0x01) i->second.pe_support = true;
786 #endif
787 if (flags & 0x02)
789 i->second.seed = true;
790 ++m_num_seeds;
793 #ifndef TORRENT_DISABLE_GEO_IP
794 int as = ses.as_for_ip(remote.address());
795 #ifndef NDEBUG
796 i->second.inet_as_num = as;
797 #endif
798 i->second.inet_as = ses.lookup_as(as);
799 #endif
800 if (is_connect_candidate(i->second, m_torrent->is_finished()))
801 ++m_num_connect_candidates;
803 else
805 bool was_conn_cand = is_connect_candidate(i->second, m_torrent->is_finished());
807 i->second.type = peer::connectable;
809 i->second.set_ip(remote);
810 i->second.source |= src;
812 // if this peer has failed before, decrease the
813 // counter to allow it another try, since somebody
814 // else is appearantly able to connect to it
815 // only trust this if it comes from the tracker
816 if (i->second.failcount > 0 && src == peer_info::tracker)
817 --i->second.failcount;
819 // if we're connected to this peer
820 // we already know if it's a seed or not
821 // so we don't have to trust this source
822 if ((flags & 0x02) && !i->second.connection)
824 if (!i->second.seed) ++m_num_seeds;
825 i->second.seed = true;
828 #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
829 if (i->second.connection)
831 // this means we're already connected
832 // to this peer. don't connect to
833 // it again.
835 m_torrent->debug_log("already connected to peer: " + remote.address().to_string() + ":"
836 + boost::lexical_cast<std::string>(remote.port()) + " "
837 + boost::lexical_cast<std::string>(i->second.connection->pid()));
839 TORRENT_ASSERT(i->second.connection->associated_torrent().lock().get() == m_torrent);
841 #endif
843 if (was_conn_cand != is_connect_candidate(i->second, m_torrent->is_finished()))
845 m_num_connect_candidates += was_conn_cand ? -1 : 1;
846 if (m_num_connect_candidates < 0) m_num_connect_candidates = 0;
850 return &i->second;
853 // this is called when we are unchoked by a peer
854 // i.e. a peer lets us know that we will receive
855 // data from now on
856 void policy::unchoked(peer_connection& c)
858 // INVARIANT_CHECK;
859 if (c.is_interesting())
861 request_a_block(*m_torrent, c);
862 c.send_block_requests();
866 // called when a peer is interested in us
867 void policy::interested(peer_connection& c)
869 // INVARIANT_CHECK;
871 TORRENT_ASSERT(std::find_if(m_peers.begin(), m_peers.end()
872 , boost::bind<bool>(std::equal_to<peer_connection*>(), bind(&peer::connection
873 , bind(&iterator::value_type::second, _1)), &c)) != m_peers.end());
875 aux::session_impl& ses = m_torrent->session();
877 // if the peer is choked and we have upload slots left,
878 // then unchoke it. Another condition that has to be met
879 // is that the torrent doesn't keep track of the individual
880 // up/down ratio for each peer (ratio == 0) or (if it does
881 // keep track) this particular connection isn't a leecher.
882 // If the peer was choked because it was leeching, don't
883 // unchoke it again.
884 // The exception to this last condition is if we're a seed.
885 // In that case we don't care if people are leeching, they
886 // can't pay for their downloads anyway.
887 if (c.is_choked()
888 && ses.num_uploads() < ses.max_uploads()
889 && (m_torrent->ratio() == 0
890 || c.share_diff() >= -free_upload_amount
891 || m_torrent->is_finished()))
893 ses.unchoke_peer(c);
895 #if defined TORRENT_VERBOSE_LOGGING
896 else if (c.is_choked())
898 std::string reason;
899 if (ses.num_uploads() >= ses.max_uploads())
901 reason = "the number of uploads ("
902 + boost::lexical_cast<std::string>(ses.num_uploads())
903 + ") is more than or equal to the limit ("
904 + boost::lexical_cast<std::string>(ses.max_uploads())
905 + ")";
907 else
909 reason = "the share ratio ("
910 + boost::lexical_cast<std::string>(c.share_diff())
911 + ") is <= free_upload_amount ("
912 + boost::lexical_cast<std::string>(int(free_upload_amount))
913 + ") and we are not seeding and the ratio ("
914 + boost::lexical_cast<std::string>(m_torrent->ratio())
915 + ")is non-zero";
917 (*c.m_logger) << time_now_string() << " DID NOT UNCHOKE [ " << reason << " ]\n";
919 #endif
922 // called when a peer is no longer interested in us
923 void policy::not_interested(peer_connection& c)
925 INVARIANT_CHECK;
927 if (m_torrent->ratio() != 0.f)
929 TORRENT_ASSERT(c.share_diff() < (std::numeric_limits<size_type>::max)());
930 size_type diff = c.share_diff();
931 if (diff > 0 && c.is_seed())
933 // the peer is a seed and has sent
934 // us more than we have sent it back.
935 // consider the download as free download
936 m_available_free_upload += diff;
937 c.add_free_upload(-diff);
941 if (!c.is_choked())
943 c.send_choke();
944 --m_num_unchoked;
946 if (m_torrent->is_seed()) seed_unchoke_one_peer();
947 else unchoke_one_peer();
952 bool policy::unchoke_one_peer()
954 INVARIANT_CHECK;
956 iterator p = find_unchoke_candidate();
957 if (p == m_peers.end()) return false;
958 TORRENT_ASSERT(p->connection);
959 TORRENT_ASSERT(!p->connection->is_disconnecting());
961 TORRENT_ASSERT(p->connection->is_choked());
962 p->connection->send_unchoke();
963 p->last_optimistically_unchoked = time_now();
964 ++m_num_unchoked;
965 return true;
968 void policy::choke_one_peer()
970 INVARIANT_CHECK;
972 iterator p = find_choke_candidate();
973 if (p == m_peers.end()) return;
974 TORRENT_ASSERT(p->connection);
975 TORRENT_ASSERT(!p->connection->is_disconnecting());
976 TORRENT_ASSERT(!p->connection->is_choked());
977 p->connection->send_choke();
978 --m_num_unchoked;
981 bool policy::connect_one_peer()
983 // INVARIANT_CHECK;
985 TORRENT_ASSERT(m_torrent->want_more_peers());
987 iterator p = find_connect_candidate();
988 if (p == m_peers.end()) return false;
990 TORRENT_ASSERT(!p->second.banned);
991 TORRENT_ASSERT(!p->second.connection);
992 TORRENT_ASSERT(p->second.type == peer::connectable);
994 TORRENT_ASSERT(is_connect_candidate(p->second, m_torrent->is_finished()));
995 if (!m_torrent->connect_to_peer(&p->second))
997 ++p->second.failcount;
998 return false;
1000 TORRENT_ASSERT(!is_connect_candidate(p->second, m_torrent->is_finished()));
1001 --m_num_connect_candidates;
1002 return true;
1005 // this is called whenever a peer connection is closed
1006 void policy::connection_closed(const peer_connection& c)
1008 // too expensive
1009 // INVARIANT_CHECK;
1011 peer* p = c.peer_info_struct();
1013 TORRENT_ASSERT((std::find_if(
1014 m_peers.begin()
1015 , m_peers.end()
1016 , match_peer_connection(c))
1017 != m_peers.end()) == (p != 0));
1019 // if we couldn't find the connection in our list, just ignore it.
1020 if (p == 0) return;
1022 TORRENT_ASSERT(p->connection == &c);
1024 p->connection = 0;
1025 p->optimistically_unchoked = false;
1027 // if fast reconnect is true, we won't
1028 // update the timestamp, and it will remain
1029 // the time when we initiated the connection.
1030 if (!c.fast_reconnect())
1031 p->connected = time_now();
1033 if (c.failed())
1035 ++p->failcount;
1036 // p->connected = time_now();
1039 if (is_connect_candidate(*p, m_torrent->is_finished()))
1040 ++m_num_connect_candidates;
1042 // if the share ratio is 0 (infinite), the
1043 // m_available_free_upload isn't used,
1044 // because it isn't necessary.
1045 if (m_torrent->ratio() != 0.f)
1047 TORRENT_ASSERT(c.associated_torrent().lock().get() == m_torrent);
1048 TORRENT_ASSERT(c.share_diff() < (std::numeric_limits<size_type>::max)());
1049 m_available_free_upload += c.share_diff();
1051 TORRENT_ASSERT(p->prev_amount_upload == 0);
1052 TORRENT_ASSERT(p->prev_amount_download == 0);
1053 p->prev_amount_download += c.statistics().total_payload_download();
1054 p->prev_amount_upload += c.statistics().total_payload_upload();
1057 void policy::peer_is_interesting(peer_connection& c)
1059 // INVARIANT_CHECK;
1061 c.send_interested();
1062 if (c.has_peer_choked()
1063 && c.allowed_fast().empty())
1064 return;
1065 request_a_block(*m_torrent, c);
1066 c.send_block_requests();
1069 #ifndef NDEBUG
1070 bool policy::has_connection(const peer_connection* c)
1072 // too expensive
1073 // INVARIANT_CHECK;
1075 TORRENT_ASSERT(c);
1076 error_code ec;
1077 TORRENT_ASSERT(c->remote() == c->get_socket()->remote_endpoint(ec) || ec);
1079 return std::find_if(
1080 m_peers.begin()
1081 , m_peers.end()
1082 , match_peer_connection(*c)) != m_peers.end();
1085 void policy::check_invariant() const
1087 TORRENT_ASSERT(m_num_connect_candidates >= 0);
1088 if (m_torrent->is_aborted()) return;
1090 int connected_peers = 0;
1092 int total_connections = 0;
1093 int nonempty_connections = 0;
1095 std::set<tcp::endpoint> unique_test;
1096 for (const_iterator i = m_peers.begin();
1097 i != m_peers.end(); ++i)
1099 peer const& p = i->second;
1100 #ifndef TORRENT_DISABLE_GEO_IP
1101 TORRENT_ASSERT(p.inet_as == 0 || p.inet_as->first == p.inet_as_num);
1102 #endif
1103 if (!m_torrent->settings().allow_multiple_connections_per_ip)
1105 TORRENT_ASSERT(m_peers.count(p.addr) == 1);
1107 else
1109 TORRENT_ASSERT(unique_test.count(p.ip()) == 0);
1110 unique_test.insert(p.ip());
1111 TORRENT_ASSERT(i->first == p.addr);
1112 // TORRENT_ASSERT(p.connection == 0 || p.ip() == p.connection->remote());
1114 ++total_connections;
1115 if (!p.connection)
1117 continue;
1119 TORRENT_ASSERT(p.prev_amount_upload == 0);
1120 TORRENT_ASSERT(p.prev_amount_download == 0);
1121 if (p.optimistically_unchoked)
1123 TORRENT_ASSERT(p.connection);
1124 TORRENT_ASSERT(!p.connection->is_choked());
1126 TORRENT_ASSERT(p.connection->peer_info_struct() == 0
1127 || p.connection->peer_info_struct() == &p);
1128 ++nonempty_connections;
1129 if (!p.connection->is_disconnecting())
1130 ++connected_peers;
1133 int num_torrent_peers = 0;
1134 for (torrent::const_peer_iterator i = m_torrent->begin();
1135 i != m_torrent->end(); ++i)
1137 if ((*i)->is_disconnecting()) continue;
1138 // ignore web_peer_connections since they are not managed
1139 // by the policy class
1140 if (dynamic_cast<web_peer_connection*>(*i)) continue;
1141 ++num_torrent_peers;
1144 if (m_torrent->has_picker())
1146 piece_picker& p = m_torrent->picker();
1147 std::vector<piece_picker::downloading_piece> downloaders = p.get_download_queue();
1149 std::set<void*> peer_set;
1150 std::vector<void*> peers;
1151 for (std::vector<piece_picker::downloading_piece>::iterator i = downloaders.begin()
1152 , end(downloaders.end()); i != end; ++i)
1154 p.get_downloaders(peers, i->index);
1155 std::copy(peers.begin(), peers.end()
1156 , std::insert_iterator<std::set<void*> >(peer_set, peer_set.begin()));
1159 for (std::set<void*>::iterator i = peer_set.begin()
1160 , end(peer_set.end()); i != end; ++i)
1162 policy::peer* p = static_cast<policy::peer*>(*i);
1163 if (p == 0) continue;
1164 if (p->connection == 0) continue;
1165 TORRENT_ASSERT(std::find_if(m_peers.begin(), m_peers.end()
1166 , match_peer_connection(*p->connection)) != m_peers.end());
1170 // this invariant is a bit complicated.
1171 // the usual case should be that connected_peers
1172 // == num_torrent_peers. But when there's an incoming
1173 // connection, it will first be added to the policy
1174 // and then be added to the torrent.
1175 // When there's an outgoing connection, it will first
1176 // be added to the torrent and then to the policy.
1177 // that's why the two second cases are in there.
1179 TORRENT_ASSERT(connected_peers == num_torrent_peers
1180 || (connected_peers == num_torrent_peers + 1
1181 && connected_peers > 0)
1182 || (connected_peers + 1 == num_torrent_peers
1183 && num_torrent_peers > 0));
1186 #endif
1188 policy::peer::peer(const tcp::endpoint& ip_, peer::connection_type t, int src)
1189 : prev_amount_upload(0)
1190 , prev_amount_download(0)
1191 , addr(ip_.address())
1192 , last_optimistically_unchoked(min_time())
1193 , connected(min_time())
1194 , connection(0)
1195 #ifndef TORRENT_DISABLE_GEO_IP
1196 , inet_as(0)
1197 #endif
1198 , port(ip_.port())
1199 , failcount(0)
1200 , trust_points(0)
1201 , source(src)
1202 , hashfails(0)
1203 , type(t)
1204 , fast_reconnects(0)
1205 #ifndef TORRENT_DISABLE_ENCRYPTION
1206 , pe_support(true)
1207 #endif
1208 , optimistically_unchoked(false)
1209 , seed(false)
1210 , on_parole(false)
1211 , banned(false)
1212 #ifndef TORRENT_DISABLE_DHT
1213 , added_to_dht(false)
1214 #endif
1216 TORRENT_ASSERT((src & 0xff) == src);
1217 TORRENT_ASSERT(connected < time_now());
1220 size_type policy::peer::total_download() const
1222 if (connection != 0)
1224 TORRENT_ASSERT(prev_amount_download == 0);
1225 return connection->statistics().total_payload_download();
1227 else
1229 return prev_amount_download;
1233 size_type policy::peer::total_upload() const
1235 if (connection != 0)
1237 TORRENT_ASSERT(prev_amount_upload == 0);
1238 return connection->statistics().total_payload_upload();
1240 else
1242 return prev_amount_upload;
1246 // this returns true if lhs is a better connect candidate than rhs
1247 bool policy::compare_peer(policy::peer const& lhs, policy::peer const& rhs
1248 , address const& external_ip) const
1250 // prefer peers with lower failcount
1251 if (lhs.failcount != rhs.failcount)
1252 return lhs.failcount < rhs.failcount;
1254 // Local peers should always be tried first
1255 bool lhs_local = is_local(lhs.addr);
1256 bool rhs_local = is_local(rhs.addr);
1257 if (lhs_local != rhs_local) return lhs_local > rhs_local;
1259 if (lhs.connected != rhs.connected)
1260 return lhs.connected < rhs.connected;
1262 #ifndef TORRENT_DISABLE_GEO_IP
1263 // don't bias fast peers when seeding
1264 if (!m_torrent->is_finished() && m_torrent->session().has_asnum_db())
1266 int lhs_as = lhs.inet_as ? lhs.inet_as->second : 0;
1267 int rhs_as = rhs.inet_as ? rhs.inet_as->second : 0;
1268 if (lhs_as != rhs_as) return lhs_as > rhs_as;
1270 #endif
1271 int lhs_distance = cidr_distance(external_ip, lhs.addr);
1272 int rhs_distance = cidr_distance(external_ip, rhs.addr);
1273 if (lhs_distance < rhs_distance) return true;
1274 return false;