diff --git a/docs/proto_v0.txt b/docs/proto_v0.txt index 2710ea397..114f0b120 100644 --- a/docs/proto_v0.txt +++ b/docs/proto_v0.txt @@ -639,7 +639,7 @@ sent inside a HSFM encrypted with a shared secret. n: uint_message_sequence_number, o: N seconds until this converstation plans terminate, s: SI of sender, - t: "<16 bytes converstation tag present only when n is 0>", + t: "<16 bytes converstation_tag>, v: 0 } diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index e2054623c..01ea34465 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -32,6 +32,7 @@ set(LIB_UTIL_SRC add_library(${UTIL_LIB} STATIC ${LIB_UTIL_SRC}) target_include_directories(${UTIL_LIB} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(${UTIL_LIB} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../include) # cut back on fluff if (NOT WIN32) diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 517850099..574295526 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -491,6 +491,28 @@ namespace llarp return true; } + void + Endpoint::PutReplyIntroFor(const ConvoTag& tag, const Introduction& intro) + { + auto itr = m_Sessions.find(tag); + if(itr == m_Sessions.end()) + { + itr = m_Sessions.emplace(tag, Session{}).first; + } + itr->second.replyIntro = intro; + itr->second.lastUsed = Now(); + } + + bool + Endpoint::GetReplyIntroFor(const ConvoTag& tag, Introduction& intro) const + { + auto itr = m_Sessions.find(tag); + if(itr == m_Sessions.end()) + return false; + intro = itr->second.replyIntro; + return true; + } + bool Endpoint::GetConvoTagsForService(const ServiceInfo& info, std::set< ConvoTag >& tags) const @@ -898,11 +920,10 @@ namespace llarp Endpoint::HandleDataMessage(const PathID_t& src, ProtocolMessage* msg) { auto path = GetPathByID(src); - if(path == nullptr) - return false; + if(path) + PutReplyIntroFor(msg->tag, path->intro); msg->sender.UpdateAddr(); PutIntroFor(msg->tag, msg->introReply); - PutSenderFor(msg->tag, path->intro); EnsureReplyPath(msg->sender); return ProcessDataMessage(msg); } @@ -1277,7 +1298,8 @@ namespace llarp ProtocolMessage m(f.T); m.proto = t; m.introReply = p->intro; - m.sender = m_Identity.pub; + PutReplyIntroFor(f.T, m.introReply); + m.sender = m_Identity.pub; m.PutBuffer(data); f.N.Randomize(); f.S = GetSeqNoForConvo(f.T); @@ -1611,11 +1633,12 @@ namespace llarp ex->msg.PutBuffer(payload); ex->msg.introReply = path->intro; + m_DataHandler->PutReplyIntroFor(currentConvoTag, path->intro); llarp_threadpool_queue_job(m_Endpoint->Worker(), {ex, &AsyncKeyExchange::Encrypt}); } - void + bool Endpoint::SendContext::Send(ProtocolFrame& msg) { auto path = m_PathSet->GetPathByRouter(remoteIntro.router); @@ -1630,6 +1653,7 @@ namespace llarp remoteIntro.router); lastGoodSend = m_Endpoint->Now(); ++sequenceNo; + return true; } else llarp::LogError("Failed to send frame on path"); @@ -1637,6 +1661,7 @@ namespace llarp else llarp::LogError("cannot send because we have no path to ", remoteIntro.router); + return false; } std::string @@ -1843,8 +1868,12 @@ namespace llarp if(m_DataHandler->GetCachedSessionKeyFor(f.T, shared)) { ProtocolMessage m; - m.proto = t; - m.introReply = path->intro; + m.proto = t; + if(!m_DataHandler->GetReplyIntroFor(f.T, m.introReply)) + { + m_DataHandler->PutReplyIntroFor(f.T, path->intro); + m.introReply = path->intro; + } m_DataHandler->PutIntroFor(f.T, remoteIntro); m.sender = m_Endpoint->m_Identity.pub; m.PutBuffer(payload); @@ -1864,11 +1893,11 @@ namespace llarp msg.P = remoteIntro.pathID; msg.Y.Randomize(); - ++sequenceNo; if(path->SendRoutingMessage(&msg, m_Endpoint->Router())) { llarp::LogDebug("sent message via ", remoteIntro.pathID, " on ", remoteIntro.router); + ++sequenceNo; lastGoodSend = now; } else diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index 58b876fef..3b953f85a 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -221,7 +221,7 @@ namespace llarp /// send a fully encrypted hidden service frame /// via a path on our pathset with path id p - void + bool Send(ProtocolFrame& f); llarp::SharedSecret sharedKey; @@ -390,6 +390,14 @@ namespace llarp bool GetIntroFor(const ConvoTag& remote, Introduction& intro) const override; + void + PutReplyIntroFor(const ConvoTag& remote, + const Introduction& intro) override; + + bool + GetReplyIntroFor(const ConvoTag& remote, + Introduction& intro) const override; + bool GetConvoTagsForService(const ServiceInfo& si, std::set< ConvoTag >& tag) const override; @@ -540,6 +548,7 @@ namespace llarp struct Session : public util::IStateful { + Introduction replyIntro; SharedSecret sharedKey; ServiceInfo remote; Introduction intro; @@ -550,9 +559,10 @@ namespace llarp ExtractStatus() const override { util::StatusObject obj{{"lastUsed", lastUsed}, + {"replyIntro", replyIntro.ExtractStatus()}, {"remote", remote.Addr().ToString()}, - {"seqno", seqno}}; - obj.Put("intro", intro.ExtractStatus()); + {"seqno", seqno}, + {"intro", intro.ExtractStatus()}}; return obj; }; diff --git a/llarp/service/handler.hpp b/llarp/service/handler.hpp index eea252b97..25e3a28d9 100644 --- a/llarp/service/handler.hpp +++ b/llarp/service/handler.hpp @@ -37,6 +37,12 @@ namespace llarp virtual bool GetIntroFor(const ConvoTag& remote, Introduction& intro) const = 0; + virtual void + PutReplyIntroFor(const ConvoTag& remote, const Introduction& intro) = 0; + + virtual bool + GetReplyIntroFor(const ConvoTag& remote, Introduction& intro) const = 0; + virtual bool GetConvoTagsForService(const ServiceInfo& si, std::set< ConvoTag >& tag) const = 0;