|
|
|
@ -5,6 +5,7 @@
|
|
|
|
|
#include <service/endpoint.hpp>
|
|
|
|
|
#include <util/thread/logic.hpp>
|
|
|
|
|
#include <utility>
|
|
|
|
|
#include <unordered_set>
|
|
|
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
|
{
|
|
|
|
@ -23,12 +24,12 @@ namespace llarp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
SendContext::Send(const ProtocolFrame& msg, path::Path_ptr path)
|
|
|
|
|
SendContext::Send(std::shared_ptr< ProtocolFrame > msg, path::Path_ptr path)
|
|
|
|
|
{
|
|
|
|
|
util::Lock lock(&m_SendQueueMutex);
|
|
|
|
|
m_SendQueue.emplace_back(
|
|
|
|
|
std::make_shared< const routing::PathTransferMessage >(
|
|
|
|
|
msg, remoteIntro.pathID),
|
|
|
|
|
*msg, remoteIntro.pathID),
|
|
|
|
|
path);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@ -37,17 +38,27 @@ namespace llarp
|
|
|
|
|
SendContext::FlushUpstream()
|
|
|
|
|
{
|
|
|
|
|
auto r = m_Endpoint->Router();
|
|
|
|
|
util::Lock lock(&m_SendQueueMutex);
|
|
|
|
|
for(const auto& item : m_SendQueue)
|
|
|
|
|
std::unordered_set< path::Path_ptr, path::Path::Ptr_Hash > flushpaths;
|
|
|
|
|
{
|
|
|
|
|
if(item.second->SendRoutingMessage(*item.first, r))
|
|
|
|
|
util::Lock lock(&m_SendQueueMutex);
|
|
|
|
|
for(const auto& item : m_SendQueue)
|
|
|
|
|
{
|
|
|
|
|
lastGoodSend = r->Now();
|
|
|
|
|
if(item.second->SendRoutingMessage(*item.first, r))
|
|
|
|
|
{
|
|
|
|
|
lastGoodSend = r->Now();
|
|
|
|
|
flushpaths.emplace(item.second);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
LogError(m_Endpoint->Name(), " failed to send frame on path");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
LogError(m_Endpoint->Name(), " failed to send frame on path");
|
|
|
|
|
|
|
|
|
|
m_SendQueue.clear();
|
|
|
|
|
}
|
|
|
|
|
// flush the select path's upstream
|
|
|
|
|
for(const auto& path : flushpaths)
|
|
|
|
|
{
|
|
|
|
|
path->FlushUpstream(r);
|
|
|
|
|
}
|
|
|
|
|
m_SendQueue.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// send on an established convo tag
|
|
|
|
@ -55,10 +66,10 @@ namespace llarp
|
|
|
|
|
SendContext::EncryptAndSendTo(const llarp_buffer_t& payload, ProtocolType t)
|
|
|
|
|
{
|
|
|
|
|
SharedSecret shared;
|
|
|
|
|
ProtocolFrame f;
|
|
|
|
|
f.N.Randomize();
|
|
|
|
|
f.T = currentConvoTag;
|
|
|
|
|
f.S = ++sequenceNo;
|
|
|
|
|
auto f = std::make_shared< ProtocolFrame >();
|
|
|
|
|
f->N.Randomize();
|
|
|
|
|
f->T = currentConvoTag;
|
|
|
|
|
f->S = ++sequenceNo;
|
|
|
|
|
|
|
|
|
|
auto path = m_PathSet->GetNewestPathByRouter(remoteIntro.router);
|
|
|
|
|
if(!path)
|
|
|
|
@ -68,29 +79,35 @@ namespace llarp
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!m_DataHandler->GetCachedSessionKeyFor(f.T, shared))
|
|
|
|
|
if(!m_DataHandler->GetCachedSessionKeyFor(f->T, shared))
|
|
|
|
|
{
|
|
|
|
|
LogError(m_Endpoint->Name(),
|
|
|
|
|
" has no cached session key on session T=", f.T);
|
|
|
|
|
" has no cached session key on session T=", f->T);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProtocolMessage m;
|
|
|
|
|
m_DataHandler->PutIntroFor(f.T, remoteIntro);
|
|
|
|
|
m_DataHandler->PutReplyIntroFor(f.T, path->intro);
|
|
|
|
|
m.proto = t;
|
|
|
|
|
m.seqno = m_Endpoint->GetSeqNoForConvo(f.T);
|
|
|
|
|
m.introReply = path->intro;
|
|
|
|
|
f.F = m.introReply.pathID;
|
|
|
|
|
m.sender = m_Endpoint->GetIdentity().pub;
|
|
|
|
|
m.tag = f.T;
|
|
|
|
|
m.PutBuffer(payload);
|
|
|
|
|
if(!f.EncryptAndSign(m, shared, m_Endpoint->GetIdentity()))
|
|
|
|
|
{
|
|
|
|
|
LogError(m_Endpoint->Name(), " failed to sign message");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
Send(f, path);
|
|
|
|
|
auto m = std::make_shared< ProtocolMessage >();
|
|
|
|
|
m_DataHandler->PutIntroFor(f->T, remoteIntro);
|
|
|
|
|
m_DataHandler->PutReplyIntroFor(f->T, path->intro);
|
|
|
|
|
m->proto = t;
|
|
|
|
|
m->seqno = m_Endpoint->GetSeqNoForConvo(f->T);
|
|
|
|
|
m->introReply = path->intro;
|
|
|
|
|
f->F = m->introReply.pathID;
|
|
|
|
|
m->sender = m_Endpoint->GetIdentity().pub;
|
|
|
|
|
m->tag = f->T;
|
|
|
|
|
m->PutBuffer(payload);
|
|
|
|
|
auto self = this;
|
|
|
|
|
m_Endpoint->CryptoWorker()->addJob([f, m, shared, path, self]() {
|
|
|
|
|
if(!f->EncryptAndSign(*m, shared, self->m_Endpoint->GetIdentity()))
|
|
|
|
|
{
|
|
|
|
|
LogError(self->m_Endpoint->Name(), " failed to sign message");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
self->m_Endpoint->RouterLogic()->queue_func([self, f, path]() {
|
|
|
|
|
self->Send(f, path);
|
|
|
|
|
self->FlushUpstream();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|