Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable/fix ports with I2P [0.18] #9142

Merged
merged 1 commit into from Feb 24, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 9 additions & 36 deletions src/net/i2p_address.cpp
Expand Up @@ -71,7 +71,7 @@ namespace net
struct i2p_serialized
{
std::string host;
std::uint16_t port;
std::uint16_t port; //! Leave for compatability with older clients

BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(host)
Expand All @@ -80,8 +80,7 @@ namespace net
};
}

i2p_address::i2p_address(const boost::string_ref host, const std::uint16_t port) noexcept
: port_(port)
i2p_address::i2p_address(const boost::string_ref host) noexcept
{
// this is a private constructor, throw if moved to public
assert(host.size() < sizeof(host_));
Expand All @@ -97,27 +96,19 @@ namespace net
}

i2p_address::i2p_address() noexcept
: port_(0)
{
static_assert(sizeof(unknown_host) <= sizeof(host_), "bad buffer size");
std::memcpy(host_, unknown_host, sizeof(unknown_host));
std::memset(host_ + sizeof(unknown_host), 0, sizeof(host_) - sizeof(unknown_host));
}

expect<i2p_address> i2p_address::make(const boost::string_ref address, const std::uint16_t default_port)
expect<i2p_address> i2p_address::make(const boost::string_ref address)
{
boost::string_ref host = address.substr(0, address.rfind(':'));
const boost::string_ref port =
address.substr(host.size() + (host.size() == address.size() ? 0 : 1));

MONERO_CHECK(host_check(host));

std::uint16_t porti = default_port;
if (!port.empty() && !epee::string_tools::get_xtype_from_string(porti, std::string{port}))
return {net::error::invalid_port};

static_assert(b32_length + sizeof(tld) == sizeof(i2p_address::host_), "bad internal host size");
return i2p_address{host, porti};
return i2p_address{host};
}

bool i2p_address::_load(epee::serialization::portable_storage& src, epee::serialization::section* hparent)
Expand All @@ -127,23 +118,21 @@ namespace net
{
std::memcpy(host_, in.host.data(), in.host.size());
std::memset(host_ + in.host.size(), 0, sizeof(host_) - in.host.size());
port_ = in.port;
return true;
}
static_assert(sizeof(unknown_host) <= sizeof(host_), "bad buffer size");
std::memcpy(host_, unknown_host, sizeof(unknown_host)); // include null terminator
port_ = 0;
return false;
}

bool i2p_address::store(epee::serialization::portable_storage& dest, epee::serialization::section* hparent) const
{
const i2p_serialized out{std::string{host_}, port_};
// Set port to 1 for backwards compatability; zero is invalid port
const i2p_serialized out{std::string{host_}, 1};
return out.store(dest, hparent);
}

i2p_address::i2p_address(const i2p_address& rhs) noexcept
: port_(rhs.port_)
{
std::memcpy(host_, rhs.host_, sizeof(host_));
}
Expand All @@ -152,7 +141,6 @@ namespace net
{
if (this != std::addressof(rhs))
{
port_ = rhs.port_;
std::memcpy(host_, rhs.host_, sizeof(host_));
}
return *this;
Expand All @@ -166,13 +154,12 @@ namespace net

bool i2p_address::equal(const i2p_address& rhs) const noexcept
{
return port_ == rhs.port_ && is_same_host(rhs);
return is_same_host(rhs);
}

bool i2p_address::less(const i2p_address& rhs) const noexcept
{
int res = std::strcmp(host_str(), rhs.host_str());
return res < 0 || (res == 0 && port() < rhs.port());
return std::strcmp(host_str(), rhs.host_str()) < 0;
}

bool i2p_address::is_same_host(const i2p_address& rhs) const noexcept
Expand All @@ -182,20 +169,6 @@ namespace net

std::string i2p_address::str() const
{
const std::size_t host_length = std::strlen(host_str());
const std::size_t port_length =
port_ == 0 ? 0 : std::numeric_limits<std::uint16_t>::digits10 + 2;

std::string out{};
out.reserve(host_length + port_length);
out.assign(host_str(), host_length);

if (port_ != 0)
{
out.push_back(':');
namespace karma = boost::spirit::karma;
karma::generate(std::back_inserter(out), karma::ushort_, port());
}
return out;
return host_str();
}
}
9 changes: 4 additions & 5 deletions src/net/i2p_address.h
Expand Up @@ -50,11 +50,10 @@ namespace net
//! b32 i2p address; internal format not condensed/decoded.
class i2p_address
{
std::uint16_t port_;
char host_[61]; // null-terminated

//! Keep in private, `host.size()` has no runtime check
i2p_address(boost::string_ref host, std::uint16_t port) noexcept;
i2p_address(boost::string_ref host) noexcept;

public:
//! \return Size of internal buffer for host.
Expand All @@ -74,7 +73,7 @@ namespace net
with `default_port` being used if port is not specified in
`address`.
*/
static expect<i2p_address> make(boost::string_ref address, std::uint16_t default_port = 0);
static expect<i2p_address> make(boost::string_ref address);

//! Load from epee p2p format, and \return false if not valid tor address
bool _load(epee::serialization::portable_storage& src, epee::serialization::section* hparent);
Expand Down Expand Up @@ -103,8 +102,8 @@ namespace net
//! \return Null-terminated `x.b32.i2p` value or `unknown_str()`.
const char* host_str() const noexcept { return host_; }

//! \return Port value or `0` if unspecified.
std::uint16_t port() const noexcept { return port_; }
//! \return `1` to work with I2P socks which considers `0` error.
std::uint16_t port() const noexcept { return 1; }

static constexpr bool is_loopback() noexcept { return false; }
static constexpr bool is_local() noexcept { return false; }
Expand Down
2 changes: 1 addition & 1 deletion src/net/parse.cpp
Expand Up @@ -81,7 +81,7 @@ namespace net
if (host_str_ref.ends_with(".onion"))
return tor_address::make(address, default_port);
if (host_str_ref.ends_with(".i2p"))
return i2p_address::make(address, default_port);
return i2p_address::make(address);

boost::system::error_code ec;
boost::asio::ip::address_v6 v6 = boost::asio::ip::address_v6::from_string(host_str, ec);
Expand Down
2 changes: 1 addition & 1 deletion src/p2p/net_peerlist_boost_serialization.h
Expand Up @@ -196,7 +196,7 @@ namespace boost
if (std::strcmp(host, net::i2p_address::unknown_str()) == 0)
na = net::i2p_address::unknown();
else
na = MONERO_UNWRAP(net::i2p_address::make(host, port));
na = MONERO_UNWRAP(net::i2p_address::make(host));
}

template <class Archive, class ver_type>
Expand Down