add utility function for generating peer ID fingerprint (#1249)

add utility function for generating peer ID fingerprint
This commit is contained in:
Arvid Norberg 2016-10-25 08:03:26 -04:00 committed by GitHub
parent cf7db392b6
commit 61af222d92
13 changed files with 202 additions and 80 deletions

View File

@ -32,6 +32,7 @@ set(sources
escape_string
string_util
file
fingerprint
gzip
hasher
hex

View File

@ -1,3 +1,4 @@
* add utility function for generating peer ID fingerprint
* fix bug in last-seen-complete
* remove file size limit in torrent_info filename constructor
* fix tail-padding for last file in create_torrent

View File

@ -582,6 +582,7 @@ SOURCES =
escape_string
string_util
file
fingerprint
gzip
hasher
hex

View File

@ -10,6 +10,7 @@ void bind_fingerprint()
using namespace boost::python;
using namespace libtorrent;
#ifndef TORRENT_NO_DEPRECATE
class_<fingerprint>("fingerprint", no_init)
.def(
init<char const*,int,int,int,int>(
@ -23,5 +24,6 @@ void bind_fingerprint()
.def_readonly("revision_version", &fingerprint::revision_version)
.def_readonly("tag_version", &fingerprint::tag_version)
;
#endif
}

View File

@ -38,90 +38,61 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/config.hpp"
#include "libtorrent/peer_id.hpp"
#include "libtorrent/assert.hpp"
#include "libtorrent/export.hpp"
namespace libtorrent
{
// This is a utility function to produce a client ID fingerprint formatted to
// the most common convention.
//
// The name string should contain exactly two characters. These are the
// characters unique to your client, used to identify it. Make sure not to
// clash with anybody else. Here are some taken id's:
//
// +----------+-----------------------+
// | id chars | client |
// +==========+=======================+
// | 'AZ' | Azureus |
// +----------+-----------------------+
// | 'LT' | libtorrent (default) |
// +----------+-----------------------+
// | 'BX' | BittorrentX |
// +----------+-----------------------+
// | 'MT' | Moonlight Torrent |
// +----------+-----------------------+
// | 'TS' | Torrent Storm |
// +----------+-----------------------+
// | 'SS' | Swarm Scope |
// +----------+-----------------------+
// | 'XT' | Xan Torrent |
// +----------+-----------------------+
//
// There's an informal directory of client id's here_.
//
// .. _here: http://wiki.theory.org/BitTorrentSpecification#peer_id
//
// The ``major``, ``minor``, ``revision`` and ``tag`` parameters are used to
// identify the version of your client.
TORRENT_EXPORT std::string generate_fingerprint(std::string name
, int major, int minor = 0, int revision = 0, int tag = 0);
// The fingerprint class represents information about a client and its version. It is used
// to encode this information into the client's peer id.
struct TORRENT_DEPRECATED_EXPORT fingerprint
struct TORRENT_DEPRECATED TORRENT_DEPRECATED_EXPORT fingerprint
{
fingerprint(const char* id_string, int major, int minor, int revision, int tag);
// The constructor takes a ``char const*`` that should point to a string constant containing
// exactly two characters. These are the characters that should be unique for your client. Make
// sure not to clash with anybody else. Here are some taken id's:
//
// +----------+-----------------------+
// | id chars | client |
// +==========+=======================+
// | 'AZ' | Azureus |
// +----------+-----------------------+
// | 'LT' | libtorrent (default) |
// +----------+-----------------------+
// | 'BX' | BittorrentX |
// +----------+-----------------------+
// | 'MT' | Moonlight Torrent |
// +----------+-----------------------+
// | 'TS' | Torrent Storm |
// +----------+-----------------------+
// | 'SS' | Swarm Scope |
// +----------+-----------------------+
// | 'XT' | Xan Torrent |
// +----------+-----------------------+
//
// There's an informal directory of client id's here_.
//
// .. _here: http://wiki.theory.org/BitTorrentSpecification#peer_id
//
// The ``major``, ``minor``, ``revision`` and ``tag`` parameters are used to identify the
// version of your client.
fingerprint(const char* id_string, int major, int minor, int revision, int tag)
: major_version(major)
, minor_version(minor)
, revision_version(revision)
, tag_version(tag)
{
TORRENT_ASSERT(id_string);
TORRENT_ASSERT(major >= 0);
TORRENT_ASSERT(minor >= 0);
TORRENT_ASSERT(revision >= 0);
TORRENT_ASSERT(tag >= 0);
TORRENT_ASSERT(std::strlen(id_string) == 2);
name[0] = id_string[0];
name[1] = id_string[1];
}
#ifndef TORRENT_NO_DEPRECATE
// generates the actual string put in the peer-id, and return it.
std::string to_string() const
{
char s[100];
snprintf(s, 100, "-%c%c%c%c%c%c-"
, name[0], name[1]
, version_to_char(major_version)
, version_to_char(minor_version)
, version_to_char(revision_version)
, version_to_char(tag_version));
return s;
}
std::string to_string() const;
#endif
char name[2];
int major_version;
int minor_version;
int revision_version;
int tag_version;
private:
char version_to_char(int v) const
{
if (v >= 0 && v < 10) return char('0' + v);
else if (v >= 10) return char('A' + (v - 10));
TORRENT_ASSERT(false);
return '0';
}
};
}

View File

@ -35,21 +35,19 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/config.hpp"
#ifndef TORRENT_NO_DEPRECATE
#include "libtorrent/aux_/disable_warnings_push.hpp"
#include <boost/optional.hpp>
#include "libtorrent/aux_/disable_warnings_pop.hpp"
#endif
#include "libtorrent/peer_id.hpp"
#include "libtorrent/fingerprint.hpp"
// TODO: hide this declaration when deprecated functions are disabled, and
// remove its internal use
namespace libtorrent
{
// TODO: hide these declarations when deprecaated functions are disabled, and
// expose them internally in a header under aux_.
// these functions don't really need to be public. This mechanism of
// advertising client software and version is also out-dated.
@ -59,6 +57,16 @@ namespace libtorrent
TORRENT_DEPRECATED_EXPORT TORRENT_DEPRECATED
std::string identify_client(const peer_id& p);
#ifndef TORRENT_NO_DEPRECATE
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
// Returns an optional fingerprint if any can be identified from the peer
// id. This can be used to automate the identification of clients. It will
// not be able to identify peers with non- standard encodings. Only Azureus
@ -67,6 +75,15 @@ namespace libtorrent
boost::optional<fingerprint>
client_fingerprint(peer_id const& p);
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#endif // TORRENT_NO_DEPRECATE
}
#endif // TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED

View File

@ -201,6 +201,14 @@ namespace libtorrent
}
#ifndef TORRENT_NO_DEPRECATE
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
TORRENT_DEPRECATED
session(fingerprint const& print
, int flags = start_default_features | add_default_plugins
@ -253,6 +261,12 @@ namespace libtorrent
}
start(flags, pack, NULL);
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#endif // TORRENT_NO_DEPRECATE
// The destructor of session will notify all trackers that our torrents

View File

@ -201,7 +201,10 @@ namespace libtorrent
// this is the fingerprint for the client. It will be used as the
// prefix to the peer_id. If this is 20 bytes (or longer) it will be
// used as the peer-id
// truncated at 20 bytes and used as the entire peer-id
//
// There is a utility function, generate_fingerprint() that can be used
// to generate a standard client peer ID fingerprint prefix.
peer_fingerprint,
// This is a comma-separated list of IP port-pairs. They will be added

View File

@ -72,6 +72,7 @@ libtorrent_rasterbar_la_SOURCES = \
file.cpp \
file_pool.cpp \
file_storage.cpp \
fingerprint.cpp \
gzip.cpp \
hasher.cpp \
hex.cpp \

View File

@ -3405,8 +3405,7 @@ namespace libtorrent
}
m_client_version = identify_client(pid);
boost::optional<fingerprint> f = client_fingerprint(pid);
if (f && std::equal(f->name, f->name + 2, "BC"))
if (pid[0] == '-' && pid[1] == 'B' && pid[2] == 'C' && pid[7] == '-')
{
// if this is a bitcomet client, lower the request queue size limit
if (max_out_request_queue() > 50) max_out_request_queue(50);

100
src/fingerprint.cpp Normal file
View File

@ -0,0 +1,100 @@
/*
Copyright (c) 2016, Arvid Norberg
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 "libtorrent/fingerprint.hpp"
#include "libtorrent/assert.hpp"
namespace libtorrent {
namespace {
char version_to_char(int const v)
{
if (v >= 0 && v < 10) return char('0' + v);
else if (v >= 10) return char('A' + (v - 10));
TORRENT_ASSERT(false);
return '0';
}
} // anonymous namespace
std::string generate_fingerprint(std::string name, int const major
, int const minor
, int const revision
, int const tag)
{
TORRENT_ASSERT_PRECOND(major >= 0);
TORRENT_ASSERT_PRECOND(minor >= 0);
TORRENT_ASSERT_PRECOND(revision >= 0);
TORRENT_ASSERT_PRECOND(tag >= 0);
TORRENT_ASSERT_PRECOND(name.size() == 2);
if (name.size() < 2) name = "--";
std::string ret;
ret.resize(8);
ret[0] = '-';
ret[1] = name[0];
ret[2] = name[1];
ret[3] = version_to_char(major);
ret[4] = version_to_char(minor);
ret[5] = version_to_char(revision);
ret[6] = version_to_char(tag);
ret[7] = '-';
return ret;
}
fingerprint::fingerprint(const char* id_string, int major, int minor
, int revision, int tag)
: major_version(major)
, minor_version(minor)
, revision_version(revision)
, tag_version(tag)
{
TORRENT_ASSERT(id_string);
TORRENT_ASSERT(major >= 0);
TORRENT_ASSERT(minor >= 0);
TORRENT_ASSERT(revision >= 0);
TORRENT_ASSERT(tag >= 0);
TORRENT_ASSERT(std::strlen(id_string) == 2);
name[0] = id_string[0];
name[1] = id_string[1];
}
#ifndef TORRENT_NO_DEPRECATE
std::string fingerprint::to_string() const
{
return generate_fingerprint(name, major_version, minor_version
, revision_version, tag_version);
}
#endif // TORRENT_NO_DEPRECATE
}

View File

@ -35,9 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <stdio.h>
#include "libtorrent/aux_/disable_warnings_push.hpp"
#include <boost/optional.hpp>
#include "libtorrent/aux_/disable_warnings_pop.hpp"
#include "libtorrent/identify_client.hpp"
@ -141,7 +139,9 @@ namespace
// must be ordered alphabetically
map_entry name_map[] =
{
{"A", "ABC"}
{"7T", "aTorrent for android"}
, {"A", "ABC"}
, {"AB", "AnyEvent BitTorrent"}
, {"AG", "Ares"}
, {"AR", "Arctic Torrent"}
, {"AT", "Artemis"}
@ -343,6 +343,8 @@ namespace
namespace libtorrent
{
#ifndef TORRENT_NO_DEPRECATE
boost::optional<fingerprint> client_fingerprint(peer_id const& p)
{
// look for azureus style id
@ -360,6 +362,8 @@ namespace libtorrent
return f;
}
#endif
std::string identify_client(peer_id const& p)
{
char const* PID = p.data();

View File

@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/broadcast_socket.hpp"
#include "libtorrent/socket_io.hpp" // for print_endpoint
#include "libtorrent/announce_entry.hpp"
#include "libtorrent/fingerprint.hpp"
#include "test.hpp"
#include "setup_transfer.hpp"
@ -159,5 +160,12 @@ TORRENT_TEST(primitives)
// test endpoint_to_bytes
TEST_EQUAL(endpoint_to_bytes(udp::endpoint(address_v4::from_string("10.11.12.13"), 8080)), "\x0a\x0b\x0c\x0d\x1f\x90");
TEST_EQUAL(endpoint_to_bytes(udp::endpoint(address_v4::from_string("16.5.127.1"), 12345)), "\x10\x05\x7f\x01\x30\x39");
// test gen_fingerprint
TEST_EQUAL(generate_fingerprint("AB", 1, 2, 3, 4), "-AB1234-");
TEST_EQUAL(generate_fingerprint("AB", 1, 2), "-AB1200-");
TEST_EQUAL(generate_fingerprint("..", 1, 10), "-..1A00-");
TEST_EQUAL(generate_fingerprint("CZ", 1, 15), "-CZ1F00-");
TEST_EQUAL(generate_fingerprint("CZ", 1, 15, 16, 17), "-CZ1FGH-");
}