2021-03-09 22:24:35 +00:00
|
|
|
#include "endpoint.hpp"
|
2019-06-17 23:19:39 +00:00
|
|
|
|
2021-03-09 22:24:35 +00:00
|
|
|
#include <llarp/handlers/exit.hpp>
|
|
|
|
#include <llarp/path/path_context.hpp>
|
2023-09-15 14:55:32 +00:00
|
|
|
#include <llarp/router/router.hpp>
|
2018-11-12 16:43:40 +00:00
|
|
|
|
2023-08-31 16:28:02 +00:00
|
|
|
namespace llarp::exit
|
2018-11-12 16:43:40 +00:00
|
|
|
{
|
2023-08-31 16:28:02 +00:00
|
|
|
Endpoint::Endpoint(
|
|
|
|
const llarp::PubKey& remoteIdent,
|
|
|
|
const llarp::path::HopHandler_ptr& beginPath,
|
|
|
|
bool rewriteIP,
|
|
|
|
huint128_t ip,
|
|
|
|
llarp::handlers::ExitEndpoint* parent)
|
|
|
|
: createdAt{parent->Now()}
|
2023-10-19 11:49:46 +00:00
|
|
|
, parent{parent}
|
|
|
|
, remote_signkey{remoteIdent}
|
|
|
|
, current_path{beginPath}
|
|
|
|
, IP{ip}
|
|
|
|
, rewrite_source{rewriteIP}
|
2018-11-12 16:43:40 +00:00
|
|
|
{
|
2023-10-19 11:49:46 +00:00
|
|
|
last_active = parent->Now();
|
2023-08-31 16:28:02 +00:00
|
|
|
}
|
2018-11-14 12:23:08 +00:00
|
|
|
|
2023-08-31 16:28:02 +00:00
|
|
|
Endpoint::~Endpoint()
|
|
|
|
{
|
2023-10-19 11:49:46 +00:00
|
|
|
if (current_path)
|
|
|
|
parent->DelEndpointInfo(current_path->RXID());
|
2023-08-31 16:28:02 +00:00
|
|
|
}
|
2018-11-14 12:23:08 +00:00
|
|
|
|
2023-08-31 16:28:02 +00:00
|
|
|
void
|
|
|
|
Endpoint::Close()
|
|
|
|
{
|
2023-10-19 11:49:46 +00:00
|
|
|
parent->RemoveExit(this);
|
2023-08-31 16:28:02 +00:00
|
|
|
}
|
2018-11-14 18:02:27 +00:00
|
|
|
|
2023-08-31 16:28:02 +00:00
|
|
|
util::StatusObject
|
|
|
|
Endpoint::ExtractStatus() const
|
|
|
|
{
|
2023-10-19 11:49:46 +00:00
|
|
|
auto now = parent->Now();
|
2023-08-31 16:28:02 +00:00
|
|
|
util::StatusObject obj{
|
2023-10-19 11:49:46 +00:00
|
|
|
{"identity", remote_signkey.ToString()},
|
|
|
|
{"ip", IP.ToString()},
|
|
|
|
{"txRate", tx_rate},
|
|
|
|
{"rxRate", rx_rate},
|
2023-08-31 16:28:02 +00:00
|
|
|
{"createdAt", to_json(createdAt)},
|
2023-10-19 11:49:46 +00:00
|
|
|
{"exiting", !rewrite_source},
|
2023-08-31 16:28:02 +00:00
|
|
|
{"looksDead", LooksDead(now)},
|
|
|
|
{"expiresSoon", ExpiresSoon(now)},
|
|
|
|
{"expired", IsExpired(now)}};
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Endpoint::UpdateLocalPath(const llarp::PathID_t& nextPath)
|
|
|
|
{
|
2023-10-19 11:49:46 +00:00
|
|
|
if (!parent->UpdateEndpointPath(remote_signkey, nextPath))
|
2023-08-31 16:28:02 +00:00
|
|
|
return false;
|
2023-10-19 11:49:46 +00:00
|
|
|
const RouterID us{parent->GetRouter()->pubkey()};
|
2023-10-21 03:30:10 +00:00
|
|
|
// TODO: is this getting a Path or a TransitHop?
|
|
|
|
// current_path = parent->GetRouter()->path_context().GetByUpstream(us, nextPath);
|
2023-08-31 16:28:02 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Endpoint::Tick(llarp_time_t now)
|
|
|
|
{
|
|
|
|
(void)now;
|
2023-10-19 11:49:46 +00:00
|
|
|
rx_rate = 0;
|
|
|
|
tx_rate = 0;
|
2023-08-31 16:28:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Endpoint::IsExpired(llarp_time_t now) const
|
|
|
|
{
|
|
|
|
auto path = GetCurrentPath();
|
|
|
|
if (path)
|
2019-02-08 19:43:25 +00:00
|
|
|
{
|
2023-08-31 16:28:02 +00:00
|
|
|
return path->Expired(now);
|
2019-02-08 19:43:25 +00:00
|
|
|
}
|
2023-08-31 16:28:02 +00:00
|
|
|
// if we don't have an underlying path we are considered expired
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Endpoint::ExpiresSoon(llarp_time_t now, llarp_time_t dlt) const
|
|
|
|
{
|
2023-10-19 11:49:46 +00:00
|
|
|
if (current_path)
|
|
|
|
return current_path->ExpiresSoon(now, dlt);
|
2023-08-31 16:28:02 +00:00
|
|
|
return true;
|
|
|
|
}
|
2019-02-08 19:43:25 +00:00
|
|
|
|
2023-08-31 16:28:02 +00:00
|
|
|
bool
|
|
|
|
Endpoint::LooksDead(llarp_time_t now, llarp_time_t timeout) const
|
|
|
|
{
|
|
|
|
if (ExpiresSoon(now, timeout))
|
|
|
|
return true;
|
|
|
|
auto path = GetCurrentPath();
|
|
|
|
if (not path)
|
|
|
|
return true;
|
|
|
|
auto lastPing = path->LastRemoteActivityAt();
|
|
|
|
if (lastPing == 0s || (now > lastPing && now - lastPing > timeout))
|
2023-10-19 11:49:46 +00:00
|
|
|
return now > last_active && now - last_active > timeout;
|
2023-08-31 16:28:02 +00:00
|
|
|
else if (lastPing > 0s) // NOLINT
|
|
|
|
return now > lastPing && now - lastPing > timeout;
|
|
|
|
return lastPing > 0s;
|
|
|
|
}
|
|
|
|
|
2023-10-19 11:49:46 +00:00
|
|
|
/* bool
|
|
|
|
Endpoint::QueueOutboundTraffic(
|
|
|
|
PathID_t path, std::vector<byte_t> buf, uint64_t counter, service::ProtocolType t)
|
2018-11-14 12:23:08 +00:00
|
|
|
{
|
2023-10-19 11:49:46 +00:00
|
|
|
const service::ConvoTag tag{path.as_array()};
|
2018-11-12 16:43:40 +00:00
|
|
|
|
2023-10-19 11:49:46 +00:00
|
|
|
// current_path->send_path_control_message(std::string method, std::string body,
|
|
|
|
std::function<void (oxen::quic::message)> func)
|
2018-11-14 18:02:27 +00:00
|
|
|
|
2023-10-19 11:49:46 +00:00
|
|
|
if (t == service::ProtocolType::QUIC)
|
|
|
|
{
|
|
|
|
auto quic = parent->GetQUICTunnel();
|
|
|
|
if (not quic)
|
|
|
|
return false;
|
|
|
|
tx_rate += buf.size();
|
|
|
|
quic->receive_packet(tag, std::move(buf));
|
|
|
|
last_active = parent->Now();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// queue overflow
|
|
|
|
if (m_UpstreamQueue.size() > MaxUpstreamQueueSize)
|
|
|
|
return false;
|
2023-08-31 16:28:02 +00:00
|
|
|
|
2022-07-28 16:07:38 +00:00
|
|
|
llarp::net::IPPacket pkt{std::move(buf)};
|
|
|
|
if (pkt.empty())
|
2018-11-14 12:23:08 +00:00
|
|
|
return false;
|
2022-07-28 16:07:38 +00:00
|
|
|
|
2023-10-19 11:49:46 +00:00
|
|
|
if (pkt.IsV6() && parent->SupportsV6())
|
|
|
|
{
|
|
|
|
huint128_t dst;
|
|
|
|
if (rewrite_source)
|
|
|
|
dst = parent->GetIfAddr();
|
|
|
|
else
|
|
|
|
dst = pkt.dstv6();
|
|
|
|
pkt.UpdateIPv6Address(IP, dst);
|
|
|
|
}
|
|
|
|
else if (pkt.IsV4() && !parent->SupportsV6())
|
|
|
|
{
|
|
|
|
huint32_t dst;
|
|
|
|
if (rewrite_source)
|
|
|
|
dst = net::TruncateV6(parent->GetIfAddr());
|
|
|
|
else
|
|
|
|
dst = pkt.dstv4();
|
|
|
|
pkt.UpdateIPv4Address(xhtonl(net::TruncateV6(IP)), xhtonl(dst));
|
|
|
|
}
|
2023-08-31 16:28:02 +00:00
|
|
|
else
|
2023-10-19 11:49:46 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
tx_rate += pkt.size();
|
|
|
|
m_UpstreamQueue.emplace(std::move(pkt), counter);
|
|
|
|
last_active = parent->Now();
|
|
|
|
return true;
|
|
|
|
} */
|
2018-11-14 12:23:08 +00:00
|
|
|
|
2023-10-19 11:49:46 +00:00
|
|
|
bool
|
|
|
|
Endpoint::QueueInboundTraffic(std::vector<byte_t>, service::ProtocolType)
|
|
|
|
{
|
|
|
|
// TODO: this will go away with removing flush
|
|
|
|
|
|
|
|
// if (type != service::ProtocolType::QUIC)
|
|
|
|
// {
|
|
|
|
// llarp::net::IPPacket pkt{std::move(buf)};
|
|
|
|
// if (pkt.empty())
|
|
|
|
// return false;
|
|
|
|
|
|
|
|
// huint128_t src;
|
|
|
|
// if (m_RewriteSource)
|
|
|
|
// src = m_Parent->GetIfAddr();
|
|
|
|
// else
|
|
|
|
// src = pkt.srcv6();
|
|
|
|
// if (pkt.IsV6())
|
|
|
|
// pkt.UpdateIPv6Address(src, m_IP);
|
|
|
|
// else
|
|
|
|
// pkt.UpdateIPv4Address(xhtonl(net::TruncateV6(src)), xhtonl(net::TruncateV6(m_IP)));
|
|
|
|
|
|
|
|
// buf = pkt.steal();
|
|
|
|
// }
|
|
|
|
|
|
|
|
// const uint8_t queue_idx = buf.size() / llarp::routing::EXIT_PAD_SIZE;
|
|
|
|
// if (m_DownstreamQueues.find(queue_idx) == m_DownstreamQueues.end())
|
|
|
|
// m_DownstreamQueues.emplace(queue_idx, InboundTrafficQueue_t{});
|
|
|
|
// auto& queue = m_DownstreamQueues.at(queue_idx);
|
|
|
|
// if (queue.size() == 0)
|
|
|
|
// {
|
|
|
|
// queue.emplace_back();
|
|
|
|
// queue.back().protocol = type;
|
|
|
|
// return queue.back().PutBuffer(std::move(buf), m_Counter++);
|
|
|
|
// }
|
|
|
|
// auto& msg = queue.back();
|
|
|
|
// if (msg.Size() + buf.size() > llarp::routing::EXIT_PAD_SIZE)
|
|
|
|
// {
|
|
|
|
// queue.emplace_back();
|
|
|
|
// queue.back().protocol = type;
|
|
|
|
// return queue.back().PutBuffer(std::move(buf), m_Counter++);
|
|
|
|
// }
|
|
|
|
// msg.protocol = type;
|
|
|
|
// return msg.PutBuffer(std::move(buf), m_Counter++);
|
|
|
|
return true;
|
2023-08-31 16:28:02 +00:00
|
|
|
}
|
2018-11-28 16:38:20 +00:00
|
|
|
|
2023-08-31 16:28:02 +00:00
|
|
|
bool
|
|
|
|
Endpoint::Flush()
|
|
|
|
{
|
|
|
|
// flush upstream queue
|
2023-10-19 11:49:46 +00:00
|
|
|
// while (m_UpstreamQueue.size())
|
|
|
|
// {
|
|
|
|
// parent->QueueOutboundTraffic(const_cast<net::IPPacket&>(m_UpstreamQueue.top().pkt).steal());
|
|
|
|
// m_UpstreamQueue.pop();
|
|
|
|
// }
|
2023-08-31 16:28:02 +00:00
|
|
|
// flush downstream queue
|
|
|
|
auto path = GetCurrentPath();
|
|
|
|
bool sent = path != nullptr;
|
2023-10-19 11:49:46 +00:00
|
|
|
// if (path)
|
|
|
|
// {
|
|
|
|
// for (auto& item : m_DownstreamQueues)
|
|
|
|
// {
|
|
|
|
// auto& queue = item.second;
|
|
|
|
// while (queue.size())
|
|
|
|
// {
|
|
|
|
// auto& msg = queue.front();
|
|
|
|
// msg.sequence_number = path->NextSeqNo();
|
|
|
|
// if (path->SendRoutingMessage(msg, m_Parent->GetRouter()))
|
|
|
|
// {
|
|
|
|
// m_RxRate += msg.Size();
|
|
|
|
// sent = true;
|
|
|
|
// }
|
|
|
|
// queue.pop_front();
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// for (auto& item : m_DownstreamQueues)
|
|
|
|
// item.second.clear();
|
2023-08-31 16:28:02 +00:00
|
|
|
return sent;
|
|
|
|
}
|
|
|
|
} // namespace llarp::exit
|