Skip to content

Commit

Permalink
update peer_info to hold a proper variant for i2p destination
Browse files Browse the repository at this point in the history
  • Loading branch information
arvidn committed Feb 2, 2025
1 parent b43dbb9 commit a12f014
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 19 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
2.1.0 not released

* fix peer_info holding an i2p destination
* implement i2p_pex, peer exchange support for i2p torrents
* deprecate torrent_alert::torrent_name()
* requires OpenSSL minimum version 1.1.0 with SNI support
Expand Down
16 changes: 14 additions & 2 deletions bindings/python/src/peer_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,22 @@ std::int64_t get_download_queue_time(peer_info const& pi)

tuple get_local_endpoint(peer_info const& pi)
{
return boost::python::make_tuple(pi.local_endpoint.address().to_string(), pi.local_endpoint.port());
auto const ep = pi.local_endpoint();
return boost::python::make_tuple(ep.address().to_string(), ep.port());
}

tuple get_remote_endpoint(peer_info const& pi)
{
auto const ep = pi.remote_endpoint();
return boost::python::make_tuple(ep.address().to_string(), ep.port());
}

#if TORRENT_ABI_VERSION < 4
tuple get_ip(peer_info const& pi)
{
return boost::python::make_tuple(pi.ip.address().to_string(), pi.ip.port());
}
#endif

