~ubuntu-branches/ubuntu/maverick/libtorrent-rasterbar/maverick

« back to all changes in this revision

Viewing changes to src/policy.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Sauthier
  • Date: 2010-08-10 12:59:37 UTC
  • mfrom: (1.3.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20100810125937-jbcmmf17y8yo9hgz
Tags: 0.15.0-0ubuntu1
* New upstream version.
* debian/patches/100_fix_html_docs.patch: refreshed.
* debian/control: bump up standards-version to 3.9.1 (no changes).

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
 
33
33
#include "libtorrent/pch.hpp"
34
34
 
35
 
#include <iostream>
36
 
 
37
35
#ifdef _MSC_VER
38
36
#pragma warning(push, 1)
39
37
#endif
72
70
{
73
71
        using namespace libtorrent;
74
72
 
75
 
        size_type collect_free_download(
76
 
                torrent::peer_iterator start
77
 
                , torrent::peer_iterator end)
78
 
        {
79
 
                size_type accumulator = 0;
80
 
                for (torrent::peer_iterator i = start; i != end; ++i)
81
 
                {
82
 
                        // if the peer is interested in us, it means it may
83
 
                        // want to trade it's surplus uploads for downloads itself
84
 
                        // (and we should not consider it free). If the share diff is
85
 
                        // negative, there's no free download to get from this peer.
86
 
                        size_type diff = (*i)->share_diff();
87
 
                        TORRENT_ASSERT(diff < (std::numeric_limits<size_type>::max)());
88
 
                        if ((*i)->is_peer_interested() || diff <= 0)
89
 
                                continue;
90
 
 
91
 
                        TORRENT_ASSERT(diff > 0);
92
 
                        (*i)->add_free_upload(-diff);
93
 
                        accumulator += diff;
94
 
                        TORRENT_ASSERT(accumulator > 0);
95
 
                }
96
 
                TORRENT_ASSERT(accumulator >= 0);
97
 
                return accumulator;
98
 
        }
99
 
 
100
 
 
101
 
        // returns the amount of free upload left after
102
 
        // it has been distributed to the peers
103
 
        size_type distribute_free_upload(
104
 
                torrent::peer_iterator start
105
 
                , torrent::peer_iterator end
106
 
                , size_type free_upload)
107
 
        {
108
 
                if (free_upload <= 0) return free_upload;
109
 
                int num_peers = 0;
110
 
                size_type total_diff = 0;
111
 
                for (torrent::peer_iterator i = start; i != end; ++i)
112
 
                {
113
 
                        size_type d = (*i)->share_diff();
114
 
                        TORRENT_ASSERT(d < (std::numeric_limits<size_type>::max)());
115
 
                        total_diff += d;
116
 
                        if (!(*i)->is_peer_interested() || (*i)->share_diff() >= 0) continue;
117
 
                        ++num_peers;
118
 
                }
119
 
 
120
 
                if (num_peers == 0) return free_upload;
121
 
                size_type upload_share;
122
 
                if (total_diff >= 0)
123
 
                {
124
 
                        upload_share = (std::min)(free_upload, total_diff) / num_peers;
125
 
                }
126
 
                else
127
 
                {
128
 
                        upload_share = (free_upload + total_diff) / num_peers;
129
 
                }
130
 
                if (upload_share < 0) return free_upload;
131
 
 
132
 
                for (torrent::peer_iterator i = start; i != end; ++i)
133
 
                {
134
 
                        peer_connection* p = *i;
135
 
                        if (!p->is_peer_interested() || p->share_diff() >= 0) continue;
136
 
                        p->add_free_upload(upload_share);
137
 
                        free_upload -= upload_share;
138
 
                }
139
 
                return free_upload;
140
 
        }
141
 
 
142
73
        struct match_peer_endpoint
143
74
        {
144
75
                match_peer_endpoint(tcp::endpoint const& ep)
145
76
                        : m_ep(ep)
146
77
                {}
147
78
 
148
 
                bool operator()(std::pair<const address, policy::peer> const& p) const
149
 
                { return p.second.addr == m_ep.address() && p.second.port == m_ep.port(); }
 
79
                bool operator()(policy::peer const* p) const
 
80
                { return p->address() == m_ep.address() && p->port == m_ep.port(); }
150
81
 
151
82
                tcp::endpoint const& m_ep;
152
83
        };
154
85
#ifdef TORRENT_DEBUG
155
86
        struct match_peer_connection
156
87
        {
157
 
                match_peer_connection(peer_connection const& c)
158
 
                        : m_conn(c)
159
 
                {}
160
 
 
161
 
                bool operator()(std::pair<const address, policy::peer> const& p) const
 
88
                match_peer_connection(peer_connection const& c) : m_conn(c) {}
 
89
 
 
90
                bool operator()(policy::peer const* p) const
 
91
                { return p->connection == &m_conn; }
 
92
 
 
93
                peer_connection const& m_conn;
 
94
        };
 
95
 
 
96
        struct match_peer_connection_or_endpoint
 
97
        {
 
98
                match_peer_connection_or_endpoint(peer_connection const& c) : m_conn(c) {}
 
99
 
 
100
                bool operator()(policy::peer const* p) const
162
101
                {
163
 
                        return p.second.connection == &m_conn
164
 
                                || (p.second.ip() == m_conn.remote()
165
 
                                        && p.second.type == policy::peer::connectable);
 
102
                        return p->connection == &m_conn
 
103
                                || (p->ip() == m_conn.remote()
 
104
                                        && p->connectable);
166
105
                }
167
106
 
168
107
                peer_connection const& m_conn;
173
112
 
174
113
namespace libtorrent
175
114
{
 
115
        // returns the rank of a peer's source. We have an affinity
 
116
        // to connecting to peers with higher rank. This is to avoid
 
117
        // problems when out peer list is diluted by stale peers from
 
118
        // the resume data for instance
 
119
        int source_rank(int source_bitmask)
 
120
        {
 
121
                int ret = 0;
 
122
                if (source_bitmask & peer_info::tracker) ret |= 1 << 5;
 
123
                if (source_bitmask & peer_info::lsd) ret |= 1 << 4;
 
124
                if (source_bitmask & peer_info::dht) ret |= 1 << 3;
 
125
                if (source_bitmask & peer_info::pex) ret |= 1 << 2;
 
126
                return ret;
 
127
        }
 
128
 
176
129
        // the case where ignore_peer is motivated is if two peers
177
130
        // have only one piece that we don't have, and it's the
178
131
        // same piece for both peers. Then they might get into an
180
133
        void request_a_block(torrent& t, peer_connection& c)
181
134
        {
182
135
                if (t.is_seed()) return;
 
136
                if (c.no_download()) return;
 
137
                if (t.upload_mode()) return;
183
138
 
184
139
                // don't request pieces before we have the metadata
185
140
                if (!t.valid_metadata()) return;
277
232
                (*c.m_logger) << time_now_string() << " PIECE_PICKER [ php: " << prefer_whole_pieces
278
233
                        << " picked: " << interesting_pieces.size() << " ]\n";
279
234
#endif
280
 
                std::deque<pending_block> const& dq = c.download_queue();
281
 
                std::deque<piece_block> const& rq = c.request_queue();
 
235
                std::vector<pending_block> const& dq = c.download_queue();
 
236
                std::vector<pending_block> const& rq = c.request_queue();
282
237
                for (std::vector<piece_block>::iterator i = interesting_pieces.begin();
283
238
                        i != interesting_pieces.end(); ++i)
284
239
                {
289
244
                                if (num_requests <= 0) break;
290
245
                                // don't request pieces we already have in our request queue
291
246
                                if (std::find_if(dq.begin(), dq.end(), has_block(*i)) != dq.end()
292
 
                                        || std::find(rq.begin(), rq.end(), *i) != rq.end())
 
247
                                        || std::find_if(rq.begin(), rq.end(), has_block(*i)) != rq.end())
293
248
                                        continue;
294
249
        
295
250
                                TORRENT_ASSERT(p.num_peers(*i) > 0);
298
253
                        }
299
254
 
300
255
                        TORRENT_ASSERT(p.num_peers(*i) == 0);
 
256
 
 
257
                        // don't request pieces we already have in our request queue
 
258
                        if (std::find_if(dq.begin(), dq.end(), has_block(*i)) != dq.end()
 
259
                                || std::find_if(rq.begin(), rq.end(), has_block(*i)) != rq.end())
 
260
                                continue;
 
261
 
301
262
                        // ok, we found a piece that's not being downloaded
302
263
                        // by somebody else. request it from this peer
303
264
                        // and return
304
 
                        c.add_request(*i);
 
265
                        if (!c.add_request(*i, 0)) continue;
305
266
                        TORRENT_ASSERT(p.num_peers(*i) == 1);
306
267
                        TORRENT_ASSERT(p.is_requested(*i));
307
268
                        num_requests--;
322
283
                // we're requesting from is less than the number of pieces
323
284
                // in the torrent, there are still some unrequested pieces
324
285
                // and we're not strictly speaking in end-game mode yet
325
 
                if (p.num_have() + p.get_download_queue().size()
 
286
                if (t.settings().strict_end_game_mode
 
287
                        && p.num_have() + p.get_download_queue().size()
326
288
                                < t.torrent_file().num_pieces())
327
289
                        return;
328
290
 
351
313
                if (now - last_request < seconds(5))
352
314
                        return;
353
315
 
354
 
                c.add_request(*i);
 
316
                c.add_request(*i, peer_connection::req_busy);
355
317
        }
356
318
 
357
319
        policy::policy(torrent* t)
358
 
                : m_round_robin(m_peers.end())
 
320
                : m_round_robin(0)
359
321
                , m_torrent(t)
360
 
                , m_available_free_upload(0)
361
322
                , m_num_connect_candidates(0)
362
323
                , m_num_seeds(0)
363
324
                , m_finished(false)
366
327
        // disconnects and removes all peers that are now filtered
367
328
        void policy::ip_filter_updated()
368
329
        {
 
330
                INVARIANT_CHECK;
 
331
 
369
332
                aux::session_impl& ses = m_torrent->session();
370
333
                piece_picker* p = 0;
371
 
                if (m_torrent->has_picker())
372
 
                        p = &m_torrent->picker();
 
334
                if (m_torrent->has_picker()) p = &m_torrent->picker();
 
335
 
373
336
                for (iterator i = m_peers.begin(); i != m_peers.end();)
374
337
                {
375
 
                        if ((ses.m_ip_filter.access(i->second.addr) & ip_filter::blocked) == 0)
 
338
                        if ((ses.m_ip_filter.access((*i)->address()) & ip_filter::blocked) == 0)
376
339
                        {
377
340
                                ++i;
378
341
                                continue;
379
342
                        }
380
343
                
381
 
                        if (i->second.connection)
 
344
                        if ((*i)->connection)
382
345
                        {
383
 
                                i->second.connection->disconnect("peer banned by IP filter");
 
346
                                (*i)->connection->disconnect(errors::banned_by_ip_filter);
384
347
                                if (ses.m_alerts.should_post<peer_blocked_alert>())
385
 
                                        ses.m_alerts.post_alert(peer_blocked_alert(i->second.addr));
386
 
                                TORRENT_ASSERT(i->second.connection == 0
387
 
                                        || i->second.connection->peer_info_struct() == 0);
 
348
                                        ses.m_alerts.post_alert(peer_blocked_alert((*i)->address()));
 
349
                                TORRENT_ASSERT((*i)->connection == 0
 
350
                                        || (*i)->connection->peer_info_struct() == 0);
388
351
                        }
389
352
                        else
390
353
                        {
391
354
                                if (ses.m_alerts.should_post<peer_blocked_alert>())
392
 
                                        ses.m_alerts.post_alert(peer_blocked_alert(i->second.addr));
 
355
                                        ses.m_alerts.post_alert(peer_blocked_alert((*i)->address()));
393
356
                        }
394
 
                        erase_peer(i++);
 
357
                        int current = i - m_peers.begin();
 
358
                        erase_peer(i);
 
359
                        i = m_peers.begin() + current;
395
360
                }
396
361
        }
397
362
 
 
363
        void policy::erase_peer(policy::peer* p)
 
364
        {
 
365
                INVARIANT_CHECK;
 
366
 
 
367
                std::pair<iterator, iterator> range = find_peers(p->address());
 
368
                iterator iter = std::find_if(range.first, range.second, match_peer_endpoint(p->ip()));
 
369
                if (iter == range.second) return;
 
370
                erase_peer(iter);
 
371
        }
 
372
 
398
373
        // any peer that is erased from m_peers will be
399
374
        // erased through this function. This way we can make
400
375
        // sure that any references to the peer are removed
404
379
                INVARIANT_CHECK;
405
380
 
406
381
                if (m_torrent->has_picker())
407
 
                        m_torrent->picker().clear_peer(&i->second);
408
 
                if (i->second.seed) --m_num_seeds;
409
 
                if (is_connect_candidate(i->second, m_finished))
 
382
                        m_torrent->picker().clear_peer(*i);
 
383
                if ((*i)->seed) --m_num_seeds;
 
384
                if (is_connect_candidate(**i, m_finished))
410
385
                {
411
386
                        TORRENT_ASSERT(m_num_connect_candidates > 0);
412
387
                        --m_num_connect_candidates;
413
388
                }
414
 
                if (m_round_robin == i) ++m_round_robin;
 
389
                TORRENT_ASSERT(m_num_connect_candidates < m_peers.size());
 
390
                if (m_round_robin > i - m_peers.begin()) --m_round_robin;
415
391
 
 
392
#if TORRENT_USE_IPV6
 
393
                if ((*i)->is_v6_addr)
 
394
                        m_torrent->session().m_ipv6_peer_pool.destroy(
 
395
                                static_cast<ipv6_peer*>(*i));
 
396
                else
 
397
#endif
 
398
                        m_torrent->session().m_ipv4_peer_pool.destroy(
 
399
                                static_cast<ipv4_peer*>(*i));
416
400
                m_peers.erase(i);
417
401
        }
418
402
 
 
403
        bool policy::should_erase_immediately(peer const& p) const
 
404
        {
 
405
                return p.source == peer_info::resume_data
 
406
                        && p.failcount > 0
 
407
                        && !p.banned;
 
408
        }
 
409
 
 
410
        bool policy::is_erase_candidate(peer const& pe, bool finished) const
 
411
        {
 
412
                return pe.connection == 0
 
413
                        && pe.last_connected != 0
 
414
                        && !pe.banned
 
415
                        && !is_connect_candidate(pe, m_finished);
 
416
        }
 
417
 
 
418
        void policy::erase_peers()
 
419
        {
 
420
                INVARIANT_CHECK;
 
421
 
 
422
                int max_peerlist_size = m_torrent->is_paused()
 
423
                        ?m_torrent->settings().max_paused_peerlist_size
 
424
                        :m_torrent->settings().max_peerlist_size;
 
425
 
 
426
                if (max_peerlist_size == 0 || m_peers.empty()) return;
 
427
 
 
428
                int erase_candidate = -1;
 
429
 
 
430
                TORRENT_ASSERT(m_finished == m_torrent->is_finished());
 
431
 
 
432
                int round_robin = rand() % m_peers.size();
 
433
 
 
434
                for (int iterations = (std::min)(int(m_peers.size()), 300);
 
435
                        iterations > 0; --iterations)
 
436
                {
 
437
                        if (m_peers.size() < max_peerlist_size * 0.95)
 
438
                                break;
 
439
 
 
440
                        if (round_robin == m_peers.size()) round_robin = 0;
 
441
 
 
442
                        peer& pe = *m_peers[round_robin];
 
443
                        int current = round_robin;
 
444
 
 
445
                        {
 
446
                                if (is_erase_candidate(pe, m_finished)
 
447
                                        && (erase_candidate == -1
 
448
                                                || !compare_peer_erase(*m_peers[erase_candidate], pe)))
 
449
                                {
 
450
                                        if (should_erase_immediately(pe))
 
451
                                        {
 
452
                                                if (erase_candidate > current) --erase_candidate;
 
453
                                                erase_peer(m_peers.begin() + current);
 
454
                                        }
 
455
                                        else
 
456
                                        {
 
457
                                                erase_candidate = current;
 
458
                                        }
 
459
                                }
 
460
                        }
 
461
 
 
462
                        ++round_robin;
 
463
                }
 
464
                
 
465
                if (erase_candidate > -1)
 
466
                        erase_peer(m_peers.begin() + erase_candidate);
 
467
        }
 
468
 
419
469
        void policy::ban_peer(policy::peer* p)
420
470
        {
421
471
                INVARIANT_CHECK;
424
474
                        --m_num_connect_candidates;
425
475
 
426
476
                p->banned = true;
 
477
                TORRENT_ASSERT(!is_connect_candidate(*p, m_finished));
 
478
        }
 
479
 
 
480
        void policy::set_connection(policy::peer* p, peer_connection* c)
 
481
        {
 
482
                INVARIANT_CHECK;
 
483
 
 
484
                TORRENT_ASSERT(c);
 
485
 
 
486
                const bool was_conn_cand = is_connect_candidate(*p, m_finished);
 
487
                p->connection = c;
 
488
                if (was_conn_cand) --m_num_connect_candidates;
 
489
        }
 
490
 
 
491
        void policy::set_failcount(policy::peer* p, int f)
 
492
        {
 
493
                INVARIANT_CHECK;
 
494
 
 
495
                const bool was_conn_cand = is_connect_candidate(*p, m_finished);
 
496
                p->failcount = f;
 
497
                if (was_conn_cand != is_connect_candidate(*p, m_finished))
 
498
                {
 
499
                        if (was_conn_cand) --m_num_connect_candidates;
 
500
                        else ++m_num_connect_candidates;
 
501
                }
427
502
        }
428
503
 
429
504
        bool policy::is_connect_candidate(peer const& p, bool finished) const
430
505
        {
431
506
                if (p.connection
432
507
                        || p.banned
433
 
                        || p.type == peer::not_connectable
 
508
                        || !p.connectable
434
509
                        || (p.seed && finished)
435
510
                        || p.failcount >= m_torrent->settings().max_failcount)
436
511
                        return false;
437
512
                
438
 
                aux::session_impl& ses = m_torrent->session();
 
513
                aux::session_impl const& ses = m_torrent->session();
439
514
                if (ses.m_port_filter.access(p.port) & port_filter::blocked)
440
515
                        return false;
441
516
                return true;
442
517
        }
443
518
 
444
 
        policy::iterator policy::find_connect_candidate()
 
519
        policy::iterator policy::find_connect_candidate(int session_time)
445
520
        {
446
521
                INVARIANT_CHECK;
447
522
 
448
 
                ptime now = time_now();
449
 
                iterator candidate = m_peers.end();
 
523
                int candidate = -1;
 
524
                int erase_candidate = -1;
 
525
 
 
526
                TORRENT_ASSERT(m_finished == m_torrent->is_finished());
450
527
 
451
528
                int min_reconnect_time = m_torrent->settings().min_reconnect_time;
452
529
                address external_ip = m_torrent->session().external_address();
461
538
                        external_ip = address_v4(bytes);
462
539
                }
463
540
 
464
 
                if (m_round_robin == m_peers.end()) m_round_robin = m_peers.begin();
 
541
                if (m_round_robin == m_peers.size()) m_round_robin = 0;
465
542
 
466
543
#ifndef TORRENT_DISABLE_DHT
467
544
                bool pinged = false;
468
545
#endif
469
546
 
 
547
                int max_peerlist_size = m_torrent->is_paused()
 
548
                        ?m_torrent->settings().max_paused_peerlist_size
 
549
                        :m_torrent->settings().max_peerlist_size;
 
550
 
470
551
                for (int iterations = (std::min)(int(m_peers.size()), 300);
471
552
                        iterations > 0; --iterations)
472
553
                {
473
 
                        if (m_round_robin == m_peers.end()) m_round_robin = m_peers.begin();
 
554
                        if (m_round_robin == m_peers.size()) m_round_robin = 0;
474
555
 
475
 
                        peer& pe = m_round_robin->second;
476
 
                        iterator current = m_round_robin;
 
556
                        peer& pe = *m_peers[m_round_robin];
 
557
                        int current = m_round_robin;
477
558
 
478
559
#ifndef TORRENT_DISABLE_DHT
479
560
                        // try to send a DHT ping to this peer
482
563
                        // advertise support)
483
564
                        if (!pinged && !pe.added_to_dht)
484
565
                        {
485
 
                                udp::endpoint node(pe.addr, pe.port);
 
566
                                udp::endpoint node(pe.address(), pe.port);
486
567
                                m_torrent->session().add_dht_node(node);
487
568
                                pe.added_to_dht = true;
488
569
                                pinged = true;
490
571
#endif
491
572
                        // if the number of peers is growing large
492
573
                        // we need to start weeding.
493
 
                        // don't remove peers we're connected to
494
 
                        // don't remove peers we've never even tried
495
 
                        // don't remove banned peers unless they're 2
496
 
                        // hours old. They should remain banned for
497
 
                        // at least that long
498
 
                        // don't remove peers that we still can try again
499
 
                        if (pe.connection == 0
500
 
                                && pe.connected != min_time()
501
 
                                && (!pe.banned || now - pe.connected > hours(2))
502
 
                                && !is_connect_candidate(pe, m_finished)
503
 
                                && m_peers.size() >= m_torrent->settings().max_peerlist_size * 0.9)
 
574
 
 
575
                        if (m_peers.size() >= max_peerlist_size * 0.95
 
576
                                && max_peerlist_size > 0)
504
577
                        {
505
 
                                erase_peer(m_round_robin++);
506
 
                                continue;
 
578
                                if (is_erase_candidate(pe, m_finished)
 
579
                                        && (erase_candidate == -1
 
580
                                                || !compare_peer_erase(*m_peers[erase_candidate], pe)))
 
581
                                {
 
582
                                        if (should_erase_immediately(pe))
 
583
                                        {
 
584
                                                if (erase_candidate > current) --erase_candidate;
 
585
                                                if (candidate > current) --candidate;
 
586
                                                erase_peer(m_peers.begin() + current);
 
587
                                        }
 
588
                                        else
 
589
                                        {
 
590
                                                erase_candidate = current;
 
591
                                        }
 
592
                                }
507
593
                        }
508
594
 
509
595
                        ++m_round_robin;
510
596
 
511
597
                        if (!is_connect_candidate(pe, m_finished)) continue;
512
598
 
513
 
                        if (candidate != m_peers.end()
514
 
                                && compare_peer(candidate->second, pe, external_ip)) continue;
 
599
                        // compare peer returns true if lhs is better than rhs. In this
 
600
                        // case, it returns true if the current candidate is better than
 
601
                        // pe, which is the peer m_round_robin points to. If it is, just
 
602
                        // keep looking.
 
603
                        if (candidate != -1
 
604
                                && compare_peer(*m_peers[candidate], pe, external_ip)) continue;
515
605
 
516
 
                        if (now - pe.connected <
517
 
                                seconds((pe.failcount + 1) * min_reconnect_time))
 
606
                        if (pe.last_connected
 
607
                                && session_time - pe.last_connected <
 
608
                                (int(pe.failcount) + 1) * min_reconnect_time)
518
609
                                continue;
519
610
 
520
611
                        candidate = current;
521
612
                }
522
613
                
 
614
                if (erase_candidate > -1)
 
615
                {
 
616
                        if (candidate > erase_candidate) --candidate;
 
617
                        erase_peer(m_peers.begin() + erase_candidate);
 
618
                }
 
619
 
523
620
#if defined TORRENT_LOGGING || defined TORRENT_VERBOSE_LOGGING
524
 
                if (candidate != m_peers.end())
 
621
                if (candidate != -1)
525
622
                {
526
623
                        (*m_torrent->session().m_logger) << time_now_string()
527
624
                                << " *** FOUND CONNECTION CANDIDATE ["
528
 
                                " ip: " << candidate->second.ip() <<
529
 
                                " d: " << cidr_distance(external_ip, candidate->second.addr) <<
 
625
                                " ip: " << m_peers[candidate]->ip() <<
 
626
                                " d: " << cidr_distance(external_ip, m_peers[candidate]->address()) <<
530
627
                                " external: " << external_ip <<
531
 
                                " t: " << total_seconds(time_now() - candidate->second.connected) <<
 
628
                                " t: " << (session_time - m_peers[candidate]->last_connected) <<
532
629
                                " ]\n";
533
630
                }
534
631
#endif
535
632
 
536
 
                return candidate;
 
633
                if (candidate == -1) return m_peers.end();
 
634
                return m_peers.begin() + candidate;
537
635
        }
538
636
 
539
637
        void policy::pulse()
540
638
        {
541
639
                INVARIANT_CHECK;
542
640
 
543
 
                // ------------------------
544
 
                // upload shift
545
 
                // ------------------------
546
 
 
547
 
                // this part will shift downloads
548
 
                // from peers that are seeds and peers
549
 
                // that don't want to download from us
550
 
                // to peers that cannot upload anything
551
 
                // to us. The shifting will make sure
552
 
                // that the torrent's share ratio
553
 
                // will be maintained
554
 
 
555
 
                // if the share ratio is 0 (infinite)
556
 
                // m_available_free_upload isn't used
557
 
                // because it isn't necessary
558
 
                if (m_torrent->ratio() != 0.f)
559
 
                {
560
 
                        // accumulate all the free download we get
561
 
                        // and add it to the available free upload
562
 
                        m_available_free_upload
563
 
                                += collect_free_download(
564
 
                                        m_torrent->begin()
565
 
                                        , m_torrent->end());
566
 
 
567
 
                        // distribute the free upload among the peers
568
 
                        m_available_free_upload = distribute_free_upload(
569
 
                                m_torrent->begin()
570
 
                                , m_torrent->end()
571
 
                                , m_available_free_upload);
572
 
                }
 
641
                erase_peers();
573
642
        }
574
643
 
575
 
        bool policy::new_connection(peer_connection& c)
 
644
        bool policy::new_connection(peer_connection& c, int session_time)
576
645
        {
577
646
                TORRENT_ASSERT(!c.is_local());
578
647
 
586
655
                // override at a time
587
656
                error_code ec;
588
657
                TORRENT_ASSERT(c.remote() == c.get_socket()->remote_endpoint(ec) || ec);
 
658
                TORRENT_ASSERT(!m_torrent->is_paused());
589
659
 
590
660
                aux::session_impl& ses = m_torrent->session();
591
661
                
593
663
                        && ses.num_connections() >= ses.max_connections()
594
664
                        && c.remote().address() != m_torrent->current_tracker().address())
595
665
                {
596
 
                        c.disconnect("too many connections, refusing incoming connection");
 
666
                        c.disconnect(errors::too_many_connections);
597
667
                        return false;
598
668
                }
599
669
 
604
674
                }
605
675
#endif
606
676
 
607
 
                iterator i;
 
677
                iterator iter;
 
678
                peer* i = 0;
608
679
 
 
680
                bool found = false;
609
681
                if (m_torrent->settings().allow_multiple_connections_per_ip)
610
682
                {
611
683
                        tcp::endpoint remote = c.remote();
612
 
                        std::pair<iterator, iterator> range = m_peers.equal_range(remote.address());
613
 
                        i = std::find_if(range.first, range.second, match_peer_endpoint(remote));
 
684
                        std::pair<iterator, iterator> range = find_peers(remote.address());
 
685
                        iter = std::find_if(range.first, range.second, match_peer_endpoint(remote));
614
686
        
615
 
                        if (i == range.second) i = m_peers.end();
 
687
                        if (iter != range.second) found = true;
616
688
                }
617
689
                else
618
690
                {
619
 
                        i = m_peers.find(c.remote().address());
 
691
                        iter = std::lower_bound(
 
692
                                m_peers.begin(), m_peers.end()
 
693
                                , c.remote().address(), peer_address_compare()
 
694
                        );
 
695
 
 
696
                        if (iter != m_peers.end() && (*iter)->address() == c.remote().address()) found = true;
620
697
                }
621
698
 
622
 
                if (i != m_peers.end())
 
699
                if (found)
623
700
                {
624
 
                        if (i->second.banned)
 
701
                        i = *iter;
 
702
 
 
703
                        if (i->banned)
625
704
                        {
626
 
                                c.disconnect("ip address banned, closing");
 
705
                                c.disconnect(errors::peer_banned);
627
706
                                return false;
628
707
                        }
629
708
 
630
 
                        if (i->second.connection != 0)
 
709
                        if (i->connection != 0)
631
710
                        {
632
711
                                boost::shared_ptr<socket_type> other_socket
633
 
                                        = i->second.connection->get_socket();
 
712
                                        = i->connection->get_socket();
634
713
                                boost::shared_ptr<socket_type> this_socket
635
714
                                        = c.get_socket();
636
715
 
642
721
 
643
722
                                if (ec1)
644
723
                                {
645
 
                                        c.disconnect(ec1.message().c_str());
 
724
                                        c.disconnect(ec1);
646
725
                                        return false;
647
726
                                }
648
727
 
649
728
                                if (self_connection)
650
729
                                {
651
 
                                        c.disconnect("connected to ourselves", 1);
652
 
                                        i->second.connection->disconnect("connected to ourselves", 1);
 
730
                                        c.disconnect(errors::self_connection, 1);
 
731
                                        i->connection->disconnect(errors::self_connection, 1);
 
732
                                        TORRENT_ASSERT(i->connection == 0);
653
733
                                        return false;
654
734
                                }
655
735
 
656
 
                                TORRENT_ASSERT(i->second.connection != &c);
 
736
                                TORRENT_ASSERT(i->connection != &c);
657
737
                                // the new connection is a local (outgoing) connection
658
738
                                // or the current one is already connected
659
739
                                if (ec2)
660
740
                                {
661
 
                                        i->second.connection->disconnect(ec2.message().c_str());
 
741
                                        i->connection->disconnect(ec2);
 
742
                                        TORRENT_ASSERT(i->connection == 0);
662
743
                                }
663
 
                                else if (!i->second.connection->is_connecting() || c.is_local())
 
744
                                else if (!i->connection->is_connecting() || c.is_local())
664
745
                                {
665
 
                                        c.disconnect("duplicate connection, closing");
 
746
                                        c.disconnect(errors::duplicate_peer_id);
666
747
                                        return false;
667
748
                                }
668
749
                                else
672
753
                                        " is connecting and this connection is incoming. closing existing "
673
754
                                        "connection in favour of this one");
674
755
#endif
675
 
                                        i->second.connection->disconnect("incoming duplicate connection "
676
 
                                                "with higher priority, closing");
 
756
                                        i->connection->disconnect(errors::duplicate_peer_id);
 
757
                                        TORRENT_ASSERT(i->connection == 0);
677
758
                                }
678
759
                        }
679
760
 
680
 
                        if (is_connect_candidate(i->second, m_finished)
681
 
                                && m_num_connect_candidates > 0)
682
 
                                --m_num_connect_candidates;
 
761
                        if (is_connect_candidate(*i, m_finished))
 
762
                        {
 
763
                                m_num_connect_candidates--;
 
764
                                TORRENT_ASSERT(m_num_connect_candidates >= 0);
 
765
                                if (m_num_connect_candidates < 0) m_num_connect_candidates = 0;
 
766
                        }
683
767
                }
