1
1
Fork 0
mirror of https://github.com/oxen-io/lokinet synced 2023-12-14 06:53:00 +01:00

Move SendContext to its own component

This commit is contained in:
Michael 2019-04-19 17:02:32 +01:00
parent 84fc90dc82
commit 2412ed59ee
No known key found for this signature in database
GPG key ID: 2D51757B47E2434C
7 changed files with 257 additions and 202 deletions

View file

@ -224,7 +224,9 @@ set(LIB_SRC
service/handler.cpp
service/info.cpp
service/lookup.cpp
service/pendingbuffer.cpp
service/protocol.cpp
service/sendcontext.cpp
service/tag.cpp
service/types.cpp
service/vanity.cpp

View file

@ -1042,19 +1042,6 @@ namespace llarp
return true;
}
Endpoint::SendContext::SendContext(const ServiceInfo& ident,
const Introduction& intro, PathSet* send,
Endpoint* ep)
: remoteIdent(ident)
, remoteIntro(intro)
, m_PathSet(send)
, m_DataHandler(ep)
, m_Endpoint(ep)
{
createdAt = ep->Now();
currentConvoTag.Zero();
}
void
Endpoint::OutboundContext::HandlePathBuilt(path::Path* p)
{
@ -1431,12 +1418,13 @@ namespace llarp
}
}
// no converstation
return EnsurePathToService(remote,
[](Address, OutboundContext* c) {
if(c)
c->UpdateIntroSet(true);
},
5000, true);
return EnsurePathToService(
remote,
[](Address, OutboundContext* c) {
if(c)
c->UpdateIntroSet(true);
},
5000, true);
}
bool
@ -1581,28 +1569,6 @@ namespace llarp
return success;
}
void
Endpoint::SendContext::AsyncEncryptAndSendTo(const llarp_buffer_t& data,
ProtocolType protocol)
{
auto now = m_Endpoint->Now();
if(remoteIntro.ExpiresSoon(now))
{
if(!MarkCurrentIntroBad(now))
{
llarp::LogWarn("no good path yet, your message may drop");
}
}
if(sequenceNo)
{
EncryptAndSendTo(data, protocol);
}
else
{
AsyncGenIntro(data, protocol);
}
}
struct AsyncKeyExchange
{
llarp::Logic* logic;
@ -1735,30 +1701,6 @@ namespace llarp
{ex, &AsyncKeyExchange::Encrypt});
}
bool
Endpoint::SendContext::Send(const ProtocolFrame& msg)
{
auto path = m_PathSet->GetByEndpointWithID(remoteIntro.router, msg.F);
if(path)
{
const routing::PathTransferMessage transfer(msg, remoteIntro.pathID);
if(path->SendRoutingMessage(&transfer, m_Endpoint->Router()))
{
llarp::LogInfo("sent intro to ", remoteIntro.pathID, " on ",
remoteIntro.router, " seqno=", sequenceNo);
lastGoodSend = m_Endpoint->Now();
++sequenceNo;
return true;
}
else
llarp::LogError("Failed to send frame on path");
}
else
llarp::LogError("cannot send because we have no path to ",
remoteIntro.router);
return false;
}
std::string
Endpoint::OutboundContext::Name() const
{
@ -1954,74 +1896,6 @@ namespace llarp
&& (dlt > buildIntervalLimit));
}
/// send on an established convo tag
void
Endpoint::SendContext::EncryptAndSendTo(const llarp_buffer_t& payload,
ProtocolType t)
{
auto crypto = m_Endpoint->Router()->crypto();
SharedSecret shared;
routing::PathTransferMessage msg;
ProtocolFrame& f = msg.T;
f.N.Randomize();
f.T = currentConvoTag;
f.S = m_Endpoint->GetSeqNoForConvo(f.T);
auto now = m_Endpoint->Now();
if(remoteIntro.ExpiresSoon(now))
{
// shift intro
if(MarkCurrentIntroBad(now))
{
llarp::LogInfo("intro shifted");
}
}
auto path = m_PathSet->GetNewestPathByRouter(remoteIntro.router);
if(!path)
{
llarp::LogError("cannot encrypt and send: no path for intro ",
remoteIntro);
return;
}
if(m_DataHandler->GetCachedSessionKeyFor(f.T, shared))
{
ProtocolMessage m;
m_DataHandler->PutIntroFor(f.T, remoteIntro);
m_DataHandler->PutReplyIntroFor(f.T, path->intro);
m.proto = t;
m.introReply = path->intro;
f.F = m.introReply.pathID;
m.sender = m_Endpoint->m_Identity.pub;
m.tag = f.T;
m.PutBuffer(payload);
if(!f.EncryptAndSign(crypto, m, shared, m_Endpoint->m_Identity))
{
llarp::LogError("failed to sign");
return;
}
}
else
{
llarp::LogError("No cached session key");
return;
}
msg.P = remoteIntro.pathID;
msg.Y.Randomize();
if(path->SendRoutingMessage(&msg, m_Endpoint->Router()))
{
llarp::LogDebug("sent message via ", remoteIntro.pathID, " on ",
remoteIntro.router);
++sequenceNo;
lastGoodSend = now;
}
else
{
llarp::LogWarn("Failed to send routing message for data");
}
}
llarp::Logic*
Endpoint::RouterLogic()
{

View file

@ -9,6 +9,8 @@
#include <service/address.hpp>
#include <service/Identity.hpp>
#include <service/handler.hpp>
#include <service/pendingbuffer.hpp>
#include <service/sendcontext.hpp>
#include <service/protocol.hpp>
// minimum time between introset shifts
@ -188,24 +190,6 @@ namespace llarp
void
FlushSNodeTraffic();
struct PendingBuffer
{
std::vector< byte_t > payload;
ProtocolType protocol;
PendingBuffer(const llarp_buffer_t& buf, ProtocolType t)
: payload(buf.sz), protocol(t)
{
memcpy(payload.data(), buf.base, buf.sz);
}
ManagedBuffer
Buffer()
{
return ManagedBuffer{llarp_buffer_t(payload)};
}
};
bool
HandleDataDrop(path::Path* p, const PathID_t& dst, uint64_t s);
@ -217,54 +201,6 @@ namespace llarp
bool
ShouldBundleRC() const override;
struct SendContext
{
SendContext(const ServiceInfo& ident, const Introduction& intro,
PathSet* send, Endpoint* ep);
void
AsyncEncryptAndSendTo(const llarp_buffer_t& payload, ProtocolType t);
/// send a fully encrypted hidden service frame
/// via a path on our pathset with path id p
bool
Send(const ProtocolFrame& f);
llarp::SharedSecret sharedKey;
ServiceInfo remoteIdent;
Introduction remoteIntro;
ConvoTag currentConvoTag;
PathSet* m_PathSet;
IDataHandler* m_DataHandler;
Endpoint* m_Endpoint;
uint64_t sequenceNo = 0;
llarp_time_t lastGoodSend = 0;
llarp_time_t createdAt;
llarp_time_t sendTimeout = 40 * 1000;
llarp_time_t connectTimeout = 60 * 1000;
bool markedBad = false;
virtual bool
ShiftIntroduction(bool rebuild = true)
{
(void)rebuild;
return true;
};
virtual void
UpdateIntroSet(bool randomizePath = false) = 0;
virtual bool
MarkCurrentIntroBad(llarp_time_t now) = 0;
private:
void
EncryptAndSendTo(const llarp_buffer_t& payload, ProtocolType t);
virtual void
AsyncGenIntro(const llarp_buffer_t& payload, ProtocolType t) = 0;
};
static void
HandlePathDead(void*);
@ -432,6 +368,9 @@ namespace llarp
void
PutNewOutboundContext(const IntroSet& introset);
uint64_t
GetSeqNoForConvo(const ConvoTag& tag);
virtual void
IntroSetPublishFail();
virtual void
@ -450,9 +389,6 @@ namespace llarp
void
PrefetchServicesByTag(const Tag& tag);
uint64_t
GetSeqNoForConvo(const ConvoTag& tag);
bool
IsolateNetwork();

View file

@ -0,0 +1 @@
#include <service/pendingbuffer.hpp>

View file

@ -0,0 +1,36 @@
#ifndef LLARP_SERVICE_PENDINGBUFFER_HPP
#define LLARP_SERVICE_PENDINGBUFFER_HPP
#include <service/protocol.hpp>
#include <util/buffer.hpp>
#include <algorithm>
#include <iterator>
#include <vector>
namespace llarp
{
namespace service
{
struct PendingBuffer
{
std::vector< byte_t > payload;
ProtocolType protocol;
PendingBuffer(const llarp_buffer_t& buf, ProtocolType t)
: payload(buf.sz), protocol(t)
{
std::copy(buf.base, buf.base + buf.sz, std::back_inserter(payload));
}
ManagedBuffer
Buffer()
{
return ManagedBuffer{llarp_buffer_t(payload)};
}
};
} // namespace service
} // namespace llarp
#endif

View file

@ -0,0 +1,138 @@
#include <service/sendcontext.hpp>
#include <messages/path_transfer.hpp>
#include <service/endpoint.hpp>
#include <router/abstractrouter.hpp>
namespace llarp
{
namespace service
{
SendContext::SendContext(const ServiceInfo& ident,
const Introduction& intro, path::PathSet* send,
Endpoint* ep)
: remoteIdent(ident)
, remoteIntro(intro)
, m_PathSet(send)
, m_DataHandler(ep)
, m_Endpoint(ep)
{
createdAt = ep->Now();
currentConvoTag.Zero();
}
bool
SendContext::Send(const ProtocolFrame& msg)
{
auto path = m_PathSet->GetByEndpointWithID(remoteIntro.router, msg.F);
if(path)
{
const routing::PathTransferMessage transfer(msg, remoteIntro.pathID);
if(path->SendRoutingMessage(&transfer, m_Endpoint->Router()))
{
llarp::LogInfo("sent intro to ", remoteIntro.pathID, " on ",
remoteIntro.router, " seqno=", sequenceNo);
lastGoodSend = m_Endpoint->Now();
++sequenceNo;
return true;
}
else
llarp::LogError("Failed to send frame on path");
}
else
llarp::LogError("cannot send because we have no path to ",
remoteIntro.router);
return false;
}
/// send on an established convo tag
void
SendContext::EncryptAndSendTo(const llarp_buffer_t& payload, ProtocolType t)
{
auto crypto = m_Endpoint->Router()->crypto();
SharedSecret shared;
routing::PathTransferMessage msg;
ProtocolFrame& f = msg.T;
f.N.Randomize();
f.T = currentConvoTag;
f.S = m_Endpoint->GetSeqNoForConvo(f.T);
auto now = m_Endpoint->Now();
if(remoteIntro.ExpiresSoon(now))
{
// shift intro
if(MarkCurrentIntroBad(now))
{
llarp::LogInfo("intro shifted");
}
}
auto path = m_PathSet->GetNewestPathByRouter(remoteIntro.router);
if(!path)
{
llarp::LogError("cannot encrypt and send: no path for intro ",
remoteIntro);
return;
}
if(m_DataHandler->GetCachedSessionKeyFor(f.T, shared))
{
ProtocolMessage m;
m_DataHandler->PutIntroFor(f.T, remoteIntro);
m_DataHandler->PutReplyIntroFor(f.T, path->intro);
m.proto = 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(crypto, m, shared, m_Endpoint->GetIdentity()))
{
llarp::LogError("failed to sign");
return;
}
}
else
{
llarp::LogError("No cached session key");
return;
}
msg.P = remoteIntro.pathID;
msg.Y.Randomize();
if(path->SendRoutingMessage(&msg, m_Endpoint->Router()))
{
llarp::LogDebug("sent message via ", remoteIntro.pathID, " on ",
remoteIntro.router);
++sequenceNo;
lastGoodSend = now;
}
else
{
llarp::LogWarn("Failed to send routing message for data");
}
}
void
SendContext::AsyncEncryptAndSendTo(const llarp_buffer_t& data,
ProtocolType protocol)
{
auto now = m_Endpoint->Now();
if(remoteIntro.ExpiresSoon(now))
{
if(!MarkCurrentIntroBad(now))
{
llarp::LogWarn("no good path yet, your message may drop");
}
}
if(sequenceNo)
{
EncryptAndSendTo(data, protocol);
}
else
{
AsyncGenIntro(data, protocol);
}
}
} // namespace service
} // namespace llarp

View file

@ -0,0 +1,68 @@
#ifndef LLARP_SERVICE_SENDCONTEXT_HPP
#define LLARP_SERVICE_SENDCONTEXT_HPP
#include <path/pathset.hpp>
#include <service/Intro.hpp>
#include <service/protocol.hpp>
#include <util/buffer.hpp>
#include <util/types.hpp>
namespace llarp
{
namespace service
{
struct ServiceInfo;
struct Endpoint;
struct Introduction;
struct SendContext
{
SendContext(const ServiceInfo& ident, const Introduction& intro,
path::PathSet* send, Endpoint* ep);
void
AsyncEncryptAndSendTo(const llarp_buffer_t& payload, ProtocolType t);
/// send a fully encrypted hidden service frame
/// via a path on our pathset with path id p
bool
Send(const ProtocolFrame& f);
SharedSecret sharedKey;
ServiceInfo remoteIdent;
Introduction remoteIntro;
ConvoTag currentConvoTag;
path::PathSet* m_PathSet;
IDataHandler* m_DataHandler;
Endpoint* m_Endpoint;
uint64_t sequenceNo = 0;
llarp_time_t lastGoodSend = 0;
llarp_time_t createdAt;
llarp_time_t sendTimeout = 40 * 1000;
llarp_time_t connectTimeout = 60 * 1000;
bool markedBad = false;
virtual bool
ShiftIntroduction(bool rebuild = true)
{
(void)rebuild;
return true;
};
virtual void
UpdateIntroSet(bool randomizePath = false) = 0;
virtual bool
MarkCurrentIntroBad(llarp_time_t now) = 0;
private:
void
EncryptAndSendTo(const llarp_buffer_t& payload, ProtocolType t);
virtual void
AsyncGenIntro(const llarp_buffer_t& payload, ProtocolType t) = 0;
};
} // namespace service
} // namespace llarp
#endif