modernize hasher to use array_view (#931)

modernize hasher to use array_view as well as adding array_view support to entry
This commit is contained in:
Arvid Norberg 2016-07-22 07:29:39 -07:00 committed by GitHub
parent 3d74b8136e
commit 7bf49c0a1c
26 changed files with 241 additions and 234 deletions

View File

@ -45,31 +45,28 @@ namespace libtorrent { namespace aux {
{
array_view() : m_ptr(nullptr), m_len(0) {}
// T -> const T conversion constructor
template <typename U, typename
= std::enable_if<std::is_convertible<U*, T*>::value>
>
template <typename U>
array_view(array_view<U> const& v)
: m_ptr(v.data()), m_len(v.size()) {}
array_view(T& p) : m_ptr(&p), m_len(1) {}
array_view(T* p, int l) : m_ptr(p), m_len(l)
{
TORRENT_ASSERT(l >= 0);
}
array_view(T* p, size_t l) : m_ptr(p), m_len(l) {}
template <size_t N>
array_view(std::array<T, N>& arr)
template <typename U, size_t N>
array_view(std::array<U, N>& arr)
: m_ptr(arr.data()), m_len(arr.size()) {}
template <size_t N>
array_view(T (&arr)[N])
template <typename U, size_t N>
array_view(U (&arr)[N])
: m_ptr(&arr[0]), m_len(N) {}
array_view(std::vector<T>& vec)
: m_ptr(vec.data()), m_len(vec.size()) {}
// anything with a .data() member function is considered a container
template <typename Cont, typename = decltype(std::declval<Cont>().data())>
array_view(Cont& c)
: m_ptr(c.data()), m_len(c.size()) {}
size_t size() const { return m_len; }
bool empty() const { return m_len == 0; }
T* data() const { return m_ptr; }
using iterator = T*;
@ -83,30 +80,26 @@ namespace libtorrent { namespace aux {
T& front() const { TORRENT_ASSERT(m_len > 0); return m_ptr[0]; }
T& back() const { TORRENT_ASSERT(m_len > 0); return m_ptr[m_len-1]; }
array_view<T> first(int const n) const
array_view<T> first(size_t const n) const
{
TORRENT_ASSERT(size() >= n);
TORRENT_ASSERT(n >= 0);
return { data(), size() - n };
}
array_view<T> last(int const n) const
array_view<T> last(size_t const n) const
{
TORRENT_ASSERT(size() >= n);
TORRENT_ASSERT(n >= 0);
return { data() + size() - n, n };
}
array_view<T> cut_first(int const n) const
array_view<T> cut_first(size_t const n) const
{
TORRENT_ASSERT(size() >= n);
TORRENT_ASSERT(n >= 0);
return { data() + n, int(size()) - n };
}
T& operator[](int const idx)
T& operator[](size_t const idx)
{
TORRENT_ASSERT(idx >= 0);
TORRENT_ASSERT(idx < m_len);
return m_ptr[idx];
}

View File

@ -71,6 +71,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/assert.hpp"
#include "libtorrent/error_code.hpp"
#include "libtorrent/aux_/array_view.hpp"
namespace libtorrent
{
@ -114,15 +115,27 @@ namespace libtorrent
// constructors directly from a specific type.
// The content of the argument is copied into the
// newly constructed entry
entry(dictionary_type const&);
entry(string_type const&);
entry(list_type const&);
entry(integer_type const&);
entry(preformatted_type const&);
entry(dictionary_type);
entry(aux::array_view<char const>);
template <typename U, typename = typename std::enable_if<
std::is_same<U, entry::string_type>::value
|| std::is_same<U, char const*>::value >::type>
entry(U v)
: m_type(undefined_t)
{
#if TORRENT_USE_ASSERTS
m_type_queried = true;
#endif
new(&data) string_type(std::move(v));
m_type = string_t;
}
entry(list_type);
entry(integer_type);
entry(preformatted_type);
// construct an empty entry of the specified type.
// see data_type enum.
entry(data_type t);
explicit entry(data_type t);
// hidden
entry(entry const& e);
@ -146,11 +159,24 @@ namespace libtorrent
entry& operator=(bdecode_node const&);
entry& operator=(entry const&);
entry& operator=(entry&&);
entry& operator=(dictionary_type const&);
entry& operator=(string_type const&);
entry& operator=(list_type const&);
entry& operator=(integer_type const&);
entry& operator=(preformatted_type const&);
entry& operator=(dictionary_type);
entry& operator=(aux::array_view<char const>);
template <typename U, typename = typename std::enable_if<
std::is_same<U, entry::string_type>::value
|| std::is_same<U, char const*>::value >::type>
entry& operator=(U v)
{
destruct();
new(&data) string_type(std::move(v));
m_type = string_t;
#if TORRENT_USE_ASSERTS
m_type_queried = true;
#endif
return *this;
}
entry& operator=(list_type);
entry& operator=(integer_type);
entry& operator=(preformatted_type);
// The ``integer()``, ``string()``, ``list()`` and ``dict()`` functions
// are accessors that return the respective type. If the ``entry`` object

View File

@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/peer_id.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/assert.hpp"
#include "libtorrent/aux_/array_view.hpp"
#include <cstdint>
@ -86,13 +87,13 @@ namespace libtorrent
// this is the same as default constructing followed by a call to
// ``update(data, len)``.
hasher(char const* data, int len);
hasher(aux::array_view<char const> data);
hasher(hasher const&);
hasher& operator=(hasher const&);
// append the following bytes to what is being hashed
hasher& update(std::string const& data) { update(data.c_str(), int(data.size())); return *this; }
hasher& update(const char* data, int len);
hasher& update(aux::array_view<char const> data);
hasher& update(char const* data, int len);
// returns the SHA-1 digest of the buffers previously passed to
// update() and the hasher constructor.

View File

@ -67,9 +67,9 @@ namespace libtorrent
{
enum { number_size = 5 };
public:
// internal
// the number of bytes of the number
static const int size = number_size * sizeof(std::uint32_t);
// the size of the hash in bytes
static constexpr size_t size() { return number_size * sizeof(std::uint32_t); }
// constructs an all-zero sha1-hash
sha1_hash() { clear(); }
@ -80,7 +80,7 @@ namespace libtorrent
static sha1_hash max()
{
sha1_hash ret;
memset(ret.m_number, 0xff, size);
memset(ret.m_number, 0xff, size());
return ret;
}
@ -90,7 +90,7 @@ namespace libtorrent
static sha1_hash min()
{
sha1_hash ret;
memset(ret.m_number, 0, size);
memset(ret.m_number, 0, size());
return ret;
}
@ -100,27 +100,25 @@ namespace libtorrent
explicit sha1_hash(char const* s)
{
if (s == 0) clear();
else std::memcpy(m_number, s, size);
else std::memcpy(m_number, s, size());
}
explicit sha1_hash(std::string const& s)
{
TORRENT_ASSERT(s.size() >= 20);
size_t sl = s.size() < size_t(size) ? s.size() : size_t(size);
std::memcpy(m_number, s.c_str(), sl);
assign(s);
}
void assign(std::string const& s)
{
TORRENT_ASSERT(s.size() >= 20);
size_t sl = s.size() < size_t(size) ? s.size() : size_t(size);
size_t const sl = s.size() < size() ? s.size() : size();
std::memcpy(m_number, s.c_str(), sl);
}
void assign(char const* str) { std::memcpy(m_number, str, size); }
void assign(char const* str) { std::memcpy(m_number, str, size()); }
char const* data() const { return reinterpret_cast<char const*>(&m_number[0]); }
char* data() { return reinterpret_cast<char*>(&m_number[0]); }
// set the sha1-hash to all zeroes.
void clear() { std::memset(m_number, 0, size); }
void clear() { std::memset(m_number, 0, size()); }
// return true if the sha1-hash is all zero.
bool is_all_zeros() const
@ -209,14 +207,14 @@ namespace libtorrent
}
// accessors for specific bytes
std::uint8_t& operator[](int i)
std::uint8_t& operator[](size_t i)
{
TORRENT_ASSERT(i >= 0 && i < size);
TORRENT_ASSERT(i < size());
return reinterpret_cast<std::uint8_t*>(m_number)[i];
}
std::uint8_t const& operator[](int i) const
std::uint8_t const& operator[](size_t i) const
{
TORRENT_ASSERT(i >= 0 && i < size);
TORRENT_ASSERT(i < size());
return reinterpret_cast<std::uint8_t const*>(m_number)[i];
}
@ -228,18 +226,17 @@ namespace libtorrent
const_iterator begin() const
{ return reinterpret_cast<std::uint8_t const*>(m_number); }
const_iterator end() const
{ return reinterpret_cast<std::uint8_t const*>(m_number) + size; }
{ return reinterpret_cast<std::uint8_t const*>(m_number) + size(); }
iterator begin()
{ return reinterpret_cast<std::uint8_t*>(m_number); }
iterator end()
{ return reinterpret_cast<std::uint8_t*>(m_number) + size; }
{ return reinterpret_cast<std::uint8_t*>(m_number) + size(); }
// return a copy of the 20 bytes representing the sha1-hash as a std::string.
// It's still a binary string with 20 binary characters.
std::string to_string() const
{
return std::string(reinterpret_cast<char const*>(&m_number[0])
, size_t(size));
return std::string(reinterpret_cast<char const*>(&m_number[0]), size());
}
private:

View File

@ -102,12 +102,12 @@ namespace libtorrent
// outgoing connection : hash ('keyA',S,SKEY)
// incoming connection : hash ('keyB',S,SKEY)
std::array<std::uint8_t, 96> secret_buf;
mp::export_bits(secret, secret_buf.begin(), 8);
std::array<char, 96> secret_buf;
mp::export_bits(secret, reinterpret_cast<std::uint8_t*>(secret_buf.data()), 8);
if (outgoing) h.update(keyA, 4); else h.update(keyB, 4);
h.update(reinterpret_cast<char const*>(secret_buf.data()), secret_buf.size());
h.update(stream_key.data(), 20);
h.update(secret_buf);
h.update(stream_key);
const sha1_hash local_key = h.final();
h.reset();
@ -117,9 +117,8 @@ namespace libtorrent
// incoming connection : hash ('keyA',S,SKEY)
if (outgoing) h.update(keyB, 4); else h.update(keyA, 4);
h.update(reinterpret_cast<char const*>(secret_buf.data())
, secret_buf.size());
h.update(stream_key.data(), 20);
h.update(secret_buf);
h.update(stream_key);
const sha1_hash remote_key = h.final();
boost::shared_ptr<rc4_handler> ret = boost::make_shared<rc4_handler>();
@ -549,8 +548,8 @@ namespace libtorrent
hasher h;
sha1_hash const& info_hash = t->torrent_file().info_hash();
key_t const secret_key = m_dh_key_exchange->get_secret();
std::array<std::uint8_t, 96> secret;
mp::export_bits(secret_key, secret.begin(), 8);
std::array<char, 96> secret;
mp::export_bits(secret_key, reinterpret_cast<std::uint8_t*>(secret.data()), 8);
int pad_size = random() % 512;
@ -561,27 +560,24 @@ namespace libtorrent
// sync hash (hash('req1',S))
h.reset();
h.update("req1",4);
h.update(reinterpret_cast<char const*>(secret.data())
, secret.size());
sha1_hash sync_hash = h.final();
h.update(secret);
sha1_hash const sync_hash = h.final();
memcpy(ptr, &sync_hash[0], 20);
memcpy(ptr, sync_hash.data(), 20);
ptr += 20;
// stream key obfuscated hash [ hash('req2',SKEY) xor hash('req3',S) ]
h.reset();
h.update("req2",4);
h.update(info_hash.data(), 20);
sha1_hash streamkey_hash = h.final();
h.update(info_hash);
sha1_hash const streamkey_hash = h.final();
h.reset();
h.update("req3",4);
h.update(reinterpret_cast<char const*>(secret.data())
, secret.size());
sha1_hash obfsc_hash = h.final();
obfsc_hash ^= streamkey_hash;
h.update(secret);
sha1_hash const obfsc_hash = h.final() ^ streamkey_hash;
memcpy(ptr, &obfsc_hash[0], 20);
memcpy(ptr, obfsc_hash.data(), 20);
ptr += 20;
// Discard DH key exchange data, setup RC4 keys
@ -2639,21 +2635,16 @@ namespace libtorrent
hasher h;
// compute synchash (hash('req1',S))
std::array<std::uint8_t, 96> buffer;
mp::export_bits(m_dh_key_exchange->get_secret(), buffer.begin(), 8);
std::array<char, 96> buffer;
mp::export_bits(m_dh_key_exchange->get_secret()
, reinterpret_cast<std::uint8_t*>(buffer.data()), 8);
h.update("req1", 4);
h.update(reinterpret_cast<char const*>(buffer.data()), buffer.size());
h.update(buffer);
m_sync_hash.reset(new (std::nothrow) sha1_hash(h.final()));
if (!m_sync_hash)
{
received_bytes(0, int(bytes_transferred));
disconnect(errors::no_memory, op_encryption);
return;
}
m_sync_hash.reset(new sha1_hash(h.final()));
}
int syncoffset = get_syncoffset(m_sync_hash->data(), 20
int const syncoffset = get_syncoffset(m_sync_hash->data(), 20
, recv_buffer.begin, recv_buffer.left());
// No sync
@ -2793,7 +2784,7 @@ namespace libtorrent
}
TORRENT_ASSERT(m_sync_vc.get());
int syncoffset = get_syncoffset(m_sync_vc.get(), 8
int const syncoffset = get_syncoffset(m_sync_vc.get(), 8
, recv_buffer.begin, recv_buffer.left());
// No sync

View File

@ -653,31 +653,27 @@ namespace libtorrent
for (int i = level_start; i < level_start + level_size; i += 2, ++parent)
{
hasher h;
h.update(m_merkle_tree[i].data(), 20);
h.update(m_merkle_tree[i+1].data(), 20);
h.update(m_merkle_tree[i]);
h.update(m_merkle_tree[i+1]);
m_merkle_tree[parent] = h.final();
}
level_start = merkle_get_parent(level_start);
level_size /= 2;
}
TORRENT_ASSERT(level_size == 1);
std::string& p = info["root hash"].string();
p.assign(m_merkle_tree[0].data(), 20);
info["root hash"] = m_merkle_tree[0];
}
else
{
std::string& p = info["pieces"].string();
for (std::vector<sha1_hash>::const_iterator i = m_piece_hash.begin();
i != m_piece_hash.end(); ++i)
{
p.append(i->data(), sha1_hash::size);
}
for (sha1_hash const& h : m_piece_hash)
p.append(h.data(), h.size());
}
std::vector<char> buf;
bencode(std::back_inserter(buf), info);
m_info_hash = hasher(&buf[0], int(buf.size())).final();
m_info_hash = hasher(buf).final();
return dict;
}

View File

@ -2117,7 +2117,7 @@ namespace libtorrent
for (int i = cursor; i < end; ++i)
{
cached_block_entry& bl = pe->blocks[i];
int size = (std::min)(block_size, piece_size - ph->offset);
int const size = (std::min)(block_size, piece_size - ph->offset);
ph->h.update(bl.buf, size);
ph->offset += size;
}

View File

@ -318,53 +318,53 @@ namespace libtorrent
#endif
}
entry::entry(dictionary_type const& v)
entry::entry(dictionary_type v)
: m_type(undefined_t)
{
#if TORRENT_USE_ASSERTS
m_type_queried = true;
#endif
new(&data) dictionary_type(v);
new(&data) dictionary_type(std::move(v));
m_type = dictionary_t;
}
entry::entry(string_type const& v)
entry::entry(aux::array_view<char const> v)
: m_type(undefined_t)
{
#if TORRENT_USE_ASSERTS
m_type_queried = true;
#endif
new(&data) string_type(v);
new(&data) string_type(v.data(), v.size());
m_type = string_t;
}
entry::entry(list_type const& v)
entry::entry(list_type v)
: m_type(undefined_t)
{
#if TORRENT_USE_ASSERTS
m_type_queried = true;
#endif
new(&data) list_type(v);
new(&data) list_type(std::move(v));
m_type = list_t;
}
entry::entry(integer_type const& v)
entry::entry(integer_type v)
: m_type(undefined_t)
{
#if TORRENT_USE_ASSERTS
m_type_queried = true;
#endif
new(&data) integer_type(v);
new(&data) integer_type(std::move(v));
m_type = int_t;
}
entry::entry(preformatted_type const& v)
entry::entry(preformatted_type v)
: m_type(undefined_t)
{
#if TORRENT_USE_ASSERTS
m_type_queried = true;
#endif
new(&data) preformatted_type(v);
new(&data) preformatted_type(std::move(v));
m_type = preformatted_t;
}
@ -446,10 +446,10 @@ namespace libtorrent
}
#endif
entry& entry::operator=(preformatted_type const& v)
entry& entry::operator=(preformatted_type v)
{
destruct();
new(&data) preformatted_type(v);
new(&data) preformatted_type(std::move(v));
m_type = preformatted_t;
#if TORRENT_USE_ASSERTS
m_type_queried = true;
@ -457,10 +457,10 @@ namespace libtorrent
return *this;
}
entry& entry::operator=(dictionary_type const& v)
entry& entry::operator=(dictionary_type v)
{
destruct();
new(&data) dictionary_type(v);
new(&data) dictionary_type(std::move(v));
m_type = dictionary_t;
#if TORRENT_USE_ASSERTS
m_type_queried = true;
@ -468,10 +468,10 @@ namespace libtorrent
return *this;
}
entry& entry::operator=(string_type const& v)
entry& entry::operator=(aux::array_view<char const> v)
{
destruct();
new(&data) string_type(v);
new(&data) string_type(v.data(), v.size());
m_type = string_t;
#if TORRENT_USE_ASSERTS
m_type_queried = true;
@ -479,10 +479,10 @@ namespace libtorrent
return *this;
}
entry& entry::operator=(list_type const& v)
entry& entry::operator=(list_type v)
{
destruct();
new(&data) list_type(v);
new(&data) list_type(std::move(v));
m_type = list_t;
#if TORRENT_USE_ASSERTS
m_type_queried = true;
@ -490,10 +490,10 @@ namespace libtorrent
return *this;
}
entry& entry::operator=(integer_type const& v)
entry& entry::operator=(integer_type v)
{
destruct();
new(&data) integer_type(v);
new(&data) integer_type(std::move(v));
m_type = int_t;
#if TORRENT_USE_ASSERTS
m_type_queried = true;

View File

@ -85,12 +85,17 @@ namespace libtorrent
#endif
}
hasher::hasher(const char* data, int len)
hasher::hasher(aux::array_view<char const> data)
: hasher()
{
update(data);
}
hasher::hasher(char const* data, int len)
: hasher()
{
TORRENT_ASSERT(data != nullptr);
TORRENT_ASSERT(len > 0);
update(data, len);
update({data, size_t(len)});
}
#ifdef TORRENT_USE_LIBGCRYPT
@ -138,16 +143,20 @@ namespace libtorrent
hasher& hasher::operator=(hasher const&) = default;
#endif
hasher& hasher::update(const char* data, int len)
hasher& hasher::update(char const* data, int len)
{
TORRENT_ASSERT(data != nullptr);
TORRENT_ASSERT(len > 0);
return update({data, size_t(len)});
}
hasher& hasher::update(aux::array_view<char const> data)
{
TORRENT_ASSERT(!data.empty());
#ifdef TORRENT_USE_LIBGCRYPT
gcry_md_write(m_context, data, len);
gcry_md_write(m_context, data.data(), data.size());
#elif TORRENT_USE_COMMONCRYPTO
CC_SHA1_Update(&m_context, reinterpret_cast<unsigned char const*>(data), len);
CC_SHA1_Update(&m_context, reinterpret_cast<unsigned char const*>(data.data()), data.size());
#elif TORRENT_USE_CRYPTOAPI
if (CryptHashData(m_context, reinterpret_cast<BYTE const*>(data), len, 0) == false)
if (CryptHashData(m_context, reinterpret_cast<BYTE const*>(data.data()), int(data.size()), 0) == false)
{
#ifndef BOOST_NO_EXCEPTIONS
throw system_error(error_code(GetLastError(), system_category()));
@ -156,9 +165,9 @@ namespace libtorrent
#endif
}
#elif defined TORRENT_USE_LIBCRYPTO
SHA1_Update(&m_context, reinterpret_cast<unsigned char const*>(data), len);
SHA1_Update(&m_context, reinterpret_cast<unsigned char const*>(data.data()), data.size());
#else
SHA1_update(&m_context, reinterpret_cast<unsigned char const*>(data), len);
SHA1_update(&m_context, reinterpret_cast<unsigned char const*>(data.data()), data.size());
#endif
return *this;
}
@ -168,12 +177,12 @@ namespace libtorrent
sha1_hash digest;
#ifdef TORRENT_USE_LIBGCRYPT
gcry_md_final(m_context);
digest.assign((const char*)gcry_md_read(m_context, 0));
digest.assign((char const*)gcry_md_read(m_context, 0));
#elif TORRENT_USE_COMMONCRYPTO
CC_SHA1_Final(digest.begin(), &m_context);
#elif TORRENT_USE_CRYPTOAPI
DWORD size = sha1_hash::size;
DWORD size = DWORD(digest.size());
if (CryptGetHashParam(m_context, HP_HASHVAL
, reinterpret_cast<BYTE*>(digest.data()), &size, 0) == false)
{
@ -183,7 +192,7 @@ namespace libtorrent
std::terminate();
#endif
}
TORRENT_ASSERT(size == sha1_hash::size);
TORRENT_ASSERT(size == digest.size());
#elif defined TORRENT_USE_LIBCRYPTO
SHA1_Final(digest.begin(), &m_context);
#else

View File

@ -81,9 +81,7 @@ namespace
// calculate the target hash for an immutable item.
sha1_hash item_target_id(std::pair<char const*, int> v)
{
hasher h;
h.update(v.first, v.second);
return h.final();
return hasher(v.first, v.second).final();
}
// calculate the target hash for a mutable item.

View File

@ -162,41 +162,42 @@ bool node::verify_token(std::string const& token, char const* info_hash
hasher h1;
error_code ec;
std::string address = addr.address().to_string(ec);
std::string const address = addr.address().to_string(ec);
if (ec) return false;
h1.update(&address[0], int(address.length()));
h1.update(address);
h1.update(reinterpret_cast<char const*>(&m_secret[0]), sizeof(m_secret[0]));
h1.update(reinterpret_cast<char const*>(info_hash), sha1_hash::size);
h1.update(info_hash, 20);
sha1_hash h = h1.final();
if (std::equal(token.begin(), token.end(), reinterpret_cast<char*>(&h[0])))
return true;
hasher h2;
h2.update(&address[0], int(address.length()));
h2.update(address);
h2.update(reinterpret_cast<char const*>(&m_secret[1]), sizeof(m_secret[1]));
h2.update(info_hash, sha1_hash::size);
h2.update(info_hash, 20);
h = h2.final();
if (std::equal(token.begin(), token.end(), reinterpret_cast<char*>(&h[0])))
return true;
return false;
}
std::string node::generate_token(udp::endpoint const& addr, char const* info_hash)
std::string node::generate_token(udp::endpoint const& addr
, char const* info_hash)
{
std::string token;
token.resize(4);
hasher h;
error_code ec;
std::string address = addr.address().to_string(ec);
std::string const address = addr.address().to_string(ec);
TORRENT_ASSERT(!ec);
h.update(&address[0], int(address.length()));
h.update(address);
h.update(reinterpret_cast<char*>(&m_secret[0]), sizeof(m_secret[0]));
h.update(info_hash, sha1_hash::size);
h.update(info_hash, 20);
sha1_hash hash = h.final();
sha1_hash const hash = h.final();
std::copy(hash.begin(), hash.begin() + 4, reinterpret_cast<char*>(&token[0]));
TORRENT_ASSERT(std::equal(token.begin(), token.end(), reinterpret_cast<char*>(&hash[0])));
TORRENT_ASSERT(std::equal(token.begin(), token.end(), hash.data()));
return token;
}

View File

@ -152,7 +152,7 @@ void make_id_secret(node_id& in)
// lets us verify whether a hash came from this function or not in the future.
hasher h(reinterpret_cast<char*>(&secret), 4);
h.update(reinterpret_cast<char*>(&rand), 4);
sha1_hash secret_hash = h.final();
sha1_hash const secret_hash = h.final();
memcpy(&in[20-4], &secret_hash[0], 4);
memcpy(&in[20-8], &rand, 4);
}

View File

@ -948,7 +948,7 @@ ip_ok:
if (m_log)
{
char hex_id[41];
aux::to_hex(e.id.data(), sha1_hash::size, hex_id);
aux::to_hex(e.id.data(), int(e.id.size()), hex_id);
m_log->log(dht_logger::routing_table, "replacing node with higher RTT: %s %s"
, hex_id, print_address(e.addr()).c_str());
}

View File

@ -93,13 +93,13 @@ namespace libtorrent
// shared_secret = (remote_pubkey ^ local_secret) % prime
m_dh_shared_secret = mp::powm(remote_pubkey, m_dh_local_secret, dh_prime);
std::array<std::uint8_t, 96> buffer;
mp::export_bits(m_dh_shared_secret, buffer.begin(), 8);
std::array<char, 96> buffer;
mp::export_bits(m_dh_shared_secret, reinterpret_cast<std::uint8_t*>(buffer.data()), 8);
// calculate the xor mask for the obfuscated hash
hasher h;
h.update("req3", 4);
h.update(reinterpret_cast<char const*>(buffer.data()), buffer.size());
h.update(buffer);
m_xor_mask = h.final();
}
@ -115,7 +115,7 @@ namespace libtorrent
int to_process = m_send_barriers.front().next;
boost::asio::mutable_buffer* bufs;
int num_bufs;
size_t num_bufs;
bool need_destruct = false;
if (to_process != INT_MAX)
{

View File

@ -612,13 +612,13 @@ namespace libtorrent
#endif
x.append(t->torrent_file().info_hash().data(), 20);
sha1_hash hash = hasher(x.c_str(), int(x.size())).final();
sha1_hash hash = hasher(x).final();
int attempts = 0;
int loops = 0;
for (;;)
{
char const* p = hash.data();
for (int i = 0; i < hash.size / sizeof(std::uint32_t); ++i)
for (int i = 0; i < hash.size() / sizeof(std::uint32_t); ++i)
{
++loops;
int const piece = detail::read_uint32(p) % num_pieces;
@ -644,7 +644,7 @@ namespace libtorrent
}
if (++attempts >= num_allowed_pieces) return;
}
hash = hasher(hash.data(), 20).final();
hash = hasher(hash).final();
}
}