684
768
                else
685
769
                {
690
774
 
691
775
                        if (int(m_peers.size()) >= m_torrent->settings().max_peerlist_size)
692
776
                        {
693
 
                                c.disconnect("peer list size exceeded, refusing incoming connection");
 
777
                                c.disconnect(errors::too_many_connections);
694
778
                                return false;
695
779
                        }
696
780
 
697
 
                        peer p(c.remote(), peer::not_connectable, 0);
698
 
                        i = m_peers.insert(std::make_pair(c.remote().address(), p));
 
781
                        if (m_round_robin > iter - m_peers.begin()) ++m_round_robin;
 
782
#if TORRENT_USE_IPV6
 
783
                        bool is_v6 = c.remote().address().is_v6();
 
784
#endif
 
785
                        peer* p =
 
786
#if TORRENT_USE_IPV6
 
787
                                is_v6 ? (peer*)m_torrent->session().m_ipv6_peer_pool.malloc() :
 
788
#endif
 
789
                                (peer*)m_torrent->session().m_ipv4_peer_pool.malloc();
 
790
                        if (p == 0) return false;
 
791
#if TORRENT_USE_IPV6
 
792
                        if (is_v6)
 
793
                                m_torrent->session().m_ipv6_peer_pool.set_next_size(500);
 
794
                        else
 
795
#endif
 
796
                                m_torrent->session().m_ipv4_peer_pool.set_next_size(500);
 
797
 
 
798
#if TORRENT_USE_IPV6
 
799
                        if (is_v6)
 
800
                                new (p) ipv6_peer(c.remote(), false, 0);
 
801
                        else
 
802
#endif
 
803
                                new (p) ipv4_peer(c.remote(), false, 0);
 
804
 
 
805
                        iter = m_peers.insert(iter, p);
 
806
 
 
807
                        i = *iter;
699
808
#ifndef TORRENT_DISABLE_GEO_IP
700
809
                        int as = ses.as_for_ip(c.remote().address());
701
810
#ifdef TORRENT_DEBUG
702
 
                        i->second.inet_as_num = as;
703
 
#endif
704
 
                        i->second.inet_as = ses.lookup_as(as);
705
 
#endif
706
 
                        i->second.source = peer_info::incoming;
 
811
                        i->inet_as_num = as;
 
812
#endif
 
813
                        i->inet_as = ses.lookup_as(as);
 
814
#endif
 
815
                        i->source = peer_info::incoming;
707
816
                }
