Reformat mysql_client.c

This commit is contained in:
Johan Wikman
2016-01-12 15:15:47 +02:00
parent 244d7ee86c
commit da29ee0f4a

View File

@ -29,9 +29,12 @@
* 24/06/2013 Massimiliano Pinto Added: fetch passwords from service users' hashtable * 24/06/2013 Massimiliano Pinto Added: fetch passwords from service users' hashtable
* 02/09/2013 Massimiliano Pinto Added: session refcount * 02/09/2013 Massimiliano Pinto Added: session refcount
* 16/12/2013 Massimiliano Pinto Added: client closed socket detection with recv(..., MSG_PEEK) * 16/12/2013 Massimiliano Pinto Added: client closed socket detection with recv(..., MSG_PEEK)
* 24/02/2014 Massimiliano Pinto Added: on failed authentication a new users' table is loaded with time and frequency limitations * 24/02/2014 Massimiliano Pinto Added: on failed authentication a new users' table is loaded
* If current user is authenticated the new users' table will replace the old one * with time and frequency limitations
* 28/02/2014 Massimiliano Pinto Added: client IPv4 in dcb->ipv4 and inet_ntop for string representation * If current user is authenticated the new users' table will
* replace the old one
* 28/02/2014 Massimiliano Pinto Added: client IPv4 in dcb->ipv4 and inet_ntop for string
* representation
* 11/03/2014 Massimiliano Pinto Added: Unix socket support * 11/03/2014 Massimiliano Pinto Added: Unix socket support
* 07/05/2014 Massimiliano Pinto Added: specific version string in server handshake * 07/05/2014 Massimiliano Pinto Added: specific version string in server handshake
* 09/09/2014 Massimiliano Pinto Added: 777 permission for socket path * 09/09/2014 Massimiliano Pinto Added: 777 permission for socket path
@ -51,7 +54,8 @@
#include <modutil.h> #include <modutil.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
MODULE_INFO info = { MODULE_INFO info =
{
MODULE_API_PROTOCOL, MODULE_API_PROTOCOL,
MODULE_GA, MODULE_GA,
GWPROTOCOL_VERSION, GWPROTOCOL_VERSION,
@ -84,7 +88,8 @@ int do_ssl_accept(MySQLProtocol* protocol);
/* /*
* The "module object" for the mysqld client protocol module. * The "module object" for the mysqld client protocol module.
*/ */
static GWPROTOCOL MyObject = { static GWPROTOCOL MyObject =
{
gw_read_client_event, /* Read - EPOLLIN handler */ gw_read_client_event, /* Read - EPOLLIN handler */
gw_MySQLWrite_client, /* Write - data from gateway */ gw_MySQLWrite_client, /* Write - data from gateway */
gw_write_client_event, /* WriteReady - EPOLLOUT handler */ gw_write_client_event, /* WriteReady - EPOLLOUT handler */
@ -103,8 +108,7 @@ static GWPROTOCOL MyObject = {
* *
* @return version string of the module * @return version string of the module
*/ */
char * char* version()
version()
{ {
return version_str; return version_str;
} }
@ -113,8 +117,7 @@ version()
* The module initialisation routine, called when the module * The module initialisation routine, called when the module
* is first loaded. * is first loaded.
*/ */
void void ModuleInit()
ModuleInit()
{ {
} }
@ -126,8 +129,7 @@ ModuleInit()
* *
* @return The module object * @return The module object
*/ */
GWPROTOCOL * GWPROTOCOL* GetModuleObject()
GetModuleObject()
{ {
return &MyObject; return &MyObject;
} }
@ -144,8 +146,8 @@ GetModuleObject()
* @return packet length * @return packet length
* *
*/ */
int int mysql_send_ok(DCB *dcb, int packet_number, int in_affected_rows, const char* mysql_message)
mysql_send_ok(DCB *dcb, int packet_number, int in_affected_rows, const char* mysql_message) { {
uint8_t *outbuf = NULL; uint8_t *outbuf = NULL;
uint32_t mysql_payload_size = 0; uint32_t mysql_payload_size = 0;
uint8_t mysql_packet_header[4]; uint8_t mysql_packet_header[4];
@ -159,13 +161,15 @@ mysql_send_ok(DCB *dcb, int packet_number, int in_affected_rows, const char* mys
affected_rows = in_affected_rows; affected_rows = in_affected_rows;
mysql_payload_size = sizeof(field_count) + mysql_payload_size =
sizeof(field_count) +
sizeof(affected_rows) + sizeof(affected_rows) +
sizeof(insert_id) + sizeof(insert_id) +
sizeof(mysql_server_status) + sizeof(mysql_server_status) +
sizeof(mysql_warning_count); sizeof(mysql_warning_count);
if (mysql_message != NULL) { if (mysql_message != NULL)
{
mysql_payload_size += strlen(mysql_message); mysql_payload_size += strlen(mysql_message);
} }
@ -206,7 +210,8 @@ mysql_send_ok(DCB *dcb, int packet_number, int in_affected_rows, const char* mys
memcpy(mysql_payload, mysql_warning_count, sizeof(mysql_warning_count)); memcpy(mysql_payload, mysql_warning_count, sizeof(mysql_warning_count));
mysql_payload = mysql_payload + sizeof(mysql_warning_count); mysql_payload = mysql_payload + sizeof(mysql_warning_count);
if (mysql_message != NULL) { if (mysql_message != NULL)
{
memcpy(mysql_payload, mysql_message, strlen(mysql_message)); memcpy(mysql_payload, mysql_message, strlen(mysql_message));
} }
@ -222,8 +227,7 @@ mysql_send_ok(DCB *dcb, int packet_number, int in_affected_rows, const char* mys
* @param dcb The descriptor control block to use for sending the handshake request * @param dcb The descriptor control block to use for sending the handshake request
* @return The packet length sent * @return The packet length sent
*/ */
int int MySQLSendHandshake(DCB* dcb)
MySQLSendHandshake(DCB* dcb)
{ {
uint8_t *outbuf = NULL; uint8_t *outbuf = NULL;
uint32_t mysql_payload_size = 0; uint32_t mysql_payload_size = 0;
@ -250,10 +254,13 @@ MySQLSendHandshake(DCB* dcb)
GWBUF *buf; GWBUF *buf;
/* get the version string from service property if available*/ /* get the version string from service property if available*/
if (dcb->service->version_string != NULL) { if (dcb->service->version_string != NULL)
{
version_string = dcb->service->version_string; version_string = dcb->service->version_string;
len_version_string = strlen(version_string); len_version_string = strlen(version_string);
} else { }
else
{
version_string = GW_MYSQL_VERSION; version_string = GW_MYSQL_VERSION;
len_version_string = strlen(GW_MYSQL_VERSION); len_version_string = strlen(GW_MYSQL_VERSION);
} }
@ -274,7 +281,12 @@ MySQLSendHandshake(DCB* dcb)
memcpy(mysql_plugin_data, server_scramble + 8, 12); memcpy(mysql_plugin_data, server_scramble + 8, 12);
mysql_payload_size = sizeof(mysql_protocol_version) + (len_version_string + 1) + sizeof(mysql_thread_id) + 8 + sizeof(mysql_filler) + sizeof(mysql_server_capabilities_one) + sizeof(mysql_server_language) + sizeof(mysql_server_status) + sizeof(mysql_server_capabilities_two) + sizeof(mysql_scramble_len) + sizeof(mysql_filler_ten) + 12 + sizeof(mysql_last_byte) + strlen("mysql_native_password") + sizeof(mysql_last_byte); mysql_payload_size =
sizeof(mysql_protocol_version) + (len_version_string + 1) + sizeof(mysql_thread_id) + 8 +
sizeof(mysql_filler) + sizeof(mysql_server_capabilities_one) + sizeof(mysql_server_language) +
sizeof(mysql_server_status) + sizeof(mysql_server_capabilities_two) + sizeof(mysql_scramble_len) +
sizeof(mysql_filler_ten) + 12 + sizeof(mysql_last_byte) + strlen("mysql_native_password") +
sizeof(mysql_last_byte);
// allocate memory for packet header + payload // allocate memory for packet header + payload
if ((buf = gwbuf_alloc(sizeof(mysql_packet_header) + mysql_payload_size)) == NULL) if ((buf = gwbuf_alloc(sizeof(mysql_packet_header) + mysql_payload_size)) == NULL)
@ -332,7 +344,6 @@ MySQLSendHandshake(DCB* dcb)
mysql_server_capabilities_one[0] &= ~GW_MYSQL_CAPABILITIES_SSL; mysql_server_capabilities_one[0] &= ~GW_MYSQL_CAPABILITIES_SSL;
} }
memcpy(mysql_handshake_payload, mysql_server_capabilities_one, sizeof(mysql_server_capabilities_one)); memcpy(mysql_handshake_payload, mysql_server_capabilities_one, sizeof(mysql_server_capabilities_one));
mysql_handshake_payload = mysql_handshake_payload + sizeof(mysql_server_capabilities_one); mysql_handshake_payload = mysql_handshake_payload + sizeof(mysql_server_capabilities_one);
@ -403,7 +414,8 @@ MySQLSendHandshake(DCB* dcb)
* @note in case of failure, dcb->data is freed before returning. If succeed, * @note in case of failure, dcb->data is freed before returning. If succeed,
* dcb->data is freed in session.c:session_free. * dcb->data is freed in session.c:session_free.
*/ */
static int gw_mysql_do_authentication(DCB *dcb, GWBUF **buf) { static int gw_mysql_do_authentication(DCB *dcb, GWBUF **buf)
{
GWBUF* queue = *buf; GWBUF* queue = *buf;
MySQLProtocol *protocol = NULL; MySQLProtocol *protocol = NULL;
/* int compress = -1; */ /* int compress = -1; */
@ -462,8 +474,8 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF **buf) {
memcpy(&protocol->client_capabilities, client_auth_packet + 4, 4); memcpy(&protocol->client_capabilities, client_auth_packet + 4, 4);
connect_with_db = connect_with_db =
GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB & gw_mysql_get_byte4( GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB &
(uint32_t *)&protocol->client_capabilities); gw_mysql_get_byte4((uint32_t *)&protocol->client_capabilities);
/* /*
compress = compress =
GW_MYSQL_CAPABILITIES_COMPRESS & gw_mysql_get_byte4( GW_MYSQL_CAPABILITIES_COMPRESS & gw_mysql_get_byte4(
@ -474,7 +486,6 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF **buf) {
* If not, start the SSL handshake. */ * If not, start the SSL handshake. */
if (protocol->protocol_auth_state != MYSQL_AUTH_SSL_HANDSHAKE_DONE) if (protocol->protocol_auth_state != MYSQL_AUTH_SSL_HANDSHAKE_DONE)
{ {
ssl = protocol->client_capabilities & GW_MYSQL_CAPABILITIES_SSL; ssl = protocol->client_capabilities & GW_MYSQL_CAPABILITIES_SSL;
/** Client didn't requested SSL when SSL mode was required*/ /** Client didn't requested SSL when SSL mode was required*/
@ -543,7 +554,8 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF **buf) {
/* /*
* Note: some clients may pass empty database, connect_with_db !=0 but database ="" * Note: some clients may pass empty database, connect_with_db !=0 but database =""
*/ */
if (connect_with_db) { if (connect_with_db)
{
database = client_data->db; database = client_data->db;
strncpy(database, strncpy(database,
(char *)(client_auth_packet + 4 + 4 + 4 + 1 + 23 + strlen(username) + (char *)(client_auth_packet + 4 + 4 + 4 + 1 + 23 + strlen(username) +
@ -551,7 +563,8 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF **buf) {
} }
/* allocate memory for token only if auth_token_len > 0 */ /* allocate memory for token only if auth_token_len > 0 */
if (auth_token_len) { if (auth_token_len)
{
auth_token = (uint8_t *)malloc(auth_token_len); auth_token = (uint8_t *)malloc(auth_token_len);
memcpy(auth_token, memcpy(auth_token,
client_auth_packet + 4 + 4 + 4 + 1 + 23 + strlen(username) + 1 + 1, client_auth_packet + 4 + 4 + 4 + 1 + 23 + strlen(username) + 1 + 1,
@ -575,12 +588,13 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF **buf) {
auth_ret = check_db_name_after_auth(dcb, database, auth_ret); auth_ret = check_db_name_after_auth(dcb, database, auth_ret);
/* On failed auth try to load users' table from backend database */ /* On failed auth try to load users' table from backend database */
if (auth_ret != 0) { if (auth_ret != 0)
if (!service_refresh_users(dcb->service)) { {
if (!service_refresh_users(dcb->service))
{
/* Try authentication again with new repository data */ /* Try authentication again with new repository data */
/* Note: if no auth client authentication will fail */ /* Note: if no auth client authentication will fail */
auth_ret = gw_check_mysql_scramble_data( auth_ret = gw_check_mysql_scramble_data(dcb,
dcb,
auth_token, auth_token,
auth_token_len, auth_token_len,
protocol->scramble, protocol->scramble,
@ -594,7 +608,8 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF **buf) {
} }
/* on succesful auth set user into dcb field */ /* on succesful auth set user into dcb field */
if (auth_ret == 0) { if (auth_ret == 0)
{
dcb->user = strdup(client_data->user); dcb->user = strdup(client_data->user);
} }
else if (dcb->service->log_auth_warnings) else if (dcb->service->log_auth_warnings)
@ -612,7 +627,8 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF **buf) {
} }
/* let's free the auth_token now */ /* let's free the auth_token now */
if (auth_token) { if (auth_token)
{
free(auth_token); free(auth_token);
} }
@ -625,8 +641,7 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF **buf) {
* @param dcb The DCB of the client * @param dcb The DCB of the client
* @param queue Queue of buffers to write * @param queue Queue of buffers to write
*/ */
int int gw_MySQLWrite_client(DCB *dcb, GWBUF *queue)
gw_MySQLWrite_client(DCB *dcb, GWBUF *queue)
{ {
return dcb_write(dcb, queue); return dcb_write(dcb, queue);
} }
@ -639,8 +654,7 @@ gw_MySQLWrite_client(DCB *dcb, GWBUF *queue)
* @param dcb The DCB of the client * @param dcb The DCB of the client
* @param queue Queue of buffers to write * @param queue Queue of buffers to write
*/ */
int int gw_MySQLWrite_client_SSL(DCB *dcb, GWBUF *queue)
gw_MySQLWrite_client_SSL(DCB *dcb, GWBUF *queue)
{ {
CHK_DCB(dcb); CHK_DCB(dcb);
#ifdef SS_DEBUG #ifdef SS_DEBUG
@ -657,8 +671,7 @@ gw_MySQLWrite_client_SSL(DCB *dcb, GWBUF *queue)
* @param dcb Descriptor control block * @param dcb Descriptor control block
* @return 0 if succeed, 1 otherwise * @return 0 if succeed, 1 otherwise
*/ */
int gw_read_client_event( int gw_read_client_event(DCB* dcb)
DCB* dcb)
{ {
SESSION *session = NULL; SESSION *session = NULL;
ROUTER_OBJECT *router = NULL; ROUTER_OBJECT *router = NULL;
@ -701,8 +714,8 @@ int gw_read_client_event(
MXS_DEBUG("[gw_read_client_event] No data in socket after SSL auth"); MXS_DEBUG("[gw_read_client_event] No data in socket after SSL auth");
return 0; return 0;
} }
break;
} }
break;
case -1: case -1:
return 1; return 1;
@ -746,7 +759,8 @@ int gw_read_client_event(
session = dcb->session; session = dcb->session;
if (protocol->protocol_auth_state == MYSQL_IDLE && session != NULL && SESSION_STATE_DUMMY != session->state) if (protocol->protocol_auth_state == MYSQL_IDLE && session != NULL &&
SESSION_STATE_DUMMY != session->state)
{ {
CHK_SESSION(session); CHK_SESSION(session);
router = session->service->router; router = session->service->router;
@ -756,8 +770,7 @@ int gw_read_client_event(
if (NULL == router_instance || NULL == rsession) if (NULL == router_instance || NULL == rsession)
{ {
/** Send ERR 1045 to client */ /** Send ERR 1045 to client */
mysql_send_auth_error( mysql_send_auth_error(dcb,
dcb,
2, 2,
0, 0,
"failed to create new session"); "failed to create new session");
@ -779,7 +792,8 @@ int gw_read_client_event(
} }
} }
if (stmt_input) { if (stmt_input)
{
/** /**
* if read queue existed appent read to it. * if read queue existed appent read to it.
@ -835,8 +849,8 @@ int gw_read_client_event(
/** /**
* Now there should be at least one complete mysql packet in read_buffer. * Now there should be at least one complete mysql packet in read_buffer.
*/ */
switch (protocol->protocol_auth_state) { switch (protocol->protocol_auth_state)
{
case MYSQL_AUTH_SENT: case MYSQL_AUTH_SENT:
{ {
int auth_val; int auth_val;
@ -851,7 +865,10 @@ int gw_read_client_event(
/** SSL was requested and the handshake is either done or /** SSL was requested and the handshake is either done or
* still ongoing. After the handshake is done, the client * still ongoing. After the handshake is done, the client
* will send another auth packet. */ * will send another auth packet. */
while((read_buffer = gwbuf_consume(read_buffer,GWBUF_LENGTH(read_buffer)))); while ((read_buffer = gwbuf_consume(read_buffer,GWBUF_LENGTH(read_buffer))))
{
;
}
break; break;
} }
@ -870,7 +887,8 @@ int gw_read_client_event(
if (session != NULL) if (session != NULL)
{ {
CHK_SESSION(session); CHK_SESSION(session);
ss_dassert(session->state != SESSION_STATE_ALLOC && session->state != SESSION_STATE_DUMMY); ss_dassert(session->state != SESSION_STATE_ALLOC &&
session->state != SESSION_STATE_DUMMY);
protocol->protocol_auth_state = MYSQL_IDLE; protocol->protocol_auth_state = MYSQL_IDLE;
/** /**
@ -889,8 +907,7 @@ int gw_read_client_event(
protocol->owner_dcb->fd); protocol->owner_dcb->fd);
/** Send ERR 1045 to client */ /** Send ERR 1045 to client */
mysql_send_auth_error( mysql_send_auth_error(dcb,
dcb,
2, 2,
0, 0,
"failed to create new session"); "failed to create new session");
@ -904,7 +921,8 @@ int gw_read_client_event(
protocol->protocol_auth_state = MYSQL_AUTH_FAILED; protocol->protocol_auth_state = MYSQL_AUTH_FAILED;
if (auth_val == 2) { if (auth_val == 2)
{
/** Send error 1049 to client */ /** Send error 1049 to client */
int message_len = 25 + MYSQL_DATABASE_MAXLEN; int message_len = 25 + MYSQL_DATABASE_MAXLEN;
@ -913,7 +931,9 @@ int gw_read_client_event(
(char*)((MYSQL_session *)dcb->data)->db); (char*)((MYSQL_session *)dcb->data)->db);
modutil_send_mysql_err_packet(dcb, 2, 0, 1049, "42000", fail_str); modutil_send_mysql_err_packet(dcb, 2, 0, 1049, "42000", fail_str);
} else { }
else
{
/** Send error 1045 to client */ /** Send error 1045 to client */
fail_str = create_auth_fail_str((char *)((MYSQL_session *)dcb->data)->user, fail_str = create_auth_fail_str((char *)((MYSQL_session *)dcb->data)->user,
dcb->remote, dcb->remote,
@ -922,7 +942,9 @@ int gw_read_client_event(
modutil_send_mysql_err_packet(dcb, 2, 0, 1045, "28000", fail_str); modutil_send_mysql_err_packet(dcb, 2, 0, 1045, "28000", fail_str);
} }
if (fail_str) if (fail_str)
{
free(fail_str); free(fail_str);
}
MXS_DEBUG("%lu [gw_read_client_event] after " MXS_DEBUG("%lu [gw_read_client_event] after "
"gw_mysql_do_authentication, fd %d, " "gw_mysql_do_authentication, fd %d, "
@ -950,7 +972,6 @@ int gw_read_client_event(
auth_val = gw_mysql_do_authentication(dcb, &read_buffer); auth_val = gw_mysql_do_authentication(dcb, &read_buffer);
if (auth_val == 0) if (auth_val == 0)
{ {
SESSION *session; SESSION *session;
@ -966,7 +987,8 @@ int gw_read_client_event(
if (session != NULL) if (session != NULL)
{ {
CHK_SESSION(session); CHK_SESSION(session);
ss_dassert(session->state != SESSION_STATE_ALLOC && session->state != SESSION_STATE_DUMMY); ss_dassert(session->state != SESSION_STATE_ALLOC &&
session->state != SESSION_STATE_DUMMY);
protocol->protocol_auth_state = MYSQL_IDLE; protocol->protocol_auth_state = MYSQL_IDLE;
/** /**
@ -985,8 +1007,7 @@ int gw_read_client_event(
protocol->owner_dcb->fd); protocol->owner_dcb->fd);
/** Send ERR 1045 to client */ /** Send ERR 1045 to client */
mysql_send_auth_error( mysql_send_auth_error(dcb,
dcb,
3, 3,
0, 0,
"failed to create new session"); "failed to create new session");
@ -1000,7 +1021,8 @@ int gw_read_client_event(
protocol->protocol_auth_state = MYSQL_AUTH_FAILED; protocol->protocol_auth_state = MYSQL_AUTH_FAILED;
if (auth_val == 2) { if (auth_val == 2)
{
/** Send error 1049 to client */ /** Send error 1049 to client */
int message_len = 25 + MYSQL_DATABASE_MAXLEN; int message_len = 25 + MYSQL_DATABASE_MAXLEN;
@ -1009,7 +1031,9 @@ int gw_read_client_event(
(char*)((MYSQL_session *)dcb->data)->db); (char*)((MYSQL_session *)dcb->data)->db);
modutil_send_mysql_err_packet(dcb, 3, 0, 1049, "42000", fail_str); modutil_send_mysql_err_packet(dcb, 3, 0, 1049, "42000", fail_str);
}else { }
else
{
/** Send error 1045 to client */ /** Send error 1045 to client */
fail_str = create_auth_fail_str((char *)((MYSQL_session *)dcb->data)->user, fail_str = create_auth_fail_str((char *)((MYSQL_session *)dcb->data)->user,
dcb->remote, dcb->remote,
@ -1018,7 +1042,9 @@ int gw_read_client_event(
modutil_send_mysql_err_packet(dcb, 3, 0, 1045, "28000", fail_str); modutil_send_mysql_err_packet(dcb, 3, 0, 1045, "28000", fail_str);
} }
if (fail_str) if (fail_str)
{
free(fail_str); free(fail_str);
}
MXS_DEBUG("%lu [gw_read_client_event] after " MXS_DEBUG("%lu [gw_read_client_event] after "
"gw_mysql_do_authentication, fd %d, " "gw_mysql_do_authentication, fd %d, "
@ -1122,16 +1148,14 @@ int gw_read_client_event(
* Create error to be sent to client if session * Create error to be sent to client if session
* can't be continued. * can't be continued.
*/ */
errbuf = mysql_create_custom_error( errbuf = mysql_create_custom_error(1,
1,
0, 0,
"Routing failed. Session is closed."); "Routing failed. Session is closed.");
/** /**
* Ensure that there are enough backends * Ensure that there are enough backends
* available. * available.
*/ */
router->handleError( router->handleError(router_instance,
router_instance,
session->router_session, session->router_session,
errbuf, errbuf,
dcb, dcb,
@ -1159,7 +1183,10 @@ int gw_read_client_event(
{ {
MXS_INFO("Session received a query in state %s", MXS_INFO("Session received a query in state %s",
STRSESSIONSTATE(ses_state)); STRSESSIONSTATE(ses_state));
while((read_buffer = GWBUF_CONSUME_ALL(read_buffer)) != NULL); while ((read_buffer = GWBUF_CONSUME_ALL(read_buffer)) != NULL)
{
;
}
goto return_rc; goto return_rc;
} }
goto return_rc; goto return_rc;
@ -1209,15 +1236,18 @@ int gw_write_client_event(DCB *dcb)
ss_dassert(dcb->state != DCB_STATE_DISCONNECTED); ss_dassert(dcb->state != DCB_STATE_DISCONNECTED);
if (dcb == NULL) { if (dcb == NULL)
{
goto return_1; goto return_1;
} }
if (dcb->state == DCB_STATE_DISCONNECTED) { if (dcb->state == DCB_STATE_DISCONNECTED)
{
goto return_1; goto return_1;
} }
if (dcb->protocol == NULL) { if (dcb->protocol == NULL)
{
goto return_1; goto return_1;
} }
protocol = (MySQLProtocol *)dcb->protocol; protocol = (MySQLProtocol *)dcb->protocol;
@ -1256,15 +1286,18 @@ int gw_write_client_event_SSL(DCB *dcb)
ss_dassert(dcb->state != DCB_STATE_DISCONNECTED); ss_dassert(dcb->state != DCB_STATE_DISCONNECTED);
if (dcb == NULL) { if (dcb == NULL)
{
goto return_1; goto return_1;
} }
if (dcb->state == DCB_STATE_DISCONNECTED) { if (dcb->state == DCB_STATE_DISCONNECTED)
{
goto return_1; goto return_1;
} }
if (dcb->protocol == NULL) { if (dcb->protocol == NULL)
{
goto return_1; goto return_1;
} }
protocol = (MySQLProtocol *)dcb->protocol; protocol = (MySQLProtocol *)dcb->protocol;
@ -1291,11 +1324,11 @@ return_1:
/** /**
* Bind the DCB to a network port or a UNIX Domain Socket. * Bind the DCB to a network port or a UNIX Domain Socket.
* @param listen_dcb Listener DCB * @param listen_dcb Listener DCB
* @param config_bind Bind address in either IP:PORT format for network sockets or PATH for UNIX Domain Sockets * @param config_bind Bind address in either IP:PORT format for network sockets or PATH
* for UNIX Domain Sockets
* @return 1 on success, 0 on error * @return 1 on success, 0 on error
*/ */
int gw_MySQLListener(DCB *listen_dcb, int gw_MySQLListener(DCB *listen_dcb, char *config_bind)
char *config_bind)
{ {
int l_so; int l_so;
struct sockaddr_in serv_addr; struct sockaddr_in serv_addr;
@ -1311,7 +1344,9 @@ int gw_MySQLListener(DCB *listen_dcb,
{ {
char *tmp = strrchr(config_bind, ':'); char *tmp = strrchr(config_bind, ':');
if (tmp) if (tmp)
{
*tmp = '\0'; *tmp = '\0';
}
// UNIX socket create // UNIX socket create
if ((l_so = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) if ((l_so = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
@ -1327,7 +1362,6 @@ int gw_MySQLListener(DCB *listen_dcb,
strncpy(local_addr.sun_path, config_bind, sizeof(local_addr.sun_path) - 1); strncpy(local_addr.sun_path, config_bind, sizeof(local_addr.sun_path) - 1);
current_addr = (struct sockaddr *) &local_addr; current_addr = (struct sockaddr *) &local_addr;
} }
else else
{ {
@ -1497,8 +1531,8 @@ int gw_MySQLAccept(DCB *listener)
CHK_DCB(listener); CHK_DCB(listener);
while (1) { while (1)
{
retry_accept: retry_accept:
#if defined(FAKE_CODE) #if defined(FAKE_CODE)
@ -1507,7 +1541,9 @@ int gw_MySQLAccept(DCB *listener)
c_sock = -1; c_sock = -1;
eno = fail_accept_errno; eno = fail_accept_errno;
fail_next_accept -= 1; fail_next_accept -= 1;
} else { }
else
{
fail_accept_errno = 0; fail_accept_errno = 0;
#endif /* FAKE_CODE */ #endif /* FAKE_CODE */
// new connection from client // new connection from client
@ -1520,8 +1556,8 @@ int gw_MySQLAccept(DCB *listener)
} }
#endif /* FAKE_CODE */ #endif /* FAKE_CODE */
if (c_sock == -1) { if (c_sock == -1)
{
if (eno == EAGAIN || eno == EWOULDBLOCK) if (eno == EAGAIN || eno == EWOULDBLOCK)
{ {
/** /**
@ -1557,7 +1593,8 @@ int gw_MySQLAccept(DCB *listener)
ts1.tv_nsec = 100 * i * i * 1000000; ts1.tv_nsec = 100 * i * i * 1000000;
nanosleep(&ts1, NULL); nanosleep(&ts1, NULL);
if (i<10) { if (i < 10)
{
goto retry_accept; goto retry_accept;
} }
rc = 1; rc = 1;
@ -1597,14 +1634,16 @@ int gw_MySQLAccept(DCB *listener)
sendbuf = GW_CLIENT_SO_SNDBUF; sendbuf = GW_CLIENT_SO_SNDBUF;
char errbuf[STRERROR_BUFLEN]; char errbuf[STRERROR_BUFLEN];
if((syseno = setsockopt(c_sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, optlen)) != 0){ if ((syseno = setsockopt(c_sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, optlen)) != 0)
{
MXS_ERROR("Failed to set socket options. Error %d: %s", MXS_ERROR("Failed to set socket options. Error %d: %s",
errno, strerror_r(errno, errbuf, sizeof(errbuf))); errno, strerror_r(errno, errbuf, sizeof(errbuf)));
} }
sendbuf = GW_CLIENT_SO_RCVBUF; sendbuf = GW_CLIENT_SO_RCVBUF;
if((syseno = setsockopt(c_sock, SOL_SOCKET, SO_RCVBUF, &sendbuf, optlen)) != 0){ if ((syseno = setsockopt(c_sock, SOL_SOCKET, SO_RCVBUF, &sendbuf, optlen)) != 0)
{
MXS_ERROR("Failed to set socket options. Error %d: %s", MXS_ERROR("Failed to set socket options. Error %d: %s",
errno, strerror_r(errno, errbuf, sizeof(errbuf))); errno, strerror_r(errno, errbuf, sizeof(errbuf)));
} }
@ -1612,7 +1651,8 @@ int gw_MySQLAccept(DCB *listener)
client_dcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER); client_dcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER);
if (client_dcb == NULL) { if (client_dcb == NULL)
{
MXS_ERROR("Failed to create DCB object for client connection."); MXS_ERROR("Failed to create DCB object for client connection.");
close(c_sock); close(c_sock);
rc = 1; rc = 1;
@ -1651,7 +1691,8 @@ int gw_MySQLAccept(DCB *listener)
protocol = mysql_protocol_init(client_dcb, c_sock); protocol = mysql_protocol_init(client_dcb, c_sock);
ss_dassert(protocol != NULL); ss_dassert(protocol != NULL);
if (protocol == NULL) { if (protocol == NULL)
{
/** delete client_dcb */ /** delete client_dcb */
dcb_close(client_dcb); dcb_close(client_dcb);
MXS_ERROR("%lu [gw_MySQLAccept] Failed to create " MXS_ERROR("%lu [gw_MySQLAccept] Failed to create "
@ -1677,8 +1718,7 @@ int gw_MySQLAccept(DCB *listener)
if (poll_add_dcb(client_dcb) == -1) if (poll_add_dcb(client_dcb) == -1)
{ {
/* Send a custom error as MySQL command reply */ /* Send a custom error as MySQL command reply */
mysql_send_custom_error( mysql_send_custom_error(client_dcb,
client_dcb,
1, 1,
0, 0,
"MaxScale encountered system limit while " "MaxScale encountered system limit while "
@ -1706,7 +1746,8 @@ int gw_MySQLAccept(DCB *listener)
} }
} /**< while 1 */ } /**< while 1 */
#if defined(SS_DEBUG) #if defined(SS_DEBUG)
if (rc == 0) { if (rc == 0)
{
CHK_DCB(client_dcb); CHK_DCB(client_dcb);
CHK_PROTOCOL(((MySQLProtocol *)client_dcb->protocol)); CHK_PROTOCOL(((MySQLProtocol *)client_dcb->protocol));
} }
@ -1716,8 +1757,7 @@ return_rc:
return rc; return rc;
} }
static int gw_error_client_event( static int gw_error_client_event(DCB* dcb)
DCB* dcb)
{ {
SESSION* session; SESSION* session;
@ -1754,11 +1794,15 @@ gw_client_close(DCB *dcb)
void* router_instance; void* router_instance;
#if defined(SS_DEBUG) #if defined(SS_DEBUG)
MySQLProtocol* protocol = (MySQLProtocol *)dcb->protocol; MySQLProtocol* protocol = (MySQLProtocol *)dcb->protocol;
if (dcb->state == DCB_STATE_POLLING || if (dcb->state == DCB_STATE_POLLING ||
dcb->state == DCB_STATE_NOPOLLING || dcb->state == DCB_STATE_NOPOLLING ||
dcb->state == DCB_STATE_ZOMBIE) dcb->state == DCB_STATE_ZOMBIE)
{ {
if (!DCB_IS_CLONE(dcb)) CHK_PROTOCOL(protocol); if (!DCB_IS_CLONE(dcb))
{
CHK_PROTOCOL(protocol);
}
} }
#endif #endif
MXS_DEBUG("%lu [gw_client_close]", pthread_self()); MXS_DEBUG("%lu [gw_client_close]", pthread_self());
@ -1805,8 +1849,7 @@ gw_client_close(DCB *dcb)
* *
* @param dcb The DCB of the connection * @param dcb The DCB of the connection
*/ */
static int static int gw_client_hangup_event(DCB *dcb)
gw_client_hangup_event(DCB *dcb)
{ {
SESSION* session; SESSION* session;
@ -1844,9 +1887,7 @@ retblock:
* *
* @return 1 if succeed, * @return 1 if succeed,
*/ */
static int route_by_statement( static int route_by_statement(SESSION* session, GWBUF** p_readbuf)
SESSION* session,
GWBUF** p_readbuf)
{ {
int rc; int rc;
GWBUF* packetbuf; GWBUF* packetbuf;
@ -1955,7 +1996,6 @@ int do_ssl_accept(MySQLProtocol* protocol)
break; break;
case -1: case -1:
spinlock_acquire(&protocol->protocol_lock); spinlock_acquire(&protocol->protocol_lock);
protocol->protocol_auth_state = MYSQL_AUTH_SSL_HANDSHAKE_FAILED; protocol->protocol_auth_state = MYSQL_AUTH_SSL_HANDSHAKE_FAILED;
spinlock_release(&protocol->protocol_lock); spinlock_release(&protocol->protocol_lock);