Additional spinlock in random_jkiss. Initial attempt at implementing dummy sessions to provide total consistency - used in mysql_client in relation to authentication - a single static dummy session is used and linked from the client dcb when authentication is not yet complete.
This commit is contained in:
@ -346,7 +346,10 @@ dcb_final_free(DCB *dcb)
|
||||
local_session->client = NULL;
|
||||
spinlock_release(&local_session->ses_lock);
|
||||
}
|
||||
session_free(local_session);
|
||||
if (SESSION_STATE_DUMMY != local_session->state)
|
||||
{
|
||||
session_free(local_session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,11 +117,13 @@ static void
|
||||
random_init_jkiss(void)
|
||||
{
|
||||
int newrand, i;
|
||||
spinlock_acquire(&random_jkiss_spinlock);
|
||||
if ((newrand = random_jkiss_devrand()) != 0) x = newrand;
|
||||
if ((newrand = random_jkiss_devrand()) != 0) y = newrand;
|
||||
if ((newrand = random_jkiss_devrand()) != 0) z = newrand;
|
||||
if ((newrand = random_jkiss_devrand()) != 0)
|
||||
c = newrand % 698769068 + 1; /* Should be less than 698769069 */
|
||||
spinlock_release(&random_jkiss_spinlock);
|
||||
|
||||
/* "Warm up" our random number generator */
|
||||
for (i = 0; i < 100; i++) random_jkiss();
|
||||
|
@ -56,6 +56,7 @@ static size_t session_id;
|
||||
static SPINLOCK session_spin = SPINLOCK_INIT;
|
||||
static SESSION *allSessions = NULL;
|
||||
|
||||
static struct session session_dummy_struct;
|
||||
|
||||
static int session_setup_filters(SESSION *session);
|
||||
static void session_simple_free(SESSION *session, DCB *dcb);
|
||||
@ -212,6 +213,48 @@ session_alloc(SERVICE *service, DCB *client_dcb)
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a dummy session so that DCBs can always have sessions.
|
||||
*
|
||||
* Only one dummy session exists, it is statically declared
|
||||
*
|
||||
* @param client_dcb The client side DCB
|
||||
* @return The dummy created session
|
||||
*/
|
||||
SESSION *
|
||||
session_alloc_dummy(DCB *client_dcb)
|
||||
{
|
||||
SESSION *session;
|
||||
|
||||
session = &session_dummy_struct;
|
||||
#if defined(SS_DEBUG)
|
||||
session->ses_chk_top = CHK_NUM_SESSION;
|
||||
session->ses_chk_tail = CHK_NUM_SESSION;
|
||||
#endif
|
||||
session->ses_is_child = false;
|
||||
spinlock_init(&session->ses_lock);
|
||||
session->service = NULL;
|
||||
session->client = NULL;
|
||||
session->n_filters = 0;
|
||||
memset(&session->stats, 0, sizeof(SESSION_STATS));
|
||||
session->stats.connect = 0;
|
||||
session->state = SESSION_STATE_DUMMY;
|
||||
/*<
|
||||
* Associate the session to the client DCB and set the reference count on
|
||||
* the session to indicate that there is a single reference to the
|
||||
* session. There is no need to protect this or use atomic add as the
|
||||
* session has not been made available to the other threads at this
|
||||
* point.
|
||||
*/
|
||||
session->data = NULL;
|
||||
session->refcount = 1;
|
||||
session->ses_id = 0;
|
||||
session->next = NULL;
|
||||
|
||||
client_dcb->session = session;
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable specified logging for the current session and increase logger
|
||||
* counter.
|
||||
@ -323,6 +366,10 @@ session_simple_free(SESSION *session, DCB *dcb)
|
||||
}
|
||||
if (session)
|
||||
{
|
||||
if (SESSION_STATE_DUMMY == session->state)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (session && session->router_session)
|
||||
{
|
||||
session->service->router->freeSession(
|
||||
@ -344,6 +391,10 @@ session_simple_free(SESSION *session, DCB *dcb)
|
||||
bool
|
||||
session_free(SESSION *session)
|
||||
{
|
||||
if (session && SESSION_STATE_DUMMY == session->state)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
CHK_SESSION(session);
|
||||
|
||||
/*
|
||||
@ -711,6 +762,8 @@ session_state(int state)
|
||||
{
|
||||
case SESSION_STATE_ALLOC:
|
||||
return "Session Allocated";
|
||||
case SESSION_STATE_DUMMY:
|
||||
return "Dummy Session";
|
||||
case SESSION_STATE_READY:
|
||||
return "Session Ready";
|
||||
case SESSION_STATE_ROUTER_READY:
|
||||
|
@ -64,7 +64,8 @@ typedef enum {
|
||||
SESSION_STATE_LISTENER, /*< for listener session */
|
||||
SESSION_STATE_LISTENER_STOPPED, /*< for listener session */
|
||||
SESSION_STATE_TO_BE_FREED, /*< ready to be freed as soon as there are no references */
|
||||
SESSION_STATE_FREE /*< for all sessions */
|
||||
SESSION_STATE_FREE, /*< for all sessions */
|
||||
SESSION_STATE_DUMMY /*< dummy session for consistency */
|
||||
} session_state_t;
|
||||
|
||||
/**
|
||||
@ -162,6 +163,7 @@ typedef struct session {
|
||||
|
||||
SESSION *get_all_sessions();
|
||||
SESSION *session_alloc(struct service *, struct dcb *);
|
||||
SESSION *session_alloc_dummy(struct dcb *);
|
||||
bool session_free(SESSION *);
|
||||
int session_isvalid(SESSION *);
|
||||
int session_reply(void *inst, void *session, GWBUF *data);
|
||||
|
@ -140,7 +140,7 @@ static MYSQL_session* gw_get_shared_session_auth_info(
|
||||
|
||||
spinlock_acquire(&dcb->session->ses_lock);
|
||||
|
||||
if (dcb->session->state != SESSION_STATE_ALLOC) {
|
||||
if (dcb->session->state != SESSION_STATE_ALLOC && dcb->session->state != SESSION_STATE_DUMMY) {
|
||||
auth_info = dcb->session->data;
|
||||
} else {
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
|
@ -912,7 +912,7 @@ int gw_read_client_event(
|
||||
if (session != NULL)
|
||||
{
|
||||
CHK_SESSION(session);
|
||||
ss_dassert(session->state != SESSION_STATE_ALLOC);
|
||||
ss_dassert(session->state != SESSION_STATE_ALLOC && session->state != SESSION_STATE_DUMMY);
|
||||
|
||||
protocol->protocol_auth_state = MYSQL_IDLE;
|
||||
/**
|
||||
@ -1012,7 +1012,7 @@ int gw_read_client_event(
|
||||
if (session != NULL)
|
||||
{
|
||||
CHK_SESSION(session);
|
||||
ss_dassert(session->state != SESSION_STATE_ALLOC);
|
||||
ss_dassert(session->state != SESSION_STATE_ALLOC && session->state != SESSION_STATE_DUMMY);
|
||||
|
||||
protocol->protocol_auth_state = MYSQL_IDLE;
|
||||
/**
|
||||
@ -1643,6 +1643,7 @@ int gw_MySQLAccept(DCB *listener)
|
||||
}
|
||||
|
||||
client_dcb->service = listener->session->service;
|
||||
client_dcb->session = session_alloc_dummy(client_dcb);
|
||||
client_dcb->fd = c_sock;
|
||||
|
||||
// get client address
|
||||
|
@ -210,10 +210,11 @@ typedef enum skygw_chk_t {
|
||||
((s) == DCB_STATE_UNDEFINED ? "DCB_STATE_UNDEFINED" : "DCB_STATE_UNKNOWN")))))))
|
||||
|
||||
#define STRSESSIONSTATE(s) ((s) == SESSION_STATE_ALLOC ? "SESSION_STATE_ALLOC" : \
|
||||
((s) == SESSION_STATE_READY ? "SESSION_STATE_READY" : \
|
||||
((s) == SESSION_STATE_LISTENER ? "SESSION_STATE_LISTENER" : \
|
||||
((s) == SESSION_STATE_LISTENER_STOPPED ? "SESSION_STATE_LISTENER_STOPPED" : \
|
||||
(s) == SESSION_STATE_ROUTER_READY ? "SESSION_STATE_ROUTER_READY":\
|
||||
((s) == SESSION_STATE_DUMMY ? "SESSION_STATE_DUMMY" : \
|
||||
((s) == SESSION_STATE_READY ? "SESSION_STATE_READY" : \
|
||||
((s) == SESSION_STATE_LISTENER ? "SESSION_STATE_LISTENER" : \
|
||||
((s) == SESSION_STATE_LISTENER_STOPPED ? "SESSION_STATE_LISTENER_STOPPED" : \
|
||||
(s) == SESSION_STATE_ROUTER_READY ? "SESSION_STATE_ROUTER_READY":\
|
||||
"SESSION_STATE_UNKNOWN"))))
|
||||
|
||||
#define STRPROTOCOLSTATE(s) ((s) == MYSQL_ALLOC ? "MYSQL_ALLOC" : \
|
||||
|
Reference in New Issue
Block a user