708
817
        
709
 
                c.set_peer_info(&i->second);
710
 
                TORRENT_ASSERT(i->second.connection == 0);
711
 
                c.add_stat(i->second.prev_amount_download, i->second.prev_amount_upload);
712
 
                i->second.prev_amount_download = 0;
713
 
                i->second.prev_amount_upload = 0;
714
 
                i->second.connection = &c;
715
 
                TORRENT_ASSERT(i->second.connection);
 
818
                TORRENT_ASSERT(i);
 
819
                c.set_peer_info(i);
 
820
                TORRENT_ASSERT(i->connection == 0);
 
821
                c.add_stat(i->prev_amount_download, i->prev_amount_upload);
 
822
 
 
823
                // restore transfer rate limits
 
824
                int rate_limit;
 
825
                rate_limit = i->upload_rate_limit;
 
826
                if (rate_limit) c.set_upload_limit(rate_limit);
 
827
                rate_limit = i->download_rate_limit;
 
828
                if (rate_limit) c.set_download_limit(rate_limit);
 
829
 
 
830
                i->prev_amount_download = 0;
 
831
                i->prev_amount_upload = 0;
 
832
                i->connection = &c;
 
833
                TORRENT_ASSERT(i->connection);
716
834
                if (!c.fast_reconnect())
