From c9a4c77fb93f9927269e662f21b30cbf45dfc558 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 8 Mar 2019 09:36:24 -0500 Subject: [PATCH 1/5] better chill with path building --- llarp/service/endpoint.cpp | 8 ++++++++ llarp/service/endpoint.hpp | 3 +++ 2 files changed, 11 insertions(+) diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 60c6688f8..9daf9c202 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1826,6 +1826,14 @@ namespace llarp { if(markedBad) return false; + if(path::Builder::ShouldBuildMore(now)) + return true; + return !ReadyToSend(); + } + + bool + Endpoint::ShouldBuildMore(llarp_time_t now) const + { bool should = path::Builder::ShouldBuildMore(now); // determine newest intro Introduction intro; diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index 342417120..f03443523 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -261,6 +261,9 @@ namespace llarp static void HandlePathDead(void*); + bool + ShouldBuildMore(llarp_time_t now) const override; + /// context needed to initiate an outbound hidden service session struct OutboundContext : public path::Builder, public SendContext { From a5557e0902c80b7db302956fca483b70b052e958 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 8 Mar 2019 09:48:09 -0500 Subject: [PATCH 2/5] always use current intro for reply --- llarp/service/endpoint.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index 9daf9c202..bff3ae6cb 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1884,11 +1884,8 @@ namespace llarp { ProtocolMessage m; m.proto = t; - if(!m_DataHandler->GetReplyIntroFor(f.T, m.introReply)) - { - m_DataHandler->PutReplyIntroFor(f.T, path->intro); - m.introReply = path->intro; - } + 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); From 792d7d16c03aea2edf3266d0092225af6b166d8a Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 8 Mar 2019 09:59:13 -0500 Subject: [PATCH 3/5] try fixing timeout issue --- llarp/link/utp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llarp/link/utp.cpp b/llarp/link/utp.cpp index 8901656d1..4b8c81b9b 100644 --- a/llarp/link/utp.cpp +++ b/llarp/link/utp.cpp @@ -230,12 +230,12 @@ namespace llarp { if(state == eClose) return true; - if(now < lastActive) + if(now <= lastActive) return false; auto dlt = now - lastActive; if(dlt >= sessionTimeout) { - LogInfo("session timeout reached for ", remoteAddr); + LogInfo("session timeout reached for ", remoteAddr, " dlt=", dlt); return true; } return false; From df17866ff794da756e5b80ac9ed4c68b97009b1e Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 8 Mar 2019 10:33:49 -0500 Subject: [PATCH 4/5] breaking protocol change, bundle source txid on outside of path transfer message. --- llarp/path/transit_hop.cpp | 2 +- llarp/service/endpoint.cpp | 21 +++++++++++---------- llarp/service/protocol.cpp | 6 ++++++ llarp/service/protocol.hpp | 3 +++ 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index 28d098b9b..4f7f0bdeb 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -293,7 +293,7 @@ namespace llarp { auto path = r->pathContext().GetPathForTransfer(msg->P); llarp::routing::DataDiscardMessage discarded(msg->P, msg->S); - if(!path) + if(path == nullptr || msg->T.F != info.txID) { return SendRoutingMessage(&discarded, r); } diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index bff3ae6cb..f14aec91b 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -1298,16 +1298,17 @@ namespace llarp { // TODO: check expiration of our end ProtocolMessage m(f.T); - m.proto = t; - m.introReply = p->intro; PutReplyIntroFor(f.T, m.introReply); - m.sender = m_Identity.pub; m.PutBuffer(data); f.N.Randomize(); - f.S = GetSeqNoForConvo(f.T); f.C.Zero(); transfer.Y.Randomize(); - transfer.P = remoteIntro.pathID; + m.proto = t; + m.introReply = p->intro; + m.sender = m_Identity.pub; + f.F = m.introReply.pathID; + f.S = GetSeqNoForConvo(f.T); + transfer.P = remoteIntro.pathID; if(!f.EncryptAndSign(Router()->crypto(), m, K, m_Identity)) { llarp::LogError("failed to encrypt and sign"); @@ -1883,14 +1884,14 @@ namespace llarp if(m_DataHandler->GetCachedSessionKeyFor(f.T, shared)) { ProtocolMessage m; - m.proto = t; + m_DataHandler->PutIntroFor(f.T, remoteIntro); m_DataHandler->PutReplyIntroFor(f.T, path->intro); + m.proto = t; m.introReply = path->intro; - m_DataHandler->PutIntroFor(f.T, remoteIntro); - m.sender = m_Endpoint->m_Identity.pub; + f.F = m.introReply.pathID; + m.sender = m_Endpoint->m_Identity.pub; + m.tag = f.T; m.PutBuffer(payload); - m.tag = f.T; - if(!f.EncryptAndSign(crypto, m, shared, m_Endpoint->m_Identity)) { llarp::LogError("failed to sign"); diff --git a/llarp/service/protocol.cpp b/llarp/service/protocol.cpp index 2eb678520..3961f9b9e 100644 --- a/llarp/service/protocol.cpp +++ b/llarp/service/protocol.cpp @@ -108,6 +108,9 @@ namespace llarp if(!BEncodeWriteDictEntry("D", D, buf)) return false; + if(!BEncodeWriteDictEntry("F", F, buf)) + return false; + if(!BEncodeWriteDictEntry("N", N, buf)) return false; if(!T.IsZero()) @@ -137,6 +140,8 @@ namespace llarp } if(!BEncodeMaybeReadDictEntry("D", D, read, key, val)) return false; + if(!BEncodeMaybeReadDictEntry("F", F, read, key, val)) + return false; if(!BEncodeMaybeReadDictEntry("C", C, read, key, val)) return false; if(!BEncodeMaybeReadDictEntry("N", N, read, key, val)) @@ -304,6 +309,7 @@ namespace llarp { C = other.C; D = other.D; + F = other.F; N = other.N; Z = other.Z; T = other.T; diff --git a/llarp/service/protocol.hpp b/llarp/service/protocol.hpp index f962ac931..ccec7efe3 100644 --- a/llarp/service/protocol.hpp +++ b/llarp/service/protocol.hpp @@ -67,6 +67,7 @@ namespace llarp Encrypted_t D; KeyExchangeNonce N; Signature Z; + PathID_t F; service::ConvoTag T; ProtocolFrame(const ProtocolFrame& other) @@ -75,6 +76,7 @@ namespace llarp , D(other.D) , N(other.N) , Z(other.Z) + , F(other.F) , T(other.T) { S = other.S; @@ -125,6 +127,7 @@ namespace llarp { C.Zero(); D.Clear(); + F.Zero(); T.Zero(); N.Zero(); Z.Zero(); From 280d85d478fbb87f944f7b46b0733861713b100d Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 8 Mar 2019 11:00:45 -0500 Subject: [PATCH 5/5] handle protocol discard --- llarp/service/endpoint.cpp | 35 +++++++++++++++++++++++++++++-- llarp/service/endpoint.hpp | 3 +++ llarp/service/handler.hpp | 3 +++ llarp/service/protocol.cpp | 43 ++++++++++++++++++++++++++++++++------ llarp/service/protocol.hpp | 6 ++++++ 5 files changed, 82 insertions(+), 8 deletions(-) diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index f14aec91b..7b624d3ef 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -978,12 +978,43 @@ namespace llarp return false; } + void + Endpoint::RemoveConvoTag(const ConvoTag& t) + { + m_Sessions.erase(t); + } + bool Endpoint::HandleHiddenServiceFrame(path::Path* p, const ProtocolFrame* frame) { - return frame->AsyncDecryptAndVerify(EndpointLogic(), Crypto(), p->RXID(), - Worker(), m_Identity, m_DataHandler); + if(frame->R) + { + // handle discard + ServiceInfo si; + if(!GetSenderFor(frame->T, si)) + return false; + // verify source + if(!frame->Verify(Crypto(), si)) + return false; + // remove convotag it doesn't exist + RemoveConvoTag(frame->T); + return true; + } + if(!frame->AsyncDecryptAndVerify(EndpointLogic(), Crypto(), p->RXID(), + Worker(), m_Identity, m_DataHandler)) + { + // send discard + ProtocolFrame f; + f.R = 1; + f.T = frame->T; + f.F = p->intro.pathID; + if(!f.Sign(Crypto(), m_Identity)) + return false; + const routing::PathTransferMessage d(f, frame->F); + return p->SendRoutingMessage(&d, router); + } + return true; } Endpoint::SendContext::SendContext(const ServiceInfo& ident, diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index f03443523..c2574c1f3 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -393,6 +393,9 @@ namespace llarp bool GetIntroFor(const ConvoTag& remote, Introduction& intro) const override; + void + RemoveConvoTag(const ConvoTag& remote) override; + void PutReplyIntroFor(const ConvoTag& remote, const Introduction& intro) override; diff --git a/llarp/service/handler.hpp b/llarp/service/handler.hpp index 25e3a28d9..e7503f1a7 100644 --- a/llarp/service/handler.hpp +++ b/llarp/service/handler.hpp @@ -25,6 +25,9 @@ namespace llarp PutCachedSessionKeyFor(const ConvoTag& remote, const SharedSecret& secret) = 0; + virtual void + RemoveConvoTag(const ConvoTag& remote) = 0; + virtual void PutSenderFor(const ConvoTag& remote, const ServiceInfo& si) = 0; diff --git a/llarp/service/protocol.cpp b/llarp/service/protocol.cpp index 3961f9b9e..a86d04eee 100644 --- a/llarp/service/protocol.cpp +++ b/llarp/service/protocol.cpp @@ -105,14 +105,23 @@ namespace llarp if(!BEncodeWriteDictEntry("C", C, buf)) return false; } - if(!BEncodeWriteDictEntry("D", D, buf)) - return false; - + if(D.size() > 0) + { + if(!BEncodeWriteDictEntry("D", D, buf)) + return false; + } if(!BEncodeWriteDictEntry("F", F, buf)) return false; - - if(!BEncodeWriteDictEntry("N", N, buf)) - return false; + if(!N.IsZero()) + { + if(!BEncodeWriteDictEntry("N", N, buf)) + return false; + } + if(R) + { + if(!BEncodeWriteDictInt("R", R, buf)) + return false; + } if(!T.IsZero()) { if(!BEncodeWriteDictEntry("T", T, buf)) @@ -148,6 +157,8 @@ namespace llarp return false; if(!BEncodeMaybeReadDictInt("S", S, read, key, val)) return false; + if(!BEncodeMaybeReadDictInt("R", R, read, key, val)) + return false; if(!BEncodeMaybeReadDictEntry("T", T, read, key, val)) return false; if(!BEncodeMaybeReadVersion("V", version, LLARP_PROTO_VERSION, read, key, @@ -169,6 +180,25 @@ namespace llarp return msg.BDecode(buf); } + bool + ProtocolFrame::Sign(llarp::Crypto* crypto, const Identity& localIdent) + { + Z.Zero(); + std::array< byte_t, MAX_PROTOCOL_MESSAGE_SIZE > tmp; + llarp_buffer_t buf(tmp); + // encode + if(!BEncode(&buf)) + { + llarp::LogError("message too big to encode"); + return false; + } + // rewind + buf.sz = buf.cur - buf.base; + buf.cur = buf.base; + // sign + return localIdent.Sign(crypto, Z, buf); + } + bool ProtocolFrame::EncryptAndSign(llarp::Crypto* crypto, const ProtocolMessage& msg, @@ -313,6 +343,7 @@ namespace llarp N = other.N; Z = other.Z; T = other.T; + R = other.R; S = other.S; version = other.version; return *this; diff --git a/llarp/service/protocol.hpp b/llarp/service/protocol.hpp index ccec7efe3..d4e0453d7 100644 --- a/llarp/service/protocol.hpp +++ b/llarp/service/protocol.hpp @@ -65,6 +65,7 @@ namespace llarp using Encrypted_t = Encrypted< 2048 >; PQCipherBlock C; Encrypted_t D; + uint64_t R; KeyExchangeNonce N; Signature Z; PathID_t F; @@ -74,6 +75,7 @@ namespace llarp : routing::IMessage() , C(other.C) , D(other.D) + , R(other.R) , N(other.N) , Z(other.Z) , F(other.F) @@ -106,6 +108,9 @@ namespace llarp EncryptAndSign(Crypto* c, const ProtocolMessage& msg, const SharedSecret& sharedkey, const Identity& localIdent); + bool + Sign(Crypto* c, const Identity& localIdent); + bool AsyncDecryptAndVerify(Logic* logic, Crypto* c, const PathID_t& srcpath, llarp_threadpool* worker, @@ -131,6 +136,7 @@ namespace llarp T.Zero(); N.Zero(); Z.Zero(); + R = 0; } bool