173 lines
5.1 KiB
C
173 lines
5.1 KiB
C
/*
|
|
* This file is distributed as part of the SkySQL Gateway. It is free
|
|
* software: you can redistribute it and/or modify it under the terms of the
|
|
* GNU General Public License as published by the Free Software Foundation,
|
|
* version 2.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program; if not, write to the Free Software Foundation, Inc., 51
|
|
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Copyright SkySQL Ab 2013
|
|
*/
|
|
|
|
/*
|
|
* MySQL Protocol common routines for client to gateway and gateway to backend
|
|
*
|
|
* Revision History
|
|
* Date Who Description
|
|
* 17/06/2013 Massimiliano Pinto Common MySQL protocol routines
|
|
*/
|
|
|
|
#include "mysql_client_server_protocol.h"
|
|
|
|
static char *version_str = "V1.0.0";
|
|
|
|
//static int gw_create_backend_connection(DCB *client_dcb, int efd);
|
|
static MySQLProtocol *gw_mysql_init(MySQLProtocol *data);
|
|
static void gw_mysql_close(MySQLProtocol **ptr);
|
|
|
|
extern gw_read_backend_event(DCB* dcb);
|
|
extern gw_write_backend_event(DCB *dcb);
|
|
extern int gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue);
|
|
extern int gw_error_backend_event(DCB *dcb);
|
|
|
|
///////////////////////////////
|
|
// Initialize mysql protocol struct
|
|
///////////////////////////////////////
|
|
MySQLProtocol *gw_mysql_init(MySQLProtocol *data) {
|
|
int rv = -1;
|
|
|
|
MySQLProtocol *input = NULL;
|
|
|
|
if (input == NULL) {
|
|
// structure allocation
|
|
input = calloc(1, sizeof(MySQLProtocol));
|
|
|
|
if (input == NULL)
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#ifdef MYSQL_CONN_DEBUG
|
|
fprintf(stderr, "gw_mysql_init() called\n");
|
|
#endif
|
|
|
|
return input;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////
|
|
// close a connection if opened
|
|
// free data scructure for MySQLProtocol
|
|
//////////////////////////////////////
|
|
void gw_mysql_close(MySQLProtocol **ptr) {
|
|
MySQLProtocol *conn = *ptr;
|
|
|
|
if (*ptr == NULL)
|
|
return;
|
|
|
|
#ifdef MYSQL_CONN_DEBUG
|
|
fprintf(stderr, "Closing MySQL connection %i, [%s]\n", conn->fd, conn->scramble);
|
|
#endif
|
|
|
|
if (conn->fd > 0) {
|
|
//COM_QUIT will not be sent here, but from the caller of this routine!
|
|
#ifdef MYSQL_CONN_DEBUG
|
|
fprintf(stderr, "mysqlgw_mysql_close() called for %i\n", conn->fd);
|
|
#endif
|
|
close(conn->fd);
|
|
} else {
|
|
#ifdef MYSQL_CONN_DEBUG
|
|
fprintf(stderr, "mysqlgw_mysql_close() called, no socket %i\n", conn->fd);
|
|
#endif
|
|
}
|
|
|
|
free(*ptr);
|
|
|
|
*ptr = NULL;
|
|
|
|
#ifdef MYSQL_CONN_DEBUG
|
|
fprintf(stderr, "mysqlgw_mysql_close() free(conn) done\n");
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* Create a new MySQL backend connection.
|
|
*
|
|
* This routine performs the MySQL connection to the backend and fills the session->backends of the callier dcb
|
|
* with the new allocatetd dcb and adds the new socket to the poll set
|
|
*
|
|
* - backend dcb allocation
|
|
* - MySQL session data fetch
|
|
* - backend connection using data in MySQL session
|
|
*
|
|
* @param client_dcb The client DCB struct
|
|
* @return 0 on Success or 1 on Failure.
|
|
*/
|
|
|
|
/*
|
|
* This function cannot work as it will be called from mysql_client.c but it needs function pointers from mysql_backend.c
|
|
* They are modules loaded separately!!
|
|
*
|
|
int gw_create_backend_connection(DCB *client_dcb) {
|
|
DCB *backend = NULL;
|
|
MySQLProtocol *ptr_proto = NULL;
|
|
MySQLProtocol *client_protocol = NULL;
|
|
SESSION *session = NULL;
|
|
MYSQL_session *s_data = NULL;
|
|
|
|
backend = (DCB *) calloc(1, sizeof(DCB));
|
|
backend->state = DCB_STATE_ALLOC;
|
|
backend->session = NULL;
|
|
backend->protocol = (MySQLProtocol *)gw_mysql_init(NULL);
|
|
|
|
ptr_proto = (MySQLProtocol *)backend->protocol;
|
|
client_protocol = (MySQLProtocol *)client_dcb->protocol;
|
|
session = DCB_SESSION(client_dcb);
|
|
s_data = (MYSQL_session *)session->data;
|
|
|
|
// this is blocking until auth done
|
|
if (gw_mysql_connect("127.0.0.1", 3306, s_data->db, s_data->user, s_data->client_sha1, backend->protocol) == 0) {
|
|
fprintf(stderr, "Connected to backend mysql server\n");
|
|
backend->fd = ptr_proto->fd;
|
|
setnonblocking(backend->fd);
|
|
} else {
|
|
fprintf(stderr, "<<<< NOT Connected to backend mysql server!!!\n");
|
|
backend->fd = -1;
|
|
}
|
|
|
|
// edge triggering flag added
|
|
ee.events = EPOLLIN | EPOLLET | EPOLLOUT;
|
|
ee.data.ptr = backend;
|
|
|
|
// if connected, add it to the epoll
|
|
if (backend->fd > 0) {
|
|
if (epoll_ctl(efd, EPOLL_CTL_ADD, backend->fd, &ee) == -1) {
|
|
perror("epoll_ctl: backend sock");
|
|
} else {
|
|
fprintf(stderr, "--> Backend conn added, bk_fd [%i], scramble [%s], is session with client_fd [%i]\n", ptr_proto->fd, ptr_proto->scramble, client_dcb->fd);
|
|
backend->state = DCB_STATE_POLLING;
|
|
backend->session = DCB_SESSION(client_dcb);
|
|
(backend->func).read = gw_read_backend_event;
|
|
(backend->func).write = gw_MySQLWrite_backend;
|
|
(backend->func).write_ready = gw_write_backend_event;
|
|
(backend->func).error = gw_error_backend_event;
|
|
|
|
// assume here one backend only.
|
|
// in session.h
|
|
// struct dcb *backends;
|
|
// instead of a list **backends;
|
|
client_dcb->session->backends = backend;
|
|
}
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
*/
|