717
 
                        i->second.connected = time_now();
 
835
                        i->last_connected = session_time;
 
836
 
 
837
                // this cannot be a connect candidate anymore, since i->connection is set
 
838
                TORRENT_ASSERT(!is_connect_candidate(*i, m_finished));
 
839
                TORRENT_ASSERT(has_connection(&c));
718
840
                return true;
719
841
        }
720
842
 
729
851
 
730
852
                if (m_torrent->settings().allow_multiple_connections_per_ip)
731
853
                {
732
 
                        tcp::endpoint remote(p->addr, port);
733
 
                        std::pair<iterator, iterator> range = m_peers.equal_range(remote.address());
 
854
                        tcp::endpoint remote(p->address(), port);
 
855
                        std::pair<iterator, iterator> range = find_peers(remote.address());
734
856
                        iterator i = std::find_if(range.first, range.second
735
857
                                , match_peer_endpoint(remote));
736
858
                        if (i != m_peers.end())
737
859
                        {
738
 
                                policy::peer& pp = i->second;
 
860
                                policy::peer& pp = **i;
739
861
                                if (pp.connection)
740
862
                                {
741
 
                                        p->connection->disconnect("duplicate connection");
 
863
                                        bool was_conn_cand = is_connect_candidate(pp, m_finished);
 
864
                                        // if we already have an entry with this
 
865
                                        // new endpoint, disconnect this one
 
866
                                        pp.connectable = true;
 
867
                                        pp.source |= src;
 
868
                                        if (!was_conn_cand && is_connect_candidate(pp, m_finished))
 
869
                                                ++m_num_connect_candidates;
 
870
                                        p->connection->disconnect(errors::duplicate_peer_id);
 
871
                                        erase_peer(p);
742
872
                                        return false;
743
873
                                }
744
874
                                erase_peer(i);
745
875
                        }
746
876
                }
 
