* lns exits

* try appeasing the clang

* clean up lambda
pull/1410/head
Jeff 4 years ago committed by GitHub
parent df36ed953d
commit 22acf0a537
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -13,6 +13,8 @@
#include <util/mem.hpp>
#include <util/str.hpp>
#include <service/name.hpp>
#include <cstdlib>
#include <fstream>
#include <ios>
@ -436,6 +438,13 @@ namespace llarp
{
arg = arg.substr(0, pos);
}
if (service::NameIsValid(arg))
{
m_LNSExitMap.Insert(range, arg);
return;
}
if (not exit.FromString(arg))
{
throw std::invalid_argument(stringify("[network]:exit-node bad address: ", arg));
@ -468,6 +477,13 @@ namespace llarp
}
const auto exit_str = arg.substr(0, pos);
auth.token = arg.substr(pos + 1);
if (service::NameIsValid(exit_str))
{
m_LNSExitAuths.emplace(exit_str, auth);
return;
}
if (not exit.FromString(exit_str))
{
throw std::invalid_argument("[network]:exit-auth invalid exit address");

@ -84,7 +84,11 @@ namespace llarp
bool m_AllowExit = false;
std::set<RouterID> m_snodeBlacklist;
net::IPRangeMap<service::Address> m_ExitMap;
net::IPRangeMap<std::string> m_LNSExitMap;
std::unordered_map<service::Address, service::AuthInfo, service::Address::Hash> m_ExitAuths;
std::unordered_map<std::string, service::AuthInfo> m_LNSExitAuths;
std::unordered_map<huint128_t, service::Address> m_mapAddrs;
service::AuthType m_AuthType = service::AuthType::eAuthTypeNone;

@ -78,6 +78,18 @@ namespace llarp
return transformed;
}
// get a value for this exact range
std::optional<Value_t>
GetExact(Range_t range) const
{
for (const auto& [r, value] : m_Entries)
{
if (r == range)
return value;
}
return std::nullopt;
}
/// return a set of all values who's range contains this IP
std::set<Value_t>
FindAll(const IP_t& addr) const

