lokinet/llarp/service/context.cpp

253 lines
6.8 KiB
C++
Raw Normal View History

#include <llarp/handlers/tun.hpp>
#include <llarp/service/context.hpp>
2018-09-21 12:53:20 +00:00
#include <llarp/service/endpoint.hpp>
namespace llarp
{
namespace service
{
Context::Context(llarp_router *r) : m_Router(r)
{
}
Context::~Context()
{
auto itr = m_Endpoints.begin();
while(itr != m_Endpoints.end())
{
itr = m_Endpoints.erase(itr);
}
}
void
Context::Tick()
{
2018-07-18 22:50:05 +00:00
auto now = llarp_time_now_ms();
auto itr = m_Endpoints.begin();
while(itr != m_Endpoints.end())
{
2018-07-18 22:50:05 +00:00
itr->second->Tick(now);
++itr;
}
}
bool
Context::hasEndpoints()
{
return m_Endpoints.size() ? true : false;
}
2018-09-22 10:23:23 +00:00
llarp::service::Endpoint *
Context::getFirstEndpoint()
{
2018-09-22 10:23:23 +00:00
if(!m_Endpoints.size())
{
llarp::LogError("No endpoints found");
return nullptr;
}
2018-09-22 10:23:23 +00:00
auto firstEndpoint = m_Endpoints.begin();
auto *uniqueEndpoint = &firstEndpoint->second;
2018-09-22 10:23:23 +00:00
return uniqueEndpoint->get();
}
bool
Context::iterate(struct endpoint_iter &i)
{
if(!m_Endpoints.size())
{
llarp::LogError("No endpoints found");
return false;
}
i.index = 0;
// llarp::util::Lock lock(access);
auto itr = m_Endpoints.begin();
while(itr != m_Endpoints.end())
{
i.endpoint = itr->second.get();
i.visit(&i);
// advance
i.index++;
itr++;
}
return true;
}
2018-09-22 10:23:23 +00:00
llarp::handlers::TunEndpoint *
Context::getFirstTun()
{
llarp::service::Endpoint *endpointer = this->getFirstEndpoint();
if(!endpointer)
{
return nullptr;
}
llarp::handlers::TunEndpoint *tunEndpoint =
dynamic_cast< llarp::handlers::TunEndpoint * >(endpointer);
return tunEndpoint;
}
llarp_tun_io *
Context::getRange()
{
llarp::handlers::TunEndpoint *tunEndpoint = this->getFirstTun();
2018-09-22 10:23:23 +00:00
if(!tunEndpoint)
{
llarp::LogError("No tunnel endpoint found");
return nullptr;
}
return &tunEndpoint->tunif;
}
2018-09-21 12:53:20 +00:00
bool
Context::Prefetch(const llarp::service::Address &addr)
{
llarp::handlers::TunEndpoint *tunEndpoint = this->getFirstTun();
2018-09-22 10:23:23 +00:00
if(!tunEndpoint)
2018-09-21 12:53:20 +00:00
{
llarp::LogError("No tunnel endpoint found");
return false;
}
2018-09-22 10:23:23 +00:00
// HiddenServiceAddresslookup *lookup = new
// HiddenServiceEndpoint(tunEndpoint, callback, addr,
// tunEndpoint->GenTXID());
return tunEndpoint->EnsurePathToService(
addr, [](Address addr, void *ctx) {}, 10000);
2018-09-21 12:53:20 +00:00
}
2018-09-20 10:05:42 +00:00
bool
Context::MapAddress(const llarp::service::Address &addr, uint32_t ip)
{
2018-09-22 10:23:23 +00:00
if(!m_Endpoints.size())
2018-09-20 10:05:42 +00:00
{
llarp::LogError("No endpoints found");
return false;
}
2018-09-22 10:23:23 +00:00
auto firstEndpoint = m_Endpoints.begin();
auto *uniqueEndpoint = &firstEndpoint->second;
2018-09-20 10:05:42 +00:00
llarp::service::Endpoint *endpointer = uniqueEndpoint->get();
2018-09-22 10:23:23 +00:00
llarp::handlers::TunEndpoint *tunEndpoint =
dynamic_cast< llarp::handlers::TunEndpoint * >(endpointer);
if(!tunEndpoint)
2018-09-20 10:05:42 +00:00
{
llarp::LogError("No tunnel endpoint found");
return false;
}
return tunEndpoint->MapAddress(addr, ip);
}
bool
MappAddressAllIter(struct Context::endpoint_iter *endpointCfg)
{
Context::mapAddressAll_context *context =
(Context::mapAddressAll_context *)endpointCfg->user;
llarp::handlers::TunEndpoint *tunEndpoint =
(llarp::handlers::TunEndpoint *)endpointCfg->endpoint;
if(!tunEndpoint)
{
llarp::LogError("No tunnel endpoint found");
return false;
}
return tunEndpoint->MapAddress(context->serviceAddr,
context->localPrivateIpAddr.tohl());
}
bool
Context::MapAddressAll(const llarp::service::Address &addr,
llarp::Addr &localPrivateIpAddr)
{
struct Context::mapAddressAll_context context;
context.serviceAddr = addr;
context.localPrivateIpAddr = localPrivateIpAddr;
struct Context::endpoint_iter i;
i.user = &context;
i.index = 0;
i.visit = &MappAddressAllIter;
return this->iterate(i);
}
bool
Context::AddDefaultEndpoint(const std::string &ifaddr,
const std::string &ifname)
{
return AddEndpoint(
{"default",
{{"type", "tun"}, {"ifaddr", ifaddr}, {"ifname", ifname}}});
}
bool
Context::AddEndpoint(const Config::section_t &conf)
{
{
2018-08-23 14:07:53 +00:00
auto itr = m_Endpoints.find(conf.first);
if(itr != m_Endpoints.end())
{
llarp::LogError("cannot add hidden service with duplicate name: ",
conf.first);
return false;
}
}
2018-08-23 14:07:53 +00:00
// extract type
std::string endpointType = "tun";
for(const auto &option : conf.second)
{
if(option.first == "type")
endpointType = option.second;
}
std::unique_ptr< llarp::service::Endpoint > service;
static std::map< std::string,
std::function< llarp::service::Endpoint *(
const std::string &, llarp_router *) > >
endpointConstructors = {
{"tun",
[](const std::string &nick,
llarp_router *r) -> llarp::service::Endpoint * {
return new llarp::handlers::TunEndpoint(nick, r);
}},
{"null",
[](const std::string &nick,
llarp_router *r) -> llarp::service::Endpoint * {
return new llarp::service::Endpoint(nick, r);
}}};
2018-08-23 14:07:53 +00:00
{
// detect type
auto itr = endpointConstructors.find(endpointType);
if(itr == endpointConstructors.end())
{
llarp::LogError("no such endpoint type: ", endpointType);
return false;
}
// construct
service = std::unique_ptr< llarp::service::Endpoint >(
itr->second(conf.first, m_Router));
}
// configure
for(const auto &option : conf.second)
{
auto &k = option.first;
2018-08-23 14:07:53 +00:00
if(k == "type")
continue;
auto &v = option.second;
if(!service->SetOption(k, v))
{
llarp::LogError("failed to set ", k, "=", v,
" for hidden service endpoint ", conf.first);
return false;
}
}
2018-08-23 14:07:53 +00:00
// start
if(service->Start())
{
2018-07-29 23:29:36 +00:00
llarp::LogInfo("added hidden service endpoint ", service->Name());
m_Endpoints.insert(std::make_pair(conf.first, std::move(service)));
return true;
}
llarp::LogError("failed to start hidden service endpoint ", conf.first);
return false;
}
2018-07-17 04:37:50 +00:00
} // namespace service
} // namespace llarp