877
#ifdef TORRENT_DEBUG
747
878
                else
748
879
                {
749
 
                        TORRENT_ASSERT(m_peers.count(p->addr) == 1);
 
880
                        std::pair<iterator, iterator> range = find_peers(p->address());
 
881
                        TORRENT_ASSERT(range.second - range.first == 1);
750
882
                }
 
883
#endif
 
884
 
751
885
                bool was_conn_cand = is_connect_candidate(*p, m_finished);
752
886
                p->port = port;
753
887
                p->source |= src;
754
 
                p->type = policy::peer::connectable;
 
888
                p->connectable = true;
755
889
 
756
890
                if (was_conn_cand != is_connect_candidate(*p, m_finished))
757
891
                {
762
896
                return true;
763
897
        }
764
898
 
 
899
        // it's important that we don't dereference
 
900
        // p here, since it is allowed to be a dangling
 
901
        // pointer. see smart_ban.cpp
765
902
        bool policy::has_peer(policy::peer const* p) const
766
903
        {
767
904
                // find p in m_peers
768
 
                for (std::multimap<address, peer>::const_iterator i = m_peers.begin()
 
905
                for (const_iterator i = m_peers.begin()
769
906
                        , end(m_peers.end()); i != end; ++i)
770
907
                {
771
 
                        if (&i->second == p) return true;
 
908
                        if (*i == p) return true;
772
909
                }
773
910
                return false;
774
911
        }
782
919
                if (was_conn_cand && !is_connect_candidate(*p, m_finished))
783
920
                {
784
921
                        --m_num_connect_candidates;
 
922
                        TORRENT_ASSERT(m_num_connect_candidates >= 0);
785
923
                        if (m_num_connect_candidates < 0) m_num_connect_candidates = 0;
786
924
                }
787
925
 
788
926
                if (s) ++m_num_seeds;
789
927
                else --m_num_seeds;
 
928
                TORRENT_ASSERT(m_num_seeds >= 0);
 
929
                TORRENT_ASSERT(m_num_seeds <= m_peers.size());
790
930
        }
791
931
 
