Restructured user message handling.

This commit is contained in:
Ravin Perera
2019-10-31 11:57:53 +05:30
parent 93d4abfd2a
commit a51ec4a030
10 changed files with 310 additions and 287 deletions

View File

@@ -13,9 +13,6 @@
namespace net = boost::asio;
namespace beast = boost::beast;
using tcp = net::ip::tcp;
using error = boost::system::error_code;
namespace usr
{
@@ -40,17 +37,10 @@ void user_session_handler::on_connect(sock::socket_session<user_outbound_message
// As soon as a user connects, we issue them a challenge message. We remember the
// challenge we issued and later verifies the user's response with it.
std::string msgstr;
std::string challengehex;
usr::create_user_challenge(msgstr, challengehex);
// We init the session unique id to associate with the challenge.
session->init_uniqueid();
// Create an entry in pending_challenges for later tracking upon challenge response.
usr::pending_challenges.try_emplace(session->uniqueid, challengehex);
user_outbound_message outmsg(std::move(msgstr));
user_outbound_message outmsg(issue_challenge(session->uniqueid));
session->send(std::move(outmsg));
// Set the challenge-issued flag to help later checks in on_message.
@@ -68,50 +58,8 @@ void user_session_handler::on_message(
// Meaning we have previously issued a challenge to the client,
if (session->flags[util::SESSION_FLAG::USER_CHALLENGE_ISSUED])
{
// The received message must be the challenge response. We need to verify it.
auto itr = usr::pending_challenges.find(session->uniqueid);
if (itr != usr::pending_challenges.end())
{
std::string userpubkeyhex;
std::string_view original_challenge = itr->second;
if (usr::verify_user_challenge_response(userpubkeyhex, message, original_challenge) == 0)
{
// Challenge singature verification successful.
// Decode hex pubkey and get binary pubkey. We area only going to keep
// the binary pubkey due to reduced memory footprint.
std::string userpubkey;
userpubkey.resize(userpubkeyhex.length() / 2);
util::hex2bin(
reinterpret_cast<unsigned char *>(userpubkey.data()),
userpubkey.length(),
userpubkeyhex);
// Now check whether this user public key is duplicate.
if (usr::sessionids.count(userpubkey) == 0)
{
// All good. Unique public key.
// Promote the connection from pending-challenges to authenticated users.
session->flags.reset(util::SESSION_FLAG::USER_CHALLENGE_ISSUED); // Clear challenge-issued flag
session->flags.set(util::SESSION_FLAG::USER_AUTHED); // Set the user-authed flag
usr::add_user(session, userpubkey); // Add the user to the global authed user list
usr::pending_challenges.erase(session->uniqueid); // Remove the stored challenge
LOG_INFO << "User connection " << session->uniqueid << " authenticated. Public key "
<< userpubkeyhex;
return;
}
else
{
LOG_INFO << "Duplicate user public key " << session->uniqueid;
}
}
else
{
LOG_INFO << "Challenge verification failed " << session->uniqueid;
}
}
if (verify_challenge(message, session))
return;
}
// Check whether this session belongs to an authenticated (challenge-verified) user.
else if (session->flags[util::SESSION_FLAG::USER_AUTHED])
@@ -119,19 +67,12 @@ void user_session_handler::on_message(
// Check whether this user is among authenticated users
// and perform authenticated msg processing.
auto itr = usr::users.find(session->uniqueid);
if (itr != usr::users.end())
auto itr = ctx.users.find(session->uniqueid);
if (itr != ctx.users.end())
{
// This is an authed user.
usr::connected_user &user = itr->second;
{
std::lock_guard<std::mutex> lock(users_mutex);
//Add to the hashed input buffer list.
user.inputs.push_back(util::hash_buffer(message, user.pubkey));
}
LOG_DBG << "Collected " << message.length() << " bytes from user";
connected_user &user = itr->second;
handle_user_message(user, message);
return;
}
}
@@ -151,14 +92,14 @@ void user_session_handler::on_close(sock::socket_session<user_outbound_message>
// Session is awaiting challenge response.
if (session->flags[util::SESSION_FLAG::USER_CHALLENGE_ISSUED])
{
usr::pending_challenges.erase(session->uniqueid);
ctx.pending_challenges.erase(session->uniqueid);
}
// Session belongs to an authed user.
else if (session->flags[util::SESSION_FLAG::USER_AUTHED])
{
// Wait for SC process completion before we remove existing user.
proc::await_contract_execution();
usr::remove_user(session->uniqueid);
remove_user(session->uniqueid);
}
LOG_INFO << "User disconnected " << session->uniqueid;