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:
Arvid Norberg 2016-08-06 13:18:48 -04:00 committed by GitHub
parent 7ea9e76b37
commit 71f5510d62
36 changed files with 163 additions and 134 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}
}
/*

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

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

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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());

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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));

View File

@ -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

View File

@ -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)

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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:

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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));

View File

@ -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);

View File

@ -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

View File

@ -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];
}

View File

@ -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);
}

View File

@ -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);
}