Merge branch 'release-1.0GA' into MAX-324

Conflicts:
	server/MaxScale_template.cnf
	server/core/service.c
This commit is contained in:
Markus Makela
2015-01-06 04:45:30 +02:00
96 changed files with 2931 additions and 1001 deletions

View File

@ -510,6 +510,16 @@ static int gw_read_backend_event(DCB *dcb) {
if (nbytes_read < 5) /*< read at least command type */
{
rc = 0;
LOGIF(LD, (skygw_log_write_flush(
LOGFILE_DEBUG,
"%p [gw_read_backend_event] Read %d bytes "
"from DCB %p, fd %d, session %s. "
"Returning to poll wait.\n",
pthread_self(),
nbytes_read,
dcb,
dcb->fd,
dcb->session)));
goto return_rc;
}
/** There is at least length and command type. */
@ -699,16 +709,6 @@ gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue)
switch (backend_protocol->protocol_auth_state) {
case MYSQL_HANDSHAKE_FAILED:
case MYSQL_AUTH_FAILED:
{
size_t len;
char* str;
uint8_t* packet = (uint8_t *)queue->start;
uint8_t* startpoint;
len = (size_t)MYSQL_GET_PACKET_LEN(packet);
startpoint = &packet[5];
str = (char *)malloc(len+1);
snprintf(str, len+1, "%s", startpoint);
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Unable to write to backend due to "
@ -717,13 +717,11 @@ gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue)
while ((queue = gwbuf_consume(
queue,
GWBUF_LENGTH(queue))) != NULL);
free(str);
rc = 0;
spinlock_release(&dcb->authlock);
goto return_rc;
break;
}
case MYSQL_IDLE:
{
uint8_t* ptr = GWBUF_DATA(queue);
@ -1165,22 +1163,37 @@ gw_backend_close(DCB *dcb)
mysql_send_com_quit(dcb, 0, quitbuf);
mysql_protocol_done(dcb);
/**
* The lock is needed only to protect the read of session->state and
* session->client values. Client's state may change by other thread
* but client's close and adding client's DCB to zombies list is executed
* only if client's DCB's state does _not_ change in parallel.
*/
spinlock_acquire(&session->ses_lock);
/**
* If session->state is STOPPING, start closing client session.
* Otherwise only this backend connection is closed.
*/
if (session != NULL && session->state == SESSION_STATE_STOPPING)
{
client_dcb = session->client;
if (client_dcb != NULL &&
client_dcb->state == DCB_STATE_POLLING)
if (session != NULL &&
session->state == SESSION_STATE_STOPPING &&
session->client != NULL)
{
if (session->client->state == DCB_STATE_POLLING)
{
spinlock_release(&session->ses_lock);
/** Close client DCB */
dcb_close(client_dcb);
dcb_close(session->client);
}
else
{
spinlock_release(&session->ses_lock);
}
}
else
{
spinlock_release(&session->ses_lock);
}
return 1;
}
@ -1495,7 +1508,7 @@ static GWBUF* process_response_data (
/** Get command which was stored in gw_MySQLWrite_backend */
p = DCB_PROTOCOL(dcb, MySQLProtocol);
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);
@ -1510,7 +1523,14 @@ static GWBUF* process_response_data (
bool succp;
srvcmd = protocol_get_srv_command(p, false);
LOGIF(LD, (skygw_log_write(
LOGFILE_DEBUG,
"%lu [process_response_data] Read command %s for DCB %p fd %d.",
pthread_self(),
STRPACKETTYPE(srvcmd),
dcb,
dcb->fd)));
/**
* Read values from protocol structure, fails if values are
* uninitialized.
@ -1582,7 +1602,7 @@ static GWBUF* process_response_data (
if (nbytes_left == 0)
{
/** No more packets in this response */
if (npackets_left == 0)
if (npackets_left == 0 && outbuf != NULL)
{
GWBUF* b = outbuf;
@ -1622,7 +1642,7 @@ static bool sescmd_response_complete(
bool succp;
p = DCB_PROTOCOL(dcb, MySQLProtocol);
CHK_PROTOCOL(p);
if (!DCB_IS_CLONE(dcb)) CHK_PROTOCOL(p);
protocol_get_response_status(p, &npackets_left, &nbytes_left);

View File

@ -144,7 +144,7 @@ GetModuleObject()
int
mysql_send_ok(DCB *dcb, int packet_number, int in_affected_rows, const char* mysql_message) {
uint8_t *outbuf = NULL;
uint8_t mysql_payload_size = 0;
uint32_t mysql_payload_size = 0;
uint8_t mysql_packet_header[4];
uint8_t *mysql_payload = NULL;
uint8_t field_count = 0;
@ -223,7 +223,7 @@ int
MySQLSendHandshake(DCB* dcb)
{
uint8_t *outbuf = NULL;
uint8_t mysql_payload_size = 0;
uint32_t mysql_payload_size = 0;
uint8_t mysql_packet_header[4];
uint8_t mysql_packet_id = 0;
uint8_t mysql_filler = GW_MYSQL_HANDSHAKE_FILLER;
@ -283,7 +283,6 @@ MySQLSendHandshake(DCB* dcb)
// write packet heder with mysql_payload_size
gw_mysql_set_byte3(mysql_packet_header, mysql_payload_size);
//mysql_packet_header[0] = mysql_payload_size;
// write packent number, now is 0
mysql_packet_header[3]= mysql_packet_id;
@ -378,15 +377,18 @@ MySQLSendHandshake(DCB* dcb)
*
* Performs the MySQL protocol 4.1 authentication, using data in GWBUF *queue
*
* The useful data: user, db, client_sha1 are copied into the MYSQL_session * dcb->session->data
* (MYSQL_session*)client_data including: user, db, client_sha1 are copied into
* the dcb->data and later to dcb->session->data.
*
* client_capabilitiesa are copied into the dcb->protocol
*
* @param dcb Descriptor Control Block of the client
* @param queue The GWBUF with data from client
* @return 0 If succeed, otherwise non-zero value
*
* @note in case of failure, dcb->data is freed before returning. If succeed,
* dcb->data is freed in session.c:session_free.
*/
static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
MySQLProtocol *protocol = NULL;
/* int compress = -1; */
@ -406,6 +408,13 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
protocol = DCB_PROTOCOL(dcb, MySQLProtocol);
CHK_PROTOCOL(protocol);
client_data = (MYSQL_session *)calloc(1, sizeof(MYSQL_session));
#if defined(SS_DEBUG)
client_data->myses_chk_top = CHK_NUM_MYSQLSES;
client_data->myses_chk_tail = CHK_NUM_MYSQLSES;
#endif
/**
* Assign authentication structure with client DCB.
*/
dcb->data = client_data;
stage1_hash = client_data->client_sha1;
@ -426,7 +435,8 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
*/
/* Detect now if there are enough bytes to continue */
if (client_auth_packet_size < (4 + 4 + 4 + 1 + 23)) {
if (client_auth_packet_size < (4 + 4 + 4 + 1 + 23))
{
return 1;
}
@ -619,7 +629,7 @@ int gw_read_client_event(
* Now there should be at least one complete mysql packet in read_buffer.
*/
switch (protocol->protocol_auth_state) {
case MYSQL_AUTH_SENT:
{
int auth_val;
@ -658,8 +668,8 @@ int gw_read_client_event(
"%lu [gw_read_client_event] session "
"creation failed. fd %d, "
"state = MYSQL_AUTH_FAILED.",
protocol->owner_dcb->fd,
pthread_self())));
pthread_self(),
protocol->owner_dcb->fd)));
/** Send ERR 1045 to client */
mysql_send_auth_error(
@ -671,7 +681,7 @@ int gw_read_client_event(
dcb_close(dcb);
}
}
else
else
{
char* fail_str = NULL;
@ -704,7 +714,15 @@ int gw_read_client_event(
"state = MYSQL_AUTH_FAILED.",
protocol->owner_dcb->fd,
pthread_self())));
/**
* Release MYSQL_session since it is not used anymore.
*/
if (!DCB_IS_CLONE(dcb))
{
free(dcb->data);
}
dcb->data = NULL;
dcb_close(dcb);
}
read_buffer = gwbuf_consume(read_buffer, nbytes_read);
@ -1396,15 +1414,13 @@ gw_client_close(DCB *dcb)
dcb->state == DCB_STATE_NOPOLLING ||
dcb->state == DCB_STATE_ZOMBIE)
{
CHK_PROTOCOL(protocol);
if (!DCB_IS_CLONE(dcb)) CHK_PROTOCOL(protocol);
}
#endif
LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG,
"%lu [gw_client_close]",
pthread_self())));
mysql_protocol_done(dcb);
mysql_protocol_done(dcb);
session = dcb->session;
/**
* session may be NULL if session_alloc failed.

View File

@ -151,38 +151,6 @@ retblock:
}
/**
* gw_mysql_close
*
* close a connection if opened
* free data scructure for MySQLProtocol
*
* @param ptr The MySQLProtocol ** to close/free
*
*/
void gw_mysql_close(MySQLProtocol **ptr) {
MySQLProtocol *conn = *ptr;
ss_dassert(*ptr != NULL);
if (*ptr == NULL)
return;
if (conn->fd > 0) {
/* COM_QUIT will not be sent here, but from the caller of this routine! */
close(conn->fd);
} else {
// no socket here
}
free(*ptr);
*ptr = NULL;
}
/**
* Read the backend server MySQL handshake
*
@ -573,6 +541,16 @@ int gw_send_authentication_to_backend(
uint8_t *curr_passwd = NULL;
unsigned int charset;
/**
* If session is stopping return with error.
*/
if (conn->owner_dcb->session == NULL ||
(conn->owner_dcb->session->state != SESSION_STATE_READY &&
conn->owner_dcb->session->state != SESSION_STATE_ROUTER_READY))
{
return 1;
}
if (strlen(dbname))
curr_db = dbname;
@ -1661,7 +1639,9 @@ mysql_send_auth_error (
* Buffer contains at least one of the following:
* complete [complete] [partial] mysql packet
*
* return pointer to gwbuf containing a complete packet or
* @param p_readbuf Address of read buffer pointer
*
* @return pointer to gwbuf containing a complete packet or
* NULL if no complete packet was found.
*/
GWBUF* gw_MySQL_get_next_packet(