list get_pieces(peer_info const& pi)
{
Expand All @@ -61,7 +70,9 @@ void bind_peer_info()
.add_property("source", make_getter(&peer_info::source, by_value()))
.add_property("read_state", make_getter(&peer_info::read_state, by_value()))
.add_property("write_state", make_getter(&peer_info::write_state, by_value()))
#if TORRENT_ABI_VERSION < 4
.add_property("ip", get_ip)
#endif
.def_readonly("up_speed", &peer_info::up_speed)
.def_readonly("down_speed", &peer_info::down_speed)
.def_readonly("payload_up_speed", &peer_info::payload_up_speed)
Expand Down Expand Up @@ -107,10 +118,11 @@ void bind_peer_info()
#if TORRENT_ABI_VERSION == 1
.def_readonly("estimated_reciprocation_rate", &peer_info::estimated_reciprocation_rate)
#endif
.add_property("local_endpoint", get_local_endpoint)
#if TORRENT_USE_I2P
.def("i2p_destination", &peer_info::i2p_destination)
#endif
.def("local_endpoint", get_local_endpoint)
.def("remote_endpoint", get_remote_endpoint)
;

// flags
Expand Down
6 changes: 3 additions & 3 deletions examples/client_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ int peer_index(lt::tcp::endpoint addr, std::vector<lt::peer_info> const& peers)
{
using namespace lt;
auto i = std::find_if(peers.begin(), peers.end()
, [&addr](peer_info const& pi) { return pi.ip == addr; });
, [&addr](peer_info const& pi) { return pi.remote_endpoint() == addr; });
if (i == peers.end()) return -1;

return int(i - peers.begin());
Expand Down Expand Up @@ -401,7 +401,7 @@ int print_peer_info(std::string& out
else
#endif
{
std::snprintf(str, sizeof(str), "%-30s ", ::print_endpoint(i->ip).c_str());
std::snprintf(str, sizeof(str), "%-30s ", ::print_endpoint(i->remote_endpoint()).c_str());
out += str;
}
}
Expand All @@ -413,7 +413,7 @@ int print_peer_info(std::string& out
else
#endif
{
std::snprintf(str, sizeof(str), "%-30s ", ::print_endpoint(i->local_endpoint).c_str());
std::snprintf(str, sizeof(str), "%-30s ", ::print_endpoint(i->local_endpoint()).c_str());
out += str;
}
}
Expand Down
24 changes: 22 additions & 2 deletions include/libtorrent/peer_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ see LICENSE file.
#ifndef TORRENT_PEER_INFO_HPP_INCLUDED
#define TORRENT_PEER_INFO_HPP_INCLUDED

#include <variant>

#include "libtorrent/socket.hpp"
#include "libtorrent/aux_/deadline_timer.hpp"
#include "libtorrent/peer_id.hpp"
Expand Down Expand Up @@ -365,18 +367,33 @@ TORRENT_VERSION_NAMESPACE_2
TORRENT_DEPRECATED int estimated_reciprocation_rate;
#endif

#if TORRENT_ABI_VERSION < 4
TORRENT_DEPRECATED tcp::endpoint ip;
#endif

private:

struct ip_endpoint {
tcp::endpoint remote;
tcp::endpoint local;
};
// the sha256_hash is the hash of the i2p destination
std::variant<ip_endpoint, sha256_hash> m_endpoint;

public:

// the IP-address to this peer. The type is an asio endpoint. For
// more info, see the asio_ documentation. This field is not valid for
// i2p peers. Instead use the i2p_destination() function.
//
// .. _asio: http://asio.sourceforge.net/asio-0.3.8/doc/asio/reference.html
tcp::endpoint ip;
tcp::endpoint remote_endpoint() const;

// the IP and port pair the socket is bound to locally. i.e. the IP
// address of the interface it's going out over. This may be useful for
// multi-homed clients with multiple interfaces to the internet.
// This field is not valid for i2p peers.
tcp::endpoint local_endpoint;
tcp::endpoint local_endpoint() const;

// The peer is not waiting for any external events to
// send or receive data.
Expand All @@ -402,6 +419,9 @@ TORRENT_VERSION_NAMESPACE_2
bandwidth_state_flags_t read_state;
bandwidth_state_flags_t write_state;

// internal
void set_endpoints(tcp::endpoint const& local, tcp::endpoint const& remote);

#if TORRENT_USE_I2P
// If this peer is an i2p peer, this function returns the destination
// address of the peer
Expand Down
3 changes: 1 addition & 2 deletions src/peer_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4642,9 +4642,8 @@ namespace {
if (!(p.flags & peer_info::i2p_socket))
#endif
{
p.ip = remote();
error_code ec;
p.local_endpoint = get_socket().local_endpoint(ec);
p.set_endpoints(get_socket().local_endpoint(ec), remote());
}

if (m_snubbed) p.flags |= peer_info::snubbed;
Expand Down
40 changes: 30 additions & 10 deletions src/peer_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,46 @@ namespace libtorrent {
peer_info::peer_info(peer_info&&) = default;
peer_info& peer_info::operator=(peer_info const&) = default;

tcp::endpoint peer_info::remote_endpoint() const
{
#if TORRENT_USE_I2P
if (flags & i2p_socket) return {};
#endif
TORRENT_ASSERT(std::holds_alternative<ip_endpoint>(m_endpoint));
return std::get<ip_endpoint>(m_endpoint).remote;
}

tcp::endpoint peer_info::local_endpoint() const
{
#if TORRENT_USE_I2P
if (flags & i2p_socket) return {};
#endif
TORRENT_ASSERT(std::holds_alternative<ip_endpoint>(m_endpoint));
return std::get<ip_endpoint>(m_endpoint).local;
}

void peer_info::set_endpoints(tcp::endpoint const& local, tcp::endpoint const& remote)
{
TORRENT_ASSERT(!(flags & i2p_socket));
m_endpoint = ip_endpoint{remote, local};
#if TORRENT_ABI_VERSION < 4
ip = remote;
#endif
}

#if TORRENT_USE_I2P
sha256_hash peer_info::i2p_destination() const
{
sha256_hash ret;
if (!(flags & i2p_socket)) return ret;

char const* destination = reinterpret_cast<char const*>(&ip);
static_assert(sizeof(tcp::endpoint) * 2 >= sizeof(sha256_hash), "tcp::endpoint is smaller than expected");

std::memcpy(ret.data(), destination, ret.size());
return ret;
TORRENT_ASSERT(std::holds_alternative<sha256_hash>(m_endpoint));
return std::get<sha256_hash>(m_endpoint);
}

void peer_info::set_i2p_destination(sha256_hash dest)
{
flags |= i2p_socket;
char* destination = reinterpret_cast<char*>(&ip);
static_assert(sizeof(tcp::endpoint) * 2 >= sizeof(sha256_hash), "tcp::endpoint is smaller than expected");

std::memcpy(destination, dest.data(), dest.size());
m_endpoint = dest;
}
#endif
}

0 comments on commit a12f014

Please sign in to comment.