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
52 changes: 28 additions & 24 deletions daemon/HTTPServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ namespace http {
{
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
s << "<b>" << tr("Local Destinations") << ":</b><br>\r\n<div class=\"list\">\r\n";
for (auto& it: i2p::client::context.GetDestinations ())
for (auto& it: i2p::client::context.GetDestinationsList ())
{
auto ident = it.second->GetIdentHash ();
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
Expand All @@ -449,10 +449,11 @@ namespace http {
s << "</div>\r\n<br>\r\n";

auto i2cpServer = i2p::client::context.GetI2CPServer ();
if (i2cpServer && !(i2cpServer->GetSessions ().empty ()))
auto i2cpSessions = i2cpServer ? i2cpServer->GetSessionsList () : std::vector<std::pair<uint16_t, std::shared_ptr<i2p::client::I2CPSession> > > ();
if (!i2cpSessions.empty ())
{
s << "<br><b>I2CP "<< tr("Local Destinations") << ":</b><br>\r\n<div class=\"list\">\r\n";
for (auto& it: i2cpServer->GetSessions ())
for (auto& it: i2cpSessions)
{
auto dest = it.second->GetDestination ();
if (dest)
Expand Down Expand Up @@ -523,15 +524,15 @@ namespace http {
<< "<th>" << tr("Type") << "</th>"
<< "<th>" << tr("EncType") << "</th>"
<< "</tr></thead>\r\n<tbody class=\"tableitem\">";
for(auto& it: dest->GetLeaseSets ())
for(auto& it: dest->GetLeaseSetsList ())
{
s << "<tr>"
<< "<td>" << it.first.ToBase32 () << "</td>"
<< "<td>" << it->GetIdentHash ().ToBase32 () << "</td>"
<< "<td><a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_EXPIRELEASE<< "&b32=" << dest->GetIdentHash ().ToBase32 ()
<< "&lease=" << it.first.ToBase32 () << "&token=" << token << "\" title=\"" << tr("Expire LeaseSet") << "\"> &#10008; </a></td>"
<< "<td>" << (int)it.second->GetStoreType () << "</td>";
if (!it.second->IsIncompatibleCrypto ())
s << "<td>" << (int)it.second->GetEncryptionType () <<"</td>";
<< "&lease=" << it->GetIdentHash ().ToBase32 () << "&token=" << token << "\" title=\"" << tr("Expire LeaseSet") << "\"> &#10008; </a></td>"
<< "<td>" << (int)it->GetStoreType () << "</td>";
if (!it->IsIncompatibleCrypto ())
s << "<td>" << (int)it->GetEncryptionType () <<"</td>";
else
s << "<td>n/a</td>";
s << "</tr>\r\n";
Expand All @@ -545,7 +546,7 @@ namespace http {
if (pool)
{
s << "<b>" << tr("Inbound tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
for (auto & it : pool->GetInboundTunnels ()) {
for (auto & it : pool->GetInboundTunnelsList ()) {
s << "<div class=\"listitem\">";
// for each tunnel hop if not zero-hop
if (it->GetNumHops ())
Expand All @@ -567,7 +568,7 @@ namespace http {
}
s << "</div>\r\n<br>\r\n";
s << "<b>" << tr("Outbound tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
for (auto & it : pool->GetOutboundTunnels ()) {
for (auto & it : pool->GetOutboundTunnelsList ()) {
s << "<div class=\"listitem\">";
s << it->GetTunnelID () << ":me &#8658;";
// for each tunnel hop if not zero-hop
Expand All @@ -593,9 +594,10 @@ namespace http {

s << "<b>" << tr("Tags") << "</b><br>\r\n"
<< tr("Incoming") << ": <i>" << dest->GetNumIncomingTags () << "</i><br>\r\n";
if (!dest->GetSessions ().empty ()) {
auto sessionsList = dest->GetSessionsList ();
if (!sessionsList.empty ()) {
std::stringstream tmp_s; uint32_t out_tags = 0;
for (const auto& it: dest->GetSessions ()) {
for (const auto& it: sessionsList) {
tmp_s << "<tr><td>" << i2p::client::context.GetAddressBook ().ToAddress(it.first) << "</td><td>" << it.second->GetNumOutgoingTags () << "</td></tr>\r\n";
out_tags += it.second->GetNumOutgoingTags ();
}
Expand All @@ -612,11 +614,12 @@ namespace http {
auto numECIESx25519Tags = dest->GetNumIncomingECIESx25519Tags ();
if (numECIESx25519Tags > 0) {
s << "<b>ECIESx25519</b><br>\r\n" << tr("Incoming Tags") << ": <i>" << numECIESx25519Tags << "</i><br>\r\n";
if (!dest->GetECIESx25519Sessions ().empty ())
auto eciesSessionsList = dest->GetECIESx25519SessionsList ().get ();
if (!eciesSessionsList.empty ())
{
std::stringstream tmp_s; uint32_t ecies_sessions = 0;
for (const auto& it: dest->GetECIESx25519Sessions ()) {
tmp_s << "<tr><td>" << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetDestination ()) << "</td><td>" << it.second->GetState () << "</td></tr>\r\n";
for (const auto& it: eciesSessionsList) {
tmp_s << "<tr><td>" << i2p::client::context.GetAddressBook ().ToAddress(it->GetDestination ()) << "</td><td>" << it->GetState () << "</td></tr>\r\n";
ecies_sessions++;
}
s << "<div class='slide'><label for='slide-ecies-sessions'>" << tr("Tags sessions") << ": <i>" << ecies_sessions << "</i></label>\r\n"
Expand Down Expand Up @@ -696,9 +699,9 @@ namespace http {
if (i2cpServer)
{
s << "<b>I2CP " << tr("Local Destination") << ":</b><br>\r\n<br>\r\n";
auto it = i2cpServer->GetSessions ().find (std::stoi (id));
if (it != i2cpServer->GetSessions ().end ())
ShowLeaseSetDestination (s, it->second->GetDestination (), 0);
auto session = i2cpServer->FindSessionByID ((uint16_t)std::stoi (id));
if (session)
ShowLeaseSetDestination (s, session->GetDestination (), 0);
else
ShowError(s, tr("I2CP session not found"));
}
Expand Down Expand Up @@ -776,7 +779,7 @@ namespace http {
auto ExplPool = i2p::tunnel::tunnels.GetExploratoryPool ();

s << "<b>" << tr("Inbound tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
for (auto & it : i2p::tunnel::tunnels.GetInboundTunnels ()) {
for (auto & it : i2p::tunnel::tunnels.GetInboundTunnelsList ()) {
s << "<div class=\"listitem\">";
if (it->GetNumHops ())
{
Expand All @@ -797,7 +800,7 @@ namespace http {
}
s << "</div>\r\n<br>\r\n";
s << "<b>" << tr("Outbound tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
for (auto & it : i2p::tunnel::tunnels.GetOutboundTunnels ()) {
for (auto & it : i2p::tunnel::tunnels.GetOutboundTunnelsList ()) {
s << "<div class=\"listitem\">";
s << it->GetTunnelID () << ":me &#8658;";
// for each tunnel hop if not zero-hop
Expand Down Expand Up @@ -899,7 +902,7 @@ namespace http {
s << "<table>\r\n";
s << "<thead><tr><th>&#8658;</th><th>ID</th><th>&#8658;</th><th>" << tr("Amount") << "</th><th>" << tr("Next") << "</th></tr></thead>\r\n";
s << "<tbody class=\"tableitem\">\r\n";
for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ())
for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnelsList ())
{
s << "<tr class=\"tcell_center\">";
if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelGateway>(it))
Expand Down Expand Up @@ -1033,10 +1036,11 @@ namespace http {
return;
}

if (sam->GetSessions ().size ())
auto samSessions = sam->GetSessionsList ();
if (samSessions.size ())
{
s << "<b>" << tr("SAM sessions") << ":</b><br>\r\n<div class=\"list\">\r\n";
for (auto& it: sam->GetSessions ())
for (auto& it: samSessions)
{
auto& name = it.second->GetLocalDestination ()->GetNickname ();
auto sam_id = i2p::data::ByteStreamToBase64 ((const uint8_t *)it.first.data (), it.first.length ()); // base64, becuase session name might be UTF-8
Expand Down
4 changes: 2 additions & 2 deletions daemon/I2PControlHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ namespace client

void I2PControlHandlers::TunnelsParticipatingHandler (std::ostringstream& results)
{
int transit = i2p::tunnel::tunnels.GetTransitTunnels ().size ();
int transit = i2p::tunnel::tunnels.CountTransitTunnels ();
InsertParam (results, "i2p.router.net.tunnels.participating", transit);
}

Expand Down Expand Up @@ -468,7 +468,7 @@ namespace client
{
pt.put("enabled", true);
boost::property_tree::ptree sam_sessions;
for (auto& it: sam->GetSessions ())
for (auto& it: sam->GetSessionsList ())
{
boost::property_tree::ptree sam_session, sam_session_sockets;
auto& name = it.second->GetLocalDestination ()->GetNickname ();
Expand Down
2 changes: 1 addition & 1 deletion libi2pd/Destination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ namespace client
auto inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
if (!outbound || !inbound)
{
if (!m_Pool->GetInboundTunnels ().empty () && !m_Pool->GetOutboundTunnels ().empty ())
if (m_Pool->HasInboundTunnels () && m_Pool->HasOutboundTunnels ())
{
LogPrint (eLogInfo, "Destination: No compatible tunnels with ", floodfill->GetIdentHash ().ToBase64 (), ". Trying another floodfill");
m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
Expand Down
13 changes: 9 additions & 4 deletions libi2pd/Destination.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <unordered_set>
#include <string>
#include <functional>
#include <future>
#include <boost/asio.hpp>
#include "Identity.h"
#include "TunnelPool.h"
Expand Down Expand Up @@ -141,7 +142,7 @@ namespace client
LeaseSetDestination (boost::asio::io_context& service, bool isPublic, const i2p::util::Mapping * params = nullptr);
~LeaseSetDestination ();
const std::string& GetNickname () const { return m_Nickname; };
auto& GetService () { return m_Service; };
auto& GetService () const { return m_Service; };

virtual void Start ();
virtual void Stop ();
Expand All @@ -150,7 +151,7 @@ namespace client
virtual bool Reconfigure(const i2p::util::Mapping& i2cpOpts);

std::shared_ptr<i2p::tunnel::TunnelPool> GetTunnelPool () { return m_Pool; };
bool IsReady () const { return m_LeaseSet && !m_LeaseSet->IsExpired () && m_Pool->GetOutboundTunnels ().size () > 0; };
bool IsReady () const { return m_LeaseSet && !m_LeaseSet->IsExpired () && m_Pool->HasOutboundTunnels (); };
std::shared_ptr<i2p::data::LeaseSet> FindLeaseSet (const i2p::data::IdentHash& ident);
bool RequestDestination (const i2p::data::IdentHash& dest, RequestComplete requestComplete = nullptr);
bool RequestDestinationWithEncryptedLeaseSet (std::shared_ptr<const i2p::data::BlindedPublicKey> dest, RequestComplete requestComplete = nullptr);
Expand Down Expand Up @@ -234,8 +235,7 @@ namespace client
public:

// for HTTP only
int GetNumRemoteLeaseSets () const { return m_RemoteLeaseSets.size (); };
const decltype(m_RemoteLeaseSets)& GetLeaseSets () const { return m_RemoteLeaseSets; };
int GetNumRemoteLeaseSets () const { std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex); return m_RemoteLeaseSets.size (); };
// copy for other threads, unlike GetLeaseSets which hands out the container itself
std::vector<std::shared_ptr<i2p::data::LeaseSet> > GetLeaseSetsList () const
{
Expand All @@ -248,6 +248,11 @@ namespace client
}
bool IsEncryptedLeaseSet () const { return m_LeaseSetType == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; };
bool IsPerClientAuth () const { return m_AuthType > 0; };
std::future<std::vector<i2p::garlic::ECIESX25519AEADRatchetSessionPtr> > GetECIESx25519SessionsList () const
{
return boost::asio::post (GetService (),
boost::asio::use_future ([this]() { return GetECIESx25519SessionsListSync (); }));
}
};

class ClientDestination: public LeaseSetDestination
Expand Down
23 changes: 20 additions & 3 deletions libi2pd/Garlic.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <inttypes.h>
#include <unordered_map>
#include <list>
#include <vector>
#include <utility>
#include <string>
#include <thread>
#include <mutex>
Expand Down Expand Up @@ -319,7 +321,7 @@ namespace garlic
bool m_IsIdling;
// outgoing sessions
int m_NumTags;
std::mutex m_SessionsMutex;
mutable std::mutex m_SessionsMutex;
std::unordered_map<i2p::data::IdentHash, ElGamalAESSessionPtr> m_Sessions;
std::unordered_map<i2p::data::Tag<32>, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session
uint8_t * m_PayloadBuffer; // for ECIESX25519AEADRatchet
Expand All @@ -341,8 +343,23 @@ namespace garlic
// for HTTP only
size_t GetNumIncomingTags () const { return m_Tags.size (); }
size_t GetNumIncomingECIESx25519Tags () const { return m_ECIESx25519Tags.size (); }
const decltype(m_Sessions)& GetSessions () const { return m_Sessions; };
const decltype(m_ECIESx25519Sessions)& GetECIESx25519Sessions () const { return m_ECIESx25519Sessions; }
// thread-safe snapshots, safe to iterate without holding any lock
std::vector<std::pair<i2p::data::IdentHash, ElGamalAESSessionPtr> > GetSessionsList () const
{
std::unique_lock<std::mutex> l(m_SessionsMutex);
return std::vector<std::pair<i2p::data::IdentHash, ElGamalAESSessionPtr> > (m_Sessions.begin (), m_Sessions.end ());
}

protected:

std::vector<ECIESX25519AEADRatchetSessionPtr> GetECIESx25519SessionsListSync () const
{
std::vector<ECIESX25519AEADRatchetSessionPtr> sessions;
sessions.reserve (m_ECIESx25519Sessions.size ());
for (const auto& it: m_ECIESx25519Sessions)
sessions.push_back (it.second);
return sessions;
}
};

void CleanUpTagsFiles ();
Expand Down
7 changes: 6 additions & 1 deletion libi2pd/TransitTunnel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ namespace tunnel
m_Thread->join ();
m_Thread = nullptr;
}
std::lock_guard<std::mutex> l(m_TransitTunnelsMutex);
m_TransitTunnels.clear ();
}

Expand Down Expand Up @@ -636,7 +637,10 @@ namespace tunnel
bool TransitTunnels::AddTransitTunnel (std::shared_ptr<TransitTunnel> tunnel)
{
if (tunnels.AddTunnel (tunnel))
{
std::lock_guard<std::mutex> l(m_TransitTunnelsMutex);
m_TransitTunnels.push_back (tunnel);
}
else
{
LogPrint (eLogError, "TransitTunnel: Tunnel with id ", tunnel->GetTunnelID (), " already exists");
Expand All @@ -647,6 +651,7 @@ namespace tunnel

void TransitTunnels::ManageTransitTunnels (uint64_t ts)
{
std::lock_guard<std::mutex> l(m_TransitTunnelsMutex);
for (auto it = m_TransitTunnels.begin (); it != m_TransitTunnels.end ();)
{
auto tunnel = *it;
Expand All @@ -670,7 +675,7 @@ namespace tunnel
{
int timeout = 0;
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
// TODO: possible race condition with I2PControl
std::lock_guard<std::mutex> l(m_TransitTunnelsMutex);
for (const auto& it : m_TransitTunnels)
{
int t = it->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT - ts;
Expand Down
12 changes: 9 additions & 3 deletions libi2pd/TransitTunnel.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <inttypes.h>
#include <list>
#include <vector>
#include <mutex>
#include <memory>
#include "Crypto.h"
Expand Down Expand Up @@ -137,7 +138,7 @@ namespace tunnel
void Stop ();
void PostTransitTunnelBuildMsg (std::shared_ptr<I2NPMessage>&& msg);

size_t GetNumTransitTunnels () const { return m_TransitTunnels.size (); }
size_t GetNumTransitTunnels () const { std::lock_guard<std::mutex> l(m_TransitTunnelsMutex); return m_TransitTunnels.size (); }
int GetTransitTunnelsExpirationTimeout ();

private:
Expand All @@ -155,14 +156,19 @@ namespace tunnel

volatile bool m_IsRunning;
std::unique_ptr<std::thread> m_Thread;
mutable std::mutex m_TransitTunnelsMutex;
std::list<std::shared_ptr<TransitTunnel> > m_TransitTunnels;
i2p::util::Queue<std::shared_ptr<I2NPMessage> > m_TunnelBuildMsgQueue;
std::mt19937 m_Rng;

public:

// for HTTP only
const auto& GetTransitTunnels () const { return m_TransitTunnels; };
// for HTTP and I2PControl; thread-safe snapshot, safe to iterate without holding any lock
std::vector<std::shared_ptr<TransitTunnel> > GetTransitTunnelsList () const
{
std::lock_guard<std::mutex> l(m_TransitTunnelsMutex);
return std::vector<std::shared_ptr<TransitTunnel> > (m_TransitTunnels.begin (), m_TransitTunnels.end ());
}
size_t GetTunnelBuildMsgQueueSize () const { return m_TunnelBuildMsgQueue.GetSize (); };
};
}
Expand Down
Loading
Loading