diff options
| author | Roman Smrž <roman.smrz@seznam.cz> | 2021-11-10 21:40:30 +0100 | 
|---|---|---|
| committer | Roman Smrž <roman.smrz@seznam.cz> | 2021-11-10 21:52:04 +0100 | 
| commit | 28220406f68f38d56648c3932c555b6d6d2b5788 (patch) | |
| tree | 82e4e41b8922cb9c82b9eee693ed165250d0773b /src | |
| parent | 02a2fbef0df2714f5fa598d82765ce463321ab56 (diff) | |
Network: hold sensitive messages until channel is established
Diffstat (limited to 'src')
| -rw-r--r-- | src/network.cpp | 51 | ||||
| -rw-r--r-- | 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 <unistd.h>  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<LocalState> & 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<Object> & objs) const +void Server::Peer::send(const TransportHeader & header, const vector<Object> & objs, bool secure)  {  	vector<uint8_t> data, part, out; @@ -559,11 +561,14 @@ void Server::Peer::send(const TransportHeader & header, const vector<Object> & o  	if (holds_alternative<Stored<Channel>>(channel))  		out = std::get<Stored<Channel>>(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<Stored<Channel>>(channel)) +		return; + +	for (const auto & data : secureOutQueue) { +		auto out = std::get<Stored<Channel>>(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<tuple<UUID, shared_ptr<WaitingRef>>> serviceQueue {}; +	vector<vector<uint8_t>> secureOutQueue {};  	shared_ptr<erebos::Peer::Priv> lpeer = nullptr; -	void send(const struct TransportHeader &, const vector<Object> &) const; +	void send(const struct TransportHeader &, const vector<Object> &, bool secure);  	void updateIdentity(ReplyBuilder &);  	void updateChannel(ReplyBuilder &);  	void updateService(ReplyBuilder &); +	void trySendOutQueue();  };  struct Peer::Priv : enable_shared_from_this<Peer::Priv> |