From 28220406f68f38d56648c3932c555b6d6d2b5788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Wed, 10 Nov 2021 21:40:30 +0100 Subject: Network: hold sensitive messages until channel is established --- src/network.cpp | 51 +++++++++++++++++++++++++++++++++++++-------------- src/network.h | 4 +++- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/network.cpp b/src/network.cpp index 8ee61b3..2db450c 100644 --- a/src/network.cpp +++ b/src/network.cpp @@ -14,6 +14,7 @@ #include using std::holds_alternative; +using std::move; using std::runtime_error; using std::scoped_lock; using std::to_string; @@ -148,15 +149,14 @@ bool Peer::send(UUID uuid, const Object & obj) const bool Peer::send(UUID uuid, const Ref & ref, const Object & obj) const { - if (hasChannel()) - if (auto speer = p->speer.lock()) { - TransportHeader header({ - { TransportHeader::Type::ServiceType, uuid }, - { TransportHeader::Type::ServiceRef, ref }, - }); - speer->send(header, { obj }); - return true; - } + if (auto speer = p->speer.lock()) { + TransportHeader header({ + { TransportHeader::Type::ServiceType, uuid }, + { TransportHeader::Type::ServiceRef, ref }, + }); + speer->send(header, { obj }, true); + return true; + } return false; } @@ -326,7 +326,9 @@ void Server::Priv::doListen() peer.updateService(reply); if (!reply.header().empty()) - peer.send(TransportHeader(reply.header()), reply.body()); + peer.send(TransportHeader(reply.header()), reply.body(), false); + + peer.trySendOutQueue(); } } else { std::cerr << "invalid packet\n"; @@ -541,12 +543,12 @@ void Server::Priv::handleLocalHeadChange(const Head & head) }); for (const auto & peer : peers) - peer->send(header, { **self.ref() }); + peer->send(header, { **self.ref() }, false); } } } -void Server::Peer::send(const TransportHeader & header, const vector & objs) const +void Server::Peer::send(const TransportHeader & header, const vector & objs, bool secure) { vector data, part, out; @@ -559,11 +561,14 @@ void Server::Peer::send(const TransportHeader & header, const vector & o if (holds_alternative>(channel)) out = std::get>(channel)->encrypt(data); + else if (secure) + secureOutQueue.emplace_back(move(data)); else out = std::move(data); - sendto(server.sock, out.data(), out.size(), 0, - (sockaddr *) &addr, sizeof(addr)); + if (!out.empty()) + sendto(server.sock, out.data(), out.size(), 0, + (sockaddr *) &addr, sizeof(addr)); } void Server::Peer::updateIdentity(ReplyBuilder & reply) @@ -647,6 +652,24 @@ void Server::Peer::updateService(ReplyBuilder & reply) serviceQueue = std::move(next); } +void Server::Peer::trySendOutQueue() +{ + if (secureOutQueue.empty()) + return; + + if (!holds_alternative>(channel)) + return; + + for (const auto & data : secureOutQueue) { + auto out = std::get>(channel)->encrypt(data); + + sendto(server.sock, out.data(), out.size(), 0, + (sockaddr *) &addr, sizeof(addr)); + } + + secureOutQueue.clear(); +} + void ReplyBuilder::header(TransportHeader::Item && item) { diff --git a/src/network.h b/src/network.h index fe7d7b4..c4f3d6f 100644 --- a/src/network.h +++ b/src/network.h @@ -56,13 +56,15 @@ struct Server::Peer PartialStorage partStorage; vector>> serviceQueue {}; + vector> secureOutQueue {}; shared_ptr lpeer = nullptr; - void send(const struct TransportHeader &, const vector &) const; + void send(const struct TransportHeader &, const vector &, bool secure); void updateIdentity(ReplyBuilder &); void updateChannel(ReplyBuilder &); void updateService(ReplyBuilder &); + void trySendOutQueue(); }; struct Peer::Priv : enable_shared_from_this -- cgit v1.2.3