mysql_client_server_protocol.h, new file name that avoids conflicts with previous one
This commit is contained in:
parent
f4711f5980
commit
4d5215e267
201
modules/include/mysql_client_server_protocol.h
Normal file
201
modules/include/mysql_client_server_protocol.h
Normal file
@ -0,0 +1,201 @@
|
||||
#ifndef _MYSQL_PROTOCOL_H
|
||||
#define _MYSQL_PROTOCOL_H
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 01-06-2013 Mark Riddoch Initial implementation
|
||||
* 14-06-2013 Massimiliano Pinto Added specific data
|
||||
* for MySQL session
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdbool.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "dcb.h"
|
||||
#include "session.h"
|
||||
#include "buffer.h"
|
||||
|
||||
#ifndef MYSQL_SCRAMBLE_LEN
|
||||
#define MYSQL_SCRAMBLE_LEN GW_MYSQL_SCRAMBLE_SIZE
|
||||
#endif
|
||||
|
||||
#define MYSQL_USER_MAXLEN 128
|
||||
#define MYSQL_DATABASE_MAXLEN 128
|
||||
|
||||
#define GW_VERSION "0.1.0"
|
||||
#define GW_MYSQL_VERSION "5.5.22-SKYSQL-" GW_VERSION
|
||||
#define GW_MYSQL_LOOP_TIMEOUT 300000000
|
||||
#define GW_MYSQL_READ 0
|
||||
#define GW_MYSQL_WRITE 1
|
||||
|
||||
#define GW_MYSQL_PROTOCOL_VERSION 10 // version is 10
|
||||
#define GW_MYSQL_HANDSHAKE_FILLER 0x00
|
||||
#define GW_MYSQL_SERVER_CAPABILITIES_BYTE1 0xff
|
||||
#define GW_MYSQL_SERVER_CAPABILITIES_BYTE2 0xf7
|
||||
#define GW_MYSQL_SERVER_LANGUAGE 0x08
|
||||
#define GW_MYSQL_MAX_PACKET_LEN 0xffffffL;
|
||||
#define GW_MYSQL_SCRAMBLE_SIZE 20
|
||||
|
||||
#define GW_NOINTR_CALL(A) do { errno = 0; A; } while (errno == EINTR)
|
||||
// network buffer is 32K
|
||||
#define MAX_BUFFER_SIZE 32768
|
||||
// socket send buffer for backend
|
||||
#define GW_BACKEND_SO_SNDBUF 1024
|
||||
#define SMALL_CHUNK 1024
|
||||
#define MAX_CHUNK SMALL_CHUNK * 8 * 4
|
||||
#define ToHex(Y) (Y>='0'&&Y<='9'?Y-'0':Y-'A'+10)
|
||||
|
||||
struct dcb;
|
||||
|
||||
/*
|
||||
* MySQL Protocol specific state data
|
||||
*/
|
||||
typedef struct {
|
||||
int fd; /* The socket descriptor */
|
||||
struct dcb *descriptor; /* The DCB of the socket we are running on */
|
||||
int state; /* Current descriptor state */
|
||||
char scramble[MYSQL_SCRAMBLE_LEN]; /* server scramble, created or received */
|
||||
uint32_t server_capabilities; /* server capabilities, created or received */
|
||||
uint32_t client_capabilities; /* client capabilities, created or received */
|
||||
unsigned long tid; /* MySQL Thread ID, in handshake */
|
||||
} MySQLProtocol;
|
||||
|
||||
/*
|
||||
* MySQL session specific data
|
||||
*
|
||||
*/
|
||||
typedef struct mysql_session {
|
||||
uint8_t client_sha1[MYSQL_SCRAMBLE_LEN]; /* SHA1(passowrd) */
|
||||
char user[MYSQL_USER_MAXLEN]; /* username */
|
||||
char db[MYSQL_DATABASE_MAXLEN]; /* database */
|
||||
} MYSQL_session;
|
||||
|
||||
/* MySQL Protocol States */
|
||||
#define MYSQL_ALLOC 0 /* Allocate data */
|
||||
#define MYSQL_AUTH_SENT 1 /* Authentication handshake has been sent */
|
||||
#define MYSQL_AUTH_RECV 2 /* Received user, password, db and capabilities */
|
||||
#define MYSQL_AUTH_FAILED 3 /* Auth failed, return error packet */
|
||||
#define MYSQL_IDLE 4 /* Auth done. Protocol is idle, waiting for statements */
|
||||
#define MYSQL_ROUTING 5 /* The received command has been routed to backend(s) */
|
||||
#define MYSQL_WAITING_RESULT 6 /* Waiting for result set */
|
||||
|
||||
/* Protocol packing macros. */
|
||||
#define gw_mysql_set_byte2(__buffer, __int) do { \
|
||||
(__buffer)[0]= (uint8_t)((__int) & 0xFF); \
|
||||
(__buffer)[1]= (uint8_t)(((__int) >> 8) & 0xFF); } while (0)
|
||||
#define gw_mysql_set_byte3(__buffer, __int) do { \
|
||||
(__buffer)[0]= (uint8_t)((__int) & 0xFF); \
|
||||
(__buffer)[1]= (uint8_t)(((__int) >> 8) & 0xFF); \
|
||||
(__buffer)[2]= (uint8_t)(((__int) >> 16) & 0xFF); } while (0)
|
||||
#define gw_mysql_set_byte4(__buffer, __int) do { \
|
||||
(__buffer)[0]= (uint8_t)((__int) & 0xFF); \
|
||||
(__buffer)[1]= (uint8_t)(((__int) >> 8) & 0xFF); \
|
||||
(__buffer)[2]= (uint8_t)(((__int) >> 16) & 0xFF); \
|
||||
(__buffer)[3]= (uint8_t)(((__int) >> 24) & 0xFF); } while (0)
|
||||
|
||||
/* Protocol unpacking macros. */
|
||||
#define gw_mysql_get_byte2(__buffer) \
|
||||
(uint16_t)((__buffer)[0] | \
|
||||
((__buffer)[1] << 8))
|
||||
#define gw_mysql_get_byte3(__buffer) \
|
||||
(uint32_t)((__buffer)[0] | \
|
||||
((__buffer)[1] << 8) | \
|
||||
((__buffer)[2] << 16))
|
||||
#define gw_mysql_get_byte4(__buffer) \
|
||||
(uint32_t)((__buffer)[0] | \
|
||||
((__buffer)[1] << 8) | \
|
||||
((__buffer)[2] << 16) | \
|
||||
((__buffer)[3] << 24))
|
||||
#define gw_mysql_get_byte8(__buffer) \
|
||||
((uint64_t)(__buffer)[0] | \
|
||||
((uint64_t)(__buffer)[1] << 8) | \
|
||||
((uint64_t)(__buffer)[2] << 16) | \
|
||||
((uint64_t)(__buffer)[3] << 24) | \
|
||||
((uint64_t)(__buffer)[4] << 32) | \
|
||||
((uint64_t)(__buffer)[5] << 40) | \
|
||||
((uint64_t)(__buffer)[6] << 48) | \
|
||||
((uint64_t)(__buffer)[7] << 56))
|
||||
|
||||
/* MySQL protocol constants */
|
||||
typedef enum
|
||||
{
|
||||
GW_MYSQL_CAPABILITIES_NONE= 0,
|
||||
GW_MYSQL_CAPABILITIES_LONG_PASSWORD= (1 << 0),
|
||||
GW_MYSQL_CAPABILITIES_FOUND_ROWS= (1 << 1),
|
||||
GW_MYSQL_CAPABILITIES_LONG_FLAG= (1 << 2),
|
||||
GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB= (1 << 3),
|
||||
GW_MYSQL_CAPABILITIES_NO_SCHEMA= (1 << 4),
|
||||
GW_MYSQL_CAPABILITIES_COMPRESS= (1 << 5),
|
||||
GW_MYSQL_CAPABILITIES_ODBC= (1 << 6),
|
||||
GW_MYSQL_CAPABILITIES_LOCAL_FILES= (1 << 7),
|
||||
GW_MYSQL_CAPABILITIES_IGNORE_SPACE= (1 << 8),
|
||||
GW_MYSQL_CAPABILITIES_PROTOCOL_41= (1 << 9),
|
||||
GW_MYSQL_CAPABILITIES_INTERACTIVE= (1 << 10),
|
||||
GW_MYSQL_CAPABILITIES_SSL= (1 << 11),
|
||||
GW_MYSQL_CAPABILITIES_IGNORE_SIGPIPE= (1 << 12),
|
||||
GW_MYSQL_CAPABILITIES_TRANSACTIONS= (1 << 13),
|
||||
GW_MYSQL_CAPABILITIES_RESERVED= (1 << 14),
|
||||
GW_MYSQL_CAPABILITIES_SECURE_CONNECTION= (1 << 15),
|
||||
GW_MYSQL_CAPABILITIES_MULTI_STATEMENTS= (1 << 16),
|
||||
GW_MYSQL_CAPABILITIES_MULTI_RESULTS= (1 << 17),
|
||||
GW_MYSQL_CAPABILITIES_PS_MULTI_RESULTS= (1 << 18),
|
||||
GW_MYSQL_CAPABILITIES_PLUGIN_AUTH= (1 << 19),
|
||||
GW_MYSQL_CAPABILITIES_SSL_VERIFY_SERVER_CERT= (1 << 30),
|
||||
GW_MYSQL_CAPABILITIES_REMEMBER_OPTIONS= (1 << 31),
|
||||
GW_MYSQL_CAPABILITIES_CLIENT= (GW_MYSQL_CAPABILITIES_LONG_PASSWORD |
|
||||
GW_MYSQL_CAPABILITIES_FOUND_ROWS |
|
||||
GW_MYSQL_CAPABILITIES_LONG_FLAG |
|
||||
GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB |
|
||||
GW_MYSQL_CAPABILITIES_LOCAL_FILES |
|
||||
GW_MYSQL_CAPABILITIES_PLUGIN_AUTH |
|
||||
GW_MYSQL_CAPABILITIES_TRANSACTIONS |
|
||||
GW_MYSQL_CAPABILITIES_PROTOCOL_41 |
|
||||
GW_MYSQL_CAPABILITIES_MULTI_STATEMENTS |
|
||||
GW_MYSQL_CAPABILITIES_MULTI_RESULTS |
|
||||
GW_MYSQL_CAPABILITIES_PS_MULTI_RESULTS |
|
||||
GW_MYSQL_CAPABILITIES_SECURE_CONNECTION),
|
||||
GW_MYSQL_CAPABILITIES_CLIENT_COMPRESS= (GW_MYSQL_CAPABILITIES_LONG_PASSWORD |
|
||||
GW_MYSQL_CAPABILITIES_FOUND_ROWS |
|
||||
GW_MYSQL_CAPABILITIES_LONG_FLAG |
|
||||
GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB |
|
||||
GW_MYSQL_CAPABILITIES_LOCAL_FILES |
|
||||
GW_MYSQL_CAPABILITIES_PLUGIN_AUTH |
|
||||
GW_MYSQL_CAPABILITIES_TRANSACTIONS |
|
||||
GW_MYSQL_CAPABILITIES_PROTOCOL_41 |
|
||||
GW_MYSQL_CAPABILITIES_MULTI_STATEMENTS |
|
||||
GW_MYSQL_CAPABILITIES_MULTI_RESULTS |
|
||||
GW_MYSQL_CAPABILITIES_PS_MULTI_RESULTS |
|
||||
GW_MYSQL_CAPABILITIES_COMPRESS
|
||||
),
|
||||
} gw_mysql_capabilities_t;
|
||||
#endif
|
@ -20,7 +20,7 @@
|
||||
# 17/06/2013 Massimiliano Pinto Added mysql_common top both libraries
|
||||
|
||||
CC=cc
|
||||
CFLAGS=-c -fPIC -I/usr/include -I../include -I../../include -Wall
|
||||
CFLAGS=-c -fPIC -I/usr/include -I../include -I../../include
|
||||
LDFLAGS=-shared
|
||||
MYSQLCLIENTSRCS=mysql_client.c mysql_common.c
|
||||
MYSQLCLIENTOBJ=$(MYSQLCLIENTSRCS:.c=.o)
|
||||
|
@ -16,7 +16,7 @@
|
||||
* Copyright SkySQL Ab 2013
|
||||
*/
|
||||
|
||||
#include "mysql_protocol.h"
|
||||
#include "mysql_client_server_protocol.h"
|
||||
|
||||
/*
|
||||
* MySQL Protocol module for handling the protocol between the gateway
|
||||
@ -30,10 +30,10 @@
|
||||
|
||||
static char *version_str = "V1.0.0";
|
||||
|
||||
static int gw_read_backend_event(DCB* dcb, int epfd);
|
||||
static int gw_write_backend_event(DCB *dcb, int epfd);
|
||||
static int gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue);
|
||||
static int gw_error_backend_event(DCB *dcb, int epfd, int event);
|
||||
int gw_read_backend_event(DCB* dcb, int epfd);
|
||||
int gw_write_backend_event(DCB *dcb, int epfd);
|
||||
int gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue);
|
||||
int gw_error_backend_event(DCB *dcb, int epfd, int event);
|
||||
|
||||
static GWPROTOCOL MyObject = {
|
||||
gw_read_backend_event, /* Read - EPOLLIN handler */
|
||||
@ -43,7 +43,8 @@ static GWPROTOCOL MyObject = {
|
||||
NULL, /* HangUp - EPOLLHUP handler */
|
||||
NULL, /* Accept */
|
||||
NULL, /* Connect */
|
||||
NULL /* Close */
|
||||
NULL, /* Close */
|
||||
NULL /* Listen */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -85,7 +86,6 @@ GetModuleObject()
|
||||
//////////////////////////////////////////
|
||||
//backend read event triggered by EPOLLIN
|
||||
//////////////////////////////////////////
|
||||
|
||||
int gw_read_backend_event(DCB *dcb, int epfd) {
|
||||
int n;
|
||||
MySQLProtocol *client_protocol = NULL;
|
||||
@ -144,7 +144,7 @@ int gw_read_backend_event(DCB *dcb, int epfd) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
@ -156,7 +156,7 @@ int gw_write_backend_event(DCB *dcb, int epfd) {
|
||||
}
|
||||
|
||||
/*
|
||||
* Write function for client DCB
|
||||
* Write function for backend DCB
|
||||
*
|
||||
* @param dcb The DCB of the client
|
||||
* @param queue Queue of buffers to write
|
||||
@ -223,10 +223,10 @@ int w, saved_errno = 0;
|
||||
if (queue && (saved_errno != EAGAIN || saved_errno != EWOULDBLOCK))
|
||||
{
|
||||
/* We had a real write failure that we must deal with */
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gw_error_backend_event(DCB *dcb, int epfd, int event) {
|
||||
|
@ -26,12 +26,12 @@
|
||||
* 17/06/2013 Massimiliano Pinto Added Client To Gateway routines
|
||||
*/
|
||||
|
||||
#include "mysql_protocol.h"
|
||||
#include "mysql_client_server_protocol.h"
|
||||
|
||||
static char *version_str = "V1.0.0";
|
||||
|
||||
static int gw_MySQLAccept(DCB *listener, int efd);
|
||||
static void gw_MySQLListener(int epfd, char *config_bind);
|
||||
static int gw_MySQLListener(int epfd, char *config_bind);
|
||||
static int gw_read_client_event(DCB* dcb, int epfd);
|
||||
static int gw_write_client_event(DCB *dcb, int epfd);
|
||||
static int gw_MySQLWrite_client(DCB *dcb, GWBUF *queue);
|
||||
@ -42,6 +42,7 @@ static int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_pas
|
||||
int mysql_send_ok(DCB *dcb, int packet_number, int in_affected_rows, const char* mysql_message);
|
||||
int mysql_send_auth_error (DCB *dcb, int packet_number, int in_affected_rows, const char* mysql_message);
|
||||
int MySQLSendHandshake(DCB* dcb);
|
||||
static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue);
|
||||
|
||||
/*
|
||||
* The "module object" for the mysqld client protocol module.
|
||||
@ -50,11 +51,12 @@ static GWPROTOCOL MyObject = {
|
||||
gw_read_client_event, /* Read - EPOLLIN handler */
|
||||
gw_MySQLWrite_client, /* Write - data from gateway */
|
||||
gw_write_client_event, /* WriteReady - EPOLLOUT handler */
|
||||
gw_error_client_event, /* Error - EPOLLERR handler */
|
||||
gw_error_client_event, /* Error - EPOLLERR handler */
|
||||
NULL, /* HangUp - EPOLLHUP handler */
|
||||
gw_MySQLAccept, /* Accept */
|
||||
NULL, /* Connect */
|
||||
NULL /* Close */
|
||||
NULL, /* Close */
|
||||
gw_MySQLListener /* Listen */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -167,7 +169,7 @@ mysql_send_ok(DCB *dcb, int packet_number, int in_affected_rows, const char* mys
|
||||
memcpy(mysql_payload, mysql_message, strlen(mysql_message));
|
||||
}
|
||||
|
||||
// write data
|
||||
// writing data in the Client buffer queue
|
||||
dcb->func.write(dcb, buf);
|
||||
|
||||
return sizeof(mysql_packet_header) + mysql_payload_size;
|
||||
@ -251,7 +253,7 @@ mysql_send_auth_error (DCB *dcb, int packet_number, int in_affected_rows, const
|
||||
// write err messg
|
||||
memcpy(mysql_payload, mysql_error_msg, strlen(mysql_error_msg));
|
||||
|
||||
// write data
|
||||
// writing data in the Client buffer queue
|
||||
dcb->func.write(dcb, buf);
|
||||
|
||||
return sizeof(mysql_packet_header) + mysql_payload_size;
|
||||
@ -398,7 +400,7 @@ MySQLSendHandshake(DCB* dcb)
|
||||
|
||||
mysql_handshake_payload++;
|
||||
|
||||
// write data
|
||||
// writing data in the Client buffer queue
|
||||
dcb->func.write(dcb, buf);
|
||||
|
||||
return sizeof(mysql_packet_header) + mysql_payload_size;
|
||||
@ -483,7 +485,6 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
|
||||
return auth_ret;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// get the sha1(sha1(password) from repository
|
||||
/////////////////////////////////////////////////
|
||||
@ -645,10 +646,10 @@ int w, saved_errno = 0;
|
||||
if (queue && (saved_errno != EAGAIN || saved_errno != EWOULDBLOCK))
|
||||
{
|
||||
/* We had a real write failure that we must deal with */
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
@ -669,6 +670,7 @@ int gw_read_client_event(DCB* dcb, int epfd) {
|
||||
|
||||
if (ioctl(dcb->fd, FIONREAD, &b)) {
|
||||
fprintf(stderr, "Client Ioctl FIONREAD error %i, %s\n", errno , strerror(errno));
|
||||
return 1;
|
||||
} else {
|
||||
//fprintf(stderr, "Client IOCTL FIONREAD bytes to read = %i\n", b);
|
||||
}
|
||||
@ -788,7 +790,7 @@ int gw_read_client_event(DCB* dcb, int epfd) {
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// client write event triggered by EPOLLOUT
|
||||
// client write event to Client triggered by EPOLLOUT
|
||||
//////////////////////////////////////////////
|
||||
int gw_write_client_event(DCB *dcb, int epfd) {
|
||||
MySQLProtocol *protocol = NULL;
|
||||
@ -827,6 +829,11 @@ int gw_write_client_event(DCB *dcb, int epfd) {
|
||||
//write to client mysql AUTH_OK packet, packet n. is 2
|
||||
mysql_send_ok(dcb, 2, 0, NULL);
|
||||
|
||||
// create one backend connection
|
||||
// This is not working now, as the backend dcb functions are in the mysql_protocol.c
|
||||
// and it will loaded separately
|
||||
//gw_create_backend_connection(dcb, epfd);
|
||||
|
||||
protocol->state = MYSQL_IDLE;
|
||||
|
||||
return 0;
|
||||
@ -890,7 +897,7 @@ int gw_write_client_event(DCB *dcb, int epfd) {
|
||||
///
|
||||
// set listener for mysql protocol
|
||||
///
|
||||
void MySQLListener(int epfd, char *config_bind) {
|
||||
int gw_MySQLListener(int epfd, char *config_bind) {
|
||||
DCB *listener;
|
||||
int l_so;
|
||||
int fl;
|
||||
@ -935,7 +942,8 @@ void MySQLListener(int epfd, char *config_bind) {
|
||||
|
||||
// socket create
|
||||
if ((l_so = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
error("can't open listening socket");
|
||||
fprintf(stderr, ">>> Error: can't open listening socket. Errno %i, %s\n", errno, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// socket options
|
||||
@ -946,9 +954,9 @@ void MySQLListener(int epfd, char *config_bind) {
|
||||
|
||||
// bind address and port
|
||||
if (bind(l_so, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
|
||||
fprintf(stderr, ">>>> Bind failed !!! %i, [%s]\n", errno, strerror(errno));
|
||||
error("can't bind to address and port");
|
||||
exit(1);
|
||||
fprintf(stderr, ">>> Bind failed !!! %i, [%s]\n", errno, strerror(errno));
|
||||
fprintf(stderr, ">>> can't bind to address and port");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(stderr, ">> GATEWAY bind is: %s:%i. FD is %i\n", address, port, l_so);
|
||||
@ -970,13 +978,15 @@ void MySQLListener(int epfd, char *config_bind) {
|
||||
|
||||
// add listening socket to epoll structure
|
||||
if (epoll_ctl(epfd, EPOLL_CTL_ADD, l_so, &ev) == -1) {
|
||||
perror("epoll_ctl: listen_sock");
|
||||
exit(EXIT_FAILURE);
|
||||
fprintf(stderr, ">>> epoll_ctl: can't add the listen_sock! Errno %i, %s\n", errno, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
listener->func.accept = gw_MySQLAccept;
|
||||
|
||||
listener->state = DCB_STATE_LISTENING;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,10 +24,21 @@
|
||||
* 17/06/2013 Massimiliano Pinto Common MySQL protocol routines
|
||||
*/
|
||||
|
||||
#include "mysql_protocol.h"
|
||||
#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, int epfd);
|
||||
extern gw_write_backend_event(DCB *dcb, int epfd);
|
||||
extern int gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue);
|
||||
extern int gw_error_backend_event(DCB *dcb, int epfd, int event);
|
||||
|
||||
///////////////////////////////
|
||||
// Initialize mysql protocol struct
|
||||
///////////////////////////////////////
|
||||
MySQLProtocol *gw_mysql_init(MySQLProtocol *data) {
|
||||
int rv = -1;
|
||||
@ -53,7 +64,7 @@ MySQLProtocol *gw_mysql_init(MySQLProtocol *data) {
|
||||
|
||||
//////////////////////////////////////
|
||||
// close a connection if opened
|
||||
// free data scructure
|
||||
// free data scructure for MySQLProtocol
|
||||
//////////////////////////////////////
|
||||
void gw_mysql_close(MySQLProtocol **ptr) {
|
||||
MySQLProtocol *conn = *ptr;
|
||||
@ -85,3 +96,79 @@ void gw_mysql_close(MySQLProtocol **ptr) {
|
||||
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 epoll set
|
||||
*
|
||||
* - backend dcb allocation
|
||||
* - MySQL session data fetch
|
||||
* - backend connection using data in MySQL session
|
||||
*
|
||||
* @param client_dcb The client DCB struct
|
||||
* @param epfd The epoll set to add the new connection
|
||||
* @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, int efd) {
|
||||
struct epoll_event ee;
|
||||
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;
|
||||
}
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user