~ubuntu-branches/debian/stretch/libtorrent/stretch

« back to all changes in this revision

Viewing changes to src/torrent/peer/peer_list.cc

  • Committer: Package Import Robot
  • Author(s): Jose Luis Rivas, Jonathan McDowell, Jose Luis Rivas
  • Date: 2015-09-30 04:03:36 UTC
  • mfrom: (1.3.7) (7.1.10 sid)
  • Revision ID: package-import@ubuntu.com-20150930040336-3u97dzmsdtd3jx03
Tags: 0.13.6-1
[ Jonathan McDowell ]
* Remove Benoît Knecht from Uploaders. Closes: #779430.

[ Jose Luis Rivas ]
* New upstream version.
* debian/watch now uses github.
* Bumped package to match the soname change. Closes: #797866.
  (urgency=medium since this is an RC-bug, gcc5 transition)
* Removed patches, they were already applied upstream.
* Updated homepage.

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
 
37
37
#include "config.h"
38
38
 
 
39
#define __STDC_FORMAT_MACROS
 
40
 
39
41
#include <algorithm>
40
42
#include <functional>
41
43
#include <rak/functional.h>
43
45
 
44
46
#include "download/available_list.h"
45
47
#include "torrent/peer/client_list.h"
 
48
#include "torrent/utils/log.h"
46
49
 
 
50
#include "download_info.h"
47
51
#include "exceptions.h"
48
52
#include "globals.h"
49
53
#include "manager.h"
50
54
#include "peer_info.h"
51
55
#include "peer_list.h"
52
56
 
 
57
#define LT_LOG_EVENTS(log_fmt, ...)                                     \
 
58
  lt_log_print_info(LOG_PEER_LIST_EVENTS, m_info, "peer_list", log_fmt, __VA_ARGS__);
 
59
#define LT_LOG_SA_FMT "'%s:%" PRIu16 "'"
 
60
 
53
61
namespace torrent {
54
62
 
55
63
ipv4_table PeerList::m_ipv4_table;
84
92
  }
85
93
};
86
94
 
 
95
//
 
96
// PeerList:
 
97
//
 
98
 
87
99
PeerList::PeerList() :
88
 
  m_availableList(new AvailableList) {
 
100
  m_available_list(new AvailableList) {
89
101
}
90
102
 
91
103
PeerList::~PeerList() {
 
104
  LT_LOG_EVENTS("deleting list total:%" PRIuPTR " available:%" PRIuPTR,
 
105
                size(), m_available_list->size());
 
106
 
92
107
  std::for_each(begin(), end(), rak::on(rak::mem_ref(&value_type::second), rak::call_delete<PeerInfo>()));
93
108
  base_type::clear();
94
109
 
95
 
  delete m_availableList;
 
110
  m_info = NULL;
 
111
  delete m_available_list;
 
112
}
 
113
 
 
114
void
 
115
PeerList::set_info(DownloadInfo* info) {
 
116
  m_info = info;
 
117
 
 
118
  LT_LOG_EVENTS("creating list", 0);
96
119
}
97
120
 
98
121
PeerInfo*
99
122
PeerList::insert_address(const sockaddr* sa, int flags) {
100
 
  if (!socket_address_key::is_comparable(sa))
 
123
  if (!socket_address_key::is_comparable(sa)) {
 
124
    LT_LOG_EVENTS("address not comparable", 0);
101
125
    return NULL;
 
126
  }
 
127
 
 
128
  const rak::socket_address* address = rak::socket_address::cast_from(sa);
102
129
 
103
130
  range_type range = base_type::equal_range(sa);
104
131
 
107
134
  //
108
135
  // What we do depends on the flags, but for now just allow one
109
136
  // PeerInfo per address key and do nothing.
110
 
  if (range.first != range.second)
 
137
  if (range.first != range.second) {
 
138
    LT_LOG_EVENTS("address already exists " LT_LOG_SA_FMT,
 
139
                  address->address_str().c_str(), address->port());
111
140
    return NULL;
112
 
 
113
 
  const rak::socket_address* address = rak::socket_address::cast_from(sa);
 
141
  }
114
142
 
115
143
  PeerInfo* peerInfo = new PeerInfo(sa);
116
144
  peerInfo->set_listen_port(address->port());
120
148
 
121
149
  base_type::insert(range.second, value_type(socket_address_key(peerInfo->socket_address()), peerInfo));
122
150
 
123
 
  if (flags & address_available && peerInfo->listen_port() != 0)
124
 
    m_availableList->push_back(address);
 
151
  if ((flags & address_available) && peerInfo->listen_port() != 0) {
 
152
    m_available_list->push_back(address);
 
153
    LT_LOG_EVENTS("added available address " LT_LOG_SA_FMT,
 
154
                  address->address_str().c_str(), address->port());
 
155
  } else {
 
156
    LT_LOG_EVENTS("added unavailable address " LT_LOG_SA_FMT,
 
157
                  address->address_str().c_str(), address->port());
 
158
  }
125
159
 
126
160
  return peerInfo;
127
161
}
133
167
 
134
168
uint32_t
135
169
PeerList::insert_available(const void* al) {
 
170
  const AddressList* addressList = static_cast<const AddressList*>(al);
 
171
 
136
172
  uint32_t inserted = 0;
137
 
  const AddressList* addressList = static_cast<const AddressList*>(al);
 
173
  uint32_t invalid = 0;
 
174
  uint32_t unneeded = 0;
 
175
  uint32_t updated = 0;
138
176
 
139
 
  if (m_availableList->size() + addressList->size() > m_availableList->capacity())
140
 
    m_availableList->reserve(m_availableList->size() + addressList->size() + 128);
 
177
  if (m_available_list->size() + addressList->size() > m_available_list->capacity())
 
178
    m_available_list->reserve(m_available_list->size() + addressList->size() + 128);
141
179
 
142
180
  // Optimize this so that we don't traverse the tree for every
143
181
  // insert, since we know 'al' is sorted.
144
182
 
145
183
  AddressList::const_iterator itr   = addressList->begin();
146
184
  AddressList::const_iterator last  = addressList->end();
147
 
  AvailableList::const_iterator availItr  = m_availableList->begin();
148
 
  AvailableList::const_iterator availLast = m_availableList->end();
 
185
  AvailableList::const_iterator availItr  = m_available_list->begin();
 
186
  AvailableList::const_iterator availLast = m_available_list->end();
149
187
 
150
188
  for (; itr != last; itr++) {
151
 
    if (!socket_address_key::is_comparable(itr->c_sockaddr()) || itr->port() == 0)
 
189
    if (!socket_address_key::is_comparable(itr->c_sockaddr()) || itr->port() == 0) {
 
190
      invalid++;
152
191
      continue;
 
192
    }
153
193
 
154
194
    availItr = std::find_if(availItr, availLast, rak::bind2nd(std::ptr_fun(&socket_address_less_rak), *itr));
155
195
 
156
196
    if (availItr != availLast && !socket_address_less(availItr->c_sockaddr(), itr->c_sockaddr())) {
157
 
      // The address is already in m_availableList, so don't bother
 
197
      // The address is already in m_available_list, so don't bother
158
198
      // going further.
 
199
      unneeded++;
159
200
      continue;
160
201
    }
161
202
 
174
215
        peerInfo->set_port(itr->port());
175
216
 
176
217
      if (peerInfo->connection() != NULL ||
177
 
          peerInfo->last_handshake() + 600 > (uint32_t)cachedTime.seconds())
 
218
          peerInfo->last_handshake() + 600 > (uint32_t)cachedTime.seconds()) {
 
219
        updated++;
178
220
        continue;
 
221
      }
179
222
 
180
223
      // If the peer has sent us bad chunks or we just connected or
181
224
      // tried to do so a few minutes ago, only update its
188
231
    // won't happen often enough to be worth it.
189
232
 
190
233
    inserted++;
191
 
    m_availableList->push_back(&*itr);
 
234
    m_available_list->push_back(&*itr);
192
235
  }
193
236
 
 
237
  LT_LOG_EVENTS("inserted peers"
 
238
                " inserted:%" PRIu32 " invalid:%" PRIu32
 
239
                " unneeded:%" PRIu32 " updated:%" PRIu32
 
240
                " total:%" PRIuPTR " available:%" PRIuPTR,
 
241
                inserted, invalid, unneeded, updated,
 
242
                size(), m_available_list->size());
 
243
 
194
244
  return inserted;
195
245
}
196
246
 
