log_manager.cc:

State update for filewriter was missing and that caused Maxscale to fail if opening of any log file failed.
dcb.c:
	Added EAGAIN and EWOULDBLOCK handling to dcb_read. If dcb_close is called for freshly created dcb, dcb is only freed.
gateway.c:
	Added file_write_footer and write_footer of which the latter is called at exit time. It simply draws a line to screen.
gw_utils.c:
	Some macros for helping comparison between gw_read_gwbuff and dcb_read, which overlap.
poll.c:
	Some macros to help enable/disable mutexing in poll_waitevents
service.c:
	Check return value of listen and session_alloc and behave accordingly.

mysql_client.c:
	If ioctl returned successfully with b==0 it earlier caused closing the client and backend dcbs. Since that doesn't reliably indicate that client has closed socket on its side, Maxscale doesn't close its sockets either.
mysql_common.c:
	In gw_receive_backend_auth, if dcb_read returns n==0, it is not considered as an error anymore. The implemented behavior is not yet complete and correct. Result should be successful but the protocol state shouldn't change to MYSQL_IDLE before backend return is received.
	In gw_send_authentication_to_backend protocol state was always set to MYSQL_AUTH_RECV even if gw_rwite had failed. Now, return value is read and state is set in caller's context basen on the return value.
skygw_utils.cc:
	Removed ss_dassert from skyge_file_init because it prevented from returning meaningful error meassage to the client.:
This commit is contained in:
vraatikka
2013-10-06 22:31:32 +03:00
parent e3a4be8b9d
commit 80b67d1083
11 changed files with 318 additions and 186 deletions

View File

@ -166,8 +166,8 @@ int gw_read_backend_handshake(MySQLProtocol *conn) {
if (h_len < (packet_len + 4)) {
/*
* data in buffer less than expected in the packet
* log error this exit point
* data in buffer less than expected in the
* packet. Log error this exit point
*/
conn->state = MYSQL_AUTH_FAILED;
return 1;
@ -177,7 +177,8 @@ int gw_read_backend_handshake(MySQLProtocol *conn) {
payload += 4;
//Now decode mysql handshake
success = gw_decode_mysql_server_handshake(conn, payload);
success = gw_decode_mysql_server_handshake(conn,
payload);
if (success < 0) {
/* MySQL handshake has not been properly decoded
@ -308,7 +309,10 @@ bool gw_receive_backend_auth(
n = dcb_read(dcb, &head);
if (n != -1 &&
/**
* Read didn't fail and there is enough data for mysql packet.
*/
if (n != -1 &&
head != NULL &&
GWBUF_LENGTH(head) >= 5)
{
@ -318,11 +322,52 @@ bool gw_receive_backend_auth(
*/
if (ptr[4] == '\x00') {
succp = true;
} else {
uint8_t* tmpbuf =
(uint8_t *)calloc(1, GWBUF_LENGTH(head)+1);
memcpy(tmpbuf, ptr, GWBUF_LENGTH(head));
skygw_log_write(
LOGFILE_TRACE,
"%lu [gw_receive_backend_auth] Invalid "
"authentication message from backend dcb %p "
"fd %d, ptr[4] = %p, msg %s.",
pthread_self(),
dcb,
dcb->fd,
tmpbuf[4],
tmpbuf);
skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Invalid authentication message from "
"backend server. Authentication failed.");
free(tmpbuf);
}
/**
* Remove data from buffer.
*/
head = gwbuf_consume(head, gwbuf_length(head));
} else {
#if 1
/**
* This is considered as success because call didn't fail,
* although no bytes was read.
*/
if (n == 0) {
succp = true;
}
#endif
skygw_log_write(
LOGFILE_TRACE,
"%lu [gw_receive_backend_auth] Reading from backend dcb "
"%p fd %d in state %s failed. n %d, head %p, len %d",
pthread_self(),
dcb,
dcb->fd,
STRDCBSTATE(dcb->state),
n,
head,
(head == NULL) ? 0 : GWBUF_LENGTH(head));
}
return succp;
}
@ -506,27 +551,22 @@ int gw_send_authentication_to_backend(
payload++;
}
memcpy(payload, "mysql_native_password", strlen("mysql_native_password"));
memcpy(payload,
"mysql_native_password",
strlen("mysql_native_password"));
payload += strlen("mysql_native_password");
payload++;
// put here the paylod size: bytes to write - 4 bytes packet header
gw_mysql_set_byte3(payload_start, (bytes-4));
// write to backend dcb
// ToDO: handle the EAGAIN | EWOULDBLOCK
rv = gw_write(dcb->fd, GWBUF_DATA(buffer), bytes);
rv = dcb_write(dcb, buffer);
gwbuf_consume(buffer, bytes);
/* Set the new state, next would be MYSQL_IDLE or MYSQL_AUTH_FAILED */
conn->state = MYSQL_AUTH_RECV;
if (rv < 0)
return rv;
else
return 0;
if (rv < 0) {
return rv;
} else {
return 0;
}
}
/**