summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2021-12-20 22:46:29 +0100
committerRoman Smrž <roman.smrz@seznam.cz>2021-12-20 22:46:29 +0100
commit1c23f04929d90acd8bccce91ca974f4ef7fc0927 (patch)
tree59f4ddba4d2c03e5bed95d05b05a3ca21d6d297e
parent9528dcbf1a567c4fe0a2ecab7dbc7fc6f4a2d6ff (diff)
Pairing: properly reset state on restarted pairing
-rw-r--r--src/pairing.cpp18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/pairing.cpp b/src/pairing.cpp
index c8e2d9f..0618a19 100644
--- a/src/pairing.cpp
+++ b/src/pairing.cpp
@@ -15,9 +15,11 @@
using namespace erebos;
using std::lock_guard;
+using std::make_shared;
using std::runtime_error;
using std::scoped_lock;
using std::thread;
+using std::unique_lock;
PairingServiceBase::~PairingServiceBase()
{
@@ -69,10 +71,14 @@ void PairingServiceBase::handle(Context & ctx)
lock_guard lock(stateLock);
auto & state = peerStates.try_emplace(ctx.peer(), new State()).first->second;
- scoped_lock lock2(state->lock);
+ unique_lock lock_state(state->lock);
if (auto request = rec->item("request").asBinary()) {
- if (state->phase != StatePhase::NoPairing)
+ if (state->phase >= StatePhase::PairingDone) {
+ auto nstate = make_shared<State>();
+ lock_state = unique_lock(nstate->lock);
+ state = move(nstate);
+ } else if (state->phase != StatePhase::NoPairing)
return;
if (requestInitHook)
@@ -158,9 +164,15 @@ void PairingServiceBase::requestPairing(UUID serviceId, const Peer & peer)
if (!pid)
throw runtime_error("Pairing request for peer without known identity");
- lock_guard lock(stateLock);
+ unique_lock lock(stateLock);
auto & state = peerStates.try_emplace(peer, new State()).first->second;
+ if (state->phase != StatePhase::NoPairing) {
+ auto nstate = make_shared<State>();
+ lock = unique_lock(nstate->lock);
+ state = move(nstate);
+ }
+
state->phase = StatePhase::OurRequest;
state->nonce.resize(32);
RAND_bytes(state->nonce.data(), state->nonce.size());