792
 
        policy::peer* policy::peer_from_tracker(tcp::endpoint const& remote, peer_id const& pid
 
932
        policy::peer* policy::add_peer(tcp::endpoint const& remote, peer_id const& pid
793
933
                , int src, char flags)
794
934
        {
795
935
                INVARIANT_CHECK;
808
948
                        return 0;
809
949
                }
810
950
 
811
 
                iterator i;
812
 
 
 
951
                // if the IP is blocked, don't add it
 
952
                if (ses.m_ip_filter.access(remote.address()) & ip_filter::blocked)
 
953
                {
 
954
                        if (ses.m_alerts.should_post<peer_blocked_alert>())
 
955
                        {
 
956
                                ses.m_alerts.post_alert(peer_blocked_alert(remote.address()));
 
957
                        }
 
958
                        return 0;
 
959
                }
 
960
 
 
961
                iterator iter;
 
962
                peer* i = 0;
 
963
 
 
964
                int max_peerlist_size = m_torrent->is_paused()
 
965
                        ?m_torrent->settings().max_paused_peerlist_size
 
966
                        :m_torrent->settings().max_peerlist_size;
 
967
 
 
968
                bool found = false;
813
969
                if (m_torrent->settings().allow_multiple_connections_per_ip)
814
970
                {
815
 
                        std::pair<iterator, iterator> range = m_peers.equal_range(remote.address());
816
 
                        i = std::find_if(range.first, range.second, match_peer_endpoint(remote));
817
 
                        if (i == range.second) i = m_peers.end();
 
971
                        std::pair<iterator, iterator> range = find_peers(remote.address());
 
972
                        iter = std::find_if(range.first, range.second, match_peer_endpoint(remote));
 
973
                        if (iter != range.second) found = true;
818
974
                }
819
975
                else
820
976
                {
821
 
                        i = m_peers.find(remote.address());
 
977
                        iter = std::lower_bound(
 
978
                                m_peers.begin(), m_peers.end()
 
979
                                , remote.address(), peer_address_compare()
 
980
                        );
 
981
 
 
982
                        if (iter != m_peers.end() && (*iter)->address() == remote.address()) found = true;
822
983
                }
823
984
 
824
 
                if (i == m_peers.end())
 
985
                if (!found)
825
986
                {
826
 
                        // if the IP is blocked, don't add it
827
 
                        if (ses.m_ip_filter.access(remote.address()) & ip_filter::blocked)
 
987
                        if (max_peerlist_size
 
988
                                && int(m_peers.size()) >= max_peerlist_size)
828
989
                        {
829
 
                                if (ses.m_alerts.should_post<peer_blocked_alert>())
830
 
                                {
831
 
                                        ses.m_alerts.post_alert(peer_blocked_alert(remote.address()));
832
 
                                }
833
 
                                return 0;
 
990
                                if (src == peer_info::resume_data) return 0;
 
991
 
 
992
                                erase_peers();
 
993
                                if (int(m_peers.size()) >= max_peerlist_size)
 
994
                                        return 0;
 
995
 
 
996
                                // since some peers were removed, we need to
 
997
                                // update the iterator to make it valid again
 
998
                                iter = std::lower_bound(
 
999
                                        m_peers.begin(), m_peers.end()
 
1000
                                        , remote.address(), peer_address_compare()
 
1001
                                );
834
1002
                        }
835
1003
 
836
 
                        if (int(m_peers.size()) >= m_torrent->settings().max_peerlist_size)
837
 
                                return 0;
 
1004
                        if (m_round_robin > iter - m_peers.begin()) ++m_round_robin;
838
1005
 
839
1006
                        // we don't have any info about this peer.
840
1007
                        // add a new entry
841
 
                        i = m_peers.insert(std::make_pair(remote.address()
842
 
                                        , peer(remote, peer::connectable, src)));
 
1008
#if TORRENT_USE_IPV6
 
1009
                        bool is_v6 = remote.address().is_v6();
 
1010
#endif
 
1011
                        peer* p =
 
1012
#if TORRENT_USE_IPV6
 
1013
                                is_v6 ? (peer*)m_torrent->session().m_ipv6_peer_pool.malloc() :
 
1014
#endif
 
1015
                                (peer*)m_torrent->session().m_ipv4_peer_pool.malloc();
 
1016
                        if (p == 0) return 0;
 
1017
#if TORRENT_USE_IPV6
 
1018
                        if (is_v6)
 
1019
                                m_torrent->session().m_ipv6_peer_pool.set_next_size(500);
 
1020
                        else
 
1021
#endif
 
1022
                                m_torrent->session().m_ipv4_peer_pool.set_next_size(500);
 
1023
 
 
1024
#if TORRENT_USE_IPV6
 
1025
                        if (is_v6)
 
1026
                                new (p) ipv6_peer(remote, true, src);
 
1027
                        else
 
1028
#endif
 
1029
                                new (p) ipv4_peer(remote, true, src);
 
1030
 
 
1031
                        iter = m_peers.insert(iter, p);
 
1032
 
 
1033
                        i = *iter;
843
1034
#ifndef TORRENT_DISABLE_ENCRYPTION
844
 
                        if (flags & 0x01) i->second.pe_support = true;
 
1035
                        if (flags & 0x01) i->pe_support = true;
845
1036
#endif
846
1037
                        if (flags & 0x02)
847
1038
                        {
848
 
                                i->second.seed = true;
 
1039
                                i->seed = true;
849
1040
                                ++m_num_seeds;
850
1041
                        }
851
1042
 
852
1043
#ifndef TORRENT_DISABLE_GEO_IP
853
1044
                        int as = ses.as_for_ip(remote.address());
854
1045
#ifdef TORRENT_DEBUG
855
 
                        i->second.inet_as_num = as;
856
 
#endif
857
 
                        i->second.inet_as = ses.lookup_as(as);
858
 
#endif
859
 
                        if (is_connect_candidate(i->second, m_finished))
 
1046
                        i->inet_as_num = as;
 
1047
#endif
 
1048
                        i->inet_as = ses.lookup_as(as);
 
1049
#endif
 
1050
                        if (is_connect_candidate(*i, m_finished))
860
1051
                                ++m_num_connect_candidates;
861
1052
                }
862
1053
                else
863
1054
                {
864
 
                        bool was_conn_cand = is_connect_candidate(i->second, m_finished);
865
 
 
866
 
                        i->second.type = peer::connectable;
867
 
 
868
 
                        i->second.set_ip(remote);
869
 
                        i->second.source |= src;
 
1055
                        i = *iter;
 
1056
 
 
1057
                        bool was_conn_cand = is_connect_candidate(*i, m_finished);
 
1058
 
 
1059
                        i->connectable = true;
 
1060
 
 
1061
                        TORRENT_ASSERT(i->address() == remote.address());
 
1062
                        i->port = remote.port();
 
1063
                        i->source |= src;
870
1064
                                
871
1065
                        // if this peer has failed before, decrease the
872
1066
                        // counter to allow it another try, since somebody
873
1067
                        // else is appearantly able to connect to it
874
1068
                        // only trust this if it comes from the tracker
875
 
                        if (i->second.failcount > 0 && src == peer_info::tracker)
876
 
                                --i->second.failcount;
 
1069
                        if (i->failcount > 0 && src == peer_info::tracker)
 
1070
                                --i->failcount;
877
1071
 
878
1072
                        // if we're connected to this peer
879
1073
                        // we already know if it's a seed or not
880
1074
                        // so we don't have to trust this source
881
 
                        if ((flags & 0x02) && !i->second.connection)
 
1075
                        if ((flags & 0x02) && !i->connection)
882
1076
                        {
883
 
                                if (!i->second.seed) ++m_num_seeds;
884
 
                                i->second.seed = true;
 
1077
                                if (!i->seed) ++m_num_seeds;
 
1078
                                i->seed = true;
885
1079
                        }
886
1080
 
887
1081
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
888
 
                        if (i->second.connection)
 
1082
                        if (i->connection)
889
1083
                        {
890
1084
                                // this means we're already connected
891
1085
                                // to this peer. don't connect to
892
1086
                                // it again.
893
1087
 
894
1088
                                error_code ec;
895
 
                                m_torrent->debug_log("already connected to peer: " + remote.address().to_string(ec) + ":"
896
 
                                        + boost::lexical_cast<std::string>(remote.port()) + " "
897
 
                                        + boost::lexical_cast<std::string>(i->second.connection->pid()));
 
1089
                                char hex_pid[41];
 
1090
                                to_hex((char*)&i->connection->pid()[0], 20, hex_pid);
 
1091
                                char msg[200];
 
1092
                                snprintf(msg, 200, "already connected to peer: %s %s"
 
1093
                                        , print_endpoint(remote).c_str(), hex_pid);
 
1094
                                m_torrent->debug_log(msg);
898
1095
 
899
 
                                TORRENT_ASSERT(i->second.connection->associated_torrent().lock().get() == m_torrent);
 
1096
                                TORRENT_ASSERT(i->connection->associated_torrent().lock().get() == m_torrent);
900
1097
                        }
901
1098
#endif
902
1099
 
903
 
                        if (was_conn_cand != is_connect_candidate(i->second, m_torrent->is_finished()))
 
1100
                        if (was_conn_cand != is_connect_candidate(*i, m_finished))
904
1101
                        {
905
1102
                                m_num_connect_candidates += was_conn_cand ? -1 : 1;
906
1103
                                if (m_num_connect_candidates < 0) m_num_connect_candidates = 0;
907
1104
                        }
908
1105
                }
909
1106
 
910
 
                return &i->second;
911
 
        }
912
 
 
913
 
        // this is called when we are unchoked by a peer
914
 
        // i.e. a peer lets us know that we will receive
915
 
        // data from now on
916
 
        void policy::unchoked(peer_connection& c)
917
 
        {
918
 
                INVARIANT_CHECK;
919
 
                if (c.is_interesting())
920
 
                {
921
 
                        request_a_block(*m_torrent, c);
922
 
                        c.send_block_requests();
923
 
                }
924
 
        }
925
 
 
926
 
        // called when a peer is interested in us
927
 
        void policy::interested(peer_connection& c)
928
 
        {
929
 
                INVARIANT_CHECK;
930
 
 
931
 
                TORRENT_ASSERT(std::find_if(m_peers.begin(), m_peers.end()
932
 
                        , boost::bind<bool>(std::equal_to<peer_connection*>(), bind(&peer::connection
933
 
                        , bind(&iterator::value_type::second, _1)), &c)) != m_peers.end());
934
 
                
935
 
                aux::session_impl& ses = m_torrent->session();
936
 
 
937
 
                // if the peer is choked and we have upload slots left,
938
 
                // then unchoke it. Another condition that has to be met
939
 
                // is that the torrent doesn't keep track of the individual
940
 
                // up/down ratio for each peer (ratio == 0) or (if it does
941
 
                // keep track) this particular connection isn't a leecher.
942
 
                // If the peer was choked because it was leeching, don't
943
 
                // unchoke it again.
944
 
                // The exception to this last condition is if we're a seed.
945
 
                // In that case we don't care if people are leeching, they
946
 
                // can't pay for their downloads anyway.
947
 
                if (c.is_choked()
948
 
                        && ses.num_uploads() < ses.max_uploads()
949
 
                        && (m_torrent->ratio() == 0
950
 
                                || c.share_diff() >= -free_upload_amount
951
 
                                || m_torrent->is_finished()))
952
 
                {
953
 
                        ses.unchoke_peer(c);
954
 
                }
955
 
#if defined TORRENT_VERBOSE_LOGGING
956
 
                else if (c.is_choked())
957
 
                {
958
 
                        std::string reason;
959
 
                        if (ses.num_uploads() >= ses.max_uploads())
960
 
                        {
961
 
                                reason = "the number of uploads ("
962
 
                                        + boost::lexical_cast<std::string>(ses.num_uploads())
963
 
                                        + ") is more than or equal to the limit ("
964
 
                                        + boost::lexical_cast<std::string>(ses.max_uploads())
965
 
                                        + ")";
966
 
                        }
967
 
                        else
968
 
                        {
969
 
                                reason = "the share ratio ("
970
 
                                        + boost::lexical_cast<std::string>(c.share_diff())
971
 
                                        + ") is <= free_upload_amount ("
972
 
                                        + boost::lexical_cast<std::string>(int(free_upload_amount))
973
 
                                        + ") and we are not seeding and the ratio ("
974
 
                                        + boost::lexical_cast<std::string>(m_torrent->ratio())
975
 
                                        + ")is non-zero";
976
 
                        }
977
 
                        (*c.m_logger) << time_now_string() << " DID NOT UNCHOKE [ " << reason << " ]\n";
978
 
                }
979
 
#endif
980
 
        }
