address resolver

This commit is contained in:
orignal 2016-03-24 14:48:07 -04:00
parent bc5ff37e37
commit 2e5c56205c
2 changed files with 103 additions and 4 deletions

View File

@ -330,8 +330,7 @@ namespace client
LoadHostsFromStream (f); LoadHostsFromStream (f);
m_IsLoaded = true; m_IsLoaded = true;
} }
// load local LoadLocal ();
m_Storage->LoadLocal (m_Addresses);
} }
void AddressBook::LoadHostsFromStream (std::istream& f) void AddressBook::LoadHostsFromStream (std::istream& f)
@ -395,6 +394,40 @@ namespace client
LogPrint (eLogError, "Addressbook: subscriptions already loaded"); LogPrint (eLogError, "Addressbook: subscriptions already loaded");
} }
void AddressBook::LoadLocal ()
{
std::map<std::string, i2p::data::IdentHash> localAddresses;
m_Storage->LoadLocal (localAddresses);
for (auto it: localAddresses)
{
auto dot = it.first.find ('.');
if (dot != std::string::npos)
{
auto domain = it.first.substr (dot + 1);
auto it1 = m_Addresses.find (domain); // find domain in our addressbook
if (it1 != m_Addresses.end ())
{
auto dest = context.FindLocalDestination (it1->second);
if (dest)
{
// address is ours
std::shared_ptr<AddressResolver> resolver;
auto it2 = m_Resolvers.find (it1->second);
if (it2 != m_Resolvers.end ())
resolver = it2->second; // resolver exists
else
{
// create new resolver
resolver = std::make_shared<AddressResolver>(dest);
m_Resolvers.insert (std::make_pair(it1->second, resolver));
}
resolver->AddAddress (it.first, it.second);
}
}
}
}
}
bool AddressBook::GetEtag (const i2p::data::IdentHash& subscription, std::string& etag, std::string& lastModified) bool AddressBook::GetEtag (const i2p::data::IdentHash& subscription, std::string& etag, std::string& lastModified)
{ {
if (m_Storage) if (m_Storage)
@ -653,6 +686,50 @@ namespace client
m_Book.LoadHostsFromStream (s); m_Book.LoadHostsFromStream (s);
return true; return true;
} }
AddressResolver::AddressResolver (std::shared_ptr<ClientDestination> destination):
m_LocalDestination (destination)
{
if (m_LocalDestination)
{
auto datagram = m_LocalDestination->GetDatagramDestination ();
if (!datagram)
datagram = m_LocalDestination->CreateDatagramDestination ();
datagram->SetReceiver (std::bind (&AddressResolver::HandleRequest, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5),
ADDRESS_RESOLVER_DATAGRAM_PORT);
}
}
void AddressResolver::HandleRequest (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
{
if (len < 9 || len < buf[8] + 9U)
{
LogPrint (eLogError, "Address request is too short ", len);
return;
}
// read requested address
uint8_t l = buf[8];
char address[255];
memcpy (address, buf + 9, l);
address[l] = 0;
// send response
uint8_t response[40];
memset (response, 0, 4); // reserved
memcpy (response + 4, buf + 4, 4); // nonce
auto it = m_LocalAddresses.find (address); // address lookup
if (it != m_LocalAddresses.end ())
memcpy (response + 8, it->second, 32); // ident
else
memset (response + 8, 0, 32); // not found
m_LocalDestination->GetDatagramDestination ()->SendDatagramTo (response, 40, from.GetIdentHash (), toPort, fromPort);
}
void AddressResolver::AddAddress (const std::string& name, const i2p::data::IdentHash& ident)
{
m_LocalAddresses[name] = ident;
}
} }
} }

View File

@ -12,6 +12,7 @@
#include "Base.h" #include "Base.h"
#include "Identity.h" #include "Identity.h"
#include "Log.h" #include "Log.h"
#include "Destination.h"
namespace i2p namespace i2p
{ {
@ -23,7 +24,7 @@ namespace client
const int CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT = 720; // in minutes (12 hours) const int CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT = 720; // in minutes (12 hours)
const int CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT = 5; // in minutes const int CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT = 5; // in minutes
const int SUBSCRIPTION_REQUEST_TIMEOUT = 60; //in second const int SUBSCRIPTION_REQUEST_TIMEOUT = 60; //in second
inline std::string GetB32Address(const i2p::data::IdentHash& ident) { return ident.ToBase32().append(".b32.i2p"); } inline std::string GetB32Address(const i2p::data::IdentHash& ident) { return ident.ToBase32().append(".b32.i2p"); }
class AddressBookStorage // interface for storage class AddressBookStorage // interface for storage
@ -45,6 +46,7 @@ namespace client
}; };
class AddressBookSubscription; class AddressBookSubscription;
class AddressResolver;
class AddressBook class AddressBook
{ {
public: public:
@ -74,13 +76,15 @@ namespace client
void LoadHosts (); void LoadHosts ();
void LoadSubscriptions (); void LoadSubscriptions ();
void LoadLocal ();
void HandleSubscriptionsUpdateTimer (const boost::system::error_code& ecode); 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, m_LocalAddresses; std::map<std::string, i2p::data::IdentHash> m_Addresses;
std::map<i2p::data::IdentHash, std::shared_ptr<AddressResolver> > m_Resolvers; // local destination->resolver
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<AddressBookSubscription *> m_Subscriptions;
@ -106,6 +110,24 @@ namespace client
std::string m_Link, m_Etag, m_LastModified; std::string m_Link, m_Etag, m_LastModified;
// m_Etag must be surrounded by "" // m_Etag must be surrounded by ""
}; };
const uint16_t ADDRESS_RESOLVER_DATAGRAM_PORT = 53;
class AddressResolver
{
public:
AddressResolver (std::shared_ptr<ClientDestination> destination);
void AddAddress (const std::string& name, const i2p::data::IdentHash& ident);
private:
void HandleRequest (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
private:
std::shared_ptr<ClientDestination> m_LocalDestination;
std::map<std::string, i2p::data::IdentHash> m_LocalAddresses;
};
} }
} }