Skip to content
Closed
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
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,8 @@ if(APPLE AND SROUTER_FULL)
endif()

add_executable(libsession-router_jank_test EXCLUDE_FROM_ALL contrib/libsession-router_jank_test.cpp)
target_link_libraries(libsession-router_jank_test PRIVATE libsession-router)
target_include_directories(libsession-router_jank_test PUBLIC include/)
target_link_libraries(libsession-router_jank_test PRIVATE libsessionrouter)

# uninstall target
if(NOT TARGET uninstall)
Expand Down
27 changes: 21 additions & 6 deletions contrib/libsession-router_jank_test.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include <session_router.hpp>
#include <session/router.hpp>

#include <exception>
#include <filesystem>
Expand All @@ -18,18 +18,19 @@ int main(int argc, char** argv)

std::string target{argv[1]};

session_router::Session Router loki{std::filesystem::path{"session_router.ini"}};
session::router::SessionRouter srouter{std::filesystem::path{"session_router.ini"}};

std::promise<void> prom;
loki.on_connected([&] {
srouter.on_connected([&] {
std::cout << "\n\x1b[32;1mSession Router connected!\x1b[0m\n\n\x1b[33;1mINITIATING SESSION TO " << target
<< "\x1b[0m\n\n"
<< std::flush;
loki.establish_udp(
srouter.establish_udp(
target,
12345,
[](auto udp_info) {
[&prom](auto udp_info) {
std::cout << "\n\x1b[32;1mUDP bound to port " << udp_info.local_port << "\x1b[0m\n\n" << std::flush;
prom.set_value();
},
[&prom](std::string_view fail_msg) {
try
Expand All @@ -45,6 +46,20 @@ int main(int argc, char** argv)
try
{
prom.get_future().get();
const auto current_path = srouter.get_path_for_session(target);
if (!current_path)
{
std::cerr << "future returned with no session / no current path.\n";
return 1;
}
size_t hop_count = 1;
std::cout << "Path to snode:\n";
for (const auto& [snode, ip] : *current_path)
{
std::cout << "\tHop " << hop_count << ":\n\t\t";
std::cout << snode << " @ " << ip << "\n";
hop_count++;
}
}
catch (const std::exception& e)
{
Expand All @@ -53,7 +68,7 @@ int main(int argc, char** argv)
}

/*
loki.map_tcp_remote_port(std::string{argv[1]}, 12345,
srouter.map_tcp_remote_port(std::string{argv[1]}, 12345,
[&](auto tunnel_info) {
std::cout << "\n\nTCP bound to port " << tunnel_info.local_port << "\n\n";
},
Expand Down
19 changes: 19 additions & 0 deletions include/session/router.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <filesystem>
#include <functional>
#include <memory>
#include <optional>
#include <thread>
#include <type_traits>

Expand Down Expand Up @@ -53,6 +54,9 @@ namespace session::router
uint16_t suggested_mtu;
};

using snode_path = std::vector<std::pair<std::string, std::string>>;
using session_path = std::pair<snode_path, std::string>;

class SessionRouter
{
std::unique_ptr<srouter::Context> context;
Expand Down Expand Up @@ -120,6 +124,21 @@ namespace session::router
// (failure). This is provided for quick-and-dirty implementation code; generally code
// should prefer the callback-based async version, above.
tunnel_info establish_udp_blocking(std::string_view remote, uint16_t port);

// If we have a session with the given remote, returns the path we are currently using for
// that session. In the case of a client<->client session, this will be the relay which we
// are using as a pivot.
//
// If there is a session but no current path, an empty vector is
// returned.
// If there is not a session to the remote, std::nullopt is returned.
std::optional<snode_path> get_path_for_session(std::string_view remote);

// Returns the path we're currently using for each session along with the remote endpoint
// of that session. In the case of snode (relay) sessions, the remote endpoint will be
// the same as the path terminus. In the case of client<->client sessions, the remote
// endpoint is the client which we're connected to via that path as a relay.
std::vector<session_path> get_all_session_paths();
};

template SessionRouter::SessionRouter(const std::filesystem::path&, std::shared_ptr<oxen::quic::Loop>);
Expand Down
9 changes: 9 additions & 0 deletions src/handlers/session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1126,4 +1126,13 @@ namespace srouter::handlers
last_tag++;
return last_tag;
}

void SessionEndpoint::for_each_session(
std::function<void(const NetworkAddress&, const session::Session&)> visit) const
{
for (const auto& [addr, s] : _sessions)
{
visit(addr, *s);
}
}
} // namespace srouter::handlers
2 changes: 2 additions & 0 deletions src/handlers/session.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ namespace srouter

void queue_session_packet(const NetworkAddress& remote, IPPacket pkt);

void for_each_session(std::function<void(const NetworkAddress&, const session::Session&)> visit) const;

session_tag next_tag();
};

Expand Down
12 changes: 12 additions & 0 deletions src/path/path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "messages/dht.hpp"
#include "messages/fetch.hpp"
#include "messages/path.hpp"
#include "nodedb.hpp"
#include "path_handler.hpp"
#include "profiling.hpp"
#include "router/router.hpp"
Expand Down Expand Up @@ -304,6 +305,17 @@ namespace srouter::path
}
path_hop_stringifier Path::hop_string() const { return {hops}; }

std::vector<std::pair<std::string, std::string>> Path::get_hops_strings_and_ips() const
{
std::vector<std::pair<std::string, std::string>> ret;
for (const auto& hop : hops)
{
auto rc = _router.node_db().get_rc(hop.router_id);
ret.emplace_back(NetworkAddress{hop.router_id, false}.to_string(), rc->addr().to_ipv4().to_string());
}
return ret;
}

nlohmann::json Path::ExtractStatus() const
{
auto now = srouter::time_now_ms();
Expand Down
2 changes: 2 additions & 0 deletions src/path/path.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ namespace srouter::path

path_hop_stringifier hop_string() const;

std::vector<std::pair<std::string, std::string>> get_hops_strings_and_ips() const;

std::chrono::milliseconds LastRemoteActivityAt() const { return last_recv_msg; }

void do_ping(std::chrono::milliseconds start_time);
Expand Down
15 changes: 15 additions & 0 deletions src/session/session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1656,4 +1656,19 @@ namespace srouter::session
_parent.router.link_endpoint().send_command(
_current_thop->downstream, "session_control"s, std::move(data), nullptr);
}

std::vector<std::pair<std::string, std::string>> OutboundSession::current_path() const
{
if (_current_path)
return _current_path->get_hops_strings_and_ips();
return {};
}

std::vector<std::pair<std::string, std::string>> InboundClientSession::current_path() const
{
if (_current_path)
return _current_path->get_hops_strings_and_ips();
return {};
}

} // namespace srouter::session
6 changes: 6 additions & 0 deletions src/session/session.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ namespace srouter
// session, but also sometimes called in other places (e.g. if we need new paths ASAP
// rather than waiting for the next tick)
virtual void tick([[maybe_unused]] std::chrono::milliseconds now) {}

virtual std::vector<std::pair<std::string, std::string>> current_path() const { return {}; };
};

class OutboundSession : public path::PathHandler, public Session
Expand Down Expand Up @@ -314,6 +316,8 @@ namespace srouter
std::string to_string() const override;

inline static constexpr int MAX_QUEUED_PACKETS = 30;

std::vector<std::pair<std::string, std::string>> current_path() const override;
};

// Outbound Session to Remote Relay
Expand Down Expand Up @@ -417,6 +421,8 @@ namespace srouter

void handle_path_switch(HopID pivot, std::shared_ptr<path::Path> path);

std::vector<std::pair<std::string, std::string>> current_path() const override;

std::string to_string() const override;
};

Expand Down
34 changes: 34 additions & 0 deletions src/session_router.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,38 @@ namespace session::router
return fut.get();
}

std::optional<snode_path> SessionRouter::get_path_for_session(std::string_view remote)
{
srouter::NetworkAddress netaddr;
try
{
netaddr = srouter::NetworkAddress{remote};
}
catch (const std::exception& e)
{
srouter::log::info(logcat, "Invalid remote address: {}", e.what());
return std::nullopt;
}

return context->router->loop.call_get([&r = context->router, addr = std::move(netaddr)]() {
std::optional<snode_path> ret;
if (auto s = r->session_endpoint().get_session(addr); s)
{
ret = s->current_path();
}
return ret;
});
}

std::vector<session_path> SessionRouter::get_all_session_paths()
{
return context->router->loop.call_get([&r = context->router]() {
std::vector<session_path> ret;
auto f = [&ret](const srouter::NetworkAddress& addr, const srouter::session::Session& s) {
ret.emplace_back(s.current_path(), addr.to_string());
};
return ret;
});
}

} // namespace session::router