197
247
uint32_t
198
248
PeerList::available_list_size() const {
199
 
  return m_availableList->size();
 
249
  return m_available_list->size();
200
250
}
201
251
 
202
252
PeerInfo*
238
288
    if (flags & connect_keep_handshakes &&
239
289
        range.first->second->is_handshake() &&
240
290
        rak::socket_address::cast_from(range.first->second->socket_address())->port() != address->port())
241
 
      m_availableList->buffer()->push_back(*address);
 
291
      m_available_list->buffer()->push_back(*address);
242
292
 
243
293
    return NULL;
244
294
  }
287
337
  if (!itr->second->is_connected())
288
338
    throw internal_error("PeerList::disconnected(...) !itr->is_connected().");
289
339
 
 
340
  if (itr->second->transfer_counter() != 0) {
 
341
    // Currently we only log these as it only affects the culling of
 
342
    // peers.
 
343
    LT_LOG_EVENTS("disconnected with non-zero transfer counter (%" PRIu32 ") for peer %40s",
 
344
                  itr->second->transfer_counter(), itr->second->id_hex());
 
345
  }
 
346
 
290
347
  itr->second->unset_flags(PeerInfo::flag_connected);
291
348
 
292
349
  // Replace the socket address port with the listening port so that
297
354
    itr->second->set_last_connection(cachedTime.seconds());
298
355
 
299
356
  if (flags & disconnect_available && itr->second->listen_port() != 0)
300
 
    m_availableList->push_back(rak::socket_address::cast_from(itr->second->socket_address()));
 
357
    m_available_list->push_back(rak::socket_address::cast_from(itr->second->socket_address()));
301
358
 
302
359
  // Do magic to get rid of unneeded entries.
303
360
  return ++itr;
315
372
 
316
373
  for (iterator itr = base_type::begin(); itr != base_type::end(); ) {
317
374
    if (itr->second->is_connected() ||
318
 
        itr->second->transfer_counter() != 0 ||
 
375
        itr->second->transfer_counter() != 0 || // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
319
376
        itr->second->last_connection() >= timer ||
320
377
 
321
378
        (flags & cull_keep_interesting && 
324
381
      continue;
325
382
    }
326
383
 
 
384
    // ##################### TODO: LOG CULLING OF PEERS ######################
 
385
    //   *** AND STATS OF DISCONNECTING PEERS (the peer info...)...
 
386
 
327
387
    // The key is a pointer to a member in the value, although the key
328
388
    // shouldn't actually be used in erase (I think), just ot be safe
329
389
    // we delete it after erase.