aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/crypto/keccak.c9
-rw-r--r--src/p2p/net_node.inl56
-rw-r--r--src/wallet/wallet_rpc_server.cpp5
3 files changed, 56 insertions, 14 deletions
diff --git a/src/crypto/keccak.c b/src/crypto/keccak.c
index 18ed3152f..851c70a25 100644
--- a/src/crypto/keccak.c
+++ b/src/crypto/keccak.c
@@ -105,9 +105,12 @@ void keccak(const uint8_t *in, size_t inlen, uint8_t *md, int mdlen)
memset(st, 0, sizeof(st));
for ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) {
- for (i = 0; i < rsizw; i++)
- st[i] ^= swap64le(((uint64_t *) in)[i]);
- keccakf(st, KECCAK_ROUNDS);
+ for (i = 0; i < rsizw; i++) {
+ uint64_t ina;
+ memcpy(&ina, in + i * 8, 8);
+ st[i] ^= swap64le(ina);
+ }
+ keccakf(st, KECCAK_ROUNDS);
}
// last block and padding
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index 60d43ba99..cec832231 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -1230,19 +1230,53 @@ namespace nodetool
size_t random_index;
const uint32_t next_needed_pruning_stripe = m_payload_handler.get_next_needed_pruning_stripe().second;
+ // build a set of all the /16 we're connected to, and prefer a peer that's not in that set
+ std::set<uint32_t> classB;
+ if (&zone == &m_network_zones.at(epee::net_utils::zone::public_)) // at returns reference, not copy
+ {
+ zone.m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
+ {
+ if (cntxt.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id())
+ {
+
+ const epee::net_utils::network_address na = cntxt.m_remote_address;
+ const uint32_t actual_ip = na.as<const epee::net_utils::ipv4_network_address>().ip();
+ classB.insert(actual_ip & 0x0000ffff);
+ }
+ return true;
+ });
+ }
+
std::deque<size_t> filtered;
const size_t limit = use_white_list ? 20 : std::numeric_limits<size_t>::max();
- size_t idx = 0;
- zone.m_peerlist.foreach (use_white_list, [&filtered, &idx, limit, next_needed_pruning_stripe](const peerlist_entry &pe){
- if (filtered.size() >= limit)
- return false;
- if (next_needed_pruning_stripe == 0 || pe.pruning_seed == 0)
- filtered.push_back(idx);
- else if (next_needed_pruning_stripe == tools::get_pruning_stripe(pe.pruning_seed))
- filtered.push_front(idx);
- ++idx;
- return true;
- });
+ size_t idx = 0, skipped = 0;
+ for (int step = 0; step < 2; ++step)
+ {
+ bool skip_duplicate_class_B = step == 0;
+ zone.m_peerlist.foreach (use_white_list, [&classB, &filtered, &idx, &skipped, skip_duplicate_class_B, limit, next_needed_pruning_stripe](const peerlist_entry &pe){
+ if (filtered.size() >= limit)
+ return false;
+ bool skip = false;
+ if (skip_duplicate_class_B && pe.adr.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id())
+ {
+ const epee::net_utils::network_address na = pe.adr;
+ uint32_t actual_ip = na.as<const epee::net_utils::ipv4_network_address>().ip();
+ skip = classB.find(actual_ip & 0x0000ffff) != classB.end();
+ }
+ if (skip)
+ ++skipped;
+ else if (next_needed_pruning_stripe == 0 || pe.pruning_seed == 0)
+ filtered.push_back(idx);
+ else if (next_needed_pruning_stripe == tools::get_pruning_stripe(pe.pruning_seed))
+ filtered.push_front(idx);
+ ++idx;
+ return true;
+ });
+ if (skipped == 0 || !filtered.empty())
+ break;
+ if (skipped)
+ MGINFO("Skipping " << skipped << " possible peers as they share a class B with existing peers");
+ }
if (filtered.empty())
{
MDEBUG("No available peer in " << (use_white_list ? "white" : "gray") << " list filtered by " << next_needed_pruning_stripe);
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
index 8b8d832dc..0e2a34470 100644
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
@@ -1745,6 +1745,11 @@ namespace tools
else if (payment_id_str.size() == 2 * sizeof(payment_id8))
{
r = epee::string_tools::hex_to_pod(payment_id_str, payment_id8);
+ if (r)
+ {
+ memcpy(payment_id.data, payment_id8.data, 8);
+ memset(payment_id.data + 8, 0, 24);
+ }
}
else
{