Merge branch 'develop' into blr
Conflicts: server/core/dcb.c server/modules/include/blr.h server/modules/routing/binlog/STATUS server/modules/routing/binlog/blr.c server/modules/routing/binlog/blr_file.c server/modules/routing/binlog/blr_master.c server/modules/routing/binlog/blr_slave.c
This commit is contained in:
@ -39,6 +39,14 @@
|
||||
|
||||
#include <httpd.h>
|
||||
#include <gw.h>
|
||||
#include <modinfo.h>
|
||||
|
||||
MODULE_INFO info = {
|
||||
MODULE_API_PROTOCOL,
|
||||
MODULE_IN_DEVELOPMENT,
|
||||
GWPROTOCOL_VERSION,
|
||||
"An experimental HTTPD implementation for use in admnistration"
|
||||
};
|
||||
|
||||
#define ISspace(x) isspace((int)(x))
|
||||
#define HTTP_SERVER_STRING "Gateway(c) v.1.0.0"
|
||||
|
||||
@ -43,6 +43,14 @@
|
||||
* 27/09/2013 Massimiliano Pinto Changed in gw_read_backend_event the check for dcb_read(), now is if rc < 0
|
||||
*
|
||||
*/
|
||||
#include <modinfo.h>
|
||||
|
||||
MODULE_INFO info = {
|
||||
MODULE_API_PROTOCOL,
|
||||
MODULE_ALPHA_RELEASE,
|
||||
GWPROTOCOL_VERSION,
|
||||
"The MySQL to backend server protocol"
|
||||
};
|
||||
|
||||
extern int lm_enabled_logfiles_bitmask;
|
||||
|
||||
@ -282,7 +290,13 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
} /* switch */
|
||||
}
|
||||
|
||||
if (backend_protocol->state == MYSQL_AUTH_FAILED) {
|
||||
if (backend_protocol->state == MYSQL_AUTH_FAILED)
|
||||
{
|
||||
/**
|
||||
* protocol state won't change anymore,
|
||||
* lock can be freed
|
||||
*/
|
||||
spinlock_release(&dcb->authlock);
|
||||
spinlock_acquire(&dcb->delayqlock);
|
||||
/*<
|
||||
* vraa : errorHandle
|
||||
@ -306,12 +320,14 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
/* try reload users' table for next connection */
|
||||
service_refresh_users(dcb->session->client->service);
|
||||
|
||||
while (session->state != SESSION_STATE_ROUTER_READY)
|
||||
while (session->state != SESSION_STATE_ROUTER_READY &&
|
||||
session->state != SESSION_STATE_STOPPING)
|
||||
{
|
||||
ss_dassert(
|
||||
session->state == SESSION_STATE_READY ||
|
||||
session->state ==
|
||||
SESSION_STATE_ROUTER_READY);
|
||||
SESSION_STATE_ROUTER_READY ||
|
||||
session->state == SESSION_STATE_STOPPING);
|
||||
/**
|
||||
* Session shouldn't be NULL at this point
|
||||
* anymore. Just checking..
|
||||
@ -319,10 +335,19 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
if (session->client->session == NULL)
|
||||
{
|
||||
rc = 1;
|
||||
goto return_with_lock;
|
||||
goto return_rc;
|
||||
}
|
||||
usleep(1);
|
||||
}
|
||||
|
||||
if (session->state == SESSION_STATE_STOPPING)
|
||||
{
|
||||
goto return_rc;
|
||||
}
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
session->state = SESSION_STATE_STOPPING;
|
||||
spinlock_release(&session->ses_lock);
|
||||
|
||||
/**
|
||||
* rsession shouldn't be NULL since session
|
||||
* state indicates that it was initialized
|
||||
@ -340,7 +365,7 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
/* close router_session */
|
||||
router->closeSession(router_instance, rsession);
|
||||
rc = 1;
|
||||
goto return_with_lock;
|
||||
goto return_rc;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -357,8 +382,7 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
/* check the delay queue and flush the data */
|
||||
if (dcb->delayq)
|
||||
{
|
||||
backend_write_delayqueue(dcb);
|
||||
rc = 1;
|
||||
rc = backend_write_delayqueue(dcb);
|
||||
goto return_with_lock;
|
||||
}
|
||||
}
|
||||
@ -569,9 +593,8 @@ gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue)
|
||||
snprintf(str, len+1, "%s", startpoint);
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Error : Routing query \"%s\" failed due to "
|
||||
"authentication failure.",
|
||||
str)));
|
||||
"Error : Unable to write to backend due to "
|
||||
"authentication failure.")));
|
||||
/** Consume query buffer */
|
||||
while ((queue = gwbuf_consume(
|
||||
queue,
|
||||
@ -669,6 +692,10 @@ static int gw_error_backend_event(DCB *dcb) {
|
||||
|
||||
if (session->state == SESSION_STATE_ROUTER_READY)
|
||||
{
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
session->state = SESSION_STATE_STOPPING;
|
||||
spinlock_release(&session->ses_lock);
|
||||
|
||||
rsession = session->router_session;
|
||||
/*<
|
||||
* rsession should never be NULL here.
|
||||
@ -874,34 +901,36 @@ static int backend_write_delayqueue(DCB *dcb)
|
||||
|
||||
spinlock_acquire(&dcb->delayqlock);
|
||||
|
||||
if (dcb->delayq == NULL)
|
||||
{
|
||||
spinlock_release(&dcb->delayqlock);
|
||||
rc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
localq = dcb->delayq;
|
||||
dcb->delayq = NULL;
|
||||
|
||||
spinlock_release(&dcb->delayqlock);
|
||||
rc = dcb_write(dcb, localq);
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
/*< vraa : errorHandle */
|
||||
/**
|
||||
* This error can be muted because it is often due
|
||||
* unexpected dcb state which means that concurrent thread
|
||||
* already wrote the queue and closed dcb.
|
||||
*/
|
||||
#if 0
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"%lu [backend_write_delayqueue] Some error occurred in "
|
||||
"backend.",
|
||||
pthread_self())));
|
||||
#endif
|
||||
"Error : failed to write buffered data to back-end "
|
||||
"server. Buffer was empty of back-end was disconnected "
|
||||
"during operation.")));
|
||||
|
||||
mysql_send_custom_error(
|
||||
dcb->session->client,
|
||||
1,
|
||||
0,
|
||||
"Unable to write to backend server. Connection was "
|
||||
"closed.");
|
||||
"Failed to write buffered data to back-end server. "
|
||||
"Buffer was empty or back-end was disconnected during "
|
||||
"operation.");
|
||||
dcb_close(dcb);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -36,11 +36,18 @@
|
||||
* 07/05/2014 Massimiliano Pinto Added: specific version string in server handshake
|
||||
*
|
||||
*/
|
||||
|
||||
#include <skygw_utils.h>
|
||||
#include <log_manager.h>
|
||||
#include <mysql_client_server_protocol.h>
|
||||
#include <gw.h>
|
||||
#include <modinfo.h>
|
||||
|
||||
MODULE_INFO info = {
|
||||
MODULE_API_PROTOCOL,
|
||||
MODULE_ALPHA_RELEASE,
|
||||
GWPROTOCOL_VERSION,
|
||||
"The client to MaxScale MySQL protocol implementation"
|
||||
};
|
||||
|
||||
extern int lm_enabled_logfiles_bitmask;
|
||||
|
||||
@ -58,11 +65,7 @@ static int gw_client_hangup_event(DCB *dcb);
|
||||
int mysql_send_ok(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);
|
||||
static int route_by_statement(
|
||||
ROUTER* router_instance,
|
||||
ROUTER_OBJECT* router,
|
||||
void* rsession,
|
||||
GWBUF* read_buf);
|
||||
static int route_by_statement(SESSION *, GWBUF *);
|
||||
|
||||
/*
|
||||
* The "module object" for the mysqld client protocol module.
|
||||
@ -507,9 +510,10 @@ int gw_read_client_event(DCB* dcb) {
|
||||
ROUTER *router_instance = NULL;
|
||||
void *rsession = NULL;
|
||||
MySQLProtocol *protocol = NULL;
|
||||
GWBUF *read_buffer = NULL;
|
||||
int b = -1;
|
||||
int rc = 0;
|
||||
|
||||
int nbytes_read = 0;
|
||||
CHK_DCB(dcb);
|
||||
protocol = DCB_PROTOCOL(dcb, MySQLProtocol);
|
||||
CHK_PROTOCOL(protocol);
|
||||
@ -536,7 +540,6 @@ int gw_read_client_event(DCB* dcb) {
|
||||
/*
|
||||
* Handle the closed client socket.
|
||||
*/
|
||||
|
||||
if (b == 0) {
|
||||
char c;
|
||||
int l_errno = 0;
|
||||
@ -553,7 +556,7 @@ int gw_read_client_event(DCB* dcb) {
|
||||
goto return_rc;
|
||||
}
|
||||
|
||||
// close client socket and the sessioA too
|
||||
// close client socket and the session too
|
||||
dcb->func.close(dcb);
|
||||
} else {
|
||||
// do nothing if reading 1 byte
|
||||
@ -561,41 +564,80 @@ int gw_read_client_event(DCB* dcb) {
|
||||
|
||||
goto return_rc;
|
||||
}
|
||||
rc = gw_read_gwbuff(dcb, &read_buffer, b);
|
||||
|
||||
if (rc != 0) {
|
||||
goto return_rc;
|
||||
}
|
||||
|
||||
nbytes_read = gwbuf_length(read_buffer);
|
||||
ss_dassert(nbytes_read > 0);
|
||||
|
||||
/**
|
||||
* if read queue existed appent read to it.
|
||||
* if length of read buffer is less than 3 or less than mysql packet
|
||||
* then return.
|
||||
* else copy mysql packets to separate buffers from read buffer and
|
||||
* continue.
|
||||
* else
|
||||
* if read queue didn't exist, length of read is less than 3 or less
|
||||
* than mysql packet then
|
||||
* create read queue and append to it and return.
|
||||
* if length read is less than mysql packet length append to read queue
|
||||
* append to it and return.
|
||||
* else (complete packet was read) continue.
|
||||
*/
|
||||
if (dcb->dcb_readqueue)
|
||||
{
|
||||
uint8_t* data = (uint8_t *)GWBUF_DATA(read_buffer);
|
||||
|
||||
read_buffer = gwbuf_append(dcb->dcb_readqueue, read_buffer);
|
||||
nbytes_read = gwbuf_length(read_buffer);
|
||||
|
||||
if (nbytes_read < 3 || nbytes_read < MYSQL_GET_PACKET_LEN(data))
|
||||
{
|
||||
rc = 0;
|
||||
goto return_rc;
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* There is at least one complete mysql packet read
|
||||
*/
|
||||
read_buffer = dcb->dcb_readqueue;
|
||||
dcb->dcb_readqueue = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t* data = (uint8_t *)GWBUF_DATA(read_buffer);
|
||||
size_t packetlen = MYSQL_GET_PACKET_LEN(data)+4;
|
||||
|
||||
if (nbytes_read < 3 || nbytes_read < packetlen)
|
||||
{
|
||||
gwbuf_append(dcb->dcb_readqueue, read_buffer);
|
||||
rc = 0;
|
||||
goto return_rc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Now there should be at least one complete mysql packet in read_buffer.
|
||||
*/
|
||||
switch (protocol->state) {
|
||||
|
||||
case MYSQL_AUTH_SENT:
|
||||
/*
|
||||
* Read all the data that is available into a chain of buffers
|
||||
*/
|
||||
{
|
||||
int len = -1;
|
||||
GWBUF *queue = NULL;
|
||||
GWBUF *gw_buffer = NULL;
|
||||
int auth_val = -1;
|
||||
//////////////////////////////////////////////////////
|
||||
// read and handle errors & close, or return if busy
|
||||
// note: if b == 0 error handling is not
|
||||
// triggered, just return
|
||||
// without closing
|
||||
//////////////////////////////////////////////////////
|
||||
rc = gw_read_gwbuff(dcb, &gw_buffer, b);
|
||||
|
||||
if (rc != 0) {
|
||||
goto return_rc;
|
||||
}
|
||||
|
||||
// example with consume, assuming one buffer only ...
|
||||
queue = gw_buffer;
|
||||
len = GWBUF_LENGTH(queue);
|
||||
|
||||
ss_dassert(len > 0);
|
||||
|
||||
auth_val = gw_mysql_do_authentication(dcb, queue);
|
||||
|
||||
|
||||
auth_val = gw_mysql_do_authentication(dcb, read_buffer);
|
||||
// Data handled withot the dcb->func.write
|
||||
// so consume it now
|
||||
// be sure to consume it all
|
||||
queue = gwbuf_consume(queue, len);
|
||||
read_buffer = gwbuf_consume(read_buffer, nbytes_read);
|
||||
|
||||
if (auth_val == 0)
|
||||
{
|
||||
@ -638,9 +680,7 @@ int gw_read_client_event(DCB* dcb) {
|
||||
* Read all the data that is available into a chain of buffers
|
||||
*/
|
||||
{
|
||||
int len = -1;
|
||||
uint8_t cap = 0;
|
||||
GWBUF *read_buffer = NULL;
|
||||
uint8_t *ptr_buff = NULL;
|
||||
int mysql_command = -1;
|
||||
bool stmt_input; /*< router input type */
|
||||
@ -655,22 +695,14 @@ int gw_read_client_event(DCB* dcb) {
|
||||
session->service->router_instance;
|
||||
rsession = session->router_session;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// read and handle errors & close, or return if busy
|
||||
//////////////////////////////////////////////////////
|
||||
rc = gw_read_gwbuff(dcb, &read_buffer, b);
|
||||
|
||||
if (rc != 0) {
|
||||
goto return_rc;
|
||||
}
|
||||
|
||||
/* Now, we are assuming in the first buffer there is
|
||||
* the information form mysql command */
|
||||
len = GWBUF_LENGTH(read_buffer);
|
||||
ptr_buff = GWBUF_DATA(read_buffer);
|
||||
|
||||
/* get mysql commang at fifth byte */
|
||||
if (ptr_buff) {
|
||||
ss_dassert(nbytes_read >= 5);
|
||||
mysql_command = ptr_buff[4];
|
||||
}
|
||||
/**
|
||||
@ -695,13 +727,13 @@ int gw_read_client_event(DCB* dcb) {
|
||||
dcb,
|
||||
1,
|
||||
0,
|
||||
"Query routing failed. Connection to "
|
||||
"Can't route query. Connection to "
|
||||
"backend lost");
|
||||
protocol->state = MYSQL_IDLE;
|
||||
}
|
||||
rc = 1;
|
||||
/** Free buffer */
|
||||
read_buffer = gwbuf_consume(read_buffer, len);
|
||||
read_buffer = gwbuf_consume(read_buffer, nbytes_read);
|
||||
goto return_rc;
|
||||
}
|
||||
/** Ask what type of input the router expects */
|
||||
@ -737,19 +769,15 @@ int gw_read_client_event(DCB* dcb) {
|
||||
|
||||
/** Route COM_QUIT to backend */
|
||||
if (mysql_command == '\x01') {
|
||||
router->routeQuery(router_instance, rsession, read_buffer);
|
||||
SESSION_ROUTE_QUERY(session, read_buffer);
|
||||
LOGIF(LD, (skygw_log_write_flush(
|
||||
LOGFILE_DEBUG,
|
||||
"%lu [gw_read_client_event] Routed COM_QUIT to "
|
||||
"backend. Close client dcb %p",
|
||||
pthread_self(),
|
||||
dcb)));
|
||||
|
||||
/** close client connection */
|
||||
(dcb->func).close(dcb);
|
||||
/** close backends connection */
|
||||
router->closeSession(router_instance, rsession);
|
||||
rc = 1;
|
||||
/** close client connection, closes router session too */
|
||||
rc = dcb->func.close(dcb);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -759,17 +787,17 @@ int gw_read_client_event(DCB* dcb) {
|
||||
* Feed each statement completely and separately
|
||||
* to router.
|
||||
*/
|
||||
rc = route_by_statement(router_instance,
|
||||
router,
|
||||
rsession,
|
||||
read_buffer);
|
||||
rc = route_by_statement(session, read_buffer);
|
||||
if (read_buffer != NULL)
|
||||
{
|
||||
/** add incomplete mysql packet to read queue */
|
||||
gwbuf_append(dcb->dcb_readqueue, read_buffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/** Feed whole packet to router */
|
||||
rc = router->routeQuery(router_instance,
|
||||
rsession,
|
||||
read_buffer);
|
||||
rc = SESSION_ROUTE_QUERY(session, read_buffer);
|
||||
}
|
||||
|
||||
/** succeed */
|
||||
@ -1230,37 +1258,16 @@ return_rc:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int gw_error_client_event(DCB *dcb) {
|
||||
SESSION* session;
|
||||
ROUTER_OBJECT* router;
|
||||
void* router_instance;
|
||||
void* rsession;
|
||||
|
||||
#if defined(SS_DEBUG)
|
||||
MySQLProtocol* protocol = (MySQLProtocol *)dcb->protocol;
|
||||
if (dcb->state == DCB_STATE_POLLING ||
|
||||
dcb->state == DCB_STATE_NOPOLLING ||
|
||||
dcb->state == DCB_STATE_ZOMBIE)
|
||||
static int gw_error_client_event(
|
||||
DCB* dcb)
|
||||
{
|
||||
CHK_PROTOCOL(protocol);
|
||||
}
|
||||
#endif
|
||||
int rc;
|
||||
|
||||
session = dcb->session;
|
||||
CHK_DCB(dcb);
|
||||
|
||||
/**
|
||||
* session may be NULL if session_alloc failed.
|
||||
* In that case router session was not created.
|
||||
*/
|
||||
if (session != NULL) {
|
||||
CHK_SESSION(session);
|
||||
router = session->service->router;
|
||||
router_instance = session->service->router_instance;
|
||||
rsession = session->router_session;
|
||||
router->closeSession(router_instance, rsession);
|
||||
}
|
||||
dcb_close(dcb);
|
||||
return 1;
|
||||
rc = dcb->func.close(dcb);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1287,6 +1294,10 @@ gw_client_close(DCB *dcb)
|
||||
*/
|
||||
if (session != NULL) {
|
||||
CHK_SESSION(session);
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
session->state = SESSION_STATE_STOPPING;
|
||||
spinlock_release(&session->ses_lock);
|
||||
|
||||
router = session->service->router;
|
||||
router_instance = session->service->router_instance;
|
||||
rsession = session->router_session;
|
||||
@ -1309,42 +1320,11 @@ gw_client_close(DCB *dcb)
|
||||
static int
|
||||
gw_client_hangup_event(DCB *dcb)
|
||||
{
|
||||
SESSION* session;
|
||||
ROUTER_OBJECT* router;
|
||||
void* router_instance;
|
||||
void* rsession;
|
||||
int rc = 1;
|
||||
int rc;
|
||||
|
||||
#if defined(SS_DEBUG)
|
||||
MySQLProtocol* protocol = (MySQLProtocol *)dcb->protocol;
|
||||
if (dcb->state == DCB_STATE_POLLING ||
|
||||
dcb->state == DCB_STATE_NOPOLLING ||
|
||||
dcb->state == DCB_STATE_ZOMBIE)
|
||||
{
|
||||
CHK_PROTOCOL(protocol);
|
||||
}
|
||||
#endif
|
||||
CHK_DCB(dcb);
|
||||
rc = dcb->func.close(dcb);
|
||||
|
||||
if (dcb->state != DCB_STATE_POLLING) {
|
||||
goto return_rc;
|
||||
}
|
||||
|
||||
session = dcb->session;
|
||||
/**
|
||||
* session may be NULL if session_alloc failed.
|
||||
* In that case router session was not created.
|
||||
*/
|
||||
if (session != NULL) {
|
||||
CHK_SESSION(session);
|
||||
router = session->service->router;
|
||||
router_instance = session->service->router_instance;
|
||||
rsession = session->router_session;
|
||||
router->closeSession(router_instance, rsession);
|
||||
}
|
||||
|
||||
dcb_close(dcb);
|
||||
return_rc:
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -1353,34 +1333,34 @@ return_rc:
|
||||
* Detect if buffer includes partial mysql packet or multiple packets.
|
||||
* Store partial packet to pendingqueue. Send complete packets one by one
|
||||
* to router.
|
||||
*
|
||||
* It is assumed readbuf includes at least one complete packet.
|
||||
* Return 1 in success. If the last packet is incomplete return success but
|
||||
* leave incomplete packet to readbuf.
|
||||
*/
|
||||
static int route_by_statement(
|
||||
ROUTER* router_instance,
|
||||
ROUTER_OBJECT* router,
|
||||
void* rsession,
|
||||
GWBUF* readbuf)
|
||||
static int route_by_statement(SESSION *session, GWBUF *readbuf)
|
||||
{
|
||||
int rc = -1;
|
||||
DCB* master_dcb;
|
||||
GWBUF* stmtbuf;
|
||||
uint8_t* payload;
|
||||
static size_t len;
|
||||
GWBUF* packetbuf;
|
||||
|
||||
do
|
||||
{
|
||||
stmtbuf = gw_MySQL_get_next_stmt(&readbuf);
|
||||
ss_dassert(stmtbuf != NULL);
|
||||
CHK_GWBUF(stmtbuf);
|
||||
|
||||
payload = (uint8_t *)GWBUF_DATA(stmtbuf);
|
||||
/**
|
||||
* If message is longer than read data, suspend routing and
|
||||
* add statement buffer to wait queue.
|
||||
*/
|
||||
rc = router->routeQuery(router_instance, rsession, stmtbuf);
|
||||
packetbuf = gw_MySQL_get_next_packet(&readbuf);
|
||||
|
||||
if (packetbuf != NULL)
|
||||
{
|
||||
CHK_GWBUF(packetbuf);
|
||||
rc = SESSION_ROUTE_QUERY(session, packetbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = 1;
|
||||
goto return_rc;
|
||||
}
|
||||
}
|
||||
while (readbuf != NULL);
|
||||
|
||||
return_rc:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -315,12 +315,17 @@ int gw_receive_backend_auth(
|
||||
/*<
|
||||
* 5th byte is 0x0 if successful.
|
||||
*/
|
||||
if (ptr[4] == '\x00') {
|
||||
if (ptr[4] == 0x00)
|
||||
{
|
||||
rc = 1;
|
||||
} else {
|
||||
uint8_t* tmpbuf =
|
||||
(uint8_t *)calloc(1, GWBUF_LENGTH(head)+1);
|
||||
memcpy(tmpbuf, ptr, GWBUF_LENGTH(head));
|
||||
}
|
||||
else if (ptr[4] == 0xff)
|
||||
{
|
||||
size_t packetlen = MYSQL_GET_PACKET_LEN(ptr)+4;
|
||||
char* bufstr = (char *)calloc(1, packetlen-3);
|
||||
|
||||
snprintf(bufstr, packetlen-6, "%s", &ptr[7]);
|
||||
|
||||
LOGIF(LD, (skygw_log_write(
|
||||
LOGFILE_DEBUG,
|
||||
"%lu [gw_receive_backend_auth] Invalid "
|
||||
@ -329,11 +334,35 @@ int gw_receive_backend_auth(
|
||||
pthread_self(),
|
||||
dcb,
|
||||
dcb->fd,
|
||||
tmpbuf[4],
|
||||
tmpbuf)));
|
||||
ptr[4],
|
||||
bufstr)));
|
||||
|
||||
free(tmpbuf);
|
||||
rc = -1;
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Error : Invalid authentication message "
|
||||
"from backend. Msg : %s",
|
||||
bufstr)));
|
||||
|
||||
free(bufstr);
|
||||
rc = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGIF(LD, (skygw_log_write(
|
||||
LOGFILE_DEBUG,
|
||||
"%lu [gw_receive_backend_auth] Invalid "
|
||||
"authentication message from backend dcb %p "
|
||||
"fd %d, ptr[4] = %p",
|
||||
pthread_self(),
|
||||
dcb,
|
||||
dcb->fd,
|
||||
ptr[4])));
|
||||
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Error : Invalid authentication message "
|
||||
"from backend. Packet type : %p",
|
||||
ptr[4])));
|
||||
}
|
||||
/*<
|
||||
* Remove data from buffer.
|
||||
@ -605,7 +634,7 @@ int gw_do_connect_to_backend(
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Error: Establishing connection to backend server "
|
||||
"%s:%d failed. Socket creation failed due "
|
||||
"%s:%d failed.\n\t\t Socket creation failed due "
|
||||
"%d, %s.",
|
||||
host,
|
||||
port,
|
||||
@ -1279,54 +1308,85 @@ mysql_send_auth_error (DCB *dcb, int packet_number, int in_affected_rows, const
|
||||
|
||||
|
||||
/**
|
||||
* Remove the first mysql statement from buffer. Return pointer to the removed
|
||||
* statement or NULL if buffer is empty.
|
||||
*
|
||||
* Clone buf, calculate the length of included mysql stmt, and point the
|
||||
* statement with cloned buffer. Move the start pointer of buf accordingly
|
||||
* so that it only cover the remaining buffer.
|
||||
* Buffer contains at least one of the following:
|
||||
* complete [complete] [partial] mysql packet
|
||||
*
|
||||
* return pointer to gwbuf containing a complete packet or
|
||||
* NULL if no complete packet was found.
|
||||
*/
|
||||
GWBUF* gw_MySQL_get_next_stmt(
|
||||
GWBUF* gw_MySQL_get_next_packet(
|
||||
GWBUF** p_readbuf)
|
||||
{
|
||||
GWBUF* stmtbuf;
|
||||
size_t buflen;
|
||||
size_t strlen;
|
||||
uint8_t* packet;
|
||||
|
||||
if (*p_readbuf == NULL)
|
||||
{
|
||||
stmtbuf = NULL;
|
||||
goto return_stmtbuf;
|
||||
}
|
||||
CHK_GWBUF(*p_readbuf);
|
||||
|
||||
if (GWBUF_EMPTY(*p_readbuf))
|
||||
{
|
||||
stmtbuf = NULL;
|
||||
goto return_stmtbuf;
|
||||
}
|
||||
buflen = GWBUF_LENGTH((*p_readbuf));
|
||||
packet = GWBUF_DATA((*p_readbuf));
|
||||
strlen = MYSQL_GET_PACKET_LEN(packet);
|
||||
GWBUF* packetbuf;
|
||||
GWBUF* readbuf;
|
||||
size_t buflen;
|
||||
size_t packetlen;
|
||||
size_t totalbuflen;
|
||||
uint8_t* data;
|
||||
readbuf = *p_readbuf;
|
||||
|
||||
if (strlen+4 == buflen)
|
||||
if (readbuf == NULL)
|
||||
{
|
||||
stmtbuf = *p_readbuf;
|
||||
*p_readbuf = NULL;
|
||||
goto return_stmtbuf;
|
||||
}
|
||||
/** vraa :Multi-packet stmt is not supported as of 7.3.14 */
|
||||
if (strlen-1 > buflen-5)
|
||||
{
|
||||
stmtbuf = NULL;
|
||||
goto return_stmtbuf;
|
||||
}
|
||||
stmtbuf = gwbuf_clone_portion(*p_readbuf, 0, strlen+4);
|
||||
*p_readbuf = gwbuf_consume(*p_readbuf, strlen+4);
|
||||
packetbuf = NULL;
|
||||
goto return_packetbuf;
|
||||
}
|
||||
CHK_GWBUF(readbuf);
|
||||
|
||||
return_stmtbuf:
|
||||
return stmtbuf;
|
||||
if (GWBUF_EMPTY(readbuf))
|
||||
{
|
||||
packetbuf = NULL;
|
||||
goto return_packetbuf;
|
||||
}
|
||||
|
||||
buflen = GWBUF_LENGTH((readbuf));
|
||||
totalbuflen = gwbuf_length(readbuf);
|
||||
data = (uint8_t *)GWBUF_DATA((readbuf));
|
||||
packetlen = MYSQL_GET_PACKET_LEN(data)+4;
|
||||
|
||||
/** packet is incomplete */
|
||||
if (packetlen > totalbuflen)
|
||||
{
|
||||
packetbuf = NULL;
|
||||
goto return_packetbuf;
|
||||
}
|
||||
|
||||
if (packetlen == buflen)
|
||||
{
|
||||
packetbuf = gwbuf_clone_portion(readbuf, 0, packetlen);
|
||||
*p_readbuf = gwbuf_consume(readbuf, packetlen);
|
||||
goto return_packetbuf;
|
||||
}
|
||||
/**
|
||||
* Packet spans multiple buffers.
|
||||
* Allocate buffer for complete packet
|
||||
* copy packet parts into it and consume copied bytes
|
||||
*/
|
||||
else if (packetlen > buflen)
|
||||
{
|
||||
size_t nbytes_copied = 0;
|
||||
uint8_t* target;
|
||||
|
||||
packetbuf = gwbuf_alloc(packetlen);
|
||||
target = GWBUF_DATA(packetbuf);
|
||||
|
||||
while (nbytes_copied < packetlen)
|
||||
{
|
||||
uint8_t* src = GWBUF_DATA(readbuf);
|
||||
size_t buflen = GWBUF_LENGTH(readbuf);
|
||||
|
||||
memcpy(target+nbytes_copied, src, buflen);
|
||||
*p_readbuf = gwbuf_consume(readbuf, buflen);
|
||||
nbytes_copied += buflen;
|
||||
}
|
||||
ss_dassert(nbytes_copied == packetlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
packetbuf = gwbuf_clone_portion(readbuf, 0, packetlen);
|
||||
*p_readbuf = gwbuf_consume(readbuf, packetlen);
|
||||
}
|
||||
|
||||
return_packetbuf:
|
||||
return packetbuf;
|
||||
}
|
||||
|
||||
|
||||
@ -1,62 +0,0 @@
|
||||
GetModuleObject httpd.c /^GetModuleObject()$/
|
||||
ISspace httpd.c /^#define ISspace(x) isspace((int)(x))$/
|
||||
ModuleInit httpd.c /^ModuleInit()$/
|
||||
MySQLSendHandshake mysql_client.c /^MySQLSendHandshake(DCB* dcb)$/
|
||||
backend_set_delayqueue mysql_backend.c /^static void backend_set_delayqueue(DCB *dcb, GWBUF/
|
||||
backend_write_delayqueue mysql_backend.c /^static int backend_write_delayqueue(DCB *dcb)$/
|
||||
gw_MySQLAccept mysql_client.c /^int gw_MySQLAccept(DCB *listener)$/
|
||||
gw_MySQLListener mysql_client.c /^int gw_MySQLListener($/
|
||||
gw_MySQLWrite_backend mysql_backend.c /^gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue)$/
|
||||
gw_MySQLWrite_client mysql_client.c /^gw_MySQLWrite_client(DCB *dcb, GWBUF *queue)$/
|
||||
gw_MySQL_get_next_stmt mysql_common.c /^GWBUF* gw_MySQL_get_next_stmt($/
|
||||
gw_backend_close mysql_backend.c /^gw_backend_close(DCB *dcb)$/
|
||||
gw_backend_hangup mysql_backend.c /^gw_backend_hangup(DCB *dcb)$/
|
||||
gw_change_user mysql_backend.c /^static int gw_change_user(DCB *backend, SERVER *se/
|
||||
gw_check_mysql_scramble_data mysql_common.c /^int gw_check_mysql_scramble_data(DCB *dcb, uint8_t/
|
||||
gw_client_close mysql_client.c /^gw_client_close(DCB *dcb)$/
|
||||
gw_client_hangup_event mysql_client.c /^gw_client_hangup_event(DCB *dcb)$/
|
||||
gw_create_backend_connection mysql_backend.c /^static int gw_create_backend_connection($/
|
||||
gw_decode_mysql_server_handshake mysql_common.c /^int gw_decode_mysql_server_handshake(MySQLProtocol/
|
||||
gw_do_connect_to_backend mysql_common.c /^int gw_do_connect_to_backend($/
|
||||
gw_error_backend_event mysql_backend.c /^static int gw_error_backend_event(DCB *dcb) {$/
|
||||
gw_error_client_event mysql_client.c /^static int gw_error_client_event(DCB *dcb) {$/
|
||||
gw_find_mysql_user_password_sha1 mysql_common.c /^int gw_find_mysql_user_password_sha1(char *usernam/
|
||||
gw_get_or_create_querystr mysql_client.c /^static char* gw_get_or_create_querystr ($/
|
||||
gw_get_shared_session_auth_info mysql_backend.c /^static MYSQL_session* gw_get_shared_session_auth_i/
|
||||
gw_mysql_close mysql_common.c /^void gw_mysql_close(MySQLProtocol **ptr) {$/
|
||||
gw_mysql_do_authentication mysql_client.c /^static int gw_mysql_do_authentication(DCB *dcb, GW/
|
||||
gw_mysql_protocol_state2string mysql_common.c /^gw_mysql_protocol_state2string (int state) {$/
|
||||
gw_read_backend_event mysql_backend.c /^static int gw_read_backend_event(DCB *dcb) {$/
|
||||
gw_read_backend_handshake mysql_common.c /^int gw_read_backend_handshake(MySQLProtocol *conn)/
|
||||
gw_read_client_event mysql_client.c /^int gw_read_client_event(DCB* dcb) {$/
|
||||
gw_receive_backend_auth mysql_common.c /^int gw_receive_backend_auth($/
|
||||
gw_send_authentication_to_backend mysql_common.c /^int gw_send_authentication_to_backend($/
|
||||
gw_send_change_user_to_backend mysql_common.c /^int gw_send_change_user_to_backend(char *dbname, c/
|
||||
gw_write_backend_event mysql_backend.c /^static int gw_write_backend_event(DCB *dcb) {$/
|
||||
gw_write_client_event mysql_client.c /^int gw_write_client_event(DCB *dcb)$/
|
||||
httpd_accept httpd.c /^httpd_accept(DCB *dcb)$/
|
||||
httpd_close httpd.c /^httpd_close(DCB *dcb)$/
|
||||
httpd_error httpd.c /^httpd_error(DCB *dcb)$/
|
||||
httpd_get_line httpd.c /^static int httpd_get_line(int sock, char *buf, int/
|
||||
httpd_hangup httpd.c /^httpd_hangup(DCB *dcb)$/
|
||||
httpd_listen httpd.c /^httpd_listen(DCB *listener, char *config)$/
|
||||
httpd_read_event httpd.c /^httpd_read_event(DCB* dcb)$/
|
||||
httpd_send_headers httpd.c /^static void httpd_send_headers(DCB *dcb, int final/
|
||||
httpd_write httpd.c /^httpd_write(DCB *dcb, GWBUF *queue)$/
|
||||
httpd_write_event httpd.c /^httpd_write_event(DCB *dcb)$/
|
||||
mysql_protocol_init mysql_common.c /^MySQLProtocol* mysql_protocol_init($/
|
||||
mysql_send_auth_error mysql_common.c /^mysql_send_auth_error (DCB *dcb, int packet_number/
|
||||
mysql_send_custom_error mysql_common.c /^mysql_send_custom_error (DCB *dcb, int packet_numb/
|
||||
mysql_send_ok mysql_client.c /^mysql_send_ok(DCB *dcb, int packet_number, int in_/
|
||||
route_by_statement mysql_client.c /^static int route_by_statement($/
|
||||
telnetd_accept telnetd.c /^telnetd_accept(DCB *dcb)$/
|
||||
telnetd_close telnetd.c /^telnetd_close(DCB *dcb)$/
|
||||
telnetd_command telnetd.c /^telnetd_command(DCB *dcb, unsigned char *cmd)$/
|
||||
telnetd_echo telnetd.c /^telnetd_echo(DCB *dcb, int enable)$/
|
||||
telnetd_error telnetd.c /^telnetd_error(DCB *dcb)$/
|
||||
telnetd_hangup telnetd.c /^telnetd_hangup(DCB *dcb)$/
|
||||
telnetd_listen telnetd.c /^telnetd_listen(DCB *listener, char *config)$/
|
||||
telnetd_read_event telnetd.c /^telnetd_read_event(DCB* dcb)$/
|
||||
telnetd_write telnetd.c /^telnetd_write(DCB *dcb, GWBUF *queue)$/
|
||||
telnetd_write_event telnetd.c /^telnetd_write_event(DCB *dcb)$/
|
||||
version httpd.c /^version()$/
|
||||
@ -36,6 +36,14 @@
|
||||
#include <adminusers.h>
|
||||
#include <skygw_utils.h>
|
||||
#include <log_manager.h>
|
||||
#include <modinfo.h>
|
||||
|
||||
MODULE_INFO info = {
|
||||
MODULE_API_PROTOCOL,
|
||||
MODULE_ALPHA_RELEASE,
|
||||
GWPROTOCOL_VERSION,
|
||||
"A telnet deamon protocol for simple administration interface"
|
||||
};
|
||||
|
||||
extern int lm_enabled_logfiles_bitmask;
|
||||
|
||||
@ -140,9 +148,6 @@ telnetd_read_event(DCB* dcb)
|
||||
int n;
|
||||
GWBUF *head = NULL;
|
||||
SESSION *session = dcb->session;
|
||||
ROUTER_OBJECT *router = session->service->router;
|
||||
ROUTER *router_instance = session->service->router_instance;
|
||||
void *rsession = session->router_session;
|
||||
TELNETD *telnetd = (TELNETD *)dcb->protocol;
|
||||
char *password, *t;
|
||||
|
||||
@ -196,7 +201,7 @@ char *password, *t;
|
||||
free(password);
|
||||
break;
|
||||
case TELNETD_STATE_DATA:
|
||||
router->routeQuery(router_instance, rsession, head);
|
||||
SESSION_ROUTE_QUERY(session, head);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user