From e90e9bb5dda132c1eb7e03d6371be82f04a14aab Mon Sep 17 00:00:00 2001 From: Savinda Senevirathne Date: Mon, 30 Nov 2020 11:11:40 +0530 Subject: [PATCH] Limiting NPL message broadcasting and forwarding to trusted nodes. (#173) * Limiting NPL message broadcasting and forwarding to trusted nodes. * Error fix in read_iosocket. --- src/p2p/p2p.cpp | 12 ++++++++---- src/p2p/p2p.hpp | 4 ++-- src/p2p/peer_session_handler.cpp | 6 ++++-- src/sc.cpp | 11 +++++++---- src/unl.cpp | 25 ++++++++++++++++++++++++- src/unl.hpp | 2 +- 6 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/p2p/p2p.cpp b/src/p2p/p2p.cpp index 308cc84a..60fadc56 100644 --- a/src/p2p/p2p.cpp +++ b/src/p2p/p2p.cpp @@ -7,6 +7,7 @@ #include "../ledger.hpp" #include "p2p.hpp" #include "self_node.hpp" +#include "../unl.hpp" namespace p2p { @@ -151,22 +152,24 @@ namespace p2p * @param fbuf Peer outbound message to be broadcasted. * @param send_to_self Whether to also send the message to self (this node). * @param is_msg_forwarding Whether this broadcast is for message forwarding. + * @param only_to_trusted_peers Whether this broadcast is only for the trusted nodes. */ - void broadcast_message(const flatbuffers::FlatBufferBuilder &fbuf, const bool send_to_self, const bool is_msg_forwarding) + void broadcast_message(const flatbuffers::FlatBufferBuilder &fbuf, const bool send_to_self, const bool is_msg_forwarding, const bool only_to_trusted_peers) { std::string_view msg = std::string_view( reinterpret_cast(fbuf.GetBufferPointer()), fbuf.GetSize()); - broadcast_message(msg, send_to_self, is_msg_forwarding); + broadcast_message(msg, send_to_self, is_msg_forwarding, only_to_trusted_peers); } /** * Broadcast the given message to all connected outbound peers. * @param message Message to be forwarded. * @param is_msg_forwarding Whether this broadcast is for message forwarding. + * @param only_to_trusted_peers Whether this broadcast is only for the trusted nodes. * @param skipping_session Session to be skipped in message forwarding(optional). */ - void broadcast_message(std::string_view message, const bool send_to_self, const bool is_msg_forwarding, const peer_comm_session *skipping_session) + void broadcast_message(std::string_view message, const bool send_to_self, const bool is_msg_forwarding, const bool only_to_trusted_peers, const peer_comm_session *skipping_session) { if (send_to_self) self::send(message); @@ -179,7 +182,8 @@ namespace p2p // Exclude given session if provided. // Messages are forwarded only to the requested nodes only in the message forwarding mode. if ((skipping_session && skipping_session == session) || - (is_msg_forwarding && !session->need_consensus_msg_forwarding)) + (is_msg_forwarding && !session->need_consensus_msg_forwarding) || + (only_to_trusted_peers && !unl::exists(session->uniqueid, true))) continue; session->send(message); diff --git a/src/p2p/p2p.hpp b/src/p2p/p2p.hpp index 9c40182b..673a8549 100644 --- a/src/p2p/p2p.hpp +++ b/src/p2p/p2p.hpp @@ -145,9 +145,9 @@ namespace p2p int resolve_peer_challenge(peer_comm_session &session, const peer_challenge_response &challenge_resp); - void broadcast_message(const flatbuffers::FlatBufferBuilder &fbuf, const bool send_to_self, const bool is_msg_forwarding = false); + void broadcast_message(const flatbuffers::FlatBufferBuilder &fbuf, const bool send_to_self, const bool is_msg_forwarding = false, const bool only_to_trusted_peers = false); - void broadcast_message(std::string_view message, const bool send_to_self, const bool is_msg_forwarding = false, const peer_comm_session *skipping_session = NULL); + void broadcast_message(std::string_view message, const bool send_to_self, const bool is_msg_forwarding = false, const bool only_to_trusted_peers = false, const peer_comm_session *skipping_session = NULL); void send_message_to_self(const flatbuffers::FlatBufferBuilder &fbuf); diff --git a/src/p2p/peer_session_handler.cpp b/src/p2p/peer_session_handler.cpp index 4edab282..83f2b288 100644 --- a/src/p2p/peer_session_handler.cpp +++ b/src/p2p/peer_session_handler.cpp @@ -79,15 +79,17 @@ namespace p2p // Check whether the message is qualified for message forwarding. if (p2p::validate_for_peer_msg_forwarding(session, container, content_message_type)) { + // Npl messages are forwarded only to trusted peers. + const bool only_to_trusted_peers = content_message_type == p2pmsg::Message_Npl_Message; if (session.need_consensus_msg_forwarding) { // Forward messages received by weakly connected nodes to other peers. - p2p::broadcast_message(message, false, false, &session); + p2p::broadcast_message(message, false, false, only_to_trusted_peers, &session); } else { // Forward message received from other nodes to weakly connected peers. - p2p::broadcast_message(message, false, true, &session); + p2p::broadcast_message(message, false, true, only_to_trusted_peers, &session); } } diff --git a/src/sc.cpp b/src/sc.cpp index a850754b..a09eb16e 100644 --- a/src/sc.cpp +++ b/src/sc.cpp @@ -506,8 +506,10 @@ namespace sc } else if (res > 0) { - // Broadcast npl messages once contract npl output is collected. - broadcast_npl_output(output); + // Broadcast npl messages once contract npl output is collected + // if the node is in the unl list. + if (unl::exists(conf::cfg.pubkey)) + broadcast_npl_output(output); } return (res > 0) ? 1 : 0; @@ -523,7 +525,7 @@ namespace sc { flatbuffers::FlatBufferBuilder fbuf(1024); msg::fbuf::p2pmsg::create_msg_from_npl_output(fbuf, output, ledger::ctx.get_lcl()); - p2p::broadcast_message(fbuf, true); + p2p::broadcast_message(fbuf, true, false, true); } } @@ -717,7 +719,8 @@ namespace sc { output.resize(READ_BUFFER_SIZE); const int res = read(pfd.fd, output.data(), READ_BUFFER_SIZE); - output.resize(res); // Resize back to the actual bytes read. + if (res > 0) + output.resize(res); // Resize back to the actual bytes read. if (res == -1) LOG_ERROR << errno << ": Error reading from contract socket. stream:" << is_stream_socket; diff --git a/src/unl.cpp b/src/unl.cpp index f8a72c77..2f322955 100644 --- a/src/unl.cpp +++ b/src/unl.cpp @@ -2,6 +2,7 @@ #include "hplog.hpp" #include "conf.hpp" #include "unl.hpp" +#include "crypto.hpp" /** * Manages the UNL public keys of this node. @@ -43,8 +44,30 @@ namespace unl return json_list; } - bool exists(const std::string &bin_pubkey) + /** + * Check whether the given pubkey is in the unl list. + * @param pubkey Pubkey to check for existence. + * @param is_in_hex Whether the given pubkey is in hex format. + * @return Return true if the given pubkey is in the unl list. + */ + bool exists(const std::string &pubkey, const bool is_in_hex) { + std::string bin_pubkey = pubkey; + if (is_in_hex) + { + // If the given pubkey is in hex format, convert the public key to binary. + std::string temp_bin_pubkey; + temp_bin_pubkey.resize(crypto::PFXD_PUBKEY_BYTES); + if (util::hex2bin( + reinterpret_cast(temp_bin_pubkey.data()), + temp_bin_pubkey.length(), + pubkey) != 0) + { + LOG_ERROR << "Error decoding hex pubkey.\n"; + return false; + } + bin_pubkey.swap(temp_bin_pubkey); + } std::shared_lock lock(unl_mutex); return list.find(bin_pubkey) != list.end(); } diff --git a/src/unl.hpp b/src/unl.hpp index f06a4b90..1da2d5c9 100644 --- a/src/unl.hpp +++ b/src/unl.hpp @@ -11,7 +11,7 @@ namespace unl size_t count(); std::set get(); std::string get_json(); - bool exists(const std::string &bin_pubkey); + bool exists(const std::string &pubkey, const bool is_in_hex = false); void init(const std::set &init_list); void update(const std::vector &additions, const std::vector &removals); void update_json_list();