View File

@ -97,8 +97,8 @@ namespace libtorrent
{
// verify the info-hash of the metadata stored in the resume file matches
// the torrent we're loading
std::pair<char const*, int> buf = info.data_section();
sha1_hash resume_ih = hasher(buf.first, buf.second).final();
sha1_hash const resume_ih = hasher(info.data_section().first
, info.data_section().second).final();
// if url is set, the info_hash is not actually the info-hash of the
// torrent, but the hash of the URL, until we have the full torrent

View File

@ -525,7 +525,7 @@ namespace libtorrent
{
std::vector<char> buf;
bencode(std::back_inserter(buf), data);
sha1_hash ret = hasher(&buf[0], int(buf.size())).final();
sha1_hash const ret = hasher(buf).final();
#ifndef TORRENT_DISABLE_DHT
async_call(&session_impl::dht_put_immutable_item, data, ret);

View File

@ -46,17 +46,17 @@ namespace libtorrent
// print a sha1_hash object to an ostream as 40 hexadecimal digits
std::ostream& operator<<(std::ostream& os, sha1_hash const& peer)
{
char out[sha1_hash::size * 2 + 1];
aux::to_hex(peer.data(), sha1_hash::size, out);
char out[sha1_hash::size() * 2 + 1];
aux::to_hex(peer.data(), int(sha1_hash::size()), out);
return os << out;
}
// read 40 hexadecimal digits from an istream into a sha1_hash
std::istream& operator>>(std::istream& is, sha1_hash& peer)
{
char hex[sha1_hash::size * 2];
is.read(hex, sha1_hash::size * 2);
if (!aux::from_hex(hex, sha1_hash::size * 2, peer.data()))
char hex[sha1_hash::size() * 2];
is.read(hex, sha1_hash::size() * 2);
if (!aux::from_hex(hex, int(sha1_hash::size()) * 2, peer.data()))
is.setstate(std::ios_base::failbit);
return is;
}
@ -108,7 +108,7 @@ namespace libtorrent
const int num_words = n / 32;
if (num_words >= number_size)
{
std::memset(m_number, 0, size);
std::memset(m_number, 0, size());
return *this;
}
@ -146,7 +146,7 @@ namespace libtorrent
const int num_words = n / 32;
if (num_words >= number_size)
{
std::memset(m_number, 0, size_t(size));
std::memset(m_number, 0, size());
return *this;
}
if (num_words > 0)

View File

@ -151,13 +151,13 @@ namespace libtorrent
if (ip.is_v6())
{
address_v6::bytes_type b = ip.to_v6().to_bytes();
h = hasher(reinterpret_cast<char*>(&b[0]), int(b.size())).final();
h = hasher(reinterpret_cast<char const*>(b.data()), int(b.size())).final();
}
else
#endif
{
address_v4::bytes_type b = ip.to_v4().to_bytes();
h = hasher(reinterpret_cast<char*>(&b[0]), int(b.size())).final();
h = hasher(reinterpret_cast<char const*>(b.data()), int(b.size())).final();
}
}

View File

@ -539,7 +539,7 @@ namespace libtorrent
#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
hasher h;
h.update("req2", 4);
h.update(m_torrent_file->info_hash().data(), 20);
h.update(m_torrent_file->info_hash());
m_ses.add_obfuscated_hash(h.final(), shared_from_this());
#endif
@ -4771,7 +4771,7 @@ namespace libtorrent
uintptr_t self = reinterpret_cast<uintptr_t>(this);
uintptr_t ses = reinterpret_cast<uintptr_t>(&m_ses);
uintptr_t storage = reinterpret_cast<uintptr_t>(m_storage.get());
sha1_hash h = hasher(reinterpret_cast<char const*>(&self), sizeof(self))
sha1_hash const h = hasher(reinterpret_cast<char const*>(&self), sizeof(self))
.update(reinterpret_cast<char const*>(&storage), sizeof(storage))
.update(reinterpret_cast<char const*>(&ses), sizeof(ses))
.final();
@ -7018,10 +7018,7 @@ namespace libtorrent
if (m_torrent_file->is_valid()) return false;
hasher h;
h.update(metadata_buf, metadata_size);
sha1_hash info_hash = h.final();
sha1_hash const info_hash = hasher(metadata_buf, metadata_size).final();
if (info_hash != m_torrent_file->info_hash())
{
if (alerts().should_post<metadata_failed_alert>())

View File

@ -1247,9 +1247,9 @@ namespace libtorrent
while (n > 0)
{
int sibling = merkle_get_sibling(n);
int parent = merkle_get_parent(n);
iter sibling_hash = subtree.find(sibling);
int const sibling = merkle_get_sibling(n);
int const parent = merkle_get_parent(n);
iter const sibling_hash = subtree.find(sibling);
if (sibling_hash == subtree.end())
return false;
to_add[n] = h;
@ -1257,13 +1257,13 @@ namespace libtorrent
hasher hs;
if (sibling < n)
{
hs.update(sibling_hash->second.data(), 20);
hs.update(h.data(), 20);
hs.update(sibling_hash->second);
hs.update(h);
}
else
{
hs.update(h.data(), 20);
hs.update(sibling_hash->second.data(), 20);
hs.update(h);
hs.update(sibling_hash->second);
}
h = hs.final();
n = parent;

View File

@ -143,11 +143,11 @@ boost::shared_ptr<libtorrent::torrent_info> make_test_torrent(
if (!pad_files.empty() && torrent_offset >= pad_files.front().first)
{
h.update(&zero, 1);
h.update(zero);
}
else
{
h.update(&data, 1);
h.update(data);
}
}
piece_hashes += h.final().to_string();

View File

@ -653,8 +653,8 @@ boost::shared_ptr<lt::torrent_info> make_torrent(const int file_sizes[]
for (int i = 0; i < fs.num_pieces(); ++i)
{
std::vector<char> const piece = generate_piece(i, fs.piece_size(i));
ct.set_hash(i, hasher(piece.data(), int(piece.size())).final());
std::vector<char> piece = generate_piece(i, fs.piece_size(i));
ct.set_hash(i, hasher(piece).final());
}
std::vector<char> buf;
@ -739,7 +739,7 @@ boost::shared_ptr<torrent_info> create_torrent(std::ostream* file
// calculate the hash for all pieces
int num = t.num_pieces();
sha1_hash ph = hasher(&piece[0], int(piece.size())).final();
sha1_hash ph = hasher(piece).final();
for (int i = 0; i < num; ++i)
t.set_hash(i, ph);

View File

@ -2013,7 +2013,7 @@ TORRENT_TEST(immutable_put)
{
TEST_EQUAL(put_immutable_item_keys[0].string_value(), "q");
TEST_EQUAL(put_immutable_item_keys[2].string_value(), "put");
std::pair<const char*, int>v = put_immutable_item_keys[6].data_section();
std::pair<const char*, int> v = put_immutable_item_keys[6].data_section();
TEST_EQUAL(std::string(v.first, v.second), flat_data);
char tok[10];
std::snprintf(tok, sizeof(tok), "%02d", i);
@ -2276,8 +2276,8 @@ TORRENT_TEST(dht_dual_stack)
if (ret)
{
char const* nodes_ptr = nodes6_keys[3].string_ptr();
TEST_CHECK(memcmp(nodes_ptr, id.data(), id.size) == 0);
nodes_ptr += id.size;
TEST_CHECK(memcmp(nodes_ptr, id.data(), id.size()) == 0);
nodes_ptr += id.size();
udp::endpoint rep = detail::read_v6_endpoint<udp::endpoint>(nodes_ptr);
TEST_EQUAL(rep, udp::endpoint(addr("4::4"), 4441));
}
@ -2309,8 +2309,8 @@ TORRENT_TEST(dht_dual_stack)
if (ret)
{
char const* nodes_ptr = nodes_keys[3].string_ptr();
TEST_CHECK(memcmp(nodes_ptr, id.data(), id.size) == 0);
nodes_ptr += id.size;
TEST_CHECK(memcmp(nodes_ptr, id.data(), id.size()) == 0);
nodes_ptr += id.size();
udp::endpoint rep = detail::read_v4_endpoint<udp::endpoint>(nodes_ptr);
TEST_EQUAL(rep, udp::endpoint(addr("4.4.4.4"), 4440));
}
@ -2343,14 +2343,14 @@ TORRENT_TEST(dht_dual_stack)
if (ret)
{
char const* nodes_ptr = nodes46_keys[3].string_ptr();
TEST_CHECK(memcmp(nodes_ptr, id.data(), id.size) == 0);
nodes_ptr += id.size;
TEST_CHECK(memcmp(nodes_ptr, id.data(), id.size()) == 0);
nodes_ptr += id.size();
udp::endpoint rep = detail::read_v4_endpoint<udp::endpoint>(nodes_ptr);
TEST_EQUAL(rep, udp::endpoint(addr("4.4.4.4"), 4440));
nodes_ptr = nodes46_keys[4].string_ptr();
TEST_CHECK(memcmp(nodes_ptr, id.data(), id.size) == 0);
nodes_ptr += id.size;
TEST_CHECK(memcmp(nodes_ptr, id.data(), id.size()) == 0);
nodes_ptr += id.size();
rep = detail::read_v6_endpoint<udp::endpoint>(nodes_ptr);
TEST_EQUAL(rep, udp::endpoint(addr("4::4"), 4441));
}

View File

@ -132,7 +132,7 @@ boost::shared_ptr<default_storage> setup_torrent(file_storage& fs
libtorrent::create_torrent t(fs, 4, -1, 0);
char buf_[4] = {0, 0, 0, 0};
sha1_hash h = hasher(buf_, 4).final();
sha1_hash h = hasher(buf_).final();
for (int i = 0; i < 6; ++i) t.set_hash(i, h);
bencode(std::back_inserter(buf), t.generate());
@ -167,12 +167,10 @@ boost::shared_ptr<default_storage> setup_torrent(file_storage& fs
return s;
}
typedef boost::shared_array<char> buf_ptr;
buf_ptr new_piece(int size)
std::vector<char> new_piece(int size)
{
buf_ptr ret(static_cast<char*>(malloc(size)), &free);
std::generate(ret.get(), ret.get() + size, random_byte);
std::vector<char> ret(size);
std::generate(ret.begin(), ret.end(), random_byte);
return ret;
}
@ -199,9 +197,9 @@ void run_storage_tests(boost::shared_ptr<torrent_info> info
int num_pieces = fs.num_pieces();
TEST_CHECK(info->num_pieces() == num_pieces);
buf_ptr piece0 = new_piece(piece_size);
buf_ptr piece1 = new_piece(piece_size);
buf_ptr piece2 = new_piece(piece_size);
std::vector<char> piece0 = new_piece(piece_size);
std::vector<char> piece1 = new_piece(piece_size);
std::vector<char> piece2 = new_piece(piece_size);
aux::session_settings set;
set.set_int(settings_pack::disk_io_write_mode
@ -233,11 +231,11 @@ void run_storage_tests(boost::shared_ptr<torrent_info> info
int ret = 0;
// write piece 1 (in slot 0)
file::iovec_t iov = { piece1.get(), half};
file::iovec_t iov = { piece1.data(), half};
ret = s->writev(&iov, 1, 0, 0, 0, ec);
if (ret != half) print_error("writev", ret, ec);
iov.iov_base = piece1.get() + half;
iov.iov_base = piece1.data() + half;
iov.iov_len = half;
ret = s->writev(&iov, 1, 0, half, 0, ec);
if (ret != half) print_error("writev", ret, ec);
@ -247,7 +245,7 @@ void run_storage_tests(boost::shared_ptr<torrent_info> info
iov.iov_len = piece_size - 9;
ret = s->readv(&iov, 1, 0, 3, 0, ec);
if (ret != piece_size - 9) print_error("readv",ret, ec);
TEST_CHECK(std::equal(piece+3, piece + piece_size-9, piece1.get()+3));
TEST_CHECK(std::equal(piece+3, piece + piece_size-9, piece1.data()+3));
// test unaligned read (where the bytes are not aligned)
iov.iov_base = piece;
@ -255,7 +253,7 @@ void run_storage_tests(boost::shared_ptr<torrent_info> info
ret = s->readv(&iov, 1, 0, 3, 0, ec);
TEST_CHECK(ret == piece_size - 9);
if (ret != piece_size - 9) print_error("readv", ret, ec);
TEST_CHECK(std::equal(piece, piece + piece_size-9, piece1.get()+3));
TEST_CHECK(std::equal(piece, piece + piece_size-9, piece1.data()+3));
// verify piece 1
iov.iov_base = piece;
@ -263,15 +261,15 @@ void run_storage_tests(boost::shared_ptr<torrent_info> info
ret = s->readv(&iov, 1, 0, 0, 0, ec);
TEST_CHECK(ret == piece_size);
if (ret != piece_size) print_error("readv", ret, ec);
TEST_CHECK(std::equal(piece, piece + piece_size, piece1.get()));
TEST_CHECK(std::equal(piece, piece + piece_size, piece1.data()));
// do the same with piece 0 and 2 (in slot 1 and 2)
iov.iov_base = piece0.get();
iov.iov_base = piece0.data();
iov.iov_len = piece_size;
ret = s->writev(&iov, 1, 1, 0, 0, ec);
if (ret != piece_size) print_error("writev", ret, ec);
iov.iov_base = piece2.get();
iov.iov_base = piece2.data();
iov.iov_len = piece_size;
ret = s->writev(&iov, 1, 2, 0, 0, ec);
if (ret != piece_size) print_error("writev", ret, ec);
@ -281,13 +279,13 @@ void run_storage_tests(boost::shared_ptr<torrent_info> info
iov.iov_len = piece_size;
ret = s->readv(&iov, 1, 1, 0, 0, ec);
if (ret != piece_size) print_error("readv", ret, ec);
TEST_CHECK(std::equal(piece, piece + piece_size, piece0.get()));
TEST_CHECK(std::equal(piece, piece + piece_size, piece0.data()));
iov.iov_base = piece;
iov.iov_len = piece_size;
ret = s->readv(&iov, 1, 2, 0, 0, ec);
if (ret != piece_size) print_error("readv", ret, ec);
TEST_CHECK(std::equal(piece, piece + piece_size, piece2.get()));
TEST_CHECK(std::equal(piece, piece + piece_size, piece2.data()));
s->release_files(ec);
}
@ -425,14 +423,14 @@ void test_check_files(std::string const& test_path
fs.add_file("temp_storage/test2.tmp", piece_size * 2);
fs.add_file("temp_storage/test3.tmp", piece_size);
buf_ptr piece0 = new_piece(piece_size);
buf_ptr piece2 = new_piece(piece_size);
std::vector<char> piece0 = new_piece(piece_size);
std::vector<char> piece2 = new_piece(piece_size);
libtorrent::create_torrent t(fs, piece_size, -1, 0);
t.set_hash(0, hasher(piece0.get(), piece_size).final());
t.set_hash(0, hasher(piece0).final());
t.set_hash(1, sha1_hash(nullptr));
t.set_hash(2, sha1_hash(nullptr));
t.set_hash(3, hasher(piece2.get(), piece_size).final());
t.set_hash(3, hasher(piece2).final());
create_directory(combine_path(test_path, "temp_storage"), ec);
if (ec) std::cerr << "create_directory: " << ec.message() << std::endl;
@ -440,11 +438,11 @@ void test_check_files(std::string const& test_path
std::ofstream f;
f.open(combine_path(test_path, combine_path("temp_storage", "test1.tmp")).c_str()
, std::ios::trunc | std::ios::binary);
f.write(piece0.get(), piece_size);
f.write(piece0.data(), piece_size);
f.close();
f.open(combine_path(test_path, combine_path("temp_storage", "test3.tmp")).c_str()
, std::ios::trunc | std::ios::binary);
f.write(piece2.get(), piece_size);
f.write(piece2.data(), piece_size);
f.close();
std::vector<char> buf;
@ -488,10 +486,10 @@ void run_test(bool unbuffered)
boost::shared_ptr<torrent_info> info;
buf_ptr piece0 = new_piece(piece_size);
buf_ptr piece1 = new_piece(piece_size);
buf_ptr piece2 = new_piece(piece_size);
buf_ptr piece3 = new_piece(piece_size);
std::vector<char> piece0 = new_piece(piece_size);
std::vector<char> piece1 = new_piece(piece_size);
std::vector<char> piece2 = new_piece(piece_size);
std::vector<char> piece3 = new_piece(piece_size);
{
error_code ec;
@ -518,10 +516,10 @@ void run_test(bool unbuffered)
libtorrent::create_torrent t(fs, piece_size, -1, 0);
TEST_CHECK(t.num_pieces() == 4);
t.set_hash(0, hasher(piece0.get(), piece_size).final());
t.set_hash(1, hasher(piece1.get(), piece_size).final());
t.set_hash(2, hasher(piece2.get(), piece_size).final());
t.set_hash(3, hasher(piece3.get(), piece_size).final());
t.set_hash(0, hasher(piece0).final());
t.set_hash(1, hasher(piece1).final());
t.set_hash(2, hasher(piece2).final());
t.set_hash(3, hasher(piece3).final());
std::vector<char> buf;
bencode(std::back_inserter(buf), t.generate());
@ -563,9 +561,9 @@ void run_test(bool unbuffered)
fs.add_file(combine_path("temp_storage", "test1.tmp"), 3 * piece_size);
libtorrent::create_torrent t(fs, piece_size, -1, 0);
TEST_CHECK(fs.file_path(0) == combine_path("temp_storage", "test1.tmp"));
t.set_hash(0, hasher(piece0.get(), piece_size).final());
t.set_hash(1, hasher(piece1.get(), piece_size).final());
t.set_hash(2, hasher(piece2.get(), piece_size).final());
t.set_hash(0, hasher(piece0).final());
t.set_hash(1, hasher(piece1).final());
t.set_hash(2, hasher(piece2).final());
std::vector<char> buf;
bencode(std::back_inserter(buf), t.generate());

View File

@ -152,7 +152,7 @@ void test_running_torrent(boost::shared_ptr<torrent_info> info, std::int64_t fil
TEST_CHECK(memcmp(&piece[0], rpa->buffer.get(), info->piece_size(0)) == 0);
TEST_CHECK(rpa->size == info->piece_size(0));
TEST_CHECK(rpa->piece == 0);
TEST_CHECK(hasher(&piece[0], int(piece.size())).final() == info->hash_for_piece(0));
TEST_CHECK(hasher(piece).final() == info->hash_for_piece(0));
}
}
}
@ -265,7 +265,7 @@ TORRENT_TEST(torrent)
piece[i] = (i % 26) + 'A';
// calculate the hash for all pieces
sha1_hash ph = hasher(&piece[0], piece.size()).final();
sha1_hash ph = hasher(piece).final();
int num = t.num_pieces();
TEST_CHECK(t.num_pieces() > 0);
for (int i = 0; i < num; ++i)
@ -292,7 +292,7 @@ TORRENT_TEST(torrent)
piece[i] = (i % 26) + 'A';
// calculate the hash for all pieces
sha1_hash ph = hasher(&piece[0], int(piece.size())).final();
sha1_hash ph = hasher(piece).final();
int num = t.num_pieces();
TEST_CHECK(t.num_pieces() > 0);
for (int i = 0; i < num; ++i)
@ -336,7 +336,7 @@ TORRENT_TEST(duplicate_is_not_error)
piece[i] = (i % 26) + 'A';
// calculate the hash for all pieces
sha1_hash ph = hasher(&piece[0], int(piece.size())).final();
sha1_hash ph = hasher(piece).final();
int num = t.num_pieces();
TEST_CHECK(t.num_pieces() > 0);
for (int i = 0; i < num; ++i)