2003-12-22 08:14:35 +01:00
|
|
|
/*
|
|
|
|
|
2018-04-09 09:04:33 +02:00
|
|
|
Copyright (c) 2003-2018, Arvid Norberg
|
2003-12-22 08:14:35 +01:00
|
|
|
All rights reserved.
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions
|
|
|
|
are met:
|
|
|
|
|
|
|
|
* Redistributions of source code must retain the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
* Redistributions in binary form must reproduce the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer in
|
|
|
|
the documentation and/or other materials provided with the distribution.
|
|
|
|
* Neither the name of the author nor the names of its
|
|
|
|
contributors may be used to endorse or promote products derived
|
|
|
|
from this software without specific prior written permission.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <cctype>
|
2005-03-13 13:52:21 +01:00
|
|
|
#include <algorithm>
|
2009-01-27 09:24:48 +01:00
|
|
|
#include <stdio.h>
|
2003-12-22 08:14:35 +01:00
|
|
|
|
2015-04-21 03:16:28 +02:00
|
|
|
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
2004-01-25 19:18:36 +01:00
|
|
|
#include <boost/optional.hpp>
|
2015-04-21 03:16:28 +02:00
|
|
|
#include "libtorrent/aux_/disable_warnings_pop.hpp"
|
2004-01-25 19:18:36 +01:00
|
|
|
|
2003-12-22 08:14:35 +01:00
|
|
|
#include "libtorrent/identify_client.hpp"
|
|
|
|
#include "libtorrent/fingerprint.hpp"
|
2012-08-26 17:26:17 +02:00
|
|
|
#include "libtorrent/string_util.hpp"
|
2003-12-22 08:14:35 +01:00
|
|
|
|
2004-02-19 12:35:08 +01:00
|
|
|
namespace
|
2003-12-22 08:14:35 +01:00
|
|
|
{
|
|
|
|
|
2004-02-19 12:35:08 +01:00
|
|
|
using namespace libtorrent;
|
|
|
|
|
2004-07-18 02:39:58 +02:00
|
|
|
int decode_digit(char c)
|
|
|
|
{
|
2009-01-11 21:40:43 +01:00
|
|
|
if (is_digit(c)) return c - '0';
|
2005-06-12 02:21:37 +02:00
|
|
|
return unsigned(c) - 'A' + 10;
|
2004-07-18 02:39:58 +02:00
|
|
|
}
|
|
|
|
|
2004-02-19 12:35:08 +01:00
|
|
|
// takes a peer id and returns a valid boost::optional
|
|
|
|
// object if the peer id matched the azureus style encoding
|
|
|
|
// the returned fingerprint contains information about the
|
|
|
|
// client's id
|
|
|
|
boost::optional<fingerprint> parse_az_style(const peer_id& id)
|
2003-12-22 08:14:35 +01:00
|
|
|
{
|
2004-02-19 12:35:08 +01:00
|
|
|
fingerprint ret("..", 0, 0, 0, 0);
|
2003-12-22 08:14:35 +01:00
|
|
|
|
2009-06-23 03:53:47 +02:00
|
|
|
if (id[0] != '-' || !is_print(id[1]) || (id[2] < '0')
|
2005-06-12 02:21:37 +02:00
|
|
|
|| (id[3] < '0') || (id[4] < '0')
|
|
|
|
|| (id[5] < '0') || (id[6] < '0')
|
2004-08-08 23:26:40 +02:00
|
|
|
|| id[7] != '-')
|
|
|
|
return boost::optional<fingerprint>();
|
2003-12-22 08:14:35 +01:00
|
|
|
|
2006-04-25 23:04:48 +02:00
|
|
|
ret.name[0] = id[1];
|
|
|
|
ret.name[1] = id[2];
|
2004-08-08 23:26:40 +02:00
|
|
|
ret.major_version = decode_digit(id[3]);
|
|
|
|
ret.minor_version = decode_digit(id[4]);
|
|
|
|
ret.revision_version = decode_digit(id[5]);
|
|
|
|
ret.tag_version = decode_digit(id[6]);
|
2004-02-19 12:35:08 +01:00
|
|
|
|
|
|
|
return boost::optional<fingerprint>(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
// checks if a peer id can possibly contain a shadow-style
|
|
|
|
// identification
|
|
|
|
boost::optional<fingerprint> parse_shadow_style(const peer_id& id)
|
|
|
|
{
|
|
|
|
fingerprint ret("..", 0, 0, 0, 0);
|
|
|
|
|
2009-11-28 23:41:21 +01:00
|
|
|
if (!is_alpha(id[0]) && !is_digit(id[0]))
|
2004-08-08 23:26:40 +02:00
|
|
|
return boost::optional<fingerprint>();
|
2004-02-19 12:35:08 +01:00
|
|
|
|
2005-06-23 01:04:37 +02:00
|
|
|
if (std::equal(id.begin()+4, id.begin()+6, "--"))
|
2004-02-19 12:35:08 +01:00
|
|
|
{
|
2005-06-23 01:04:37 +02:00
|
|
|
if ((id[1] < '0') || (id[2] < '0')
|
2005-06-12 02:21:37 +02:00
|
|
|
|| (id[3] < '0'))
|
2004-08-08 23:26:40 +02:00
|
|
|
return boost::optional<fingerprint>();
|
|
|
|
ret.major_version = decode_digit(id[1]);
|
|
|
|
ret.minor_version = decode_digit(id[2]);
|
|
|
|
ret.revision_version = decode_digit(id[3]);
|
2004-02-19 12:35:08 +01:00
|
|
|
}
|
2004-08-08 23:26:40 +02:00
|
|
|
else
|
2004-02-19 12:35:08 +01:00
|
|
|
{
|
2004-08-08 23:26:40 +02:00
|
|
|
if (id[8] != 0 || id[1] > 127 || id[2] > 127 || id[3] > 127)
|
|
|
|
return boost::optional<fingerprint>();
|
|
|
|
ret.major_version = id[1];
|
|
|
|
ret.minor_version = id[2];
|
|
|
|
ret.revision_version = id[3];
|
2003-12-22 08:14:35 +01:00
|
|
|
}
|
2004-08-08 23:26:40 +02:00
|
|
|
|
2006-04-25 23:04:48 +02:00
|
|
|
ret.name[0] = id[0];
|
|
|
|
ret.name[1] = 0;
|
2003-12-22 08:14:35 +01:00
|
|
|
|
2004-02-19 12:35:08 +01:00
|
|
|
ret.tag_version = 0;
|
|
|
|
return boost::optional<fingerprint>(ret);
|
|
|
|
}
|
2003-12-22 08:14:35 +01:00
|
|
|
|
2004-06-14 01:30:42 +02:00
|
|
|
// checks if a peer id can possibly contain a mainline-style
|
|
|
|
// identification
|
|
|
|
boost::optional<fingerprint> parse_mainline_style(const peer_id& id)
|
|
|
|
{
|
2006-07-23 21:42:13 +02:00
|
|
|
char ids[21];
|
|
|
|
std::copy(id.begin(), id.end(), ids);
|
|
|
|
ids[20] = 0;
|
2004-06-14 01:30:42 +02:00
|
|
|
fingerprint ret("..", 0, 0, 0, 0);
|
2006-04-25 23:04:48 +02:00
|
|
|
ret.name[1] = 0;
|
2004-08-08 23:26:40 +02:00
|
|
|
ret.tag_version = 0;
|
2006-07-23 21:42:59 +02:00
|
|
|
if (sscanf(ids, "%c%d-%d-%d--", &ret.name[0], &ret.major_version, &ret.minor_version
|
2006-07-23 21:42:13 +02:00
|
|
|
, &ret.revision_version) != 4
|
2009-06-23 03:53:47 +02:00
|
|
|
|| !is_print(ret.name[0]))
|
2006-07-23 21:42:13 +02:00
|
|
|
return boost::optional<fingerprint>();
|
|
|
|
|
2004-08-08 23:26:40 +02:00
|
|
|
return boost::optional<fingerprint>(ret);
|
|
|
|
}
|
2004-06-14 01:30:42 +02:00
|
|
|
|
2007-05-14 14:02:57 +02:00
|
|
|
struct map_entry
|
|
|
|
{
|
|
|
|
char const* id;
|
|
|
|
char const* name;
|
|
|
|
};
|
2004-06-14 01:30:42 +02:00
|
|
|
|
2004-10-13 15:13:52 +02:00
|
|
|
// only support BitTorrentSpecification
|
2004-08-08 23:26:40 +02:00
|
|
|
// must be ordered alphabetically
|
|
|
|
map_entry name_map[] =
|
|
|
|
{
|
2016-10-25 14:03:26 +02:00
|
|
|
{"7T", "aTorrent for android"}
|
|
|
|
, {"A", "ABC"}
|
|
|
|
, {"AB", "AnyEvent BitTorrent"}
|
2013-02-16 19:29:09 +01:00
|
|
|
, {"AG", "Ares"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"AR", "Arctic Torrent"}
|
2010-04-28 18:14:27 +02:00
|
|
|
, {"AT", "Artemis"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"AV", "Avicora"}
|
|
|
|
, {"AX", "BitPump"}
|
|
|
|
, {"AZ", "Azureus"}
|
2013-02-16 19:29:09 +01:00
|
|
|
, {"A~", "Ares"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"BB", "BitBuddy"}
|
|
|
|
, {"BC", "BitComet"}
|
2014-06-13 19:34:15 +02:00
|
|
|
, {"BE", "baretorrent"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"BF", "Bitflu"}
|
|
|
|
, {"BG", "BTG"}
|
2010-04-28 18:14:27 +02:00
|
|
|
, {"BL", "BitBlinder"}
|
|
|
|
, {"BP", "BitTorrent Pro"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"BR", "BitRocket"}
|
|
|
|
, {"BS", "BTSlave"}
|
2014-06-13 19:34:15 +02:00
|
|
|
, {"BT", "BitTorrent"}
|
|
|
|
, {"BU", "BigUp"}
|
2010-04-28 18:14:27 +02:00
|
|
|
, {"BW", "BitWombat"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"BX", "BittorrentX"}
|
|
|
|
, {"CD", "Enhanced CTorrent"}
|
|
|
|
, {"CT", "CTorrent"}
|
2009-04-12 20:46:07 +02:00
|
|
|
, {"DE", "Deluge"}
|
2010-04-28 18:14:27 +02:00
|
|
|
, {"DP", "Propagate Data Client"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"EB", "EBit"}
|
|
|
|
, {"ES", "electric sheep"}
|
2010-04-28 18:14:27 +02:00
|
|
|
, {"FC", "FileCroc"}
|
|
|
|
, {"FT", "FoxTorrent"}
|
2014-06-13 19:34:15 +02:00
|
|
|
, {"FX", "Freebox BitTorrent"}
|
2010-04-28 18:14:27 +02:00
|
|
|
, {"GS", "GSTorrent"}
|
|
|
|
, {"HK", "Hekate"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"HL", "Halite"}
|
|
|
|
, {"HN", "Hydranode"}
|
2014-06-13 19:34:15 +02:00
|
|
|
, {"IL", "iLivid"}
|
2010-04-28 18:14:27 +02:00
|
|
|
, {"KG", "KGet"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"KT", "KTorrent"}
|
2008-08-10 22:18:18 +02:00
|
|
|
, {"LC", "LeechCraft"}
|
2010-04-28 18:14:27 +02:00
|
|
|
, {"LH", "LH-ABC"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"LK", "Linkage"}
|
|
|
|
, {"LP", "lphant"}
|
|
|
|
, {"LT", "libtorrent"}
|
2010-04-28 18:14:27 +02:00
|
|
|
, {"LW", "Limewire"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"M", "Mainline"}
|
|
|
|
, {"ML", "MLDonkey"}
|
|
|
|
, {"MO", "Mono Torrent"}
|
|
|
|
, {"MP", "MooPolice"}
|
2007-11-22 03:29:44 +01:00
|
|
|
, {"MR", "Miro"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"MT", "Moonlight Torrent"}
|
2010-04-28 18:14:27 +02:00
|
|
|
, {"NX", "Net Transport"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"O", "Osprey Permaseed"}
|
2013-02-16 19:29:09 +01:00
|
|
|
, {"OS", "OneSwarm"}
|
|
|
|
, {"OT", "OmegaTorrent"}
|
|
|
|
, {"PD", "Pando"}
|
|
|
|
, {"Q", "BTQueue"}
|
2010-04-16 18:08:39 +02:00
|
|
|
, {"QD", "QQDownload"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"QT", "Qt 4"}
|
|
|
|
, {"R", "Tribler"}
|
2013-02-16 19:29:09 +01:00
|
|
|
, {"RT", "Retriever"}
|
|
|
|
, {"RZ", "RezTorrent"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"S", "Shadow"}
|
|
|
|
, {"SB", "Swiftbit"}
|
2010-04-16 18:08:39 +02:00
|
|
|
, {"SD", "Xunlei"}
|
2014-06-13 19:34:15 +02:00
|
|
|
, {"SK", "spark"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"SN", "ShareNet"}
|
|
|
|
, {"SS", "SwarmScope"}
|
2007-08-24 04:11:41 +02:00
|
|
|
, {"ST", "SymTorrent"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"SZ", "Shareaza"}
|
2013-02-16 19:29:09 +01:00
|
|
|
, {"S~", "Shareaza (beta)"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"T", "BitTornado"}
|
2014-06-13 19:34:15 +02:00
|
|
|
, {"TB", "Torch"}
|
2013-02-16 19:29:09 +01:00
|
|
|
, {"TL", "Tribler"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"TN", "Torrent.NET"}
|
|
|
|
, {"TR", "Transmission"}
|
|
|
|
, {"TS", "TorrentStorm"}
|
|
|
|
, {"TT", "TuoTu"}
|
|
|
|
, {"U", "UPnP"}
|
|
|
|
, {"UL", "uLeecher"}
|
2010-04-28 18:14:27 +02:00
|
|
|
, {"UM", "uTorrent Mac"}
|
2007-07-02 18:47:32 +02:00
|
|
|
, {"UT", "uTorrent"}
|
2010-04-16 18:08:39 +02:00
|
|
|
, {"VG", "Vagaa"}
|
2010-04-28 18:14:27 +02:00
|
|
|
, {"WT", "BitLet"}
|
|
|
|
, {"WY", "FireTorrent"}
|
2014-06-13 19:34:15 +02:00
|
|
|
, {"XF", "Xfplay"}
|
2007-08-24 04:11:41 +02:00
|
|
|
, {"XL", "Xunlei"}
|
2010-04-28 18:14:27 +02:00
|
|
|
, {"XS", "XSwifter"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"XT", "XanTorrent"}
|
|
|
|
, {"XX", "Xtorrent"}
|
|
|
|
, {"ZT", "ZipTorrent"}
|
2007-05-30 11:52:36 +02:00
|
|
|
, {"lt", "rTorrent"}
|
2007-05-14 14:02:57 +02:00
|
|
|
, {"pX", "pHoeniX"}
|
|
|
|
, {"qB", "qBittorrent"}
|
2007-08-24 04:11:41 +02:00
|
|
|
, {"st", "SharkTorrent"}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct generic_map_entry
|
|
|
|
{
|
|
|
|
int offset;
|
|
|
|
char const* id;
|
|
|
|
char const* name;
|
|
|
|
};
|
|
|
|
// non-standard names
|
|
|
|
generic_map_entry generic_mappings[] =
|
|
|
|
{
|
|
|
|
{0, "Deadman Walking-", "Deadman"}
|
|
|
|
, {5, "Azureus", "Azureus 2.0.3.2"}
|
|
|
|
, {0, "DansClient", "XanTorrent"}
|
|
|
|
, {4, "btfans", "SimpleBT"}
|
|
|
|
, {0, "PRC.P---", "Bittorrent Plus! II"}
|
|
|
|
, {0, "P87.P---", "Bittorrent Plus!"}
|
|
|
|
, {0, "S587Plus", "Bittorrent Plus!"}
|
|
|
|
, {0, "martini", "Martini Man"}
|
|
|
|
, {0, "Plus---", "Bittorrent Plus"}
|
|
|
|
, {0, "turbobt", "TurboBT"}
|
|
|
|
, {0, "a00---0", "Swarmy"}
|
|
|
|
, {0, "a02---0", "Swarmy"}
|
|
|
|
, {0, "T00---0", "Teeweety"}
|
|
|
|
, {0, "BTDWV-", "Deadman Walking"}
|
|
|
|
, {2, "BS", "BitSpirit"}
|
|
|
|
, {0, "Pando-", "Pando"}
|
|
|
|
, {0, "LIME", "LimeWire"}
|
|
|
|
, {0, "btuga", "BTugaXP"}
|
|
|
|
, {0, "oernu", "BTugaXP"}
|
|
|
|
, {0, "Mbrst", "Burst!"}
|
|
|
|
, {0, "PEERAPP", "PeerApp"}
|
|
|
|
, {0, "Plus", "Plus!"}
|
|
|
|
, {0, "-Qt-", "Qt"}
|
|
|
|
, {0, "exbc", "BitComet"}
|
|
|
|
, {0, "DNA", "BitTorrent DNA"}
|
|
|
|
, {0, "-G3", "G3 Torrent"}
|
|
|
|
, {0, "-FG", "FlashGet"}
|
|
|
|
, {0, "-ML", "MLdonkey"}
|
2013-09-26 02:30:14 +02:00
|
|
|
, {0, "-MG", "Media Get"}
|
2007-08-24 04:11:41 +02:00
|
|
|
, {0, "XBT", "XBT"}
|
|
|
|
, {0, "OP", "Opera"}
|
|
|
|
, {2, "RS", "Rufus"}
|
|
|
|
, {0, "AZ2500BT", "BitTyrant"}
|
2013-01-19 03:25:25 +01:00
|
|
|
, {0, "btpd/", "BitTorrent Protocol Daemon"}
|
2013-09-26 02:30:14 +02:00
|
|
|
, {0, "TIX", "Tixati"}
|
|
|
|
, {0, "QVOD", "Qvod"}
|
2004-08-08 23:26:40 +02:00
|
|
|
};
|
|
|
|
|
2007-05-14 14:02:57 +02:00
|
|
|
bool compare_id(map_entry const& lhs, map_entry const& rhs)
|
2004-08-08 23:26:40 +02:00
|
|
|
{
|
2007-05-14 14:02:57 +02:00
|
|
|
return lhs.id[0] < rhs.id[0]
|
|
|
|
|| ((lhs.id[0] == rhs.id[0]) && (lhs.id[1] < rhs.id[1]));
|
2004-08-08 23:26:40 +02:00
|
|
|
}
|
2004-06-14 01:30:42 +02:00
|
|
|
|
2004-08-08 23:26:40 +02:00
|
|
|
std::string lookup(fingerprint const& f)
|
|
|
|
{
|
2009-04-12 20:46:07 +02:00
|
|
|
char identity[200];
|
2004-06-14 01:30:42 +02:00
|
|
|
|
2004-08-08 23:26:40 +02:00
|
|
|
const int size = sizeof(name_map)/sizeof(name_map[0]);
|
2007-05-14 14:02:57 +02:00
|
|
|
map_entry tmp = {f.name, ""};
|
2004-08-08 23:26:40 +02:00
|
|
|
map_entry* i =
|
|
|
|
std::lower_bound(name_map, name_map + size
|
2007-05-14 14:02:57 +02:00
|
|
|
, tmp, &compare_id);
|
2004-06-14 01:30:42 +02:00
|
|
|
|
2005-03-13 13:52:21 +01:00
|
|
|
#ifndef NDEBUG
|
2015-08-09 04:53:11 +02:00
|
|
|
for (int j = 1; j < size; ++j)
|
2005-03-13 13:52:21 +01:00
|
|
|
{
|
2015-08-09 04:53:11 +02:00
|
|
|
TORRENT_ASSERT(compare_id(name_map[j-1]
|
|
|
|
, name_map[j]));
|
2005-03-13 13:52:21 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-04-12 20:46:07 +02:00
|
|
|
char temp[3];
|
|
|
|
char const* name = 0;
|
2007-05-14 14:02:57 +02:00
|
|
|
if (i < name_map + size && std::equal(f.name, f.name + 2, i->id))
|
2009-04-12 20:46:07 +02:00
|
|
|
{
|
|
|
|
name = i->name;
|
|
|
|
}
|
2004-08-08 23:26:40 +02:00
|
|
|
else
|
2005-10-13 23:37:32 +02:00
|
|
|
{
|
2009-04-12 20:46:07 +02:00
|
|
|
// if we don't have this client in the list
|
|
|
|
// just use the one or two letter code
|
|
|
|
memcpy(temp, f.name, 2);
|
|
|
|
temp[2] = 0;
|
|
|
|
name = temp;
|
2005-10-13 23:37:32 +02:00
|
|
|
}
|
2004-06-14 01:30:42 +02:00
|
|
|
|
2009-04-12 20:46:07 +02:00
|
|
|
int num_chars = snprintf(identity, sizeof(identity), "%s %u.%u.%u", name
|
|
|
|
, f.major_version, f.minor_version, f.revision_version);
|
2005-10-13 23:37:32 +02:00
|
|
|
|
2009-04-12 20:46:07 +02:00
|
|
|
if (f.tag_version != 0)
|
|
|
|
{
|
|
|
|
snprintf(identity + num_chars, sizeof(identity) - num_chars
|
|
|
|
, ".%u", f.tag_version);
|
|
|
|
}
|
2004-06-14 01:30:42 +02:00
|
|
|
|
2009-04-12 20:46:07 +02:00
|
|
|
return identity;
|
2004-06-14 01:30:42 +02:00
|
|
|
}
|
|
|
|
|
2015-08-09 04:53:11 +02:00
|
|
|
bool find_string(char const* id, char const* search)
|
2004-08-08 23:26:40 +02:00
|
|
|
{
|
|
|
|
return std::equal(search, search + std::strlen(search), id);
|
|
|
|
}
|
|
|
|
}
|
2003-12-22 08:14:35 +01:00
|
|
|
|
2004-02-19 12:35:08 +01:00
|
|
|
namespace libtorrent
|
|
|
|
{
|
2003-12-22 08:14:35 +01:00
|
|
|
|
2016-10-25 14:03:26 +02:00
|
|
|
#ifndef TORRENT_NO_DEPRECATE
|
|
|
|
|
2006-05-15 00:30:05 +02:00
|
|
|
boost::optional<fingerprint> client_fingerprint(peer_id const& p)
|
|
|
|
{
|
|
|
|
// look for azureus style id
|
|
|
|
boost::optional<fingerprint> f;
|
|
|
|
f = parse_az_style(p);
|
|
|
|
if (f) return f;
|
|
|
|
|
|
|
|
// look for shadow style id
|
|
|
|
f = parse_shadow_style(p);
|
|
|
|
if (f) return f;
|
|
|
|
|
|
|
|
// look for mainline style id
|
|
|
|
f = parse_mainline_style(p);
|
|
|
|
if (f) return f;
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
2016-10-25 14:03:26 +02:00
|
|
|
#endif
|
|
|
|
|
2006-05-15 00:30:05 +02:00
|
|
|
std::string identify_client(peer_id const& p)
|
2003-12-22 08:14:35 +01:00
|
|
|
{
|
2015-08-09 04:53:11 +02:00
|
|
|
char const* PID = p.data();
|
2003-12-22 08:14:35 +01:00
|
|
|
boost::optional<fingerprint> f;
|
2004-06-30 09:53:42 +02:00
|
|
|
|
2004-07-18 02:39:58 +02:00
|
|
|
if (p.is_all_zeros()) return "Unknown";
|
2003-12-22 08:14:35 +01:00
|
|
|
|
|
|
|
// ----------------------
|
|
|
|
// non standard encodings
|
|
|
|
// ----------------------
|
|
|
|
|
2007-08-24 04:11:41 +02:00
|
|
|
int num_generic_mappings = sizeof(generic_mappings) / sizeof(generic_mappings[0]);
|
|
|
|
|
|
|
|
for (int i = 0; i < num_generic_mappings; ++i)
|
|
|
|
{
|
|
|
|
generic_map_entry const& e = generic_mappings[i];
|
|
|
|
if (find_string(PID + e.offset, e.id)) return e.name;
|
|
|
|
}
|
2003-12-22 08:14:35 +01:00
|
|
|
|
2005-02-27 10:30:34 +01:00
|
|
|
if (find_string(PID, "-BOW") && PID[7] == '-')
|
2015-08-11 02:03:24 +02:00
|
|
|
return "Bits on Wheels " + std::string(PID + 4, PID + 7);
|
2005-08-09 01:32:38 +02:00
|
|
|
|
2005-02-27 10:30:34 +01:00
|
|
|
if (find_string(PID, "eX"))
|
|
|
|
{
|
2015-08-09 04:53:11 +02:00
|
|
|
std::string user(PID + 2, PID + 14);
|
2015-05-23 03:38:47 +02:00
|
|
|
return std::string("eXeem ('") + user.c_str() + "')";
|
2005-02-27 10:30:34 +01:00
|
|
|
}
|
|
|
|
|
2003-12-22 08:14:35 +01:00
|
|
|
if (std::equal(PID, PID + 13, "\0\0\0\0\0\0\0\0\0\0\0\0\x97"))
|
|
|
|
return "Experimental 3.2.1b2";
|
|
|
|
|
|
|
|
if (std::equal(PID, PID + 13, "\0\0\0\0\0\0\0\0\0\0\0\0\0"))
|
|
|
|
return "Experimental 3.1";
|
|
|
|
|
2005-02-27 10:30:34 +01:00
|
|
|
// look for azureus style id
|
|
|
|
f = parse_az_style(p);
|
|
|
|
if (f) return lookup(*f);
|
|
|
|
|
|
|
|
// look for shadow style id
|
|
|
|
f = parse_shadow_style(p);
|
|
|
|
if (f) return lookup(*f);
|
|
|
|
|
|
|
|
// look for mainline style id
|
|
|
|
f = parse_mainline_style(p);
|
|
|
|
if (f) return lookup(*f);
|
2009-04-12 20:46:07 +02:00
|
|
|
|
|
|
|
|
2003-12-22 08:14:35 +01:00
|
|
|
if (std::equal(PID, PID + 12, "\0\0\0\0\0\0\0\0\0\0\0\0"))
|
|
|
|
return "Generic";
|
|
|
|
|
2004-05-21 01:26:40 +02:00
|
|
|
std::string unknown("Unknown [");
|
|
|
|
for (peer_id::const_iterator i = p.begin(); i != p.end(); ++i)
|
|
|
|
{
|
2009-06-23 03:53:47 +02:00
|
|
|
unknown += is_print(char(*i))?*i:'.';
|
2004-05-21 01:26:40 +02:00
|
|
|
}
|
|
|
|
unknown += "]";
|
|
|
|
return unknown;
|
2003-12-22 08:14:35 +01:00
|
|
|
}
|
|
|
|
}
|
2015-05-23 03:38:47 +02:00
|
|
|
|