Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,12 @@ class bp_connection_manager {
EOS_ASSERT(comma_pos != std::string::npos, chain::plugin_config_exception,
"p2p-bp-gossip-endpoint ${e} must consist of bp-account-name,inbound-server-endpoint,outbound-ip-address separated by commas, second comma is missing", ("e", entry));
auto inbound_server_endpoint = rest.substr(0, comma_pos);
boost::trim(inbound_server_endpoint);
const auto& [host, port, type] = net_utils::split_host_port_type(inbound_server_endpoint);
EOS_ASSERT( !host.empty() && !port.empty() && type.empty(), chain::plugin_config_exception,
"Invalid p2p-bp-gossip-endpoint inbound server endpoint ${p}, syntax host:port", ("p", inbound_server_endpoint));
auto outbound_ip_address = rest.substr(comma_pos + 1);
boost::trim(outbound_ip_address);
EOS_ASSERT( outbound_ip_address.length() <= net_utils::max_p2p_address_length, chain::plugin_config_exception,
"p2p-bp-gossip-endpoint outbound-ip-address ${a} too long, must be less than ${m}",
("a", outbound_ip_address)("m", net_utils::max_p2p_address_length) );
Expand Down
51 changes: 24 additions & 27 deletions plugins/net_plugin/include/eosio/net_plugin/net_utils.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#pragma once

#include <ostream>
#include <eosio/chain/exceptions.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/algorithm/string.hpp>

#include <string>
#include <sstream>
Expand Down Expand Up @@ -51,51 +51,52 @@ namespace detail {
}

/// @return host, port, remainder
inline std::tuple<std::string, std::string, std::string> split_host_port_remainder(const std::string& peer_add, bool should_throw) {
inline std::tuple<std::string, std::string, std::string> split_host_port_remainder(const std::string& endpoint_input, bool should_throw) {
using std::string;
// host:port[:trx|:blk][:<rate>]
if (peer_add.empty()) {
EOS_ASSERT(!should_throw, chain::plugin_config_exception, "Address specification is empty" );
if (endpoint_input.size() > max_p2p_address_length) {
EOS_ASSERT(!should_throw, chain::plugin_config_exception, "Address specification exceeds max p2p address length" );
return {};
}
if (peer_add.size() > max_p2p_address_length) {
EOS_ASSERT(!should_throw, chain::plugin_config_exception, "Address specification exceeds max p2p address length" );
string endpoint = endpoint_input;
boost::trim(endpoint);
if (endpoint.empty()) {
EOS_ASSERT(!should_throw, chain::plugin_config_exception, "Address specification is empty" );
return {};
}

auto colon_count = std::count(peer_add.begin(), peer_add.end(), ':');
auto colon_count = std::count(endpoint.begin(), endpoint.end(), ':');
string::size_type end_bracket = 0;
if (peer_add[0] == '[') {
end_bracket = peer_add.find(']');
if (endpoint[0] == '[') {
end_bracket = endpoint.find(']');
if (end_bracket == string::npos) {
EOS_ASSERT(!should_throw, chain::plugin_config_exception,
"Invalid address specification ${a}, IPv6 no closing square bracket", ("a", peer_add) );
"Invalid address specification ${a}, IPv6 no closing square bracket", ("a", endpoint) );
return {};
}
} else if (colon_count >= 7) {
EOS_ASSERT(!should_throw, chain::plugin_config_exception,
"Invalid address specification ${a}; IPv6 addresses must be enclosed in square brackets.", ("a", peer_add));
"Invalid address specification ${a}; IPv6 addresses must be enclosed in square brackets.", ("a", endpoint));
return {};

} else if (colon_count < 1 || colon_count > 3) {
EOS_ASSERT(!should_throw, chain::plugin_config_exception,
"Invalid address specification ${a}; unexpected number of colons.", ("a", peer_add));
"Invalid address specification ${a}; unexpected number of colons.", ("a", endpoint));
return {};
}
string::size_type colon = peer_add.find(':', end_bracket+1);
string::size_type colon = endpoint.find(':', end_bracket+1);
if (colon == string::npos) {
EOS_ASSERT(!should_throw, chain::plugin_config_exception,
"Invalid address specification ${a}; missing port specification.", ("a", peer_add));
"Invalid address specification ${a}; missing port specification.", ("a", endpoint));
return {};
}
if (end_bracket != 0 && end_bracket+1 != colon) {
EOS_ASSERT(!should_throw, chain::plugin_config_exception,
"Invalid address specification ${a}; unexpected character after ']'.", ("a", peer_add));
"Invalid address specification ${a}; unexpected character after ']'.", ("a", endpoint));
return {};
}
string::size_type colon2 = peer_add.find(':', colon + 1);
string host = end_bracket != 0 ? peer_add.substr( 1, end_bracket - 1 ) : peer_add.substr( 0, colon );
string port = peer_add.substr( colon + 1, colon2 == string::npos ? string::npos : colon2 - (colon + 1));
string::size_type colon2 = endpoint.find(':', colon + 1);
string host = end_bracket != 0 ? endpoint.substr( 1, end_bracket - 1 ) : endpoint.substr( 0, colon );
string port = endpoint.substr( colon + 1, colon2 == string::npos ? string::npos : colon2 - (colon + 1));
string remainder;
if (colon2 == string::npos) {
auto port_end = port.find_first_not_of("0123456789");
Expand All @@ -104,7 +105,7 @@ namespace detail {
remainder = port.substr( port_end );
}
} else {
remainder = peer_add.substr( colon2 + 1 );
remainder = endpoint.substr( colon2 + 1 );
}
return {std::move(host), std::move(port), std::move(remainder)};
}
Expand All @@ -123,15 +124,11 @@ namespace detail {
auto operator<=>(const endpoint& lhs) const = default;
};

/// @return host, port, type. returns empty on invalid peer_add, does not throw
inline std::tuple<std::string, std::string, std::string> split_host_port_type(const std::string& peer_add) {

using std::string;
/// @return host, port, type. returns empty on invalid endpoint, does not throw
inline std::tuple<std::string, std::string, std::string> split_host_port_type(const std::string& endpoint) {
// host:port[:trx|:blk][:<rate>] // rate is discarded
if (peer_add.empty()) return {};

constexpr bool should_throw = false;
auto [host, port, remainder] = detail::split_host_port_remainder(peer_add, should_throw);
auto [host, port, remainder] = detail::split_host_port_remainder(endpoint, should_throw);
if (host.empty() || port.empty()) return {};

std::string type;
Expand Down
2 changes: 1 addition & 1 deletion plugins/net_plugin/tests/rate_limit_parse_unittest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ BOOST_AUTO_TEST_CASE(test_split_host_port_type) {
, "0.0.0.0:9776:blk:0"
, "0.0.0.0:9877:trx:640KB/s"
, "192.168.0.1:9878:blk:20MiB/s"
, "localhost:9879:trx:0.5KB/s"
, " localhost:9879:trx:0.5KB/s"
, "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:9876:trx:250KB/s"
, "[::1]:9876:trx:250KB/s"
, "2001:db8:85a3:8d3:1319:8a2e:370:7348:9876:trx:250KB/s"
Expand Down