981
 
 
982
 
        // called when a peer is no longer interested in us
983
 
        void policy::not_interested(peer_connection& c)
984
 
        {
985
 
                INVARIANT_CHECK;
986
 
 
987
 
                if (m_torrent->ratio() != 0.f)
988
 
                {
989
 
                        TORRENT_ASSERT(c.share_diff() < (std::numeric_limits<size_type>::max)());
990
 
                        size_type diff = c.share_diff();
991
 
                        if (diff > 0 && c.is_seed())
992
 
                        {
993
 
                                // the peer is a seed and has sent
994
 
                                // us more than we have sent it back.
995
 
                                // consider the download as free download
996
 
                                m_available_free_upload += diff;
997
 
                                c.add_free_upload(-diff);
998
 
                        }
999
 
                }
1000
 
        }
1001
 
/*
1002
 
        bool policy::unchoke_one_peer()
1003
 
        {
1004
 
                INVARIANT_CHECK;
1005
 
 
1006
 
                iterator p = find_unchoke_candidate();
1007
 
                if (p == m_peers.end()) return false;
1008
 
                TORRENT_ASSERT(p->connection);
1009
 
                TORRENT_ASSERT(!p->connection->is_disconnecting());
1010
 
 
1011
 
                TORRENT_ASSERT(p->connection->is_choked());
1012
 
                p->connection->send_unchoke();
1013
 
                p->last_optimistically_unchoked = time_now();
1014
 
                ++m_num_unchoked;
1015
 
                return true;
1016
 
        }
1017
 
 
1018
 
        void policy::choke_one_peer()
1019
 
        {
1020
 
                INVARIANT_CHECK;
1021
 
 
1022
 
                iterator p = find_choke_candidate();
1023
 
                if (p == m_peers.end()) return;
1024
 
                TORRENT_ASSERT(p->connection);
1025
 
                TORRENT_ASSERT(!p->connection->is_disconnecting());
1026
 
                TORRENT_ASSERT(!p->connection->is_choked());
1027
 
                p->connection->send_choke();
1028
 
                --m_num_unchoked;
1029
 
        }
1030
 
*/
1031
 
        bool policy::connect_one_peer()
 
1107
                return i;
 
1108
        }
 
1109
 
 
1110
        bool policy::connect_one_peer(int session_time)
1032
1111
        {
1033
1112
                INVARIANT_CHECK;
1034
1113
 
1035
1114
                TORRENT_ASSERT(m_torrent->want_more_peers());
1036
1115
                
1037
 
                iterator p = find_connect_candidate();
1038
 
                if (p == m_peers.end()) return false;
 
1116
                iterator i = find_connect_candidate(session_time);
 
1117
                if (i == m_peers.end()) return false;
 
1118
                peer& p = **i;
1039
1119
 
1040
 
                TORRENT_ASSERT(!p->second.banned);
1041
 
                TORRENT_ASSERT(!p->second.connection);
1042
 
                TORRENT_ASSERT(p->second.type == peer::connectable);
 
1120
                TORRENT_ASSERT(!p.banned);
 
1121
                TORRENT_ASSERT(!p.connection);
 
1122
                TORRENT_ASSERT(p.connectable);
1043
1123
 
1044
1124
                TORRENT_ASSERT(m_finished == m_torrent->is_finished());
1045
 
                TORRENT_ASSERT(is_connect_candidate(p->second, m_finished));
1046
 
                if (!m_torrent->connect_to_peer(&p->second))
 
1125
                TORRENT_ASSERT(is_connect_candidate(p, m_finished));
 
1126
                if (!m_torrent->connect_to_peer(&p))
1047
1127
                {
1048
 
                        ++p->second.failcount;
1049
 
                        if (!is_connect_candidate(p->second, m_finished))
 
1128
                        // failcount is a 5 bit value
 
1129
                        const bool was_conn_cand = is_connect_candidate(p, m_finished);
 
1130
                        if (p.failcount < 31) ++p.failcount;
 
1131
                        if (was_conn_cand && !is_connect_candidate(p, m_finished))
1050
1132
                                --m_num_connect_candidates;
1051
1133
                        return false;
1052
1134
                }
1053
 
                TORRENT_ASSERT(p->second.connection);
1054
 
                TORRENT_ASSERT(!is_connect_candidate(p->second, m_finished));
1055
 
                --m_num_connect_candidates;
 
1135
                TORRENT_ASSERT(p.connection);
 
1136
                TORRENT_ASSERT(!is_connect_candidate(p, m_finished));
1056
1137
                return true;
1057
1138
        }
1058
1139
 
1059
1140
        // this is called whenever a peer connection is closed
1060
 
        void policy::connection_closed(const peer_connection& c)
 
1141
        void policy::connection_closed(const peer_connection& c, int session_time)
1061
1142
        {
1062
1143
                INVARIANT_CHECK;
1063
1144
 
1073
1154
                if (p == 0) return;
1074
1155
 
1075
1156
                TORRENT_ASSERT(p->connection == &c);
 
1157
                TORRENT_ASSERT(!is_connect_candidate(*p, m_finished));
 
1158
 
 
1159
                // save transfer rate limits
 
1160
                int rate_limit;
 
1161
                p->upload_rate_limit = c.upload_limit();
 
1162
                p->download_rate_limit = c.download_limit();
1076
1163
 
1077
1164
                p->connection = 0;
1078
1165
                p->optimistically_unchoked = false;
1081
1168
                // update the timestamp, and it will remain
1082
1169
                // the time when we initiated the connection.
1083
1170
                if (!c.fast_reconnect())
1084
 
                        p->connected = time_now();
 
1171
                        p->last_connected = session_time;
1085
1172
 
1086
1173
                if (c.failed())
1087
1174
                {
1088
 
                        ++p->failcount;
1089
 
//                      p->connected = time_now();
 
1175
                        // failcount is a 5 bit value
 
1176
                        if (p->failcount < 31) ++p->failcount;
1090
1177
                }
1091
1178
 
1092
1179
                if (is_connect_candidate(*p, m_finished))
1093
1180
                        ++m_num_connect_candidates;
1094
1181
 
1095
 
                // if the share ratio is 0 (infinite), the
1096
 
                // m_available_free_upload isn't used,
1097
 
                // because it isn't necessary.
1098
 
                if (m_torrent->ratio() != 0.f)
1099
 
                {
1100
 
                        TORRENT_ASSERT(c.associated_torrent().lock().get() == m_torrent);
1101
 
                        TORRENT_ASSERT(c.share_diff() < (std::numeric_limits<size_type>::max)());
1102
 
                        m_available_free_upload += c.share_diff();
1103
 
                }
1104
 
                TORRENT_ASSERT(p->prev_amount_upload == 0);
1105
 
                TORRENT_ASSERT(p->prev_amount_download == 0);
1106
 
                p->prev_amount_download += c.statistics().total_payload_download();
1107
 
                p->prev_amount_upload += c.statistics().total_payload_upload();
 
1182
                // if we're already a seed, it's not as important
 
1183
                // to keep all the possibly stale peers
 
1184
                // if we're not a seed, but we have too many peers
 
1185
                // start weeding the ones we only know from resume
 
1186
                // data first
 
1187
                // at this point it may be tempting to erase peers
 
1188
                // from the peer list, but keep in mind that we might
 
1189
                // have gotten to this point through new_connection, just
 
1190
                // disconnecting an old peer, relying on this policy::peer
 
1191
                // to still exist when we get back there, to assign the new
 
1192
                // peer connection pointer to it. The peer list must
 
1193
                // be left intact.
1108
1194
        }
1109
1195
 
1110
1196
        void policy::peer_is_interesting(peer_connection& c)
1111
1197
        {
1112
1198
                INVARIANT_CHECK;
1113
1199
 
 
1200
                // no peer should be interesting if we're finished
 
1201
                TORRENT_ASSERT(!m_torrent->is_finished());
 
1202
 
1114
1203
                if (c.in_handshake()) return;
1115
1204
                c.send_interested();
1116
1205
                if (c.has_peer_choked()
1132
1221
                for (const_iterator i = m_peers.begin();
1133
1222
                        i != m_peers.end(); ++i)
1134
1223
                {
1135
 
                        m_num_connect_candidates += is_connect_candidate(i->second, m_finished);
 
1224
                        m_num_connect_candidates += is_connect_candidate(**i, m_finished);
1136
1225
                }
1137
1226
        }
1138
1227
 
1148
1237
                return std::find_if(
1149
1238
                        m_peers.begin()
1150
1239
                        , m_peers.end()
1151
 
                        , match_peer_connection(*c)) != m_peers.end();
 
1240
                        , match_peer_connection_or_endpoint(*c)) != m_peers.end();
