lokinet/llarp/exit/endpoint.cpp

185 lines
4.6 KiB
C++
Raw Normal View History

2018-12-12 01:06:46 +00:00
#include <exit/endpoint.hpp>
2018-12-12 01:12:59 +00:00
#include <handlers/exit.hpp>
#include <router/router.hpp>
namespace llarp
{
namespace exit
{
2018-11-14 12:23:08 +00:00
Endpoint::Endpoint(const llarp::PubKey& remoteIdent,
const llarp::PathID_t& beginPath, bool rewriteIP,
huint32_t ip, llarp::handlers::ExitEndpoint* parent)
2018-12-23 13:29:11 +00:00
: createdAt(parent->Now())
, m_Parent(parent)
2018-11-14 12:23:08 +00:00
, m_remoteSignKey(remoteIdent)
, m_CurrentPath(beginPath)
, m_IP(ip)
2018-11-14 12:23:08 +00:00
, m_RewriteSource(rewriteIP)
2018-11-29 21:19:20 +00:00
, m_Counter(0)
2018-11-14 12:23:08 +00:00
{
2018-11-28 12:32:38 +00:00
m_LastActive = parent->Now();
2018-11-14 12:23:08 +00:00
}
Endpoint::~Endpoint()
{
m_Parent->DelEndpointInfo(m_CurrentPath);
2018-11-14 12:23:08 +00:00
}
2018-11-14 18:02:27 +00:00
void
Endpoint::Close()
{
m_Parent->RemoveExit(this);
}
2018-11-14 12:23:08 +00:00
bool
Endpoint::UpdateLocalPath(const llarp::PathID_t& nextPath)
{
if(!m_Parent->UpdateEndpointPath(m_remoteSignKey, nextPath))
return false;
m_CurrentPath = nextPath;
return true;
}
2018-11-14 18:02:27 +00:00
void
Endpoint::Tick(llarp_time_t now)
{
(void)now;
m_RxRate = 0;
m_TxRate = 0;
}
bool
Endpoint::IsExpired(llarp_time_t now) const
{
auto path = GetCurrentPath();
if(path)
{
return path->Expired(now);
}
// if we don't have an underlying path we are considered expired
return true;
}
2018-11-14 18:02:27 +00:00
bool
Endpoint::ExpiresSoon(llarp_time_t now, llarp_time_t dlt) const
{
auto path = GetCurrentPath();
if(path)
return path->ExpiresSoon(now, dlt);
return true;
}
bool
Endpoint::LooksDead(llarp_time_t now, llarp_time_t timeout) const
2018-11-28 12:32:38 +00:00
{
if(ExpiresSoon(now, timeout))
return true;
auto path = GetCurrentPath();
if(!path)
return true;
auto lastPing = path->LastRemoteActivityAt();
if(lastPing == 0 || (now > lastPing && now - lastPing > timeout))
return now > m_LastActive && now - m_LastActive > timeout;
2018-12-27 15:31:24 +00:00
else if(lastPing)
return now > lastPing && now - lastPing > timeout;
2018-12-27 15:18:23 +00:00
return lastPing > 0;
2018-11-28 12:32:38 +00:00
}
2018-11-14 12:23:08 +00:00
bool
2018-11-29 21:19:20 +00:00
Endpoint::QueueOutboundTraffic(llarp_buffer_t buf, uint64_t counter)
2018-11-14 12:23:08 +00:00
{
2018-11-29 21:19:20 +00:00
// queue overflow
if(m_UpstreamQueue.size() > MaxUpstreamQueueSize)
return false;
2018-11-14 12:23:08 +00:00
llarp::net::IPv4Packet pkt;
if(!pkt.Load(buf))
return false;
2018-11-14 12:23:08 +00:00
huint32_t dst;
if(m_RewriteSource)
dst = m_Parent->GetIfAddr();
else
dst = pkt.dst();
pkt.UpdateIPv4PacketOnDst(m_IP, dst);
2018-11-29 21:19:20 +00:00
m_UpstreamQueue.emplace(pkt, counter);
2018-11-14 18:02:27 +00:00
m_TxRate += buf.sz;
2018-11-28 12:32:38 +00:00
m_LastActive = m_Parent->Now();
2018-11-14 18:02:27 +00:00
return true;
2018-11-14 12:23:08 +00:00
}
bool
2018-11-28 16:38:20 +00:00
Endpoint::QueueInboundTraffic(llarp_buffer_t buf)
{
2018-11-28 16:38:20 +00:00
llarp::net::IPv4Packet pkt;
if(!pkt.Load(buf))
return false;
2018-11-29 13:12:35 +00:00
huint32_t src;
if(m_RewriteSource)
src = m_Parent->GetIfAddr();
else
src = pkt.src();
pkt.UpdateIPv4PacketOnDst(src, m_IP);
auto pktbuf = pkt.Buffer();
uint8_t queue_idx = pktbuf.sz / llarp::routing::ExitPadSize;
auto& queue = m_DownstreamQueues[queue_idx];
if(queue.size() == 0)
{
queue.emplace_back();
2018-11-29 21:19:20 +00:00
return queue.back().PutBuffer(buf, m_Counter++);
}
auto& msg = queue.back();
2018-11-29 13:12:35 +00:00
if(msg.Size() + pktbuf.sz > llarp::routing::ExitPadSize)
{
queue.emplace_back();
2018-11-29 21:19:20 +00:00
return queue.back().PutBuffer(pktbuf, m_Counter++);
2018-11-29 13:12:35 +00:00
}
else
2018-11-29 21:19:20 +00:00
return msg.PutBuffer(pktbuf, m_Counter++);
2018-11-28 16:38:20 +00:00
}
bool
2018-11-29 21:19:20 +00:00
Endpoint::Flush()
2018-11-28 16:38:20 +00:00
{
2018-11-29 21:19:20 +00:00
// flush upstream queue
while(m_UpstreamQueue.size())
{
m_Parent->QueueOutboundTraffic(m_UpstreamQueue.top().pkt.ConstBuffer());
m_UpstreamQueue.pop();
}
// flush downstream queue
2018-11-28 16:38:20 +00:00
auto path = GetCurrentPath();
bool sent = path != nullptr;
2018-11-28 16:38:20 +00:00
if(path)
{
for(auto& item : m_DownstreamQueues)
2018-11-28 16:38:20 +00:00
{
auto& queue = item.second;
while(queue.size())
2018-11-28 16:38:20 +00:00
{
auto& msg = queue.front();
msg.S = path->NextSeqNo();
if(path->SendRoutingMessage(&msg, m_Parent->GetRouter()))
{
m_RxRate += msg.Size();
sent = true;
}
queue.pop_front();
2018-11-28 16:38:20 +00:00
}
}
}
for(auto& item : m_DownstreamQueues)
item.second.clear();
2018-11-28 16:38:20 +00:00
return sent;
}
llarp::path::IHopHandler*
Endpoint::GetCurrentPath() const
{
auto router = m_Parent->GetRouter();
return router->paths.GetByUpstream(router->pubkey(), m_CurrentPath);
}
} // namespace exit
} // namespace llarp