Skip to content

Commit c3a8665

Browse files
committed
use lock_guard for streams mutex
1 parent a5ded7f commit c3a8665

7 files changed

Lines changed: 85 additions & 10 deletions

File tree

daemon/I2PControl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ namespace client
9090
m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler;
9191
m_MethodHandlers["NetworkSetting"] = &I2PControlHandlers::NetworkSettingHandler;
9292
m_MethodHandlers["ClientServicesInfo"] = &I2PControlHandlers::ClientServicesInfoHandler;
93+
m_MethodHandlers["LocalDestinationInfo"] = &I2PControlHandlers::LocalDestinationInfoHandler;
9394

9495
// I2PControl
9596
m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler;
@@ -465,6 +466,7 @@ namespace client
465466
X509_NAME_add_entry_by_txt (name, "C", MBSTRING_ASC, (unsigned char *)"A1", -1, -1, 0); // country (Anonymous proxy)
466467
X509_NAME_add_entry_by_txt (name, "O", MBSTRING_ASC, (unsigned char *)I2P_CONTROL_CERTIFICATE_ORGANIZATION, -1, -1, 0); // organization
467468
X509_NAME_add_entry_by_txt (name, "CN", MBSTRING_ASC, (unsigned char *)I2P_CONTROL_CERTIFICATE_COMMON_NAME, -1, -1, 0); // common name
469+
X509_set_subject_name (x509, name);
468470
X509_set_issuer_name (x509, name); // set issuer to ourselves
469471
X509_sign (x509, pkey, EVP_sha1 ()); // sign, last param must be NULL for EdDSA
470472
X509_NAME_free (name);

daemon/I2PControlHandlers.cpp

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,53 @@ namespace client
100100
ss << "\"" << name << "\":" << buf.str();
101101
}
102102

103+
// LocalDestinationInfo
104+
105+
void I2PControlHandlers::LocalDestinationInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
106+
{
107+
auto& addressBook = i2p::client::context.GetAddressBook ();
108+
auto addr = addressBook.GetAddress (params.get<std::string> ("destination", ""));
109+
auto dest = addr && addr->IsIdentHash () ?
110+
i2p::client::context.FindLocalDestination (addr->identHash) : nullptr;
111+
if (!dest)
112+
{
113+
InsertParam (results, "error", std::string ("destination not found"));
114+
return;
115+
}
116+
InsertParam (results, "destination", addressBook.ToAddress (dest->GetIdentHash ()));
117+
118+
// arrays are written by hand: write_json makes an array only below the root
119+
results << ",\"leasesets\":[";
120+
bool first = true;
121+
for (const auto& it: dest->GetLeaseSetsList ())
122+
{
123+
if (!it) continue;
124+
boost::property_tree::ptree ls;
125+
ls.put ("address", addressBook.ToAddress (it->GetIdentHash ()));
126+
ls.put ("type", (int)it->GetStoreType ());
127+
ls.put ("encType", (int)it->GetEncryptionType ());
128+
if (!first) results << ",";
129+
first = false;
130+
boost::property_tree::write_json (results, ls, false);
131+
}
132+
results << "],\"streams\":[";
133+
first = true;
134+
for (const auto& it: dest->GetAllStreams ())
135+
{
136+
if (!it) continue;
137+
auto identity = it->GetRemoteIdentity ();
138+
boost::property_tree::ptree st;
139+
st.put ("id", it->GetRecvStreamID ());
140+
st.put ("destination", identity ? addressBook.ToAddress (identity->GetIdentHash ()) : "");
141+
st.put ("sent", it->GetNumSentBytes ());
142+
st.put ("received", it->GetNumReceivedBytes ());
143+
if (!first) results << ",";
144+
first = false;
145+
boost::property_tree::write_json (results, st, false);
146+
}
147+
results << "]";
148+
}
149+
103150
// RouterInfo
104151

105152
void I2PControlHandlers::RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
@@ -308,13 +355,15 @@ namespace client
308355

