merged RC_1_1 into master

This commit is contained in:
arvidn 2016-10-26 23:30:58 -04:00
commit 500bb24dba
17 changed files with 241 additions and 95 deletions

View File

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

View File

@ -42,6 +42,7 @@
* resume data no longer has timestamps of files
* require C++11 to build libtorrent
* 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

@ -605,6 +605,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

@ -949,7 +949,7 @@ bool handle_alert(libtorrent::session& ses, libtorrent::alert* a
save_file(filename, buffer);
files.insert(std::pair<std::string, libtorrent::torrent_handle>(filename, h));
hash_to_filename.insert(std::make_pair(hash, filename));
hash_to_filename[hash] = filename;
non_files.erase(h);
}
}

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];
std::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_FAIL();
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 deprecated 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

@ -257,6 +257,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
@ -309,6 +317,12 @@ namespace libtorrent
}
start(flags, std::move(pack), nullptr);
}
#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

@ -207,7 +207,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

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

View File

@ -3381,8 +3381,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);

View File

@ -335,6 +335,8 @@ namespace libtorrent
end = int(p->blocks_in_piece);
}
TORRENT_ASSERT(end <= p->blocks_in_piece);
// count number of blocks that would be flushed
int num_blocks = 0;
for (int i = end-1; i >= 0; --i)
@ -2083,6 +2085,12 @@ namespace libtorrent
DLOG("kick_hasher: %d - %d (piece: %d offset: %d)\n"
, cursor, end, int(pe->piece), ph->offset);
// save a local copy of offset to avoid concurrent access
int offset = ph->offset;
#if TORRENT_USE_ASSERTS
int old_offset = offset;
#endif
l.unlock();
time_point start_time = clock_type::now();
@ -2090,15 +2098,18 @@ namespace libtorrent
for (int i = cursor; i < end; ++i)
{
cached_block_entry& bl = pe->blocks[i];
int const size = (std::min)(block_size, piece_size - ph->offset);
int const size = (std::min)(block_size, piece_size - offset);
ph->h.update(bl.buf, size);
ph->offset += size;
offset += size;
}
std::uint64_t hash_time = total_microseconds(clock_type::now() - start_time);
l.lock();
TORRENT_ASSERT(old_offset == ph->offset);
ph->offset = offset;
TORRENT_PIECE_ASSERT(pe->hashing, pe);
TORRENT_PIECE_ASSERT(pe->hash, pe);
@ -2318,22 +2329,28 @@ namespace libtorrent
// to keep the cache footprint low, try to evict a volatile piece
m_disk_cache.try_evict_one_volatile();
// save a local copy of offset to avoid concurrent access
int offset = ph->offset;
#if TORRENT_USE_ASSERTS
int old_offset = offset;
#endif
l.unlock();
int ret = 0;
int next_locked_block = 0;
for (int i = ph->offset / block_size; i < blocks_in_piece; ++i)
for (int i = offset / block_size; i < blocks_in_piece; ++i)
{
file::iovec_t iov;
iov.iov_len = (std::min)(block_size, piece_size - ph->offset);
iov.iov_len = (std::min)(block_size, piece_size - offset);
if (next_locked_block < num_locked_blocks
&& locked_blocks[next_locked_block] == i)
{
++next_locked_block;
TORRENT_PIECE_ASSERT(pe->blocks[i].buf, pe);
TORRENT_PIECE_ASSERT(ph->offset == i * block_size, pe);
ph->offset += int(iov.iov_len);
TORRENT_PIECE_ASSERT(offset == i * block_size, pe);
offset += int(iov.iov_len);
ph->h.update({pe->blocks[i].buf, iov.iov_len});
}
else
@ -2363,9 +2380,9 @@ namespace libtorrent
time_point start_time = clock_type::now();
TORRENT_PIECE_ASSERT(ph->offset == i * block_size, pe);
TORRENT_PIECE_ASSERT(offset == i * block_size, pe);
ret = j->storage->get_storage_impl()->readv(iov, j->piece
, ph->offset, file_flags, j->error);
, offset, file_flags, j->error);
if (ret < 0)
{
@ -2398,8 +2415,8 @@ namespace libtorrent
m_stats_counters.inc_stats_counter(counters::disk_job_time, read_time);
}
TORRENT_PIECE_ASSERT(ph->offset == i * block_size, pe);
ph->offset += int(iov.iov_len);
TORRENT_PIECE_ASSERT(offset == i * block_size, pe);
offset += int(iov.iov_len);
ph->h.update({static_cast<char const*>(iov.iov_base), iov.iov_len});
l.lock();
@ -2410,6 +2427,9 @@ namespace libtorrent
l.lock();
TORRENT_ASSERT(old_offset == ph->offset);
ph->offset = offset;
// decrement the refcounts of the blocks we just hashed
for (int i = 0; i < num_locked_blocks; ++i)
m_disk_cache.dec_block_refcount(pe, locked_blocks[i], block_cache::ref_hashing);

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_FAIL();
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 <cstdio>
#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

@ -502,9 +502,9 @@ namespace libtorrent
// don't do full file allocations on network drives
#if TORRENT_USE_WSTRING
std::wstring file_name = convert_to_wstring(m_save_path);
int drive_type = GetDriveTypeW(file_name.c_str());
int const drive_type = GetDriveTypeW(file_name.c_str());
#else
int drive_type = GetDriveTypeA(m_save_path.c_str());
int const drive_type = GetDriveTypeA(m_save_path.c_str());
#endif
if (drive_type == DRIVE_REMOTE)
@ -1246,7 +1246,8 @@ namespace libtorrent
if (m_file_created[file] == false)
{
error_code e;
h->set_size(files().file_size(file), e);
boost::int64_t const size = files().file_size(file);
h->set_size(size, e);
m_file_created.set_bit(file);
if (e)
{
@ -1255,6 +1256,7 @@ namespace libtorrent
ec.operation = storage_error::fallocate;
return h;
}
m_stat_cache.set_dirty(file);
}
}
return h;

View File

@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/socket_io.hpp" // for print_endpoint
#include "libtorrent/announce_entry.hpp"
#include "libtorrent/hex.hpp" // from_hex
#include "libtorrent/fingerprint.hpp"
#include "test.hpp"
#include "setup_transfer.hpp"
@ -141,6 +142,13 @@ 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-");
}
TORRENT_TEST(printf_int64)

View File

@ -214,7 +214,9 @@ void test_piece_priorities(bool test_deprecated = false)
alert const* a = wait_for_alert(ses, save_resume_data_alert::alert_type);
TEST_CHECK(a);
if (save_resume_data_alert const* ra = alert_cast<save_resume_data_alert>(a))
save_resume_data_alert const* ra = alert_cast<save_resume_data_alert>(a);
TEST_CHECK(ra);
if (ra)
{
std::printf("%s\n", ra->resume_data->to_string().c_str());
entry::string_type prios = (*ra->resume_data)["piece_priority"].string();