@ -7,6 +7,7 @@
#include <net/route.hpp>
#include <service/context.hpp>
#include <service/auth.hpp>
#include <service/name.hpp>
namespace llarp::rpc
{
@ -123,18 +124,27 @@ namespace llarp::rpc
return;
}
std::optional<service::Address> exit;
std::optional<std::string> lnsExit;
IPRange range;
bool map = true;
const auto exit_itr = obj.find("exit");
if (exit_itr != obj.end())
{
service::Address addr;
if (not addr.FromString(exit_itr->get<std::string>()))
const auto exit_str = exit_itr->get<std::string>();
if (service::NameIsValid(exit_str))
{
lnsExit = exit_str;
}
else if (not addr.FromString(exit_str))
{
reply(CreateJSONError("invalid exit address"));
return;
}
exit = addr;
else
{
exit = addr;
}
}
const auto unmap_itr = obj.find("unmap");
@ -166,59 +176,88 @@ namespace llarp::rpc
{
endpoint = endpoint_itr->get<std::string>();
}
LogicCall(r->logic(), [map, exit, range, token, endpoint, r, reply]() mutable {
auto ep = r->hiddenServiceContext().GetEndpointByName(endpoint);
if (ep == nullptr)
{
reply(CreateJSONError("no endpoint with name " + endpoint));
return;
}
if (map and exit.has_value())
{
ep->MapExitRange(range, *exit);
if (token.has_value())
{
ep->SetAuthInfoForEndpoint(*exit, service::AuthInfo{*token});
}
ep->EnsurePathToService(
*exit,
[reply, ep, r](auto, service::OutboundContext* ctx) {
if (ctx == nullptr)
LogicCall(
r->logic(), [map, exit, lnsExit, range, token, endpoint, r, reply]() mutable {
auto ep = r->hiddenServiceContext().GetEndpointByName(endpoint);
if (ep == nullptr)
{
reply(CreateJSONError("no endpoint with name " + endpoint));
return;
}
if (map and (exit.has_value() or lnsExit.has_value()))
{
auto mapExit = [=](service::Address addr) mutable {
ep->MapExitRange(range, addr);
if (token.has_value())
{
reply(CreateJSONError("could not find exit"));
return;
ep->SetAuthInfoForEndpoint(*exit, service::AuthInfo{*token});
}
r->ForEachPeer(
[r](auto session, auto) mutable {
const auto ip = session->GetRemoteEndpoint().toIP();
r->routePoker().AddRoute(ip);
ep->EnsurePathToService(
addr,
[reply, ep, r](auto, service::OutboundContext* ctx) {
if (ctx == nullptr)
{
reply(CreateJSONError("could not find exit"));
return;
}
r->ForEachPeer(
[r](auto session, auto) mutable {
const auto ip = session->GetRemoteEndpoint().toIP();
r->routePoker().AddRoute(ip);
},
false);
net::AddDefaultRouteViaInterface(ep->GetIfName());
reply(CreateJSONResponse("OK"));
},
false);
net::AddDefaultRouteViaInterface(ep->GetIfName());
reply(CreateJSONResponse("OK"));
},
5s);
return;
}
else if (map and not exit.has_value())
{
reply(CreateJSONError("no exit address provided"));
return;
}
else if (not map)
{
net::DelDefaultRouteViaInterface(ep->GetIfName());
5s);
};
if (exit.has_value())
{
mapExit(*exit);
}
else if (lnsExit.has_value())
{
ep->LookupNameAsync(*lnsExit, [reply, mapExit](auto maybe) mutable {
if (not maybe.has_value())
{
reply(CreateJSONError("we could not find an exit with that name"));
return;
}
if (maybe->IsZero())
{
reply(CreateJSONError("lokinet exit does not exist"));
return;
}
mapExit(*maybe);
});
}
else
{
reply(
CreateJSONError("WTF inconsistent request, no exit address or lns "
"name provided?"));
}
return;
}
else if (map and not exit.has_value())
{
reply(CreateJSONError("no exit address provided"));
return;
}
else if (not map)
{
net::DelDefaultRouteViaInterface(ep->GetIfName());
r->ForEachPeer(
[r](auto session, auto) mutable {
const auto ip = session->GetRemoteEndpoint().toIP();
r->routePoker().DelRoute(ip);
},
false);
ep->UnmapExitRange(range);
}
reply(CreateJSONResponse("OK"));
});
r->ForEachPeer(
[r](auto session, auto) mutable {
const auto ip = session->GetRemoteEndpoint().toIP();
r->routePoker().DelRoute(ip);
},
false);
ep->UnmapExitRange(range);
}
reply(CreateJSONResponse("OK"));
});
});
})
.add_request_command("config", [&](lokimq::Message& msg) {

@ -65,6 +65,14 @@ namespace llarp
SetAuthInfoForEndpoint(exit, auth);
}
conf.m_LNSExitMap.ForEachEntry([&](const IPRange& range, const std::string& name) {
std::optional<AuthInfo> auth;
const auto itr = conf.m_LNSExitAuths.find(name);
if (itr != conf.m_LNSExitAuths.end())
auth = itr->second;
m_StartupLNSMappings[name] = std::make_pair(range, auth);
});
return m_state->Configure(conf);
}
@ -227,6 +235,29 @@ namespace llarp
now, m_state->m_RemoteSessions, m_state->m_DeadSessions, Sessions());
// expire convotags
EndpointUtil::ExpireConvoSessions(now, Sessions());
if (NumInStatus(path::ePathEstablished) > 1)
{
for (const auto& item : m_StartupLNSMappings)
{
LookupNameAsync(
item.first, [name = item.first, info = item.second, this](auto maybe_addr) {
if (maybe_addr.has_value())
{
const auto maybe_range = info.first;
const auto maybe_auth = info.second;
m_StartupLNSMappings.erase(name);
if (maybe_range.has_value())
m_ExitMap.Insert(*maybe_range, *maybe_addr);
if (maybe_auth.has_value())
SetAuthInfoForEndpoint(*maybe_addr, *maybe_auth);
}
});
}
}
}
bool
@ -774,6 +805,12 @@ namespace llarp
bool
Endpoint::HasExit() const
{
for (const auto& [name, info] : m_StartupLNSMappings)
{
if (info.first.has_value())
return true;
}
return not m_ExitMap.Empty();
}
@ -787,8 +824,10 @@ namespace llarp
handler(maybe);
return true;
}
LogInfo(Name(), " looking up LNS name: ", name);
auto path = PickRandomEstablishedPath();
if (path == nullptr)
return false;
LogInfo(Name(), " looking up LNS name: ", name);
auto job = new LookupNameJob(this, GenTXID(), name, handler);
return job->SendRequestViaPath(path, m_router);
}

@ -470,6 +470,10 @@ namespace llarp
std::shared_ptr<IAuthPolicy> m_AuthPolicy;
std::unordered_map<Address, AuthInfo, Address::Hash> m_RemoteAuthInfos;
/// (lns name, optional exit range, optional auth info) for looking up on startup
std::unordered_map<std::string, std::pair<std::optional<IPRange>, std::optional<AuthInfo>>>
m_StartupLNSMappings;
RecvPacketQueue_t m_InboundTrafficQueue;
SendMessageQueue_t m_SendQueue;

Loading…
Cancel
Save