2018-12-12 02:04:32 +00:00
|
|
|
#include <buffer.hpp>
|
2018-12-12 02:52:51 +00:00
|
|
|
#include <endian.hpp>
|
|
|
|
#include <messages/discard.hpp>
|
|
|
|
#include <path.hpp>
|
2018-12-12 02:04:32 +00:00
|
|
|
#include <router.hpp>
|
|
|
|
#include <routing/handler.hpp>
|
2018-06-22 00:25:30 +00:00
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
{
|
2018-06-25 15:12:08 +00:00
|
|
|
namespace path
|
2018-06-22 00:25:30 +00:00
|
|
|
{
|
2018-06-26 16:23:43 +00:00
|
|
|
TransitHop::TransitHop()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
bool
|
|
|
|
TransitHop::Expired(llarp_time_t now) const
|
|
|
|
{
|
2018-11-14 18:02:27 +00:00
|
|
|
return now >= ExpireTime();
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-06-22 00:25:30 +00:00
|
|
|
|
2018-08-22 16:19:51 +00:00
|
|
|
llarp_time_t
|
|
|
|
TransitHop::ExpireTime() const
|
|
|
|
{
|
|
|
|
return started + lifetime;
|
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
TransitHopInfo::TransitHopInfo(const TransitHopInfo& other)
|
|
|
|
: txID(other.txID)
|
|
|
|
, rxID(other.rxID)
|
|
|
|
, upstream(other.upstream)
|
|
|
|
, downstream(other.downstream)
|
|
|
|
{
|
|
|
|
}
|
2018-06-22 00:25:30 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
TransitHopInfo::TransitHopInfo(const RouterID& down,
|
|
|
|
const LR_CommitRecord& record)
|
|
|
|
: txID(record.txid)
|
|
|
|
, rxID(record.rxid)
|
|
|
|
, upstream(record.nextHop)
|
|
|
|
, downstream(down)
|
|
|
|
{
|
|
|
|
}
|
2018-06-22 00:25:30 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
TransitHop::TransitHop(const TransitHop& other)
|
|
|
|
: info(other.info)
|
|
|
|
, pathKey(other.pathKey)
|
|
|
|
, started(other.started)
|
|
|
|
, lifetime(other.lifetime)
|
|
|
|
, version(other.version)
|
2018-06-22 00:25:30 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
bool
|
2018-11-12 16:43:40 +00:00
|
|
|
TransitHop::SendRoutingMessage(const llarp::routing::IMessage* msg,
|
2018-12-10 16:26:46 +00:00
|
|
|
llarp::Router* r)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2018-10-02 15:00:34 +00:00
|
|
|
if(!IsEndpoint(r->pubkey()))
|
|
|
|
return false;
|
|
|
|
byte_t tmp[MAX_LINK_MSG_SIZE - 128];
|
2018-06-25 15:12:08 +00:00
|
|
|
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
|
|
|
if(!msg->BEncode(&buf))
|
|
|
|
{
|
2018-07-05 15:44:06 +00:00
|
|
|
llarp::LogError("failed to encode routing message");
|
2018-06-25 15:12:08 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
TunnelNonce N;
|
|
|
|
N.Randomize();
|
2018-07-23 22:36:46 +00:00
|
|
|
buf.sz = buf.cur - buf.base;
|
2018-10-02 15:00:34 +00:00
|
|
|
// pad to nearest MESSAGE_PAD_SIZE bytes
|
|
|
|
auto dlt = buf.sz % MESSAGE_PAD_SIZE;
|
|
|
|
if(dlt)
|
2018-07-23 22:36:46 +00:00
|
|
|
{
|
2018-10-02 15:00:34 +00:00
|
|
|
dlt = MESSAGE_PAD_SIZE - dlt;
|
2018-07-23 22:36:46 +00:00
|
|
|
// randomize padding
|
2018-10-02 15:00:34 +00:00
|
|
|
r->crypto.randbytes(buf.cur, dlt);
|
|
|
|
buf.sz += dlt;
|
2018-07-23 22:36:46 +00:00
|
|
|
}
|
2018-06-25 15:12:08 +00:00
|
|
|
buf.cur = buf.base;
|
|
|
|
return HandleDownstream(buf, N, r);
|
|
|
|
}
|
2018-06-22 00:25:30 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
bool
|
|
|
|
TransitHop::HandleDownstream(llarp_buffer_t buf, const TunnelNonce& Y,
|
2018-12-10 16:26:46 +00:00
|
|
|
llarp::Router* r)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
2018-09-19 14:12:46 +00:00
|
|
|
RelayDownstreamMessage msg;
|
|
|
|
msg.pathid = info.rxID;
|
|
|
|
msg.Y = Y ^ nonceXOR;
|
2018-06-25 15:12:08 +00:00
|
|
|
r->crypto.xchacha20(buf, pathKey, Y);
|
2018-09-19 14:12:46 +00:00
|
|
|
msg.X = buf;
|
|
|
|
llarp::LogDebug("relay ", msg.X.size(), " bytes downstream from ",
|
2018-07-05 15:44:06 +00:00
|
|
|
info.upstream, " to ", info.downstream);
|
2018-09-19 14:12:46 +00:00
|
|
|
return r->SendToOrQueue(info.downstream, &msg);
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-06-22 00:25:30 +00:00
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
bool
|
|
|
|
TransitHop::HandleUpstream(llarp_buffer_t buf, const TunnelNonce& Y,
|
2018-12-10 16:26:46 +00:00
|
|
|
llarp::Router* r)
|
2018-06-25 15:12:08 +00:00
|
|
|
{
|
|
|
|
r->crypto.xchacha20(buf, pathKey, Y);
|
2018-10-02 15:00:34 +00:00
|
|
|
if(IsEndpoint(r->pubkey()))
|
2018-06-26 16:23:43 +00:00
|
|
|
{
|
2018-12-27 15:31:24 +00:00
|
|
|
m_LastActivity = r->Now();
|
|
|
|
return r->ParseRoutingMessageBuffer(buf, this, info.rxID);
|
2018-06-26 16:23:43 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-09-19 14:12:46 +00:00
|
|
|
RelayUpstreamMessage msg;
|
|
|
|
msg.pathid = info.txID;
|
|
|
|
msg.Y = Y ^ nonceXOR;
|
2018-06-26 16:23:43 +00:00
|
|
|
|
2018-09-19 14:12:46 +00:00
|
|
|
msg.X = buf;
|
|
|
|
llarp::LogDebug("relay ", msg.X.size(), " bytes upstream from ",
|
2018-07-05 15:44:06 +00:00
|
|
|
info.downstream, " to ", info.upstream);
|
2018-09-19 14:12:46 +00:00
|
|
|
return r->SendToOrQueue(info.upstream, &msg);
|
2018-06-26 16:23:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
TransitHop::HandleDHTMessage(const llarp::dht::IMessage* msg,
|
2018-12-10 16:26:46 +00:00
|
|
|
llarp::Router* r)
|
2018-06-26 16:23:43 +00:00
|
|
|
{
|
2018-07-05 15:44:06 +00:00
|
|
|
return r->dht->impl.RelayRequestForPath(info.rxID, msg);
|
2018-06-26 16:23:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
TransitHop::HandlePathLatencyMessage(
|
2018-12-10 16:26:46 +00:00
|
|
|
const llarp::routing::PathLatencyMessage* msg, llarp::Router* r)
|
2018-06-26 16:23:43 +00:00
|
|
|
{
|
|
|
|
llarp::routing::PathLatencyMessage reply;
|
|
|
|
reply.L = msg->T;
|
|
|
|
return SendRoutingMessage(&reply, r);
|
2018-06-25 15:12:08 +00:00
|
|
|
}
|
2018-06-26 16:23:43 +00:00
|
|
|
|
|
|
|
bool
|
|
|
|
TransitHop::HandlePathConfirmMessage(
|
2018-11-07 15:30:22 +00:00
|
|
|
__attribute__((unused)) const llarp::routing::PathConfirmMessage* msg,
|
2018-12-10 16:26:46 +00:00
|
|
|
__attribute__((unused)) llarp::Router* r)
|
2018-06-26 16:23:43 +00:00
|
|
|
{
|
2018-11-07 15:30:22 +00:00
|
|
|
llarp::LogWarn("unwarranted path confirm message on ", info);
|
2018-06-26 16:23:43 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-09-11 15:28:36 +00:00
|
|
|
bool
|
|
|
|
TransitHop::HandleDataDiscardMessage(
|
2018-11-07 15:30:22 +00:00
|
|
|
__attribute__((unused)) const llarp::routing::DataDiscardMessage* msg,
|
2018-12-10 16:26:46 +00:00
|
|
|
__attribute__((unused)) llarp::Router* r)
|
2018-09-11 15:28:36 +00:00
|
|
|
{
|
|
|
|
llarp::LogWarn("unwarranted path data discard message on ", info);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-11-12 16:43:40 +00:00
|
|
|
bool
|
|
|
|
TransitHop::HandleObtainExitMessage(
|
2018-12-10 16:26:46 +00:00
|
|
|
const llarp::routing::ObtainExitMessage* msg, llarp::Router* r)
|
2018-11-12 16:43:40 +00:00
|
|
|
{
|
2018-11-14 12:23:08 +00:00
|
|
|
if(msg->Verify(&r->crypto)
|
2018-11-14 21:02:36 +00:00
|
|
|
&& r->exitContext.ObtainNewExit(msg->I, info.rxID, msg->E != 0))
|
2018-11-14 12:23:08 +00:00
|
|
|
{
|
|
|
|
llarp::routing::GrantExitMessage grant;
|
|
|
|
grant.S = NextSeqNo();
|
|
|
|
grant.T = msg->T;
|
2018-11-14 18:02:27 +00:00
|
|
|
if(!grant.Sign(&r->crypto, r->identity))
|
2018-11-14 21:16:11 +00:00
|
|
|
{
|
|
|
|
llarp::LogError("Failed to sign grant exit message");
|
2018-11-14 18:02:27 +00:00
|
|
|
return false;
|
2018-11-14 21:16:11 +00:00
|
|
|
}
|
2018-11-14 12:23:08 +00:00
|
|
|
return SendRoutingMessage(&grant, r);
|
|
|
|
}
|
|
|
|
// TODO: exponential backoff
|
|
|
|
// TODO: rejected policies
|
|
|
|
llarp::routing::RejectExitMessage reject;
|
|
|
|
reject.S = NextSeqNo();
|
|
|
|
reject.T = msg->T;
|
2018-11-14 18:02:27 +00:00
|
|
|
if(!reject.Sign(&r->crypto, r->identity))
|
2018-11-14 21:16:11 +00:00
|
|
|
{
|
|
|
|
llarp::LogError("Failed to sign reject exit message");
|
2018-11-14 18:02:27 +00:00
|
|
|
return false;
|
2018-11-14 21:16:11 +00:00
|
|
|
}
|
2018-11-14 12:23:08 +00:00
|
|
|
return SendRoutingMessage(&reject, r);
|
2018-11-12 16:43:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
TransitHop::HandleCloseExitMessage(
|
2018-12-10 16:26:46 +00:00
|
|
|
const llarp::routing::CloseExitMessage* msg, llarp::Router* r)
|
2018-11-12 16:43:40 +00:00
|
|
|
{
|
2018-11-14 21:02:36 +00:00
|
|
|
llarp::routing::DataDiscardMessage discard(info.rxID, msg->S);
|
|
|
|
auto ep = r->exitContext.FindEndpointForPath(info.rxID);
|
2018-11-14 18:02:27 +00:00
|
|
|
if(ep && msg->Verify(&r->crypto, ep->PubKey()))
|
|
|
|
{
|
|
|
|
ep->Close();
|
|
|
|
// ep is now gone af
|
|
|
|
llarp::routing::CloseExitMessage reply;
|
|
|
|
reply.S = NextSeqNo();
|
|
|
|
if(reply.Sign(&r->crypto, r->identity))
|
|
|
|
return SendRoutingMessage(&reply, r);
|
|
|
|
}
|
|
|
|
return SendRoutingMessage(&discard, r);
|
2018-11-12 16:43:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2018-11-14 12:23:08 +00:00
|
|
|
TransitHop::HandleUpdateExitVerifyMessage(
|
2018-12-10 16:26:46 +00:00
|
|
|
const llarp::routing::UpdateExitVerifyMessage* msg, llarp::Router* r)
|
2018-11-12 16:43:40 +00:00
|
|
|
{
|
|
|
|
(void)msg;
|
|
|
|
(void)r;
|
2018-11-14 12:23:08 +00:00
|
|
|
llarp::LogError("unwarranted exit verify on ", info);
|
2018-11-12 16:43:40 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-11-14 12:23:08 +00:00
|
|
|
bool
|
|
|
|
TransitHop::HandleUpdateExitMessage(
|
2018-12-10 16:26:46 +00:00
|
|
|
const llarp::routing::UpdateExitMessage* msg, llarp::Router* r)
|
2018-11-14 12:23:08 +00:00
|
|
|
{
|
|
|
|
auto ep = r->exitContext.FindEndpointForPath(msg->P);
|
|
|
|
if(ep)
|
|
|
|
{
|
2018-11-14 18:02:27 +00:00
|
|
|
if(!msg->Verify(&r->crypto, ep->PubKey()))
|
|
|
|
return false;
|
|
|
|
|
2018-11-14 21:02:36 +00:00
|
|
|
if(ep->UpdateLocalPath(info.rxID))
|
2018-11-14 12:23:08 +00:00
|
|
|
{
|
2018-11-14 18:02:27 +00:00
|
|
|
llarp::routing::UpdateExitVerifyMessage reply;
|
|
|
|
reply.T = msg->T;
|
|
|
|
reply.S = NextSeqNo();
|
|
|
|
return SendRoutingMessage(&reply, r);
|
2018-11-14 12:23:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// on fail tell message was discarded
|
2018-11-14 21:02:36 +00:00
|
|
|
llarp::routing::DataDiscardMessage discard(info.rxID, msg->S);
|
2018-11-14 12:23:08 +00:00
|
|
|
return SendRoutingMessage(&discard, r);
|
|
|
|
}
|
|
|
|
|
2018-11-12 16:43:40 +00:00
|
|
|
bool
|
|
|
|
TransitHop::HandleRejectExitMessage(
|
2018-12-10 16:26:46 +00:00
|
|
|
const llarp::routing::RejectExitMessage* msg, llarp::Router* r)
|
2018-11-12 16:43:40 +00:00
|
|
|
{
|
|
|
|
(void)msg;
|
|
|
|
(void)r;
|
2018-11-14 18:02:27 +00:00
|
|
|
llarp::LogError(info, " got unwarrented RXM");
|
2018-11-12 16:43:40 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
TransitHop::HandleGrantExitMessage(
|
2018-12-10 16:26:46 +00:00
|
|
|
const llarp::routing::GrantExitMessage* msg, llarp::Router* r)
|
2018-11-12 16:43:40 +00:00
|
|
|
{
|
|
|
|
(void)msg;
|
|
|
|
(void)r;
|
2018-11-14 18:02:27 +00:00
|
|
|
llarp::LogError(info, " got unwarrented GXM");
|
2018-11-12 16:43:40 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
TransitHop::HandleTransferTrafficMessage(
|
2018-12-10 16:26:46 +00:00
|
|
|
const llarp::routing::TransferTrafficMessage* msg, llarp::Router* r)
|
2018-11-12 16:43:40 +00:00
|
|
|
{
|
2018-11-14 21:02:36 +00:00
|
|
|
auto endpoint = r->exitContext.FindEndpointForPath(info.rxID);
|
2018-11-15 13:54:53 +00:00
|
|
|
if(endpoint)
|
2018-11-14 18:02:27 +00:00
|
|
|
{
|
2018-11-28 17:29:29 +00:00
|
|
|
bool sent = true;
|
2018-12-02 18:07:07 +00:00
|
|
|
for(const auto& pkt : msg->X)
|
2018-11-29 21:19:20 +00:00
|
|
|
{
|
|
|
|
// check short packet buffer
|
|
|
|
if(pkt.size() <= 8)
|
|
|
|
continue;
|
|
|
|
uint64_t counter = bufbe64toh(pkt.data());
|
2018-12-02 18:07:07 +00:00
|
|
|
sent &= endpoint->QueueOutboundTraffic(
|
|
|
|
llarp::InitBuffer(pkt.data() + 8, pkt.size() - 8), counter);
|
2018-11-29 21:19:20 +00:00
|
|
|
}
|
2018-11-28 17:29:29 +00:00
|
|
|
return sent;
|
2018-11-14 18:02:27 +00:00
|
|
|
}
|
2018-11-15 13:54:53 +00:00
|
|
|
else
|
|
|
|
llarp::LogError("No exit endpoint on ", info);
|
2018-11-14 18:02:27 +00:00
|
|
|
// discarded
|
2018-11-14 21:02:36 +00:00
|
|
|
llarp::routing::DataDiscardMessage discard(info.rxID, msg->S);
|
2018-11-14 18:02:27 +00:00
|
|
|
return SendRoutingMessage(&discard, r);
|
2018-11-12 16:43:40 +00:00
|
|
|
}
|
|
|
|
|
2018-06-26 16:23:43 +00:00
|
|
|
bool
|
|
|
|
TransitHop::HandlePathTransferMessage(
|
2018-12-10 16:26:46 +00:00
|
|
|
const llarp::routing::PathTransferMessage* msg, llarp::Router* r)
|
2018-06-26 16:23:43 +00:00
|
|
|
{
|
2018-10-06 16:37:54 +00:00
|
|
|
auto path = r->paths.GetPathForTransfer(msg->P);
|
2018-11-14 18:02:27 +00:00
|
|
|
llarp::routing::DataDiscardMessage discarded(msg->P, msg->S);
|
2018-08-12 17:22:29 +00:00
|
|
|
if(!path)
|
|
|
|
{
|
2018-11-14 18:02:27 +00:00
|
|
|
return SendRoutingMessage(&discarded, r);
|
2018-08-12 17:22:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
byte_t tmp[service::MAX_PROTOCOL_MESSAGE_SIZE];
|
|
|
|
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
|
|
|
if(!msg->T.BEncode(&buf))
|
|
|
|
{
|
2018-11-14 18:02:27 +00:00
|
|
|
llarp::LogWarn(info, " failed to transfer data message, encode failed");
|
|
|
|
return SendRoutingMessage(&discarded, r);
|
2018-08-12 17:22:29 +00:00
|
|
|
}
|
2018-12-24 16:09:05 +00:00
|
|
|
// rewind
|
2018-08-12 17:22:29 +00:00
|
|
|
buf.sz = buf.cur - buf.base;
|
|
|
|
buf.cur = buf.base;
|
|
|
|
// send
|
2018-11-14 18:02:27 +00:00
|
|
|
if(path->HandleDownstream(buf, msg->Y, r))
|
|
|
|
return true;
|
|
|
|
return SendRoutingMessage(&discarded, r);
|
2018-06-26 16:23:43 +00:00
|
|
|
}
|
|
|
|
|
2018-06-25 15:12:08 +00:00
|
|
|
} // namespace path
|
2018-06-22 05:44:19 +00:00
|
|
|
} // namespace llarp
|