3 Copyright (c) 2003, Arvid Norberg
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
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"
38 #pragma warning(push, 1)
41 #include <boost/bind.hpp>
42 #include <boost/utility.hpp>
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"
60 #include "libtorrent/bt_peer_connection.hpp"
65 class peer_connection
;
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)
90 TORRENT_ASSERT(diff
> 0);
91 (*i
)->add_free_upload(-diff
);
93 TORRENT_ASSERT(accumulator
> 0);
95 TORRENT_ASSERT(accumulator
>= 0);
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
;
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
)());
115 if (!(*i
)->is_peer_interested() || (*i
)->share_diff() >= 0) continue;
119 if (num_peers
== 0) return free_upload
;
120 size_type upload_share
;
123 upload_share
= (std::min
)(free_upload
, total_diff
) / num_peers
;
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
;
141 struct match_peer_endpoint
143 match_peer_endpoint(tcp::endpoint
const& ep
)
147 bool operator()(std::pair
<const address
, policy::peer
> const& p
) const
148 { return p
.second
.ip
== m_ep
; }
150 tcp::endpoint
const& m_ep
;
154 struct match_peer_connection
156 match_peer_connection(peer_connection
const& 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
;
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";
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.
218 TORRENT_ASSERT(c
.remote() == c
.get_socket()->remote_endpoint(ec
) || ec
);
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
);
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";
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())
289 TORRENT_ASSERT(p
.num_peers(*i
) > 0);
290 busy_pieces
.push_back(*i
);
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
299 TORRENT_ASSERT(p
.num_peers(*i
) == 1);
300 TORRENT_ASSERT(p
.is_requested(*i
));
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.
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
));
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
));
327 TORRENT_ASSERT(p
.is_requested(*i
));
328 TORRENT_ASSERT(p
.num_peers(*i
) > 0);
332 policy::policy(torrent
* t
)
333 : m_round_robin(m_peers
.end())
335 , m_available_free_upload(0)
336 , m_num_connect_candidates(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();
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
.ip
.address()) & ip_filter::blocked
) == 0)
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
.ip
.address()));
361 TORRENT_ASSERT(i
->second
.connection
== 0
362 || i
->second
.connection
->peer_info_struct() == 0);
366 if (ses
.m_alerts
.should_post
<peer_blocked_alert
>())
367 ses
.m_alerts
.post_alert(peer_blocked_alert(i
->second
.ip
.address()));
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
;
389 bool policy::is_connect_candidate(peer
const& p
, bool finished
)
393 || p
.type
== peer::not_connectable
394 || (p
.seed
&& finished
)
395 || p
.failcount
>= m_torrent
->settings().max_failcount
)
398 aux::session_impl
& ses
= m_torrent
->session();
399 if (ses
.m_port_filter
.access(p
.ip
.port()) & port_filter::blocked
)
404 policy::iterator
policy::find_connect_candidate()
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
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
.ip
.address(), pe
.ip
.port());
448 m_torrent
->session().add_dht_node(node
);
449 pe
.added_to_dht
= true;
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
++);
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
))
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
.ip
.address()) <<
492 " external: " << external_ip
<<
493 " t: " << total_seconds(time_now() - candidate
->second
.connected
) <<
505 // ------------------------
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(
529 // distribute the free upload among the peers
530 m_available_free_upload
= distribute_free_upload(
533 , m_available_free_upload
);
537 bool policy::new_connection(peer_connection
& c
)
539 TORRENT_ASSERT(!c
.is_local());
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
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");
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");
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();
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");
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
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
);
607 c
.disconnect(ec1
.message().c_str());
613 c
.disconnect("connected to ourselves", 1);
614 i
->second
.connection
->disconnect("connected to ourselves", 1);
618 TORRENT_ASSERT(i
->second
.connection
!= &c
);
619 // the new connection is a local (outgoing) connection
620 // or the current one is already connected
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");
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");
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
;
647 // we don't have any info about this peer.
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");
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());
663 i
->second
.inet_as_num
= as
;
665 i
->second
.inet_as
= ses
.lookup_as(as
);
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();
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
->ip
.port() == port
) return true;
688 if (m_torrent
->settings().allow_multiple_connections_per_ip
)
690 tcp::endpoint
remote(p
->ip
.address(), 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
;
699 p
->connection
->disconnect("duplicate connection");
707 TORRENT_ASSERT(m_peers
.count(p
->ip
.address()) == 1);
709 bool was_conn_cand
= is_connect_candidate(*p
, m_torrent
->is_finished());
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;
721 bool policy::has_peer(policy::peer
const* p
) const
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;
732 policy::peer
* policy::peer_from_tracker(tcp::endpoint
const& remote
, peer_id
const& pid
733 , int src
, char flags
)
738 // just ignore the obviously invalid entries
739 if (remote
.address() == address() || remote
.port() == 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()));
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();
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()));
777 if (int(m_peers
.size()) >= m_torrent
->settings().max_peerlist_size
)
780 // we don't have any info about this peer.
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;
789 i
->second
.seed
= true;
793 #ifndef TORRENT_DISABLE_GEO_IP
794 int as
= ses
.as_for_ip(remote
.address());
796 i
->second
.inet_as_num
= as
;
798 i
->second
.inet_as
= ses
.lookup_as(as
);
800 if (is_connect_candidate(i
->second
, m_torrent
->is_finished()))
801 ++m_num_connect_candidates
;
805 bool was_conn_cand
= is_connect_candidate(i
->second
, m_torrent
->is_finished());
807 i
->second
.type
= peer::connectable
;
809 i
->second
.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
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
);
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;
853 // this is called when we are unchoked by a peer
854 // i.e. a peer lets us know that we will receive
856 void policy::unchoked(peer_connection
& c
)
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
)
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
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.
888 && ses
.num_uploads() < ses
.max_uploads()
889 && (m_torrent
->ratio() == 0
890 || c
.share_diff() >= -free_upload_amount
891 || m_torrent
->is_finished()))
895 #if defined TORRENT_VERBOSE_LOGGING
896 else if (c
.is_choked())
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())
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())
917 (*c
.m_logger
) << time_now_string() << " DID NOT UNCHOKE [ " << reason
<< " ]\n";
922 // called when a peer is no longer interested in us
923 void policy::not_interested(peer_connection
& c
)
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
);
946 if (m_torrent->is_seed()) seed_unchoke_one_peer();
947 else unchoke_one_peer();
952 bool policy::unchoke_one_peer()
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();
968 void policy::choke_one_peer()
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();
981 bool policy::connect_one_peer()
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
;
1000 TORRENT_ASSERT(!is_connect_candidate(p
->second
, m_torrent
->is_finished()));
1001 --m_num_connect_candidates
;
1005 // this is called whenever a peer connection is closed
1006 void policy::connection_closed(const peer_connection
& c
)
1011 peer
* p
= c
.peer_info_struct();
1013 TORRENT_ASSERT((std::find_if(
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.
1022 TORRENT_ASSERT(p
->connection
== &c
);
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();
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
)
1061 c
.send_interested();
1062 if (c
.has_peer_choked()
1063 && c
.allowed_fast().empty())
1065 request_a_block(*m_torrent
, c
);
1066 c
.send_block_requests();
1070 bool policy::has_connection(const peer_connection
* c
)
1077 TORRENT_ASSERT(c
->remote() == c
->get_socket()->remote_endpoint(ec
) || ec
);
1079 return std::find_if(
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
);
1103 if (!m_torrent
->settings().allow_multiple_connections_per_ip
)
1105 TORRENT_ASSERT(m_peers
.count(p
.ip
.address()) == 1);
1109 TORRENT_ASSERT(unique_test
.count(p
.ip
) == 0);
1110 unique_test
.insert(p
.ip
);
1111 TORRENT_ASSERT(i
->first
== p
.ip
.address());
1112 // TORRENT_ASSERT(p.connection == 0 || p.ip == p.connection->remote());
1114 ++total_connections
;
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())
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));
1188 policy::peer::peer(const tcp::endpoint
& ip_
, peer::connection_type t
, int src
)
1190 #ifndef TORRENT_DISABLE_GEO_IP
1198 , fast_reconnects(0)
1199 #ifndef TORRENT_DISABLE_ENCRYPTION
1202 , optimistically_unchoked(false)
1206 #ifndef TORRENT_DISABLE_DHT
1207 , added_to_dht(false)
1210 , prev_amount_upload(0)
1211 , prev_amount_download(0)
1212 , last_optimistically_unchoked(min_time())
1213 , connected(min_time())
1215 TORRENT_ASSERT((src
& 0xff) == src
);
1216 TORRENT_ASSERT(connected
< time_now());
1219 size_type
policy::peer::total_download() const
1221 if (connection
!= 0)
1223 TORRENT_ASSERT(prev_amount_download
== 0);
1224 return connection
->statistics().total_payload_download();
1228 return prev_amount_download
;
1232 size_type
policy::peer::total_upload() const
1234 if (connection
!= 0)
1236 TORRENT_ASSERT(prev_amount_upload
== 0);
1237 return connection
->statistics().total_payload_upload();
1241 return prev_amount_upload
;
1245 // this returns true if lhs is a better connect candidate than rhs
1246 bool policy::compare_peer(policy::peer
const& lhs
, policy::peer
const& rhs
1247 , address
const& external_ip
) const
1249 // prefer peers with lower failcount
1250 if (lhs
.failcount
!= rhs
.failcount
)
1251 return lhs
.failcount
< rhs
.failcount
;
1253 // Local peers should always be tried first
1254 bool lhs_local
= is_local(lhs
.ip
.address());
1255 bool rhs_local
= is_local(rhs
.ip
.address());
1256 if (lhs_local
!= rhs_local
) return lhs_local
> rhs_local
;
1258 if (lhs
.connected
!= rhs
.connected
)
1259 return lhs
.connected
< rhs
.connected
;
1261 #ifndef TORRENT_DISABLE_GEO_IP
1262 // don't bias fast peers when seeding
1263 if (!m_torrent
->is_finished() && m_torrent
->session().has_asnum_db())
1265 int lhs_as
= lhs
.inet_as
? lhs
.inet_as
->second
: 0;
1266 int rhs_as
= rhs
.inet_as
? rhs
.inet_as
->second
: 0;
1267 if (lhs_as
!= rhs_as
) return lhs_as
> rhs_as
;
1270 int lhs_distance
= cidr_distance(external_ip
, lhs
.ip
.address());
1271 int rhs_distance
= cidr_distance(external_ip
, rhs
.ip
.address());
1272 if (lhs_distance
< rhs_distance
) return true;