1152
1241
        }
1153
1242
 
1154
1243
        void policy::check_invariant() const
1165
1254
                int connect_candidates = 0;
1166
1255
 
1167
1256
                std::set<tcp::endpoint> unique_test;
 
1257
                const_iterator prev = m_peers.end();
1168
1258
                for (const_iterator i = m_peers.begin();
1169
1259
                        i != m_peers.end(); ++i)
1170
1260
                {
1171
 
                        peer const& p = i->second;
1172
 
                        if (is_connect_candidate(p, m_finished)) ++connect_candidates;
 
1261
                        if (prev != m_peers.end()) ++prev;
 
1262
                        if (i == m_peers.begin() + 1) prev = m_peers.begin();
 
1263
                        if (prev != m_peers.end())
 
1264
                        {
 
1265
                                if (m_torrent->settings().allow_multiple_connections_per_ip)
 
1266
                                        TORRENT_ASSERT(!((*i)->address() < (*prev)->address()));
 
1267
                                else
 
1268
                                        TORRENT_ASSERT((*prev)->address() < (*i)->address());
 
1269
                        }
 
1270
                        peer const& p = **i;
 
1271
                        if (is_connect_candidate(p, m_finished)) ++connect_candidates;
1173
1272
#ifndef TORRENT_DISABLE_GEO_IP
1174
1273
                        TORRENT_ASSERT(p.inet_as == 0 || p.inet_as->first == p.inet_as_num);
1175
1274
#endif
1176
1275
                        if (!m_torrent->settings().allow_multiple_connections_per_ip)
1177
1276
                        {
1178
 
                                TORRENT_ASSERT(m_peers.count(p.addr) == 1);
 
1277
                                std::pair<const_iterator, const_iterator> range = find_peers(p.address());
 
1278
                                TORRENT_ASSERT(range.second - range.first == 1);
1179
1279
                        }
1180
1280
                        else
1181
1281
                        {
1182
1282
                                TORRENT_ASSERT(unique_test.count(p.ip()) == 0);
1183
1283
                                unique_test.insert(p.ip());
1184
 
                                TORRENT_ASSERT(i->first == p.addr);
1185
1284
//                              TORRENT_ASSERT(p.connection == 0 || p.ip() == p.connection->remote());
1186
1285
                        }
1187
1286
                        ++total_connections;
1189
1288
                        {
1190
1289
                                continue;
1191
1290
                        }
1192
 
                        TORRENT_ASSERT(p.prev_amount_upload == 0);
1193
 
                        TORRENT_ASSERT(p.prev_amount_download == 0);
1194
1291
                        if (p.optimistically_unchoked)
1195
1292
                        {
1196
1293
                                TORRENT_ASSERT(p.connection);
1238
1335
                                if (p == 0) continue;
1239
1336
                                if (p->connection == 0) continue;
1240
1337
                                TORRENT_ASSERT(std::find_if(m_peers.begin(), m_peers.end()
1241
 
                                        , match_peer_connection(*p->connection)) != m_peers.end());
 
1338
                                        , match_peer_connection_or_endpoint(*p->connection)) != m_peers.end());
1242
1339
                        }
1243
1340
                }
1244
 
#endif
 
1341
#endif // TORRENT_EXPENSIVE_INVARIANT_CHECKS
1245
1342
 
1246
1343
                // this invariant is a bit complicated.
1247
1344
                // the usual case should be that connected_peers
1259
1356
                                && num_torrent_peers > 0));
1260
1357
*/
1261
1358
        }
1262
 
#endif
1263
 
 
1264
 
        policy::peer::peer(const tcp::endpoint& ip_, peer::connection_type t, int src)
 
1359
#endif // TORRENT_DEBUG
 
1360
 
 
1361
        policy::peer::peer()
 
1362
        {}
 
1363
 
 
1364
        policy::peer::peer(boost::uint16_t port, bool conn, int src)
1265
1365
                : prev_amount_upload(0)
1266
1366
                , prev_amount_download(0)
1267
 
                , addr(ip_.address())
1268
 
                , last_optimistically_unchoked(min_time())
1269
 
                , connected(min_time())
1270
1367
                , connection(0)
1271
1368
#ifndef TORRENT_DISABLE_GEO_IP
1272
1369
                , inet_as(0)
1273
1370
#endif
1274
 
                , port(ip_.port())
 
1371
                , last_optimistically_unchoked(0)
 
1372
                , last_connected(0)
 
1373
                , port(port)
 
1374
                , upload_rate_limit(0)
 
1375
                , download_rate_limit(0)
 
1376
                , hashfails(0)
1275
1377
                , failcount(0)
 
1378
                , connectable(conn)
 
1379
                , optimistically_unchoked(false)
 
1380
                , seed(false)
 
1381
                , fast_reconnects(0)
1276
1382
                , trust_points(0)
1277
1383
                , source(src)
1278
 
                , hashfails(0)
1279
 
                , type(t)
1280
 
                , fast_reconnects(0)
1281
1384
#ifndef TORRENT_DISABLE_ENCRYPTION
1282
1385
                , pe_support(true)
1283
1386
#endif
1284
 
                , optimistically_unchoked(false)
1285
 
                , seed(false)
 
1387
#if TORRENT_USE_IPV6
 
1388
                , is_v6_addr(false)
 
1389
#endif
1286
1390
                , on_parole(false)
1287
1391
                , banned(false)
1288
1392
#ifndef TORRENT_DISABLE_DHT
1290
1394
#endif
1291
1395
        {
1292
1396
                TORRENT_ASSERT((src & 0xff) == src);
1293
 
                TORRENT_ASSERT(connected < time_now());
1294
1397
        }
1295
1398
 
1296
1399
        size_type policy::peer::total_download() const
1319
1422
                }
1320
1423
        }
1321
1424
 
 
1425
        // this returns true if lhs is a better erase candidate than rhs
 
1426
        bool policy::compare_peer_erase(policy::peer const& lhs, policy::peer const& rhs) const
 
1427
        {
 
1428
                bool lhs_resume_data_source = lhs.source == peer_info::resume_data;
 
1429
                bool rhs_resume_data_source = rhs.source == peer_info::resume_data;
 
1430
 
 
1431
                // prefer to drop peers whose only source is resume data
 
1432
                if (lhs_resume_data_source != rhs_resume_data_source)
 
1433
                        return lhs_resume_data_source > rhs_resume_data_source;
 
1434
 
 
1435
                // prefer peers with higher failcount
 
1436
                return lhs.failcount > rhs.failcount;
 
1437
        }
 
1438
 
1322
1439
        // this returns true if lhs is a better connect candidate than rhs
1323
1440
        bool policy::compare_peer(policy::peer const& lhs, policy::peer const& rhs
1324
1441
                , address const& external_ip) const
1328
1445
                        return lhs.failcount < rhs.failcount;
1329
1446
 
1330
1447
                // Local peers should always be tried first
1331
 
                bool lhs_local = is_local(lhs.addr);
1332
 
                bool rhs_local = is_local(rhs.addr);
 
1448
                bool lhs_local = is_local(lhs.address());
 
1449
                bool rhs_local = is_local(rhs.address());
1333
1450
                if (lhs_local != rhs_local) return lhs_local > rhs_local;
1334
1451
 
1335
 
                if (lhs.connected != rhs.connected)
1336
 
                        return lhs.connected < rhs.connected;
 
1452
                if (lhs.last_connected != rhs.last_connected)
 
1453
                        return lhs.last_connected < rhs.last_connected;
 
1454
 
 
1455
                int lhs_rank = source_rank(lhs.source);
 
1456
                int rhs_rank = source_rank(rhs.source);
 
1457
                if (lhs_rank != rhs_rank) return lhs_rank > rhs_rank;
1337
1458
 
1338
1459
#ifndef TORRENT_DISABLE_GEO_IP
1339
1460
                // don't bias fast peers when seeding
1344
1465
                        if (lhs_as != rhs_as) return lhs_as > rhs_as;
1345
1466
                }
1346
1467
#endif
1347
 
                int lhs_distance = cidr_distance(external_ip, lhs.addr);
1348
 
                int rhs_distance = cidr_distance(external_ip, rhs.addr);
 
1468
                int lhs_distance = cidr_distance(external_ip, lhs.address());
 
1469
                int rhs_distance = cidr_distance(external_ip, rhs.address());
1349
1470
                if (lhs_distance < rhs_distance) return true;
1350
1471
                return false;
1351
1472
        }