You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lokinet/llarp/exit/session.cpp

141 lines
4.1 KiB
C++

#include <llarp/exit/session.hpp>
#include "router.hpp"
namespace llarp
{
namespace exit
{
BaseSession::BaseSession(const llarp::RouterID& router,
std::function< bool(llarp_buffer_t) > writepkt,
llarp_router* r, size_t numpaths, size_t hoplen)
: llarp::path::Builder(r, r->dht, numpaths, hoplen)
, m_ExitRouter(router)
, m_WritePacket(writepkt)
{
r->crypto.identity_keygen(m_ExitIdentity);
}
BaseSession::~BaseSession()
{
}
bool
BaseSession::ShouldBuildMore(llarp_time_t now) const
{
const size_t expect = (1 + (m_NumPaths / 2));
if(NumPathsExistingAt(now + (10 * 1000)) < expect)
return true;
if(AvailablePaths(llarp::path::ePathRoleExit) < expect)
return true;
return false;
}
bool
BaseSession::SelectHop(llarp_nodedb* db, const RouterContact& prev,
RouterContact& cur, size_t hop,
llarp::path::PathRole roles)
{
if(hop == numHops - 1)
return llarp_nodedb_get_rc(db, m_ExitRouter, cur);
else
return path::Builder::SelectHop(db, prev, cur, hop, roles);
}
void
BaseSession::HandlePathBuilt(llarp::path::Path* p)
{
p->SetDropHandler(std::bind(&BaseSession::HandleTrafficDrop, this,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3));
p->SetExitTrafficHandler(std::bind(&BaseSession::HandleTraffic, this,
std::placeholders::_1,
std::placeholders::_2));
p->AddObtainExitHandler(std::bind(&BaseSession::HandleGotExit, this,
std::placeholders::_1,
std::placeholders::_2));
llarp::routing::ObtainExitMessage obtain;
obtain.S = p->NextSeqNo();
obtain.T = llarp_randint();
// TODO: set expiratation
obtain.X = 0;
// TODO: distinguish between service node traffic
6 years ago
obtain.E = 1;
if(!obtain.Sign(&router->crypto, m_ExitIdentity))
{
llarp::LogError("Failed to sign exit request");
return;
}
if(p->SendExitRequest(&obtain, router))
llarp::LogInfo("asking ", m_ExitRouter, " for exit");
else
llarp::LogError("faild to send exit request");
}
bool
BaseSession::HandleGotExit(llarp::path::Path* p, llarp_time_t b)
{
if(b == 0)
{
llarp::LogInfo("obtained an exit via ", p->Endpoint());
}
return true;
}
bool
BaseSession::HandleTraffic(llarp::path::Path* p, llarp_buffer_t pkt)
{
(void)p;
if(m_WritePacket)
return m_WritePacket(pkt);
return false;
}
bool
BaseSession::HandleTrafficDrop(llarp::path::Path* p, const PathID_t& path,
uint64_t s)
{
(void)p;
llarp::LogError("dropped traffic on exit ", m_ExitRouter, " S=", s,
" P=", path);
return true;
}
bool
BaseSession::QueueUpstreamTraffic(llarp::net::IPv4Packet pkt, const size_t N)
{
if(m_UpstreamQueue.size() == 0)
m_UpstreamQueue.emplace_back();
auto & back = m_UpstreamQueue.back();
auto buf = pkt.Buffer();
// pack to nearest N
if(back.Size() + buf.sz > N)
{
m_UpstreamQueue.emplace_back();
return m_UpstreamQueue.back().PutBuffer(buf);
}
else
return back.PutBuffer(buf);
}
6 years ago
bool
BaseSession::FlushUpstreamTraffic()
{
auto path = PickRandomEstablishedPath(llarp::path::ePathRoleExit);
if(!path)
{
// discard
m_UpstreamQueue.clear();
return false;
}
while(m_UpstreamQueue.size())
{
auto & msg = m_UpstreamQueue.front();
msg.S = path->NextSeqNo();
path->SendRoutingMessage(&msg, router);
m_UpstreamQueue.pop_front();
}
return true;
}
} // namespace exit
} // namespace llarp