KILL [CONNECTION | QUERY] support, part2B

Various small changes to part2, as suggested by comments and otherwise.
Mostly renaming, working logic should not change.

Exception: session id changed to 64bit in the container and associated
functions. Another commit will change it to 64bit in the session itself.
This commit is contained in:
Esa Korhonen
2017-05-04 17:51:10 +03:00
parent 17f6e94cba
commit ee20191645
6 changed files with 84 additions and 68 deletions

View File

@ -73,35 +73,49 @@ static MXS_SESSION* session_alloc_body(SERVICE* service, DCB* client_dcb,
namespace
{
/**
* Checks if issuer_user@issuer_host has the privilege to kill the target session.
* Currently just checks that the user and host are the same.
*
* This function should only be called in the worker thread normally handling
* the target session, otherwise target session could be freed while function is
* running.
*
* @param issuer_user User name of command issuer
* @param issuer_host Host/ip of command issuer
* @param target Target session
* @return
*/
bool issuer_can_kill_target(const string& issuer_user, const string& issuer_host,
const MXS_SESSION* target)
{
DCB* target_dcb = target->client_dcb;
return ((strcmp(issuer_user.c_str(), target_dcb->user) == 0) &&
(strcmp(issuer_host.c_str(), target_dcb->remote) == 0));
}
class KillCmdTask : public maxscale::Worker::DisposableTask
{
private:
std::string m_issuer_username;
std::string m_issuer_host;
uint64_t m_target_id;
public:
KillCmdTask(MXS_SESSION* issuer, uint64_t target_id)
: m_issuer_user(issuer->client_dcb->user)
, m_issuer_host(issuer->client_dcb->remote)
, m_target_id(target_id)
{
DCB* issuer_dcb = issuer->client_dcb;
m_issuer_username.assign(issuer_dcb->user);
m_issuer_host.assign(issuer_dcb->remote);
m_target_id = target_id;
}
void execute(maxscale::Worker& worker)
{
MXS_SESSION* target = worker.find_in_session_map(m_target_id);
if (target)
MXS_SESSION* target = worker.find_session(m_target_id);
if (target && issuer_can_kill_target(m_issuer_user, m_issuer_host, target))
{
DCB* target_dcb = target->client_dcb;
if ((strcmp(m_issuer_username.c_str(), target_dcb->user) == 0) &&
(strcmp(m_issuer_host.c_str(), target_dcb->remote) == 0))
{
poll_fake_hangup_event(target_dcb);
}
poll_fake_hangup_event(target->client_dcb);
}
}
private:
std::string m_issuer_user;
std::string m_issuer_host;
uint64_t m_target_id;
};
}
@ -1036,26 +1050,28 @@ uint32_t session_get_next_id()
return atomic_add_uint32(&next_session_id, 1);
}
void session_broadcast_kill_command(MXS_SESSION* issuer, uint32_t target_id)
void session_broadcast_kill_command(MXS_SESSION* issuer, uint64_t target_id)
{
/* First, check if the target id belongs to the current worker. If it does,
* send hangup event. Otherwise, use a worker task to send a message to all
* workers.
*/
MXS_SESSION* target_ses = mxs_find_in_session_map(target_id);
if (target_ses)
MXS_SESSION* target = mxs_worker_find_session(target_id);
if (target &&
issuer_can_kill_target(issuer->client_dcb->user,
issuer->client_dcb->remote,
target))
{
if ((strcmp(issuer->client_dcb->user, target_ses->client_dcb->user) == 0) &&
(strcmp(issuer->client_dcb->remote, target_ses->client_dcb->remote) == 0))
{
poll_fake_hangup_event(target_ses->client_dcb);
}
poll_fake_hangup_event(target->client_dcb);
}
else
{
KillCmdTask* kill_task = new KillCmdTask(issuer, target_id);
std::auto_ptr<maxscale::Worker::DisposableTask> sTask(kill_task);
maxscale::Worker::broadcast(sTask);
KillCmdTask* kill_task = new (std::nothrow) KillCmdTask(issuer, target_id);
if (kill_task)
{
std::auto_ptr<KillCmdTask> sKillTask(kill_task);
maxscale::Worker::broadcast(sKillTask);
}
}
}