From 77c759ac337bc5aa3343e447512f62a77af8e377 Mon Sep 17 00:00:00 2001 From: Massimiliano Pinto Date: Wed, 3 Jul 2013 10:01:35 +0200 Subject: [PATCH] New version of mysql async connect: preparing for the new connect() --- modules/protocol/mysql_backend.c | 40 +++++++++++++++++++++++++++----- modules/protocol/mysql_common.c | 37 ++++++++++++++++++----------- 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/modules/protocol/mysql_backend.c b/modules/protocol/mysql_backend.c index 600a847b4..663aed9af 100644 --- a/modules/protocol/mysql_backend.c +++ b/modules/protocol/mysql_backend.c @@ -33,6 +33,7 @@ * 27/06/2013 Vilho Raatikka Added skygw_log_write command as an example * and necessary headers. * 01/07/2013 Massimiliano Pinto Put Log Manager example code behind SS_DEBUG macros. + * 03/07/2013 Massimiliano Pinto Added delayq for incoming data before mysql connection */ static char *version_str = "V1.0.0"; @@ -44,6 +45,8 @@ static int gw_write_backend_event(DCB *dcb); static int gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue); static int gw_error_backend_event(DCB *dcb); static int gw_backend_close(DCB *dcb); +static int backend_write_delayqueue(DCB *dcb); +static void backend_set_delayqueue(DCB *dcb, GWBUF *queue); static GWPROTOCOL MyObject = { gw_read_backend_event, /* Read - EPOLLIN handler */ @@ -704,6 +707,31 @@ int gw_mysql_connect(char *host, int port, char *dbname, char *user, uint8_t *pa } +/** + * This routine put into the delay queue the input queue + * The input is what backend DCB is receiving + * The routine is called from func.write() when mysql backend connection + * is not yet complete buu there are inout data from client + * + * @param dcb The current backend DCB + * @param queue Input data in the GWBUF struct + */ +static void backend_set_delayqueue(DCB *dcb, GWBUF *queue) { + spinlock_acquire(&dcb->delayqlock); + + if (dcb->delayq) { + /* Append data */ + dcb->delayq = gwbuf_append(dcb->delayq, queue); + } else { + if (queue != NULL) { + /* create the delay queue */ + dcb->delayq = queue; + } + } + + spinlock_release(&dcb->delayqlock); +} + /** * This routine writes the delayq via dcb_write * The dcb->delayq contains data received from the client before @@ -714,15 +742,15 @@ int gw_mysql_connect(char *host, int port, char *dbname, char *user, uint8_t *pa */ static int backend_write_delayqueue(DCB *dcb) { - GWBUF *localq = NULL; + GWBUF *localq = NULL; - spinlock_acquire(&dcb->delayqlock); + spinlock_acquire(&dcb->delayqlock); - localq = dcb->delayq; - dcb->delayq = NULL; + localq = dcb->delayq; + dcb->delayq = NULL; - spinlock_release(&dcb->delayqlock); + spinlock_release(&dcb->delayqlock); - return dcb_write(dcb, localq); + return dcb_write(dcb, localq); } ///// diff --git a/modules/protocol/mysql_common.c b/modules/protocol/mysql_common.c index 397d18440..18d935d8e 100644 --- a/modules/protocol/mysql_common.c +++ b/modules/protocol/mysql_common.c @@ -130,7 +130,7 @@ int gw_read_backend_handshake(MySQLProtocol *conn) { return 1; } -/* +/** * Decode mysql server handshake */ int gw_decode_mysql_server_handshake(MySQLProtocol *conn, uint8_t *payload) { @@ -200,9 +200,12 @@ int gw_decode_mysql_server_handshake(MySQLProtocol *conn, uint8_t *payload) { return 0; } -/* - Receive the MySQL authentication packet from backend, packet # is 2 -*/ +/** + * Receive the MySQL authentication packet from backend, packet # is 2 + * + * @param conn The MySQL protocol structure + * @return 0 for user authenticated or 1 for authentication failed + */ int gw_receive_backend_auth(MySQLProtocol *conn) { int rv = 1; int n = -1; @@ -220,12 +223,8 @@ int gw_receive_backend_auth(MySQLProtocol *conn) { // check if the auth is SUCCESFUL if (ptr[4] == '\x00') { // Auth is OK - conn->state = MYSQL_IDLE; - rv = 0; } else { - conn->state = MYSQL_AUTH_FAILED; - rv = 1; } @@ -239,10 +238,15 @@ int gw_receive_backend_auth(MySQLProtocol *conn) { return rv; } -/* - * send authentication to backend +/** + * Write MySQL authentication packet to backend server + * + * @param conn MySQL protocol structure + * @param dbname The selected database + * @param user The selected user + * @param passwd The SHA1(real_password): Note real_password is unknown + * @return 0 on success, 1 on failure */ - int gw_send_authentication_to_backend(char *dbname, char *user, uint8_t *passwd, MySQLProtocol *conn) { int compress = 0; int rv; @@ -268,7 +272,9 @@ int gw_send_authentication_to_backend(char *dbname, char *user, uint8_t *passwd, dcb = conn->descriptor; +#ifdef DEBUG_MYSQL_CONN fprintf(stderr, ">> Sending credentials %s, %s, db %s\n", user, passwd, dbname); +#endif // Zero the vars memset(&server_capabilities, '\0', sizeof(server_capabilities)); @@ -281,8 +287,9 @@ int gw_send_authentication_to_backend(char *dbname, char *user, uint8_t *passwd, if (compress) { final_capabilities |= GW_MYSQL_CAPABILITIES_COMPRESS; +#ifdef DEBUG_MYSQL_CONN fprintf(stderr, ">>>> Backend Connection with compression\n"); - fflush(stderr); +#endif } if (curr_passwd != NULL) { @@ -318,7 +325,8 @@ int gw_send_authentication_to_backend(char *dbname, char *user, uint8_t *passwd, gw_mysql_set_byte4(client_capabilities, final_capabilities); - + // Protocol MySQL HandshakeResponse for CLIENT_PROTOCOL_41 + // 4 bytes capabilities + 4 bytes max packet size + 1 byte charset + 23 '\0' bytes // 4 + 4 + 1 + 23 = 32 bytes = 32; @@ -376,7 +384,7 @@ int gw_send_authentication_to_backend(char *dbname, char *user, uint8_t *passwd, // 23 bytes of 0 payload += 23; - // 4 + 4 + 4 + 1 + 23 = 36 + // 4 + 4 + 4 + 1 + 23 = 36, this includes the 4 bytes packet header memcpy(payload, user, strlen(user)); payload += strlen(user); @@ -409,6 +417,7 @@ int gw_send_authentication_to_backend(char *dbname, char *user, uint8_t *passwd, 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