mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-03-22 00:59:08 +01:00
commit
c09212de81
56 changed files with 564 additions and 662 deletions
|
@ -3,7 +3,6 @@ cache:
|
||||||
apt: true
|
apt: true
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
- osx
|
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
addons:
|
addons:
|
||||||
|
|
|
@ -173,7 +173,7 @@ namespace client
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto it: addresses) {
|
for (const auto& it: addresses) {
|
||||||
f << it.first << "," << it.second.ToBase32 () << std::endl;
|
f << it.first << "," << it.second.ToBase32 () << std::endl;
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
|
@ -260,8 +260,6 @@ namespace client
|
||||||
m_Storage = nullptr;
|
m_Storage = nullptr;
|
||||||
}
|
}
|
||||||
m_DefaultSubscription = nullptr;
|
m_DefaultSubscription = nullptr;
|
||||||
for (auto it: m_Subscriptions)
|
|
||||||
delete it;
|
|
||||||
m_Subscriptions.clear ();
|
m_Subscriptions.clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,7 +401,7 @@ namespace client
|
||||||
{
|
{
|
||||||
getline(f, s);
|
getline(f, s);
|
||||||
if (!s.length()) continue; // skip empty line
|
if (!s.length()) continue; // skip empty line
|
||||||
m_Subscriptions.push_back (new AddressBookSubscription (*this, s));
|
m_Subscriptions.push_back (std::make_shared<AddressBookSubscription> (*this, s));
|
||||||
}
|
}
|
||||||
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded");
|
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded");
|
||||||
}
|
}
|
||||||
|
@ -418,7 +416,7 @@ namespace client
|
||||||
{
|
{
|
||||||
std::map<std::string, i2p::data::IdentHash> localAddresses;
|
std::map<std::string, i2p::data::IdentHash> localAddresses;
|
||||||
m_Storage->LoadLocal (localAddresses);
|
m_Storage->LoadLocal (localAddresses);
|
||||||
for (auto it: localAddresses)
|
for (const auto& it: localAddresses)
|
||||||
{
|
{
|
||||||
auto dot = it.first.find ('.');
|
auto dot = it.first.find ('.');
|
||||||
if (dot != std::string::npos)
|
if (dot != std::string::npos)
|
||||||
|
@ -462,7 +460,7 @@ namespace client
|
||||||
int nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT;
|
int nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT;
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
if (m_DefaultSubscription) m_DefaultSubscription.reset (nullptr);
|
if (m_DefaultSubscription) m_DefaultSubscription = nullptr;
|
||||||
if (m_IsLoaded)
|
if (m_IsLoaded)
|
||||||
nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT;
|
nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT;
|
||||||
else
|
else
|
||||||
|
@ -516,16 +514,17 @@ namespace client
|
||||||
// download it from http://i2p-projekt.i2p/hosts.txt
|
// download it from http://i2p-projekt.i2p/hosts.txt
|
||||||
LogPrint (eLogInfo, "Addressbook: trying to download it from default subscription.");
|
LogPrint (eLogInfo, "Addressbook: trying to download it from default subscription.");
|
||||||
if (!m_DefaultSubscription)
|
if (!m_DefaultSubscription)
|
||||||
m_DefaultSubscription.reset (new AddressBookSubscription (*this, DEFAULT_SUBSCRIPTION_ADDRESS));
|
m_DefaultSubscription = std::make_shared<AddressBookSubscription>(*this, DEFAULT_SUBSCRIPTION_ADDRESS);
|
||||||
m_IsDownloading = true;
|
m_IsDownloading = true;
|
||||||
m_DefaultSubscription->CheckUpdates ();
|
std::thread load_hosts(std::bind (&AddressBookSubscription::CheckUpdates, m_DefaultSubscription));
|
||||||
|
load_hosts.detach(); // TODO: use join
|
||||||
}
|
}
|
||||||
else if (!m_Subscriptions.empty ())
|
else if (!m_Subscriptions.empty ())
|
||||||
{
|
{
|
||||||
// pick random subscription
|
// pick random subscription
|
||||||
auto ind = rand () % m_Subscriptions.size();
|
auto ind = rand () % m_Subscriptions.size();
|
||||||
m_IsDownloading = true;
|
m_IsDownloading = true;
|
||||||
std::thread load_hosts(&AddressBookSubscription::CheckUpdates, m_Subscriptions[ind]);
|
std::thread load_hosts(std::bind (&AddressBookSubscription::CheckUpdates, m_Subscriptions[ind]));
|
||||||
load_hosts.detach(); // TODO: use join
|
load_hosts.detach(); // TODO: use join
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -659,15 +658,16 @@ namespace client
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(newDataReceivedMutex);
|
std::unique_lock<std::mutex> l(newDataReceivedMutex);
|
||||||
i2p::client::context.GetSharedLocalDestination ()->RequestDestination (m_Ident,
|
i2p::client::context.GetSharedLocalDestination ()->RequestDestination (m_Ident,
|
||||||
[&newDataReceived, &leaseSet](std::shared_ptr<i2p::data::LeaseSet> ls)
|
[&newDataReceived, &leaseSet, &newDataReceivedMutex](std::shared_ptr<i2p::data::LeaseSet> ls)
|
||||||
{
|
{
|
||||||
leaseSet = ls;
|
leaseSet = ls;
|
||||||
|
std::unique_lock<std::mutex> l1(newDataReceivedMutex);
|
||||||
newDataReceived.notify_all ();
|
newDataReceived.notify_all ();
|
||||||
});
|
});
|
||||||
if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout)
|
if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Addressbook: Subscription LeaseSet request timeout expired");
|
LogPrint (eLogError, "Addressbook: Subscription LeaseSet request timeout expired");
|
||||||
i2p::client::context.GetSharedLocalDestination ()->CancelDestinationRequest (m_Ident);
|
i2p::client::context.GetSharedLocalDestination ()->CancelDestinationRequest (m_Ident, false); // don't notify, because we know it already
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,8 +102,8 @@ namespace client
|
||||||
std::map<uint32_t, std::string> m_Lookups; // nonce -> address
|
std::map<uint32_t, std::string> m_Lookups; // nonce -> address
|
||||||
AddressBookStorage * m_Storage;
|
AddressBookStorage * m_Storage;
|
||||||
volatile bool m_IsLoaded, m_IsDownloading;
|
volatile bool m_IsLoaded, m_IsDownloading;
|
||||||
std::vector<AddressBookSubscription *> m_Subscriptions;
|
std::vector<std::shared_ptr<AddressBookSubscription> > m_Subscriptions;
|
||||||
std::unique_ptr<AddressBookSubscription> m_DefaultSubscription; // in case if we don't know any addresses yet
|
std::shared_ptr<AddressBookSubscription> m_DefaultSubscription; // in case if we don't know any addresses yet
|
||||||
boost::asio::deadline_timer * m_SubscriptionsUpdateTimer;
|
boost::asio::deadline_timer * m_SubscriptionsUpdateTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
8
BOB.cpp
8
BOB.cpp
|
@ -536,8 +536,8 @@ namespace client
|
||||||
void BOBCommandSession::ListCommandHandler (const char * operand, size_t len)
|
void BOBCommandSession::ListCommandHandler (const char * operand, size_t len)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "BOB: list");
|
LogPrint (eLogDebug, "BOB: list");
|
||||||
auto& destinations = m_Owner.GetDestinations ();
|
const auto& destinations = m_Owner.GetDestinations ();
|
||||||
for (auto it: destinations)
|
for (const auto& it: destinations)
|
||||||
SendData (it.first.c_str ());
|
SendData (it.first.c_str ());
|
||||||
SendReplyOK ("Listing done");
|
SendReplyOK ("Listing done");
|
||||||
}
|
}
|
||||||
|
@ -619,7 +619,7 @@ namespace client
|
||||||
BOBCommandChannel::~BOBCommandChannel ()
|
BOBCommandChannel::~BOBCommandChannel ()
|
||||||
{
|
{
|
||||||
Stop ();
|
Stop ();
|
||||||
for (auto it: m_Destinations)
|
for (const auto& it: m_Destinations)
|
||||||
delete it.second;
|
delete it.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -633,7 +633,7 @@ namespace client
|
||||||
void BOBCommandChannel::Stop ()
|
void BOBCommandChannel::Stop ()
|
||||||
{
|
{
|
||||||
m_IsRunning = false;
|
m_IsRunning = false;
|
||||||
for (auto it: m_Destinations)
|
for (auto& it: m_Destinations)
|
||||||
it.second->Stop ();
|
it.second->Stop ();
|
||||||
m_Acceptor.cancel ();
|
m_Acceptor.cancel ();
|
||||||
m_Service.stop ();
|
m_Service.stop ();
|
||||||
|
|
|
@ -194,7 +194,7 @@ namespace client
|
||||||
|
|
||||||
LogPrint(eLogInfo, "Clients: stopping AddressBook");
|
LogPrint(eLogInfo, "Clients: stopping AddressBook");
|
||||||
m_AddressBook.Stop ();
|
m_AddressBook.Stop ();
|
||||||
for (auto it: m_Destinations)
|
for (auto& it: m_Destinations)
|
||||||
it.second->Stop ();
|
it.second->Stop ();
|
||||||
m_Destinations.clear ();
|
m_Destinations.clear ();
|
||||||
m_SharedLocalDestination = nullptr;
|
m_SharedLocalDestination = nullptr;
|
||||||
|
|
|
@ -148,6 +148,11 @@ namespace config {
|
||||||
"Enable or disable elgamal precomputation table")
|
"Enable or disable elgamal precomputation table")
|
||||||
;
|
;
|
||||||
|
|
||||||
|
options_description reseed("Reseed options");
|
||||||
|
reseed.add_options()
|
||||||
|
("reseed.file", value<std::string>()->default_value(""), "Path to .su3 file")
|
||||||
|
;
|
||||||
|
|
||||||
options_description trust("Trust options");
|
options_description trust("Trust options");
|
||||||
trust.add_options()
|
trust.add_options()
|
||||||
("trust.enabled", value<bool>()->default_value(false), "enable explicit trust options")
|
("trust.enabled", value<bool>()->default_value(false), "enable explicit trust options")
|
||||||
|
@ -166,6 +171,7 @@ namespace config {
|
||||||
.add(i2pcontrol)
|
.add(i2pcontrol)
|
||||||
.add(upnp)
|
.add(upnp)
|
||||||
.add(precomputation)
|
.add(precomputation)
|
||||||
|
.add(reseed)
|
||||||
.add(trust)
|
.add(trust)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ namespace client
|
||||||
{
|
{
|
||||||
if (m_IsRunning)
|
if (m_IsRunning)
|
||||||
Stop ();
|
Stop ();
|
||||||
for (auto it: m_LeaseSetRequests)
|
for (auto& it: m_LeaseSetRequests)
|
||||||
if (it.second->requestComplete) it.second->requestComplete (nullptr);
|
if (it.second->requestComplete) it.second->requestComplete (nullptr);
|
||||||
m_LeaseSetRequests.clear ();
|
m_LeaseSetRequests.clear ();
|
||||||
if (m_Pool)
|
if (m_Pool)
|
||||||
|
@ -479,24 +479,25 @@ namespace client
|
||||||
{
|
{
|
||||||
if (!m_Pool || !IsReady ())
|
if (!m_Pool || !IsReady ())
|
||||||
{
|
{
|
||||||
if (requestComplete) requestComplete (nullptr);
|
if (requestComplete)
|
||||||
|
m_Service.post ([requestComplete](void){requestComplete (nullptr);});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_Service.post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), dest, requestComplete));
|
m_Service.post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), dest, requestComplete));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LeaseSetDestination::CancelDestinationRequest (const i2p::data::IdentHash& dest)
|
void LeaseSetDestination::CancelDestinationRequest (const i2p::data::IdentHash& dest, bool notify)
|
||||||
{
|
{
|
||||||
auto s = shared_from_this ();
|
auto s = shared_from_this ();
|
||||||
m_Service.post ([dest, s](void)
|
m_Service.post ([dest, notify, s](void)
|
||||||
{
|
{
|
||||||
auto it = s->m_LeaseSetRequests.find (dest);
|
auto it = s->m_LeaseSetRequests.find (dest);
|
||||||
if (it != s->m_LeaseSetRequests.end ())
|
if (it != s->m_LeaseSetRequests.end ())
|
||||||
{
|
{
|
||||||
auto requestComplete = it->second->requestComplete;
|
auto requestComplete = it->second->requestComplete;
|
||||||
s->m_LeaseSetRequests.erase (it);
|
s->m_LeaseSetRequests.erase (it);
|
||||||
if (requestComplete) requestComplete (nullptr);
|
if (notify && requestComplete) requestComplete (nullptr);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -635,7 +636,7 @@ namespace client
|
||||||
it = m_RemoteLeaseSets.erase (it);
|
it = m_RemoteLeaseSets.erase (it);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,7 +664,7 @@ namespace client
|
||||||
{
|
{
|
||||||
m_StreamingDestination = std::make_shared<i2p::stream::StreamingDestination> (GetSharedFromThis ()); // TODO:
|
m_StreamingDestination = std::make_shared<i2p::stream::StreamingDestination> (GetSharedFromThis ()); // TODO:
|
||||||
m_StreamingDestination->Start ();
|
m_StreamingDestination->Start ();
|
||||||
for (auto it: m_StreamingDestinationsByPorts)
|
for (auto& it: m_StreamingDestinationsByPorts)
|
||||||
it.second->Start ();
|
it.second->Start ();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -677,7 +678,7 @@ namespace client
|
||||||
{
|
{
|
||||||
m_StreamingDestination->Stop ();
|
m_StreamingDestination->Stop ();
|
||||||
m_StreamingDestination = nullptr;
|
m_StreamingDestination = nullptr;
|
||||||
for (auto it: m_StreamingDestinationsByPorts)
|
for (auto& it: m_StreamingDestinationsByPorts)
|
||||||
it.second->Stop ();
|
it.second->Stop ();
|
||||||
if (m_DatagramDestination)
|
if (m_DatagramDestination)
|
||||||
{
|
{
|
||||||
|
|
|
@ -79,7 +79,7 @@ namespace client
|
||||||
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->GetOutboundTunnels ().size () > 0; };
|
||||||
std::shared_ptr<const i2p::data::LeaseSet> FindLeaseSet (const i2p::data::IdentHash& ident);
|
std::shared_ptr<const i2p::data::LeaseSet> FindLeaseSet (const i2p::data::IdentHash& ident);
|
||||||
bool RequestDestination (const i2p::data::IdentHash& dest, RequestComplete requestComplete = nullptr);
|
bool RequestDestination (const i2p::data::IdentHash& dest, RequestComplete requestComplete = nullptr);
|
||||||
void CancelDestinationRequest (const i2p::data::IdentHash& dest);
|
void CancelDestinationRequest (const i2p::data::IdentHash& dest, bool notify = true);
|
||||||
|
|
||||||
// implements GarlicDestination
|
// implements GarlicDestination
|
||||||
std::shared_ptr<const i2p::data::LocalLeaseSet> GetLeaseSet ();
|
std::shared_ptr<const i2p::data::LocalLeaseSet> GetLeaseSet ();
|
||||||
|
|
12
Garlic.cpp
12
Garlic.cpp
|
@ -111,7 +111,7 @@ namespace garlic
|
||||||
it = m_UnconfirmedTagsMsgs.erase (it);
|
it = m_UnconfirmedTagsMsgs.erase (it);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ namespace garlic
|
||||||
if (ts >= it->creationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT)
|
if (ts >= it->creationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT)
|
||||||
it = m_SessionTags.erase (it);
|
it = m_SessionTags.erase (it);
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
CleanupUnconfirmedTags ();
|
CleanupUnconfirmedTags ();
|
||||||
return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty ();
|
return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty ();
|
||||||
|
@ -144,7 +144,7 @@ namespace garlic
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -615,7 +615,7 @@ namespace garlic
|
||||||
it = m_Tags.erase (it);
|
it = m_Tags.erase (it);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
if (numExpiredTags > 0)
|
if (numExpiredTags > 0)
|
||||||
LogPrint (eLogDebug, "Garlic: ", numExpiredTags, " tags expired for ", GetIdentHash().ToBase64 ());
|
LogPrint (eLogDebug, "Garlic: ", numExpiredTags, " tags expired for ", GetIdentHash().ToBase64 ());
|
||||||
|
@ -631,7 +631,7 @@ namespace garlic
|
||||||
it = m_Sessions.erase (it);
|
it = m_Sessions.erase (it);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -662,7 +662,7 @@ namespace garlic
|
||||||
void GarlicDestination::SetLeaseSetUpdated ()
|
void GarlicDestination::SetLeaseSetUpdated ()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_SessionsMutex);
|
std::unique_lock<std::mutex> l(m_SessionsMutex);
|
||||||
for (auto it: m_Sessions)
|
for (auto& it: m_Sessions)
|
||||||
it.second->SetLeaseSetUpdated ();
|
it.second->SetLeaseSetUpdated ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
HTTP.cpp
2
HTTP.cpp
|
@ -160,7 +160,7 @@ namespace http {
|
||||||
strsplit(query, tokens, '&');
|
strsplit(query, tokens, '&');
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
for (auto it : tokens) {
|
for (const auto& it : tokens) {
|
||||||
std::size_t eq = it.find ('=');
|
std::size_t eq = it.find ('=');
|
||||||
if (eq != std::string::npos) {
|
if (eq != std::string::npos) {
|
||||||
auto e = std::pair<std::string, std::string>(it.substr(0, eq), it.substr(eq + 1));
|
auto e = std::pair<std::string, std::string>(it.substr(0, eq), it.substr(eq + 1));
|
||||||
|
|
|
@ -113,7 +113,7 @@ namespace proxy {
|
||||||
<< "<p>Remote host not found in router's addressbook</p>\r\n"
|
<< "<p>Remote host not found in router's addressbook</p>\r\n"
|
||||||
<< "<p>You may try to find this host on jumpservices below:</p>\r\n"
|
<< "<p>You may try to find this host on jumpservices below:</p>\r\n"
|
||||||
<< "<ul>\r\n";
|
<< "<ul>\r\n";
|
||||||
for (auto & js : jumpservices) {
|
for (const auto& js : jumpservices) {
|
||||||
ss << " <li><a href=\"" << js.second << host << "\">" << js.first << "</a></li>\r\n";
|
ss << " <li><a href=\"" << js.second << host << "\">" << js.first << "</a></li>\r\n";
|
||||||
}
|
}
|
||||||
ss << "</ul>\r\n";
|
ss << "</ul>\r\n";
|
||||||
|
@ -164,7 +164,7 @@ namespace proxy {
|
||||||
req.del_header("Forwarded");
|
req.del_header("Forwarded");
|
||||||
/* drop proxy-disclosing headers */
|
/* drop proxy-disclosing headers */
|
||||||
std::vector<std::string> toErase;
|
std::vector<std::string> toErase;
|
||||||
for (auto it : req.headers) {
|
for (const auto& it : req.headers) {
|
||||||
if (it.first.compare(0, 12, "X-Forwarded-") == 0) {
|
if (it.first.compare(0, 12, "X-Forwarded-") == 0) {
|
||||||
toErase.push_back(it.first);
|
toErase.push_back(it.first);
|
||||||
} else if (it.first.compare(0, 6, "Proxy-") == 0) {
|
} else if (it.first.compare(0, 6, "Proxy-") == 0) {
|
||||||
|
@ -173,7 +173,7 @@ namespace proxy {
|
||||||
/* allow */
|
/* allow */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto header : toErase) {
|
for (const auto& header : toErase) {
|
||||||
req.headers.erase(header);
|
req.headers.erase(header);
|
||||||
}
|
}
|
||||||
/* replace headers */
|
/* replace headers */
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
#include "HTTPServer.h"
|
#include "HTTPServer.h"
|
||||||
#include "Daemon.h"
|
#include "Daemon.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#ifdef WIN32_APP
|
||||||
|
#include "Win32/Win32App.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// For image and info
|
// For image and info
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
@ -141,12 +144,14 @@ namespace http {
|
||||||
" <a href=\"/\">Main page</a><br>\r\n<br>\r\n"
|
" <a href=\"/\">Main page</a><br>\r\n<br>\r\n"
|
||||||
" <a href=\"/?page=" << HTTP_PAGE_COMMANDS << "\">Router commands</a><br>\r\n"
|
" <a href=\"/?page=" << HTTP_PAGE_COMMANDS << "\">Router commands</a><br>\r\n"
|
||||||
" <a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATIONS << "\">Local destinations</a><br>\r\n"
|
" <a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATIONS << "\">Local destinations</a><br>\r\n"
|
||||||
" <a href=\"/?page=" << HTTP_PAGE_LEASESETS << "\">Lease Sets</a><br>\r\n"
|
" <a href=\"/?page=" << HTTP_PAGE_LEASESETS << "\">LeaseSets</a><br>\r\n"
|
||||||
" <a href=\"/?page=" << HTTP_PAGE_TUNNELS << "\">Tunnels</a><br>\r\n"
|
" <a href=\"/?page=" << HTTP_PAGE_TUNNELS << "\">Tunnels</a><br>\r\n"
|
||||||
" <a href=\"/?page=" << HTTP_PAGE_TRANSIT_TUNNELS << "\">Transit tunnels</a><br>\r\n"
|
" <a href=\"/?page=" << HTTP_PAGE_TRANSIT_TUNNELS << "\">Transit tunnels</a><br>\r\n"
|
||||||
" <a href=\"/?page=" << HTTP_PAGE_TRANSPORTS << "\">Transports</a><br>\r\n"
|
" <a href=\"/?page=" << HTTP_PAGE_TRANSPORTS << "\">Transports</a><br>\r\n"
|
||||||
" <a href=\"/?page=" << HTTP_PAGE_I2P_TUNNELS << "\">I2P tunnels</a><br>\r\n"
|
" <a href=\"/?page=" << HTTP_PAGE_I2P_TUNNELS << "\">I2P tunnels</a><br>\r\n";
|
||||||
" <a href=\"/?page=" << HTTP_PAGE_SAM_SESSIONS << "\">SAM sessions</a><br>\r\n"
|
if (i2p::client::context.GetSAMBridge ())
|
||||||
|
s << " <a href=\"/?page=" << HTTP_PAGE_SAM_SESSIONS << "\">SAM sessions</a><br>\r\n";
|
||||||
|
s <<
|
||||||
"</div>\r\n"
|
"</div>\r\n"
|
||||||
"<div class=right>";
|
"<div class=right>";
|
||||||
}
|
}
|
||||||
|
@ -207,7 +212,7 @@ namespace http {
|
||||||
s << "<b>Router Family:</b> " << i2p::context.GetRouterInfo().GetProperty("family") << "<br>\r\n";
|
s << "<b>Router Family:</b> " << i2p::context.GetRouterInfo().GetProperty("family") << "<br>\r\n";
|
||||||
s << "<b>Router Caps:</b> " << i2p::context.GetRouterInfo().GetProperty("caps") << "<br>\r\n";
|
s << "<b>Router Caps:</b> " << i2p::context.GetRouterInfo().GetProperty("caps") << "<br>\r\n";
|
||||||
s << "<b>Our external address:</b>" << "<br>\r\n" ;
|
s << "<b>Our external address:</b>" << "<br>\r\n" ;
|
||||||
for (auto address : i2p::context.GetRouterInfo().GetAddresses())
|
for (const auto& address : i2p::context.GetRouterInfo().GetAddresses())
|
||||||
{
|
{
|
||||||
switch (address->transportStyle)
|
switch (address->transportStyle)
|
||||||
{
|
{
|
||||||
|
@ -280,7 +285,7 @@ namespace http {
|
||||||
}
|
}
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
s << "<b>Tags</b><br>Incoming: " << dest->GetNumIncomingTags () << "<br>Outgoing:<br>" << std::endl;
|
s << "<b>Tags</b><br>Incoming: " << dest->GetNumIncomingTags () << "<br>Outgoing:<br>" << std::endl;
|
||||||
for (auto it: dest->GetSessions ())
|
for (const auto& it: dest->GetSessions ())
|
||||||
{
|
{
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(it.first) << " ";
|
s << i2p::client::context.GetAddressBook ().ToAddress(it.first) << " ";
|
||||||
s << it.second->GetNumOutgoingTags () << "<br>" << std::endl;
|
s << it.second->GetNumOutgoingTags () << "<br>" << std::endl;
|
||||||
|
@ -311,7 +316,7 @@ namespace http {
|
||||||
s << "<th>Status</th>";
|
s << "<th>Status</th>";
|
||||||
s << "</tr>";
|
s << "</tr>";
|
||||||
|
|
||||||
for (auto it: dest->GetAllStreams ())
|
for (const auto& it: dest->GetAllStreams ())
|
||||||
{
|
{
|
||||||
s << "<tr>";
|
s << "<tr>";
|
||||||
s << "<td>" << it->GetSendStreamID () << "</td>";
|
s << "<td>" << it->GetSendStreamID () << "</td>";
|
||||||
|
@ -331,7 +336,7 @@ namespace http {
|
||||||
|
|
||||||
void ShowLeasesSets(std::stringstream& s)
|
void ShowLeasesSets(std::stringstream& s)
|
||||||
{
|
{
|
||||||
s << "<div id='leasesets'>LeaseSets</div><br>";
|
s << "<div id='leasesets'><b>LeaseSets:</b></div><br>";
|
||||||
// for each lease set
|
// for each lease set
|
||||||
i2p::data::netdb.VisitLeaseSets(
|
i2p::data::netdb.VisitLeaseSets(
|
||||||
[&s](const i2p::data::IdentHash dest, std::shared_ptr<i2p::data::LeaseSet> leaseSet)
|
[&s](const i2p::data::IdentHash dest, std::shared_ptr<i2p::data::LeaseSet> leaseSet)
|
||||||
|
@ -409,28 +414,34 @@ namespace http {
|
||||||
else
|
else
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_ENABLE_TRANSIT << "\">Accept transit tunnels</a><br>\r\n";
|
s << " <a href=\"/?cmd=" << HTTP_COMMAND_ENABLE_TRANSIT << "\">Accept transit tunnels</a><br>\r\n";
|
||||||
#if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID))
|
#if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID))
|
||||||
if (Daemon.gracefullShutdownInterval) {
|
if (Daemon.gracefullShutdownInterval)
|
||||||
|
{
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "\">Cancel gracefull shutdown (";
|
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "\">Cancel gracefull shutdown (";
|
||||||
s << Daemon.gracefullShutdownInterval;
|
s << Daemon.gracefullShutdownInterval;
|
||||||
s << " seconds remains)</a><br>\r\n";
|
s << " seconds remains)</a><br>\r\n";
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "\">Start gracefull shutdown</a><br>\r\n";
|
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "\">Start gracefull shutdown</a><br>\r\n";
|
||||||
}
|
}
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "\">Force shutdown</a><br>\r\n";
|
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WIN32_APP
|
||||||
|
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "\">Gracefull shutdown</a><br>\r\n";
|
||||||
|
#endif
|
||||||
|
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "\">Force shutdown</a><br>\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowTransitTunnels (std::stringstream& s)
|
void ShowTransitTunnels (std::stringstream& s)
|
||||||
{
|
{
|
||||||
s << "<b>Transit tunnels:</b><br>\r\n<br>\r\n";
|
s << "<b>Transit tunnels:</b><br>\r\n<br>\r\n";
|
||||||
for (auto it: i2p::tunnel::tunnels.GetTransitTunnels ())
|
for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ())
|
||||||
{
|
{
|
||||||
if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelGateway>(it))
|
if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelGateway>(it))
|
||||||
s << it->GetTunnelID () << " ⇒ ";
|
s << it->GetTunnelID () << " ⇒ ";
|
||||||
else if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelEndpoint>(it))
|
else if (std::dynamic_pointer_cast<i2p::tunnel::TransitTunnelEndpoint>(it))
|
||||||
s << " ⇒ " << it->GetTunnelID ();
|
s << " ⇒ " << it->GetTunnelID ();
|
||||||
else
|
else
|
||||||
s << " ⇒ " << it->GetTunnelID () << " ⇒ ";
|
s << " ⇒ " << it->GetTunnelID () << " ⇒ ";
|
||||||
s << " " << it->GetNumTransmittedBytes () << "<br>\r\n";
|
s << " " << it->GetNumTransmittedBytes () << "<br>\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -442,15 +453,15 @@ namespace http {
|
||||||
if (ntcpServer)
|
if (ntcpServer)
|
||||||
{
|
{
|
||||||
s << "<b>NTCP</b><br>\r\n";
|
s << "<b>NTCP</b><br>\r\n";
|
||||||
for (auto it: ntcpServer->GetNTCPSessions ())
|
for (const auto& it: ntcpServer->GetNTCPSessions ())
|
||||||
{
|
{
|
||||||
if (it.second && it.second->IsEstablished ())
|
if (it.second && it.second->IsEstablished ())
|
||||||
{
|
{
|
||||||
// incoming connection doesn't have remote RI
|
// incoming connection doesn't have remote RI
|
||||||
if (it.second->IsOutgoing ()) s << " ⇒ ";
|
if (it.second->IsOutgoing ()) s << " ⇒ ";
|
||||||
s << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": "
|
s << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": "
|
||||||
<< it.second->GetSocket ().remote_endpoint().address ().to_string ();
|
<< it.second->GetSocket ().remote_endpoint().address ().to_string ();
|
||||||
if (!it.second->IsOutgoing ()) s << " ⇒ ";
|
if (!it.second->IsOutgoing ()) s << " ⇒ ";
|
||||||
s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
||||||
s << "<br>\r\n" << std::endl;
|
s << "<br>\r\n" << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -460,24 +471,24 @@ namespace http {
|
||||||
if (ssuServer)
|
if (ssuServer)
|
||||||
{
|
{
|
||||||
s << "<br>\r\n<b>SSU</b><br>\r\n";
|
s << "<br>\r\n<b>SSU</b><br>\r\n";
|
||||||
for (auto it: ssuServer->GetSessions ())
|
for (const auto& it: ssuServer->GetSessions ())
|
||||||
{
|
{
|
||||||
auto endpoint = it.second->GetRemoteEndpoint ();
|
auto endpoint = it.second->GetRemoteEndpoint ();
|
||||||
if (it.second->IsOutgoing ()) s << " ⇒ ";
|
if (it.second->IsOutgoing ()) s << " ⇒ ";
|
||||||
s << endpoint.address ().to_string () << ":" << endpoint.port ();
|
s << endpoint.address ().to_string () << ":" << endpoint.port ();
|
||||||
if (!it.second->IsOutgoing ()) s << " ⇒ ";
|
if (!it.second->IsOutgoing ()) s << " ⇒ ";
|
||||||
s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
||||||
if (it.second->GetRelayTag ())
|
if (it.second->GetRelayTag ())
|
||||||
s << " [itag:" << it.second->GetRelayTag () << "]";
|
s << " [itag:" << it.second->GetRelayTag () << "]";
|
||||||
s << "<br>\r\n" << std::endl;
|
s << "<br>\r\n" << std::endl;
|
||||||
}
|
}
|
||||||
s << "<br>\r\n<b>SSU6</b><br>\r\n";
|
s << "<br>\r\n<b>SSU6</b><br>\r\n";
|
||||||
for (auto it: ssuServer->GetSessionsV6 ())
|
for (const auto& it: ssuServer->GetSessionsV6 ())
|
||||||
{
|
{
|
||||||
auto endpoint = it.second->GetRemoteEndpoint ();
|
auto endpoint = it.second->GetRemoteEndpoint ();
|
||||||
if (it.second->IsOutgoing ()) s << " ⇒ ";
|
if (it.second->IsOutgoing ()) s << " ⇒ ";
|
||||||
s << endpoint.address ().to_string () << ":" << endpoint.port ();
|
s << endpoint.address ().to_string () << ":" << endpoint.port ();
|
||||||
if (!it.second->IsOutgoing ()) s << " ⇒ ";
|
if (!it.second->IsOutgoing ()) s << " ⇒ ";
|
||||||
s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]";
|
||||||
s << "<br>\r\n" << std::endl;
|
s << "<br>\r\n" << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -517,7 +528,7 @@ namespace http {
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n";
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n";
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
s << "<b>Streams:</b><br>\r\n";
|
s << "<b>Streams:</b><br>\r\n";
|
||||||
for (auto it: session->ListSockets())
|
for (const auto& it: session->ListSockets())
|
||||||
{
|
{
|
||||||
switch (it->GetSocketType ())
|
switch (it->GetSocketType ())
|
||||||
{
|
{
|
||||||
|
@ -538,7 +549,7 @@ namespace http {
|
||||||
{
|
{
|
||||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << it.second->GetName () << "</a> ⇐ ";
|
s << it.second->GetName () << "</a> ⇐ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << "<br>\r\n"<< std::endl;
|
s << "<br>\r\n"<< std::endl;
|
||||||
}
|
}
|
||||||
|
@ -547,7 +558,7 @@ namespace http {
|
||||||
{
|
{
|
||||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << it.second->GetName () << "</a> ⇒ ";
|
s << it.second->GetName () << "</a> ⇒ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << ":" << it.second->GetLocalPort ();
|
s << ":" << it.second->GetLocalPort ();
|
||||||
s << "</a><br>\r\n"<< std::endl;
|
s << "</a><br>\r\n"<< std::endl;
|
||||||
|
@ -723,6 +734,9 @@ namespace http {
|
||||||
i2p::context.SetAcceptsTunnels (false);
|
i2p::context.SetAcceptsTunnels (false);
|
||||||
#if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID))
|
#if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID))
|
||||||
Daemon.gracefullShutdownInterval = 10*60;
|
Daemon.gracefullShutdownInterval = 10*60;
|
||||||
|
#endif
|
||||||
|
#ifdef WIN32_APP
|
||||||
|
i2p::win32::GracefulShutdown ();
|
||||||
#endif
|
#endif
|
||||||
} else if (cmd == HTTP_COMMAND_SHUTDOWN_CANCEL) {
|
} else if (cmd == HTTP_COMMAND_SHUTDOWN_CANCEL) {
|
||||||
i2p::context.SetAcceptsTunnels (true);
|
i2p::context.SetAcceptsTunnels (true);
|
||||||
|
@ -770,12 +784,14 @@ namespace http {
|
||||||
std::string pass; i2p::config::GetOption("http.pass", pass);
|
std::string pass; i2p::config::GetOption("http.pass", pass);
|
||||||
/* generate pass if needed */
|
/* generate pass if needed */
|
||||||
if (needAuth && pass == "") {
|
if (needAuth && pass == "") {
|
||||||
|
uint8_t random[16];
|
||||||
char alnum[] = "0123456789"
|
char alnum[] = "0123456789"
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
"abcdefghijklmnopqrstuvwxyz";
|
"abcdefghijklmnopqrstuvwxyz";
|
||||||
pass.resize(16);
|
pass.resize(sizeof(random));
|
||||||
for (size_t i = 0; i < pass.size(); i++) {
|
RAND_bytes(random, sizeof(random));
|
||||||
pass[i] = alnum[rand() % (sizeof(alnum) - 1)];
|
for (size_t i = 0; i < sizeof(random); i++) {
|
||||||
|
pass[i] = alnum[random[i] % (sizeof(alnum) - 1)];
|
||||||
}
|
}
|
||||||
i2p::config::SetOption("http.pass", pass);
|
i2p::config::SetOption("http.pass", pass);
|
||||||
LogPrint(eLogInfo, "HTTPServer: password set to ", pass);
|
LogPrint(eLogInfo, "HTTPServer: password set to ", pass);
|
||||||
|
|
2
I2CP.cpp
2
I2CP.cpp
|
@ -659,7 +659,7 @@ namespace client
|
||||||
{
|
{
|
||||||
m_IsRunning = false;
|
m_IsRunning = false;
|
||||||
m_Acceptor.cancel ();
|
m_Acceptor.cancel ();
|
||||||
for (auto it: m_Sessions)
|
for (auto& it: m_Sessions)
|
||||||
it.second->Stop ();
|
it.second->Stop ();
|
||||||
m_Sessions.clear ();
|
m_Sessions.clear ();
|
||||||
m_Service.stop ();
|
m_Service.stop ();
|
||||||
|
|
|
@ -202,7 +202,7 @@ namespace i2p
|
||||||
len += 32;
|
len += 32;
|
||||||
buf[len] = routers.size ();
|
buf[len] = routers.size ();
|
||||||
len++;
|
len++;
|
||||||
for (auto it: routers)
|
for (const auto& it: routers)
|
||||||
{
|
{
|
||||||
memcpy (buf + len, it, 32);
|
memcpy (buf + len, it, 32);
|
||||||
len += 32;
|
len += 32;
|
||||||
|
|
|
@ -358,7 +358,7 @@ namespace client
|
||||||
|
|
||||||
void I2PControlService::RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
void I2PControlService::RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
||||||
{
|
{
|
||||||
for (auto it = params.begin (); it != params.end (); it++)
|
for (auto it = params.begin (); it != params.end (); ++it)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "I2PControl: RouterInfo request: ", it->first);
|
LogPrint (eLogDebug, "I2PControl: RouterInfo request: ", it->first);
|
||||||
auto it1 = m_RouterInfoHandlers.find (it->first);
|
auto it1 = m_RouterInfoHandlers.find (it->first);
|
||||||
|
@ -434,7 +434,7 @@ namespace client
|
||||||
|
|
||||||
void I2PControlService::RouterManagerHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
void I2PControlService::RouterManagerHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
||||||
{
|
{
|
||||||
for (auto it = params.begin (); it != params.end (); it++)
|
for (auto it = params.begin (); it != params.end (); ++it)
|
||||||
{
|
{
|
||||||
if (it != params.begin ()) results << ",";
|
if (it != params.begin ()) results << ",";
|
||||||
LogPrint (eLogDebug, "I2PControl: RouterManager request: ", it->first);
|
LogPrint (eLogDebug, "I2PControl: RouterManager request: ", it->first);
|
||||||
|
@ -483,7 +483,7 @@ namespace client
|
||||||
// network setting
|
// network setting
|
||||||
void I2PControlService::NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
void I2PControlService::NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
|
||||||
{
|
{
|
||||||
for (auto it = params.begin (); it != params.end (); it++)
|
for (auto it = params.begin (); it != params.end (); ++it)
|
||||||
{
|
{
|
||||||
if (it != params.begin ()) results << ",";
|
if (it != params.begin ()) results << ",";
|
||||||
LogPrint (eLogDebug, "I2PControl: NetworkSetting request: ", it->first);
|
LogPrint (eLogDebug, "I2PControl: NetworkSetting request: ", it->first);
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace data
|
||||||
|
|
||||||
// reset existing leases
|
// reset existing leases
|
||||||
if (m_StoreLeases)
|
if (m_StoreLeases)
|
||||||
for (auto it: m_Leases)
|
for (auto& it: m_Leases)
|
||||||
it->isUpdated = false;
|
it->isUpdated = false;
|
||||||
else
|
else
|
||||||
m_Leases.clear ();
|
m_Leases.clear ();
|
||||||
|
@ -123,7 +123,7 @@ namespace data
|
||||||
m_Leases.erase (it++);
|
m_Leases.erase (it++);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ namespace data
|
||||||
{
|
{
|
||||||
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
std::vector<std::shared_ptr<const Lease> > leases;
|
std::vector<std::shared_ptr<const Lease> > leases;
|
||||||
for (auto it: m_Leases)
|
for (const auto& it: m_Leases)
|
||||||
{
|
{
|
||||||
auto endDate = it->endDate;
|
auto endDate = it->endDate;
|
||||||
if (withThreshold)
|
if (withThreshold)
|
||||||
|
@ -183,7 +183,7 @@ namespace data
|
||||||
bool LeaseSet::HasExpiredLeases () const
|
bool LeaseSet::HasExpiredLeases () const
|
||||||
{
|
{
|
||||||
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
for (auto it: m_Leases)
|
for (const auto& it: m_Leases)
|
||||||
if (ts >= it->endDate) return true;
|
if (ts >= it->endDate) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ ifeq ($(USE_WIN32_APP), yes)
|
||||||
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
|
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_AESNI),yes)
|
ifeq ($(USE_AESNI),1)
|
||||||
CPU_FLAGS = -maes -DAESNI
|
CPU_FLAGS = -maes -DAESNI
|
||||||
else
|
else
|
||||||
CPU_FLAGS = -msse
|
CPU_FLAGS = -msse
|
||||||
|
|
|
@ -19,7 +19,8 @@ namespace i2p
|
||||||
namespace transport
|
namespace transport
|
||||||
{
|
{
|
||||||
NTCPSession::NTCPSession (NTCPServer& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter):
|
NTCPSession::NTCPSession (NTCPServer& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter):
|
||||||
TransportSession (in_RemoteRouter), m_Server (server), m_Socket (m_Server.GetService ()),
|
TransportSession (in_RemoteRouter, NTCP_TERMINATION_TIMEOUT),
|
||||||
|
m_Server (server), m_Socket (m_Server.GetService ()),
|
||||||
m_TerminationTimer (m_Server.GetService ()), m_IsEstablished (false), m_IsTerminated (false),
|
m_TerminationTimer (m_Server.GetService ()), m_IsEstablished (false), m_IsTerminated (false),
|
||||||
m_ReceiveBufferOffset (0), m_NextMessage (nullptr), m_IsSending (false)
|
m_ReceiveBufferOffset (0), m_NextMessage (nullptr), m_IsSending (false)
|
||||||
{
|
{
|
||||||
|
@ -665,7 +666,7 @@ namespace transport
|
||||||
{
|
{
|
||||||
m_IsSending = true;
|
m_IsSending = true;
|
||||||
std::vector<boost::asio::const_buffer> bufs;
|
std::vector<boost::asio::const_buffer> bufs;
|
||||||
for (auto it: msgs)
|
for (const auto& it: msgs)
|
||||||
bufs.push_back (CreateMsgBuffer (it));
|
bufs.push_back (CreateMsgBuffer (it));
|
||||||
boost::asio::async_write (m_Socket, bufs, boost::asio::transfer_all (),
|
boost::asio::async_write (m_Socket, bufs, boost::asio::transfer_all (),
|
||||||
std::bind(&NTCPSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, msgs));
|
std::bind(&NTCPSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, msgs));
|
||||||
|
@ -715,7 +716,7 @@ namespace transport
|
||||||
{
|
{
|
||||||
if (m_SendQueue.size () < NTCP_MAX_OUTGOING_QUEUE_SIZE)
|
if (m_SendQueue.size () < NTCP_MAX_OUTGOING_QUEUE_SIZE)
|
||||||
{
|
{
|
||||||
for (auto it: msgs)
|
for (const auto& it: msgs)
|
||||||
m_SendQueue.push_back (it);
|
m_SendQueue.push_back (it);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -731,7 +732,7 @@ namespace transport
|
||||||
void NTCPSession::ScheduleTermination ()
|
void NTCPSession::ScheduleTermination ()
|
||||||
{
|
{
|
||||||
m_TerminationTimer.cancel ();
|
m_TerminationTimer.cancel ();
|
||||||
m_TerminationTimer.expires_from_now (boost::posix_time::seconds(NTCP_TERMINATION_TIMEOUT));
|
m_TerminationTimer.expires_from_now (boost::posix_time::seconds(GetTerminationTimeout ()));
|
||||||
m_TerminationTimer.async_wait (std::bind (&NTCPSession::HandleTerminationTimer,
|
m_TerminationTimer.async_wait (std::bind (&NTCPSession::HandleTerminationTimer,
|
||||||
shared_from_this (), std::placeholders::_1));
|
shared_from_this (), std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
@ -740,7 +741,7 @@ namespace transport
|
||||||
{
|
{
|
||||||
if (ecode != boost::asio::error::operation_aborted)
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "NTCP: No activity for ", NTCP_TERMINATION_TIMEOUT, " seconds");
|
LogPrint (eLogDebug, "NTCP: No activity for ", GetTerminationTimeout (), " seconds");
|
||||||
//Terminate ();
|
//Terminate ();
|
||||||
m_Socket.close ();// invoke Terminate () from HandleReceive
|
m_Socket.close ();// invoke Terminate () from HandleReceive
|
||||||
}
|
}
|
||||||
|
@ -766,7 +767,7 @@ namespace transport
|
||||||
m_Thread = new std::thread (std::bind (&NTCPServer::Run, this));
|
m_Thread = new std::thread (std::bind (&NTCPServer::Run, this));
|
||||||
// create acceptors
|
// create acceptors
|
||||||
auto& addresses = context.GetRouterInfo ().GetAddresses ();
|
auto& addresses = context.GetRouterInfo ().GetAddresses ();
|
||||||
for (auto address: addresses)
|
for (const auto& address: addresses)
|
||||||
{
|
{
|
||||||
if (address->transportStyle == i2p::data::RouterInfo::eTransportNTCP)
|
if (address->transportStyle == i2p::data::RouterInfo::eTransportNTCP)
|
||||||
{
|
{
|
||||||
|
|
35
NetDb.cpp
35
NetDb.cpp
|
@ -14,7 +14,6 @@
|
||||||
#include "RouterContext.h"
|
#include "RouterContext.h"
|
||||||
#include "Garlic.h"
|
#include "Garlic.h"
|
||||||
#include "NetDb.h"
|
#include "NetDb.h"
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
using namespace i2p::transport;
|
using namespace i2p::transport;
|
||||||
|
|
||||||
|
@ -52,7 +51,7 @@ namespace data
|
||||||
{
|
{
|
||||||
if (m_IsRunning)
|
if (m_IsRunning)
|
||||||
{
|
{
|
||||||
for (auto it: m_RouterInfos)
|
for (auto& it: m_RouterInfos)
|
||||||
it.second->SaveProfile ();
|
it.second->SaveProfile ();
|
||||||
DeleteObsoleteProfiles ();
|
DeleteObsoleteProfiles ();
|
||||||
m_RouterInfos.clear ();
|
m_RouterInfos.clear ();
|
||||||
|
@ -72,7 +71,7 @@ namespace data
|
||||||
|
|
||||||
void NetDb::Run ()
|
void NetDb::Run ()
|
||||||
{
|
{
|
||||||
uint32_t lastSave = 0, lastPublish = 0, lastExploratory = 0, lastManageRequest = 0;
|
uint32_t lastSave = 0, lastPublish = 0, lastExploratory = 0, lastManageRequest = 0, lastDestinationCleanup = 0;
|
||||||
while (m_IsRunning)
|
while (m_IsRunning)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -122,7 +121,11 @@ namespace data
|
||||||
}
|
}
|
||||||
lastSave = ts;
|
lastSave = ts;
|
||||||
}
|
}
|
||||||
|
if (ts - lastDestinationCleanup >= i2p::garlic::INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
||||||
|
{
|
||||||
|
i2p::context.CleanupDestination ();
|
||||||
|
lastDestinationCleanup = ts;
|
||||||
|
}
|
||||||
// if we're in hidden mode don't publish or explore
|
// if we're in hidden mode don't publish or explore
|
||||||
// if (m_HiddenMode) continue;
|
// if (m_HiddenMode) continue;
|
||||||
|
|
||||||
|
@ -336,7 +339,7 @@ namespace data
|
||||||
m_LastLoad = i2p::util::GetSecondsSinceEpoch();
|
m_LastLoad = i2p::util::GetSecondsSinceEpoch();
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
m_Storage.Traverse(files);
|
m_Storage.Traverse(files);
|
||||||
for (auto path : files)
|
for (const auto& path : files)
|
||||||
LoadRouterInfo(path);
|
LoadRouterInfo(path);
|
||||||
|
|
||||||
LogPrint (eLogInfo, "NetDb: ", m_RouterInfos.size(), " routers loaded (", m_Floodfills.size (), " floodfils)");
|
LogPrint (eLogInfo, "NetDb: ", m_RouterInfos.size(), " routers loaded (", m_Floodfills.size (), " floodfils)");
|
||||||
|
@ -354,7 +357,7 @@ namespace data
|
||||||
expirationTimeout = i2p::context.IsFloodfill () ? NETDB_FLOODFILL_EXPIRATION_TIMEOUT*1000LL :
|
expirationTimeout = i2p::context.IsFloodfill () ? NETDB_FLOODFILL_EXPIRATION_TIMEOUT*1000LL :
|
||||||
NETDB_MIN_EXPIRATION_TIMEOUT*1000LL + (NETDB_MAX_EXPIRATION_TIMEOUT - NETDB_MIN_EXPIRATION_TIMEOUT)*1000LL*NETDB_MIN_ROUTERS/total;
|
NETDB_MIN_EXPIRATION_TIMEOUT*1000LL + (NETDB_MAX_EXPIRATION_TIMEOUT - NETDB_MIN_EXPIRATION_TIMEOUT)*1000LL*NETDB_MIN_ROUTERS/total;
|
||||||
|
|
||||||
for (auto it: m_RouterInfos)
|
for (auto& it: m_RouterInfos)
|
||||||
{
|
{
|
||||||
std::string ident = it.second->GetIdentHashBase64();
|
std::string ident = it.second->GetIdentHashBase64();
|
||||||
std::string path = m_Storage.Path(ident);
|
std::string path = m_Storage.Path(ident);
|
||||||
|
@ -402,7 +405,7 @@ namespace data
|
||||||
it = m_RouterInfos.erase (it);
|
it = m_RouterInfos.erase (it);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// clean up expired floodfiils
|
// clean up expired floodfiils
|
||||||
|
@ -412,7 +415,7 @@ namespace data
|
||||||
if ((*it)->IsUnreachable ())
|
if ((*it)->IsUnreachable ())
|
||||||
it = m_Floodfills.erase (it);
|
it = m_Floodfills.erase (it);
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -898,7 +901,7 @@ namespace data
|
||||||
{
|
{
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
std::unique_lock<std::mutex> l(m_RouterInfosMutex);
|
std::unique_lock<std::mutex> l(m_RouterInfosMutex);
|
||||||
for (auto it: m_RouterInfos)
|
for (const auto& it: m_RouterInfos)
|
||||||
{
|
{
|
||||||
if (i >= ind)
|
if (i >= ind)
|
||||||
{
|
{
|
||||||
|
@ -930,7 +933,7 @@ namespace data
|
||||||
else
|
else
|
||||||
minMetric.SetMax ();
|
minMetric.SetMax ();
|
||||||
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
||||||
for (auto it: m_Floodfills)
|
for (const auto& it: m_Floodfills)
|
||||||
{
|
{
|
||||||
if (!it->IsUnreachable ())
|
if (!it->IsUnreachable ())
|
||||||
{
|
{
|
||||||
|
@ -961,7 +964,7 @@ namespace data
|
||||||
if (closeThanUsOnly) ourMetric = destKey ^ i2p::context.GetIdentHash ();
|
if (closeThanUsOnly) ourMetric = destKey ^ i2p::context.GetIdentHash ();
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
||||||
for (auto it: m_Floodfills)
|
for (const auto& it: m_Floodfills)
|
||||||
{
|
{
|
||||||
if (!it->IsUnreachable ())
|
if (!it->IsUnreachable ())
|
||||||
{
|
{
|
||||||
|
@ -980,11 +983,11 @@ namespace data
|
||||||
|
|
||||||
std::vector<IdentHash> res;
|
std::vector<IdentHash> res;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (auto it: sorted)
|
for (const auto& it: sorted)
|
||||||
{
|
{
|
||||||
if (i < num)
|
if (i < num)
|
||||||
{
|
{
|
||||||
auto& ident = it.r->GetIdentHash ();
|
const auto& ident = it.r->GetIdentHash ();
|
||||||
if (!excluded.count (ident))
|
if (!excluded.count (ident))
|
||||||
{
|
{
|
||||||
res.push_back (ident);
|
res.push_back (ident);
|
||||||
|
@ -1013,7 +1016,7 @@ namespace data
|
||||||
IdentHash destKey = CreateRoutingKey (destination);
|
IdentHash destKey = CreateRoutingKey (destination);
|
||||||
minMetric.SetMax ();
|
minMetric.SetMax ();
|
||||||
// must be called from NetDb thread only
|
// must be called from NetDb thread only
|
||||||
for (auto it: m_RouterInfos)
|
for (const auto& it: m_RouterInfos)
|
||||||
{
|
{
|
||||||
if (!it.second->IsFloodfill ())
|
if (!it.second->IsFloodfill ())
|
||||||
{
|
{
|
||||||
|
@ -1039,7 +1042,7 @@ namespace data
|
||||||
it = m_LeaseSets.erase (it);
|
it = m_LeaseSets.erase (it);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1051,7 +1054,7 @@ namespace data
|
||||||
if (ts > it->second.second + 180) // 3 minutes
|
if (ts > it->second.second + 180) // 3 minutes
|
||||||
it = m_LookupResponses.erase (it);
|
it = m_LookupResponses.erase (it);
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ namespace data
|
||||||
if (done)
|
if (done)
|
||||||
it = m_RequestedDestinations.erase (it);
|
it = m_RequestedDestinations.erase (it);
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,7 +167,7 @@ namespace data
|
||||||
|
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
m_ProfilesStorage.Traverse(files);
|
m_ProfilesStorage.Traverse(files);
|
||||||
for (auto path: files) {
|
for (const auto& path: files) {
|
||||||
if (stat(path.c_str(), &st) != 0) {
|
if (stat(path.c_str(), &st) != 0) {
|
||||||
LogPrint(eLogWarning, "Profiling: Can't stat(): ", path);
|
LogPrint(eLogWarning, "Profiling: Can't stat(): ", path);
|
||||||
continue;
|
continue;
|
||||||
|
|
5
Queue.h
5
Queue.h
|
@ -7,6 +7,7 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
|
@ -20,7 +21,7 @@ namespace util
|
||||||
void Put (Element e)
|
void Put (Element e)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_QueueMutex);
|
std::unique_lock<std::mutex> l(m_QueueMutex);
|
||||||
m_Queue.push (e);
|
m_Queue.push (std::move(e));
|
||||||
m_NonEmpty.notify_one ();
|
m_NonEmpty.notify_one ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +30,7 @@ namespace util
|
||||||
if (!vec.empty ())
|
if (!vec.empty ())
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_QueueMutex);
|
std::unique_lock<std::mutex> l(m_QueueMutex);
|
||||||
for (auto it: vec)
|
for (const auto& it: vec)
|
||||||
m_Queue.push (it);
|
m_Queue.push (it);
|
||||||
m_NonEmpty.notify_one ();
|
m_NonEmpty.notify_one ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "NetDb.h"
|
#include "NetDb.h"
|
||||||
#include "HTTP.h"
|
#include "HTTP.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
|
@ -51,6 +52,13 @@ namespace data
|
||||||
|
|
||||||
int Reseeder::ReseedNowSU3 ()
|
int Reseeder::ReseedNowSU3 ()
|
||||||
{
|
{
|
||||||
|
std::string filename; i2p::config::GetOption("reseed.file", filename);
|
||||||
|
if (filename.length() > 0) // reseed file is specified
|
||||||
|
{
|
||||||
|
auto num = ProcessSU3File (filename.c_str ());
|
||||||
|
if (num > 0) return num; // success
|
||||||
|
LogPrint (eLogWarning, "Can't reseed from ", filename, " . Trying from hosts");
|
||||||
|
}
|
||||||
auto ind = rand () % httpsReseedHostList.size ();
|
auto ind = rand () % httpsReseedHostList.size ();
|
||||||
std::string& reseedHost = httpsReseedHostList[ind];
|
std::string& reseedHost = httpsReseedHostList[ind];
|
||||||
return ReseedFromSU3 (reseedHost);
|
return ReseedFromSU3 (reseedHost);
|
||||||
|
|
|
@ -112,7 +112,7 @@ namespace i2p
|
||||||
void RouterContext::UpdatePort (int port)
|
void RouterContext::UpdatePort (int port)
|
||||||
{
|
{
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
for (auto address : m_RouterInfo.GetAddresses ())
|
for (auto& address : m_RouterInfo.GetAddresses ())
|
||||||
{
|
{
|
||||||
if (address->port != port)
|
if (address->port != port)
|
||||||
{
|
{
|
||||||
|
@ -127,7 +127,7 @@ namespace i2p
|
||||||
void RouterContext::UpdateAddress (const boost::asio::ip::address& host)
|
void RouterContext::UpdateAddress (const boost::asio::ip::address& host)
|
||||||
{
|
{
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
for (auto address : m_RouterInfo.GetAddresses ())
|
for (auto& address : m_RouterInfo.GetAddresses ())
|
||||||
{
|
{
|
||||||
if (address->host != host && address->IsCompatible (host))
|
if (address->host != host && address->IsCompatible (host))
|
||||||
{
|
{
|
||||||
|
@ -244,7 +244,7 @@ namespace i2p
|
||||||
m_RouterInfo.SetCaps (i2p::data::RouterInfo::eUnreachable | i2p::data::RouterInfo::eSSUTesting); // LU, B
|
m_RouterInfo.SetCaps (i2p::data::RouterInfo::eUnreachable | i2p::data::RouterInfo::eSSUTesting); // LU, B
|
||||||
// remove NTCP address
|
// remove NTCP address
|
||||||
auto& addresses = m_RouterInfo.GetAddresses ();
|
auto& addresses = m_RouterInfo.GetAddresses ();
|
||||||
for (auto it = addresses.begin (); it != addresses.end (); it++)
|
for (auto it = addresses.begin (); it != addresses.end (); ++it)
|
||||||
{
|
{
|
||||||
if ((*it)->transportStyle == i2p::data::RouterInfo::eTransportNTCP &&
|
if ((*it)->transportStyle == i2p::data::RouterInfo::eTransportNTCP &&
|
||||||
(*it)->host.is_v4 ())
|
(*it)->host.is_v4 ())
|
||||||
|
@ -254,7 +254,7 @@ namespace i2p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// delete previous introducers
|
// delete previous introducers
|
||||||
for (auto addr : addresses)
|
for (auto& addr : addresses)
|
||||||
addr->introducers.clear ();
|
addr->introducers.clear ();
|
||||||
|
|
||||||
// update
|
// update
|
||||||
|
@ -274,7 +274,7 @@ namespace i2p
|
||||||
|
|
||||||
// insert NTCP back
|
// insert NTCP back
|
||||||
auto& addresses = m_RouterInfo.GetAddresses ();
|
auto& addresses = m_RouterInfo.GetAddresses ();
|
||||||
for (auto addr : addresses)
|
for (const auto& addr : addresses)
|
||||||
{
|
{
|
||||||
if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU &&
|
if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU &&
|
||||||
addr->host.is_v4 ())
|
addr->host.is_v4 ())
|
||||||
|
@ -285,7 +285,7 @@ namespace i2p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// delete previous introducers
|
// delete previous introducers
|
||||||
for (auto addr : addresses)
|
for (auto& addr : addresses)
|
||||||
addr->introducers.clear ();
|
addr->introducers.clear ();
|
||||||
|
|
||||||
// update
|
// update
|
||||||
|
@ -316,7 +316,7 @@ namespace i2p
|
||||||
bool updated = false, found = false;
|
bool updated = false, found = false;
|
||||||
int port = 0;
|
int port = 0;
|
||||||
auto& addresses = m_RouterInfo.GetAddresses ();
|
auto& addresses = m_RouterInfo.GetAddresses ();
|
||||||
for (auto addr: addresses)
|
for (auto& addr: addresses)
|
||||||
{
|
{
|
||||||
if (addr->host.is_v6 () && addr->transportStyle == i2p::data::RouterInfo::eTransportNTCP)
|
if (addr->host.is_v6 () && addr->transportStyle == i2p::data::RouterInfo::eTransportNTCP)
|
||||||
{
|
{
|
||||||
|
@ -440,6 +440,12 @@ namespace i2p
|
||||||
i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg);
|
i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RouterContext::CleanupDestination ()
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> l(m_GarlicMutex);
|
||||||
|
i2p::garlic::GarlicDestination::CleanupExpiredTags ();
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t RouterContext::GetUptime () const
|
uint32_t RouterContext::GetUptime () const
|
||||||
{
|
{
|
||||||
return i2p::util::GetSecondsSinceEpoch () - m_StartupTime;
|
return i2p::util::GetSecondsSinceEpoch () - m_StartupTime;
|
||||||
|
|
|
@ -72,6 +72,7 @@ namespace i2p
|
||||||
|
|
||||||
void UpdateNTCPV6Address (const boost::asio::ip::address& host); // called from NTCP session
|
void UpdateNTCPV6Address (const boost::asio::ip::address& host); // called from NTCP session
|
||||||
void UpdateStats ();
|
void UpdateStats ();
|
||||||
|
void CleanupDestination (); // garlic destination
|
||||||
|
|
||||||
// implements LocalDestination
|
// implements LocalDestination
|
||||||
std::shared_ptr<const i2p::data::IdentityEx> GetIdentity () const { return m_Keys.GetPublic (); };
|
std::shared_ptr<const i2p::data::IdentityEx> GetIdentity () const { return m_Keys.GetPublic (); };
|
||||||
|
|
|
@ -369,19 +369,19 @@ namespace data
|
||||||
SetProperty ("caps", caps);
|
SetProperty ("caps", caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::WriteToStream (std::ostream& s)
|
void RouterInfo::WriteToStream (std::ostream& s) const
|
||||||
{
|
{
|
||||||
uint64_t ts = htobe64 (m_Timestamp);
|
uint64_t ts = htobe64 (m_Timestamp);
|
||||||
s.write ((char *)&ts, sizeof (ts));
|
s.write ((const char *)&ts, sizeof (ts));
|
||||||
|
|
||||||
// addresses
|
// addresses
|
||||||
uint8_t numAddresses = m_Addresses->size ();
|
uint8_t numAddresses = m_Addresses->size ();
|
||||||
s.write ((char *)&numAddresses, sizeof (numAddresses));
|
s.write ((char *)&numAddresses, sizeof (numAddresses));
|
||||||
for (auto addr : *m_Addresses)
|
for (const auto& addr_ptr : *m_Addresses)
|
||||||
{
|
{
|
||||||
Address& address = *addr;
|
const Address& address = *addr_ptr;
|
||||||
s.write ((char *)&address.cost, sizeof (address.cost));
|
s.write ((const char *)&address.cost, sizeof (address.cost));
|
||||||
s.write ((char *)&address.date, sizeof (address.date));
|
s.write ((const char *)&address.date, sizeof (address.date));
|
||||||
std::stringstream properties;
|
std::stringstream properties;
|
||||||
if (address.transportStyle == eTransportNTCP)
|
if (address.transportStyle == eTransportNTCP)
|
||||||
WriteString ("NTCP", s);
|
WriteString ("NTCP", s);
|
||||||
|
@ -410,7 +410,7 @@ namespace data
|
||||||
if (address.introducers.size () > 0)
|
if (address.introducers.size () > 0)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (auto introducer: address.introducers)
|
for (const auto& introducer: address.introducers)
|
||||||
{
|
{
|
||||||
WriteString ("ihost" + boost::lexical_cast<std::string>(i), properties);
|
WriteString ("ihost" + boost::lexical_cast<std::string>(i), properties);
|
||||||
properties << '=';
|
properties << '=';
|
||||||
|
@ -419,7 +419,7 @@ namespace data
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
for (auto introducer: address.introducers)
|
for (const auto& introducer: address.introducers)
|
||||||
{
|
{
|
||||||
WriteString ("ikey" + boost::lexical_cast<std::string>(i), properties);
|
WriteString ("ikey" + boost::lexical_cast<std::string>(i), properties);
|
||||||
properties << '=';
|
properties << '=';
|
||||||
|
@ -431,7 +431,7 @@ namespace data
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
for (auto introducer: address.introducers)
|
for (const auto& introducer: address.introducers)
|
||||||
{
|
{
|
||||||
WriteString ("iport" + boost::lexical_cast<std::string>(i), properties);
|
WriteString ("iport" + boost::lexical_cast<std::string>(i), properties);
|
||||||
properties << '=';
|
properties << '=';
|
||||||
|
@ -440,7 +440,7 @@ namespace data
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
for (auto introducer: address.introducers)
|
for (const auto& introducer: address.introducers)
|
||||||
{
|
{
|
||||||
WriteString ("itag" + boost::lexical_cast<std::string>(i), properties);
|
WriteString ("itag" + boost::lexical_cast<std::string>(i), properties);
|
||||||
properties << '=';
|
properties << '=';
|
||||||
|
@ -482,7 +482,7 @@ namespace data
|
||||||
|
|
||||||
// properties
|
// properties
|
||||||
std::stringstream properties;
|
std::stringstream properties;
|
||||||
for (auto& p : m_Properties)
|
for (const auto& p : m_Properties)
|
||||||
{
|
{
|
||||||
WriteString (p.first, properties);
|
WriteString (p.first, properties);
|
||||||
properties << '=';
|
properties << '=';
|
||||||
|
@ -570,10 +570,10 @@ namespace data
|
||||||
addr->cost = 2;
|
addr->cost = 2;
|
||||||
addr->date = 0;
|
addr->date = 0;
|
||||||
addr->mtu = 0;
|
addr->mtu = 0;
|
||||||
for (auto it: *m_Addresses) // don't insert same address twice
|
for (const auto& it: *m_Addresses) // don't insert same address twice
|
||||||
if (*it == *addr) return;
|
if (*it == *addr) return;
|
||||||
m_Addresses->push_back(addr);
|
|
||||||
m_SupportedTransports |= addr->host.is_v6 () ? eNTCPV6 : eNTCPV4;
|
m_SupportedTransports |= addr->host.is_v6 () ? eNTCPV6 : eNTCPV4;
|
||||||
|
m_Addresses->push_back(std::move(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu)
|
void RouterInfo::AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu)
|
||||||
|
@ -586,21 +586,22 @@ namespace data
|
||||||
addr->date = 0;
|
addr->date = 0;
|
||||||
addr->mtu = mtu;
|
addr->mtu = mtu;
|
||||||
memcpy (addr->key, key, 32);
|
memcpy (addr->key, key, 32);
|
||||||
for (auto it: *m_Addresses) // don't insert same address twice
|
for (const auto& it: *m_Addresses) // don't insert same address twice
|
||||||
if (*it == *addr) return;
|
if (*it == *addr) return;
|
||||||
m_Addresses->push_back(addr);
|
|
||||||
m_SupportedTransports |= addr->host.is_v6 () ? eSSUV6 : eSSUV4;
|
m_SupportedTransports |= addr->host.is_v6 () ? eSSUV6 : eSSUV4;
|
||||||
|
m_Addresses->push_back(std::move(addr));
|
||||||
|
|
||||||
m_Caps |= eSSUTesting;
|
m_Caps |= eSSUTesting;
|
||||||
m_Caps |= eSSUIntroducer;
|
m_Caps |= eSSUIntroducer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterInfo::AddIntroducer (const Introducer& introducer)
|
bool RouterInfo::AddIntroducer (const Introducer& introducer)
|
||||||
{
|
{
|
||||||
for (auto addr : *m_Addresses)
|
for (auto& addr : *m_Addresses)
|
||||||
{
|
{
|
||||||
if (addr->transportStyle == eTransportSSU && addr->host.is_v4 ())
|
if (addr->transportStyle == eTransportSSU && addr->host.is_v4 ())
|
||||||
{
|
{
|
||||||
for (auto intro: addr->introducers)
|
for (auto& intro: addr->introducers)
|
||||||
if (intro.iTag == introducer.iTag) return false; // already presented
|
if (intro.iTag == introducer.iTag) return false; // already presented
|
||||||
addr->introducers.push_back (introducer);
|
addr->introducers.push_back (introducer);
|
||||||
return true;
|
return true;
|
||||||
|
@ -611,11 +612,11 @@ namespace data
|
||||||
|
|
||||||
bool RouterInfo::RemoveIntroducer (const boost::asio::ip::udp::endpoint& e)
|
bool RouterInfo::RemoveIntroducer (const boost::asio::ip::udp::endpoint& e)
|
||||||
{
|
{
|
||||||
for (auto addr: *m_Addresses)
|
for (auto& addr: *m_Addresses)
|
||||||
{
|
{
|
||||||
if (addr->transportStyle == eTransportSSU && addr->host.is_v4 ())
|
if (addr->transportStyle == eTransportSSU && addr->host.is_v4 ())
|
||||||
{
|
{
|
||||||
for (std::vector<Introducer>::iterator it = addr->introducers.begin (); it != addr->introducers.end (); it++)
|
for (auto it = addr->introducers.begin (); it != addr->introducers.end (); ++it)
|
||||||
if ( boost::asio::ip::udp::endpoint (it->iHost, it->iPort) == e)
|
if ( boost::asio::ip::udp::endpoint (it->iHost, it->iPort) == e)
|
||||||
{
|
{
|
||||||
addr->introducers.erase (it);
|
addr->introducers.erase (it);
|
||||||
|
@ -707,7 +708,7 @@ namespace data
|
||||||
if (addr->host.is_v6 ())
|
if (addr->host.is_v6 ())
|
||||||
it = m_Addresses->erase (it);
|
it = m_Addresses->erase (it);
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -723,7 +724,7 @@ namespace data
|
||||||
if (addr->host.is_v4 ())
|
if (addr->host.is_v4 ())
|
||||||
it = m_Addresses->erase (it);
|
it = m_Addresses->erase (it);
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -752,7 +753,7 @@ namespace data
|
||||||
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetAddress (TransportStyle s, bool v4only, bool v6only) const
|
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetAddress (TransportStyle s, bool v4only, bool v6only) const
|
||||||
{
|
{
|
||||||
auto addresses = m_Addresses;
|
auto addresses = m_Addresses;
|
||||||
for (auto address : *addresses)
|
for (const auto& address : *addresses)
|
||||||
{
|
{
|
||||||
if (address->transportStyle == s)
|
if (address->transportStyle == s)
|
||||||
{
|
{
|
||||||
|
|
|
@ -187,9 +187,9 @@ namespace data
|
||||||
void ReadFromFile ();
|
void ReadFromFile ();
|
||||||
void ReadFromStream (std::istream& s);
|
void ReadFromStream (std::istream& s);
|
||||||
void ReadFromBuffer (bool verifySignature);
|
void ReadFromBuffer (bool verifySignature);
|
||||||
void WriteToStream (std::ostream& s);
|
void WriteToStream (std::ostream& s) const;
|
||||||
size_t ReadString (char * str, std::istream& s);
|
static size_t ReadString (char* str, std::istream& s);
|
||||||
void WriteString (const std::string& str, std::ostream& s);
|
static void WriteString (const std::string& str, std::ostream& s);
|
||||||
void ExtractCaps (const char * value);
|
void ExtractCaps (const char * value);
|
||||||
std::shared_ptr<const Address> GetAddress (TransportStyle s, bool v4only, bool v6only = false) const;
|
std::shared_ptr<const Address> GetAddress (TransportStyle s, bool v4only, bool v6only = false) const;
|
||||||
void UpdateCapsProperty ();
|
void UpdateCapsProperty ();
|
||||||
|
|
4
SAM.cpp
4
SAM.cpp
|
@ -686,7 +686,7 @@ namespace client
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(m_SocketsMutex);
|
std::lock_guard<std::mutex> lock(m_SocketsMutex);
|
||||||
for (auto sock : m_Sockets) {
|
for (auto& sock : m_Sockets) {
|
||||||
sock->CloseStream();
|
sock->CloseStream();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -719,7 +719,7 @@ namespace client
|
||||||
{
|
{
|
||||||
m_IsRunning = false;
|
m_IsRunning = false;
|
||||||
m_Acceptor.cancel ();
|
m_Acceptor.cancel ();
|
||||||
for (auto it: m_Sessions)
|
for (auto& it: m_Sessions)
|
||||||
it.second->CloseStreams ();
|
it.second->CloseStreams ();
|
||||||
m_Sessions.clear ();
|
m_Sessions.clear ();
|
||||||
m_Service.stop ();
|
m_Service.stop ();
|
||||||
|
|
2
SAM.h
2
SAM.h
|
@ -154,7 +154,7 @@ namespace client
|
||||||
std::list<std::shared_ptr<SAMSocket> > l;
|
std::list<std::shared_ptr<SAMSocket> > l;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(m_SocketsMutex);
|
std::lock_guard<std::mutex> lock(m_SocketsMutex);
|
||||||
for( auto & sock : m_Sockets ) l.push_back(sock);
|
for(const auto& sock : m_Sockets ) l.push_back(sock);
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace proxy
|
||||||
{
|
{
|
||||||
uint8_t size;
|
uint8_t size;
|
||||||
char value[max_socks_hostname_size];
|
char value[max_socks_hostname_size];
|
||||||
void FromString (std::string str)
|
void FromString (const std::string& str)
|
||||||
{
|
{
|
||||||
size = str.length();
|
size = str.length();
|
||||||
if (str.length() > max_socks_hostname_size) size = max_socks_hostname_size;
|
if (str.length() > max_socks_hostname_size) size = max_socks_hostname_size;
|
||||||
|
|
22
SSU.cpp
22
SSU.cpp
|
@ -237,9 +237,8 @@ namespace transport
|
||||||
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSUSession> > * sessions)
|
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSUSession> > * sessions)
|
||||||
{
|
{
|
||||||
std::shared_ptr<SSUSession> session;
|
std::shared_ptr<SSUSession> session;
|
||||||
for (auto it1: packets)
|
for (auto& packet: packets)
|
||||||
{
|
{
|
||||||
auto packet = it1;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!session || session->GetRemoteEndpoint () != packet->from) // we received packet for other session than previous
|
if (!session || session->GetRemoteEndpoint () != packet->from) // we received packet for other session than previous
|
||||||
|
@ -431,11 +430,11 @@ namespace transport
|
||||||
|
|
||||||
void SSUServer::DeleteAllSessions ()
|
void SSUServer::DeleteAllSessions ()
|
||||||
{
|
{
|
||||||
for (auto it: m_Sessions)
|
for (auto& it: m_Sessions)
|
||||||
it.second->Close ();
|
it.second->Close ();
|
||||||
m_Sessions.clear ();
|
m_Sessions.clear ();
|
||||||
|
|
||||||
for (auto it: m_SessionsV6)
|
for (auto& it: m_SessionsV6)
|
||||||
it.second->Close ();
|
it.second->Close ();
|
||||||
m_SessionsV6.clear ();
|
m_SessionsV6.clear ();
|
||||||
}
|
}
|
||||||
|
@ -444,7 +443,7 @@ namespace transport
|
||||||
std::shared_ptr<SSUSession> SSUServer::GetRandomV4Session (Filter filter) // v4 only
|
std::shared_ptr<SSUSession> SSUServer::GetRandomV4Session (Filter filter) // v4 only
|
||||||
{
|
{
|
||||||
std::vector<std::shared_ptr<SSUSession> > filteredSessions;
|
std::vector<std::shared_ptr<SSUSession> > filteredSessions;
|
||||||
for (auto s :m_Sessions)
|
for (const auto& s :m_Sessions)
|
||||||
if (filter (s.second)) filteredSessions.push_back (s.second);
|
if (filter (s.second)) filteredSessions.push_back (s.second);
|
||||||
if (filteredSessions.size () > 0)
|
if (filteredSessions.size () > 0)
|
||||||
{
|
{
|
||||||
|
@ -468,7 +467,7 @@ namespace transport
|
||||||
std::shared_ptr<SSUSession> SSUServer::GetRandomV6Session (Filter filter) // v6 only
|
std::shared_ptr<SSUSession> SSUServer::GetRandomV6Session (Filter filter) // v6 only
|
||||||
{
|
{
|
||||||
std::vector<std::shared_ptr<SSUSession> > filteredSessions;
|
std::vector<std::shared_ptr<SSUSession> > filteredSessions;
|
||||||
for (auto s :m_SessionsV6)
|
for (const auto& s :m_SessionsV6)
|
||||||
if (filter (s.second)) filteredSessions.push_back (s.second);
|
if (filter (s.second)) filteredSessions.push_back (s.second);
|
||||||
if (filteredSessions.size () > 0)
|
if (filteredSessions.size () > 0)
|
||||||
{
|
{
|
||||||
|
@ -535,7 +534,7 @@ namespace transport
|
||||||
std::list<boost::asio::ip::udp::endpoint> newList;
|
std::list<boost::asio::ip::udp::endpoint> newList;
|
||||||
size_t numIntroducers = 0;
|
size_t numIntroducers = 0;
|
||||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
for (auto it :m_Introducers)
|
for (const auto& it : m_Introducers)
|
||||||
{
|
{
|
||||||
auto session = FindSession (it);
|
auto session = FindSession (it);
|
||||||
if (session && ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION)
|
if (session && ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION)
|
||||||
|
@ -552,11 +551,9 @@ namespace transport
|
||||||
{
|
{
|
||||||
// create new
|
// create new
|
||||||
auto introducers = FindIntroducers (SSU_MAX_NUM_INTRODUCERS);
|
auto introducers = FindIntroducers (SSU_MAX_NUM_INTRODUCERS);
|
||||||
if (introducers.size () > 0)
|
for (const auto& it1: introducers)
|
||||||
{
|
{
|
||||||
for (auto it1: introducers)
|
const auto& ep = it1->GetRemoteEndpoint ();
|
||||||
{
|
|
||||||
auto& ep = it1->GetRemoteEndpoint ();
|
|
||||||
i2p::data::RouterInfo::Introducer introducer;
|
i2p::data::RouterInfo::Introducer introducer;
|
||||||
introducer.iHost = ep.address ();
|
introducer.iHost = ep.address ();
|
||||||
introducer.iPort = ep.port ();
|
introducer.iPort = ep.port ();
|
||||||
|
@ -569,7 +566,6 @@ namespace transport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
m_Introducers = newList;
|
m_Introducers = newList;
|
||||||
if (m_Introducers.size () < SSU_MAX_NUM_INTRODUCERS)
|
if (m_Introducers.size () < SSU_MAX_NUM_INTRODUCERS)
|
||||||
{
|
{
|
||||||
|
@ -637,7 +633,7 @@ namespace transport
|
||||||
it = m_PeerTests.erase (it);
|
it = m_PeerTests.erase (it);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
if (numDeleted > 0)
|
if (numDeleted > 0)
|
||||||
LogPrint (eLogDebug, "SSU: ", numDeleted, " peer tests have been expired");
|
LogPrint (eLogDebug, "SSU: ", numDeleted, " peer tests have been expired");
|
||||||
|
|
36
SSUData.cpp
36
SSUData.cpp
|
@ -25,10 +25,10 @@ namespace transport
|
||||||
}
|
}
|
||||||
|
|
||||||
SSUData::SSUData (SSUSession& session):
|
SSUData::SSUData (SSUSession& session):
|
||||||
m_Session (session), m_ResendTimer (session.GetService ()), m_DecayTimer (session.GetService ()),
|
m_Session (session), m_ResendTimer (session.GetService ()),
|
||||||
m_IncompleteMessagesCleanupTimer (session.GetService ()),
|
m_IncompleteMessagesCleanupTimer (session.GetService ()),
|
||||||
m_MaxPacketSize (session.IsV6 () ? SSU_V6_MAX_PACKET_SIZE : SSU_V4_MAX_PACKET_SIZE),
|
m_MaxPacketSize (session.IsV6 () ? SSU_V6_MAX_PACKET_SIZE : SSU_V4_MAX_PACKET_SIZE),
|
||||||
m_PacketSize (m_MaxPacketSize)
|
m_PacketSize (m_MaxPacketSize), m_LastMessageReceivedTime (0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,6 @@ namespace transport
|
||||||
void SSUData::Stop ()
|
void SSUData::Stop ()
|
||||||
{
|
{
|
||||||
m_ResendTimer.cancel ();
|
m_ResendTimer.cancel ();
|
||||||
m_DecayTimer.cancel ();
|
|
||||||
m_IncompleteMessagesCleanupTimer.cancel ();
|
m_IncompleteMessagesCleanupTimer.cancel ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,11 +232,8 @@ namespace transport
|
||||||
{
|
{
|
||||||
if (!m_ReceivedMessages.count (msgID))
|
if (!m_ReceivedMessages.count (msgID))
|
||||||
{
|
{
|
||||||
if (m_ReceivedMessages.size () > MAX_NUM_RECEIVED_MESSAGES)
|
|
||||||
m_ReceivedMessages.clear ();
|
|
||||||
else
|
|
||||||
ScheduleDecay ();
|
|
||||||
m_ReceivedMessages.insert (msgID);
|
m_ReceivedMessages.insert (msgID);
|
||||||
|
m_LastMessageReceivedTime = i2p::util::GetSecondsSinceEpoch ();
|
||||||
if (!msg->IsExpired ())
|
if (!msg->IsExpired ())
|
||||||
m_Handler.PutNextMessage (msg);
|
m_Handler.PutNextMessage (msg);
|
||||||
else
|
else
|
||||||
|
@ -448,7 +444,7 @@ namespace transport
|
||||||
|
|
||||||
it->second->numResends++;
|
it->second->numResends++;
|
||||||
it->second->nextResendTime += it->second->numResends*RESEND_INTERVAL;
|
it->second->nextResendTime += it->second->numResends*RESEND_INTERVAL;
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -457,7 +453,7 @@ namespace transport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
if (numResent < MAX_OUTGOING_WINDOW_SIZE)
|
if (numResent < MAX_OUTGOING_WINDOW_SIZE)
|
||||||
ScheduleResend ();
|
ScheduleResend ();
|
||||||
|
@ -469,21 +465,6 @@ namespace transport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUData::ScheduleDecay ()
|
|
||||||
{
|
|
||||||
m_DecayTimer.cancel ();
|
|
||||||
m_DecayTimer.expires_from_now (boost::posix_time::seconds(DECAY_INTERVAL));
|
|
||||||
auto s = m_Session.shared_from_this();
|
|
||||||
m_ResendTimer.async_wait ([s](const boost::system::error_code& ecode)
|
|
||||||
{ s->m_Data.HandleDecayTimer (ecode); });
|
|
||||||
}
|
|
||||||
|
|
||||||
void SSUData::HandleDecayTimer (const boost::system::error_code& ecode)
|
|
||||||
{
|
|
||||||
if (ecode != boost::asio::error::operation_aborted)
|
|
||||||
m_ReceivedMessages.clear ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SSUData::ScheduleIncompleteMessagesCleanup ()
|
void SSUData::ScheduleIncompleteMessagesCleanup ()
|
||||||
{
|
{
|
||||||
m_IncompleteMessagesCleanupTimer.cancel ();
|
m_IncompleteMessagesCleanupTimer.cancel ();
|
||||||
|
@ -506,8 +487,13 @@ namespace transport
|
||||||
it = m_IncompleteMessages.erase (it);
|
it = m_IncompleteMessages.erase (it);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
|
// decay
|
||||||
|
if (m_ReceivedMessages.size () > MAX_NUM_RECEIVED_MESSAGES ||
|
||||||
|
i2p::util::GetSecondsSinceEpoch () > m_LastMessageReceivedTime + DECAY_INTERVAL)
|
||||||
|
m_ReceivedMessages.clear ();
|
||||||
|
|
||||||
ScheduleIncompleteMessagesCleanup ();
|
ScheduleIncompleteMessagesCleanup ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
SSUData.h
10
SSUData.h
|
@ -5,7 +5,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <unordered_set>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include "I2NPProtocol.h"
|
#include "I2NPProtocol.h"
|
||||||
|
@ -109,9 +109,6 @@ namespace transport
|
||||||
void ScheduleResend ();
|
void ScheduleResend ();
|
||||||
void HandleResendTimer (const boost::system::error_code& ecode);
|
void HandleResendTimer (const boost::system::error_code& ecode);
|
||||||
|
|
||||||
void ScheduleDecay ();
|
|
||||||
void HandleDecayTimer (const boost::system::error_code& ecode);
|
|
||||||
|
|
||||||
void ScheduleIncompleteMessagesCleanup ();
|
void ScheduleIncompleteMessagesCleanup ();
|
||||||
void HandleIncompleteMessagesCleanupTimer (const boost::system::error_code& ecode);
|
void HandleIncompleteMessagesCleanupTimer (const boost::system::error_code& ecode);
|
||||||
|
|
||||||
|
@ -121,10 +118,11 @@ namespace transport
|
||||||
SSUSession& m_Session;
|
SSUSession& m_Session;
|
||||||
std::map<uint32_t, std::unique_ptr<IncompleteMessage> > m_IncompleteMessages;
|
std::map<uint32_t, std::unique_ptr<IncompleteMessage> > m_IncompleteMessages;
|
||||||
std::map<uint32_t, std::unique_ptr<SentMessage> > m_SentMessages;
|
std::map<uint32_t, std::unique_ptr<SentMessage> > m_SentMessages;
|
||||||
std::set<uint32_t> m_ReceivedMessages;
|
std::unordered_set<uint32_t> m_ReceivedMessages;
|
||||||
boost::asio::deadline_timer m_ResendTimer, m_DecayTimer, m_IncompleteMessagesCleanupTimer;
|
boost::asio::deadline_timer m_ResendTimer, m_IncompleteMessagesCleanupTimer;
|
||||||
int m_MaxPacketSize, m_PacketSize;
|
int m_MaxPacketSize, m_PacketSize;
|
||||||
i2p::I2NPMessagesHandler m_Handler;
|
i2p::I2NPMessagesHandler m_Handler;
|
||||||
|
uint32_t m_LastMessageReceivedTime; // in second
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,8 @@ namespace i2p
|
||||||
namespace transport
|
namespace transport
|
||||||
{
|
{
|
||||||
SSUSession::SSUSession (SSUServer& server, boost::asio::ip::udp::endpoint& remoteEndpoint,
|
SSUSession::SSUSession (SSUServer& server, boost::asio::ip::udp::endpoint& remoteEndpoint,
|
||||||
std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest ): TransportSession (router),
|
std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest ):
|
||||||
|
TransportSession (router, SSU_TERMINATION_TIMEOUT),
|
||||||
m_Server (server), m_RemoteEndpoint (remoteEndpoint), m_Timer (GetService ()),
|
m_Server (server), m_RemoteEndpoint (remoteEndpoint), m_Timer (GetService ()),
|
||||||
m_IsPeerTest (peerTest),m_State (eSessionStateUnknown), m_IsSessionKey (false),
|
m_IsPeerTest (peerTest),m_State (eSessionStateUnknown), m_IsSessionKey (false),
|
||||||
m_RelayTag (0),m_Data (*this), m_IsDataReceived (false)
|
m_RelayTag (0),m_Data (*this), m_IsDataReceived (false)
|
||||||
|
@ -882,7 +883,7 @@ namespace transport
|
||||||
void SSUSession::ScheduleTermination ()
|
void SSUSession::ScheduleTermination ()
|
||||||
{
|
{
|
||||||
m_Timer.cancel ();
|
m_Timer.cancel ();
|
||||||
m_Timer.expires_from_now (boost::posix_time::seconds(SSU_TERMINATION_TIMEOUT));
|
m_Timer.expires_from_now (boost::posix_time::seconds(GetTerminationTimeout ()));
|
||||||
m_Timer.async_wait (std::bind (&SSUSession::HandleTerminationTimer,
|
m_Timer.async_wait (std::bind (&SSUSession::HandleTerminationTimer,
|
||||||
shared_from_this (), std::placeholders::_1));
|
shared_from_this (), std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
@ -891,7 +892,7 @@ namespace transport
|
||||||
{
|
{
|
||||||
if (ecode != boost::asio::error::operation_aborted)
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "SSU: no activity with ", m_RemoteEndpoint, " for ", SSU_TERMINATION_TIMEOUT, " seconds");
|
LogPrint (eLogWarning, "SSU: no activity with ", m_RemoteEndpoint, " for ", GetTerminationTimeout (), " seconds");
|
||||||
Failed ();
|
Failed ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -906,7 +907,7 @@ namespace transport
|
||||||
{
|
{
|
||||||
if (m_State == eSessionStateEstablished)
|
if (m_State == eSessionStateEstablished)
|
||||||
{
|
{
|
||||||
for (auto it: msgs)
|
for (const auto& it: msgs)
|
||||||
if (it) m_Data.Send (it);
|
if (it) m_Data.Send (it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,7 +263,7 @@ namespace stream
|
||||||
if (nacked)
|
if (nacked)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "Streaming: Packet ", seqn, " NACK");
|
LogPrint (eLogDebug, "Streaming: Packet ", seqn, " NACK");
|
||||||
it++;
|
++it;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,7 +412,7 @@ namespace stream
|
||||||
}
|
}
|
||||||
bool isEmpty = m_SentPackets.empty ();
|
bool isEmpty = m_SentPackets.empty ();
|
||||||
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
for (auto it: packets)
|
for (auto& it: packets)
|
||||||
{
|
{
|
||||||
it->sendTime = ts;
|
it->sendTime = ts;
|
||||||
m_SentPackets.insert (it);
|
m_SentPackets.insert (it);
|
||||||
|
@ -762,7 +762,7 @@ namespace stream
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
if (expired && m_CurrentRemoteLease)
|
if (expired && m_CurrentRemoteLease)
|
||||||
{
|
{
|
||||||
for (auto it: leases)
|
for (const auto& it: leases)
|
||||||
if ((it->tunnelGateway == m_CurrentRemoteLease->tunnelGateway) && (it->tunnelID != m_CurrentRemoteLease->tunnelID))
|
if ((it->tunnelGateway == m_CurrentRemoteLease->tunnelGateway) && (it->tunnelID != m_CurrentRemoteLease->tunnelID))
|
||||||
{
|
{
|
||||||
m_CurrentRemoteLease = it;
|
m_CurrentRemoteLease = it;
|
||||||
|
@ -798,7 +798,7 @@ namespace stream
|
||||||
|
|
||||||
StreamingDestination::~StreamingDestination ()
|
StreamingDestination::~StreamingDestination ()
|
||||||
{
|
{
|
||||||
for (auto it: m_SavedPackets)
|
for (auto& it: m_SavedPackets)
|
||||||
{
|
{
|
||||||
for (auto it1: it.second) delete it1;
|
for (auto it1: it.second) delete it1;
|
||||||
it.second.clear ();
|
it.second.clear ();
|
||||||
|
@ -877,7 +877,7 @@ namespace stream
|
||||||
else // follow on packet without SYN
|
else // follow on packet without SYN
|
||||||
{
|
{
|
||||||
uint32_t receiveStreamID = packet->GetReceiveStreamID ();
|
uint32_t receiveStreamID = packet->GetReceiveStreamID ();
|
||||||
for (auto it: m_Streams)
|
for (auto& it: m_Streams)
|
||||||
if (it.second->GetSendStreamID () == receiveStreamID)
|
if (it.second->GetSendStreamID () == receiveStreamID)
|
||||||
{
|
{
|
||||||
// found
|
// found
|
||||||
|
@ -944,7 +944,7 @@ namespace stream
|
||||||
m_Owner->GetService ().post([acceptor, this](void)
|
m_Owner->GetService ().post([acceptor, this](void)
|
||||||
{
|
{
|
||||||
m_Acceptor = acceptor;
|
m_Acceptor = acceptor;
|
||||||
for (auto it: m_PendingIncomingStreams)
|
for (auto& it: m_PendingIncomingStreams)
|
||||||
if (it->GetStatus () == eStreamStatusOpen) // still open?
|
if (it->GetStatus () == eStreamStatusOpen) // still open?
|
||||||
m_Acceptor (it);
|
m_Acceptor (it);
|
||||||
m_PendingIncomingStreams.clear ();
|
m_PendingIncomingStreams.clear ();
|
||||||
|
@ -963,7 +963,7 @@ namespace stream
|
||||||
if (ecode != boost::asio::error::operation_aborted)
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Streaming: Pending incoming timeout expired");
|
LogPrint (eLogWarning, "Streaming: Pending incoming timeout expired");
|
||||||
for (auto it: m_PendingIncomingStreams)
|
for (auto& it: m_PendingIncomingStreams)
|
||||||
it->Close ();
|
it->Close ();
|
||||||
m_PendingIncomingStreams.clear ();
|
m_PendingIncomingStreams.clear ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,8 +53,8 @@ namespace transport
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TransportSession (std::shared_ptr<const i2p::data::RouterInfo> router):
|
TransportSession (std::shared_ptr<const i2p::data::RouterInfo> router, int terminationTimeout):
|
||||||
m_DHKeysPair (nullptr), m_NumSentBytes (0), m_NumReceivedBytes (0), m_IsOutgoing (router)
|
m_DHKeysPair (nullptr), m_NumSentBytes (0), m_NumReceivedBytes (0), m_IsOutgoing (router), m_TerminationTimeout (terminationTimeout)
|
||||||
{
|
{
|
||||||
if (router)
|
if (router)
|
||||||
m_RemoteIdentity = router->GetRouterIdentity ();
|
m_RemoteIdentity = router->GetRouterIdentity ();
|
||||||
|
@ -70,6 +70,9 @@ namespace transport
|
||||||
size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
|
size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
|
||||||
bool IsOutgoing () const { return m_IsOutgoing; };
|
bool IsOutgoing () const { return m_IsOutgoing; };
|
||||||
|
|
||||||
|
int GetTerminationTimeout () const { return m_TerminationTimeout; };
|
||||||
|
void SetTerminationTimeout (int terminationTimeout) { m_TerminationTimeout = terminationTimeout; };
|
||||||
|
|
||||||
virtual void SendI2NPMessages (const std::vector<std::shared_ptr<I2NPMessage> >& msgs) = 0;
|
virtual void SendI2NPMessages (const std::vector<std::shared_ptr<I2NPMessage> >& msgs) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -78,6 +81,7 @@ namespace transport
|
||||||
std::shared_ptr<i2p::crypto::DHKeys> m_DHKeysPair; // X - for client and Y - for server
|
std::shared_ptr<i2p::crypto::DHKeys> m_DHKeysPair; // X - for client and Y - for server
|
||||||
size_t m_NumSentBytes, m_NumReceivedBytes;
|
size_t m_NumSentBytes, m_NumReceivedBytes;
|
||||||
bool m_IsOutgoing;
|
bool m_IsOutgoing;
|
||||||
|
int m_TerminationTimeout;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,7 @@ namespace transport
|
||||||
m_Thread = new std::thread (std::bind (&Transports::Run, this));
|
m_Thread = new std::thread (std::bind (&Transports::Run, this));
|
||||||
// create acceptors
|
// create acceptors
|
||||||
auto& addresses = context.GetRouterInfo ().GetAddresses ();
|
auto& addresses = context.GetRouterInfo ().GetAddresses ();
|
||||||
for (auto address : addresses)
|
for (const auto& address : addresses)
|
||||||
{
|
{
|
||||||
if (m_NTCPServer == nullptr && enableNTCP)
|
if (m_NTCPServer == nullptr && enableNTCP)
|
||||||
{
|
{
|
||||||
|
@ -236,7 +236,7 @@ namespace transport
|
||||||
if (ident == i2p::context.GetRouterInfo ().GetIdentHash ())
|
if (ident == i2p::context.GetRouterInfo ().GetIdentHash ())
|
||||||
{
|
{
|
||||||
// we send it to ourself
|
// we send it to ourself
|
||||||
for (auto it: msgs)
|
for (auto& it: msgs)
|
||||||
i2p::HandleI2NPMessage (it);
|
i2p::HandleI2NPMessage (it);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -266,7 +266,7 @@ namespace transport
|
||||||
{
|
{
|
||||||
if (it->second.delayedMessages.size () < MAX_NUM_DELAYED_MESSAGES)
|
if (it->second.delayedMessages.size () < MAX_NUM_DELAYED_MESSAGES)
|
||||||
{
|
{
|
||||||
for (auto it1: msgs)
|
for (auto& it1: msgs)
|
||||||
it->second.delayedMessages.push_back (it1);
|
it->second.delayedMessages.push_back (it1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -569,6 +569,8 @@ namespace transport
|
||||||
}
|
}
|
||||||
if (sendDatabaseStore)
|
if (sendDatabaseStore)
|
||||||
session->SendI2NPMessages ({ CreateDatabaseStoreMsg () });
|
session->SendI2NPMessages ({ CreateDatabaseStoreMsg () });
|
||||||
|
else
|
||||||
|
session->SetTerminationTimeout (10); // most likely it's publishing, no follow-up messages expected, set timeout to 10 seconds
|
||||||
it->second.sessions.push_back (session);
|
it->second.sessions.push_back (session);
|
||||||
session->SendI2NPMessages (it->second.delayedMessages);
|
session->SendI2NPMessages (it->second.delayedMessages);
|
||||||
it->second.delayedMessages.clear ();
|
it->second.delayedMessages.clear ();
|
||||||
|
@ -634,7 +636,7 @@ namespace transport
|
||||||
it = m_Peers.erase (it);
|
it = m_Peers.erase (it);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
UpdateBandwidth (); // TODO: use separate timer(s) for it
|
UpdateBandwidth (); // TODO: use separate timer(s) for it
|
||||||
if (i2p::context.GetStatus () == eRouterStatusTesting) // if still testing, repeat peer test
|
if (i2p::context.GetStatus () == eRouterStatusTesting) // if still testing, repeat peer test
|
||||||
|
@ -656,7 +658,7 @@ namespace transport
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(m_FamilyMutex);
|
std::lock_guard<std::mutex> lock(m_FamilyMutex);
|
||||||
m_TrustedFamilies.clear();
|
m_TrustedFamilies.clear();
|
||||||
for ( auto fam : families )
|
for ( const auto& fam : families )
|
||||||
m_TrustedFamilies.push_back(fam);
|
m_TrustedFamilies.push_back(fam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace transport
|
||||||
|
|
||||||
void Done ()
|
void Done ()
|
||||||
{
|
{
|
||||||
for (auto it: sessions)
|
for (auto& it: sessions)
|
||||||
it->Done ();
|
it->Done ();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
26
Tunnel.cpp
26
Tunnel.cpp
|
@ -186,7 +186,7 @@ namespace tunnel
|
||||||
{
|
{
|
||||||
for (auto& it: m_Hops)
|
for (auto& it: m_Hops)
|
||||||
{
|
{
|
||||||
s << " ⇒ ";
|
s << " ⇒ ";
|
||||||
s << i2p::data::GetIdentHashAbbreviation (it->ident->GetIdentHash ());
|
s << i2p::data::GetIdentHashAbbreviation (it->ident->GetIdentHash ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ namespace tunnel
|
||||||
void InboundTunnel::Print (std::stringstream& s) const
|
void InboundTunnel::Print (std::stringstream& s) const
|
||||||
{
|
{
|
||||||
PrintHops (s);
|
PrintHops (s);
|
||||||
s << " ⇒ " << GetTunnelID () << ":me";
|
s << " ⇒ " << GetTunnelID () << ":me";
|
||||||
}
|
}
|
||||||
|
|
||||||
ZeroHopsInboundTunnel::ZeroHopsInboundTunnel ():
|
ZeroHopsInboundTunnel::ZeroHopsInboundTunnel ():
|
||||||
|
@ -224,7 +224,7 @@ namespace tunnel
|
||||||
|
|
||||||
void ZeroHopsInboundTunnel::Print (std::stringstream& s) const
|
void ZeroHopsInboundTunnel::Print (std::stringstream& s) const
|
||||||
{
|
{
|
||||||
s << " ⇒ " << GetTunnelID () << ":me";
|
s << " ⇒ " << GetTunnelID () << ":me";
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutboundTunnel::SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr<i2p::I2NPMessage> msg)
|
void OutboundTunnel::SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr<i2p::I2NPMessage> msg)
|
||||||
|
@ -265,7 +265,7 @@ namespace tunnel
|
||||||
{
|
{
|
||||||
s << GetTunnelID () << ":me";
|
s << GetTunnelID () << ":me";
|
||||||
PrintHops (s);
|
PrintHops (s);
|
||||||
s << " ⇒ ";
|
s << " ⇒ ";
|
||||||
}
|
}
|
||||||
|
|
||||||
ZeroHopsOutboundTunnel::ZeroHopsOutboundTunnel ():
|
ZeroHopsOutboundTunnel::ZeroHopsOutboundTunnel ():
|
||||||
|
@ -297,7 +297,7 @@ namespace tunnel
|
||||||
|
|
||||||
void ZeroHopsOutboundTunnel::Print (std::stringstream& s) const
|
void ZeroHopsOutboundTunnel::Print (std::stringstream& s) const
|
||||||
{
|
{
|
||||||
s << GetTunnelID () << ":me ⇒ ";
|
s << GetTunnelID () << ":me ⇒ ";
|
||||||
}
|
}
|
||||||
|
|
||||||
Tunnels tunnels;
|
Tunnels tunnels;
|
||||||
|
@ -345,7 +345,7 @@ namespace tunnel
|
||||||
{
|
{
|
||||||
std::shared_ptr<InboundTunnel> tunnel;
|
std::shared_ptr<InboundTunnel> tunnel;
|
||||||
size_t minReceived = 0;
|
size_t minReceived = 0;
|
||||||
for (auto it : m_InboundTunnels)
|
for (const auto& it : m_InboundTunnels)
|
||||||
{
|
{
|
||||||
if (!it->IsEstablished ()) continue;
|
if (!it->IsEstablished ()) continue;
|
||||||
if (!tunnel || it->GetNumReceivedBytes () < minReceived)
|
if (!tunnel || it->GetNumReceivedBytes () < minReceived)
|
||||||
|
@ -362,7 +362,7 @@ namespace tunnel
|
||||||
if (m_OutboundTunnels.empty ()) return nullptr;
|
if (m_OutboundTunnels.empty ()) return nullptr;
|
||||||
uint32_t ind = rand () % m_OutboundTunnels.size (), i = 0;
|
uint32_t ind = rand () % m_OutboundTunnels.size (), i = 0;
|
||||||
std::shared_ptr<OutboundTunnel> tunnel;
|
std::shared_ptr<OutboundTunnel> tunnel;
|
||||||
for (auto it: m_OutboundTunnels)
|
for (const auto& it: m_OutboundTunnels)
|
||||||
{
|
{
|
||||||
if (it->IsEstablished ())
|
if (it->IsEstablished ())
|
||||||
{
|
{
|
||||||
|
@ -586,7 +586,7 @@ namespace tunnel
|
||||||
m_NumFailedTunnelCreations++;
|
m_NumFailedTunnelCreations++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
it++;
|
++it;
|
||||||
break;
|
break;
|
||||||
case eTunnelStateBuildFailed:
|
case eTunnelStateBuildFailed:
|
||||||
LogPrint (eLogDebug, "Tunnel: pending build request ", it->first, " failed, deleted");
|
LogPrint (eLogDebug, "Tunnel: pending build request ", it->first, " failed, deleted");
|
||||||
|
@ -595,7 +595,7 @@ namespace tunnel
|
||||||
break;
|
break;
|
||||||
case eTunnelStateBuildReplyReceived:
|
case eTunnelStateBuildReplyReceived:
|
||||||
// intermediate state, will be either established of build failed
|
// intermediate state, will be either established of build failed
|
||||||
it++;
|
++it;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// success
|
// success
|
||||||
|
@ -635,7 +635,7 @@ namespace tunnel
|
||||||
if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
|
if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
|
||||||
tunnel->SetState (eTunnelStateExpiring);
|
tunnel->SetState (eTunnelStateExpiring);
|
||||||
}
|
}
|
||||||
it++;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -738,9 +738,8 @@ namespace tunnel
|
||||||
void Tunnels::ManageTunnelPools ()
|
void Tunnels::ManageTunnelPools ()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_PoolsMutex);
|
std::unique_lock<std::mutex> l(m_PoolsMutex);
|
||||||
for (auto it: m_Pools)
|
for (auto& pool : m_Pools)
|
||||||
{
|
{
|
||||||
auto pool = it;
|
|
||||||
if (pool && pool->IsActive ())
|
if (pool && pool->IsActive ())
|
||||||
{
|
{
|
||||||
pool->CreateTunnels ();
|
pool->CreateTunnels ();
|
||||||
|
@ -856,7 +855,7 @@ namespace tunnel
|
||||||
int timeout = 0;
|
int timeout = 0;
|
||||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
// TODO: possible race condition with I2PControl
|
// TODO: possible race condition with I2PControl
|
||||||
for (auto it: m_TransitTunnels)
|
for (const auto& it : m_TransitTunnels)
|
||||||
{
|
{
|
||||||
int t = it->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT - ts;
|
int t = it->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT - ts;
|
||||||
if (t > timeout) timeout = t;
|
if (t > timeout) timeout = t;
|
||||||
|
@ -883,4 +882,3 @@ namespace tunnel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -213,7 +213,7 @@ namespace tunnel
|
||||||
void CreatePeers (const Peers& peers)
|
void CreatePeers (const Peers& peers)
|
||||||
{
|
{
|
||||||
TunnelHopConfig * prev = nullptr;
|
TunnelHopConfig * prev = nullptr;
|
||||||
for (auto it: peers)
|
for (const auto& it: peers)
|
||||||
{
|
{
|
||||||
auto hop = new TunnelHopConfig (it);
|
auto hop = new TunnelHopConfig (it);
|
||||||
if (prev)
|
if (prev)
|
||||||
|
|
|
@ -197,7 +197,7 @@ namespace tunnel
|
||||||
{
|
{
|
||||||
m_Buffer.CompleteCurrentTunnelDataMessage ();
|
m_Buffer.CompleteCurrentTunnelDataMessage ();
|
||||||
auto tunnelMsgs = m_Buffer.GetTunnelDataMsgs ();
|
auto tunnelMsgs = m_Buffer.GetTunnelDataMsgs ();
|
||||||
for (auto tunnelMsg : tunnelMsgs)
|
for (auto& tunnelMsg : tunnelMsgs)
|
||||||
{
|
{
|
||||||
m_Tunnel->EncryptTunnelMsg (tunnelMsg, tunnelMsg);
|
m_Tunnel->EncryptTunnelMsg (tunnelMsg, tunnelMsg);
|
||||||
tunnelMsg->FillI2NPMessageHeader (eI2NPTunnelData);
|
tunnelMsg->FillI2NPMessageHeader (eI2NPTunnelData);
|
||||||
|
|
|
@ -49,13 +49,13 @@ namespace tunnel
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
|
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
|
||||||
for (auto it: m_InboundTunnels)
|
for (auto& it: m_InboundTunnels)
|
||||||
it->SetTunnelPool (nullptr);
|
it->SetTunnelPool (nullptr);
|
||||||
m_InboundTunnels.clear ();
|
m_InboundTunnels.clear ();
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
|
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
|
||||||
for (auto it: m_OutboundTunnels)
|
for (auto& it: m_OutboundTunnels)
|
||||||
it->SetTunnelPool (nullptr);
|
it->SetTunnelPool (nullptr);
|
||||||
m_OutboundTunnels.clear ();
|
m_OutboundTunnels.clear ();
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ namespace tunnel
|
||||||
if (expiredTunnel)
|
if (expiredTunnel)
|
||||||
{
|
{
|
||||||
expiredTunnel->SetTunnelPool (nullptr);
|
expiredTunnel->SetTunnelPool (nullptr);
|
||||||
for (auto it: m_Tests)
|
for (auto& it: m_Tests)
|
||||||
if (it.second.second == expiredTunnel) it.second.second = nullptr;
|
if (it.second.second == expiredTunnel) it.second.second = nullptr;
|
||||||
|
|
||||||
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
|
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
|
||||||
|
@ -101,7 +101,7 @@ namespace tunnel
|
||||||
if (expiredTunnel)
|
if (expiredTunnel)
|
||||||
{
|
{
|
||||||
expiredTunnel->SetTunnelPool (nullptr);
|
expiredTunnel->SetTunnelPool (nullptr);
|
||||||
for (auto it: m_Tests)
|
for (auto& it: m_Tests)
|
||||||
if (it.second.first == expiredTunnel) it.second.first = nullptr;
|
if (it.second.first == expiredTunnel) it.second.first = nullptr;
|
||||||
|
|
||||||
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
|
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
|
||||||
|
@ -114,7 +114,7 @@ namespace tunnel
|
||||||
std::vector<std::shared_ptr<InboundTunnel> > v;
|
std::vector<std::shared_ptr<InboundTunnel> > v;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
|
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
|
||||||
for (auto it : m_InboundTunnels)
|
for (const auto& it : m_InboundTunnels)
|
||||||
{
|
{
|
||||||
if (i >= num) break;
|
if (i >= num) break;
|
||||||
if (it->IsEstablished ())
|
if (it->IsEstablished ())
|
||||||
|
@ -144,7 +144,7 @@ namespace tunnel
|
||||||
if (tunnels.empty ()) return nullptr;
|
if (tunnels.empty ()) return nullptr;
|
||||||
uint32_t ind = rand () % (tunnels.size ()/2 + 1), i = 0;
|
uint32_t ind = rand () % (tunnels.size ()/2 + 1), i = 0;
|
||||||
typename TTunnels::value_type tunnel = nullptr;
|
typename TTunnels::value_type tunnel = nullptr;
|
||||||
for (auto it: tunnels)
|
for (const auto& it: tunnels)
|
||||||
{
|
{
|
||||||
if (it->IsEstablished () && it != excluded)
|
if (it->IsEstablished () && it != excluded)
|
||||||
{
|
{
|
||||||
|
@ -164,7 +164,7 @@ namespace tunnel
|
||||||
if (old)
|
if (old)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
|
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
|
||||||
for (auto it: m_OutboundTunnels)
|
for (const auto& it: m_OutboundTunnels)
|
||||||
if (it->IsEstablished () && old->GetEndpointIdentHash () == it->GetEndpointIdentHash ())
|
if (it->IsEstablished () && old->GetEndpointIdentHash () == it->GetEndpointIdentHash ())
|
||||||
{
|
{
|
||||||
tunnel = it;
|
tunnel = it;
|
||||||
|
@ -182,7 +182,7 @@ namespace tunnel
|
||||||
int num = 0;
|
int num = 0;
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
|
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
|
||||||
for (auto it : m_InboundTunnels)
|
for (const auto& it : m_InboundTunnels)
|
||||||
if (it->IsEstablished ()) num++;
|
if (it->IsEstablished ()) num++;
|
||||||
}
|
}
|
||||||
for (int i = num; i < m_NumInboundTunnels; i++)
|
for (int i = num; i < m_NumInboundTunnels; i++)
|
||||||
|
@ -191,7 +191,7 @@ namespace tunnel
|
||||||
num = 0;
|
num = 0;
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
|
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
|
||||||
for (auto it : m_OutboundTunnels)
|
for (const auto& it : m_OutboundTunnels)
|
||||||
if (it->IsEstablished ()) num++;
|
if (it->IsEstablished ()) num++;
|
||||||
}
|
}
|
||||||
for (int i = num; i < m_NumOutboundTunnels; i++)
|
for (int i = num; i < m_NumOutboundTunnels; i++)
|
||||||
|
@ -203,11 +203,10 @@ namespace tunnel
|
||||||
decltype(m_Tests) tests;
|
decltype(m_Tests) tests;
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_TestsMutex);
|
std::unique_lock<std::mutex> l(m_TestsMutex);
|
||||||
tests = m_Tests;
|
tests.swap(m_Tests);
|
||||||
m_Tests.clear ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto it: tests)
|
for (auto& it: tests)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Tunnels: test of tunnel ", it.first, " failed");
|
LogPrint (eLogWarning, "Tunnels: test of tunnel ", it.first, " failed");
|
||||||
// if test failed again with another tunnel we consider it failed
|
// if test failed again with another tunnel we consider it failed
|
||||||
|
@ -248,12 +247,12 @@ namespace tunnel
|
||||||
if ((*it1)->IsFailed ())
|
if ((*it1)->IsFailed ())
|
||||||
{
|
{
|
||||||
failed = true;
|
failed = true;
|
||||||
it1++;
|
++it1;
|
||||||
}
|
}
|
||||||
if ((*it2)->IsFailed ())
|
if ((*it2)->IsFailed ())
|
||||||
{
|
{
|
||||||
failed = true;
|
failed = true;
|
||||||
it2++;
|
++it2;
|
||||||
}
|
}
|
||||||
if (!failed)
|
if (!failed)
|
||||||
{
|
{
|
||||||
|
@ -265,7 +264,7 @@ namespace tunnel
|
||||||
}
|
}
|
||||||
(*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (),
|
(*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (),
|
||||||
CreateDeliveryStatusMsg (msgID));
|
CreateDeliveryStatusMsg (msgID));
|
||||||
it1++; it2++;
|
++it1; ++it2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
15
UPnP.cpp
15
UPnP.cpp
|
@ -49,7 +49,9 @@ namespace transport
|
||||||
m_IsRunning = true;
|
m_IsRunning = true;
|
||||||
LogPrint(eLogInfo, "UPnP: starting");
|
LogPrint(eLogInfo, "UPnP: starting");
|
||||||
m_Service.post (std::bind (&UPnP::Discover, this));
|
m_Service.post (std::bind (&UPnP::Discover, this));
|
||||||
|
std::unique_lock<std::mutex> l(m_StartedMutex);
|
||||||
m_Thread.reset (new std::thread (std::bind (&UPnP::Run, this)));
|
m_Thread.reset (new std::thread (std::bind (&UPnP::Run, this)));
|
||||||
|
m_Started.wait_for (l, std::chrono::seconds (5)); // 5 seconds maximum
|
||||||
}
|
}
|
||||||
|
|
||||||
UPnP::~UPnP ()
|
UPnP::~UPnP ()
|
||||||
|
@ -80,6 +82,11 @@ namespace transport
|
||||||
#else
|
#else
|
||||||
m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, &nerror);
|
m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, &nerror);
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
// notify satrting thread
|
||||||
|
std::unique_lock<std::mutex> l(m_StartedMutex);
|
||||||
|
m_Started.notify_all ();
|
||||||
|
}
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
r = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr));
|
r = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr));
|
||||||
|
@ -115,8 +122,8 @@ namespace transport
|
||||||
|
|
||||||
void UPnP::PortMapping ()
|
void UPnP::PortMapping ()
|
||||||
{
|
{
|
||||||
auto a = context.GetRouterInfo().GetAddresses();
|
const auto& a = context.GetRouterInfo().GetAddresses();
|
||||||
for (auto address : a)
|
for (const auto& address : a)
|
||||||
{
|
{
|
||||||
if (!address->host.is_v6 ())
|
if (!address->host.is_v6 ())
|
||||||
TryPortMapping (address);
|
TryPortMapping (address);
|
||||||
|
@ -132,8 +139,8 @@ namespace transport
|
||||||
|
|
||||||
void UPnP::CloseMapping ()
|
void UPnP::CloseMapping ()
|
||||||
{
|
{
|
||||||
auto a = context.GetRouterInfo().GetAddresses();
|
const auto& a = context.GetRouterInfo().GetAddresses();
|
||||||
for (auto address : a)
|
for (const auto& address : a)
|
||||||
{
|
{
|
||||||
if (!address->host.is_v6 ())
|
if (!address->host.is_v6 ())
|
||||||
CloseMapping (address);
|
CloseMapping (address);
|
||||||
|
|
6
UPnP.h
6
UPnP.h
|
@ -4,6 +4,8 @@
|
||||||
#ifdef USE_UPNP
|
#ifdef USE_UPNP
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <miniupnpc/miniwget.h>
|
#include <miniupnpc/miniwget.h>
|
||||||
|
@ -13,8 +15,6 @@
|
||||||
|
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace transport
|
namespace transport
|
||||||
|
@ -45,6 +45,8 @@ namespace transport
|
||||||
|
|
||||||
bool m_IsRunning;
|
bool m_IsRunning;
|
||||||
std::unique_ptr<std::thread> m_Thread;
|
std::unique_ptr<std::thread> m_Thread;
|
||||||
|
std::condition_variable m_Started;
|
||||||
|
std::mutex m_StartedMutex;
|
||||||
boost::asio::io_service m_Service;
|
boost::asio::io_service m_Service;
|
||||||
boost::asio::deadline_timer m_Timer;
|
boost::asio::deadline_timer m_Timer;
|
||||||
struct UPNPUrls m_upnpUrls;
|
struct UPNPUrls m_upnpUrls;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
#include "../Config.h"
|
#include "../Config.h"
|
||||||
|
#include "../RouterContext.h"
|
||||||
#include "../version.h"
|
#include "../version.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "Win32App.h"
|
#include "Win32App.h"
|
||||||
|
@ -15,10 +16,13 @@
|
||||||
#define ID_EXIT 2001
|
#define ID_EXIT 2001
|
||||||
#define ID_CONSOLE 2002
|
#define ID_CONSOLE 2002
|
||||||
#define ID_APP 2003
|
#define ID_APP 2003
|
||||||
|
#define ID_GRACEFUL_SHUTDOWN 2004
|
||||||
|
|
||||||
#define ID_TRAY_ICON 2050
|
#define ID_TRAY_ICON 2050
|
||||||
#define WM_TRAYICON (WM_USER + 1)
|
#define WM_TRAYICON (WM_USER + 1)
|
||||||
|
|
||||||
|
#define IDT_GRACEFUL_SHUTDOWN_TIMER 2100
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace win32
|
namespace win32
|
||||||
|
@ -30,6 +34,7 @@ namespace win32
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app");
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About...");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About...");
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, NULL, NULL);
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, NULL, NULL);
|
||||||
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown");
|
||||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit");
|
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit");
|
||||||
SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE);
|
SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE);
|
||||||
SendMessage (hWnd, WM_INITMENUPOPUP, (WPARAM)hPopup, 0);
|
SendMessage (hWnd, WM_INITMENUPOPUP, (WPARAM)hPopup, 0);
|
||||||
|
@ -82,6 +87,7 @@ namespace win32
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
{
|
{
|
||||||
RemoveTrayIcon (hWnd);
|
RemoveTrayIcon (hWnd);
|
||||||
|
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
|
||||||
PostQuitMessage (0);
|
PostQuitMessage (0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -101,6 +107,12 @@ namespace win32
|
||||||
PostMessage (hWnd, WM_CLOSE, 0, 0);
|
PostMessage (hWnd, WM_CLOSE, 0, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
case ID_GRACEFUL_SHUTDOWN:
|
||||||
|
{
|
||||||
|
i2p::context.SetAcceptsTunnels (false);
|
||||||
|
SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case ID_CONSOLE:
|
case ID_CONSOLE:
|
||||||
{
|
{
|
||||||
char buf[30];
|
char buf[30];
|
||||||
|
@ -167,6 +179,15 @@ namespace win32
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case WM_TIMER:
|
||||||
|
{
|
||||||
|
if (wParam == IDT_GRACEFUL_SHUTDOWN_TIMER)
|
||||||
|
{
|
||||||
|
PostMessage (hWnd, WM_CLOSE, 0, 0); // exit
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return DefWindowProc( hWnd, uMsg, wParam, lParam);
|
return DefWindowProc( hWnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
@ -218,5 +239,13 @@ namespace win32
|
||||||
{
|
{
|
||||||
UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL));
|
UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GracefulShutdown ()
|
||||||
|
{
|
||||||
|
HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd"));
|
||||||
|
if (hWnd)
|
||||||
|
PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_GRACEFUL_SHUTDOWN, 0), 0);
|
||||||
|
return hWnd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace win32
|
||||||
bool StartWin32App ();
|
bool StartWin32App ();
|
||||||
void StopWin32App ();
|
void StopWin32App ();
|
||||||
int RunWin32App ();
|
int RunWin32App ();
|
||||||
|
bool GracefulShutdown ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // WIN32APP_H__
|
#endif // WIN32APP_H__
|
||||||
|
|
5
debian/patches/01-tune-build-opts.patch
vendored
5
debian/patches/01-tune-build-opts.patch
vendored
|
@ -1,14 +1,15 @@
|
||||||
diff --git a/Makefile b/Makefile
|
diff --git a/Makefile b/Makefile
|
||||||
index fe8ae7e..fc8abda 100644
|
index 7d04ba0..33ee184 100644
|
||||||
--- a/Makefile
|
--- a/Makefile
|
||||||
+++ b/Makefile
|
+++ b/Makefile
|
||||||
@@ -9,9 +9,9 @@ DEPS := obj/make.dep
|
@@ -9,10 +9,10 @@ DEPS := obj/make.dep
|
||||||
|
|
||||||
include filelist.mk
|
include filelist.mk
|
||||||
|
|
||||||
-USE_AESNI := yes
|
-USE_AESNI := yes
|
||||||
+USE_AESNI := no
|
+USE_AESNI := no
|
||||||
USE_STATIC := no
|
USE_STATIC := no
|
||||||
|
USE_MESHNET := no
|
||||||
-USE_UPNP := no
|
-USE_UPNP := no
|
||||||
+USE_UPNP := yes
|
+USE_UPNP := yes
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
Building on Android
|
Building on Android
|
||||||
===================
|
===================
|
||||||
|
|
||||||
|
There are two versions: with QT and without QT.
|
||||||
|
|
||||||
Pre-requesties
|
Pre-requesties
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
@ -8,12 +10,12 @@ You need to install Android SDK, NDK and QT with android support.
|
||||||
|
|
||||||
- [SDK](https://developer.android.com/studio/index.html) (choose command line tools only)
|
- [SDK](https://developer.android.com/studio/index.html) (choose command line tools only)
|
||||||
- [NDK](https://developer.android.com/ndk/downloads/index.html)
|
- [NDK](https://developer.android.com/ndk/downloads/index.html)
|
||||||
- [QT](https://www.qt.io/download-open-source/). Choose one for your platform for android. For example QT 5.6 under Linux would be [this file](http://download.qt.io/official_releases/qt/5.6/5.6.1-1/qt-opensource-linux-x64-android-5.6.1-1.run )
|
- [QT](https://www.qt.io/download-open-source/)(for QT only). Choose one for your platform for android. For example QT 5.6 under Linux would be [this file](http://download.qt.io/official_releases/qt/5.6/5.6.1-1/qt-opensource-linux-x64-android-5.6.1-1.run )
|
||||||
|
|
||||||
You also need Java JDK and Ant.
|
You also need Java JDK and Ant.
|
||||||
|
|
||||||
QT-Creator
|
QT-Creator (for QT only)
|
||||||
----------
|
------------------------
|
||||||
Open QT-creator that should be installed with QT.
|
Open QT-creator that should be installed with QT.
|
||||||
Go to Settings/Anndroid and specify correct paths to SDK and NDK.
|
Go to Settings/Anndroid and specify correct paths to SDK and NDK.
|
||||||
If everything is correct you will see two set avaiable:
|
If everything is correct you will see two set avaiable:
|
||||||
|
@ -30,11 +32,26 @@ git clone https://github.com/PurpleI2P/android-ifaddrs.git
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Building the app
|
Building the app with QT
|
||||||
----------------
|
------------------------
|
||||||
- Open qt/i2pd_qt/i2pd_qt.pro in the QT-creator.
|
- Open qt/i2pd_qt/i2pd_qt.pro in the QT-creator
|
||||||
- Change line MAIN_PATH = /path/to/libraries to actual path where did you put the dependancies to.
|
- Change line MAIN_PATH = /path/to/libraries to an actual path where you put the dependancies to
|
||||||
- Select appropriate project (usually armeabi-v7a) and build.
|
- Select appropriate project (usually armeabi-v7a) and build
|
||||||
- You will find an .apk file in android-build/bin folder.
|
- You will find an .apk file in android-build/bin folder
|
||||||
|
|
||||||
|
Building the app without QT
|
||||||
|
---------------------------
|
||||||
|
- Change line I2PD_LIBS_PATH in android/jni/Application.mk to an actual path where you put the dependancies to
|
||||||
|
- Run 'ndk-build -j4' from andorid folder
|
||||||
|
- Create or edit file 'local.properties'. Place 'sdk.dir=<path to SDK>' and 'ndk.dir=<path to NDK>'
|
||||||
|
- Run 'ant clean debug'
|
||||||
|
|
||||||
|
Creating release .apk
|
||||||
|
----------------------
|
||||||
|
In order to create release .apk you must obtain a Java keystore file(.jks). Either you have in already, or you can generate it yourself using keytool, or from one of you existing well-know ceritificates. For example, i2pd release are signed with this [certificate](https://github.com/PurpleI2P/i2pd/blob/openssl/contrib/certificates/router/orignal_at_mail.i2p.crt).
|
||||||
|
Create file 'ant.propeties'
|
||||||
|
key.store='path to keystore file'
|
||||||
|
key.alias='alias name'
|
||||||
|
key.store.password='keystore password'
|
||||||
|
key.alias.password='alias password'
|
||||||
|
Run 'ant clean release'
|
||||||
|
|
|
@ -23,7 +23,7 @@ After successfull build i2pd could be installed with:
|
||||||
```bash
|
```bash
|
||||||
make install
|
make install
|
||||||
```
|
```
|
||||||
or you can just use 'make' once you have all dependacies (boost and openssl) installed
|
or you can just use 'make' once you have all dependencies (boost and openssl) installed
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/PurpleI2P/i2pd.git
|
git clone https://github.com/PurpleI2P/i2pd.git
|
||||||
|
|
|
@ -161,15 +161,17 @@ support for this. Unpack client source code in a sibling folder,
|
||||||
e.g. C:\dev\miniupnpc . You may want to remove version number from
|
e.g. C:\dev\miniupnpc . You may want to remove version number from
|
||||||
folder name included in downloaded archive.
|
folder name included in downloaded archive.
|
||||||
|
|
||||||
Note that you might need to build DLL yourself for 64-bit systems
|
|
||||||
using msys2 as 64-bit DLLs are not provided by the project.
|
|
||||||
|
|
||||||
You can also install it through the MSYS2
|
You can also install it through the MSYS2
|
||||||
and build with USE_UPNP key.
|
and build with USE_UPNP key.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pacman -S mingw-w64-i686-miniupnpc
|
pacman -S mingw-w64-i686-miniupnpc
|
||||||
make USE_UPNP=1
|
make USE_UPNP=yes
|
||||||
|
```
|
||||||
|
or
|
||||||
|
```bash
|
||||||
|
pacman -S mingw-x86_64-miniupnpc
|
||||||
|
make USE_UPNP=yes
|
||||||
```
|
```
|
||||||
|
|
||||||
### Creating Visual Studio project
|
### Creating Visual Studio project
|
||||||
|
|
|
@ -70,7 +70,9 @@ All options below still possible in cmdline, but better write it in config file:
|
||||||
|
|
||||||
* --upnp.enabled= - Enable or disable UPnP, false by default for CLI and true for GUI (Windows, Android)
|
* --upnp.enabled= - Enable or disable UPnP, false by default for CLI and true for GUI (Windows, Android)
|
||||||
* --upnp.name= - Name i2pd appears in UPnP forwardings list. I2Pd by default
|
* --upnp.name= - Name i2pd appears in UPnP forwardings list. I2Pd by default
|
||||||
|
|
||||||
* --precomputation.elgamal= - Use ElGamal precomputated tables. false for x64 and true for other platforms by default
|
* --precomputation.elgamal= - Use ElGamal precomputated tables. false for x64 and true for other platforms by default
|
||||||
|
* --reseed.file - Full path to SU3 file to reseed from
|
||||||
|
|
||||||
* --limits.transittunnels= - Override maximum number of transit tunnels. 2500 by default
|
* --limits.transittunnels= - Override maximum number of transit tunnels. 2500 by default
|
||||||
|
|
||||||
|
@ -109,7 +111,7 @@ tunnels.conf:
|
||||||
# * keys -- our identity, if unset, will be generated on every startup,
|
# * keys -- our identity, if unset, will be generated on every startup,
|
||||||
# if set and file missing, keys will be generated and placed to this file
|
# if set and file missing, keys will be generated and placed to this file
|
||||||
# * address -- local interface to bind
|
# * address -- local interface to bind
|
||||||
# * signaturetype -- signature type for new destination. 0,1 or 7
|
# * signaturetype -- signature type for new destination. 0 (DSA/SHA1), 1 (EcDSA/SHA256) or 7 (EdDSA/SHA512)
|
||||||
[IRC]
|
[IRC]
|
||||||
type = client
|
type = client
|
||||||
address = 127.0.0.1
|
address = 127.0.0.1
|
||||||
|
|
|
@ -5,7 +5,7 @@ LIB_SRC = \
|
||||||
SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \
|
SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \
|
||||||
Transports.cpp Tunnel.cpp TunnelEndpoint.cpp TunnelPool.cpp TunnelGateway.cpp \
|
Transports.cpp Tunnel.cpp TunnelEndpoint.cpp TunnelPool.cpp TunnelGateway.cpp \
|
||||||
Destination.cpp Base.cpp I2PEndian.cpp FS.cpp Config.cpp Family.cpp \
|
Destination.cpp Base.cpp I2PEndian.cpp FS.cpp Config.cpp Family.cpp \
|
||||||
util.cpp api.cpp
|
Config.cpp util.cpp api.cpp
|
||||||
|
|
||||||
LIB_CLIENT_SRC = \
|
LIB_CLIENT_SRC = \
|
||||||
AddressBook.cpp BOB.cpp ClientContext.cpp I2PTunnel.cpp I2PService.cpp \
|
AddressBook.cpp BOB.cpp ClientContext.cpp I2PTunnel.cpp I2PService.cpp \
|
||||||
|
@ -13,5 +13,5 @@ LIB_CLIENT_SRC = \
|
||||||
|
|
||||||
# also: Daemon{Linux,Win32}.cpp will be added later
|
# also: Daemon{Linux,Win32}.cpp will be added later
|
||||||
DAEMON_SRC = \
|
DAEMON_SRC = \
|
||||||
HTTPServer.cpp I2PControl.cpp UPnP.cpp Daemon.cpp Config.cpp i2pd.cpp
|
HTTPServer.cpp I2PControl.cpp UPnP.cpp Daemon.cpp i2pd.cpp
|
||||||
|
|
||||||
|
|
159
util.cpp
159
util.cpp
|
@ -1,12 +1,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm>
|
|
||||||
#include <cctype>
|
|
||||||
#include <functional>
|
|
||||||
#include <fstream>
|
|
||||||
#include <set>
|
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include <boost/lexical_cast.hpp>
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
|
@ -60,158 +55,6 @@ namespace i2p
|
||||||
{
|
{
|
||||||
namespace util
|
namespace util
|
||||||
{
|
{
|
||||||
namespace http
|
|
||||||
{
|
|
||||||
std::string GetHttpContent (std::istream& response)
|
|
||||||
{
|
|
||||||
std::string version, statusMessage;
|
|
||||||
response >> version; // HTTP version
|
|
||||||
int status;
|
|
||||||
response >> status; // status
|
|
||||||
std::getline (response, statusMessage);
|
|
||||||
if (status == 200) // OK
|
|
||||||
{
|
|
||||||
bool isChunked = false;
|
|
||||||
std::string header;
|
|
||||||
while (!response.eof () && header != "\r")
|
|
||||||
{
|
|
||||||
std::getline(response, header);
|
|
||||||
auto colon = header.find (':');
|
|
||||||
if (colon != std::string::npos)
|
|
||||||
{
|
|
||||||
std::string field = header.substr (0, colon);
|
|
||||||
std::transform(field.begin(), field.end(), field.begin(), ::tolower);
|
|
||||||
if (field == i2p::util::http::TRANSFER_ENCODING)
|
|
||||||
isChunked = (header.find ("chunked", colon + 1) != std::string::npos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
if (isChunked)
|
|
||||||
MergeChunkedResponse (response, ss);
|
|
||||||
else
|
|
||||||
ss << response.rdbuf();
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogPrint (eLogError, "HTTPClient: error, server responds ", status);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MergeChunkedResponse (std::istream& response, std::ostream& merged)
|
|
||||||
{
|
|
||||||
while (!response.eof ())
|
|
||||||
{
|
|
||||||
std::string hexLen;
|
|
||||||
size_t len;
|
|
||||||
std::getline (response, hexLen);
|
|
||||||
std::istringstream iss (hexLen);
|
|
||||||
iss >> std::hex >> len;
|
|
||||||
if (!len || len > 10000000L) // 10M
|
|
||||||
{
|
|
||||||
LogPrint (eLogError, "Unexpected chunk length ", len);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
char * buf = new char[len];
|
|
||||||
response.read (buf, len);
|
|
||||||
merged.write (buf, len);
|
|
||||||
delete[] buf;
|
|
||||||
std::getline (response, hexLen); // read \r\n after chunk
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
url::url(const std::string& url_s)
|
|
||||||
{
|
|
||||||
portstr_ = "80";
|
|
||||||
port_ = 80;
|
|
||||||
user_ = "";
|
|
||||||
pass_ = "";
|
|
||||||
|
|
||||||
parse(url_s);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// code for parser tests
|
|
||||||
//{
|
|
||||||
// i2p::util::http::url u_0("http://127.0.0.1:7070/asdasd?qqqqqqqqqqqq");
|
|
||||||
// i2p::util::http::url u_1("http://user:password@site.com:8080/asdasd?qqqqqqqqqqqqq");
|
|
||||||
// i2p::util::http::url u_2("http://user:password@site.com/asdasd?qqqqqqqqqqqqqq");
|
|
||||||
// i2p::util::http::url u_3("http://user:@site.com/asdasd?qqqqqqqqqqqqq");
|
|
||||||
// i2p::util::http::url u_4("http://user@site.com/asdasd?qqqqqqqqqqqq");
|
|
||||||
// i2p::util::http::url u_5("http://@site.com:800/asdasd?qqqqqqqqqqqq");
|
|
||||||
// i2p::util::http::url u_6("http://@site.com:err_port/asdasd?qqqqqqqqqqqq");
|
|
||||||
// i2p::util::http::url u_7("http://user:password@site.com:err_port/asdasd?qqqqqqqqqqqq");
|
|
||||||
//}
|
|
||||||
void url::parse(const std::string& url_s)
|
|
||||||
{
|
|
||||||
const std::string prot_end("://");
|
|
||||||
std::string::const_iterator prot_i = search(url_s.begin(), url_s.end(),
|
|
||||||
prot_end.begin(), prot_end.end());
|
|
||||||
protocol_.reserve(distance(url_s.begin(), prot_i));
|
|
||||||
transform(url_s.begin(), prot_i,
|
|
||||||
back_inserter(protocol_),
|
|
||||||
std::ptr_fun<int,int>(tolower)); // protocol is icase
|
|
||||||
if( prot_i == url_s.end() )
|
|
||||||
return;
|
|
||||||
advance(prot_i, prot_end.length());
|
|
||||||
std::string::const_iterator path_i = find(prot_i, url_s.end(), '/');
|
|
||||||
host_.reserve(distance(prot_i, path_i));
|
|
||||||
transform(prot_i, path_i,
|
|
||||||
back_inserter(host_),
|
|
||||||
std::ptr_fun<int,int>(tolower)); // host is icase
|
|
||||||
|
|
||||||
// parse user/password
|
|
||||||
auto user_pass_i = find(host_.begin(), host_.end(), '@');
|
|
||||||
if (user_pass_i != host_.end())
|
|
||||||
{
|
|
||||||
std::string user_pass = std::string(host_.begin(), user_pass_i);
|
|
||||||
auto pass_i = find(user_pass.begin(), user_pass.end(), ':');
|
|
||||||
if (pass_i != user_pass.end())
|
|
||||||
{
|
|
||||||
user_ = std::string(user_pass.begin(), pass_i);
|
|
||||||
pass_ = std::string(pass_i + 1, user_pass.end());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
user_ = user_pass;
|
|
||||||
|
|
||||||
host_.assign(user_pass_i + 1, host_.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse port
|
|
||||||
auto port_i = find(host_.begin(), host_.end(), ':');
|
|
||||||
if (port_i != host_.end())
|
|
||||||
{
|
|
||||||
portstr_ = std::string(port_i + 1, host_.end());
|
|
||||||
host_.assign(host_.begin(), port_i);
|
|
||||||
try{
|
|
||||||
port_ = boost::lexical_cast<decltype(port_)>(portstr_);
|
|
||||||
}
|
|
||||||
catch (std::exception e) {
|
|
||||||
port_ = 80;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string::const_iterator query_i = find(path_i, url_s.end(), '?');
|
|
||||||
path_.assign(path_i, query_i);
|
|
||||||
if( query_i != url_s.end() )
|
|
||||||
++query_i;
|
|
||||||
query_.assign(query_i, url_s.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string urlDecode(const std::string& data)
|
|
||||||
{
|
|
||||||
std::string res(data);
|
|
||||||
for (size_t pos = res.find('%'); pos != std::string::npos; pos = res.find('%',pos+1))
|
|
||||||
{
|
|
||||||
char c = strtol(res.substr(pos+1,2).c_str(), NULL, 16);
|
|
||||||
res.replace(pos,3,1,c);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace net
|
namespace net
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
29
util.h
29
util.h
|
@ -22,7 +22,6 @@ namespace i2p
|
||||||
{
|
{
|
||||||
namespace util
|
namespace util
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
wrapper arround boost::lexical_cast that "never" fails
|
wrapper arround boost::lexical_cast that "never" fails
|
||||||
*/
|
*/
|
||||||
|
@ -35,34 +34,6 @@ namespace util
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace http
|
|
||||||
{
|
|
||||||
// in (lower case)
|
|
||||||
const char ETAG[] = "etag"; // ETag
|
|
||||||
const char LAST_MODIFIED[] = "last-modified"; // Last-Modified
|
|
||||||
const char TRANSFER_ENCODING[] = "transfer-encoding"; // Transfer-Encoding
|
|
||||||
const char CONTENT_ENCODING[] = "content-encoding"; // Content-Encoding
|
|
||||||
// out
|
|
||||||
const char IF_NONE_MATCH[] = "If-None-Match";
|
|
||||||
const char IF_MODIFIED_SINCE[] = "If-Modified-Since";
|
|
||||||
|
|
||||||
std::string GetHttpContent (std::istream& response);
|
|
||||||
void MergeChunkedResponse (std::istream& response, std::ostream& merged);
|
|
||||||
std::string urlDecode(const std::string& data);
|
|
||||||
|
|
||||||
struct url {
|
|
||||||
url(const std::string& url_s); // omitted copy, ==, accessors, ...
|
|
||||||
private:
|
|
||||||
void parse(const std::string& url_s);
|
|
||||||
public:
|
|
||||||
std::string protocol_, host_, path_, query_;
|
|
||||||
std::string portstr_;
|
|
||||||
unsigned int port_;
|
|
||||||
std::string user_;
|
|
||||||
std::string pass_;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace net
|
namespace net
|
||||||
{
|
{
|
||||||
int GetMTU (const boost::asio::ip::address& localAddress);
|
int GetMTU (const boost::asio::ip::address& localAddress);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c)
|
#define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c)
|
||||||
|
|
||||||
#define I2PD_VERSION_MAJOR 2
|
#define I2PD_VERSION_MAJOR 2
|
||||||
#define I2PD_VERSION_MINOR 8
|
#define I2PD_VERSION_MINOR 9
|
||||||
#define I2PD_VERSION_MICRO 0
|
#define I2PD_VERSION_MICRO 0
|
||||||
#define I2PD_VERSION_PATCH 0
|
#define I2PD_VERSION_PATCH 0
|
||||||
#define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO)
|
#define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO)
|
||||||
|
|
Loading…
Add table
Reference in a new issue