make the random function produce proper random distributions, based o… (#981)
make the random function produce proper random distributions, based on uniform_int_distribution of C++11. also clean up piece_picker's priority_range to return two results instead of taking pointers to out-parameters. fix recent pe-crypto regression exposed by this change
This commit is contained in:
parent
7ea9e76b37
commit
71f5510d62
|
@ -324,14 +324,6 @@ private:
|
|||
read_packet
|
||||
};
|
||||
|
||||
#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
|
||||
enum
|
||||
{
|
||||
handshake_len = 68,
|
||||
dh_key_len = 96
|
||||
};
|
||||
#endif
|
||||
|
||||
// state of on_receive. one of the enums in state_t
|
||||
std::uint8_t m_state;
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ namespace libtorrent
|
|||
// to a list). The definition doesn't mention such a limit though.
|
||||
typedef std::map<std::string, entry> dictionary_type;
|
||||
typedef std::string string_type;
|
||||
typedef std::list<entry> list_type;
|
||||
typedef std::vector<entry> list_type;
|
||||
typedef std::int64_t integer_type;
|
||||
typedef std::vector<char> preformatted_type;
|
||||
|
||||
|
|
|
@ -58,6 +58,8 @@ namespace libtorrent
|
|||
|
||||
using key_t = mp::number<mp::cpp_int_backend<768, 768, mp::unsigned_magnitude, mp::unchecked, void>>;
|
||||
|
||||
std::array<char, 96> export_key(key_t const& k);
|
||||
|
||||
// RC4 state from libtomcrypt
|
||||
struct rc4 {
|
||||
int x, y;
|
||||
|
|
|
@ -716,7 +716,7 @@ namespace libtorrent
|
|||
|
||||
// fills in the range [start, end) of pieces in
|
||||
// m_pieces that have priority 'prio'
|
||||
void priority_range(int prio, int* start, int* end);
|
||||
std::pair<int, int> priority_range(int prio);
|
||||
|
||||
// adds the piece 'index' to m_pieces
|
||||
void add(int index);
|
||||
|
|
|
@ -35,6 +35,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace libtorrent
|
||||
{
|
||||
std::uint32_t TORRENT_EXTRA_EXPORT random();
|
||||
std::uint32_t TORRENT_EXTRA_EXPORT randint(int i);
|
||||
std::uint32_t TORRENT_EXTRA_EXPORT random(std::uint32_t max);
|
||||
std::uint32_t TORRENT_EXTRA_EXPORT randint(std::uint32_t one_past_end);
|
||||
}
|
||||
|
|
|
@ -61,13 +61,13 @@ namespace {
|
|||
// this is the IP address assigned to node 'idx'
|
||||
asio::ip::address addr_from_int(int /* idx */)
|
||||
{
|
||||
return asio::ip::address_v4(lt::random());
|
||||
return rand_v4();
|
||||
}
|
||||
|
||||
asio::ip::address addr6_from_int(int /* idx */)
|
||||
{
|
||||
asio::ip::address_v6::bytes_type bytes;
|
||||
for (uint8_t& b : bytes) b = uint8_t(lt::random());
|
||||
for (uint8_t& b : bytes) b = uint8_t(lt::random(0xff));
|
||||
return asio::ip::address_v6(bytes);
|
||||
}
|
||||
|
||||
|
@ -217,7 +217,7 @@ struct dht_node final : lt::dht::udp_socket_interface
|
|||
// there are no more slots in this bucket, just move ont
|
||||
if (nodes_per_bucket[bucket] == 0) continue;
|
||||
--nodes_per_bucket[bucket];
|
||||
bool const added = dht().m_table.node_seen(n.first, n.second, (lt::random() % 300) + 10);
|
||||
bool const added = dht().m_table.node_seen(n.first, n.second, lt::random(300) + 10);
|
||||
TEST_CHECK(added);
|
||||
if (m_add_dead_nodes)
|
||||
{
|
||||
|
@ -226,7 +226,7 @@ struct dht_node final : lt::dht::udp_socket_interface
|
|||
dht::node_id target = dht::generate_random_id() & ~mask;
|
||||
target |= id & mask;
|
||||
dht().m_table.node_seen(target, rand_udp_ep(m_ipv6 ? rand_v6 : rand_v4)
|
||||
, (lt::random() % 300) + 10);
|
||||
, lt::random(300) + 10);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -143,8 +143,8 @@ TORRENT_TEST(dht_bootstrap)
|
|||
{
|
||||
ses.post_session_stats();
|
||||
std::printf("depth: %d nodes: %d\n", routing_table_depth, num_nodes);
|
||||
TEST_CHECK(routing_table_depth >= 9);
|
||||
TEST_CHECK(num_nodes >= 115);
|
||||
TEST_CHECK(routing_table_depth >= 8);
|
||||
TEST_CHECK(num_nodes >= 110);
|
||||
dht.stop();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -42,12 +42,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
#include <boost/multiprecision/integer.hpp>
|
||||
|
||||
// for backwards compatibility with boost < 1.60 which was before export_bits
|
||||
// and import_bits were introduced
|
||||
#if BOOST_VERSION < 106000
|
||||
#include "libtorrent/aux_/cppint_import_export.hpp"
|
||||
#endif
|
||||
|
||||
#include "libtorrent/aux_/disable_warnings_pop.hpp"
|
||||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
|
@ -88,6 +82,12 @@ namespace libtorrent
|
|||
#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
|
||||
namespace {
|
||||
|
||||
enum
|
||||
{
|
||||
handshake_len = 68,
|
||||
dh_key_len = 96
|
||||
};
|
||||
|
||||
// stream key (info hash of attached torrent)
|
||||
// secret is the DH shared secret
|
||||
// initializes m_enc_handler
|
||||
|
@ -102,8 +102,7 @@ namespace libtorrent
|
|||
// outgoing connection : hash ('keyA',S,SKEY)
|
||||
// incoming connection : hash ('keyB',S,SKEY)
|
||||
|
||||
std::array<char, 96> secret_buf;
|
||||
mp::export_bits(secret, reinterpret_cast<std::uint8_t*>(secret_buf.data()), 8);
|
||||
std::array<char, dh_key_len> const secret_buf = export_key(secret);
|
||||
|
||||
if (outgoing) h.update(keyA); else h.update(keyB);
|
||||
h.update(secret_buf);
|
||||
|
@ -486,8 +485,7 @@ namespace libtorrent
|
|||
#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
|
||||
|
||||
namespace {
|
||||
char random_byte()
|
||||
{ return random() & 0xff; }
|
||||
char random_byte() { return random(0xff); }
|
||||
}
|
||||
|
||||
void bt_peer_connection::write_pe1_2_dhkey()
|
||||
|
@ -511,7 +509,7 @@ namespace libtorrent
|
|||
return;
|
||||
}
|
||||
|
||||
int const pad_size = random() % 512;
|
||||
int const pad_size = random(512);
|
||||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
peer_log(peer_log_alert::info, "ENCRYPTION", "pad size: %d", pad_size);
|
||||
|
@ -521,8 +519,8 @@ namespace libtorrent
|
|||
char* ptr = msg;
|
||||
int const buf_size = dh_key_len + pad_size;
|
||||
|
||||
mp::export_bits(m_dh_key_exchange->get_local_key()
|
||||
, reinterpret_cast<std::uint8_t*>(ptr), 8);
|
||||
std::array<char, dh_key_len> const local_key = export_key(m_dh_key_exchange->get_local_key());
|
||||
memcpy(ptr, local_key.data(), dh_key_len);
|
||||
ptr += dh_key_len;
|
||||
|
||||
std::generate(ptr, ptr + pad_size, random_byte);
|
||||
|
@ -548,10 +546,9 @@ 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<char, 96> secret;
|
||||
mp::export_bits(secret_key, reinterpret_cast<std::uint8_t*>(secret.data()), 8);
|
||||
std::array<char, dh_key_len> const secret = export_key(secret_key);
|
||||
|
||||
int pad_size = random() % 512;
|
||||
int const pad_size = random(512);
|
||||
|
||||
// synchash,skeyhash,vc,crypto_provide,len(pad),pad,len(ia)
|
||||
char msg[20 + 20 + 8 + 4 + 2 + 512 + 2];
|
||||
|
@ -566,6 +563,12 @@ namespace libtorrent
|
|||
|
||||
std::memcpy(ptr, sync_hash.data(), 20);
|
||||
ptr += 20;
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
peer_log(peer_log_alert::info, "ENCRYPTION"
|
||||
, "writing synchash %s secret: %s"
|
||||
, aux::to_hex(sync_hash).c_str()
|
||||
, aux::to_hex(secret).c_str());
|
||||
#endif
|
||||
|
||||
static char const req2[4] = {'r', 'e', 'q', '2'};
|
||||
// stream key obfuscated hash [ hash('req2',SKEY) xor hash('req3',S) ]
|
||||
|
@ -591,13 +594,13 @@ namespace libtorrent
|
|||
m_dh_key_exchange.reset(); // secret should be invalid at this point
|
||||
|
||||
// write the verification constant and crypto field
|
||||
int encrypt_size = sizeof(msg) - 512 + pad_size - 40;
|
||||
|
||||
std::uint8_t crypto_provide = m_settings.get_int(settings_pack::allowed_enc_level);
|
||||
int const encrypt_size = sizeof(msg) - 512 + pad_size - 40;
|
||||
|
||||
// this is an invalid setting, but let's just make the best of the situation
|
||||
if ((crypto_provide & settings_pack::pe_both) == 0)
|
||||
crypto_provide = settings_pack::pe_both;
|
||||
int const enc_level = m_settings.get_int(settings_pack::allowed_enc_level);
|
||||
std::uint8_t const crypto_provide = ((enc_level & settings_pack::pe_both) == 0)
|
||||
? settings_pack::pe_both
|
||||
: enc_level;
|
||||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
char const* level[] = {"plaintext", "rc4", "plaintext rc4"};
|
||||
|
@ -621,7 +624,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(crypto_select == 0x02 || crypto_select == 0x01);
|
||||
TORRENT_ASSERT(!m_sent_handshake);
|
||||
|
||||
int const pad_size = random() % 512;
|
||||
int const pad_size = random(512);
|
||||
|
||||
int const buf_size = 8 + 4 + 2 + pad_size;
|
||||
char msg[512 + 8 + 4 + 2];
|
||||
|
@ -669,7 +672,6 @@ namespace libtorrent
|
|||
detail::write_uint32(crypto_field, write_buf);
|
||||
detail::write_uint16(pad_size, write_buf); // len (pad)
|
||||
|
||||
// fill pad with zeroes
|
||||
std::generate(write_buf, write_buf + pad_size, random_byte);
|
||||
write_buf += pad_size;
|
||||
|
||||
|
@ -678,6 +680,7 @@ namespace libtorrent
|
|||
detail::write_uint16(handshake_len, write_buf); // len(IA)
|
||||
}
|
||||
|
||||
// TODO: 3 use span instead of (pointer,len) pairs
|
||||
int bt_peer_connection::get_syncoffset(char const* src, int const src_size
|
||||
, char const* target, int const target_size) const
|
||||
{
|
||||
|
@ -809,7 +812,7 @@ namespace libtorrent
|
|||
// in anonymous mode, every peer connection
|
||||
// has a unique peer-id
|
||||
for (int i = 0; i < 20; ++i)
|
||||
m_our_peer_id[i] = random() & 0xff;
|
||||
m_our_peer_id[i] = random(0xff);
|
||||
}
|
||||
|
||||
std::memcpy(ptr, m_our_peer_id.data(), 20);
|
||||
|
@ -2637,12 +2640,17 @@ namespace libtorrent
|
|||
|
||||
static char const req1[4] = {'r', 'e', 'q', '1'};
|
||||
// compute synchash (hash('req1',S))
|
||||
std::array<char, 96> buffer;
|
||||
mp::export_bits(m_dh_key_exchange->get_secret()
|
||||
, reinterpret_cast<std::uint8_t*>(buffer.data()), 8);
|
||||
std::array<char, dh_key_len> const buffer = export_key(m_dh_key_exchange->get_secret());
|
||||
hasher h(req1);
|
||||
h.update(buffer);
|
||||
m_sync_hash.reset(new sha1_hash(h.final()));
|
||||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
peer_log(peer_log_alert::info, "ENCRYPTION"
|
||||
, "looking for synchash %s secret: %s"
|
||||
, aux::to_hex(*m_sync_hash).c_str()
|
||||
, aux::to_hex(buffer).c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
int const syncoffset = get_syncoffset(m_sync_hash->data(), 20
|
||||
|
|
|
@ -125,8 +125,7 @@ namespace libtorrent
|
|||
|
||||
if (m_external_addresses.size() > 40)
|
||||
{
|
||||
if (random() % 100 < 50)
|
||||
return maybe_rotate();
|
||||
if (random(1)) return maybe_rotate();
|
||||
|
||||
// use stable sort here to maintain the fifo-order
|
||||
// of the entries with the same number of votes
|
||||
|
|
|
@ -236,20 +236,35 @@ namespace
|
|||
// max_peers_reply should probably be specified in bytes
|
||||
if (!v.peers.empty() && v.peers.begin()->addr.protocol() == tcp::v6())
|
||||
max /= 4;
|
||||
int num = (std::min)(int(v.peers.size()), max);
|
||||
// we're picking "to_pick" from a list of "num" at random.
|
||||
int const to_pick = (std::min)(int(v.peers.size()), max);
|
||||
std::set<peer_entry>::const_iterator iter = v.peers.begin();
|
||||
entry::list_type& pe = peers["values"].list();
|
||||
std::string endpoint;
|
||||
|
||||
for (int t = 0, m = 0; m < num && iter != v.peers.end(); ++iter, ++t)
|
||||
for (int t = 0, m = 0; m < to_pick && iter != v.peers.end(); ++iter)
|
||||
{
|
||||
if ((random() / float(UINT_MAX + 1.f)) * (num - t) >= num - m) continue;
|
||||
// if the node asking for peers is a seed, skip seeds from the
|
||||
// peer list
|
||||
if (noseed && iter->seed) continue;
|
||||
endpoint.resize(18);
|
||||
std::string::iterator out = endpoint.begin();
|
||||
|
||||
++t;
|
||||
std::string* str;
|
||||
if (t <= to_pick)
|
||||
{
|
||||
pe.push_back(entry());
|
||||
str = &pe.back().string();
|
||||
}
|
||||
else
|
||||
{
|
||||
// maybe replace an item we've already picked
|
||||
if (random(t-1) >= to_pick) continue;
|
||||
str = &pe[random(to_pick - 1)].string();
|
||||
}
|
||||
|
||||
str->resize(18);
|
||||
std::string::iterator out = str->begin();
|
||||
write_endpoint(iter->addr, out);
|
||||
endpoint.resize(out - endpoint.begin());
|
||||
pe.push_back(entry(endpoint));
|
||||
str->resize(out - str->begin());
|
||||
|
||||
++m;
|
||||
}
|
||||
|
@ -316,7 +331,7 @@ namespace
|
|||
{
|
||||
// when we're at capacity, there's a 50/50 chance of dropping the
|
||||
// announcing peer or an existing peer
|
||||
if (random() & 1) return;
|
||||
if (random(1)) return;
|
||||
i = v->peers.lower_bound(peer);
|
||||
if (i == v->peers.end()) --i;
|
||||
v->peers.erase(i++);
|
||||
|
|
|
@ -117,8 +117,8 @@ node::node(udp proto, udp_socket_interface* sock
|
|||
, m_counters(cnt)
|
||||
, m_storage(storage)
|
||||
{
|
||||
m_secret[0] = random();
|
||||
m_secret[1] = random();
|
||||
m_secret[0] = random(0xffffffff);
|
||||
m_secret[1] = random(0xffffffff);
|
||||
}
|
||||
|
||||
node::~node() = default;
|
||||
|
@ -242,7 +242,7 @@ int node::bucket_size(int bucket)
|
|||
void node::new_write_key()
|
||||
{
|
||||
m_secret[1] = m_secret[0];
|
||||
m_secret[0] = random();
|
||||
m_secret[0] = random(0xffffffff);
|
||||
}
|
||||
|
||||
void node::unreachable(udp::endpoint const& ep)
|
||||
|
|
|
@ -132,9 +132,9 @@ node_id generate_id_impl(address const& ip_, std::uint32_t r)
|
|||
|
||||
id[0] = (c >> 24) & 0xff;
|
||||
id[1] = (c >> 16) & 0xff;
|
||||
id[2] = ((c >> 8) & 0xf8) | (random() & 0x7);
|
||||
id[2] = ((c >> 8) & 0xf8) | random(0x7);
|
||||
|
||||
for (int i = 3; i < 19; ++i) id[i] = random() & 0xff;
|
||||
for (int i = 3; i < 19; ++i) id[i] = random(0xff);
|
||||
id[19] = r & 0xff;
|
||||
|
||||
return id;
|
||||
|
@ -144,14 +144,14 @@ static std::uint32_t secret = 0;
|
|||
|
||||
void make_id_secret(node_id& in)
|
||||
{
|
||||
if (secret == 0) secret = (random() % 0xfffffffe) + 1;
|
||||
if (secret == 0) secret = random(0xfffffffe) + 1;
|
||||
|
||||
std::uint32_t rand = random();
|
||||
std::uint32_t const rand = random(0xffffffff);
|
||||
|
||||
// generate the last 4 bytes as a "signature" of the previous 4 bytes. This
|
||||
// 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);
|
||||
hasher h(reinterpret_cast<char const*>(&secret), 4);
|
||||
h.update(reinterpret_cast<char const*>(&rand), 4);
|
||||
sha1_hash const secret_hash = h.final();
|
||||
memcpy(&in[20-4], &secret_hash[0], 4);
|
||||
memcpy(&in[20-8], &rand, 4);
|
||||
|
@ -160,7 +160,7 @@ void make_id_secret(node_id& in)
|
|||
node_id generate_random_id()
|
||||
{
|
||||
char r[20];
|
||||
for (int i = 0; i < 20; ++i) r[i] = random() & 0xff;
|
||||
for (int i = 0; i < 20; ++i) r[i] = random(0xff);
|
||||
return hasher(r, 20).final();
|
||||
}
|
||||
|
||||
|
@ -195,7 +195,7 @@ bool verify_id(node_id const& nid, address const& source_ip)
|
|||
|
||||
node_id generate_id(address const& ip)
|
||||
{
|
||||
return generate_id_impl(ip, random());
|
||||
return generate_id_impl(ip, random(0xffffffff));
|
||||
}
|
||||
|
||||
bool matching_prefix(node_entry const& n, int mask, int prefix, int bucket_index)
|
||||
|
|
|
@ -461,7 +461,7 @@ bool rpc_manager::invoke(entry& e, udp::endpoint target_addr
|
|||
std::string transaction_id;
|
||||
transaction_id.resize(2);
|
||||
char* out = &transaction_id[0];
|
||||
int tid = (random() ^ (random() << 5)) & 0xffff;
|
||||
int tid = random(0x7fff);
|
||||
io::write_uint16(tid, out);
|
||||
e["t"] = transaction_id;
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ void traversal_algorithm::add_entry(node_id const& id, udp::endpoint addr, unsig
|
|||
{
|
||||
address_v6::bytes_type addr_bytes = o->target_addr().to_v6().to_bytes();
|
||||
address_v6::bytes_type::const_iterator prefix_it = addr_bytes.begin();
|
||||
std::uint64_t prefix6 = detail::read_uint64(prefix_it);
|
||||
std::uint64_t const prefix6 = detail::read_uint64(prefix_it);
|
||||
|
||||
if (m_peer6_prefixes.insert(prefix6).second)
|
||||
goto add_result;
|
||||
|
@ -167,8 +167,8 @@ void traversal_algorithm::add_entry(node_id const& id, udp::endpoint addr, unsig
|
|||
#endif
|
||||
{
|
||||
// mask the lower octet
|
||||
std::uint32_t prefix4 = o->target_addr().to_v4().to_ulong();
|
||||
prefix4 &= 0xffffff00;
|
||||
std::uint32_t const prefix4
|
||||
= o->target_addr().to_v4().to_ulong() & 0xffffff00;
|
||||
|
||||
if (m_peer4_prefixes.insert(prefix4).second)
|
||||
goto add_result;
|
||||
|
|
|
@ -91,7 +91,7 @@ lsd::lsd(io_service& ios, peer_callback_t const& cb
|
|||
, m_log_cb(log)
|
||||
#endif
|
||||
, m_broadcast_timer(ios)
|
||||
, m_cookie((random() ^ boost::uintptr_t(this)) & 0x7fffffff)
|
||||
, m_cookie((random(0x7fffffff) ^ boost::uintptr_t(this)) & 0x7fffffff)
|
||||
, m_disabled(false)
|
||||
#if TORRENT_USE_IPV6
|
||||
, m_disabled6(false)
|
||||
|
|
|
@ -66,11 +66,28 @@ namespace libtorrent
|
|||
("0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A36210000000000090563");
|
||||
}
|
||||
|
||||
std::array<char, 96> export_key(key_t const& k)
|
||||
{
|
||||
std::array<char, 96> ret;
|
||||
std::uint8_t* begin = reinterpret_cast<std::uint8_t*>(ret.data());
|
||||
std::uint8_t* end = mp::export_bits(k, begin, 8);
|
||||
|
||||
// TODO: it would be nice to be able to export to a fixed width field, so
|
||||
// we wouldn't have to shift it later
|
||||
if (end < begin + 96)
|
||||
{
|
||||
int const len = end - begin;
|
||||
memmove(begin + 96 - len, begin, len);
|
||||
memset(begin, 0, 96 - len);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Set the prime P and the generator, generate local public key
|
||||
dh_key_exchange::dh_key_exchange()
|
||||
{
|
||||
std::array<std::uint8_t, 96> random_key;
|
||||
for (auto& i : random_key) i = random();
|
||||
for (auto& i : random_key) i = random(0xff);
|
||||
|
||||
// create local key (random)
|
||||
mp::import_bits(m_dh_local_secret, random_key.begin(), random_key.end());
|
||||
|
|
|
@ -346,7 +346,7 @@ namespace libtorrent
|
|||
if (m_finished != state->is_finished)
|
||||
recalculate_connect_candidates(state);
|
||||
|
||||
int round_robin = random() % m_peers.size();
|
||||
int round_robin = random(std::uint32_t(m_peers.size()-1));
|
||||
|
||||
int low_watermark = max_peerlist_size * 95 / 100;
|
||||
if (low_watermark == max_peerlist_size) --low_watermark;
|
||||
|
@ -361,7 +361,7 @@ namespace libtorrent
|
|||
|
||||
torrent_peer& pe = *m_peers[round_robin];
|
||||
TORRENT_ASSERT(pe.in_use);
|
||||
int current = round_robin;
|
||||
int const current = round_robin;
|
||||
|
||||
if (is_erase_candidate(pe)
|
||||
&& (erase_candidate == -1
|
||||
|
|
|
@ -773,15 +773,15 @@ namespace libtorrent
|
|||
return std::make_pair(min_availability + m_seeds, fraction_part * 1000 / num_pieces);
|
||||
}
|
||||
|
||||
void piece_picker::priority_range(int prio, int* start, int* end)
|
||||
std::pair<int, int> piece_picker::priority_range(int prio)
|
||||
{
|
||||
TORRENT_ASSERT(prio >= 0);
|
||||
TORRENT_ASSERT(prio < int(m_priority_boundaries.size())
|
||||
|| m_dirty);
|
||||
if (prio == 0) *start = 0;
|
||||
else *start = m_priority_boundaries[prio - 1];
|
||||
*end = m_priority_boundaries[prio];
|
||||
TORRENT_ASSERT(*start <= *end);
|
||||
TORRENT_ASSERT(prio < int(m_priority_boundaries.size()) || m_dirty);
|
||||
std::pair<int, int> const ret{
|
||||
prio == 0 ? 0 : m_priority_boundaries[prio-1]
|
||||
, m_priority_boundaries[prio]};
|
||||
TORRENT_ASSERT(ret.first <= ret.second);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void piece_picker::add(int index)
|
||||
|
@ -802,11 +802,10 @@ namespace libtorrent
|
|||
|
||||
TORRENT_ASSERT(int(m_priority_boundaries.size()) >= priority);
|
||||
|
||||
int range_start, range_end;
|
||||
priority_range(priority, &range_start, &range_end);
|
||||
int new_index;
|
||||
if (range_end == range_start) new_index = range_start;
|
||||
else new_index = random() % (range_end - range_start + 1) + range_start;
|
||||
auto range = priority_range(priority);
|
||||
int new_index = (range.second == range.first)
|
||||
? range.first
|
||||
: random(range.second - range.first) + range.first;
|
||||
|
||||
#ifdef TORRENT_PICKER_LOG
|
||||
std::cerr << "[" << this << "] " << "add " << index << " (" << priority << ")" << std::endl;
|
||||
|
@ -1028,10 +1027,8 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(elem_index < int(m_pieces.size()));
|
||||
TORRENT_ASSERT(m_piece_map[m_pieces[elem_index]].priority(this) == priority);
|
||||
|
||||
int range_start, range_end;
|
||||
priority_range(priority, &range_start, &range_end);
|
||||
TORRENT_ASSERT(range_start < range_end);
|
||||
int other_index = random() % (range_end - range_start) + range_start;
|
||||
auto const range = priority_range(priority);
|
||||
int const other_index = random(range.second - range.first - 1) + range.first;
|
||||
|
||||
if (other_index == elem_index) return;
|
||||
|
||||
|
@ -2206,7 +2203,7 @@ namespace libtorrent
|
|||
// we're not using rarest first (only for the first
|
||||
// bucket, since that's where the currently downloading
|
||||
// pieces are)
|
||||
int start_piece = random() % m_piece_map.size();
|
||||
int const start_piece = int(random(std::uint32_t(m_piece_map.size()-1)));
|
||||
|
||||
int piece = start_piece;
|
||||
while (num_blocks > 0)
|
||||
|
@ -2385,7 +2382,7 @@ get_out:
|
|||
while (partials_size > 0)
|
||||
{
|
||||
pc.inc_stats_counter(counters::piece_picker_busy_loops);
|
||||
int piece = random() % partials_size;
|
||||
int piece = random(partials_size-1);
|
||||
downloading_piece const* dp = partials[piece];
|
||||
TORRENT_ASSERT(pieces[dp->index]);
|
||||
TORRENT_ASSERT(piece_priority(dp->index) > 0);
|
||||
|
@ -2409,8 +2406,7 @@ get_out:
|
|||
if (!temp.empty())
|
||||
{
|
||||
ret |= picker_log_alert::end_game;
|
||||
|
||||
interesting_blocks.push_back(temp[random() % temp.size()]);
|
||||
interesting_blocks.push_back(temp[random(std::uint32_t(temp.size()) - 1)]);
|
||||
--num_blocks;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -43,31 +43,31 @@ namespace libtorrent
|
|||
|
||||
#ifdef TORRENT_BUILD_SIMULATOR
|
||||
|
||||
std::uint32_t random()
|
||||
std::uint32_t random(std::uint32_t max)
|
||||
{
|
||||
// make sure random numbers are deterministic. Seed with a fixed number
|
||||
static mt19937 random_engine(4040);
|
||||
return uniform_int_distribution<std::uint32_t>(0
|
||||
, (std::numeric_limits<std::uint32_t>::max)())(random_engine);
|
||||
static mt19937 random_engine(0x82daf973);
|
||||
return uniform_int_distribution<std::uint32_t>(0, max)(random_engine);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
std::uint32_t random()
|
||||
std::uint32_t random(std::uint32_t max)
|
||||
{
|
||||
// TODO: versions prior to msvc-14 (visual studio 2015) do
|
||||
// not generate thread safe initialization of statics
|
||||
static random_device dev;
|
||||
static mt19937 random_engine(dev());
|
||||
return uniform_int_distribution<std::uint32_t>(0
|
||||
, (std::numeric_limits<std::uint32_t>::max)())(random_engine);
|
||||
return uniform_int_distribution<std::uint32_t>(0, max)(random_engine);
|
||||
}
|
||||
|
||||
#endif // TORRENT_BUILD_SIMULATOR
|
||||
|
||||
std::uint32_t randint(int i)
|
||||
|
||||
std::uint32_t randint(std::uint32_t one_past_end)
|
||||
{
|
||||
return random() % i;
|
||||
return random(one_past_end - 1);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -2038,7 +2038,7 @@ namespace aux {
|
|||
socks5_stream& s = *m_socks_listen_socket->get<socks5_stream>();
|
||||
|
||||
m_socks_listen_port = listen_port();
|
||||
if (m_socks_listen_port == 0) m_socks_listen_port = 2000 + random() % 60000;
|
||||
if (m_socks_listen_port == 0) m_socks_listen_port = 2000 + random(60000);
|
||||
s.async_listen(tcp::endpoint(address_v4::any(), m_socks_listen_port)
|
||||
, std::bind(&session_impl::on_socks_listen, this
|
||||
, m_socks_listen_socket, _1));
|
||||
|
|
|
@ -78,7 +78,7 @@ namespace
|
|||
{
|
||||
explicit smart_ban_plugin(torrent& t)
|
||||
: m_torrent(t)
|
||||
, m_salt(random())
|
||||
, m_salt(random(0xffffffff))
|
||||
{}
|
||||
|
||||
void on_piece_pass(int p) override
|
||||
|
|
|
@ -143,7 +143,7 @@ namespace libtorrent
|
|||
|
||||
// the random number
|
||||
while (begin != end)
|
||||
*begin++ = printable[random() % (sizeof(printable)-1)];
|
||||
*begin++ = printable[random(sizeof(printable)-2)];
|
||||
}
|
||||
|
||||
char* allocate_string_copy(char const* str)
|
||||
|
|
|
@ -1363,7 +1363,7 @@ namespace libtorrent
|
|||
{
|
||||
// schedule a disk tick in 2 minutes or so
|
||||
if (m_storage_tick != 0) return;
|
||||
m_storage_tick = 120 + (random() % 60);
|
||||
m_storage_tick = 120 + random(60);
|
||||
update_want_tick();
|
||||
}
|
||||
|
||||
|
@ -1415,7 +1415,7 @@ namespace libtorrent
|
|||
{
|
||||
if (j->ret && m_storage_tick == 0)
|
||||
{
|
||||
m_storage_tick = 120 + (random() % 20);
|
||||
m_storage_tick = 120 + random(20);
|
||||
update_want_tick();
|
||||
}
|
||||
}
|
||||
|
@ -4709,7 +4709,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
if (avail_vec.empty()) return -1;
|
||||
return avail_vec[random() % avail_vec.size()];
|
||||
return avail_vec[random(avail_vec.size() - 1)];
|
||||
}
|
||||
|
||||
void torrent::on_files_deleted(disk_io_job const* j)
|
||||
|
@ -9713,7 +9713,7 @@ namespace libtorrent
|
|||
return;
|
||||
|
||||
// now, pick one of the rarest pieces to download
|
||||
int const pick = random() % rarest_pieces.size();
|
||||
int const pick = random(rarest_pieces.size() - 1);
|
||||
bool const was_finished = is_finished();
|
||||
m_picker->set_piece_priority(rarest_pieces[pick], 1);
|
||||
update_gauge();
|
||||
|
|
|
@ -443,9 +443,7 @@ namespace libtorrent
|
|||
std::uint32_t new_tid;
|
||||
|
||||
// don't use 0, because that has special meaning (unintialized)
|
||||
do {
|
||||
new_tid = random();
|
||||
} while (new_tid == 0);
|
||||
new_tid = random(0xfffffffe) + 1;
|
||||
|
||||
if (m_transaction_id != 0)
|
||||
m_man.update_transaction_id(shared_from_this(), new_tid);
|
||||
|
|
|
@ -1365,7 +1365,7 @@ void upnp::on_upnp_map_response(error_code const& e
|
|||
// some routers return 501 action failed, instead of 716
|
||||
// The external port conflicts with another mapping
|
||||
// pick a random port
|
||||
m.external_port = 40000 + (random() % 10000);
|
||||
m.external_port = 40000 + random(10000);
|
||||
m.action = mapping_t::action_add;
|
||||
++m.failcount;
|
||||
update_map(d, mapping);
|
||||
|
|
|
@ -471,7 +471,7 @@ namespace libtorrent { namespace
|
|||
|
||||
void failed_hash_check(time_point const& now)
|
||||
{
|
||||
m_request_limit = now + seconds(20 + (std::int64_t(random()) * 50) / UINT_MAX);
|
||||
m_request_limit = now + seconds(20 + random(50));
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -338,7 +338,7 @@ namespace libtorrent
|
|||
}
|
||||
else
|
||||
{
|
||||
send_id = random() & 0xffff;
|
||||
send_id = random(0xffff);
|
||||
recv_id = send_id - 1;
|
||||
}
|
||||
utp_socket_impl* impl = construct_utp_impl(recv_id, send_id, str, this);
|
||||
|
|
|
@ -1356,7 +1356,7 @@ void utp_socket_impl::send_syn()
|
|||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
m_seq_nr = random() & 0xffff;
|
||||
m_seq_nr = random(0xffff);
|
||||
m_acked_seq_nr = (m_seq_nr - 1) & ACK_MASK;
|
||||
m_loss_seq_nr = m_acked_seq_nr;
|
||||
m_ack_nr = 0;
|
||||
|
@ -1476,7 +1476,7 @@ void utp_socket_impl::send_reset(utp_header const* ph)
|
|||
h.connection_id = m_send_id;
|
||||
h.timestamp_difference_microseconds = m_reply_micro;
|
||||
h.wnd_size = 0;
|
||||
h.seq_nr = random() & 0xffff;
|
||||
h.seq_nr = random(0xffff);
|
||||
h.ack_nr = ph->seq_nr;
|
||||
time_point now = clock_type::now();
|
||||
h.timestamp_microseconds = std::uint32_t(
|
||||
|
@ -3091,7 +3091,7 @@ bool utp_socket_impl::incoming_packet(span<std::uint8_t const> buf
|
|||
m_port = ep.port();
|
||||
|
||||
m_ack_nr = ph->seq_nr;
|
||||
m_seq_nr = random() & 0xffff;
|
||||
m_seq_nr = random(0xffff);
|
||||
m_acked_seq_nr = (m_seq_nr - 1) & ACK_MASK;
|
||||
m_loss_seq_nr = m_acked_seq_nr;
|
||||
m_fast_resend_seq_nr = m_seq_nr;
|
||||
|
|
|
@ -46,6 +46,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "libtorrent/assert.hpp"
|
||||
#include "libtorrent/file.hpp"
|
||||
#include "libtorrent/random.hpp"
|
||||
#include <csignal>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -322,7 +323,8 @@ EXPORT int main(int argc, char const* argv[])
|
|||
#else
|
||||
chdir(dir);
|
||||
#endif
|
||||
std::fprintf(stderr, "test: %s\ncwd = \"%s\"\n", executable, test_dir.c_str());
|
||||
std::fprintf(stderr, "test: %s\ncwd = \"%s\"\nrnd: %x\n"
|
||||
, executable, test_dir.c_str(), libtorrent::random(0xffffffff));
|
||||
|
||||
int total_failures = 0;
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ sha1_hash rand_hash()
|
|||
{
|
||||
sha1_hash ret;
|
||||
for (int i = 0; i < 20; ++i)
|
||||
ret[i] = boost::uint8_t(lt::random() & 0xff);
|
||||
ret[i] = boost::uint8_t(lt::random(0xff));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ address rand_v6()
|
|||
{
|
||||
address_v6::bytes_type bytes;
|
||||
for (int i = 0; i < int(bytes.size()); ++i)
|
||||
bytes[i] = boost::uint8_t(lt::random() & 0xff);
|
||||
bytes[i] = boost::uint8_t(lt::random(0xff));
|
||||
return address_v6(bytes);
|
||||
}
|
||||
#endif
|
||||
|
@ -533,7 +533,7 @@ int start_proxy(int proxy_type)
|
|||
if (i->second.type == proxy_type) { return i->first; }
|
||||
}
|
||||
|
||||
int port = 2000 + (lt::random() % 6000);
|
||||
int port = 2000 + lt::random(6000);
|
||||
error_code ec;
|
||||
io_service ios;
|
||||
|
||||
|
@ -601,7 +601,7 @@ boost::shared_ptr<T> clone_ptr(boost::shared_ptr<T> const& ptr)
|
|||
}
|
||||
|
||||
unsigned char random_byte()
|
||||
{ return lt::random() & 0xff; }
|
||||
{ return lt::random(0xff); }
|
||||
|
||||
std::vector<char> generate_piece(int const idx, int const piece_size)
|
||||
{
|
||||
|
@ -958,7 +958,7 @@ pid_type web_server_pid = 0;
|
|||
|
||||
int start_web_server(bool ssl, bool chunked_encoding, bool keepalive)
|
||||
{
|
||||
int port = 2000 + (lt::random() % 6000);
|
||||
int port = 2000 + lt::random(6000);
|
||||
error_code ec;
|
||||
io_service ios;
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ void test_swarm(int flags)
|
|||
// three peers before finishing.
|
||||
float rate_limit = 100000;
|
||||
|
||||
int port = lt::random() % 100;
|
||||
int port = lt::random(100);
|
||||
char iface[50];
|
||||
std::snprintf(iface, sizeof(iface), "0.0.0.0:480%02d", port);
|
||||
pack.set_int(settings_pack::upload_rate_limit, int(rate_limit));
|
||||
|
|
|
@ -254,7 +254,7 @@ TORRENT_TEST(peer_limit)
|
|||
|
||||
for (int i = 0; i < 200; ++i)
|
||||
{
|
||||
s->announce_peer(n1, tcp::endpoint(rand_v4(), lt::random())
|
||||
s->announce_peer(n1, tcp::endpoint(rand_v4(), lt::random(0xffff))
|
||||
, "torrent_name", false);
|
||||
dht_storage_counters cnt = s->counters();
|
||||
TEST_CHECK(cnt.peers <= 42);
|
||||
|
@ -271,7 +271,7 @@ TORRENT_TEST(torrent_limit)
|
|||
|
||||
for (int i = 0; i < 200; ++i)
|
||||
{
|
||||
s->announce_peer(rand_hash(), tcp::endpoint(rand_v4(), lt::random())
|
||||
s->announce_peer(rand_hash(), tcp::endpoint(rand_v4(), lt::random(0xffff))
|
||||
, "", false);
|
||||
dht_storage_counters cnt = s->counters();
|
||||
TEST_CHECK(cnt.torrents <= 42);
|
||||
|
|
|
@ -116,10 +116,10 @@ session_proxy test_proxy(settings_pack::proxy_type_t proxy_type, int flags)
|
|||
|
||||
// since multiple sessions may exist simultaneously (because of the
|
||||
// pipelining of the tests) they actually need to use different ports
|
||||
static int listen_port = 10000 + libtorrent::random() % 50000;
|
||||
static int listen_port = 10000 + libtorrent::random(50000);
|
||||
char iface[200];
|
||||
std::snprintf(iface, sizeof(iface), "127.0.0.1:%d", listen_port);
|
||||
listen_port += (libtorrent::random() % 10) + 1;
|
||||
listen_port += libtorrent::random(10) + 1;
|
||||
sett.set_str(settings_pack::listen_interfaces, iface);
|
||||
|
||||
// if we don't do this, the peer connection test
|
||||
|
|
|
@ -48,7 +48,7 @@ TORRENT_TEST(random)
|
|||
|
||||
for (int i = 0; i < repetitions; ++i)
|
||||
{
|
||||
std::uint32_t val = libtorrent::random();
|
||||
std::uint32_t val = libtorrent::random(0xffffffff);
|
||||
val >>= byte * 8;
|
||||
++buckets[val & 0xff];
|
||||
}
|
||||
|
|
|
@ -182,7 +182,7 @@ boost::shared_ptr<torrent_info> generate_torrent()
|
|||
for (int i = 0; i < num; ++i)
|
||||
{
|
||||
sha1_hash ph;
|
||||
for (int k = 0; k < 20; ++k) ph[k] = lt::random();
|
||||
for (int k = 0; k < 20; ++k) ph[k] = lt::random(0xff);
|
||||
t.set_hash(i, ph);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ boost::shared_ptr<torrent_info> generate_torrent()
|
|||
for (int i = 0; i < num; ++i)
|
||||
{
|
||||
sha1_hash ph;
|
||||
for (int k = 0; k < 20; ++k) ph[k] = lt::random();
|
||||
for (int k = 0; k < 20; ++k) ph[k] = lt::random(0xff);
|
||||
t.set_hash(i, ph);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue