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:
parent
84fc90dc82
commit
2412ed59ee
7 changed files with 257 additions and 202 deletions
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
1
llarp/service/pendingbuffer.cpp
Normal file
1
llarp/service/pendingbuffer.cpp
Normal file
|
@ -0,0 +1 @@
|
|||
#include <service/pendingbuffer.hpp>
|
36
llarp/service/pendingbuffer.hpp
Normal file
36
llarp/service/pendingbuffer.hpp
Normal 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
|
138
llarp/service/sendcontext.cpp
Normal file
138
llarp/service/sendcontext.cpp
Normal 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
|
68
llarp/service/sendcontext.hpp
Normal file
68
llarp/service/sendcontext.hpp
Normal 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
|
Loading…
Reference in a new issue