~ubuntu-branches/ubuntu/wily/libtorrent/wily-proposed

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Rogério Brito
  • Date: 2011-03-20 01:06:18 UTC
  • mfrom: (1.1.13 upstream) (4.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20110320010618-g3wyylccqzqko73c
Tags: 0.12.7-5
* Use Steinar's "real" patch for IPv6. Addresses #490277, #618275,
  and Closes: #617791.
* Adapt libtorrent-0.12.6-ipv6-07.patch. It FTBFS otherwise.
* Add proper attibution to the IPv6 patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// libTorrent - BitTorrent library
 
2
// Copyright (C) 2005-2007, Jari Sundell
 
3
//
 
4
// This program is free software; you can redistribute it and/or modify
 
5
// it under the terms of the GNU General Public License as published by
 
6
// the Free Software Foundation; either version 2 of the License, or
 
7
// (at your option) any later version.
 
8
// 
 
9
// This program is distributed in the hope that it will be useful,
 
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
// GNU General Public License for more details.
 
13
// 
 
14
// You should have received a copy of the GNU General Public License
 
15
// along with this program; if not, write to the Free Software
 
16
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
//
 
18
// In addition, as a special exception, the copyright holders give
 
19
// permission to link the code of portions of this program with the
 
20
// OpenSSL library under certain conditions as described in each
 
21
// individual source file, and distribute linked combinations
 
22
// including the two.
 
23
//
 
24
// You must obey the GNU General Public License in all respects for
 
25
// all of the code used other than OpenSSL.  If you modify file(s)
 
26
// with this exception, you may extend this exception to your version
 
27
// of the file(s), but you are not obligated to do so.  If you do not
 
28
// wish to do so, delete this exception statement from your version.
 
29
// If you delete this exception statement from all source files in the
 
30
// program, then also delete it here.
 
31
//
 
32
// Contact:  Jari Sundell <jaris@ifi.uio.no>
 
33
//
 
34
//           Skomakerveien 33
 
35
//           3185 Skoppum, NORWAY
 
36
 
 
37
#include "config.h"
 
38
 
 
39
#include <algorithm>
 
40
#include <rak/functional.h>
 
41
#include <rak/string_manip.h>
 
42
 
 
43
#include "client_list.h"
 
44
#include "exceptions.h"
 
45
#include "hash_string.h"
 
46
 
 
47
namespace torrent {
 
48
 
 
49
ClientList::ClientList() {
 
50
  insert(ClientInfo::TYPE_UNKNOWN, NULL, NULL, NULL);
 
51
 
 
52
  // Move this to a seperate initialize function in libtorrent.
 
53
 
 
54
  // Sorted by popularity to optimize search. This list is heavily
 
55
  // biased by my own prejudices, and not at all based on facts.
 
56
 
 
57
  // First batch of clients.
 
58
  insert_helper(ClientInfo::TYPE_AZUREUS, "AZ", NULL, NULL, "Azureus");
 
59
  insert_helper(ClientInfo::TYPE_AZUREUS, "BC", NULL, NULL, "BitComet");
 
60
  insert_helper(ClientInfo::TYPE_AZUREUS, "CD", NULL, NULL, "Enhanced CTorrent");
 
61
  insert_helper(ClientInfo::TYPE_AZUREUS, "KT", NULL, NULL, "KTorrent");
 
62
  insert_helper(ClientInfo::TYPE_AZUREUS, "LT", NULL, NULL, "libtorrent");
 
63
  insert_helper(ClientInfo::TYPE_AZUREUS, "lt", NULL, NULL, "libTorrent");
 
64
  insert_helper(ClientInfo::TYPE_AZUREUS, "UT", NULL, NULL, "uTorrent");
 
65
 
 
66
  insert_helper(ClientInfo::TYPE_MAINLINE, "M", NULL, NULL, "Mainline");
 
67
 
 
68
  insert_helper(ClientInfo::TYPE_COMPACT, "T", NULL, NULL, "BitTornado");
 
69
 
 
70
  // Second batch of clients.
 
71
  insert_helper(ClientInfo::TYPE_AZUREUS, "AR", NULL, NULL, "Arctic");
 
72
  insert_helper(ClientInfo::TYPE_AZUREUS, "BB", NULL, NULL, "BitBuddy");
 
73
  insert_helper(ClientInfo::TYPE_AZUREUS, "BX", NULL, NULL, "Bittorrent X");
 
74
  insert_helper(ClientInfo::TYPE_AZUREUS, "BS", NULL, NULL, "BTSlave");
 
75
  insert_helper(ClientInfo::TYPE_AZUREUS, "CT", NULL, NULL, "CTorrent");
 
76
  insert_helper(ClientInfo::TYPE_AZUREUS, "DE", NULL, NULL, "DelugeTorrent");
 
77
  insert_helper(ClientInfo::TYPE_AZUREUS, "ES", NULL, NULL, "Electric Sheep");
 
78
  insert_helper(ClientInfo::TYPE_AZUREUS, "LP", NULL, NULL, "Lphant");
 
79
  insert_helper(ClientInfo::TYPE_AZUREUS, "MT", NULL, NULL, "MoonlightTorrent");
 
80
  insert_helper(ClientInfo::TYPE_AZUREUS, "MP", NULL, NULL, "MooPolice");
 
81
  insert_helper(ClientInfo::TYPE_AZUREUS, "QT", NULL, NULL, "Qt 4 Torrent");
 
82
  insert_helper(ClientInfo::TYPE_AZUREUS, "RT", NULL, NULL, "Retriever");
 
83
  insert_helper(ClientInfo::TYPE_AZUREUS, "SZ", NULL, NULL, "Shareaza");
 
84
  insert_helper(ClientInfo::TYPE_AZUREUS, "SS", NULL, NULL, "SwarmScope");
 
85
  insert_helper(ClientInfo::TYPE_AZUREUS, "SB", NULL, NULL, "Swiftbit");
 
86
  insert_helper(ClientInfo::TYPE_AZUREUS, "TN", NULL, NULL, "TorrentDotNET");
 
87
  insert_helper(ClientInfo::TYPE_AZUREUS, "TS", NULL, NULL, "Torrentstorm");
 
88
  insert_helper(ClientInfo::TYPE_AZUREUS, "TR", NULL, NULL, "Transmission");
 
89
  insert_helper(ClientInfo::TYPE_AZUREUS, "XT", NULL, NULL, "XanTorrent");
 
90
  insert_helper(ClientInfo::TYPE_AZUREUS, "ZT", NULL, NULL, "ZipTorrent");
 
91
 
 
92
  insert_helper(ClientInfo::TYPE_COMPACT, "A", NULL, NULL, "ABC");
 
93
  insert_helper(ClientInfo::TYPE_COMPACT, "S", NULL, NULL, "Shadow's client");
 
94
  insert_helper(ClientInfo::TYPE_COMPACT, "U", NULL, NULL, "UPnP NAT BitTorrent");
 
95
  insert_helper(ClientInfo::TYPE_COMPACT, "O", NULL, NULL, "Osprey Permaseed");
 
96
 
 
97
  // Third batch of clients.
 
98
  insert_helper(ClientInfo::TYPE_AZUREUS, "AX", NULL, NULL, "BitPump");
 
99
  insert_helper(ClientInfo::TYPE_AZUREUS, "BF", NULL, NULL, "BitFlu");
 
100
  insert_helper(ClientInfo::TYPE_AZUREUS, "BG", NULL, NULL, "BTG");
 
101
  insert_helper(ClientInfo::TYPE_AZUREUS, "BR", NULL, NULL, "BitRocket");
 
102
  insert_helper(ClientInfo::TYPE_AZUREUS, "EB", NULL, NULL, "EBit");
 
103
  insert_helper(ClientInfo::TYPE_AZUREUS, "HL", NULL, NULL, "Halite");
 
104
  insert_helper(ClientInfo::TYPE_AZUREUS, "qB", NULL, NULL, "qBittorrent");
 
105
  insert_helper(ClientInfo::TYPE_AZUREUS, "UL", NULL, NULL, "uLeecher!");
 
106
  insert_helper(ClientInfo::TYPE_AZUREUS, "XL", NULL, NULL, "XeiLun");
 
107
 
 
108
  insert_helper(ClientInfo::TYPE_COMPACT, "R", NULL, NULL, "Tribler");
 
109
}
 
110
 
 
111
ClientList::~ClientList() {
 
112
  for (iterator itr = begin(), last = end(); itr != last; ++itr)
 
113
    delete itr->info();
 
114
}
 
115
 
 
116
ClientList::iterator
 
117
ClientList::insert(ClientInfo::id_type type, const char* key, const char* version, const char* upperVersion) {
 
118
  if (type >= ClientInfo::TYPE_MAX_SIZE)
 
119
    throw input_error("Invalid client info id type.");
 
120
 
 
121
  ClientInfo clientInfo;
 
122
 
 
123
  clientInfo.set_type(type);
 
124
  clientInfo.set_info(new ClientInfo::info_type);
 
125
  clientInfo.set_short_description("Unknown");
 
126
 
 
127
  std::memset(clientInfo.mutable_key(), 0, ClientInfo::max_key_size);
 
128
 
 
129
  if (key == NULL)
 
130
    std::memset(clientInfo.mutable_key(), 0, ClientInfo::max_key_size);
 
131
  else
 
132
    std::strncpy(clientInfo.mutable_key(), key, ClientInfo::max_key_size);
 
133
    
 
134
  if (version != NULL)
 
135
    std::memcpy(clientInfo.mutable_version(), version, ClientInfo::max_version_size);
 
136
  else
 
137
    std::memset(clientInfo.mutable_version(), 0, ClientInfo::max_version_size);
 
138
 
 
139
  if (upperVersion != NULL)
 
140
    std::memcpy(clientInfo.mutable_upper_version(), upperVersion, ClientInfo::max_version_size);
 
141
  else
 
142
    std::memset(clientInfo.mutable_upper_version(), -1, ClientInfo::max_version_size);
 
143
 
 
144
  return base_type::insert(end(), clientInfo);
 
145
}
 
146
 
 
147
ClientList::iterator
 
148
ClientList::insert_helper(ClientInfo::id_type type,
 
149
                          const char* key,
 
150
                          const char* version,
 
151
                          const char* upperVersion,
 
152
                          const char* shortDescription) {
 
153
  char newKey[ClientInfo::max_key_size];
 
154
 
 
155
  std::memset(newKey, 0, ClientInfo::max_key_size);
 
156
  std::memcpy(newKey, key, ClientInfo::key_size(type));
 
157
 
 
158
  iterator itr = insert(type, newKey, version, upperVersion);
 
159
  itr->set_short_description(shortDescription);
 
160
 
 
161
  return itr;
 
162
}
 
163
 
 
164
// Make this properly honor const-ness.
 
165
bool
 
166
ClientList::retrieve_id(ClientInfo* dest, const HashString& id) const {
 
167
  if (id[0] == '-' && id[7] == '-' &&
 
168
      std::isalpha(id[1]) && std::isalpha(id[2]) &&
 
169
      std::isxdigit(id[3]) && std::isxdigit(id[4]) && std::isxdigit(id[5]) && std::isxdigit(id[6])) {
 
170
    dest->set_type(ClientInfo::TYPE_AZUREUS);
 
171
 
 
172
    dest->mutable_key()[0] = id[1];
 
173
    dest->mutable_key()[1] = id[2];
 
174
    
 
175
    for (int i = 0; i < 4; i++)
 
176
      dest->mutable_version()[i] = dest->mutable_upper_version()[i] = rak::hexchar_to_value(id[3 + i]);
 
177
 
 
178
  } else if (std::isalpha(id[0]) && id[4] == '-' &&
 
179
             std::isxdigit(id[1]) && std::isxdigit(id[2]) && std::isxdigit(id[3])) {
 
180
    dest->set_type(ClientInfo::TYPE_COMPACT);
 
181
 
 
182
    dest->mutable_key()[0] = id[0];
 
183
    dest->mutable_key()[1] = '\0';
 
184
    
 
185
    dest->mutable_version()[0] = dest->mutable_upper_version()[0] = rak::hexchar_to_value(id[1]);
 
186
    dest->mutable_version()[1] = dest->mutable_upper_version()[1] = rak::hexchar_to_value(id[2]);
 
187
    dest->mutable_version()[2] = dest->mutable_upper_version()[2] = rak::hexchar_to_value(id[3]);
 
188
    dest->mutable_version()[3] = dest->mutable_upper_version()[3] = '\0';
 
189
 
 
190
  } else if (std::isalpha(id[0]) && std::isdigit(id[1]) && id[2] == '-' &&
 
191
             std::isdigit(id[3]) && (id[6] == '-' || id[7] == '-')) {
 
192
 
 
193
    dest->set_type(ClientInfo::TYPE_MAINLINE);
 
194
 
 
195
    dest->mutable_key()[0] = id[0];
 
196
    dest->mutable_key()[1] = '\0';
 
197
    
 
198
    dest->mutable_version()[0] = dest->mutable_upper_version()[0] = rak::hexchar_to_value(id[1]);
 
199
 
 
200
    if (id[4] == '-' && std::isdigit(id[5]) && id[6] == '-') {
 
201
      dest->mutable_version()[1] = dest->mutable_upper_version()[1] = rak::hexchar_to_value(id[3]);
 
202
      dest->mutable_version()[2] = dest->mutable_upper_version()[2] = rak::hexchar_to_value(id[5]);
 
203
      dest->mutable_version()[3] = dest->mutable_upper_version()[3] = '\0';
 
204
 
 
205
    } else if (std::isdigit(id[4]) && id[5] == '-' && std::isdigit(id[6]) && id[7] == '-') {
 
206
      dest->mutable_version()[1] = dest->mutable_upper_version()[1] = rak::hexchar_to_value(id[3]) * 10 + rak::hexchar_to_value(id[4]);
 
207
      dest->mutable_version()[2] = dest->mutable_upper_version()[2] = rak::hexchar_to_value(id[6]);
 
208
      dest->mutable_version()[3] = dest->mutable_upper_version()[3] = '\0';
 
209
 
 
210
    } else {
 
211
      *dest = *begin();
 
212
      std::memset(dest->mutable_upper_version(), 0, ClientInfo::max_version_size);
 
213
 
 
214
      return false;
 
215
    }
 
216
 
 
217
  } else {
 
218
    // And then the incompatible idiots that make life difficult for us
 
219
    // others. (There's '3' schemes to choose from already...)
 
220
    //
 
221
    // Or not...
 
222
 
 
223
    // The first entry always contains the default ClientInfo.
 
224
    *dest = *begin();
 
225
    std::memset(dest->mutable_upper_version(), 0, ClientInfo::max_version_size);
 
226
 
 
227
    return false;
 
228
  }
 
229
 
 
230
  const_iterator itr = std::find_if(begin() + 1, end(), rak::bind1st(std::ptr_fun(&ClientInfo::intersects), *dest));
 
231
 
 
232
  if (itr == end())
 
233
    dest->set_info(begin()->info());
 
234
  else
 
235
    dest->set_info(itr->info());    
 
236
 
 
237
  return true;
 
238
}
 
239
 
 
240
void
 
241
ClientList::retrieve_unknown(ClientInfo* dest) const {
 
242
  *dest = *begin();
 
243
  std::memset(dest->mutable_upper_version(), 0, ClientInfo::max_version_size);
 
244
}
 
245
 
 
246
}