mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-03-13 08:11:11 +00:00
check and update addressbook subscriptions
This commit is contained in:
parent
3f314d8355
commit
7b5e8a9661
@ -7,6 +7,7 @@
|
|||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include <cryptopp/osrng.h>
|
||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "Identity.h"
|
#include "Identity.h"
|
||||||
@ -151,12 +152,12 @@ namespace client
|
|||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
AddressBook::AddressBook (): m_IsLoaded (false), m_IsDownloading (false),
|
AddressBook::AddressBook (): m_IsLoaded (false), m_IsDownloading (false),
|
||||||
m_DefaultSubscription (nullptr)
|
m_DefaultSubscription (nullptr), m_SubscriptionsUpdateTimer (nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
AddressBook::~AddressBook ()
|
AddressBook::~AddressBook ()
|
||||||
{
|
{
|
||||||
if (m_IsDownloading)
|
if (m_IsDownloading)
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "Subscription is downloading. Waiting for temination...");
|
LogPrint (eLogInfo, "Subscription is downloading. Waiting for temination...");
|
||||||
@ -179,7 +180,7 @@ namespace client
|
|||||||
delete m_DefaultSubscription;
|
delete m_DefaultSubscription;
|
||||||
for (auto it: m_Subscriptions)
|
for (auto it: m_Subscriptions)
|
||||||
delete it;
|
delete it;
|
||||||
|
delete m_SubscriptionsUpdateTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddressBookStorage * AddressBook::CreateStorage ()
|
AddressBookStorage * AddressBook::CreateStorage ()
|
||||||
@ -339,11 +340,71 @@ namespace client
|
|||||||
m_Subscriptions.push_back (new AddressBookSubscription (*this, s));
|
m_Subscriptions.push_back (new AddressBookSubscription (*this, s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogWarning, "subscriptions.txt not found");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Subscriptions already loaded");
|
LogPrint (eLogError, "Subscriptions already loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddressBook::DownloadComplete (bool success)
|
||||||
|
{
|
||||||
|
m_IsDownloading = false;
|
||||||
|
m_SubscriptionsUpdateTimer->expires_from_now (boost::posix_time::minutes(
|
||||||
|
success ? CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT : CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT));
|
||||||
|
m_SubscriptionsUpdateTimer->async_wait (std::bind (&AddressBook::HandleSubscriptionsUpdateTimer,
|
||||||
|
this, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddressBook::StartSubscriptions ()
|
||||||
|
{
|
||||||
|
LoadSubscriptions ();
|
||||||
|
if (!m_Subscriptions.size ()) return;
|
||||||
|
|
||||||
|
auto dest = i2p::client::context.GetSharedLocalDestination ();
|
||||||
|
if (dest)
|
||||||
|
{
|
||||||
|
m_SubscriptionsUpdateTimer = new boost::asio::deadline_timer (dest->GetService ());
|
||||||
|
m_SubscriptionsUpdateTimer->expires_from_now (boost::posix_time::minutes(INITIAL_SUBSCRIPTION_UPDATE_TIMEOUT));
|
||||||
|
m_SubscriptionsUpdateTimer->async_wait (std::bind (&AddressBook::HandleSubscriptionsUpdateTimer,
|
||||||
|
this, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "Can't start subscriptions: missing shared local destination");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddressBook::StopSubscriptions ()
|
||||||
|
{
|
||||||
|
if (m_SubscriptionsUpdateTimer)
|
||||||
|
m_SubscriptionsUpdateTimer->cancel ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddressBook::HandleSubscriptionsUpdateTimer (const boost::system::error_code& ecode)
|
||||||
|
{
|
||||||
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
|
{
|
||||||
|
auto dest = i2p::client::context.GetSharedLocalDestination ();
|
||||||
|
if (!dest) return;
|
||||||
|
if (m_IsLoaded && !m_IsDownloading && dest->IsReady ())
|
||||||
|
{
|
||||||
|
// pick random subscription
|
||||||
|
CryptoPP::AutoSeededRandomPool rnd;
|
||||||
|
auto ind = rnd.GenerateWord32 (0, m_Subscriptions.size() - 1);
|
||||||
|
m_IsDownloading = true;
|
||||||
|
m_Subscriptions[ind]->CheckSubscription ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!m_IsLoaded)
|
||||||
|
LoadHosts ();
|
||||||
|
// try it again later
|
||||||
|
m_SubscriptionsUpdateTimer->expires_from_now (boost::posix_time::minutes(INITIAL_SUBSCRIPTION_RETRY_TIMEOUT));
|
||||||
|
m_SubscriptionsUpdateTimer->async_wait (std::bind (&AddressBook::HandleSubscriptionsUpdateTimer,
|
||||||
|
this, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AddressBookSubscription::AddressBookSubscription (AddressBook& book, const std::string& link):
|
AddressBookSubscription::AddressBookSubscription (AddressBook& book, const std::string& link):
|
||||||
m_Book (book), m_Link (link)
|
m_Book (book), m_Link (link)
|
||||||
{
|
{
|
||||||
@ -358,6 +419,7 @@ namespace client
|
|||||||
void AddressBookSubscription::Request ()
|
void AddressBookSubscription::Request ()
|
||||||
{
|
{
|
||||||
// must be run in separate thread
|
// must be run in separate thread
|
||||||
|
bool success = false;
|
||||||
i2p::util::http::url u (m_Link);
|
i2p::util::http::url u (m_Link);
|
||||||
i2p::data::IdentHash ident;
|
i2p::data::IdentHash ident;
|
||||||
if (m_Book.GetIdentHash (u.host_, ident))
|
if (m_Book.GetIdentHash (u.host_, ident))
|
||||||
@ -433,6 +495,7 @@ namespace client
|
|||||||
}
|
}
|
||||||
if (!response.eof ())
|
if (!response.eof ())
|
||||||
{
|
{
|
||||||
|
success = true;
|
||||||
if (!isChunked)
|
if (!isChunked)
|
||||||
m_Book.LoadHostsFromStream (response);
|
m_Book.LoadHostsFromStream (response);
|
||||||
else
|
else
|
||||||
@ -452,7 +515,7 @@ namespace client
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Can't resolve ", u.host_);
|
LogPrint (eLogError, "Can't resolve ", u.host_);
|
||||||
m_Book.SetIsDownloading (false);
|
m_Book.DownloadComplete (success);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,10 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <list>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <boost/asio.hpp>
|
||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "Identity.h"
|
#include "Identity.h"
|
||||||
@ -17,7 +18,11 @@ namespace i2p
|
|||||||
namespace client
|
namespace client
|
||||||
{
|
{
|
||||||
const char DEFAULT_SUBSCRIPTION_ADDRESS[] = "http://udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p/hosts.txt";
|
const char DEFAULT_SUBSCRIPTION_ADDRESS[] = "http://udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p/hosts.txt";
|
||||||
|
const int INITIAL_SUBSCRIPTION_UPDATE_TIMEOUT = 3; // in minutes
|
||||||
|
const int INITIAL_SUBSCRIPTION_RETRY_TIMEOUT = 1; // in minutes
|
||||||
|
const int CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT = 240; // in minutes
|
||||||
|
const int CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT = 5; // in minutes
|
||||||
|
|
||||||
class AddressBookStorage // interface for storage
|
class AddressBookStorage // interface for storage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -44,8 +49,10 @@ namespace client
|
|||||||
void InsertAddress (const std::string& address, const std::string& base64); // for jump service
|
void InsertAddress (const std::string& address, const std::string& base64); // for jump service
|
||||||
void InsertAddress (const i2p::data::IdentityEx& address);
|
void InsertAddress (const i2p::data::IdentityEx& address);
|
||||||
|
|
||||||
|
void StartSubscriptions ();
|
||||||
|
void StopSubscriptions ();
|
||||||
void LoadHostsFromStream (std::istream& f);
|
void LoadHostsFromStream (std::istream& f);
|
||||||
void SetIsDownloading (bool isDownloading) { m_IsDownloading = isDownloading; };
|
void DownloadComplete (bool success);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -53,14 +60,17 @@ namespace client
|
|||||||
void LoadHosts ();
|
void LoadHosts ();
|
||||||
void LoadSubscriptions ();
|
void LoadSubscriptions ();
|
||||||
|
|
||||||
|
void HandleSubscriptionsUpdateTimer (const boost::system::error_code& ecode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::mutex m_AddressBookMutex;
|
std::mutex m_AddressBookMutex;
|
||||||
std::map<std::string, i2p::data::IdentHash> m_Addresses;
|
std::map<std::string, i2p::data::IdentHash> m_Addresses;
|
||||||
AddressBookStorage * m_Storage;
|
AddressBookStorage * m_Storage;
|
||||||
volatile bool m_IsLoaded, m_IsDownloading;
|
volatile bool m_IsLoaded, m_IsDownloading;
|
||||||
std::list<AddressBookSubscription *> m_Subscriptions;
|
std::vector<AddressBookSubscription *> m_Subscriptions;
|
||||||
AddressBookSubscription * m_DefaultSubscription; // in case if we don't know any addresses yet
|
AddressBookSubscription * m_DefaultSubscription; // in case if we don't know any addresses yet
|
||||||
|
boost::asio::deadline_timer * m_SubscriptionsUpdateTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AddressBookSubscription
|
class AddressBookSubscription
|
||||||
|
@ -77,10 +77,12 @@ namespace client
|
|||||||
m_BOBCommandChannel->Start ();
|
m_BOBCommandChannel->Start ();
|
||||||
LogPrint("BOB command channel started");
|
LogPrint("BOB command channel started");
|
||||||
}
|
}
|
||||||
|
m_AddressBook.StartSubscriptions ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientContext::Stop ()
|
void ClientContext::Stop ()
|
||||||
{
|
{
|
||||||
|
m_AddressBook.StopSubscriptions ();
|
||||||
m_HttpProxy->Stop();
|
m_HttpProxy->Stop();
|
||||||
delete m_HttpProxy;
|
delete m_HttpProxy;
|
||||||
m_HttpProxy = nullptr;
|
m_HttpProxy = nullptr;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user