309356
void I2PControlHandlers::ClientServicesInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
310357
{
358+
bool first = true;
311359
for (auto it = params.begin (); it != params.end (); it++)
312360
{
313361
LogPrint (eLogDebug, "I2PControl: ClientServicesInfo request: ", it->first);
314362
auto it1 = m_ClientServicesInfoHandlers.find (it->first);
315363
if (it1 != m_ClientServicesInfoHandlers.end ())
316364
{
317-
if (it != params.begin ()) results << ",";
365+
if (!first) results << ",";
366+
else first = false;
318367
(this->*(it1->second))(results);
319368
}
320369
else

daemon/I2PControlHandlers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ namespace client
2929
void RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
3030
void NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
3131
void ClientServicesInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
32+
void LocalDestinationInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results);
3233

3334
protected:
3435

libi2pd/Destination.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,13 +1447,12 @@ namespace client
14471447
{
14481448
std::vector<std::shared_ptr<const i2p::stream::Stream> > ret;
14491449
if (m_StreamingDestination)
1450+
ret = m_StreamingDestination->GetStreamsList ();
1451+
for (auto& it: m_StreamingDestinationsByPorts)
14501452
{
1451-
for (auto& it: m_StreamingDestination->GetStreams ())
1452-
ret.push_back (it.second);
1453+
auto streams = it.second->GetStreamsList ();
1454+
ret.insert (ret.end (), streams.begin (), streams.end ());
14531455
}
1454-
for (auto& it: m_StreamingDestinationsByPorts)
1455-
for (auto& it1: it.second->GetStreams ())
1456-
ret.push_back (it1.second);
14571456
return ret;
14581457
}
14591458

libi2pd/Destination.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <string.h>
1313
#include <thread>
1414
#include <mutex>
15+
#include <vector>
1516
#include <memory>
1617
#include <map>
1718
#include <unordered_map>
@@ -235,6 +236,16 @@ namespace client
235236
// for HTTP only
236237
int GetNumRemoteLeaseSets () const { return m_RemoteLeaseSets.size (); };
237238
const decltype(m_RemoteLeaseSets)& GetLeaseSets () const { return m_RemoteLeaseSets; };
239+
// copy for other threads, unlike GetLeaseSets which hands out the container itself
240+
std::vector<std::shared_ptr<i2p::data::LeaseSet> > GetLeaseSetsList () const
241+
{
242+
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
243+
std::vector<std::shared_ptr<i2p::data::LeaseSet> > leaseSets;
244+
leaseSets.reserve (m_RemoteLeaseSets.size ());
245+
for (const auto& it: m_RemoteLeaseSets)
246+
leaseSets.push_back (it.second);
247+
return leaseSets;
248+
}
238249
bool IsEncryptedLeaseSet () const { return m_LeaseSetType == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2; };
239250
bool IsPerClientAuth () const { return m_AuthType > 0; };
240251
};

libi2pd/Streaming.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2162,7 +2162,7 @@ namespace stream
21622162
m_PendingIncomingTimer.cancel ();
21632163
m_PendingIncomingStreams.clear ();
21642164
{
2165-
std::unique_lock<std::mutex> l(m_StreamsMutex);
2165+
std::lock_guard<std::mutex> l(m_StreamsMutex);
21662166
for (auto it: m_Streams)
21672167
it.second->Terminate (false); // we delete here
21682168
m_Streams.clear ();
@@ -2326,7 +2326,7 @@ namespace stream
23262326
std::shared_ptr<Stream> StreamingDestination::CreateNewOutgoingStream (std::shared_ptr<const i2p::data::LeaseSet> remote, int port)
23272327
{
23282328
auto s = std::make_shared<Stream> (m_Owner->GetService (), *this, remote, port);
2329-
std::unique_lock<std::mutex> l(m_StreamsMutex);
2329+
std::lock_guard<std::mutex> l(m_StreamsMutex);
23302330
m_Streams.emplace (s->GetRecvStreamID (), s);
23312331
return s;
23322332
}
@@ -2340,7 +2340,7 @@ namespace stream
23402340
std::shared_ptr<Stream> StreamingDestination::CreateNewIncomingStream (uint32_t receiveStreamID)
23412341
{
23422342
auto s = std::make_shared<Stream> (m_Owner->GetService (), *this);
2343-
std::unique_lock<std::mutex> l(m_StreamsMutex);
2343+
std::lock_guard<std::mutex> l(m_StreamsMutex);
23442344
m_Streams.emplace (s->GetRecvStreamID (), s);
23452345
m_IncomingStreams.emplace (receiveStreamID, s);
23462346
return s;
@@ -2350,7 +2350,7 @@ namespace stream
23502350
{
23512351
if (stream)
23522352
{
2353-
std::unique_lock<std::mutex> l(m_StreamsMutex);
2353+
std::lock_guard<std::mutex> l(m_StreamsMutex);
23542354
m_Streams.erase (stream->GetRecvStreamID ());
23552355
if (stream->IsIncoming ())
23562356
m_IncomingStreams.erase (stream->GetSendStreamID ());
@@ -2375,6 +2375,15 @@ namespace stream
23752375
}
23762376
}
23772377

2378+
std::vector<std::shared_ptr<const Stream> > StreamingDestination::GetStreamsList ()
2379+
{
2380+
std::vector<std::shared_ptr<const Stream> > streams;
2381+
std::lock_guard<std::mutex> l(m_StreamsMutex);
2382+
for (const auto& it: m_Streams)
2383+
streams.push_back (it.second);
2384+
return streams;
2385+
}
2386+
23782387
bool StreamingDestination::DeleteStream (uint32_t recvStreamID)
23792388
{
23802389
auto it = m_Streams.find (recvStreamID);

libi2pd/Streaming.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <unordered_map>
1515
#include <set>
1616
#include <queue>
17+
#include <vector>
1718
#include <functional>
1819
#include <memory>
1920
#include <mutex>
@@ -391,6 +392,9 @@ namespace stream
391392

392393
// for HTTP only
393394
const decltype(m_Streams)& GetStreams () const { return m_Streams; };
395+
396+
// copy for other threads, unlike GetStreams which hands out the map itself
397+
std::vector<std::shared_ptr<const Stream> > GetStreamsList ();
394398
};
395399

396400
//-------------------------------------------------

0 commit comments

Comments
 (0)