mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-17 15:25:35 +00:00
commit
2e89d149e4
@ -656,6 +656,7 @@ start a new session
|
|||||||
A: "H",
|
A: "H",
|
||||||
C: "<1048 bytes ciphertext block>",
|
C: "<1048 bytes ciphertext block>",
|
||||||
D: "<N bytes encrypted HSD>",
|
D: "<N bytes encrypted HSD>",
|
||||||
|
F: "<16 bytes source path_id>",
|
||||||
N: "<32 bytes nonce for key exchange>",
|
N: "<32 bytes nonce for key exchange>",
|
||||||
V: 0,
|
V: 0,
|
||||||
Z: "<64 bytes signature of entire message using sender's signing key>"
|
Z: "<64 bytes signature of entire message using sender's signing key>"
|
||||||
@ -691,6 +692,8 @@ C, K = PQKE_A(I_B.k)
|
|||||||
N = RAND(32)
|
N = RAND(32)
|
||||||
D = SE(X, K, N)
|
D = SE(X, K, N)
|
||||||
|
|
||||||
|
path = PickSendPath()
|
||||||
|
|
||||||
M = {
|
M = {
|
||||||
A: "T",
|
A: "T",
|
||||||
P: I_B.P,
|
P: I_B.P,
|
||||||
@ -699,6 +702,7 @@ M = {
|
|||||||
A: "H",
|
A: "H",
|
||||||
C: C,
|
C: C,
|
||||||
D: D,
|
D: D,
|
||||||
|
F: path.lastHop.txID,
|
||||||
N: N,
|
N: N,
|
||||||
V: 0,
|
V: 0,
|
||||||
Z: "\x00" * 64
|
Z: "\x00" * 64
|
||||||
@ -711,6 +715,8 @@ Z = S(A_sk, BE(M))
|
|||||||
alice transmits a TDFM to router with public key I_B.K via her path that ends
|
alice transmits a TDFM to router with public key I_B.K via her path that ends
|
||||||
with router with public key I_B.k
|
with router with public key I_B.k
|
||||||
|
|
||||||
|
path = PickSendPath()
|
||||||
|
|
||||||
{
|
{
|
||||||
A: "T",
|
A: "T",
|
||||||
P: I_B.P,
|
P: I_B.P,
|
||||||
@ -719,6 +725,7 @@ with router with public key I_B.k
|
|||||||
A: "H",
|
A: "H",
|
||||||
C: C,
|
C: C,
|
||||||
D: D,
|
D: D,
|
||||||
|
F: path.lastHop.txID,
|
||||||
N: N,
|
N: N,
|
||||||
V: 0,
|
V: 0,
|
||||||
Z: Z
|
Z: Z
|
||||||
@ -744,6 +751,7 @@ transfer data on a session previously made
|
|||||||
{
|
{
|
||||||
A: "H",
|
A: "H",
|
||||||
D: "<N bytes encrypted HSD>",
|
D: "<N bytes encrypted HSD>",
|
||||||
|
F: "<16 bytes path id of soruce>",
|
||||||
N: "<32 bytes nonce for symettric cipher>",
|
N: "<32 bytes nonce for symettric cipher>",
|
||||||
T: "<16 bytes converstation tag>",
|
T: "<16 bytes converstation tag>",
|
||||||
V: 0,
|
V: 0,
|
||||||
|
@ -172,26 +172,24 @@ namespace llarp
|
|||||||
IHopHandler*
|
IHopHandler*
|
||||||
PathContext::GetByUpstream(const RouterID& remote, const PathID_t& id)
|
PathContext::GetByUpstream(const RouterID& remote, const PathID_t& id)
|
||||||
{
|
{
|
||||||
auto own = MapGet(
|
auto own = MapGet(m_OurPaths, id,
|
||||||
m_OurPaths, id,
|
[](__attribute__((unused)) const PathSet* s) -> bool {
|
||||||
[](__attribute__((unused)) const PathSet* s) -> bool {
|
// TODO: is this right?
|
||||||
// TODO: is this right?
|
return true;
|
||||||
return true;
|
},
|
||||||
},
|
[remote, id](PathSet* p) -> IHopHandler* {
|
||||||
[remote, id](PathSet* p) -> IHopHandler* {
|
return p->GetByUpstream(remote, id);
|
||||||
return p->GetByUpstream(remote, id);
|
});
|
||||||
});
|
|
||||||
if(own)
|
if(own)
|
||||||
return own;
|
return own;
|
||||||
|
|
||||||
return MapGet(
|
return MapGet(m_TransitPaths, id,
|
||||||
m_TransitPaths, id,
|
[remote](const std::shared_ptr< TransitHop >& hop) -> bool {
|
||||||
[remote](const std::shared_ptr< TransitHop >& hop) -> bool {
|
return hop->info.upstream == remote;
|
||||||
return hop->info.upstream == remote;
|
},
|
||||||
},
|
[](const std::shared_ptr< TransitHop >& h) -> IHopHandler* {
|
||||||
[](const std::shared_ptr< TransitHop >& h) -> IHopHandler* {
|
return h.get();
|
||||||
return h.get();
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -208,14 +206,13 @@ namespace llarp
|
|||||||
IHopHandler*
|
IHopHandler*
|
||||||
PathContext::GetByDownstream(const RouterID& remote, const PathID_t& id)
|
PathContext::GetByDownstream(const RouterID& remote, const PathID_t& id)
|
||||||
{
|
{
|
||||||
return MapGet(
|
return MapGet(m_TransitPaths, id,
|
||||||
m_TransitPaths, id,
|
[remote](const std::shared_ptr< TransitHop >& hop) -> bool {
|
||||||
[remote](const std::shared_ptr< TransitHop >& hop) -> bool {
|
return hop->info.downstream == remote;
|
||||||
return hop->info.downstream == remote;
|
},
|
||||||
},
|
[](const std::shared_ptr< TransitHop >& h) -> IHopHandler* {
|
||||||
[](const std::shared_ptr< TransitHop >& h) -> IHopHandler* {
|
return h.get();
|
||||||
return h.get();
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PathSet*
|
PathSet*
|
||||||
@ -440,6 +437,13 @@ namespace llarp
|
|||||||
return intro.latency > 0 && _status == ePathEstablished;
|
return intro.latency > 0 && _status == ePathEstablished;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Path::IsEndpoint(const RouterID& r, const PathID_t& id) const
|
||||||
|
{
|
||||||
|
return hops[hops.size() - 1].rc.pubkey == r
|
||||||
|
&& hops[hops.size() - 1].txID == id;
|
||||||
|
}
|
||||||
|
|
||||||
RouterID
|
RouterID
|
||||||
Path::Upstream() const
|
Path::Upstream() const
|
||||||
{
|
{
|
||||||
|
@ -156,6 +156,22 @@ namespace llarp
|
|||||||
return chosen;
|
return chosen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Path*
|
||||||
|
PathSet::GetByEndpointWithID(RouterID ep, PathID_t id) const
|
||||||
|
{
|
||||||
|
Lock_t l(&m_PathsMutex);
|
||||||
|
auto itr = m_Paths.begin();
|
||||||
|
while(itr != m_Paths.end())
|
||||||
|
{
|
||||||
|
if(itr->second->IsEndpoint(ep, id))
|
||||||
|
{
|
||||||
|
return itr->second;
|
||||||
|
}
|
||||||
|
++itr;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
Path*
|
Path*
|
||||||
PathSet::GetPathByID(PathID_t id) const
|
PathSet::GetPathByID(PathID_t id) const
|
||||||
{
|
{
|
||||||
|
@ -176,6 +176,9 @@ namespace llarp
|
|||||||
Path*
|
Path*
|
||||||
GetPathByID(PathID_t id) const;
|
GetPathByID(PathID_t id) const;
|
||||||
|
|
||||||
|
Path*
|
||||||
|
GetByEndpointWithID(RouterID router, PathID_t id) const;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GetCurrentIntroductionsWithFilter(
|
GetCurrentIntroductionsWithFilter(
|
||||||
std::set< service::Introduction >& intros,
|
std::set< service::Introduction >& intros,
|
||||||
|
@ -998,6 +998,7 @@ namespace llarp
|
|||||||
if(!frame->Verify(Crypto(), si))
|
if(!frame->Verify(Crypto(), si))
|
||||||
return false;
|
return false;
|
||||||
// remove convotag it doesn't exist
|
// remove convotag it doesn't exist
|
||||||
|
LogWarn("remove convotag T=", frame->T);
|
||||||
RemoveConvoTag(frame->T);
|
RemoveConvoTag(frame->T);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1027,6 +1028,7 @@ namespace llarp
|
|||||||
, m_Endpoint(ep)
|
, m_Endpoint(ep)
|
||||||
{
|
{
|
||||||
createdAt = ep->Now();
|
createdAt = ep->Now();
|
||||||
|
currentConvoTag.Zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1583,6 +1585,7 @@ namespace llarp
|
|||||||
self->handler->PutCachedSessionKeyFor(self->msg.tag, self->sharedKey);
|
self->handler->PutCachedSessionKeyFor(self->msg.tag, self->sharedKey);
|
||||||
self->handler->PutIntroFor(self->msg.tag, self->remoteIntro);
|
self->handler->PutIntroFor(self->msg.tag, self->remoteIntro);
|
||||||
self->handler->PutSenderFor(self->msg.tag, self->remote);
|
self->handler->PutSenderFor(self->msg.tag, self->remote);
|
||||||
|
self->handler->PutReplyIntroFor(self->msg.tag, self->msg.introReply);
|
||||||
self->hook(self->frame);
|
self->hook(self->frame);
|
||||||
delete self;
|
delete self;
|
||||||
}
|
}
|
||||||
@ -1669,24 +1672,22 @@ namespace llarp
|
|||||||
|
|
||||||
ex->msg.PutBuffer(payload);
|
ex->msg.PutBuffer(payload);
|
||||||
ex->msg.introReply = path->intro;
|
ex->msg.introReply = path->intro;
|
||||||
m_DataHandler->PutReplyIntroFor(currentConvoTag, path->intro);
|
ex->frame.F = ex->msg.introReply.pathID;
|
||||||
llarp_threadpool_queue_job(m_Endpoint->Worker(),
|
llarp_threadpool_queue_job(m_Endpoint->Worker(),
|
||||||
{ex, &AsyncKeyExchange::Encrypt});
|
{ex, &AsyncKeyExchange::Encrypt});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Endpoint::SendContext::Send(ProtocolFrame& msg)
|
Endpoint::SendContext::Send(const ProtocolFrame& msg)
|
||||||
{
|
{
|
||||||
auto path = m_PathSet->GetPathByRouter(remoteIntro.router);
|
auto path = m_PathSet->GetByEndpointWithID(remoteIntro.router, msg.F);
|
||||||
if(path == nullptr)
|
|
||||||
path = m_Endpoint->GetPathByRouter(remoteIntro.router);
|
|
||||||
if(path)
|
if(path)
|
||||||
{
|
{
|
||||||
routing::PathTransferMessage transfer(msg, remoteIntro.pathID);
|
const routing::PathTransferMessage transfer(msg, remoteIntro.pathID);
|
||||||
if(path->SendRoutingMessage(&transfer, m_Endpoint->Router()))
|
if(path->SendRoutingMessage(&transfer, m_Endpoint->Router()))
|
||||||
{
|
{
|
||||||
llarp::LogDebug("sent data to ", remoteIntro.pathID, " on ",
|
llarp::LogInfo("sent intro to ", remoteIntro.pathID, " on ",
|
||||||
remoteIntro.router);
|
remoteIntro.router, " seqno=", sequenceNo);
|
||||||
lastGoodSend = m_Endpoint->Now();
|
lastGoodSend = m_Endpoint->Now();
|
||||||
++sequenceNo;
|
++sequenceNo;
|
||||||
return true;
|
return true;
|
||||||
@ -1798,16 +1799,23 @@ namespace llarp
|
|||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
// send control message if we look too quiet
|
// send control message if we look too quiet
|
||||||
if(now - lastGoodSend > (sendTimeout / 2))
|
if(lastGoodSend)
|
||||||
{
|
{
|
||||||
if(!GetNewestPathByRouter(remoteIntro.router))
|
if(now - lastGoodSend > (sendTimeout / 2))
|
||||||
{
|
{
|
||||||
BuildOneAlignedTo(remoteIntro.router);
|
if(!GetNewestPathByRouter(remoteIntro.router))
|
||||||
|
{
|
||||||
|
BuildOneAlignedTo(remoteIntro.router);
|
||||||
|
}
|
||||||
|
Encrypted< 64 > tmp;
|
||||||
|
tmp.Randomize();
|
||||||
|
llarp_buffer_t buf(tmp.data(), tmp.size());
|
||||||
|
AsyncEncryptAndSendTo(buf, eProtocolControl);
|
||||||
|
SharedSecret k;
|
||||||
|
if(currentConvoTag.IsZero())
|
||||||
|
return false;
|
||||||
|
return !m_DataHandler->HasConvoTag(currentConvoTag);
|
||||||
}
|
}
|
||||||
Encrypted< 64 > tmp;
|
|
||||||
tmp.Randomize();
|
|
||||||
llarp_buffer_t buf(tmp.data(), tmp.size());
|
|
||||||
AsyncEncryptAndSendTo(buf, eProtocolControl);
|
|
||||||
}
|
}
|
||||||
// if we are dead return true so we are removed
|
// if we are dead return true so we are removed
|
||||||
return lastGoodSend
|
return lastGoodSend
|
||||||
@ -1815,6 +1823,12 @@ namespace llarp
|
|||||||
: (now >= createdAt && now - createdAt > connectTimeout);
|
: (now >= createdAt && now - createdAt > connectTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Endpoint::HasConvoTag(const ConvoTag& t) const
|
||||||
|
{
|
||||||
|
return m_Sessions.find(t) != m_Sessions.end();
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Endpoint::OutboundContext::SelectHop(llarp_nodedb* db,
|
Endpoint::OutboundContext::SelectHop(llarp_nodedb* db,
|
||||||
const RouterContact& prev,
|
const RouterContact& prev,
|
||||||
|
@ -222,7 +222,7 @@ namespace llarp
|
|||||||
/// send a fully encrypted hidden service frame
|
/// send a fully encrypted hidden service frame
|
||||||
/// via a path on our pathset with path id p
|
/// via a path on our pathset with path id p
|
||||||
bool
|
bool
|
||||||
Send(ProtocolFrame& f);
|
Send(const ProtocolFrame& f);
|
||||||
|
|
||||||
llarp::SharedSecret sharedKey;
|
llarp::SharedSecret sharedKey;
|
||||||
ServiceInfo remoteIdent;
|
ServiceInfo remoteIdent;
|
||||||
@ -261,6 +261,9 @@ namespace llarp
|
|||||||
static void
|
static void
|
||||||
HandlePathDead(void*);
|
HandlePathDead(void*);
|
||||||
|
|
||||||
|
bool
|
||||||
|
HasConvoTag(const ConvoTag& t) const override;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ShouldBuildMore(llarp_time_t now) const override;
|
ShouldBuildMore(llarp_time_t now) const override;
|
||||||
|
|
||||||
|
@ -28,6 +28,9 @@ namespace llarp
|
|||||||
virtual void
|
virtual void
|
||||||
RemoveConvoTag(const ConvoTag& remote) = 0;
|
RemoveConvoTag(const ConvoTag& remote) = 0;
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
HasConvoTag(const ConvoTag& remote) const = 0;
|
||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
PutSenderFor(const ConvoTag& remote, const ServiceInfo& si) = 0;
|
PutSenderFor(const ConvoTag& remote, const ServiceInfo& si) = 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user