Reformat mysql_backend.c

This commit is contained in:
Johan Wikman
2016-01-12 14:54:35 +02:00
parent 1b94c5b519
commit 244d7ee86c

View File

@ -37,10 +37,11 @@
* 12/07/2013 Massimiliano Pinto Added Mysql Change User via dcb->func.auth()
* 15/07/2013 Massimiliano Pinto Added Mysql session change via dcb->func.session()
* 17/07/2013 Massimiliano Pinto Added dcb->command update from gwbuf->command for proper routing
server replies to client via router->clientReply
* server replies to client via router->clientReply
* 04/09/2013 Massimiliano Pinto Added dcb->session and dcb->session->client checks for NULL
* 12/09/2013 Massimiliano Pinto Added checks in gw_read_backend_event() for gw_read_backend_handshake
* 27/09/2013 Massimiliano Pinto Changed in gw_read_backend_event the check for dcb_read(), now is if rc < 0
* 27/09/2013 Massimiliano Pinto Changed in gw_read_backend_event the check for dcb_read(),
* now is if rc < 0
* 24/10/2014 Massimiliano Pinto Added Mysql user@host @db authentication support
* 10/11/2014 Massimiliano Pinto Client charset is passed to backend
* 19/06/2015 Martin Brampton Persistent connection handling
@ -50,7 +51,8 @@
*/
#include <modinfo.h>
MODULE_INFO info = {
MODULE_INFO info =
{
MODULE_API_PROTOCOL,
MODULE_GA,
GWPROTOCOL_VERSION,
@ -75,11 +77,12 @@ static bool sescmd_response_complete(DCB* dcb);
#if defined(NOT_USED)
static int gw_session(DCB *backend_dcb, void *data);
static int gw_session(DCB *backend_dcb, void *data);
#endif
static MYSQL_session* gw_get_shared_session_auth_info(DCB* dcb);
static GWPROTOCOL MyObject = {
static GWPROTOCOL MyObject =
{
gw_read_backend_event, /* Read - EPOLLIN handler */
gw_MySQLWrite_backend, /* Write - data from gateway */
gw_write_backend_event, /* WriteReady - EPOLLOUT handler */
@ -98,8 +101,7 @@ static GWPROTOCOL MyObject = {
*
* @return version string of the module
*/
char *
version()
char* version()
{
return version_str;
}
@ -108,8 +110,7 @@ version()
* The module initialisation routine, called when the module
* is first loaded.
*/
void
ModuleInit()
void ModuleInit()
{
}
@ -121,15 +122,12 @@ ModuleInit()
*
* @return The module object
*/
GWPROTOCOL *
GetModuleObject()
GWPROTOCOL* GetModuleObject()
{
return &MyObject;
}
static MYSQL_session* gw_get_shared_session_auth_info(
DCB* dcb)
static MYSQL_session* gw_get_shared_session_auth_info(DCB* dcb)
{
MYSQL_session* auth_info = NULL;
CHK_DCB(dcb);
@ -137,9 +135,12 @@ static MYSQL_session* gw_get_shared_session_auth_info(
spinlock_acquire(&dcb->session->ses_lock);
if (dcb->session->state != SESSION_STATE_ALLOC && dcb->session->state != SESSION_STATE_DUMMY) {
if (dcb->session->state != SESSION_STATE_ALLOC && dcb->session->state != SESSION_STATE_DUMMY)
{
auth_info = dcb->session->data;
} else {
}
else
{
MXS_ERROR("%lu [gw_get_shared_session_auth_info] Couldn't get "
"session authentication info. Session in a wrong state %d.",
pthread_self(),
@ -155,7 +156,8 @@ static MYSQL_session* gw_get_shared_session_auth_info(
* @param dcb The backend Descriptor Control Block
* @return 1 on operation, 0 for no action
*/
static int gw_read_backend_event(DCB *dcb) {
static int gw_read_backend_event(DCB *dcb)
{
MySQLProtocol *client_protocol = NULL;
MySQLProtocol *backend_protocol = NULL;
MYSQL_session *current_session = NULL;
@ -168,7 +170,7 @@ static int gw_read_backend_event(DCB *dcb) {
goto return_rc;
}
if(dcb->session == NULL)
if (dcb->session == NULL)
{
goto return_rc;
}
@ -190,7 +192,6 @@ static int gw_read_backend_event(DCB *dcb) {
backend_protocol->protocol_auth_state,
STRPROTOCOLSTATE(backend_protocol->protocol_auth_state));
/* backend is connected:
*
* 1. read server handshake
@ -228,8 +229,7 @@ static int gw_read_backend_event(DCB *dcb) {
* Decode password and send the auth credentials
* to backend.
*/
if (gw_send_authentication_to_backend(
current_session->db,
if (gw_send_authentication_to_backend(current_session->db,
current_session->user,
current_session->client_sha1,
backend_protocol) != 0)
@ -289,10 +289,10 @@ static int gw_read_backend_event(DCB *dcb) {
/**
* Read backend's reply to authentication message
*/
receive_rc =
gw_receive_backend_auth(backend_protocol);
receive_rc = gw_receive_backend_auth(backend_protocol);
switch (receive_rc) {
switch (receive_rc)
{
case -1:
backend_protocol->protocol_auth_state = MYSQL_AUTH_FAILED;
MXS_DEBUG("%lu [gw_read_backend_event] after "
@ -347,9 +347,11 @@ static int gw_read_backend_event(DCB *dcb) {
if (dcb->delayq != NULL)
{
while ((dcb->delayq = gwbuf_consume(
dcb->delayq,
GWBUF_LENGTH(dcb->delayq))) != NULL);
while ((dcb->delayq = gwbuf_consume(dcb->delayq,
GWBUF_LENGTH(dcb->delayq))) != NULL)
{
;
}
}
spinlock_release(&dcb->delayqlock);
@ -370,9 +372,7 @@ static int gw_read_backend_event(DCB *dcb) {
dcb,
dcb->session);
#endif
errbuf = mysql_create_custom_error(
1,
errbuf = mysql_create_custom_error(1,
0,
"Authentication with backend failed. "
"Session will be closed.");
@ -453,13 +453,11 @@ static int gw_read_backend_event(DCB *dcb) {
#if defined(SS_DEBUG)
MXS_ERROR("Backend read error handling #2.");
#endif
errbuf = mysql_create_custom_error(
1,
errbuf = mysql_create_custom_error(1,
0,
"Read from backend failed");
router->handleError(
router_instance,
router->handleError(router_instance,
session->router_session,
errbuf,
dcb,
@ -487,7 +485,7 @@ static int gw_read_backend_event(DCB *dcb) {
ss_dassert(read_buffer != NULL || dcb->dcb_readqueue != NULL);
}
if(dcb->dcb_readqueue)
if (dcb->dcb_readqueue)
{
read_buffer = gwbuf_append(dcb->dcb_readqueue,read_buffer);
}
@ -504,13 +502,12 @@ static int gw_read_backend_event(DCB *dcb) {
{
GWBUF *tmp = modutil_get_complete_packets(&read_buffer);
if(tmp == NULL)
if (tmp == NULL)
{
/** No complete packets */
dcb->dcb_readqueue = read_buffer;
rc = 0;
goto return_rc;
}
dcb->dcb_readqueue = read_buffer;
@ -521,8 +518,7 @@ static int gw_read_backend_event(DCB *dcb) {
* If protocol has session command set, concatenate whole
* response into one buffer.
*/
if (protocol_get_srv_command((MySQLProtocol *)dcb->protocol, false) !=
MYSQL_COM_UNDEFINED)
if (protocol_get_srv_command((MySQLProtocol *)dcb->protocol, false) != MYSQL_COM_UNDEFINED)
{
read_buffer = process_response_data(dcb, read_buffer, gwbuf_length(read_buffer));
/**
@ -535,7 +531,8 @@ static int gw_read_backend_event(DCB *dcb) {
goto return_rc;
}
if (!read_buffer) {
if (!read_buffer)
{
MXS_NOTICE("%lu [gw_read_backend_event] "
"Read buffer unexpectedly null, even though response "
"not marked as complete. User: %s",
@ -560,13 +557,11 @@ static int gw_read_backend_event(DCB *dcb) {
{
CHK_PROTOCOL(client_protocol);
if (client_protocol->protocol_auth_state ==
MYSQL_IDLE)
if (client_protocol->protocol_auth_state == MYSQL_IDLE)
{
gwbuf_set_type(read_buffer, GWBUF_TYPE_MYSQL);
router->clientReply(
router_instance,
router->clientReply(router_instance,
session->router_session,
read_buffer,
dcb);
@ -601,30 +596,30 @@ return_with_lock:
* @param dcb The descriptor control block
* @return 1 in success, 0 in case of failure,
*/
static int gw_write_backend_event(DCB *dcb) {
static int gw_write_backend_event(DCB *dcb)
{
int rc = 0;
MySQLProtocol *backend_protocol = dcb->protocol;
/*<
* Don't write to backend if backend_dcb is not in poll set anymore.
*/
if (dcb->state != DCB_STATE_POLLING) {
if (dcb->state != DCB_STATE_POLLING)
{
uint8_t* data;
if (dcb->writeq != NULL)
{
data = (uint8_t *)GWBUF_DATA(dcb->writeq);
if(dcb->session->client == NULL)
if (dcb->session->client == NULL)
{
rc = 0;
}
else if (!(MYSQL_IS_COM_QUIT(data)))
{
/*< vraa : errorHandle */
mysql_send_custom_error(
dcb->session->client,
mysql_send_custom_error(dcb->session->client,
1,
0,
"Writing to backend failed due invalid Maxscale "
@ -656,7 +651,8 @@ static int gw_write_backend_event(DCB *dcb) {
goto return_rc;
}
if (backend_protocol->protocol_auth_state == MYSQL_PENDING_CONNECT) {
if (backend_protocol->protocol_auth_state == MYSQL_PENDING_CONNECT)
{
backend_protocol->protocol_auth_state = MYSQL_CONNECTED;
rc = 1;
goto return_rc;
@ -681,8 +677,7 @@ return_rc:
* @param queue Queue of buffers to write
* @return 0 on failure, 1 on success
*/
static int
gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue)
static int gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue)
{
MySQLProtocol *backend_protocol = dcb->protocol;
int rc = 0;
@ -694,7 +689,8 @@ gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue)
* If auth failed, return value is 0, write and buffered write
* return 1.
*/
switch (backend_protocol->protocol_auth_state) {
switch (backend_protocol->protocol_auth_state)
{
case MYSQL_HANDSHAKE_FAILED:
case MYSQL_AUTH_FAILED:
if (dcb->session->state != SESSION_STATE_STOPPING)
@ -709,7 +705,10 @@ gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue)
/** Consume query buffer */
while ((queue = gwbuf_consume(
queue,
GWBUF_LENGTH(queue))) != NULL);
GWBUF_LENGTH(queue))) != NULL)
{
;
}
rc = 0;
spinlock_release(&dcb->authlock);
goto return_rc;
@ -744,8 +743,8 @@ gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue)
/** Write to backend */
rc = dcb_write(dcb, queue);
goto return_rc;
break;
}
break;
default:
{
@ -776,8 +775,8 @@ gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue)
spinlock_release(&dcb->authlock);
rc = 1;
goto return_rc;
break;
}
break;
}
return_rc:
return rc;
@ -836,8 +835,7 @@ static int gw_error_backend_event(DCB *dcb)
}
return 1;
}
errbuf = mysql_create_custom_error(
1,
errbuf = mysql_create_custom_error(1,
0,
"Lost connection to backend server.");
@ -916,8 +914,7 @@ retblock:
* backend server. Positive fd is copied to protocol and to dcb.
* If fails, fd == -1 and socket is closed.
*/
static int gw_create_backend_connection(
DCB *backend_dcb,
static int gw_create_backend_connection(DCB *backend_dcb,
SERVER *server,
SESSION *session)
{
@ -928,7 +925,8 @@ static int gw_create_backend_connection(
protocol = mysql_protocol_init(backend_dcb, -1);
ss_dassert(protocol != NULL);
if (protocol == NULL) {
if (protocol == NULL)
{
MXS_DEBUG("%lu [gw_create_backend_connection] Failed to create "
"protocol object for backend connection.",
pthread_self());
@ -958,7 +956,8 @@ static int gw_create_backend_connection(
backend_dcb->protocol = protocol;
/*< Set protocol state */
switch (rv) {
switch (rv)
{
case 0:
ss_dassert(fd > 0);
protocol->fd = fd;
@ -1014,8 +1013,7 @@ return_fd:
* @param dcb The current Backend DCB
* @return 1 always
*/
static int
gw_backend_hangup(DCB *dcb)
static int gw_backend_hangup(DCB *dcb)
{
SESSION* session;
void* rsession;
@ -1033,7 +1031,7 @@ gw_backend_hangup(DCB *dcb)
}
session = dcb->session;
if(session == NULL)
if (session == NULL)
{
goto retblock;
}
@ -1044,8 +1042,7 @@ gw_backend_hangup(DCB *dcb)
router = session->service->router;
router_instance = session->service->router_instance;
errbuf = mysql_create_custom_error(
1,
errbuf = mysql_create_custom_error(1,
0,
"Lost connection to backend server.");
@ -1091,7 +1088,7 @@ gw_backend_hangup(DCB *dcb)
goto retblock;
}
#if defined(SS_DEBUG)
if(ses_state != SESSION_STATE_STOPPING)
if (ses_state != SESSION_STATE_STOPPING)
{
MXS_ERROR("Backend hangup error handling.");
}
@ -1125,8 +1122,7 @@ retblock:
* @param dcb The current Backend DCB
* @return 1 always
*/
static int
gw_backend_close(DCB *dcb)
static int gw_backend_close(DCB *dcb)
{
DCB* client_dcb;
SESSION* session;
@ -1135,8 +1131,7 @@ gw_backend_close(DCB *dcb)
CHK_DCB(dcb);
session = dcb->session;
MXS_DEBUG("%lu [gw_backend_close]",
pthread_self());
MXS_DEBUG("%lu [gw_backend_close]", pthread_self());
quitbuf = mysql_create_com_quit(NULL, 0);
gwbuf_set_type(quitbuf, GWBUF_TYPE_MYSQL);
@ -1195,14 +1190,19 @@ gw_backend_close(DCB *dcb)
* @param dcb The current backend DCB
* @param queue Input data in the GWBUF struct
*/
static void backend_set_delayqueue(DCB *dcb, GWBUF *queue) {
static void backend_set_delayqueue(DCB *dcb, GWBUF *queue)
{
spinlock_acquire(&dcb->delayqlock);
if (dcb->delayq) {
if (dcb->delayq)
{
/* Append data */
dcb->delayq = gwbuf_append(dcb->delayq, queue);
} else {
if (queue != NULL) {
}
else
{
if (queue != NULL)
{
/* create the delay queue */
dcb->delayq = queue;
}
@ -1242,8 +1242,7 @@ static int backend_write_delayqueue(DCB *dcb)
GWBUF* new_packet;
mses = (MYSQL_session *)dcb->session->client->data;
new_packet = gw_create_change_user_packet(
mses,
new_packet = gw_create_change_user_packet(mses,
(MySQLProtocol *)dcb->protocol);
/**
* Remove previous packet which lacks scramble
@ -1274,8 +1273,7 @@ static int backend_write_delayqueue(DCB *dcb)
#if defined(SS_DEBUG)
MXS_INFO("Backend write delayqueue error handling.");
#endif
errbuf = mysql_create_custom_error(
1,
errbuf = mysql_create_custom_error(1,
0,
"Failed to write buffered data to back-end server. "
"Buffer was empty or back-end was disconnected during "
@ -1309,8 +1307,7 @@ static int backend_write_delayqueue(DCB *dcb)
* @param queue The GWBUF containing the COM_CHANGE_USER receveid
* @return 1 on success and 0 on failure
*/
static int gw_change_user(
DCB *backend,
static int gw_change_user(DCB *backend,
SERVER *server,
SESSION *in_session,
GWBUF *queue)
@ -1343,12 +1340,15 @@ static int gw_change_user(
client_auth_packet++;
/* allocate memory for token only if auth_token_len > 0 */
if (auth_token_len > 0) {
if (auth_token_len > 0)
{
auth_token = (uint8_t *)malloc(auth_token_len);
ss_dassert(auth_token != NULL);
if (auth_token == NULL)
{
return rv;
}
memcpy(auth_token, client_auth_packet, auth_token_len);
client_auth_packet += auth_token_len;
}
@ -1357,14 +1357,19 @@ static int gw_change_user(
strncpy(database, (char *)client_auth_packet,MYSQL_DATABASE_MAXLEN);
/* get character set */
if (strlen(database)) {
if (strlen(database))
{
client_auth_packet += strlen(database) + 1;
} else {
}
else
{
client_auth_packet++;
}
if (client_auth_packet && *client_auth_packet)
{
memcpy(&backend_protocol->charset, client_auth_packet, sizeof(int));
}
/* save current_database name */
strncpy(current_database, current_session->db,MYSQL_DATABASE_MAXLEN);
@ -1387,12 +1392,13 @@ static int gw_change_user(
username,
client_sha1);
if (auth_ret != 0) {
if (!service_refresh_users(backend->session->client->service)) {
if (auth_ret != 0)
{
if (!service_refresh_users(backend->session->client->service))
{
/* Try authentication again with new repository data */
/* Note: if no auth client authentication will fail */
auth_ret = gw_check_mysql_scramble_data(
backend->session->client,
auth_ret = gw_check_mysql_scramble_data(backend->session->client,
auth_token, auth_token_len,
client_protocol->scramble,
sizeof(client_protocol->scramble),
@ -1406,17 +1412,24 @@ static int gw_change_user(
/* let's free the auth_token now */
if (auth_token)
{
free(auth_token);
}
if (auth_ret != 0) {
if (auth_ret != 0)
{
char *password_set = NULL;
char *message = NULL;
GWBUF* buf;
if (auth_token_len > 0)
{
password_set = (char *)client_sha1;
}
else
{
password_set = "";
}
/**
* Create an error message and make it look like legit reply
@ -1473,8 +1486,7 @@ retblock:
*
* @return GWBUF which includes complete MySQL packet
*/
static GWBUF* process_response_data (
DCB* dcb,
static GWBUF* process_response_data(DCB* dcb,
GWBUF* readbuf,
int nbytes_to_process)
{
@ -1487,7 +1499,10 @@ static GWBUF* process_response_data (
/** Get command which was stored in gw_MySQLWrite_backend */
p = DCB_PROTOCOL(dcb, MySQLProtocol);
if (!DCB_IS_CLONE(dcb)) CHK_PROTOCOL(p);
if (!DCB_IS_CLONE(dcb))
{
CHK_PROTOCOL(p);
}
/** All buffers processed here are sescmd responses */
gwbuf_set_type(readbuf, GWBUF_TYPE_SESCMD_RESPONSE);
@ -1605,7 +1620,7 @@ static GWBUF* process_response_data (
* three bytes left. If there is less than three
* bytes in the buffer or it is NULL, we need to
wait for more data from the backend server.*/
if(readbuf == NULL || GWBUF_LENGTH(readbuf) < 3)
if (readbuf == NULL || GWBUF_LENGTH(readbuf) < 3)
{
MXS_DEBUG("%lu [%s] Read %d packets. Waiting for %d more "
"packets for a total of %d packets.",
@ -1631,8 +1646,7 @@ static GWBUF* process_response_data (
}
static bool sescmd_response_complete(
DCB* dcb)
static bool sescmd_response_complete(DCB* dcb)
{
int npackets_left;
ssize_t nbytes_left;
@ -1640,7 +1654,10 @@ static bool sescmd_response_complete(
bool succp;
p = DCB_PROTOCOL(dcb, MySQLProtocol);
if (!DCB_IS_CLONE(dcb)) CHK_PROTOCOL(p);
if (!DCB_IS_CLONE(dcb))
{
CHK_PROTOCOL(p);
}
protocol_get_response_status(p, &npackets_left, &nbytes_left);