Uncrustify maxscale
See script directory for method. The script to run in the top level MaxScale directory is called maxscale-uncrustify.sh, which uses another script, list-src, from the same directory (so you need to set your PATH). The uncrustify version was 0.66.
This commit is contained in:
@ -43,19 +43,19 @@
|
||||
#define ISspace(x) isspace((int)(x))
|
||||
#define CDC_SERVER_STRING "MaxScale(c) v.1.0.0"
|
||||
|
||||
static int cdc_read_event(DCB* dcb);
|
||||
static int cdc_write_event(DCB *dcb);
|
||||
static int cdc_write(DCB *dcb, GWBUF *queue);
|
||||
static int cdc_error(DCB *dcb);
|
||||
static int cdc_hangup(DCB *dcb);
|
||||
static int cdc_accept(DCB *dcb);
|
||||
static int cdc_close(DCB *dcb);
|
||||
static int cdc_listen(DCB *dcb, char *config);
|
||||
static CDC_protocol *cdc_protocol_init(DCB* dcb);
|
||||
static void cdc_protocol_done(DCB* dcb);
|
||||
static int do_auth(DCB *dcb, GWBUF *buffer, void *data);
|
||||
static void write_auth_ack(DCB *dcb);
|
||||
static void write_auth_err(DCB *dcb);
|
||||
static int cdc_read_event(DCB* dcb);
|
||||
static int cdc_write_event(DCB* dcb);
|
||||
static int cdc_write(DCB* dcb, GWBUF* queue);
|
||||
static int cdc_error(DCB* dcb);
|
||||
static int cdc_hangup(DCB* dcb);
|
||||
static int cdc_accept(DCB* dcb);
|
||||
static int cdc_close(DCB* dcb);
|
||||
static int cdc_listen(DCB* dcb, char* config);
|
||||
static CDC_protocol* cdc_protocol_init(DCB* dcb);
|
||||
static void cdc_protocol_done(DCB* dcb);
|
||||
static int do_auth(DCB* dcb, GWBUF* buffer, void* data);
|
||||
static void write_auth_ack(DCB* dcb);
|
||||
static void write_auth_err(DCB* dcb);
|
||||
|
||||
static char* cdc_default_auth()
|
||||
{
|
||||
@ -72,47 +72,46 @@ extern "C"
|
||||
*
|
||||
* @return The module object
|
||||
*/
|
||||
MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{
|
||||
static MXS_PROTOCOL MyObject =
|
||||
MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{
|
||||
cdc_read_event, /* Read - EPOLLIN handler */
|
||||
cdc_write, /* Write - data from gateway */
|
||||
cdc_write_event, /* WriteReady - EPOLLOUT handler */
|
||||
cdc_error, /* Error - EPOLLERR handler */
|
||||
cdc_hangup, /* HangUp - EPOLLHUP handler */
|
||||
cdc_accept, /* Accept */
|
||||
NULL, /* Connect */
|
||||
cdc_close, /* Close */
|
||||
cdc_listen, /* Create a listener */
|
||||
NULL, /* Authentication */
|
||||
cdc_default_auth, /* default authentication */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static MXS_MODULE info =
|
||||
{
|
||||
MXS_MODULE_API_PROTOCOL,
|
||||
MXS_MODULE_IN_DEVELOPMENT,
|
||||
MXS_PROTOCOL_VERSION,
|
||||
"A Change Data Capture Listener implementation for use in binlog events retrieval",
|
||||
"V1.0.0",
|
||||
MXS_NO_MODULE_CAPABILITIES,
|
||||
&MyObject,
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
static MXS_PROTOCOL MyObject =
|
||||
{
|
||||
{MXS_END_MODULE_PARAMS}
|
||||
}
|
||||
};
|
||||
cdc_read_event, /* Read - EPOLLIN handler */
|
||||
cdc_write, /* Write - data from gateway */
|
||||
cdc_write_event, /* WriteReady - EPOLLOUT handler */
|
||||
cdc_error, /* Error - EPOLLERR handler */
|
||||
cdc_hangup, /* HangUp - EPOLLHUP handler */
|
||||
cdc_accept, /* Accept */
|
||||
NULL, /* Connect */
|
||||
cdc_close, /* Close */
|
||||
cdc_listen, /* Create a listener */
|
||||
NULL, /* Authentication */
|
||||
cdc_default_auth, /* default authentication */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
return &info;
|
||||
}
|
||||
static MXS_MODULE info =
|
||||
{
|
||||
MXS_MODULE_API_PROTOCOL,
|
||||
MXS_MODULE_IN_DEVELOPMENT,
|
||||
MXS_PROTOCOL_VERSION,
|
||||
"A Change Data Capture Listener implementation for use in binlog events retrieval",
|
||||
"V1.0.0",
|
||||
MXS_NO_MODULE_CAPABILITIES,
|
||||
&MyObject,
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
{
|
||||
{MXS_END_MODULE_PARAMS}
|
||||
}
|
||||
};
|
||||
|
||||
return &info;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,17 +120,16 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
||||
* @param dcb The descriptor control block
|
||||
* @return
|
||||
*/
|
||||
static int
|
||||
cdc_read_event(DCB* dcb)
|
||||
static int cdc_read_event(DCB* dcb)
|
||||
{
|
||||
MXS_SESSION *session = dcb->session;
|
||||
CDC_protocol *protocol = (CDC_protocol *) dcb->protocol;
|
||||
MXS_SESSION* session = dcb->session;
|
||||
CDC_protocol* protocol = (CDC_protocol*) dcb->protocol;
|
||||
int n, rc = 0;
|
||||
GWBUF *head = NULL;
|
||||
GWBUF* head = NULL;
|
||||
int auth_val = CDC_STATE_AUTH_FAILED;
|
||||
CDC_session *client_data = (CDC_session *) dcb->data;
|
||||
CDC_session* client_data = (CDC_session*) dcb->data;
|
||||
|
||||
if ((n = dcb_read(dcb, &head, 0)) > 0)
|
||||
if ((n = dcb_read(dcb, &head, 0)) > 0)
|
||||
{
|
||||
switch (protocol->state)
|
||||
{
|
||||
@ -158,7 +156,8 @@ cdc_read_event(DCB* dcb)
|
||||
write_auth_ack(dcb);
|
||||
|
||||
MXS_INFO("%s: Client [%s] authenticated with user [%s]",
|
||||
dcb->service->name, dcb->remote != NULL ? dcb->remote : "",
|
||||
dcb->service->name,
|
||||
dcb->remote != NULL ? dcb->remote : "",
|
||||
client_data->user);
|
||||
}
|
||||
else
|
||||
@ -173,25 +172,27 @@ cdc_read_event(DCB* dcb)
|
||||
|
||||
write_auth_err(dcb);
|
||||
MXS_ERROR("%s: authentication failure from [%s], user [%s]",
|
||||
dcb->service->name, dcb->remote != NULL ? dcb->remote : "",
|
||||
dcb->service->name,
|
||||
dcb->remote != NULL ? dcb->remote : "",
|
||||
client_data->user);
|
||||
|
||||
/* force the client connection close */
|
||||
dcb_close(dcb);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case CDC_STATE_HANDLE_REQUEST:
|
||||
// handle CLOSE command, it shoudl be routed as well and client connection closed after last transmission
|
||||
// handle CLOSE command, it shoudl be routed as well and client connection closed after last
|
||||
// transmission
|
||||
if (strncmp((char*)GWBUF_DATA(head), "CLOSE", GWBUF_LENGTH(head)) == 0)
|
||||
{
|
||||
MXS_INFO("%s: Client [%s] has requested CLOSE action",
|
||||
dcb->service->name, dcb->remote != NULL ? dcb->remote : "");
|
||||
dcb->service->name,
|
||||
dcb->remote != NULL ? dcb->remote : "");
|
||||
|
||||
// gwbuf_set_type(head, GWBUF_TYPE_CDC);
|
||||
// the router will close the client connection
|
||||
//rc = MXS_SESSION_ROUTE_QUERY(session, head);
|
||||
// rc = MXS_SESSION_ROUTE_QUERY(session, head);
|
||||
|
||||
// buffer not handled by router right now, consume it
|
||||
gwbuf_free(head);
|
||||
@ -202,8 +203,10 @@ cdc_read_event(DCB* dcb)
|
||||
else
|
||||
{
|
||||
MXS_INFO("%s: Client [%s] requested [%.*s] action",
|
||||
dcb->service->name, dcb->remote != NULL ? dcb->remote : "",
|
||||
(int)GWBUF_LENGTH(head), (char*)GWBUF_DATA(head));
|
||||
dcb->service->name,
|
||||
dcb->remote != NULL ? dcb->remote : "",
|
||||
(int)GWBUF_LENGTH(head),
|
||||
(char*)GWBUF_DATA(head));
|
||||
|
||||
// gwbuf_set_type(head, GWBUF_TYPE_CDC);
|
||||
rc = MXS_SESSION_ROUTE_QUERY(session, head);
|
||||
@ -211,8 +214,10 @@ cdc_read_event(DCB* dcb)
|
||||
break;
|
||||
|
||||
default:
|
||||
MXS_INFO("%s: Client [%s] in unknown state %d", dcb->service->name,
|
||||
dcb->remote != NULL ? dcb->remote : "", protocol->state);
|
||||
MXS_INFO("%s: Client [%s] in unknown state %d",
|
||||
dcb->service->name,
|
||||
dcb->remote != NULL ? dcb->remote : "",
|
||||
protocol->state);
|
||||
gwbuf_free(head);
|
||||
|
||||
break;
|
||||
@ -228,8 +233,7 @@ cdc_read_event(DCB* dcb)
|
||||
* @param dcb The descriptor control block
|
||||
* @return
|
||||
*/
|
||||
static int
|
||||
cdc_write_event(DCB *dcb)
|
||||
static int cdc_write_event(DCB* dcb)
|
||||
{
|
||||
return dcb_drain_writeq(dcb);
|
||||
}
|
||||
@ -243,8 +247,7 @@ cdc_write_event(DCB *dcb)
|
||||
* @param dcb Descriptor Control Block for the socket
|
||||
* @param queue Linked list of buffes to write
|
||||
*/
|
||||
static int
|
||||
cdc_write(DCB *dcb, GWBUF *queue)
|
||||
static int cdc_write(DCB* dcb, GWBUF* queue)
|
||||
{
|
||||
int rc;
|
||||
rc = dcb_write(dcb, queue);
|
||||
@ -256,8 +259,7 @@ cdc_write(DCB *dcb, GWBUF *queue)
|
||||
*
|
||||
* @param dcb The descriptor control block
|
||||
*/
|
||||
static int
|
||||
cdc_error(DCB *dcb)
|
||||
static int cdc_error(DCB* dcb)
|
||||
{
|
||||
dcb_close(dcb);
|
||||
return 0;
|
||||
@ -268,8 +270,7 @@ cdc_error(DCB *dcb)
|
||||
*
|
||||
* @param dcb The descriptor control block
|
||||
*/
|
||||
static int
|
||||
cdc_hangup(DCB *dcb)
|
||||
static int cdc_hangup(DCB* dcb)
|
||||
{
|
||||
dcb_close(dcb);
|
||||
return 0;
|
||||
@ -281,16 +282,15 @@ cdc_hangup(DCB *dcb)
|
||||
*
|
||||
* @param dcb The descriptor control block
|
||||
*/
|
||||
static int
|
||||
cdc_accept(DCB *listener)
|
||||
static int cdc_accept(DCB* listener)
|
||||
{
|
||||
int n_connect = 0;
|
||||
DCB *client_dcb;
|
||||
DCB* client_dcb;
|
||||
|
||||
while ((client_dcb = dcb_accept(listener)) != NULL)
|
||||
{
|
||||
CDC_session *client_data = NULL;
|
||||
CDC_protocol *protocol = NULL;
|
||||
CDC_session* client_data = NULL;
|
||||
CDC_protocol* protocol = NULL;
|
||||
|
||||
/* allocating CDC protocol */
|
||||
protocol = cdc_protocol_init(client_dcb);
|
||||
@ -301,7 +301,7 @@ cdc_accept(DCB *listener)
|
||||
continue;
|
||||
}
|
||||
|
||||
client_dcb->protocol = (CDC_protocol *) protocol;
|
||||
client_dcb->protocol = (CDC_protocol*) protocol;
|
||||
|
||||
/* Dummy session */
|
||||
client_dcb->session = session_set_dummy(client_dcb);
|
||||
@ -312,9 +312,11 @@ cdc_accept(DCB *listener)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* create the session data for CDC */
|
||||
/* this coud be done in anothe routine, let's keep it here for now */
|
||||
client_data = (CDC_session *) MXS_CALLOC(1, sizeof(CDC_session));
|
||||
/*
|
||||
* create the session data for CDC
|
||||
* this coud be done in anothe routine, let's keep it here for now
|
||||
*/
|
||||
client_data = (CDC_session*) MXS_CALLOC(1, sizeof(CDC_session));
|
||||
if (client_data == NULL)
|
||||
{
|
||||
dcb_close(client_dcb);
|
||||
@ -326,7 +328,8 @@ cdc_accept(DCB *listener)
|
||||
/* client protocol state change to CDC_STATE_WAIT_FOR_AUTH */
|
||||
protocol->state = CDC_STATE_WAIT_FOR_AUTH;
|
||||
|
||||
MXS_NOTICE("%s: new connection from [%s]", client_dcb->service->name,
|
||||
MXS_NOTICE("%s: new connection from [%s]",
|
||||
client_dcb->service->name,
|
||||
client_dcb->remote != NULL ? client_dcb->remote : "");
|
||||
|
||||
n_connect++;
|
||||
@ -341,10 +344,9 @@ cdc_accept(DCB *listener)
|
||||
*
|
||||
* @param dcb The descriptor control block
|
||||
*/
|
||||
static int
|
||||
cdc_close(DCB *dcb)
|
||||
static int cdc_close(DCB* dcb)
|
||||
{
|
||||
CDC_protocol *p = (CDC_protocol *) dcb->protocol;
|
||||
CDC_protocol* p = (CDC_protocol*) dcb->protocol;
|
||||
|
||||
if (!p)
|
||||
{
|
||||
@ -363,8 +365,7 @@ cdc_close(DCB *dcb)
|
||||
* @param listener The Listener DCB
|
||||
* @param config Configuration (ip:port)
|
||||
*/
|
||||
static int
|
||||
cdc_listen(DCB *listener, char *config)
|
||||
static int cdc_listen(DCB* listener, char* config)
|
||||
{
|
||||
return (dcb_listen(listener, config, "CDC") < 0) ? 0 : 1;
|
||||
}
|
||||
@ -376,12 +377,11 @@ cdc_listen(DCB *listener, char *config)
|
||||
* @return New allocated protocol or NULL on errors
|
||||
*
|
||||
*/
|
||||
static CDC_protocol *
|
||||
cdc_protocol_init(DCB* dcb)
|
||||
static CDC_protocol* cdc_protocol_init(DCB* dcb)
|
||||
{
|
||||
CDC_protocol* p;
|
||||
|
||||
p = (CDC_protocol *) MXS_CALLOC(1, sizeof(CDC_protocol));
|
||||
p = (CDC_protocol*) MXS_CALLOC(1, sizeof(CDC_protocol));
|
||||
|
||||
if (p == NULL)
|
||||
{
|
||||
@ -404,17 +404,16 @@ cdc_protocol_init(DCB* dcb)
|
||||
* @param dcb DCB with allocateid protocol
|
||||
*
|
||||
*/
|
||||
static void
|
||||
cdc_protocol_done(DCB* dcb)
|
||||
static void cdc_protocol_done(DCB* dcb)
|
||||
{
|
||||
CDC_protocol* p = (CDC_protocol *) dcb->protocol;
|
||||
CDC_protocol* p = (CDC_protocol*) dcb->protocol;
|
||||
|
||||
if (!p)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
p = (CDC_protocol *) dcb->protocol;
|
||||
p = (CDC_protocol*) dcb->protocol;
|
||||
|
||||
spinlock_acquire(&p->lock);
|
||||
|
||||
@ -431,8 +430,7 @@ cdc_protocol_done(DCB* dcb)
|
||||
* @param dcb Current client DCB
|
||||
*
|
||||
*/
|
||||
static void
|
||||
write_auth_ack(DCB *dcb)
|
||||
static void write_auth_ack(DCB* dcb)
|
||||
{
|
||||
dcb_printf(dcb, "OK\n");
|
||||
}
|
||||
@ -443,9 +441,7 @@ write_auth_ack(DCB *dcb)
|
||||
* @param dcb Current client DCB
|
||||
*
|
||||
*/
|
||||
static void
|
||||
write_auth_err(DCB *dcb)
|
||||
static void write_auth_err(DCB* dcb)
|
||||
{
|
||||
dcb_printf(dcb, "ERROR: Authentication failed\n");
|
||||
}
|
||||
|
||||
|
@ -45,17 +45,17 @@
|
||||
#define ISspace(x) isspace((int)(x))
|
||||
#define HTTP_SERVER_STRING "MaxScale(c) v.1.0.0"
|
||||
|
||||
static int httpd_read_event(DCB* dcb);
|
||||
static int httpd_write_event(DCB *dcb);
|
||||
static int httpd_write(DCB *dcb, GWBUF *queue);
|
||||
static int httpd_error(DCB *dcb);
|
||||
static int httpd_hangup(DCB *dcb);
|
||||
static int httpd_accept(DCB *dcb);
|
||||
static int httpd_close(DCB *dcb);
|
||||
static int httpd_listen(DCB *dcb, char *config);
|
||||
static int httpd_get_line(int sock, char *buf, int size);
|
||||
static void httpd_send_headers(DCB *dcb, int final, bool auth_ok);
|
||||
static char *httpd_default_auth();
|
||||
static int httpd_read_event(DCB* dcb);
|
||||
static int httpd_write_event(DCB* dcb);
|
||||
static int httpd_write(DCB* dcb, GWBUF* queue);
|
||||
static int httpd_error(DCB* dcb);
|
||||
static int httpd_hangup(DCB* dcb);
|
||||
static int httpd_accept(DCB* dcb);
|
||||
static int httpd_close(DCB* dcb);
|
||||
static int httpd_listen(DCB* dcb, char* config);
|
||||
static int httpd_get_line(int sock, char* buf, int size);
|
||||
static void httpd_send_headers(DCB* dcb, int final, bool auth_ok);
|
||||
static char* httpd_default_auth();
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@ -67,47 +67,46 @@ extern "C"
|
||||
*
|
||||
* @return The module object
|
||||
*/
|
||||
MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{
|
||||
static MXS_PROTOCOL MyObject =
|
||||
MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{
|
||||
httpd_read_event, /**< Read - EPOLLIN handler */
|
||||
httpd_write, /**< Write - data from gateway */
|
||||
httpd_write_event, /**< WriteReady - EPOLLOUT handler */
|
||||
httpd_error, /**< Error - EPOLLERR handler */
|
||||
httpd_hangup, /**< HangUp - EPOLLHUP handler */
|
||||
httpd_accept, /**< Accept */
|
||||
NULL, /**< Connect */
|
||||
httpd_close, /**< Close */
|
||||
httpd_listen, /**< Create a listener */
|
||||
NULL, /**< Authentication */
|
||||
httpd_default_auth, /**< Default authenticator */
|
||||
NULL, /**< Connection limit reached */
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static MXS_MODULE info =
|
||||
{
|
||||
MXS_MODULE_API_PROTOCOL,
|
||||
MXS_MODULE_IN_DEVELOPMENT,
|
||||
MXS_PROTOCOL_VERSION,
|
||||
"An experimental HTTPD implementation for use in administration",
|
||||
"V1.2.0",
|
||||
MXS_NO_MODULE_CAPABILITIES,
|
||||
&MyObject,
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
static MXS_PROTOCOL MyObject =
|
||||
{
|
||||
{MXS_END_MODULE_PARAMS}
|
||||
}
|
||||
};
|
||||
httpd_read_event, /**< Read - EPOLLIN handler */
|
||||
httpd_write, /**< Write - data from gateway */
|
||||
httpd_write_event, /**< WriteReady - EPOLLOUT handler */
|
||||
httpd_error, /**< Error - EPOLLERR handler */
|
||||
httpd_hangup, /**< HangUp - EPOLLHUP handler */
|
||||
httpd_accept, /**< Accept */
|
||||
NULL, /**< Connect */
|
||||
httpd_close, /**< Close */
|
||||
httpd_listen, /**< Create a listener */
|
||||
NULL, /**< Authentication */
|
||||
httpd_default_auth, /**< Default authenticator */
|
||||
NULL, /**< Connection limit reached */
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
return &info;
|
||||
}
|
||||
static MXS_MODULE info =
|
||||
{
|
||||
MXS_MODULE_API_PROTOCOL,
|
||||
MXS_MODULE_IN_DEVELOPMENT,
|
||||
MXS_PROTOCOL_VERSION,
|
||||
"An experimental HTTPD implementation for use in administration",
|
||||
"V1.2.0",
|
||||
MXS_NO_MODULE_CAPABILITIES,
|
||||
&MyObject,
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
{
|
||||
{MXS_END_MODULE_PARAMS}
|
||||
}
|
||||
};
|
||||
|
||||
return &info;
|
||||
}
|
||||
}
|
||||
/*lint +e14 */
|
||||
|
||||
@ -118,7 +117,7 @@ static const char* default_auth = "NullAuthAllow";
|
||||
*
|
||||
* @return name of authenticator
|
||||
*/
|
||||
static char *httpd_default_auth()
|
||||
static char* httpd_default_auth()
|
||||
{
|
||||
return (char*)default_auth;
|
||||
}
|
||||
@ -131,17 +130,17 @@ static char *httpd_default_auth()
|
||||
*/
|
||||
static int httpd_read_event(DCB* dcb)
|
||||
{
|
||||
MXS_SESSION *session = dcb->session;
|
||||
MXS_SESSION* session = dcb->session;
|
||||
|
||||
int numchars = 1;
|
||||
char buf[HTTPD_REQUESTLINE_MAXLEN - 1] = "";
|
||||
char *query_string = NULL;
|
||||
char* query_string = NULL;
|
||||
char method[HTTPD_METHOD_MAXLEN - 1] = "";
|
||||
char url[HTTPD_SMALL_BUFFER] = "";
|
||||
size_t i, j;
|
||||
int headers_read = 0;
|
||||
HTTPD_session *client_data = NULL;
|
||||
GWBUF *uri;
|
||||
HTTPD_session* client_data = NULL;
|
||||
GWBUF* uri;
|
||||
|
||||
client_data = static_cast<HTTPD_session*>(dcb->data);
|
||||
|
||||
@ -167,13 +166,13 @@ static int httpd_read_event(DCB* dcb)
|
||||
/* check allowed http methods */
|
||||
if (strcasecmp(method, "GET") && strcasecmp(method, "POST"))
|
||||
{
|
||||
//httpd_unimplemented(dcb->fd);
|
||||
// httpd_unimplemented(dcb->fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
while ( (j < sizeof(buf)) && ISspace(buf[j]))
|
||||
while ((j < sizeof(buf)) && ISspace(buf[j]))
|
||||
{
|
||||
j++;
|
||||
}
|
||||
@ -215,8 +214,8 @@ static int httpd_read_event(DCB* dcb)
|
||||
|
||||
while ((numchars > 0) && strcmp("\n", buf))
|
||||
{
|
||||
char *value = NULL;
|
||||
char *end = NULL;
|
||||
char* value = NULL;
|
||||
char* end = NULL;
|
||||
numchars = httpd_get_line(dcb->fd, buf, sizeof(buf));
|
||||
if ((value = strchr(buf, ':')))
|
||||
{
|
||||
@ -236,7 +235,7 @@ static int httpd_read_event(DCB* dcb)
|
||||
|
||||
if (strcmp(buf, "Authorization") == 0)
|
||||
{
|
||||
GWBUF *auth_data = gwbuf_alloc_and_load(strlen(value), value);
|
||||
GWBUF* auth_data = gwbuf_alloc_and_load(strlen(value), value);
|
||||
MXS_OOM_IFNULL(auth_data);
|
||||
|
||||
if (auth_data)
|
||||
@ -285,7 +284,7 @@ static int httpd_read_event(DCB* dcb)
|
||||
}
|
||||
if (strcmp(url, "/services") == 0)
|
||||
{
|
||||
ResultSet *set, *seviceGetList();
|
||||
ResultSet* set, * seviceGetList();
|
||||
if ((set = serviceGetList()) != NULL)
|
||||
{
|
||||
resultset_stream_json(set, dcb);
|
||||
@ -295,7 +294,7 @@ static int httpd_read_event(DCB* dcb)
|
||||
#endif
|
||||
if (auth_ok && (uri = gwbuf_alloc(strlen(url) + 1)) != NULL)
|
||||
{
|
||||
strcpy((char *)GWBUF_DATA(uri), url);
|
||||
strcpy((char*)GWBUF_DATA(uri), url);
|
||||
gwbuf_set_type(uri, GWBUF_TYPE_HTTP);
|
||||
MXS_SESSION_ROUTE_QUERY(session, uri);
|
||||
}
|
||||
@ -312,7 +311,7 @@ static int httpd_read_event(DCB* dcb)
|
||||
* @param dcb The descriptor control block
|
||||
* @return
|
||||
*/
|
||||
static int httpd_write_event(DCB *dcb)
|
||||
static int httpd_write_event(DCB* dcb)
|
||||
{
|
||||
return dcb_drain_writeq(dcb);
|
||||
}
|
||||
@ -326,7 +325,7 @@ static int httpd_write_event(DCB *dcb)
|
||||
* @param dcb Descriptor Control Block for the socket
|
||||
* @param queue Linked list of buffes to write
|
||||
*/
|
||||
static int httpd_write(DCB *dcb, GWBUF *queue)
|
||||
static int httpd_write(DCB* dcb, GWBUF* queue)
|
||||
{
|
||||
int rc;
|
||||
rc = dcb_write(dcb, queue);
|
||||
@ -338,7 +337,7 @@ static int httpd_write(DCB *dcb, GWBUF *queue)
|
||||
*
|
||||
* @param dcb The descriptor control block
|
||||
*/
|
||||
static int httpd_error(DCB *dcb)
|
||||
static int httpd_error(DCB* dcb)
|
||||
{
|
||||
dcb_close(dcb);
|
||||
return 0;
|
||||
@ -349,7 +348,7 @@ static int httpd_error(DCB *dcb)
|
||||
*
|
||||
* @param dcb The descriptor control block
|
||||
*/
|
||||
static int httpd_hangup(DCB *dcb)
|
||||
static int httpd_hangup(DCB* dcb)
|
||||
{
|
||||
dcb_close(dcb);
|
||||
return 0;
|
||||
@ -361,17 +360,17 @@ static int httpd_hangup(DCB *dcb)
|
||||
*
|
||||
* @param listener The descriptor control block
|
||||
*/
|
||||
static int httpd_accept(DCB *listener)
|
||||
static int httpd_accept(DCB* listener)
|
||||
{
|
||||
int n_connect = 0;
|
||||
DCB *client_dcb;
|
||||
DCB* client_dcb;
|
||||
|
||||
while ((client_dcb = dcb_accept(listener)) != NULL)
|
||||
{
|
||||
HTTPD_session *client_data = NULL;
|
||||
HTTPD_session* client_data = NULL;
|
||||
|
||||
/* create the session data for HTTPD */
|
||||
if ((client_data = (HTTPD_session *)MXS_CALLOC(1, sizeof(HTTPD_session))) == NULL)
|
||||
if ((client_data = (HTTPD_session*)MXS_CALLOC(1, sizeof(HTTPD_session))) == NULL)
|
||||
{
|
||||
dcb_close(client_dcb);
|
||||
continue;
|
||||
@ -397,7 +396,7 @@ static int httpd_accept(DCB *listener)
|
||||
* @param dcb The descriptor control block
|
||||
*/
|
||||
|
||||
static int httpd_close(DCB *dcb)
|
||||
static int httpd_close(DCB* dcb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -408,7 +407,7 @@ static int httpd_close(DCB *dcb)
|
||||
* @param listener The Listener DCB
|
||||
* @param config Configuration (ip:port)
|
||||
*/
|
||||
static int httpd_listen(DCB *listener, char *config)
|
||||
static int httpd_listen(DCB* listener, char* config)
|
||||
{
|
||||
return (dcb_listen(listener, config, "HTTPD") < 0) ? 0 : 1;
|
||||
}
|
||||
@ -416,7 +415,7 @@ static int httpd_listen(DCB *listener, char *config)
|
||||
/**
|
||||
* HTTPD get line from client
|
||||
*/
|
||||
static int httpd_get_line(int sock, char *buf, int size)
|
||||
static int httpd_get_line(int sock, char* buf, int size)
|
||||
{
|
||||
int i = 0;
|
||||
char c = '\0';
|
||||
@ -461,16 +460,16 @@ static int httpd_get_line(int sock, char *buf, int size)
|
||||
/**
|
||||
* HTTPD send basic headers with 200 OK
|
||||
*/
|
||||
static void httpd_send_headers(DCB *dcb, int final, bool auth_ok)
|
||||
static void httpd_send_headers(DCB* dcb, int final, bool auth_ok)
|
||||
{
|
||||
char date[64] = "";
|
||||
const char *fmt = "%a, %d %b %Y %H:%M:%S GMT";
|
||||
const char* fmt = "%a, %d %b %Y %H:%M:%S GMT";
|
||||
time_t httpd_current_time = time(NULL);
|
||||
|
||||
struct tm tm;
|
||||
localtime_r(&httpd_current_time, &tm);
|
||||
strftime(date, sizeof(date), fmt, &tm);
|
||||
const char *response = auth_ok ? "200 OK" : "401 Unauthorized";
|
||||
const char* response = auth_ok ? "200 OK" : "401 Unauthorized";
|
||||
dcb_printf(dcb,
|
||||
"HTTP/1.1 %s\r\n"
|
||||
"Date: %s\r\n"
|
||||
@ -478,7 +477,9 @@ static void httpd_send_headers(DCB *dcb, int final, bool auth_ok)
|
||||
"Connection: close\r\n"
|
||||
"WWW-Authenticate: Basic realm=\"MaxInfo\"\r\n"
|
||||
"Content-Type: application/json\r\n",
|
||||
response, date, HTTP_SERVER_STRING);
|
||||
response,
|
||||
date,
|
||||
HTTP_SERVER_STRING);
|
||||
|
||||
/* close the headers */
|
||||
if (final)
|
||||
|
@ -40,12 +40,12 @@
|
||||
|
||||
MXS_BEGIN_DECLS
|
||||
|
||||
#define HTTPD_SMALL_BUFFER 1024
|
||||
#define HTTPD_METHOD_MAXLEN 128
|
||||
#define HTTPD_USER_MAXLEN 128
|
||||
#define HTTPD_HOSTNAME_MAXLEN 512
|
||||
#define HTTPD_USERAGENT_MAXLEN 1024
|
||||
#define HTTPD_FIELD_MAXLEN 8192
|
||||
#define HTTPD_SMALL_BUFFER 1024
|
||||
#define HTTPD_METHOD_MAXLEN 128
|
||||
#define HTTPD_USER_MAXLEN 128
|
||||
#define HTTPD_HOSTNAME_MAXLEN 512
|
||||
#define HTTPD_USERAGENT_MAXLEN 1024
|
||||
#define HTTPD_FIELD_MAXLEN 8192
|
||||
#define HTTPD_REQUESTLINE_MAXLEN 8192
|
||||
|
||||
/**
|
||||
@ -54,15 +54,17 @@ MXS_BEGIN_DECLS
|
||||
*/
|
||||
typedef struct httpd_session
|
||||
{
|
||||
char user[HTTPD_USER_MAXLEN]; /*< username for authentication*/
|
||||
char *cookies; /*< all input cookies */
|
||||
char hostname[HTTPD_HOSTNAME_MAXLEN]; /*< The hostname */
|
||||
char useragent[HTTPD_USERAGENT_MAXLEN]; /*< The useragent */
|
||||
char method[HTTPD_METHOD_MAXLEN]; /*< The HTTPD Method */
|
||||
char *url; /*< the URL in the request */
|
||||
char *path_info; /*< the Pathinfo, starts with /, is the extra path segments after the document name */
|
||||
char *query_string; /*< the Query string, starts with ?, after path_info and document name */
|
||||
int headers_received; /*< All the headers has been received, if 1 */
|
||||
char user[HTTPD_USER_MAXLEN]; /*< username for authentication*/
|
||||
char* cookies; /*< all input cookies */
|
||||
char hostname[HTTPD_HOSTNAME_MAXLEN]; /*< The hostname */
|
||||
char useragent[HTTPD_USERAGENT_MAXLEN];/*< The useragent */
|
||||
char method[HTTPD_METHOD_MAXLEN]; /*< The HTTPD Method */
|
||||
char* url; /*< the URL in the request */
|
||||
char* path_info; /*< the Pathinfo, starts with /, is the extra path segments after
|
||||
* the document name */
|
||||
char* query_string; /*< the Query string, starts with ?, after path_info and document
|
||||
* name */
|
||||
int headers_received; /*< All the headers has been received, if 1 */
|
||||
} HTTPD_session;
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -23,13 +23,13 @@
|
||||
|
||||
static const uint32_t poll_events = EPOLLIN | EPOLLOUT | EPOLLET | ERROR_EVENTS;
|
||||
|
||||
LocalClient::LocalClient(MYSQL_session* session, MySQLProtocol* proto, int fd):
|
||||
m_state(VC_WAITING_HANDSHAKE),
|
||||
m_sock(fd),
|
||||
m_expected_bytes(0),
|
||||
m_client(*session),
|
||||
m_protocol(*proto),
|
||||
m_self_destruct(false)
|
||||
LocalClient::LocalClient(MYSQL_session* session, MySQLProtocol* proto, int fd)
|
||||
: m_state(VC_WAITING_HANDSHAKE)
|
||||
, m_sock(fd)
|
||||
, m_expected_bytes(0)
|
||||
, m_client(*session)
|
||||
, m_protocol(*proto)
|
||||
, m_self_destruct(false)
|
||||
{
|
||||
MXB_POLL_DATA::handler = LocalClient::poll_handler;
|
||||
}
|
||||
@ -183,7 +183,6 @@ GWBUF* LocalClient::read_complete_packet()
|
||||
rval = m_partial.release();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return rval;
|
||||
@ -238,7 +237,7 @@ LocalClient* LocalClient::create(MYSQL_session* session, MySQLProtocol* proto, c
|
||||
|
||||
if (fd > 0 && (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0 || errno == EINPROGRESS))
|
||||
{
|
||||
LocalClient* relay = new (std::nothrow) LocalClient(session, proto, fd);
|
||||
LocalClient* relay = new( std::nothrow) LocalClient(session, proto, fd);
|
||||
|
||||
if (relay)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -45,41 +45,44 @@
|
||||
/** Return type of process_special_commands() */
|
||||
typedef enum spec_com_res_t
|
||||
{
|
||||
RES_CONTINUE, // No special command detected, proceed as normal.
|
||||
RES_END, // Query handling completed, do not send to filters/router.
|
||||
RES_MORE_DATA // Possible special command, but not enough data to be sure. Must
|
||||
RES_CONTINUE, // No special command detected, proceed as normal.
|
||||
RES_END, // Query handling completed, do not send to filters/router.
|
||||
RES_MORE_DATA // Possible special command, but not enough data to be sure. Must
|
||||
// wait for more data.
|
||||
} spec_com_res_t;
|
||||
|
||||
const char WORD_KILL[] = "KILL";
|
||||
|
||||
static int process_init(void);
|
||||
static int process_init(void);
|
||||
static void process_finish(void);
|
||||
static int thread_init(void);
|
||||
static int thread_init(void);
|
||||
static void thread_finish(void);
|
||||
|
||||
static int gw_MySQLAccept(DCB *listener);
|
||||
static int gw_MySQLListener(DCB *listener, char *config_bind);
|
||||
static int gw_read_client_event(DCB* dcb);
|
||||
static int gw_write_client_event(DCB *dcb);
|
||||
static int gw_MySQLWrite_client(DCB *dcb, GWBUF *queue);
|
||||
static int gw_error_client_event(DCB *dcb);
|
||||
static int gw_client_close(DCB *dcb);
|
||||
static int gw_client_hangup_event(DCB *dcb);
|
||||
static char *gw_default_auth();
|
||||
static int gw_connection_limit(DCB *dcb, int limit);
|
||||
static int MySQLSendHandshake(DCB* dcb);
|
||||
static int route_by_statement(MXS_SESSION *, uint64_t, GWBUF **);
|
||||
static void mysql_client_auth_error_handling(DCB *dcb, int auth_val, int packet_number);
|
||||
static int gw_read_do_authentication(DCB *dcb, GWBUF *read_buffer, int nbytes_read);
|
||||
static int gw_read_normal_data(DCB *dcb, GWBUF *read_buffer, int nbytes_read);
|
||||
static int gw_read_finish_processing(DCB *dcb, GWBUF *read_buffer, uint64_t capabilities);
|
||||
static void gw_process_one_new_client(DCB *client_dcb);
|
||||
static spec_com_res_t process_special_commands(DCB *client_dcb, GWBUF *read_buffer, int nbytes_read);
|
||||
static spec_com_res_t handle_query_kill(DCB* dcb, GWBUF* read_buffer, spec_com_res_t current,
|
||||
bool is_complete, unsigned int packet_len);
|
||||
static bool parse_kill_query(char *query, uint64_t *thread_id_out, kill_type_t *kt_out, std::string* user);
|
||||
static void parse_and_set_trx_state(MXS_SESSION *ses, GWBUF *data);
|
||||
static int gw_MySQLAccept(DCB* listener);
|
||||
static int gw_MySQLListener(DCB* listener, char* config_bind);
|
||||
static int gw_read_client_event(DCB* dcb);
|
||||
static int gw_write_client_event(DCB* dcb);
|
||||
static int gw_MySQLWrite_client(DCB* dcb, GWBUF* queue);
|
||||
static int gw_error_client_event(DCB* dcb);
|
||||
static int gw_client_close(DCB* dcb);
|
||||
static int gw_client_hangup_event(DCB* dcb);
|
||||
static char* gw_default_auth();
|
||||
static int gw_connection_limit(DCB* dcb, int limit);
|
||||
static int MySQLSendHandshake(DCB* dcb);
|
||||
static int route_by_statement(MXS_SESSION*, uint64_t, GWBUF**);
|
||||
static void mysql_client_auth_error_handling(DCB* dcb, int auth_val, int packet_number);
|
||||
static int gw_read_do_authentication(DCB* dcb, GWBUF* read_buffer, int nbytes_read);
|
||||
static int gw_read_normal_data(DCB* dcb, GWBUF* read_buffer, int nbytes_read);
|
||||
static int gw_read_finish_processing(DCB* dcb, GWBUF* read_buffer, uint64_t capabilities);
|
||||
static void gw_process_one_new_client(DCB* client_dcb);
|
||||
static spec_com_res_t process_special_commands(DCB* client_dcb, GWBUF* read_buffer, int nbytes_read);
|
||||
static spec_com_res_t handle_query_kill(DCB* dcb,
|
||||
GWBUF* read_buffer,
|
||||
spec_com_res_t current,
|
||||
bool is_complete,
|
||||
unsigned int packet_len);
|
||||
static bool parse_kill_query(char* query, uint64_t* thread_id_out, kill_type_t* kt_out, std::string* user);
|
||||
static void parse_and_set_trx_state(MXS_SESSION* ses, GWBUF* data);
|
||||
/**
|
||||
* The module entry point routine. It is this routine that
|
||||
* must populate the structure that is referred to as the
|
||||
@ -132,7 +135,6 @@ extern "C"
|
||||
|
||||
return &info;
|
||||
}
|
||||
|
||||
}
|
||||
/*lint +e14 */
|
||||
|
||||
@ -148,7 +150,9 @@ static int process_init(void)
|
||||
if (rv != 0)
|
||||
{
|
||||
MXS_ERROR("MySQL initialization failed, MariaDB MaxScale will exit. "
|
||||
"MySQL Error: %d, %s.", mysql_errno(NULL), mysql_error(NULL));
|
||||
"MySQL Error: %d, %s.",
|
||||
mysql_errno(NULL),
|
||||
mysql_error(NULL));
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -192,7 +196,7 @@ static void thread_finish(void)
|
||||
*
|
||||
* @return name of authenticator
|
||||
*/
|
||||
static char *gw_default_auth()
|
||||
static char* gw_default_auth()
|
||||
{
|
||||
return (char*)"MySQLAuth";
|
||||
}
|
||||
@ -205,13 +209,13 @@ static char *gw_default_auth()
|
||||
*/
|
||||
int MySQLSendHandshake(DCB* dcb)
|
||||
{
|
||||
uint8_t *outbuf = NULL;
|
||||
uint8_t* outbuf = NULL;
|
||||
uint32_t mysql_payload_size = 0;
|
||||
uint8_t mysql_packet_header[4];
|
||||
uint8_t mysql_packet_id = 0;
|
||||
/* uint8_t mysql_filler = GW_MYSQL_HANDSHAKE_FILLER; not needed*/
|
||||
uint8_t mysql_protocol_version = GW_MYSQL_PROTOCOL_VERSION;
|
||||
uint8_t *mysql_handshake_payload = NULL;
|
||||
uint8_t* mysql_handshake_payload = NULL;
|
||||
uint8_t mysql_thread_id_num[4];
|
||||
uint8_t mysql_scramble_buf[9] = "";
|
||||
uint8_t mysql_plugin_data[13] = "";
|
||||
@ -223,7 +227,7 @@ int MySQLSendHandshake(DCB* dcb)
|
||||
uint8_t mysql_filler_ten[10] = {};
|
||||
/* uint8_t mysql_last_byte = 0x00; not needed */
|
||||
char server_scramble[GW_MYSQL_SCRAMBLE_SIZE + 1] = "";
|
||||
char *version_string;
|
||||
char* version_string;
|
||||
int len_version_string = 0;
|
||||
|
||||
bool is_maria = false;
|
||||
@ -239,8 +243,8 @@ int MySQLSendHandshake(DCB* dcb)
|
||||
}
|
||||
}
|
||||
|
||||
MySQLProtocol *protocol = DCB_PROTOCOL(dcb, MySQLProtocol);
|
||||
GWBUF *buf;
|
||||
MySQLProtocol* protocol = DCB_PROTOCOL(dcb, MySQLProtocol);
|
||||
GWBUF* buf;
|
||||
|
||||
version_string = dcb->service->version_string;
|
||||
len_version_string = strlen(version_string);
|
||||
@ -276,12 +280,13 @@ int MySQLSendHandshake(DCB* dcb)
|
||||
const char* plugin_name = DEFAULT_MYSQL_AUTH_PLUGIN;
|
||||
int plugin_name_len = strlen(plugin_name);
|
||||
|
||||
mysql_payload_size =
|
||||
sizeof(mysql_protocol_version) + (len_version_string + 1) + sizeof(mysql_thread_id_num) + 8 +
|
||||
sizeof(/* mysql_filler */ uint8_t) + sizeof(mysql_server_capabilities_one) + sizeof(mysql_server_language) +
|
||||
sizeof(mysql_server_status) + sizeof(mysql_server_capabilities_two) + sizeof(mysql_scramble_len) +
|
||||
sizeof(mysql_filler_ten) + 12 + sizeof(/* mysql_last_byte */ uint8_t) + plugin_name_len +
|
||||
sizeof(/* mysql_last_byte */ uint8_t);
|
||||
mysql_payload_size
|
||||
= sizeof(mysql_protocol_version) + (len_version_string + 1) + sizeof(mysql_thread_id_num) + 8
|
||||
+ sizeof( /* mysql_filler */ uint8_t) + sizeof(mysql_server_capabilities_one)
|
||||
+ sizeof(mysql_server_language)
|
||||
+ sizeof(mysql_server_status) + sizeof(mysql_server_capabilities_two) + sizeof(mysql_scramble_len)
|
||||
+ sizeof(mysql_filler_ten) + 12 + sizeof( /* mysql_last_byte */ uint8_t) + plugin_name_len
|
||||
+ sizeof( /* mysql_last_byte */ uint8_t);
|
||||
|
||||
// allocate memory for packet header + payload
|
||||
if ((buf = gwbuf_alloc(sizeof(mysql_packet_header) + mysql_payload_size)) == NULL)
|
||||
@ -306,7 +311,7 @@ int MySQLSendHandshake(DCB* dcb)
|
||||
mysql_handshake_payload = mysql_handshake_payload + sizeof(mysql_protocol_version);
|
||||
|
||||
// write server version plus 0 filler
|
||||
strcpy((char *)mysql_handshake_payload, version_string);
|
||||
strcpy((char*)mysql_handshake_payload, version_string);
|
||||
mysql_handshake_payload = mysql_handshake_payload + len_version_string;
|
||||
|
||||
*mysql_handshake_payload = 0x00;
|
||||
@ -346,20 +351,20 @@ int MySQLSendHandshake(DCB* dcb)
|
||||
memcpy(mysql_handshake_payload, &mysql_server_language, sizeof(mysql_server_language));
|
||||
mysql_handshake_payload = mysql_handshake_payload + sizeof(mysql_server_language);
|
||||
|
||||
//write server status
|
||||
// write server status
|
||||
mysql_server_status[0] = 2;
|
||||
mysql_server_status[1] = 0;
|
||||
memcpy(mysql_handshake_payload, mysql_server_status, sizeof(mysql_server_status));
|
||||
mysql_handshake_payload = mysql_handshake_payload + sizeof(mysql_server_status);
|
||||
|
||||
//write server capabilities part two
|
||||
// write server capabilities part two
|
||||
mysql_server_capabilities_two[0] = (uint8_t)(GW_MYSQL_CAPABILITIES_SERVER >> 16);
|
||||
mysql_server_capabilities_two[1] = (uint8_t)(GW_MYSQL_CAPABILITIES_SERVER >> 24);
|
||||
|
||||
// Check that we match the old values
|
||||
mxb_assert(mysql_server_capabilities_two[0] == 15);
|
||||
/** NOTE: pre-2.1 versions sent the fourth byte of the capabilities as
|
||||
the value 128 even though there's no such capability. */
|
||||
* the value 128 even though there's no such capability. */
|
||||
|
||||
memcpy(mysql_handshake_payload, mysql_server_capabilities_two, sizeof(mysql_server_capabilities_two));
|
||||
mysql_handshake_payload = mysql_handshake_payload + sizeof(mysql_server_capabilities_two);
|
||||
@ -368,7 +373,7 @@ int MySQLSendHandshake(DCB* dcb)
|
||||
memcpy(mysql_handshake_payload, &mysql_scramble_len, sizeof(mysql_scramble_len));
|
||||
mysql_handshake_payload = mysql_handshake_payload + sizeof(mysql_scramble_len);
|
||||
|
||||
//write 10 filler
|
||||
// write 10 filler
|
||||
memcpy(mysql_handshake_payload, mysql_filler_ten, sizeof(mysql_filler_ten));
|
||||
mysql_handshake_payload = mysql_handshake_payload + sizeof(mysql_filler_ten);
|
||||
|
||||
@ -376,7 +381,7 @@ int MySQLSendHandshake(DCB* dcb)
|
||||
memcpy(mysql_handshake_payload, mysql_plugin_data, 12);
|
||||
mysql_handshake_payload = mysql_handshake_payload + 12;
|
||||
|
||||
//write last byte, 0
|
||||
// write last byte, 0
|
||||
*mysql_handshake_payload = 0x00;
|
||||
mysql_handshake_payload++;
|
||||
|
||||
@ -384,7 +389,7 @@ int MySQLSendHandshake(DCB* dcb)
|
||||
memcpy(mysql_handshake_payload, plugin_name, plugin_name_len);
|
||||
mysql_handshake_payload = mysql_handshake_payload + plugin_name_len;
|
||||
|
||||
//write last byte, 0
|
||||
// write last byte, 0
|
||||
*mysql_handshake_payload = 0x00;
|
||||
|
||||
// writing data in the Client buffer queue
|
||||
@ -399,7 +404,7 @@ int MySQLSendHandshake(DCB* dcb)
|
||||
* @param dcb The DCB of the client
|
||||
* @param queue Queue of buffers to write
|
||||
*/
|
||||
int gw_MySQLWrite_client(DCB *dcb, GWBUF *queue)
|
||||
int gw_MySQLWrite_client(DCB* dcb, GWBUF* queue)
|
||||
{
|
||||
if (GWBUF_IS_REPLY_OK(queue) && dcb->service->session_track_trx_state)
|
||||
{
|
||||
@ -416,8 +421,8 @@ int gw_MySQLWrite_client(DCB *dcb, GWBUF *queue)
|
||||
*/
|
||||
int gw_read_client_event(DCB* dcb)
|
||||
{
|
||||
MySQLProtocol *protocol;
|
||||
GWBUF *read_buffer = NULL;
|
||||
MySQLProtocol* protocol;
|
||||
GWBUF* read_buffer = NULL;
|
||||
int return_code = 0;
|
||||
uint32_t nbytes_read = 0;
|
||||
uint32_t max_bytes = 0;
|
||||
@ -428,7 +433,7 @@ int gw_read_client_event(DCB* dcb)
|
||||
return 1;
|
||||
}
|
||||
|
||||
protocol = (MySQLProtocol *)dcb->protocol;
|
||||
protocol = (MySQLProtocol*)dcb->protocol;
|
||||
|
||||
MXS_DEBUG("Protocol state: %s", gw_mysql_protocol_state2string(protocol->protocol_auth_state));
|
||||
|
||||
@ -481,9 +486,9 @@ int gw_read_client_event(DCB* dcb)
|
||||
*
|
||||
*/
|
||||
case MXS_AUTH_STATE_MESSAGE_READ:
|
||||
if (nbytes_read < 3 ||
|
||||
(0 == max_bytes && nbytes_read < MYSQL_GET_PACKET_LEN(read_buffer)) ||
|
||||
(0 != max_bytes && nbytes_read < max_bytes))
|
||||
if (nbytes_read < 3
|
||||
|| (0 == max_bytes && nbytes_read < MYSQL_GET_PACKET_LEN(read_buffer))
|
||||
|| (0 != max_bytes && nbytes_read < max_bytes))
|
||||
{
|
||||
dcb_readq_append(dcb, read_buffer);
|
||||
}
|
||||
@ -558,16 +563,16 @@ static int get_zstr_len(const char* str, int len)
|
||||
* @param dcb Client DCB
|
||||
* @param buffer Buffer containing the handshake response packet
|
||||
*/
|
||||
static void store_client_information(DCB *dcb, GWBUF *buffer)
|
||||
static void store_client_information(DCB* dcb, GWBUF* buffer)
|
||||
{
|
||||
size_t len = gwbuf_length(buffer);
|
||||
uint8_t data[len];
|
||||
MySQLProtocol *proto = (MySQLProtocol*)dcb->protocol;
|
||||
MYSQL_session *ses = (MYSQL_session*)dcb->data;
|
||||
MySQLProtocol* proto = (MySQLProtocol*)dcb->protocol;
|
||||
MYSQL_session* ses = (MYSQL_session*)dcb->data;
|
||||
|
||||
gwbuf_copy_data(buffer, 0, len, data);
|
||||
mxb_assert(MYSQL_GET_PAYLOAD_LEN(data) + MYSQL_HEADER_LEN == len ||
|
||||
len == MYSQL_AUTH_PACKET_BASE_SIZE); // For SSL request packet
|
||||
mxb_assert(MYSQL_GET_PAYLOAD_LEN(data) + MYSQL_HEADER_LEN == len
|
||||
|| len == MYSQL_AUTH_PACKET_BASE_SIZE); // For SSL request packet
|
||||
|
||||
proto->client_capabilities = gw_mysql_get_byte4(data + MYSQL_CLIENT_CAP_OFFSET);
|
||||
proto->charset = data[MYSQL_CHARSET_OFFSET];
|
||||
@ -624,7 +629,7 @@ static void store_client_information(DCB *dcb, GWBUF *buffer)
|
||||
* @param buf Buffer containing packet
|
||||
* @param bytes Number of bytes available
|
||||
*/
|
||||
static void check_packet(DCB *dcb, GWBUF *buf, int bytes)
|
||||
static void check_packet(DCB* dcb, GWBUF* buf, int bytes)
|
||||
{
|
||||
uint8_t hdr[MYSQL_HEADER_LEN];
|
||||
mxb_assert(gwbuf_copy_data(buf, 0, MYSQL_HEADER_LEN, hdr) == MYSQL_HEADER_LEN);
|
||||
@ -653,8 +658,7 @@ static void check_packet(DCB *dcb, GWBUF *buf, int bytes)
|
||||
* @param nbytes_read The number of bytes of data read
|
||||
* @return 0 if succeed, 1 otherwise
|
||||
*/
|
||||
static int
|
||||
gw_read_do_authentication(DCB *dcb, GWBUF *read_buffer, int nbytes_read)
|
||||
static int gw_read_do_authentication(DCB* dcb, GWBUF* read_buffer, int nbytes_read)
|
||||
{
|
||||
MXB_AT_DEBUG(check_packet(dcb, read_buffer, nbytes_read));
|
||||
|
||||
@ -676,7 +680,8 @@ gw_read_do_authentication(DCB *dcb, GWBUF *read_buffer, int nbytes_read)
|
||||
* this will be packet number two since the first packet will be the
|
||||
* Protocol::SSLRequest packet.
|
||||
*
|
||||
* @see https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::SSLRequest
|
||||
* @see
|
||||
*https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::SSLRequest
|
||||
*/
|
||||
store_client_information(dcb, read_buffer);
|
||||
}
|
||||
@ -702,7 +707,7 @@ gw_read_do_authentication(DCB *dcb, GWBUF *read_buffer, int nbytes_read)
|
||||
auth_val = MXS_AUTH_BAD_HANDSHAKE;
|
||||
}
|
||||
|
||||
MySQLProtocol *protocol = (MySQLProtocol *)dcb->protocol;
|
||||
MySQLProtocol* protocol = (MySQLProtocol*)dcb->protocol;
|
||||
|
||||
/**
|
||||
* At this point, if the auth_val return code indicates success
|
||||
@ -717,7 +722,7 @@ gw_read_do_authentication(DCB *dcb, GWBUF *read_buffer, int nbytes_read)
|
||||
if (dcb->user == NULL)
|
||||
{
|
||||
/** User authentication complete, copy the username to the DCB */
|
||||
MYSQL_session *ses = (MYSQL_session*)dcb->data;
|
||||
MYSQL_session* ses = (MYSQL_session*)dcb->data;
|
||||
if ((dcb->user = MXS_STRDUP(ses->user)) == NULL)
|
||||
{
|
||||
dcb_close(dcb);
|
||||
@ -734,13 +739,13 @@ gw_read_do_authentication(DCB *dcb, GWBUF *read_buffer, int nbytes_read)
|
||||
* is changed so that future data will go through the
|
||||
* normal data handling function instead of this one.
|
||||
*/
|
||||
MXS_SESSION *session =
|
||||
session_alloc_with_id(dcb->service, dcb, protocol->thread_id);
|
||||
MXS_SESSION* session
|
||||
= session_alloc_with_id(dcb->service, dcb, protocol->thread_id);
|
||||
|
||||
if (session != NULL)
|
||||
{
|
||||
mxb_assert(session->state != SESSION_STATE_ALLOC &&
|
||||
session->state != SESSION_STATE_DUMMY);
|
||||
mxb_assert(session->state != SESSION_STATE_ALLOC
|
||||
&& session->state != SESSION_STATE_DUMMY);
|
||||
// For the time being only the sql_mode is stored in MXS_SESSION::client_protocol_data.
|
||||
session->client_protocol_data = QC_SQL_MODE_DEFAULT;
|
||||
protocol->protocol_auth_state = MXS_AUTH_STATE_COMPLETE;
|
||||
@ -764,9 +769,9 @@ gw_read_do_authentication(DCB *dcb, GWBUF *read_buffer, int nbytes_read)
|
||||
* then the protocol state is updated, the client is notified of the failure
|
||||
* and the DCB is closed.
|
||||
*/
|
||||
if (MXS_AUTH_SUCCEEDED != auth_val &&
|
||||
MXS_AUTH_INCOMPLETE != auth_val &&
|
||||
MXS_AUTH_SSL_INCOMPLETE != auth_val)
|
||||
if (MXS_AUTH_SUCCEEDED != auth_val
|
||||
&& MXS_AUTH_INCOMPLETE != auth_val
|
||||
&& MXS_AUTH_SSL_INCOMPLETE != auth_val)
|
||||
{
|
||||
protocol->protocol_auth_state = MXS_AUTH_STATE_FAILED;
|
||||
mysql_client_auth_error_handling(dcb, auth_val, next_sequence);
|
||||
@ -787,7 +792,7 @@ gw_read_do_authentication(DCB *dcb, GWBUF *read_buffer, int nbytes_read)
|
||||
* @param offset Offset where the split is made
|
||||
* @return The first part of the buffer
|
||||
*/
|
||||
static GWBUF* split_and_store(DCB *client_dcb, GWBUF* queue, int offset)
|
||||
static GWBUF* split_and_store(DCB* client_dcb, GWBUF* queue, int offset)
|
||||
{
|
||||
GWBUF* newbuf = gwbuf_split(&queue, offset);
|
||||
dcb_readq_append(client_dcb, queue);
|
||||
@ -803,7 +808,7 @@ static GWBUF* split_and_store(DCB *client_dcb, GWBUF* queue, int offset)
|
||||
* @param dcb DCB to check
|
||||
* @return True if the DCB protocol is not expecting any data
|
||||
*/
|
||||
static bool protocol_is_idle(DCB *dcb)
|
||||
static bool protocol_is_idle(DCB* dcb)
|
||||
{
|
||||
return dcb->protocol_bytes_processed == dcb->protocol_packet_length;
|
||||
}
|
||||
@ -848,7 +853,7 @@ static bool process_client_commands(DCB* dcb, int bytes_available, GWBUF** buffe
|
||||
if (protocol_is_idle(dcb))
|
||||
{
|
||||
int pktlen;
|
||||
uint8_t cmd = (uint8_t)MXS_COM_QUERY; // Treat empty packets as COM_QUERY
|
||||
uint8_t cmd = (uint8_t)MXS_COM_QUERY; // Treat empty packets as COM_QUERY
|
||||
|
||||
uint8_t packet_header[MYSQL_HEADER_LEN];
|
||||
|
||||
@ -877,7 +882,7 @@ static bool process_client_commands(DCB* dcb, int bytes_available, GWBUF** buffe
|
||||
break;
|
||||
}
|
||||
|
||||
MySQLProtocol *proto = (MySQLProtocol*)dcb->protocol;
|
||||
MySQLProtocol* proto = (MySQLProtocol*)dcb->protocol;
|
||||
if (dcb->protocol_packet_length - MYSQL_HEADER_LEN != GW_MYSQL_MAX_PACKET_LEN)
|
||||
{
|
||||
/** We're processing the first packet of a command */
|
||||
@ -971,8 +976,10 @@ char* handle_variables(MXS_SESSION* session, GWBUF** read_buffer)
|
||||
const SetParser::Result::Item& value = *j;
|
||||
|
||||
message = session_set_variable_value(session,
|
||||
variable.first, variable.second,
|
||||
value.first, value.second);
|
||||
variable.first,
|
||||
variable.second,
|
||||
value.first,
|
||||
value.second);
|
||||
|
||||
++i;
|
||||
++j;
|
||||
@ -1005,10 +1012,9 @@ char* handle_variables(MXS_SESSION* session, GWBUF** read_buffer)
|
||||
* @param nbytes_read The number of bytes of data read
|
||||
* @return 0 if succeed, 1 otherwise
|
||||
*/
|
||||
static int
|
||||
gw_read_normal_data(DCB *dcb, GWBUF *read_buffer, int nbytes_read)
|
||||
static int gw_read_normal_data(DCB* dcb, GWBUF* read_buffer, int nbytes_read)
|
||||
{
|
||||
MXS_SESSION *session;
|
||||
MXS_SESSION* session;
|
||||
mxs_session_state_t session_state_value;
|
||||
uint64_t capabilities = 0;
|
||||
|
||||
@ -1037,8 +1043,8 @@ gw_read_normal_data(DCB *dcb, GWBUF *read_buffer, int nbytes_read)
|
||||
uint8_t pktlen[MYSQL_HEADER_LEN];
|
||||
size_t n_copied = gwbuf_copy_data(read_buffer, 0, MYSQL_HEADER_LEN, pktlen);
|
||||
|
||||
if (n_copied != sizeof(pktlen) ||
|
||||
(uint32_t)nbytes_read < MYSQL_GET_PAYLOAD_LEN(pktlen) + MYSQL_HEADER_LEN)
|
||||
if (n_copied != sizeof(pktlen)
|
||||
|| (uint32_t)nbytes_read < MYSQL_GET_PAYLOAD_LEN(pktlen) + MYSQL_HEADER_LEN)
|
||||
{
|
||||
dcb_readq_append(dcb, read_buffer);
|
||||
return 0;
|
||||
@ -1049,7 +1055,7 @@ gw_read_normal_data(DCB *dcb, GWBUF *read_buffer, int nbytes_read)
|
||||
* If a COM_CHANGE_USER is in progress, this must not be done as the client
|
||||
* is sending authentication data that does not have the command byte.
|
||||
*/
|
||||
MySQLProtocol *proto = (MySQLProtocol*)dcb->protocol;
|
||||
MySQLProtocol* proto = (MySQLProtocol*)dcb->protocol;
|
||||
|
||||
if (!proto->changing_user)
|
||||
{
|
||||
@ -1122,8 +1128,8 @@ gw_read_normal_data(DCB *dcb, GWBUF *read_buffer, int nbytes_read)
|
||||
*/
|
||||
void check_pool_candidate(DCB* dcb)
|
||||
{
|
||||
MXS_SESSION *session = dcb->session;
|
||||
MySQLProtocol *proto = (MySQLProtocol*)dcb->protocol;
|
||||
MXS_SESSION* session = dcb->session;
|
||||
MySQLProtocol* proto = (MySQLProtocol*)dcb->protocol;
|
||||
|
||||
if (proto->current_command == MXS_COM_QUIT)
|
||||
{
|
||||
@ -1147,12 +1153,11 @@ void check_pool_candidate(DCB* dcb)
|
||||
* @param capabilities The router capabilities flags
|
||||
* @return 0 if succeed, 1 otherwise
|
||||
*/
|
||||
static int
|
||||
gw_read_finish_processing(DCB *dcb, GWBUF *read_buffer, uint64_t capabilities)
|
||||
static int gw_read_finish_processing(DCB* dcb, GWBUF* read_buffer, uint64_t capabilities)
|
||||
{
|
||||
MXS_SESSION *session = dcb->session;
|
||||
uint8_t *payload = GWBUF_DATA(read_buffer);
|
||||
MySQLProtocol *proto = (MySQLProtocol*)dcb->protocol;
|
||||
MXS_SESSION* session = dcb->session;
|
||||
uint8_t* payload = GWBUF_DATA(read_buffer);
|
||||
MySQLProtocol* proto = (MySQLProtocol*)dcb->protocol;
|
||||
int return_code = 0;
|
||||
|
||||
/** Reset error handler when routing of the new query begins */
|
||||
@ -1167,11 +1172,12 @@ gw_read_finish_processing(DCB *dcb, GWBUF *read_buffer, uint64_t capabilities)
|
||||
|
||||
if (read_buffer != NULL)
|
||||
{
|
||||
/* Must have been data left over */
|
||||
/* Add incomplete mysql packet to read queue */
|
||||
/*
|
||||
* Must have been data left over
|
||||
* Add incomplete mysql packet to read queue
|
||||
*/
|
||||
|
||||
dcb_readq_append(dcb, read_buffer);
|
||||
|
||||
}
|
||||
}
|
||||
else if (NULL != session->router_session || (rcap_type_required(capabilities, RCAP_TYPE_NO_RSESSION)))
|
||||
@ -1182,8 +1188,10 @@ gw_read_finish_processing(DCB *dcb, GWBUF *read_buffer, uint64_t capabilities)
|
||||
/** Feed the whole buffer to the router */
|
||||
return_code = MXS_SESSION_ROUTE_QUERY(session, read_buffer) ? 0 : 1;
|
||||
}
|
||||
/* else return_code is still 0 from when it was originally set */
|
||||
/* Note that read_buffer has been freed or transferred by this point */
|
||||
/*
|
||||
* else return_code is still 0 from when it was originally set
|
||||
* Note that read_buffer has been freed or transferred by this point
|
||||
*/
|
||||
|
||||
if (return_code != 0)
|
||||
{
|
||||
@ -1209,12 +1217,11 @@ gw_read_finish_processing(DCB *dcb, GWBUF *read_buffer, uint64_t capabilities)
|
||||
* @param auth_val The type of authentication failure
|
||||
* @note Authentication status codes are defined in maxscale/protocol/mysql.h
|
||||
*/
|
||||
static void
|
||||
mysql_client_auth_error_handling(DCB *dcb, int auth_val, int packet_number)
|
||||
static void mysql_client_auth_error_handling(DCB* dcb, int auth_val, int packet_number)
|
||||
{
|
||||
int message_len;
|
||||
char *fail_str = NULL;
|
||||
MYSQL_session *session = (MYSQL_session*)dcb->data;
|
||||
char* fail_str = NULL;
|
||||
MYSQL_session* session = (MYSQL_session*)dcb->data;
|
||||
|
||||
switch (auth_val)
|
||||
{
|
||||
@ -1240,7 +1247,8 @@ mysql_client_auth_error_handling(DCB *dcb, int auth_val, int packet_number)
|
||||
case MXS_AUTH_FAILED_SSL:
|
||||
MXS_DEBUG("client is "
|
||||
"not SSL capable for SSL listener. fd %d, "
|
||||
"state = MYSQL_FAILED_AUTH_SSL.", dcb->fd);
|
||||
"state = MYSQL_FAILED_AUTH_SSL.",
|
||||
dcb->fd);
|
||||
|
||||
/** Send ERR 1045 to client */
|
||||
mysql_send_auth_error(dcb, packet_number, 0, "Access without SSL denied");
|
||||
@ -1248,19 +1256,24 @@ mysql_client_auth_error_handling(DCB *dcb, int auth_val, int packet_number)
|
||||
|
||||
case MXS_AUTH_SSL_INCOMPLETE:
|
||||
MXS_DEBUG("unable to complete SSL authentication. fd %d, "
|
||||
"state = MYSQL_AUTH_SSL_INCOMPLETE.", dcb->fd);
|
||||
"state = MYSQL_AUTH_SSL_INCOMPLETE.",
|
||||
dcb->fd);
|
||||
|
||||
/** Send ERR 1045 to client */
|
||||
mysql_send_auth_error(dcb, packet_number, 0,
|
||||
mysql_send_auth_error(dcb,
|
||||
packet_number,
|
||||
0,
|
||||
"failed to complete SSL authentication");
|
||||
break;
|
||||
|
||||
case MXS_AUTH_FAILED:
|
||||
MXS_DEBUG("authentication failed. fd %d, state = MYSQL_FAILED_AUTH.", dcb->fd);
|
||||
/** Send error 1045 to client */
|
||||
fail_str = create_auth_fail_str(session->user, dcb->remote,
|
||||
fail_str = create_auth_fail_str(session->user,
|
||||
dcb->remote,
|
||||
session->auth_token_len > 0,
|
||||
session->db, auth_val);
|
||||
session->db,
|
||||
auth_val);
|
||||
modutil_send_mysql_err_packet(dcb, packet_number, 0, 1045, "28000", fail_str);
|
||||
break;
|
||||
|
||||
@ -1271,16 +1284,17 @@ mysql_client_auth_error_handling(DCB *dcb, int auth_val, int packet_number)
|
||||
default:
|
||||
MXS_DEBUG("authentication failed. fd %d, state unrecognized.", dcb->fd);
|
||||
/** Send error 1045 to client */
|
||||
fail_str = create_auth_fail_str(session->user, dcb->remote,
|
||||
fail_str = create_auth_fail_str(session->user,
|
||||
dcb->remote,
|
||||
session->auth_token_len > 0,
|
||||
session->db, auth_val);
|
||||
session->db,
|
||||
auth_val);
|
||||
modutil_send_mysql_err_packet(dcb, packet_number, 0, 1045, "28000", fail_str);
|
||||
}
|
||||
MXS_FREE(fail_str);
|
||||
}
|
||||
|
||||
static int
|
||||
gw_connection_limit(DCB *dcb, int limit)
|
||||
static int gw_connection_limit(DCB* dcb, int limit)
|
||||
{
|
||||
return mysql_send_standard_error(dcb, 0, 1040, "Too many connections");
|
||||
}
|
||||
@ -1301,9 +1315,9 @@ gw_connection_limit(DCB *dcb, int limit)
|
||||
* @details (write detailed description here)
|
||||
*
|
||||
*/
|
||||
int gw_write_client_event(DCB *dcb)
|
||||
int gw_write_client_event(DCB* dcb)
|
||||
{
|
||||
MySQLProtocol *protocol = NULL;
|
||||
MySQLProtocol* protocol = NULL;
|
||||
|
||||
mxb_assert(dcb->state != DCB_STATE_DISCONNECTED);
|
||||
|
||||
@ -1321,7 +1335,7 @@ int gw_write_client_event(DCB *dcb)
|
||||
{
|
||||
goto return_1;
|
||||
}
|
||||
protocol = (MySQLProtocol *)dcb->protocol;
|
||||
protocol = (MySQLProtocol*)dcb->protocol;
|
||||
|
||||
if (protocol->protocol_auth_state == MXS_AUTH_STATE_COMPLETE)
|
||||
{
|
||||
@ -1340,7 +1354,7 @@ return_1:
|
||||
* for UNIX Domain Sockets
|
||||
* @return 1 on success, 0 on error
|
||||
*/
|
||||
int gw_MySQLListener(DCB *listen_dcb, char *config_bind)
|
||||
int gw_MySQLListener(DCB* listen_dcb, char* config_bind)
|
||||
{
|
||||
if (dcb_listen(listen_dcb, config_bind, "MySQL") < 0)
|
||||
{
|
||||
@ -1363,22 +1377,22 @@ int gw_MySQLListener(DCB *listen_dcb, char *config_bind)
|
||||
* @return 0 in success, 1 in failure
|
||||
*
|
||||
*/
|
||||
int gw_MySQLAccept(DCB *listener)
|
||||
int gw_MySQLAccept(DCB* listener)
|
||||
{
|
||||
DCB *client_dcb;
|
||||
DCB* client_dcb;
|
||||
|
||||
while ((client_dcb = dcb_accept(listener)) != NULL)
|
||||
{
|
||||
gw_process_one_new_client(client_dcb);
|
||||
} /**< while client_dcb != NULL */
|
||||
} /**< while client_dcb != NULL */
|
||||
|
||||
/* Must have broken out of while loop or received NULL client_dcb */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void gw_process_one_new_client(DCB *client_dcb)
|
||||
static void gw_process_one_new_client(DCB* client_dcb)
|
||||
{
|
||||
MySQLProtocol *protocol;
|
||||
MySQLProtocol* protocol;
|
||||
|
||||
protocol = mysql_protocol_init(client_dcb, client_dcb->fd);
|
||||
|
||||
@ -1391,7 +1405,7 @@ static void gw_process_one_new_client(DCB *client_dcb)
|
||||
}
|
||||
client_dcb->protocol = protocol;
|
||||
|
||||
//send handshake to the client_dcb
|
||||
// send handshake to the client_dcb
|
||||
MySQLSendHandshake(client_dcb);
|
||||
|
||||
// client protocol state change
|
||||
@ -1416,13 +1430,15 @@ static void gw_process_one_new_client(DCB *client_dcb)
|
||||
|
||||
/** Previous state is recovered in poll_add_dcb. */
|
||||
MXS_ERROR("Failed to add dcb %p for fd %d to epoll set.",
|
||||
client_dcb, client_dcb->fd);
|
||||
client_dcb,
|
||||
client_dcb->fd);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_DEBUG("Added dcb %p for fd %d to epoll set.",
|
||||
client_dcb, client_dcb->fd);
|
||||
client_dcb,
|
||||
client_dcb->fd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1438,7 +1454,7 @@ static int gw_error_client_event(DCB* dcb)
|
||||
goto retblock;
|
||||
}
|
||||
|
||||
#if defined(SS_DEBUG)
|
||||
#if defined (SS_DEBUG)
|
||||
MXS_DEBUG("Client error event handling.");
|
||||
#endif
|
||||
dcb_close(dcb);
|
||||
@ -1447,7 +1463,7 @@ retblock:
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int gw_client_close(DCB *dcb)
|
||||
static int gw_client_close(DCB* dcb)
|
||||
{
|
||||
mxb_assert(dcb->protocol);
|
||||
|
||||
@ -1455,11 +1471,11 @@ static int gw_client_close(DCB *dcb)
|
||||
{
|
||||
MXS_SESSION* target = dcb->session;
|
||||
|
||||
if (target->state != SESSION_STATE_TO_BE_FREED &&
|
||||
target->state != SESSION_STATE_DUMMY)
|
||||
if (target->state != SESSION_STATE_TO_BE_FREED
|
||||
&& target->state != SESSION_STATE_DUMMY)
|
||||
{
|
||||
mxb_assert(target->state == SESSION_STATE_ROUTER_READY ||
|
||||
target->state == SESSION_STATE_STOPPING);
|
||||
mxb_assert(target->state == SESSION_STATE_ROUTER_READY
|
||||
|| target->state == SESSION_STATE_STOPPING);
|
||||
MXB_AT_DEBUG(bool removed = ) mxs_rworker_deregister_session(target->ses_id);
|
||||
mxb_assert(removed);
|
||||
session_close(target);
|
||||
@ -1477,7 +1493,7 @@ static int gw_client_close(DCB *dcb)
|
||||
*
|
||||
* @param dcb The DCB of the connection
|
||||
*/
|
||||
static int gw_client_hangup_event(DCB *dcb)
|
||||
static int gw_client_hangup_event(DCB* dcb)
|
||||
{
|
||||
MXS_SESSION* session = dcb->session;
|
||||
|
||||
@ -1491,8 +1507,8 @@ static int gw_client_hangup_event(DCB *dcb)
|
||||
}
|
||||
|
||||
// The client did not send a COM_QUIT packet
|
||||
std::string errmsg{"Connection killed by MaxScale"};
|
||||
std::string extra{session_get_close_reason(dcb->session)};
|
||||
std::string errmsg {"Connection killed by MaxScale"};
|
||||
std::string extra {session_get_close_reason(dcb->session)};
|
||||
|
||||
if (!extra.empty())
|
||||
{
|
||||
@ -1515,7 +1531,7 @@ static int gw_client_hangup_event(DCB *dcb)
|
||||
*/
|
||||
void update_current_command(DCB* dcb, GWBUF* buffer)
|
||||
{
|
||||
MySQLProtocol *proto = (MySQLProtocol*)dcb->protocol;
|
||||
MySQLProtocol* proto = (MySQLProtocol*)dcb->protocol;
|
||||
uint8_t cmd = (uint8_t)MXS_COM_QUERY;
|
||||
|
||||
/**
|
||||
@ -1568,10 +1584,14 @@ static bool reauthenticate_client(MXS_SESSION* session, GWBUF* packetbuf)
|
||||
MYSQL_session* data = (MYSQL_session*)session->client_dcb->data;
|
||||
strcpy(data->user, user);
|
||||
|
||||
int rc = session->client_dcb->authfunc.reauthenticate(session->client_dcb, data->user,
|
||||
&payload[0], payload.size(),
|
||||
proto->scramble, sizeof(proto->scramble),
|
||||
data->client_sha1, sizeof(data->client_sha1));
|
||||
int rc = session->client_dcb->authfunc.reauthenticate(session->client_dcb,
|
||||
data->user,
|
||||
&payload[0],
|
||||
payload.size(),
|
||||
proto->scramble,
|
||||
sizeof(proto->scramble),
|
||||
data->client_sha1,
|
||||
sizeof(data->client_sha1));
|
||||
|
||||
if (rc == MXS_AUTH_SUCCEEDED)
|
||||
{
|
||||
@ -1637,11 +1657,11 @@ static int route_by_statement(MXS_SESSION* session, uint64_t capabilities, GWBUF
|
||||
if (rcap_type_required(capabilities, RCAP_TYPE_CONTIGUOUS_INPUT))
|
||||
{
|
||||
mxb_assert(GWBUF_IS_CONTIGUOUS(packetbuf));
|
||||
SERVICE *service = session->client_dcb->service;
|
||||
SERVICE* service = session->client_dcb->service;
|
||||
|
||||
if (rcap_type_required(capabilities, RCAP_TYPE_TRANSACTION_TRACKING) &&
|
||||
!service->session_track_trx_state &&
|
||||
!session_is_load_active(session))
|
||||
if (rcap_type_required(capabilities, RCAP_TYPE_TRANSACTION_TRACKING)
|
||||
&& !service->session_track_trx_state
|
||||
&& !session_is_load_active(session))
|
||||
{
|
||||
if (session_trx_is_ending(session))
|
||||
{
|
||||
@ -1760,12 +1780,12 @@ return_rc:
|
||||
* @param nbytes_read How many bytes were read
|
||||
* @return see @c spec_com_res_t
|
||||
*/
|
||||
static spec_com_res_t process_special_commands(DCB *dcb, GWBUF *read_buffer, int nbytes_read)
|
||||
static spec_com_res_t process_special_commands(DCB* dcb, GWBUF* read_buffer, int nbytes_read)
|
||||
{
|
||||
spec_com_res_t rval = RES_CONTINUE;
|
||||
bool is_complete = false;
|
||||
unsigned int packet_len =
|
||||
MYSQL_GET_PAYLOAD_LEN((uint8_t *)GWBUF_DATA(read_buffer)) + MYSQL_HEADER_LEN;
|
||||
unsigned int packet_len
|
||||
= MYSQL_GET_PAYLOAD_LEN((uint8_t*)GWBUF_DATA(read_buffer)) + MYSQL_HEADER_LEN;
|
||||
if (gwbuf_length(read_buffer) == packet_len)
|
||||
{
|
||||
is_complete = true;
|
||||
@ -1777,11 +1797,11 @@ static spec_com_res_t process_special_commands(DCB *dcb, GWBUF *read_buffer, int
|
||||
* The option is stored as a two byte integer with the values 0 for enabling
|
||||
* multi-statements and 1 for disabling it.
|
||||
*/
|
||||
MySQLProtocol *proto = (MySQLProtocol*)dcb->protocol;
|
||||
MySQLProtocol* proto = (MySQLProtocol*)dcb->protocol;
|
||||
uint8_t opt;
|
||||
|
||||
if (proto->current_command == MXS_COM_SET_OPTION &&
|
||||
gwbuf_copy_data(read_buffer, MYSQL_HEADER_LEN + 2, 1, &opt))
|
||||
if (proto->current_command == MXS_COM_SET_OPTION
|
||||
&& gwbuf_copy_data(read_buffer, MYSQL_HEADER_LEN + 2, 1, &opt))
|
||||
{
|
||||
if (opt)
|
||||
{
|
||||
@ -1822,8 +1842,8 @@ static spec_com_res_t process_special_commands(DCB *dcb, GWBUF *read_buffer, int
|
||||
const int SHORTEST_KILL = sizeof("KILL 1") - 1;
|
||||
const int LONGEST_KILL = sizeof("KILL CONNECTION 12345678901234567890 ;");
|
||||
/* Is length within limits for a kill-type query? */
|
||||
if (packet_len >= (MYSQL_HEADER_LEN + 1 + SHORTEST_KILL) &&
|
||||
packet_len <= (MYSQL_HEADER_LEN + 1 + LONGEST_KILL))
|
||||
if (packet_len >= (MYSQL_HEADER_LEN + 1 + SHORTEST_KILL)
|
||||
&& packet_len <= (MYSQL_HEADER_LEN + 1 + LONGEST_KILL))
|
||||
{
|
||||
rval = handle_query_kill(dcb, read_buffer, rval, is_complete, packet_len);
|
||||
}
|
||||
@ -1843,16 +1863,21 @@ static spec_com_res_t process_special_commands(DCB *dcb, GWBUF *read_buffer, int
|
||||
* @param packet_len Read from sql header
|
||||
* @return Updated (or old) value of rval
|
||||
*/
|
||||
spec_com_res_t handle_query_kill(DCB* dcb, GWBUF* read_buffer, spec_com_res_t current,
|
||||
bool is_complete, unsigned int packet_len)
|
||||
spec_com_res_t handle_query_kill(DCB* dcb,
|
||||
GWBUF* read_buffer,
|
||||
spec_com_res_t current,
|
||||
bool is_complete,
|
||||
unsigned int packet_len)
|
||||
{
|
||||
spec_com_res_t rval = current;
|
||||
/* First, we need to detect the text "KILL" (ignorecase) in the start
|
||||
* of the packet. Copy just enough characters. */
|
||||
const size_t KILL_BEGIN_LEN = sizeof(WORD_KILL) - 1;
|
||||
char startbuf[KILL_BEGIN_LEN]; // Not 0-terminated, careful...
|
||||
size_t copied_len = gwbuf_copy_data(read_buffer, MYSQL_HEADER_LEN + 1,
|
||||
KILL_BEGIN_LEN, (uint8_t*)startbuf);
|
||||
char startbuf[KILL_BEGIN_LEN]; // Not 0-terminated, careful...
|
||||
size_t copied_len = gwbuf_copy_data(read_buffer,
|
||||
MYSQL_HEADER_LEN + 1,
|
||||
KILL_BEGIN_LEN,
|
||||
(uint8_t*)startbuf);
|
||||
if (is_complete)
|
||||
{
|
||||
if (strncasecmp(WORD_KILL, startbuf, KILL_BEGIN_LEN) == 0)
|
||||
@ -1860,7 +1885,7 @@ spec_com_res_t handle_query_kill(DCB* dcb, GWBUF* read_buffer, spec_com_res_t cu
|
||||
/* Good chance that the query is a KILL-query. Copy the entire
|
||||
* buffer and process. */
|
||||
size_t buffer_len = packet_len - (MYSQL_HEADER_LEN + 1);
|
||||
char querybuf[buffer_len + 1]; // 0-terminated
|
||||
char querybuf[buffer_len + 1]; // 0-terminated
|
||||
copied_len = gwbuf_copy_data(read_buffer,
|
||||
MYSQL_HEADER_LEN + 1,
|
||||
buffer_len,
|
||||
@ -1918,7 +1943,7 @@ static void extract_user(char* token, std::string* user)
|
||||
* @param kt_out Kill command type output
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
static bool parse_kill_query(char *query, uint64_t *thread_id_out, kill_type_t *kt_out, std::string* user)
|
||||
static bool parse_kill_query(char* query, uint64_t* thread_id_out, kill_type_t* kt_out, std::string* user)
|
||||
{
|
||||
const char WORD_CONNECTION[] = "CONNECTION";
|
||||
const char WORD_QUERY[] = "QUERY";
|
||||
@ -1940,10 +1965,10 @@ static bool parse_kill_query(char *query, uint64_t *thread_id_out, kill_type_t *
|
||||
SEMICOLON,
|
||||
DONE
|
||||
} state = KILL;
|
||||
char *saveptr = NULL;
|
||||
char* saveptr = NULL;
|
||||
bool error = false;
|
||||
|
||||
char *token = strtok_r(query, DELIM, &saveptr);
|
||||
char* token = strtok_r(query, DELIM, &saveptr);
|
||||
|
||||
while (token && !error)
|
||||
{
|
||||
@ -2001,13 +2026,13 @@ static bool parse_kill_query(char *query, uint64_t *thread_id_out, kill_type_t *
|
||||
}
|
||||
else
|
||||
{
|
||||
char *endptr_id = NULL;
|
||||
char* endptr_id = NULL;
|
||||
|
||||
long long int l = strtoll(token, &endptr_id, 0);
|
||||
long long int l = strtoll(token, &endptr_id, 0);
|
||||
|
||||
if ((l == LLONG_MAX && errno == ERANGE) ||
|
||||
(*endptr_id != '\0' && *endptr_id != ';') ||
|
||||
l <= 0 || endptr_id == token)
|
||||
if ((l == LLONG_MAX && errno == ERANGE)
|
||||
|| (*endptr_id != '\0' && *endptr_id != ';')
|
||||
|| l <= 0 || endptr_id == token)
|
||||
{
|
||||
// Not a positive 32-bit integer
|
||||
error = true;
|
||||
@ -2015,7 +2040,7 @@ static bool parse_kill_query(char *query, uint64_t *thread_id_out, kill_type_t *
|
||||
else
|
||||
{
|
||||
mxb_assert(*endptr_id == '\0' || *endptr_id == ';');
|
||||
state = SEMICOLON; // In case we have space before ;
|
||||
state = SEMICOLON; // In case we have space before ;
|
||||
get_next = true;
|
||||
thread_id = l;
|
||||
}
|
||||
@ -2065,22 +2090,22 @@ static bool parse_kill_query(char *query, uint64_t *thread_id_out, kill_type_t *
|
||||
}
|
||||
|
||||
/*
|
||||
* Mapping three session tracker's info to mxs_session_trx_state_t
|
||||
* SESSION_TRACK_STATE_CHANGE:
|
||||
* Get lasted autocommit value;
|
||||
* https://dev.mysql.com/worklog/task/?id=6885
|
||||
* SESSION_TRACK_TRANSACTION_TYPE:
|
||||
* Get transaction boundaries
|
||||
* TX_EMPTY => SESSION_TRX_INACTIVE
|
||||
* TX_EXPLICIT | TX_IMPLICIT => SESSION_TRX_ACTIVE
|
||||
* https://dev.mysql.com/worklog/task/?id=6885
|
||||
* SESSION_TRACK_TRANSACTION_CHARACTERISTICS
|
||||
* Get trx characteristics such as read only, read write, snapshot ...
|
||||
*
|
||||
*/
|
||||
static void parse_and_set_trx_state(MXS_SESSION *ses, GWBUF *data)
|
||||
* Mapping three session tracker's info to mxs_session_trx_state_t
|
||||
* SESSION_TRACK_STATE_CHANGE:
|
||||
* Get lasted autocommit value;
|
||||
* https://dev.mysql.com/worklog/task/?id=6885
|
||||
* SESSION_TRACK_TRANSACTION_TYPE:
|
||||
* Get transaction boundaries
|
||||
* TX_EMPTY => SESSION_TRX_INACTIVE
|
||||
* TX_EXPLICIT | TX_IMPLICIT => SESSION_TRX_ACTIVE
|
||||
* https://dev.mysql.com/worklog/task/?id=6885
|
||||
* SESSION_TRACK_TRANSACTION_CHARACTERISTICS
|
||||
* Get trx characteristics such as read only, read write, snapshot ...
|
||||
*
|
||||
*/
|
||||
static void parse_and_set_trx_state(MXS_SESSION* ses, GWBUF* data)
|
||||
{
|
||||
char *autocommit = gwbuf_get_property(data, (char *)"autocommit");
|
||||
char* autocommit = gwbuf_get_property(data, (char*)"autocommit");
|
||||
|
||||
if (autocommit)
|
||||
{
|
||||
@ -2094,7 +2119,7 @@ static void parse_and_set_trx_state(MXS_SESSION *ses, GWBUF *data)
|
||||
session_set_autocommit(ses, false);
|
||||
}
|
||||
}
|
||||
char *trx_state = gwbuf_get_property(data, (char *)"trx_state");
|
||||
char* trx_state = gwbuf_get_property(data, (char*)"trx_state");
|
||||
if (trx_state)
|
||||
{
|
||||
mysql_tx_state_t s = parse_trx_state(trx_state);
|
||||
@ -2103,12 +2128,12 @@ static void parse_and_set_trx_state(MXS_SESSION *ses, GWBUF *data)
|
||||
{
|
||||
session_set_trx_state(ses, SESSION_TRX_INACTIVE);
|
||||
}
|
||||
else if ((s & TX_EXPLICIT) || (s & TX_IMPLICIT))
|
||||
else if ((s & TX_EXPLICIT) || (s & TX_IMPLICIT))
|
||||
{
|
||||
session_set_trx_state(ses, SESSION_TRX_ACTIVE);
|
||||
}
|
||||
}
|
||||
char *trx_characteristics = gwbuf_get_property(data, (char *)"trx_characteristics");
|
||||
char* trx_characteristics = gwbuf_get_property(data, (char*)"trx_characteristics");
|
||||
if (trx_characteristics)
|
||||
{
|
||||
if (strncmp(trx_characteristics, "START TRANSACTION READ ONLY;", 28) == 0)
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
#include <vector>
|
||||
@ -23,10 +23,10 @@ class SetParser : public maxscale::CustomParser
|
||||
public:
|
||||
enum status_t
|
||||
{
|
||||
ERROR, // Some fatal error occurred; mem alloc failed, parsing failed, etc.
|
||||
IS_SET_SQL_MODE, // The COM_QUERY is "set [GLOBAL|SESSION] sql_mode=..."
|
||||
IS_SET_MAXSCALE, // The COM_QUERY is "set @MAXSCALE..."
|
||||
NOT_RELEVANT // Neither of the above.
|
||||
ERROR, // Some fatal error occurred; mem alloc failed, parsing failed, etc.
|
||||
IS_SET_SQL_MODE,// The COM_QUERY is "set [GLOBAL|SESSION] sql_mode=..."
|
||||
IS_SET_MAXSCALE,// The COM_QUERY is "set @MAXSCALE..."
|
||||
NOT_RELEVANT // Neither of the above.
|
||||
};
|
||||
|
||||
enum
|
||||
@ -49,15 +49,22 @@ public:
|
||||
{
|
||||
public:
|
||||
typedef std::pair<const char*, const char*> Item;
|
||||
typedef std::vector<Item> Items;
|
||||
typedef std::vector<Item> Items;
|
||||
|
||||
Result()
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
const Items& variables() const { return m_variables; }
|
||||
const Items& values() const { return m_values; }
|
||||
const Items& variables() const
|
||||
{
|
||||
return m_variables;
|
||||
}
|
||||
const Items& values() const
|
||||
{
|
||||
return m_values;
|
||||
}
|
||||
|
||||
void add_variable(const char *begin, const char* end)
|
||||
void add_variable(const char* begin, const char* end)
|
||||
{
|
||||
m_variables.push_back(Item(begin, end));
|
||||
}
|
||||
@ -226,10 +233,9 @@ public:
|
||||
private:
|
||||
static bool is_set(const char* pStmt)
|
||||
{
|
||||
return
|
||||
(pStmt[0] == 's' || pStmt[0] == 'S') &&
|
||||
(pStmt[1] == 'e' || pStmt[1] == 'E') &&
|
||||
(pStmt[2] == 't' || pStmt[2] == 'T');
|
||||
return (pStmt[0] == 's' || pStmt[0] == 'S')
|
||||
&& (pStmt[1] == 'e' || pStmt[1] == 'E')
|
||||
&& (pStmt[2] == 't' || pStmt[2] == 'T');
|
||||
}
|
||||
|
||||
static bool is_set(const uint8_t* pStmt)
|
||||
@ -239,7 +245,7 @@ private:
|
||||
|
||||
static bool is_error(status_t rv)
|
||||
{
|
||||
return (rv == ERROR);
|
||||
return rv == ERROR;
|
||||
}
|
||||
|
||||
status_t initialize(GWBUF* pBuffer)
|
||||
@ -271,8 +277,8 @@ private:
|
||||
|
||||
++m_pI;
|
||||
|
||||
while ((m_pI < m_pEnd) &&
|
||||
(is_alpha(*m_pI) || is_number(*m_pI) || (*m_pI == '.') || (*m_pI == '_')))
|
||||
while ((m_pI < m_pEnd)
|
||||
&& (is_alpha(*m_pI) || is_number(*m_pI) || (*m_pI == '.') || (*m_pI == '_')))
|
||||
{
|
||||
++m_pI;
|
||||
}
|
||||
@ -526,7 +532,8 @@ private:
|
||||
if (m_pI != m_pEnd)
|
||||
{
|
||||
MXS_WARNING("Non-space data found after semi-colon: '%.*s'.",
|
||||
(int)(m_pEnd - m_pI), m_pI);
|
||||
(int)(m_pEnd - m_pI),
|
||||
m_pI);
|
||||
}
|
||||
|
||||
token = PARSER_EXHAUSTED;
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
#include <maxscale/customparser.hh>
|
||||
@ -22,16 +22,16 @@ class SetSqlModeParser : public maxscale::CustomParser
|
||||
public:
|
||||
enum sql_mode_t
|
||||
{
|
||||
DEFAULT, // "set sql_mode=DEFAULT"
|
||||
ORACLE, // "set sql_mode=ORACLE", "set sql_mode='PIPES_AS_CONCAT,ORACLE', autocommit=false", etc.
|
||||
SOMETHING // "set sql_mode=PIPES_AS_CONCAT"
|
||||
DEFAULT, // "set sql_mode=DEFAULT"
|
||||
ORACLE, // "set sql_mode=ORACLE", "set sql_mode='PIPES_AS_CONCAT,ORACLE', autocommit=false", etc.
|
||||
SOMETHING // "set sql_mode=PIPES_AS_CONCAT"
|
||||
};
|
||||
|
||||
enum result_t
|
||||
{
|
||||
ERROR, // Some fatal error occurred; mem alloc failed, parsing failed, etc.
|
||||
IS_SET_SQL_MODE, // The COM_QUERY is "set sql_mode=..."
|
||||
NOT_SET_SQL_MODE // The COM_QUERY is NOT "set sql_mode=..."
|
||||
ERROR, // Some fatal error occurred; mem alloc failed, parsing failed, etc.
|
||||
IS_SET_SQL_MODE,// The COM_QUERY is "set sql_mode=..."
|
||||
NOT_SET_SQL_MODE// The COM_QUERY is NOT "set sql_mode=..."
|
||||
};
|
||||
|
||||
enum
|
||||
@ -95,7 +95,8 @@ public:
|
||||
payload_len = MYSQL_GET_PAYLOAD_LEN(header);
|
||||
}
|
||||
|
||||
if (payload_len >= 20) // sizeof(command byte) + strlen("SET sql_mode=ORACLE"), the minimum needed.
|
||||
if (payload_len >= 20) // sizeof(command byte) + strlen("SET sql_mode=ORACLE"), the minimum
|
||||
// needed.
|
||||
{
|
||||
// We need 4 bytes from the payload to deduce whether more investigations are needed.
|
||||
uint8_t payload[4];
|
||||
@ -157,7 +158,7 @@ public:
|
||||
bypass_whitespace();
|
||||
|
||||
// Check that there's enough characters to contain a SET keyword
|
||||
bool long_enough = m_pEnd - m_pI > 3 ;
|
||||
bool long_enough = m_pEnd - m_pI > 3;
|
||||
|
||||
if (long_enough && is_set(m_pI))
|
||||
{
|
||||
@ -230,10 +231,9 @@ public:
|
||||
private:
|
||||
static bool is_set(const char* pStmt)
|
||||
{
|
||||
return
|
||||
(pStmt[0] == 's' || pStmt[0] == 'S') &&
|
||||
(pStmt[1] == 'e' || pStmt[1] == 'E') &&
|
||||
(pStmt[2] == 't' || pStmt[2] == 'T');
|
||||
return (pStmt[0] == 's' || pStmt[0] == 'S')
|
||||
&& (pStmt[1] == 'e' || pStmt[1] == 'E')
|
||||
&& (pStmt[2] == 't' || pStmt[2] == 'T');
|
||||
}
|
||||
|
||||
static bool is_set(const uint8_t* pStmt)
|
||||
@ -243,7 +243,7 @@ private:
|
||||
|
||||
static bool is_error(result_t rv)
|
||||
{
|
||||
return (rv == ERROR);
|
||||
return rv == ERROR;
|
||||
}
|
||||
|
||||
result_t initialize(GWBUF* pBuffer)
|
||||
@ -566,7 +566,8 @@ private:
|
||||
if (m_pI != m_pEnd)
|
||||
{
|
||||
MXS_INFO("Non-space data found after semi-colon: '%.*s'.",
|
||||
(int)(m_pEnd - m_pI), m_pI);
|
||||
(int)(m_pEnd - m_pI),
|
||||
m_pI);
|
||||
}
|
||||
|
||||
token = PARSER_EXHAUSTED;
|
||||
|
@ -10,7 +10,7 @@
|
||||
* of this software will be governed by version 2 or later of the General
|
||||
* Public License.
|
||||
*/
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <maxscale/ccdefs.hh>
|
||||
#include <maxscale/customparser.hh>
|
||||
@ -22,9 +22,9 @@ class SqlModeParser : public maxscale::CustomParser
|
||||
public:
|
||||
enum sql_mode_t
|
||||
{
|
||||
DEFAULT, // "set sql_mode=DEFAULT"
|
||||
ORACLE, // "set sql_mode=ORACLE", "set sql_mode='PIPES_AS_CONCAT,ORACLE', autocommit=false", etc.
|
||||
SOMETHING // "set sql_mode=PIPES_AS_CONCAT"
|
||||
DEFAULT, // "set sql_mode=DEFAULT"
|
||||
ORACLE, // "set sql_mode=ORACLE", "set sql_mode='PIPES_AS_CONCAT,ORACLE', autocommit=false", etc.
|
||||
SOMETHING // "set sql_mode=PIPES_AS_CONCAT"
|
||||
};
|
||||
|
||||
enum
|
||||
@ -54,7 +54,7 @@ public:
|
||||
sql_mode_t sql_mode = SOMETHING;
|
||||
|
||||
m_pSql = pBegin;
|
||||
m_pI = m_pSql;
|
||||
m_pI = m_pSql;
|
||||
m_pEnd = pEnd;
|
||||
|
||||
return parse();
|
||||
@ -222,7 +222,8 @@ private:
|
||||
if (m_pI != m_pEnd)
|
||||
{
|
||||
MXS_WARNING("Non-space data found after semi-colon: '%.*s'.",
|
||||
(int)(m_pEnd - m_pI), m_pI);
|
||||
(int)(m_pEnd - m_pI),
|
||||
m_pI);
|
||||
}
|
||||
|
||||
token = PARSER_EXHAUSTED;
|
||||
|
@ -40,7 +40,6 @@ GWBUF* gwbuf_create_com_query(const char* zStmt)
|
||||
|
||||
return pBuf;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -67,7 +66,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"DEFAULT"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -78,7 +77,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"DEFAULT"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -89,7 +88,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"DEFAULT"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -100,8 +99,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"DEFAULT"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -112,8 +110,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"DEFAULT"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -124,8 +121,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"DEFAULT"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -136,20 +132,18 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"ORACLE"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
"SET SQL_MODE=BLAH", // So short that it cannot be DEFAULT|ORACLE
|
||||
"SET SQL_MODE=BLAH", // So short that it cannot be DEFAULT|ORACLE
|
||||
P::IS_SET_SQL_MODE,
|
||||
{
|
||||
{
|
||||
"SQL_MODE",
|
||||
"BLAH"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -160,8 +154,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"'BLAH'"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -172,7 +165,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"BLAHBLAH"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -183,7 +176,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"'ORACLE'"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -194,7 +187,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"'BLAH, A, B, ORACLE'"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -205,7 +198,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"'BLAH, A, B, XYZ_123'"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -216,7 +209,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"'A,B, ORACLE'"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -227,7 +220,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"ORACLE"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -238,7 +231,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"ORACLE"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -249,7 +242,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"ORACLE"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -260,7 +253,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"ORACLE"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -271,7 +264,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"ORACLE"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -282,7 +275,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"ORACLE"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -293,7 +286,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"ORACLE"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -304,7 +297,7 @@ struct TEST_CASE
|
||||
"SQL_MODE",
|
||||
"ORACLE"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -315,21 +308,21 @@ struct TEST_CASE
|
||||
"sql_mode",
|
||||
"ORACLE"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
"SET MAXSCALE=",
|
||||
P::NOT_RELEVANT,
|
||||
{
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
"SET MAXSCALE.CACHE.ENABLED=TRUE",
|
||||
P::NOT_RELEVANT,
|
||||
{
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -340,7 +333,7 @@ struct TEST_CASE
|
||||
"@MAXSCALE.CACHE.ENABLED",
|
||||
"TRUE"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -351,7 +344,7 @@ struct TEST_CASE
|
||||
"@MAXSCALE.CACHE.ENABLED",
|
||||
"TRUE"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -366,7 +359,7 @@ struct TEST_CASE
|
||||
"@maxscale.cache.enabled",
|
||||
"FALSE"
|
||||
},
|
||||
{ NULL, NULL }
|
||||
{NULL, NULL}
|
||||
}
|
||||
},
|
||||
};
|
||||
@ -404,13 +397,13 @@ int test(GWBUF** ppStmt, SetParser::status_t expected_status, const TEST_CASE::E
|
||||
{
|
||||
size_t l1 = variable.second - variable.first;
|
||||
|
||||
if ((l1 == strlen(expectation.zVariable)) &&
|
||||
(memcmp(variable.first, expectation.zVariable, l1) == 0))
|
||||
if ((l1 == strlen(expectation.zVariable))
|
||||
&& (memcmp(variable.first, expectation.zVariable, l1) == 0))
|
||||
{
|
||||
size_t l2 = value.second - value.first;
|
||||
|
||||
if ((l2 == strlen(expectation.zValue)) &&
|
||||
(memcmp(value.first, expectation.zValue, l2) == 0))
|
||||
if ((l2 == strlen(expectation.zValue))
|
||||
&& (memcmp(value.first, expectation.zValue, l2) == 0))
|
||||
{
|
||||
cout << "OK";
|
||||
}
|
||||
@ -530,7 +523,7 @@ int test_non_contiguous()
|
||||
|
||||
while (pTail)
|
||||
{
|
||||
size_t n = MYSQL_HEADER_LEN + rand() % 10; // Between 4 and 13 bytes long chunks.
|
||||
size_t n = MYSQL_HEADER_LEN + rand() % 10; // Between 4 and 13 bytes long chunks.
|
||||
|
||||
GWBUF* pHead = gwbuf_split(&pTail, n);
|
||||
|
||||
@ -584,7 +577,6 @@ int test()
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,7 +41,6 @@ GWBUF* gwbuf_create_com_query(const char* zStmt)
|
||||
|
||||
return pBuf;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -290,7 +289,7 @@ int test_non_contiguous()
|
||||
|
||||
while (pTail)
|
||||
{
|
||||
size_t n = MYSQL_HEADER_LEN + rand() % 10; // Between 4 and 13 bytes long chunks.
|
||||
size_t n = MYSQL_HEADER_LEN + rand() % 10; // Between 4 and 13 bytes long chunks.
|
||||
|
||||
GWBUF* pHead = gwbuf_split(&pTail, n);
|
||||
|
||||
@ -344,7 +343,6 @@ int test()
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -145,7 +145,6 @@ int test()
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -46,7 +46,7 @@ MySQLProtocol* mysql_protocol_init(DCB* dcb, int fd)
|
||||
{
|
||||
MySQLProtocol* p;
|
||||
|
||||
p = (MySQLProtocol *) MXS_CALLOC(1, sizeof(MySQLProtocol));
|
||||
p = (MySQLProtocol*) MXS_CALLOC(1, sizeof(MySQLProtocol));
|
||||
mxb_assert(p != NULL);
|
||||
|
||||
if (p == NULL)
|
||||
@ -74,7 +74,7 @@ return_p:
|
||||
bool mysql_protocol_done(DCB* dcb)
|
||||
{
|
||||
bool rval = false;
|
||||
MySQLProtocol* p = (MySQLProtocol *)dcb->protocol;
|
||||
MySQLProtocol* p = (MySQLProtocol*)dcb->protocol;
|
||||
|
||||
if (p->protocol_state == MYSQL_PROTOCOL_ACTIVE)
|
||||
{
|
||||
@ -86,24 +86,31 @@ bool mysql_protocol_done(DCB* dcb)
|
||||
return rval;
|
||||
}
|
||||
|
||||
const char* gw_mysql_protocol_state2string (int state)
|
||||
const char* gw_mysql_protocol_state2string(int state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case MXS_AUTH_STATE_INIT:
|
||||
return "Authentication initialized";
|
||||
|
||||
case MXS_AUTH_STATE_PENDING_CONNECT:
|
||||
return "Network connection pending";
|
||||
|
||||
case MXS_AUTH_STATE_CONNECTED:
|
||||
return "Network connection created";
|
||||
|
||||
case MXS_AUTH_STATE_MESSAGE_READ:
|
||||
return "Read server handshake";
|
||||
|
||||
case MXS_AUTH_STATE_RESPONSE_SENT:
|
||||
return "Response to handshake sent";
|
||||
|
||||
case MXS_AUTH_STATE_FAILED:
|
||||
return "Authentication failed";
|
||||
|
||||
case MXS_AUTH_STATE_COMPLETE:
|
||||
return "Authentication is complete.";
|
||||
|
||||
default:
|
||||
return "MySQL (unknown protocol state)";
|
||||
}
|
||||
@ -142,16 +149,16 @@ GWBUF* mysql_create_com_quit(GWBUF* bufparam,
|
||||
*data++ = 0x0;
|
||||
*data++ = 0x0;
|
||||
*data++ = packet_number;
|
||||
*data = 0x1;
|
||||
*data = 0x1;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
int mysql_send_com_quit(DCB* dcb,
|
||||
int packet_number,
|
||||
int mysql_send_com_quit(DCB* dcb,
|
||||
int packet_number,
|
||||
GWBUF* bufparam)
|
||||
{
|
||||
GWBUF *buf;
|
||||
GWBUF* buf;
|
||||
int nbytes = 0;
|
||||
|
||||
mxb_assert(packet_number <= 255);
|
||||
@ -179,8 +186,8 @@ int mysql_send_com_quit(DCB* dcb,
|
||||
}
|
||||
|
||||
|
||||
GWBUF* mysql_create_custom_error(int packet_number,
|
||||
int affected_rows,
|
||||
GWBUF* mysql_create_custom_error(int packet_number,
|
||||
int affected_rows,
|
||||
const char* msg)
|
||||
{
|
||||
uint8_t* outbuf = NULL;
|
||||
@ -199,7 +206,7 @@ GWBUF* mysql_create_custom_error(int packet_number,
|
||||
mysql_state = "HY000";
|
||||
|
||||
field_count = 0xff;
|
||||
gw_mysql_set_byte2(mysql_err, /* mysql_errno */ 2003);
|
||||
gw_mysql_set_byte2(mysql_err, /* mysql_errno */ 2003);
|
||||
mysql_statemsg[0] = '#';
|
||||
memcpy(mysql_statemsg + 1, mysql_state, 5);
|
||||
|
||||
@ -208,11 +215,11 @@ GWBUF* mysql_create_custom_error(int packet_number,
|
||||
mysql_error_msg = msg;
|
||||
}
|
||||
|
||||
mysql_payload_size =
|
||||
sizeof(field_count) +
|
||||
sizeof(mysql_err) +
|
||||
sizeof(mysql_statemsg) +
|
||||
strlen(mysql_error_msg);
|
||||
mysql_payload_size
|
||||
= sizeof(field_count)
|
||||
+ sizeof(mysql_err)
|
||||
+ sizeof(mysql_statemsg)
|
||||
+ strlen(mysql_error_msg);
|
||||
|
||||
/** allocate memory for packet header + payload */
|
||||
errbuf = gwbuf_alloc(sizeof(mysql_packet_header) + mysql_payload_size);
|
||||
@ -264,17 +271,16 @@ GWBUF* mysql_create_custom_error(int packet_number,
|
||||
* @param error_message Text message to be included
|
||||
* @return GWBUF A buffer containing the error message, ready to send
|
||||
*/
|
||||
GWBUF *
|
||||
mysql_create_standard_error(int packet_number,
|
||||
int error_number,
|
||||
const char *error_message)
|
||||
GWBUF* mysql_create_standard_error(int packet_number,
|
||||
int error_number,
|
||||
const char* error_message)
|
||||
{
|
||||
uint8_t *outbuf = NULL;
|
||||
uint8_t* outbuf = NULL;
|
||||
uint32_t mysql_payload_size = 0;
|
||||
uint8_t mysql_packet_header[4];
|
||||
uint8_t mysql_error_number[2];
|
||||
uint8_t *mysql_handshake_payload = NULL;
|
||||
GWBUF *buf;
|
||||
uint8_t* mysql_handshake_payload = NULL;
|
||||
GWBUF* buf;
|
||||
|
||||
mysql_payload_size = 1 + sizeof(mysql_error_number) + strlen(error_message);
|
||||
|
||||
@ -323,13 +329,12 @@ mysql_create_standard_error(int packet_number,
|
||||
* @param error_message Text message to be included
|
||||
* @return 0 on failure, 1 on success
|
||||
*/
|
||||
int
|
||||
mysql_send_standard_error(DCB *dcb,
|
||||
int packet_number,
|
||||
int error_number,
|
||||
const char *error_message)
|
||||
int mysql_send_standard_error(DCB* dcb,
|
||||
int packet_number,
|
||||
int error_number,
|
||||
const char* error_message)
|
||||
{
|
||||
GWBUF *buf;
|
||||
GWBUF* buf;
|
||||
buf = mysql_create_standard_error(packet_number, error_number, error_message);
|
||||
return buf ? dcb->func.write(dcb, buf) : 0;
|
||||
}
|
||||
@ -347,10 +352,10 @@ mysql_send_standard_error(DCB *dcb,
|
||||
* @return 1 Non-zero if data was sent
|
||||
*
|
||||
*/
|
||||
int mysql_send_custom_error(DCB *dcb,
|
||||
int packet_number,
|
||||
int in_affected_rows,
|
||||
const char *mysql_message)
|
||||
int mysql_send_custom_error(DCB* dcb,
|
||||
int packet_number,
|
||||
int in_affected_rows,
|
||||
const char* mysql_message)
|
||||
{
|
||||
GWBUF* buf;
|
||||
|
||||
@ -371,34 +376,35 @@ int mysql_send_custom_error(DCB *dcb,
|
||||
* @return packet length
|
||||
*
|
||||
*/
|
||||
int mysql_send_auth_error(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)
|
||||
{
|
||||
uint8_t *outbuf = NULL;
|
||||
uint8_t* outbuf = NULL;
|
||||
uint32_t mysql_payload_size = 0;
|
||||
uint8_t mysql_packet_header[4];
|
||||
uint8_t *mysql_payload = NULL;
|
||||
uint8_t* mysql_payload = NULL;
|
||||
uint8_t field_count = 0;
|
||||
uint8_t mysql_err[2];
|
||||
uint8_t mysql_statemsg[6];
|
||||
const char *mysql_error_msg = NULL;
|
||||
const char *mysql_state = NULL;
|
||||
const char* mysql_error_msg = NULL;
|
||||
const char* mysql_state = NULL;
|
||||
|
||||
GWBUF *buf;
|
||||
GWBUF* buf;
|
||||
|
||||
if (dcb->state != DCB_STATE_POLLING)
|
||||
{
|
||||
MXS_DEBUG("dcb %p is in a state %s, and it is not in epoll set anymore. Skip error sending.",
|
||||
dcb, STRDCBSTATE(dcb->state));
|
||||
dcb,
|
||||
STRDCBSTATE(dcb->state));
|
||||
return 0;
|
||||
}
|
||||
mysql_error_msg = "Access denied!";
|
||||
mysql_state = "28000";
|
||||
|
||||
field_count = 0xff;
|
||||
gw_mysql_set_byte2(mysql_err, /*mysql_errno */ 1045);
|
||||
gw_mysql_set_byte2(mysql_err, /*mysql_errno */ 1045);
|
||||
mysql_statemsg[0] = '#';
|
||||
memcpy(mysql_statemsg + 1, mysql_state, 5);
|
||||
|
||||
@ -407,8 +413,8 @@ int mysql_send_auth_error(DCB *dcb,
|
||||
mysql_error_msg = mysql_message;
|
||||
}
|
||||
|
||||
mysql_payload_size =
|
||||
sizeof(field_count) + sizeof(mysql_err) + sizeof(mysql_statemsg) + strlen(mysql_error_msg);
|
||||
mysql_payload_size
|
||||
= sizeof(field_count) + sizeof(mysql_err) + sizeof(mysql_statemsg) + strlen(mysql_error_msg);
|
||||
|
||||
// allocate memory for packet header + payload
|
||||
if ((buf = gwbuf_alloc(sizeof(mysql_packet_header) + mysql_payload_size)) == NULL)
|
||||
@ -447,16 +453,16 @@ int mysql_send_auth_error(DCB *dcb,
|
||||
return sizeof(mysql_packet_header) + mysql_payload_size;
|
||||
}
|
||||
|
||||
char* create_auth_failed_msg(GWBUF*readbuf,
|
||||
char* hostaddr,
|
||||
char* create_auth_failed_msg(GWBUF* readbuf,
|
||||
char* hostaddr,
|
||||
uint8_t* sha1)
|
||||
{
|
||||
char* errstr;
|
||||
char* uname = (char *)GWBUF_DATA(readbuf) + 5;
|
||||
char* uname = (char*)GWBUF_DATA(readbuf) + 5;
|
||||
const char* ferrstr = "Access denied for user '%s'@'%s' (using password: %s)";
|
||||
|
||||
/** -4 comes from 2X'%s' minus terminating char */
|
||||
errstr = (char *)MXS_MALLOC(strlen(uname) + strlen(ferrstr) + strlen(hostaddr) + strlen("YES") - 6 + 1);
|
||||
errstr = (char*)MXS_MALLOC(strlen(uname) + strlen(ferrstr) + strlen(hostaddr) + strlen("YES") - 6 + 1);
|
||||
|
||||
if (errstr != NULL)
|
||||
{
|
||||
@ -477,11 +483,11 @@ char* create_auth_failed_msg(GWBUF*readbuf,
|
||||
*
|
||||
* @return Pointer to the allocated string or NULL on failure
|
||||
*/
|
||||
char *create_auth_fail_str(char *username,
|
||||
char *hostaddr,
|
||||
bool password,
|
||||
char *db,
|
||||
int errcode)
|
||||
char* create_auth_fail_str(char* username,
|
||||
char* hostaddr,
|
||||
bool password,
|
||||
char* db,
|
||||
int errcode)
|
||||
{
|
||||
char* errstr;
|
||||
const char* ferrstr;
|
||||
@ -508,9 +514,9 @@ char *create_auth_fail_str(char *username,
|
||||
{
|
||||
ferrstr = "Access denied for user '%s'@'%s' (using password: %s)";
|
||||
}
|
||||
errstr = (char *)MXS_MALLOC(strlen(username) + strlen(ferrstr) +
|
||||
strlen(hostaddr) + strlen("YES") - 6 +
|
||||
db_len + ((db_len > 0) ? (strlen(" to database ") + 2) : 0) + 1);
|
||||
errstr = (char*)MXS_MALLOC(strlen(username) + strlen(ferrstr)
|
||||
+ strlen(hostaddr) + strlen("YES") - 6
|
||||
+ db_len + ((db_len > 0) ? (strlen(" to database ") + 2) : 0) + 1);
|
||||
|
||||
if (errstr == NULL)
|
||||
{
|
||||
@ -545,16 +551,16 @@ retblock:
|
||||
* @param readbuf Pointer to a buffer where the data is stored
|
||||
* @return True on success, false if an error occurred while data was being read
|
||||
*/
|
||||
bool read_complete_packet(DCB *dcb, GWBUF **readbuf)
|
||||
bool read_complete_packet(DCB* dcb, GWBUF** readbuf)
|
||||
{
|
||||
bool rval = false;
|
||||
GWBUF *localbuf = NULL;
|
||||
GWBUF* localbuf = NULL;
|
||||
|
||||
if (dcb_read(dcb, &localbuf, 0) >= 0)
|
||||
{
|
||||
rval = true;
|
||||
dcb->last_read = mxs_clock();
|
||||
GWBUF *packets = modutil_get_complete_packets(&localbuf);
|
||||
GWBUF* packets = modutil_get_complete_packets(&localbuf);
|
||||
|
||||
if (packets)
|
||||
{
|
||||
@ -590,8 +596,8 @@ bool gw_get_shared_session_auth_info(DCB* dcb, MYSQL_session* session)
|
||||
mxb_assert(dcb->data);
|
||||
memcpy(session, dcb->data, sizeof(MYSQL_session));
|
||||
}
|
||||
else if (dcb->session->state != SESSION_STATE_ALLOC &&
|
||||
dcb->session->state != SESSION_STATE_DUMMY)
|
||||
else if (dcb->session->state != SESSION_STATE_ALLOC
|
||||
&& dcb->session->state != SESSION_STATE_DUMMY)
|
||||
{
|
||||
memcpy(session, dcb->session->client_dcb->data, sizeof(MYSQL_session));
|
||||
}
|
||||
@ -617,25 +623,25 @@ bool gw_get_shared_session_auth_info(DCB* dcb, MYSQL_session* session)
|
||||
*
|
||||
* @todo Support more than 255 affected rows
|
||||
*/
|
||||
int mxs_mysql_send_ok(DCB *dcb, int sequence, uint8_t affected_rows, const char* message)
|
||||
int mxs_mysql_send_ok(DCB* dcb, int sequence, uint8_t affected_rows, const char* message)
|
||||
{
|
||||
uint8_t *outbuf = NULL;
|
||||
uint8_t* outbuf = NULL;
|
||||
uint32_t mysql_payload_size = 0;
|
||||
uint8_t mysql_packet_header[4];
|
||||
uint8_t *mysql_payload = NULL;
|
||||
uint8_t* mysql_payload = NULL;
|
||||
uint8_t field_count = 0;
|
||||
uint8_t insert_id = 0;
|
||||
uint8_t mysql_server_status[2];
|
||||
uint8_t mysql_warning_counter[2];
|
||||
GWBUF *buf;
|
||||
GWBUF* buf;
|
||||
|
||||
|
||||
mysql_payload_size =
|
||||
sizeof(field_count) +
|
||||
sizeof(affected_rows) +
|
||||
sizeof(insert_id) +
|
||||
sizeof(mysql_server_status) +
|
||||
sizeof(mysql_warning_counter);
|
||||
mysql_payload_size
|
||||
= sizeof(field_count)
|
||||
+ sizeof(affected_rows)
|
||||
+ sizeof(insert_id)
|
||||
+ sizeof(mysql_server_status)
|
||||
+ sizeof(mysql_warning_counter);
|
||||
|
||||
if (message != NULL)
|
||||
{
|
||||
@ -706,8 +712,12 @@ int mxs_mysql_send_ok(DCB *dcb, int sequence, uint8_t affected_rows, const char*
|
||||
*
|
||||
* @return The length of the response packet
|
||||
*/
|
||||
static int response_length(bool with_ssl, bool ssl_established, char *user, uint8_t *passwd,
|
||||
char *dbname, const char *auth_module)
|
||||
static int response_length(bool with_ssl,
|
||||
bool ssl_established,
|
||||
char* user,
|
||||
uint8_t* passwd,
|
||||
char* dbname,
|
||||
const char* auth_module)
|
||||
{
|
||||
long bytes;
|
||||
|
||||
@ -760,7 +770,7 @@ static int response_length(bool with_ssl, bool ssl_established, char *user, uint
|
||||
* @param passwd The SHA1(password) sent by the client
|
||||
* @param output Pointer where the resulting 20 byte hash is stored
|
||||
*/
|
||||
static void calculate_hash(uint8_t *scramble, uint8_t *passwd, uint8_t *output)
|
||||
static void calculate_hash(uint8_t* scramble, uint8_t* passwd, uint8_t* output)
|
||||
{
|
||||
uint8_t hash1[GW_MYSQL_SCRAMBLE_SIZE] = "";
|
||||
uint8_t hash2[GW_MYSQL_SCRAMBLE_SIZE] = "";
|
||||
@ -788,8 +798,7 @@ static void calculate_hash(uint8_t *scramble, uint8_t *passwd, uint8_t *output)
|
||||
*
|
||||
* @return Address of the next byte after the end of the stored password
|
||||
*/
|
||||
static uint8_t *
|
||||
load_hashed_password(uint8_t *scramble, uint8_t *payload, uint8_t *passwd)
|
||||
static uint8_t* load_hashed_password(uint8_t* scramble, uint8_t* payload, uint8_t* passwd)
|
||||
{
|
||||
*payload++ = GW_MYSQL_SCRAMBLE_SIZE;
|
||||
calculate_hash(scramble, passwd, payload);
|
||||
@ -812,8 +821,10 @@ load_hashed_password(uint8_t *scramble, uint8_t *payload, uint8_t *passwd)
|
||||
* @return Bit mask (32 bits)
|
||||
* @note Capability bits are defined in maxscale/protocol/mysql.h
|
||||
*/
|
||||
static uint32_t
|
||||
create_capabilities(MySQLProtocol *conn, bool with_ssl, bool db_specified, uint64_t capabilities)
|
||||
static uint32_t create_capabilities(MySQLProtocol* conn,
|
||||
bool with_ssl,
|
||||
bool db_specified,
|
||||
uint64_t capabilities)
|
||||
{
|
||||
uint32_t final_capabilities;
|
||||
|
||||
@ -823,9 +834,11 @@ create_capabilities(MySQLProtocol *conn, bool with_ssl, bool db_specified, uint6
|
||||
if (with_ssl)
|
||||
{
|
||||
final_capabilities |= (uint32_t)GW_MYSQL_CAPABILITIES_SSL;
|
||||
/* Unclear whether we should include this */
|
||||
/* Maybe it should depend on whether CA certificate is provided */
|
||||
/* final_capabilities |= (uint32_t)GW_MYSQL_CAPABILITIES_SSL_VERIFY_SERVER_CERT; */
|
||||
/*
|
||||
* Unclear whether we should include this
|
||||
* Maybe it should depend on whether CA certificate is provided
|
||||
* final_capabilities |= (uint32_t)GW_MYSQL_CAPABILITIES_SSL_VERIFY_SERVER_CERT;
|
||||
*/
|
||||
}
|
||||
|
||||
if (rcap_type_required(capabilities, RCAP_TYPE_SESSION_STATE_TRACKING))
|
||||
@ -853,12 +866,14 @@ create_capabilities(MySQLProtocol *conn, bool with_ssl, bool db_specified, uint6
|
||||
return final_capabilities;
|
||||
}
|
||||
|
||||
GWBUF* gw_generate_auth_response(MYSQL_session* client, MySQLProtocol *conn,
|
||||
bool with_ssl, bool ssl_established,
|
||||
GWBUF* gw_generate_auth_response(MYSQL_session* client,
|
||||
MySQLProtocol* conn,
|
||||
bool with_ssl,
|
||||
bool ssl_established,
|
||||
uint64_t service_capabilities)
|
||||
{
|
||||
uint8_t client_capabilities[4] = {0, 0, 0, 0};
|
||||
uint8_t *curr_passwd = NULL;
|
||||
uint8_t* curr_passwd = NULL;
|
||||
|
||||
if (memcmp(client->client_sha1, null_client_sha1, MYSQL_SCRAMBLE_LEN) != 0)
|
||||
{
|
||||
@ -875,12 +890,16 @@ GWBUF* gw_generate_auth_response(MYSQL_session* client, MySQLProtocol *conn,
|
||||
*/
|
||||
const char* auth_plugin_name = DEFAULT_MYSQL_AUTH_PLUGIN;
|
||||
|
||||
long bytes = response_length(with_ssl, ssl_established, client->user,
|
||||
curr_passwd, client->db, auth_plugin_name);
|
||||
long bytes = response_length(with_ssl,
|
||||
ssl_established,
|
||||
client->user,
|
||||
curr_passwd,
|
||||
client->db,
|
||||
auth_plugin_name);
|
||||
|
||||
// allocating the GWBUF
|
||||
GWBUF *buffer = gwbuf_alloc(bytes);
|
||||
uint8_t *payload = GWBUF_DATA(buffer);
|
||||
GWBUF* buffer = gwbuf_alloc(bytes);
|
||||
uint8_t* payload = GWBUF_DATA(buffer);
|
||||
|
||||
// clearing data
|
||||
memset(payload, '\0', bytes);
|
||||
@ -937,7 +956,6 @@ GWBUF* gw_generate_auth_response(MYSQL_session* client, MySQLProtocol *conn,
|
||||
}
|
||||
|
||||
memcpy(payload, auth_plugin_name, strlen(auth_plugin_name));
|
||||
|
||||
}
|
||||
|
||||
return buffer;
|
||||
@ -949,15 +967,15 @@ GWBUF* gw_generate_auth_response(MYSQL_session* client, MySQLProtocol *conn,
|
||||
* @param dcb Backend DCB
|
||||
* @return Authentication state after sending handshake response
|
||||
*/
|
||||
mxs_auth_state_t gw_send_backend_auth(DCB *dcb)
|
||||
mxs_auth_state_t gw_send_backend_auth(DCB* dcb)
|
||||
{
|
||||
mxs_auth_state_t rval = MXS_AUTH_STATE_FAILED;
|
||||
|
||||
if (dcb->session == NULL ||
|
||||
(dcb->session->state != SESSION_STATE_READY &&
|
||||
dcb->session->state != SESSION_STATE_ROUTER_READY) ||
|
||||
(dcb->server->server_ssl &&
|
||||
dcb->ssl_state == SSL_HANDSHAKE_FAILED))
|
||||
if (dcb->session == NULL
|
||||
|| (dcb->session->state != SESSION_STATE_READY
|
||||
&& dcb->session->state != SESSION_STATE_ROUTER_READY)
|
||||
|| (dcb->server->server_ssl
|
||||
&& dcb->ssl_state == SSL_HANDSHAKE_FAILED))
|
||||
{
|
||||
return rval;
|
||||
}
|
||||
@ -968,8 +986,10 @@ mxs_auth_state_t gw_send_backend_auth(DCB *dcb)
|
||||
MYSQL_session client;
|
||||
gw_get_shared_session_auth_info(dcb->session->client_dcb, &client);
|
||||
|
||||
GWBUF* buffer = gw_generate_auth_response(&client, (MySQLProtocol*)dcb->protocol,
|
||||
with_ssl, ssl_established,
|
||||
GWBUF* buffer = gw_generate_auth_response(&client,
|
||||
(MySQLProtocol*)dcb->protocol,
|
||||
with_ssl,
|
||||
ssl_established,
|
||||
dcb->service->capabilities);
|
||||
mxb_assert(buffer);
|
||||
|
||||
@ -994,13 +1014,13 @@ int send_mysql_native_password_response(DCB* dcb)
|
||||
MYSQL_session local_session;
|
||||
gw_get_shared_session_auth_info(dcb, &local_session);
|
||||
|
||||
uint8_t *curr_passwd = memcmp(local_session.client_sha1, null_client_sha1, MYSQL_SCRAMBLE_LEN) ?
|
||||
local_session.client_sha1 : null_client_sha1;
|
||||
uint8_t* curr_passwd = memcmp(local_session.client_sha1, null_client_sha1, MYSQL_SCRAMBLE_LEN)
|
||||
? local_session.client_sha1 : null_client_sha1;
|
||||
|
||||
GWBUF* buffer = gwbuf_alloc(MYSQL_HEADER_LEN + GW_MYSQL_SCRAMBLE_SIZE);
|
||||
uint8_t* data = GWBUF_DATA(buffer);
|
||||
gw_mysql_set_byte3(data, GW_MYSQL_SCRAMBLE_SIZE);
|
||||
data[3] = 2; // This is the third packet after the COM_CHANGE_USER
|
||||
data[3] = 2; // This is the third packet after the COM_CHANGE_USER
|
||||
calculate_hash(proto->scramble, curr_passwd, data + MYSQL_HEADER_LEN);
|
||||
|
||||
return dcb_write(dcb, buffer);
|
||||
@ -1015,7 +1035,7 @@ bool send_auth_switch_request_packet(DCB* dcb)
|
||||
|
||||
uint8_t* data = GWBUF_DATA(buffer);
|
||||
gw_mysql_set_byte3(data, len);
|
||||
data[3] = 1; // First response to the COM_CHANGE_USER
|
||||
data[3] = 1; // First response to the COM_CHANGE_USER
|
||||
data[MYSQL_HEADER_LEN] = MYSQL_REPLY_AUTHSWITCHREQUEST;
|
||||
memcpy(data + MYSQL_HEADER_LEN + 1, plugin, sizeof(plugin));
|
||||
memcpy(data + MYSQL_HEADER_LEN + 1 + sizeof(plugin), proto->scramble, GW_MYSQL_SCRAMBLE_SIZE);
|
||||
@ -1031,9 +1051,9 @@ bool send_auth_switch_request_packet(DCB* dcb)
|
||||
* @return 0 on success, < 0 on failure
|
||||
*
|
||||
*/
|
||||
int gw_decode_mysql_server_handshake(MySQLProtocol *conn, uint8_t *payload)
|
||||
int gw_decode_mysql_server_handshake(MySQLProtocol* conn, uint8_t* payload)
|
||||
{
|
||||
uint8_t *server_version_end = NULL;
|
||||
uint8_t* server_version_end = NULL;
|
||||
uint16_t mysql_server_capabilities_one = 0;
|
||||
uint16_t mysql_server_capabilities_two = 0;
|
||||
uint8_t scramble_data_1[GW_SCRAMBLE_LENGTH_323] = "";
|
||||
@ -1053,7 +1073,7 @@ int gw_decode_mysql_server_handshake(MySQLProtocol *conn, uint8_t *payload)
|
||||
payload++;
|
||||
|
||||
// Get server version (string)
|
||||
server_version_end = (uint8_t *) gw_strend((char*) payload);
|
||||
server_version_end = (uint8_t*) gw_strend((char*) payload);
|
||||
|
||||
payload = server_version_end + 1;
|
||||
|
||||
@ -1074,7 +1094,7 @@ int gw_decode_mysql_server_handshake(MySQLProtocol *conn, uint8_t *payload)
|
||||
|
||||
mysql_server_capabilities_one = gw_mysql_get_byte2(payload);
|
||||
|
||||
//Get capabilities_part 1 (2 bytes) + 1 language + 2 server_status
|
||||
// Get capabilities_part 1 (2 bytes) + 1 language + 2 server_status
|
||||
payload += 5;
|
||||
|
||||
mysql_server_capabilities_two = gw_mysql_get_byte2(payload);
|
||||
@ -1091,8 +1111,8 @@ int gw_decode_mysql_server_handshake(MySQLProtocol *conn, uint8_t *payload)
|
||||
mxb_assert(scramble_len > GW_SCRAMBLE_LENGTH_323);
|
||||
mxb_assert(scramble_len <= GW_MYSQL_SCRAMBLE_SIZE);
|
||||
|
||||
if ((scramble_len < GW_SCRAMBLE_LENGTH_323) ||
|
||||
scramble_len > GW_MYSQL_SCRAMBLE_SIZE)
|
||||
if ((scramble_len < GW_SCRAMBLE_LENGTH_323)
|
||||
|| scramble_len > GW_MYSQL_SCRAMBLE_SIZE)
|
||||
{
|
||||
/* log this */
|
||||
return -2;
|
||||
@ -1123,11 +1143,11 @@ int gw_decode_mysql_server_handshake(MySQLProtocol *conn, uint8_t *payload)
|
||||
* @param dcb Backend DCB
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
bool gw_read_backend_handshake(DCB *dcb, GWBUF *buffer)
|
||||
bool gw_read_backend_handshake(DCB* dcb, GWBUF* buffer)
|
||||
{
|
||||
MySQLProtocol *proto = (MySQLProtocol *)dcb->protocol;
|
||||
MySQLProtocol* proto = (MySQLProtocol*)dcb->protocol;
|
||||
bool rval = false;
|
||||
uint8_t *payload = GWBUF_DATA(buffer) + 4;
|
||||
uint8_t* payload = GWBUF_DATA(buffer) + 4;
|
||||
|
||||
if (gw_decode_mysql_server_handshake(proto, payload) >= 0)
|
||||
{
|
||||
@ -1137,21 +1157,21 @@ bool gw_read_backend_handshake(DCB *dcb, GWBUF *buffer)
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool mxs_mysql_is_ok_packet(GWBUF *buffer)
|
||||
bool mxs_mysql_is_ok_packet(GWBUF* buffer)
|
||||
{
|
||||
uint8_t cmd = 0xff; // Default should differ from the OK packet
|
||||
uint8_t cmd = 0xff; // Default should differ from the OK packet
|
||||
gwbuf_copy_data(buffer, MYSQL_HEADER_LEN, 1, &cmd);
|
||||
return cmd == MYSQL_REPLY_OK;
|
||||
}
|
||||
|
||||
bool mxs_mysql_is_err_packet(GWBUF *buffer)
|
||||
bool mxs_mysql_is_err_packet(GWBUF* buffer)
|
||||
{
|
||||
uint8_t cmd = 0x00; // Default should differ from the ERR packet
|
||||
uint8_t cmd = 0x00; // Default should differ from the ERR packet
|
||||
gwbuf_copy_data(buffer, MYSQL_HEADER_LEN, 1, &cmd);
|
||||
return cmd == MYSQL_REPLY_ERR;
|
||||
}
|
||||
|
||||
bool mxs_mysql_is_result_set(GWBUF *buffer)
|
||||
bool mxs_mysql_is_result_set(GWBUF* buffer)
|
||||
{
|
||||
bool rval = false;
|
||||
uint8_t cmd;
|
||||
@ -1177,20 +1197,20 @@ bool mxs_mysql_is_result_set(GWBUF *buffer)
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool mxs_mysql_is_local_infile(GWBUF *buffer)
|
||||
bool mxs_mysql_is_local_infile(GWBUF* buffer)
|
||||
{
|
||||
uint8_t cmd = 0xff; // Default should differ from the OK packet
|
||||
uint8_t cmd = 0xff; // Default should differ from the OK packet
|
||||
gwbuf_copy_data(buffer, MYSQL_HEADER_LEN, 1, &cmd);
|
||||
return cmd == MYSQL_REPLY_LOCAL_INFILE;
|
||||
}
|
||||
|
||||
bool mxs_mysql_is_prep_stmt_ok(GWBUF *buffer)
|
||||
bool mxs_mysql_is_prep_stmt_ok(GWBUF* buffer)
|
||||
{
|
||||
bool rval = false;
|
||||
uint8_t cmd;
|
||||
|
||||
if (gwbuf_copy_data(buffer, MYSQL_HEADER_LEN, 1, &cmd) &&
|
||||
cmd == MYSQL_REPLY_OK)
|
||||
if (gwbuf_copy_data(buffer, MYSQL_HEADER_LEN, 1, &cmd)
|
||||
&& cmd == MYSQL_REPLY_OK)
|
||||
{
|
||||
rval = true;
|
||||
}
|
||||
@ -1200,15 +1220,15 @@ bool mxs_mysql_is_prep_stmt_ok(GWBUF *buffer)
|
||||
|
||||
bool mxs_mysql_is_ps_command(uint8_t cmd)
|
||||
{
|
||||
return cmd == MXS_COM_STMT_EXECUTE ||
|
||||
cmd == MXS_COM_STMT_BULK_EXECUTE ||
|
||||
cmd == MXS_COM_STMT_SEND_LONG_DATA ||
|
||||
cmd == MXS_COM_STMT_CLOSE ||
|
||||
cmd == MXS_COM_STMT_FETCH ||
|
||||
cmd == MXS_COM_STMT_RESET;
|
||||
return cmd == MXS_COM_STMT_EXECUTE
|
||||
|| cmd == MXS_COM_STMT_BULK_EXECUTE
|
||||
|| cmd == MXS_COM_STMT_SEND_LONG_DATA
|
||||
|| cmd == MXS_COM_STMT_CLOSE
|
||||
|| cmd == MXS_COM_STMT_FETCH
|
||||
|| cmd == MXS_COM_STMT_RESET;
|
||||
}
|
||||
|
||||
bool mxs_mysql_more_results_after_ok(GWBUF *buffer)
|
||||
bool mxs_mysql_more_results_after_ok(GWBUF* buffer)
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
@ -1259,10 +1279,10 @@ bool mxs_mysql_extract_ps_response(GWBUF* buffer, MXS_PS_RESPONSE* out)
|
||||
uint8_t params[MYSQL_PS_ID_SIZE];
|
||||
uint8_t warnings[MYSQL_PS_WARN_SIZE];
|
||||
|
||||
if (gwbuf_copy_data(buffer, MYSQL_PS_ID_OFFSET, sizeof(id), id) == sizeof(id) &&
|
||||
gwbuf_copy_data(buffer, MYSQL_PS_COLS_OFFSET, sizeof(cols), cols) == sizeof(cols) &&
|
||||
gwbuf_copy_data(buffer, MYSQL_PS_PARAMS_OFFSET, sizeof(params), params) == sizeof(params) &&
|
||||
gwbuf_copy_data(buffer, MYSQL_PS_WARN_OFFSET, sizeof(warnings), warnings) == sizeof(warnings))
|
||||
if (gwbuf_copy_data(buffer, MYSQL_PS_ID_OFFSET, sizeof(id), id) == sizeof(id)
|
||||
&& gwbuf_copy_data(buffer, MYSQL_PS_COLS_OFFSET, sizeof(cols), cols) == sizeof(cols)
|
||||
&& gwbuf_copy_data(buffer, MYSQL_PS_PARAMS_OFFSET, sizeof(params), params) == sizeof(params)
|
||||
&& gwbuf_copy_data(buffer, MYSQL_PS_WARN_OFFSET, sizeof(warnings), warnings) == sizeof(warnings))
|
||||
{
|
||||
out->id = gw_mysql_get_byte4(id);
|
||||
out->columns = gw_mysql_get_byte2(cols);
|
||||
@ -1289,9 +1309,9 @@ uint32_t mxs_mysql_extract_ps_id(GWBUF* buffer)
|
||||
|
||||
bool mxs_mysql_command_will_respond(uint8_t cmd)
|
||||
{
|
||||
return cmd != MXS_COM_STMT_SEND_LONG_DATA &&
|
||||
cmd != MXS_COM_QUIT &&
|
||||
cmd != MXS_COM_STMT_CLOSE;
|
||||
return cmd != MXS_COM_STMT_SEND_LONG_DATA
|
||||
&& cmd != MXS_COM_QUIT
|
||||
&& cmd != MXS_COM_STMT_CLOSE;
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -1302,50 +1322,52 @@ typedef std::map<SERVER*, std::string> TargetList;
|
||||
|
||||
struct KillInfo
|
||||
{
|
||||
typedef bool (*DcbCallback)(DCB *dcb, void *data);
|
||||
typedef bool (* DcbCallback)(DCB* dcb, void* data);
|
||||
|
||||
KillInfo(std::string query, MXS_SESSION* ses, DcbCallback callback):
|
||||
origin(mxs_rworker_get_current_id()),
|
||||
query_base(query),
|
||||
protocol(*(MySQLProtocol*)ses->client_dcb->protocol),
|
||||
cb(callback)
|
||||
KillInfo(std::string query, MXS_SESSION* ses, DcbCallback callback)
|
||||
: origin(mxs_rworker_get_current_id())
|
||||
, query_base(query)
|
||||
, protocol(*(MySQLProtocol*)ses->client_dcb->protocol)
|
||||
, cb(callback)
|
||||
{
|
||||
gw_get_shared_session_auth_info(ses->client_dcb, &session);
|
||||
}
|
||||
|
||||
int origin;
|
||||
std::string query_base;
|
||||
int origin;
|
||||
std::string query_base;
|
||||
MYSQL_session session;
|
||||
MySQLProtocol protocol;
|
||||
DcbCallback cb;
|
||||
TargetList targets;
|
||||
DcbCallback cb;
|
||||
TargetList targets;
|
||||
};
|
||||
|
||||
static bool kill_func(DCB *dcb, void *data);
|
||||
static bool kill_func(DCB* dcb, void* data);
|
||||
|
||||
struct ConnKillInfo: public KillInfo
|
||||
struct ConnKillInfo : public KillInfo
|
||||
{
|
||||
ConnKillInfo(uint64_t id, std::string query, MXS_SESSION* ses):
|
||||
KillInfo(query, ses, kill_func),
|
||||
target_id(id)
|
||||
{}
|
||||
ConnKillInfo(uint64_t id, std::string query, MXS_SESSION* ses)
|
||||
: KillInfo(query, ses, kill_func)
|
||||
, target_id(id)
|
||||
{
|
||||
}
|
||||
|
||||
uint64_t target_id;
|
||||
};
|
||||
|
||||
static bool kill_user_func(DCB *dcb, void *data);
|
||||
static bool kill_user_func(DCB* dcb, void* data);
|
||||
|
||||
struct UserKillInfo: public KillInfo
|
||||
struct UserKillInfo : public KillInfo
|
||||
{
|
||||
UserKillInfo(std::string name, std::string query, MXS_SESSION* ses):
|
||||
KillInfo(query, ses, kill_user_func),
|
||||
user(name)
|
||||
{}
|
||||
UserKillInfo(std::string name, std::string query, MXS_SESSION* ses)
|
||||
: KillInfo(query, ses, kill_user_func)
|
||||
, user(name)
|
||||
{
|
||||
}
|
||||
|
||||
std::string user;
|
||||
};
|
||||
|
||||
static bool kill_func(DCB *dcb, void *data)
|
||||
static bool kill_func(DCB* dcb, void* data)
|
||||
{
|
||||
ConnKillInfo* info = static_cast<ConnKillInfo*>(data);
|
||||
|
||||
@ -1371,14 +1393,14 @@ static bool kill_func(DCB *dcb, void *data)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool kill_user_func(DCB *dcb, void *data)
|
||||
static bool kill_user_func(DCB* dcb, void* data)
|
||||
{
|
||||
UserKillInfo* info = (UserKillInfo*)data;
|
||||
|
||||
if (dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER &&
|
||||
strcasecmp(dcb->session->client_dcb->user, info->user.c_str()) == 0)
|
||||
if (dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER
|
||||
&& strcasecmp(dcb->session->client_dcb->user, info->user.c_str()) == 0)
|
||||
{
|
||||
info->targets[dcb->server] = info->query_base;
|
||||
info->targets[dcb->server] = info->query_base;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1403,7 +1425,6 @@ static void worker_func(int thread_id, void* data)
|
||||
|
||||
delete info;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void mxs_mysql_execute_kill(MXS_SESSION* issuer, uint64_t target_id, kill_type_t type)
|
||||
@ -1417,8 +1438,10 @@ void mxs_mysql_execute_kill(MXS_SESSION* issuer, uint64_t target_id, kill_type_t
|
||||
{
|
||||
MXB_WORKER* worker = mxs_rworker_get(i);
|
||||
mxb_assert(worker);
|
||||
mxb_worker_post_message(worker, MXB_WORKER_MSG_CALL, (intptr_t)worker_func,
|
||||
(intptr_t)new ConnKillInfo(target_id, ss.str(), issuer));
|
||||
mxb_worker_post_message(worker,
|
||||
MXB_WORKER_MSG_CALL,
|
||||
(intptr_t)worker_func,
|
||||
(intptr_t) new ConnKillInfo(target_id, ss.str(), issuer));
|
||||
}
|
||||
|
||||
mxs_mysql_send_ok(issuer->client_dcb, 1, 0, NULL);
|
||||
@ -1435,8 +1458,10 @@ void mxs_mysql_execute_kill_user(MXS_SESSION* issuer, const char* user, kill_typ
|
||||
{
|
||||
MXB_WORKER* worker = mxs_rworker_get(i);
|
||||
mxb_assert(worker);
|
||||
mxb_worker_post_message(worker, MXB_WORKER_MSG_CALL, (intptr_t)worker_func,
|
||||
(intptr_t)new UserKillInfo(user, ss.str(), issuer));
|
||||
mxb_worker_post_message(worker,
|
||||
MXB_WORKER_MSG_CALL,
|
||||
(intptr_t)worker_func,
|
||||
(intptr_t) new UserKillInfo(user, ss.str(), issuer));
|
||||
}
|
||||
|
||||
mxs_mysql_send_ok(issuer->client_dcb, 1, 0, NULL);
|
||||
@ -1448,59 +1473,64 @@ void mxs_mysql_execute_kill_user(MXS_SESSION* issuer, const char* user, kill_typ
|
||||
* @param packet_offset Ok packet offset in this buff
|
||||
* @param packet_len Ok packet lengh
|
||||
*/
|
||||
void mxs_mysql_parse_ok_packet(GWBUF *buff, size_t packet_offset, size_t packet_len)
|
||||
void mxs_mysql_parse_ok_packet(GWBUF* buff, size_t packet_offset, size_t packet_len)
|
||||
{
|
||||
uint8_t local_buf[packet_len];
|
||||
uint8_t *ptr = local_buf;
|
||||
char *trx_info, *var_name, *var_value;
|
||||
uint8_t* ptr = local_buf;
|
||||
char* trx_info, * var_name, * var_value;
|
||||
|
||||
gwbuf_copy_data(buff, packet_offset, packet_len, local_buf);
|
||||
ptr += (MYSQL_HEADER_LEN + 1); // Header and Command type
|
||||
mxs_leint_consume(&ptr); // Affected rows
|
||||
mxs_leint_consume(&ptr); // Last insert-id
|
||||
ptr += (MYSQL_HEADER_LEN + 1); // Header and Command type
|
||||
mxs_leint_consume(&ptr); // Affected rows
|
||||
mxs_leint_consume(&ptr); // Last insert-id
|
||||
uint16_t server_status = gw_mysql_get_byte2(ptr);
|
||||
ptr += 2; // status
|
||||
ptr += 2; // number of warnings
|
||||
ptr += 2; // status
|
||||
ptr += 2; // number of warnings
|
||||
|
||||
if (ptr < (local_buf + packet_len))
|
||||
{
|
||||
size_t size;
|
||||
mxs_lestr_consume(&ptr, &size); // info
|
||||
mxs_lestr_consume(&ptr, &size); // info
|
||||
|
||||
if (server_status & SERVER_SESSION_STATE_CHANGED)
|
||||
if (server_status & SERVER_SESSION_STATE_CHANGED)
|
||||
{
|
||||
MXB_AT_DEBUG(uint64_t data_size = )mxs_leint_consume(&ptr); // total SERVER_SESSION_STATE_CHANGED length
|
||||
MXB_AT_DEBUG(uint64_t data_size = ) mxs_leint_consume(&ptr); // total
|
||||
// SERVER_SESSION_STATE_CHANGED
|
||||
// length
|
||||
mxb_assert(data_size == packet_len - (ptr - local_buf));
|
||||
|
||||
while (ptr < (local_buf + packet_len))
|
||||
{
|
||||
enum_session_state_type type =
|
||||
(enum enum_session_state_type)mxs_leint_consume(&ptr);
|
||||
#if defined(SS_DEBUG)
|
||||
enum_session_state_type type
|
||||
= (enum enum_session_state_type)mxs_leint_consume(&ptr);
|
||||
#if defined (SS_DEBUG)
|
||||
mxb_assert(type <= SESSION_TRACK_TRANSACTION_TYPE);
|
||||
#endif
|
||||
switch (type)
|
||||
{
|
||||
case SESSION_TRACK_STATE_CHANGE:
|
||||
case SESSION_TRACK_SCHEMA:
|
||||
size = mxs_leint_consume(&ptr); // Length of the overall entity.
|
||||
size = mxs_leint_consume(&ptr); // Length of the overall entity.
|
||||
ptr += size;
|
||||
break;
|
||||
|
||||
case SESSION_TRACK_GTIDS:
|
||||
mxs_leint_consume(&ptr); // Length of the overall entity.
|
||||
mxs_leint_consume(&ptr); // encoding specification
|
||||
mxs_leint_consume(&ptr); // Length of the overall entity.
|
||||
mxs_leint_consume(&ptr); // encoding specification
|
||||
var_value = mxs_lestr_consume_dup(&ptr);
|
||||
gwbuf_add_property(buff, MXS_LAST_GTID, var_value);
|
||||
MXS_FREE(var_value);
|
||||
break;
|
||||
|
||||
case SESSION_TRACK_TRANSACTION_CHARACTERISTICS:
|
||||
mxs_leint_consume(&ptr); //length
|
||||
mxs_leint_consume(&ptr); // length
|
||||
var_value = mxs_lestr_consume_dup(&ptr);
|
||||
gwbuf_add_property(buff, "trx_characteristics", var_value);
|
||||
MXS_FREE(var_value);
|
||||
break;
|
||||
|
||||
case SESSION_TRACK_SYSTEM_VARIABLES:
|
||||
mxs_leint_consume(&ptr); //lenth
|
||||
mxs_leint_consume(&ptr); // lenth
|
||||
// system variables like autocommit, schema, charset ...
|
||||
var_name = mxs_lestr_consume_dup(&ptr);
|
||||
var_value = mxs_lestr_consume_dup(&ptr);
|
||||
@ -1509,13 +1539,15 @@ void mxs_mysql_parse_ok_packet(GWBUF *buff, size_t packet_offset, size_t packet_
|
||||
MXS_FREE(var_name);
|
||||
MXS_FREE(var_value);
|
||||
break;
|
||||
|
||||
case SESSION_TRACK_TRANSACTION_TYPE:
|
||||
mxs_leint_consume(&ptr); // length
|
||||
mxs_leint_consume(&ptr); // length
|
||||
trx_info = mxs_lestr_consume_dup(&ptr);
|
||||
MXS_DEBUG("get trx_info:%s", trx_info);
|
||||
gwbuf_add_property(buff, (char *)"trx_state", trx_info);
|
||||
gwbuf_add_property(buff, (char*)"trx_state", trx_info);
|
||||
MXS_FREE(trx_info);
|
||||
break;
|
||||
|
||||
default:
|
||||
mxs_lestr_consume(&ptr, &size);
|
||||
MXS_WARNING("recieved unexpecting session track type:%d", type);
|
||||
@ -1531,29 +1563,32 @@ void mxs_mysql_parse_ok_packet(GWBUF *buff, size_t packet_offset, size_t packet_
|
||||
* @param buff Buffer contain multi compelte packets
|
||||
* @param server_capabilities Server capabilities
|
||||
*/
|
||||
void mxs_mysql_get_session_track_info(GWBUF *buff, MySQLProtocol *proto)
|
||||
void mxs_mysql_get_session_track_info(GWBUF* buff, MySQLProtocol* proto)
|
||||
{
|
||||
size_t offset = 0;
|
||||
uint8_t header_and_command[MYSQL_HEADER_LEN + 1];
|
||||
if (proto->server_capabilities & GW_MYSQL_CAPABILITIES_SESSION_TRACK)
|
||||
{
|
||||
while (gwbuf_copy_data(buff, offset, MYSQL_HEADER_LEN + 1, header_and_command) == (MYSQL_HEADER_LEN + 1))
|
||||
while (gwbuf_copy_data(buff,
|
||||
offset,
|
||||
MYSQL_HEADER_LEN + 1,
|
||||
header_and_command) == (MYSQL_HEADER_LEN + 1))
|
||||
{
|
||||
size_t packet_len = gw_mysql_get_byte3(header_and_command) + MYSQL_HEADER_LEN;
|
||||
uint8_t cmd = header_and_command[MYSQL_COM_OFFSET];
|
||||
|
||||
if (packet_len > MYSQL_OK_PACKET_MIN_LEN &&
|
||||
cmd == MYSQL_REPLY_OK &&
|
||||
(proto->num_eof_packets % 2) == 0)
|
||||
if (packet_len > MYSQL_OK_PACKET_MIN_LEN
|
||||
&& cmd == MYSQL_REPLY_OK
|
||||
&& (proto->num_eof_packets % 2) == 0)
|
||||
{
|
||||
buff->gwbuf_type |= GWBUF_TYPE_REPLY_OK;
|
||||
mxs_mysql_parse_ok_packet(buff, offset, packet_len);
|
||||
}
|
||||
|
||||
if ((proto->current_command == MXS_COM_QUERY ||
|
||||
proto->current_command == MXS_COM_STMT_FETCH ||
|
||||
proto->current_command == MXS_COM_STMT_EXECUTE) &&
|
||||
cmd == MYSQL_REPLY_EOF)
|
||||
if ((proto->current_command == MXS_COM_QUERY
|
||||
|| proto->current_command == MXS_COM_STMT_FETCH
|
||||
|| proto->current_command == MXS_COM_STMT_EXECUTE)
|
||||
&& cmd == MYSQL_REPLY_EOF)
|
||||
{
|
||||
proto->num_eof_packets++;
|
||||
}
|
||||
@ -1603,7 +1638,7 @@ void mxs_mysql_get_session_track_info(GWBUF *buff, MySQLProtocol *proto)
|
||||
* L tables were explicitly locked using LOCK TABLES
|
||||
* _ LOCK TABLES is not active in this session
|
||||
* */
|
||||
mysql_tx_state_t parse_trx_state(const char *str)
|
||||
mysql_tx_state_t parse_trx_state(const char* str)
|
||||
{
|
||||
int s = TX_EMPTY;
|
||||
mxb_assert(str);
|
||||
@ -1614,34 +1649,42 @@ mysql_tx_state_t parse_trx_state(const char *str)
|
||||
case 'T':
|
||||
s |= TX_EXPLICIT;
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
s |= TX_IMPLICIT;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
s |= TX_READ_UNSAFE;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
s |= TX_READ_TRX;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
s |= TX_WRITE_UNSAFE;
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
s |= TX_WRITE_TRX;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
s |= TX_STMT_UNSAFE;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
s |= TX_RESULT_SET;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
s |= TX_LOCKED_TABLES;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
while (*(str++) != 0);
|
||||
|
||||
|
@ -4,10 +4,13 @@
|
||||
|
||||
#define NO_THREAD_ID 0
|
||||
|
||||
int test_one_query(const char *query, bool should_succeed, uint64_t expected_tid,
|
||||
int expected_kt, std::string expected_user)
|
||||
int test_one_query(const char* query,
|
||||
bool should_succeed,
|
||||
uint64_t expected_tid,
|
||||
int expected_kt,
|
||||
std::string expected_user)
|
||||
{
|
||||
char *query_copy = MXS_STRDUP_A(query);
|
||||
char* query_copy = MXS_STRDUP_A(query);
|
||||
uint64_t result_tid = 1111111;
|
||||
kill_type_t result_kt = KT_QUERY;
|
||||
std::string user;
|
||||
@ -21,8 +24,8 @@ int test_one_query(const char *query, bool should_succeed, uint64_t expected_tid
|
||||
bool success = parse_kill_query(query_copy, &result_tid, &result_kt, &user);
|
||||
MXS_FREE(query_copy);
|
||||
|
||||
if (success == should_succeed && result_tid == expected_tid &&
|
||||
result_kt == expected_kt && expected_user == user)
|
||||
if (success == should_succeed && result_tid == expected_tid
|
||||
&& result_kt == expected_kt && expected_user == user)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -51,55 +54,60 @@ int test_one_query(const char *query, bool should_succeed, uint64_t expected_tid
|
||||
}
|
||||
typedef struct test_t
|
||||
{
|
||||
const char *query;
|
||||
bool should_succeed;
|
||||
uint64_t correct_id;
|
||||
int correct_kt;
|
||||
const char* query;
|
||||
bool should_succeed;
|
||||
uint64_t correct_id;
|
||||
int correct_kt;
|
||||
const char* correct_user;
|
||||
} test_t;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
test_t tests[] =
|
||||
{
|
||||
{" kill ConNectioN 123 ", true, 123, KT_CONNECTION},
|
||||
{"kIlL coNNectioN 987654321 ;", true, 987654321, KT_CONNECTION},
|
||||
{" Ki5L CoNNectioN 987654321 ", false, 0, KT_CONNECTION},
|
||||
{"1", false, 0, KT_CONNECTION},
|
||||
{"kILL 1", true, 1, KT_CONNECTION},
|
||||
{"\n\t kill \nQueRy 456", true, 456, KT_QUERY},
|
||||
{" A kill 1; ", false, 0, KT_CONNECTION},
|
||||
{" kill connection 1A", false, 0, KT_CONNECTION},
|
||||
{" kill connection 1 A ", false, 0, KT_CONNECTION},
|
||||
{"kill query 7 ; select * ", false, 0, KT_CONNECTION},
|
||||
{"KIll query 12345678901234567890", false, 0, KT_QUERY}, // 32-bit integer overflow
|
||||
{"KIll query \t \n \t 21 \n \t ", true, 21, KT_QUERY},
|
||||
{"KIll \t \n \t -6 \n \t ", false, 0, KT_CONNECTION},
|
||||
{"KIll 12345678901234567890123456 \n \t ", false, 0, KT_CONNECTION},
|
||||
{"kill ;", false, 0, KT_QUERY},
|
||||
{" kill ConNectioN 123 HARD", false, 123, KT_CONNECTION},
|
||||
{" kill ConNectioN 123 SOFT", false, 123, KT_CONNECTION},
|
||||
{" kill ConNectioN SOFT 123", false, 123, KT_CONNECTION},
|
||||
{" kill HARD ConNectioN 123", true, 123, KT_CONNECTION | KT_HARD},
|
||||
{" kill SOFT ConNectioN 123", true, 123, KT_CONNECTION | KT_SOFT},
|
||||
{" kill HARD 123", true, 123, KT_CONNECTION | KT_HARD},
|
||||
{" kill SOFT 123", true, 123, KT_CONNECTION | KT_SOFT},
|
||||
{"KIll soft query 21 ", true, 21, KT_QUERY | KT_SOFT},
|
||||
{"KIll query soft 21 ", false, 21, KT_QUERY},
|
||||
{"KIll query user maxuser ", true, NO_THREAD_ID, KT_QUERY, "maxuser"},
|
||||
{"KIll user query maxuser ", false, NO_THREAD_ID, KT_QUERY}
|
||||
{" kill ConNectioN 123 ", true, 123, KT_CONNECTION },
|
||||
{"kIlL coNNectioN 987654321 ;", true, 987654321, KT_CONNECTION },
|
||||
{" Ki5L CoNNectioN 987654321 ", false, 0, KT_CONNECTION },
|
||||
{"1", false, 0, KT_CONNECTION },
|
||||
{"kILL 1", true, 1, KT_CONNECTION },
|
||||
{"\n\t kill \nQueRy 456", true, 456, KT_QUERY },
|
||||
{" A kill 1; ", false, 0, KT_CONNECTION },
|
||||
{" kill connection 1A", false, 0, KT_CONNECTION },
|
||||
{" kill connection 1 A ", false, 0, KT_CONNECTION },
|
||||
{"kill query 7 ; select * ", false, 0, KT_CONNECTION },
|
||||
{"KIll query 12345678901234567890", false, 0, KT_QUERY }, // 32-bit
|
||||
// integer
|
||||
// overflow
|
||||
{"KIll query \t \n \t 21 \n \t ", true, 21, KT_QUERY },
|
||||
{"KIll \t \n \t -6 \n \t ", false, 0, KT_CONNECTION },
|
||||
{"KIll 12345678901234567890123456 \n \t ", false, 0, KT_CONNECTION },
|
||||
{"kill ;", false, 0, KT_QUERY },
|
||||
{" kill ConNectioN 123 HARD", false, 123, KT_CONNECTION },
|
||||
{" kill ConNectioN 123 SOFT", false, 123, KT_CONNECTION },
|
||||
{" kill ConNectioN SOFT 123", false, 123, KT_CONNECTION },
|
||||
{" kill HARD ConNectioN 123", true, 123, KT_CONNECTION | KT_HARD},
|
||||
{" kill SOFT ConNectioN 123", true, 123, KT_CONNECTION | KT_SOFT},
|
||||
{" kill HARD 123", true, 123, KT_CONNECTION | KT_HARD},
|
||||
{" kill SOFT 123", true, 123, KT_CONNECTION | KT_SOFT},
|
||||
{"KIll soft query 21 ", true, 21, KT_QUERY | KT_SOFT },
|
||||
{"KIll query soft 21 ", false, 21, KT_QUERY },
|
||||
{"KIll query user maxuser ", true, NO_THREAD_ID, KT_QUERY, "maxuser" },
|
||||
{"KIll user query maxuser ", false, NO_THREAD_ID, KT_QUERY }
|
||||
};
|
||||
int result = 0;
|
||||
int arr_size = sizeof(tests) / sizeof(test_t);
|
||||
for (int i = 0; i < arr_size; i++)
|
||||
{
|
||||
const char *query = tests[i].query;
|
||||
const char* query = tests[i].query;
|
||||
bool should_succeed = tests[i].should_succeed;
|
||||
uint64_t expected_tid = tests[i].correct_id;
|
||||
int expected_kt = tests[i].correct_kt;
|
||||
std::string expected_user = tests[i].correct_user ? tests[i].correct_user : "";
|
||||
result += test_one_query(query, should_succeed, expected_tid,
|
||||
expected_kt, expected_user);
|
||||
result += test_one_query(query,
|
||||
should_succeed,
|
||||
expected_tid,
|
||||
expected_kt,
|
||||
expected_user);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -56,17 +56,17 @@
|
||||
|
||||
#define GETPWUID_BUF_LEN 255
|
||||
|
||||
static int maxscaled_read_event(DCB* dcb);
|
||||
static int maxscaled_write_event(DCB *dcb);
|
||||
static int maxscaled_write(DCB *dcb, GWBUF *queue);
|
||||
static int maxscaled_error(DCB *dcb);
|
||||
static int maxscaled_hangup(DCB *dcb);
|
||||
static int maxscaled_accept(DCB *dcb);
|
||||
static int maxscaled_close(DCB *dcb);
|
||||
static int maxscaled_listen(DCB *dcb, char *config);
|
||||
static char *mxsd_default_auth();
|
||||
static int maxscaled_read_event(DCB* dcb);
|
||||
static int maxscaled_write_event(DCB* dcb);
|
||||
static int maxscaled_write(DCB* dcb, GWBUF* queue);
|
||||
static int maxscaled_error(DCB* dcb);
|
||||
static int maxscaled_hangup(DCB* dcb);
|
||||
static int maxscaled_accept(DCB* dcb);
|
||||
static int maxscaled_close(DCB* dcb);
|
||||
static int maxscaled_listen(DCB* dcb, char* config);
|
||||
static char* mxsd_default_auth();
|
||||
|
||||
static bool authenticate_unix_socket(MAXSCALED *protocol, DCB *dcb)
|
||||
static bool authenticate_unix_socket(MAXSCALED* protocol, DCB* dcb)
|
||||
{
|
||||
bool authenticated = false;
|
||||
|
||||
@ -77,13 +77,13 @@ static bool authenticate_unix_socket(MAXSCALED *protocol, DCB *dcb)
|
||||
if (getsockopt(dcb->fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == 0)
|
||||
{
|
||||
struct passwd pw_entry;
|
||||
struct passwd *pw_tmp;
|
||||
struct passwd* pw_tmp;
|
||||
char buf[GETPWUID_BUF_LEN];
|
||||
|
||||
/* Fetch username from UID */
|
||||
if (getpwuid_r(ucred.uid, &pw_entry, buf, sizeof(buf), &pw_tmp) == 0)
|
||||
{
|
||||
GWBUF *username;
|
||||
GWBUF* username;
|
||||
|
||||
/* Set user in protocol */
|
||||
protocol->username = strdup(pw_entry.pw_name);
|
||||
@ -93,8 +93,8 @@ static bool authenticate_unix_socket(MAXSCALED *protocol, DCB *dcb)
|
||||
strcpy((char*)GWBUF_DATA(username), protocol->username);
|
||||
|
||||
/* Authenticate the user */
|
||||
if (dcb->authfunc.extract(dcb, username) &&
|
||||
dcb->authfunc.authenticate(dcb) == 0)
|
||||
if (dcb->authfunc.extract(dcb, username)
|
||||
&& dcb->authfunc.authenticate(dcb) == 0)
|
||||
{
|
||||
dcb_printf(dcb, MAXADMIN_AUTH_SUCCESS_REPLY);
|
||||
protocol->state = MAXSCALED_STATE_DATA;
|
||||
@ -124,13 +124,13 @@ static bool authenticate_unix_socket(MAXSCALED *protocol, DCB *dcb)
|
||||
}
|
||||
|
||||
|
||||
static bool authenticate_inet_socket(MAXSCALED *protocol, DCB *dcb)
|
||||
static bool authenticate_inet_socket(MAXSCALED* protocol, DCB* dcb)
|
||||
{
|
||||
dcb_printf(dcb, MAXADMIN_AUTH_USER_PROMPT);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool authenticate_socket(MAXSCALED *protocol, DCB *dcb)
|
||||
static bool authenticate_socket(MAXSCALED* protocol, DCB* dcb)
|
||||
{
|
||||
bool authenticated = false;
|
||||
|
||||
@ -167,49 +167,48 @@ extern "C"
|
||||
*
|
||||
* @return The module object
|
||||
*/
|
||||
MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{
|
||||
MXS_INFO("Initialise MaxScaled Protocol module.");
|
||||
|
||||
static MXS_PROTOCOL MyObject =
|
||||
MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{
|
||||
maxscaled_read_event, /**< Read - EPOLLIN handler */
|
||||
maxscaled_write, /**< Write - data from gateway */
|
||||
maxscaled_write_event, /**< WriteReady - EPOLLOUT handler */
|
||||
maxscaled_error, /**< Error - EPOLLERR handler */
|
||||
maxscaled_hangup, /**< HangUp - EPOLLHUP handler */
|
||||
maxscaled_accept, /**< Accept */
|
||||
NULL, /**< Connect */
|
||||
maxscaled_close, /**< Close */
|
||||
maxscaled_listen, /**< Create a listener */
|
||||
NULL, /**< Authentication */
|
||||
mxsd_default_auth, /**< Default authenticator */
|
||||
NULL, /**< Connection limit reached */
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
MXS_INFO("Initialise MaxScaled Protocol module.");
|
||||
|
||||
static MXS_MODULE info =
|
||||
{
|
||||
MXS_MODULE_API_PROTOCOL,
|
||||
MXS_MODULE_GA,
|
||||
MXS_PROTOCOL_VERSION,
|
||||
"A maxscale protocol for the administration interface",
|
||||
"V2.0.0",
|
||||
MXS_NO_MODULE_CAPABILITIES,
|
||||
&MyObject,
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
static MXS_PROTOCOL MyObject =
|
||||
{
|
||||
{MXS_END_MODULE_PARAMS}
|
||||
}
|
||||
};
|
||||
maxscaled_read_event, /**< Read - EPOLLIN handler */
|
||||
maxscaled_write, /**< Write - data from gateway */
|
||||
maxscaled_write_event, /**< WriteReady - EPOLLOUT handler */
|
||||
maxscaled_error, /**< Error - EPOLLERR handler */
|
||||
maxscaled_hangup, /**< HangUp - EPOLLHUP handler */
|
||||
maxscaled_accept, /**< Accept */
|
||||
NULL, /**< Connect */
|
||||
maxscaled_close, /**< Close */
|
||||
maxscaled_listen, /**< Create a listener */
|
||||
NULL, /**< Authentication */
|
||||
mxsd_default_auth, /**< Default authenticator */
|
||||
NULL, /**< Connection limit reached */
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
return &info;
|
||||
}
|
||||
static MXS_MODULE info =
|
||||
{
|
||||
MXS_MODULE_API_PROTOCOL,
|
||||
MXS_MODULE_GA,
|
||||
MXS_PROTOCOL_VERSION,
|
||||
"A maxscale protocol for the administration interface",
|
||||
"V2.0.0",
|
||||
MXS_NO_MODULE_CAPABILITIES,
|
||||
&MyObject,
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
{
|
||||
{MXS_END_MODULE_PARAMS}
|
||||
}
|
||||
};
|
||||
|
||||
return &info;
|
||||
}
|
||||
}
|
||||
/*lint +e14 */
|
||||
|
||||
@ -218,7 +217,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
||||
*
|
||||
* @return name of authenticator
|
||||
*/
|
||||
static char *mxsd_default_auth()
|
||||
static char* mxsd_default_auth()
|
||||
{
|
||||
return const_cast<char*>("MaxAdminAuth");
|
||||
}
|
||||
@ -232,8 +231,8 @@ static char *mxsd_default_auth()
|
||||
static int maxscaled_read_event(DCB* dcb)
|
||||
{
|
||||
int n;
|
||||
GWBUF *head = NULL;
|
||||
MAXSCALED *maxscaled = (MAXSCALED *)dcb->protocol;
|
||||
GWBUF* head = NULL;
|
||||
MAXSCALED* maxscaled = (MAXSCALED*)dcb->protocol;
|
||||
|
||||
if ((n = dcb_read(dcb, &head, 0)) != -1)
|
||||
{
|
||||
@ -259,7 +258,7 @@ static int maxscaled_read_event(DCB* dcb)
|
||||
|
||||
case MAXSCALED_STATE_PASSWD:
|
||||
{
|
||||
char *password = strndup((char*)GWBUF_DATA(head), GWBUF_LENGTH(head));
|
||||
char* password = strndup((char*)GWBUF_DATA(head), GWBUF_LENGTH(head));
|
||||
if (admin_verify_inet_user(maxscaled->username, password))
|
||||
{
|
||||
dcb_printf(dcb, MAXADMIN_AUTH_SUCCESS_REPLY);
|
||||
@ -299,7 +298,7 @@ static int maxscaled_read_event(DCB* dcb)
|
||||
* @param dcb The descriptor control block
|
||||
* @return
|
||||
*/
|
||||
static int maxscaled_write_event(DCB *dcb)
|
||||
static int maxscaled_write_event(DCB* dcb)
|
||||
{
|
||||
return dcb_drain_writeq(dcb);
|
||||
}
|
||||
@ -313,7 +312,7 @@ static int maxscaled_write_event(DCB *dcb)
|
||||
* @param dcb Descriptor Control Block for the socket
|
||||
* @param queue Linked list of buffes to write
|
||||
*/
|
||||
static int maxscaled_write(DCB *dcb, GWBUF *queue)
|
||||
static int maxscaled_write(DCB* dcb, GWBUF* queue)
|
||||
{
|
||||
int rc;
|
||||
rc = dcb_write(dcb, queue);
|
||||
@ -325,7 +324,7 @@ static int maxscaled_write(DCB *dcb, GWBUF *queue)
|
||||
*
|
||||
* @param dcb The descriptor control block
|
||||
*/
|
||||
static int maxscaled_error(DCB *dcb)
|
||||
static int maxscaled_error(DCB* dcb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -335,7 +334,7 @@ static int maxscaled_error(DCB *dcb)
|
||||
*
|
||||
* @param dcb The descriptor control block
|
||||
*/
|
||||
static int maxscaled_hangup(DCB *dcb)
|
||||
static int maxscaled_hangup(DCB* dcb)
|
||||
{
|
||||
dcb_close(dcb);
|
||||
return 0;
|
||||
@ -348,16 +347,16 @@ static int maxscaled_hangup(DCB *dcb)
|
||||
* @param dcb The descriptor control block
|
||||
* @return The number of new connections created
|
||||
*/
|
||||
static int maxscaled_accept(DCB *listener)
|
||||
static int maxscaled_accept(DCB* listener)
|
||||
{
|
||||
int n_connect = 0;
|
||||
DCB *client_dcb;
|
||||
DCB* client_dcb;
|
||||
socklen_t len = sizeof(struct ucred);
|
||||
struct ucred ucred;
|
||||
|
||||
while ((client_dcb = dcb_accept(listener)) != NULL)
|
||||
{
|
||||
MAXSCALED *maxscaled_protocol = (MAXSCALED *)calloc(1, sizeof(MAXSCALED));
|
||||
MAXSCALED* maxscaled_protocol = (MAXSCALED*)calloc(1, sizeof(MAXSCALED));
|
||||
|
||||
if (!maxscaled_protocol)
|
||||
{
|
||||
@ -378,7 +377,7 @@ static int maxscaled_accept(DCB *listener)
|
||||
}
|
||||
|
||||
spinlock_init(&maxscaled_protocol->lock);
|
||||
client_dcb->protocol = (void *)maxscaled_protocol;
|
||||
client_dcb->protocol = (void*)maxscaled_protocol;
|
||||
|
||||
client_dcb->session = session_alloc(listener->session->service, client_dcb);
|
||||
|
||||
@ -399,9 +398,9 @@ static int maxscaled_accept(DCB *listener)
|
||||
* @param dcb The descriptor control block
|
||||
*/
|
||||
|
||||
static int maxscaled_close(DCB *dcb)
|
||||
static int maxscaled_close(DCB* dcb)
|
||||
{
|
||||
MAXSCALED *maxscaled = static_cast<MAXSCALED*>(dcb->protocol);
|
||||
MAXSCALED* maxscaled = static_cast<MAXSCALED*>(dcb->protocol);
|
||||
|
||||
if (!maxscaled)
|
||||
{
|
||||
@ -426,9 +425,9 @@ static int maxscaled_close(DCB *dcb)
|
||||
* @param config Configuration (ip:port)
|
||||
* @return 0 on failure, 1 on success
|
||||
*/
|
||||
static int maxscaled_listen(DCB *listener, char *config)
|
||||
static int maxscaled_listen(DCB* listener, char* config)
|
||||
{
|
||||
const char *socket_path = NULL;
|
||||
const char* socket_path = NULL;
|
||||
|
||||
/* check for default UNIX socket */
|
||||
if (strncmp(config, MAXADMIN_CONFIG_DEFAULT_SOCKET_TAG, MAXADMIN_CONFIG_DEFAULT_SOCKET_TAG_LEN) == 0)
|
||||
|
@ -38,12 +38,12 @@ typedef struct maxscaled
|
||||
{
|
||||
SPINLOCK lock; /**< Protocol structure lock */
|
||||
int state; /**< The connection state */
|
||||
char *username; /**< The login name of the user */
|
||||
char* username; /**< The login name of the user */
|
||||
} MAXSCALED;
|
||||
|
||||
#define MAXSCALED_STATE_LOGIN 1 /**< Waiting for user */
|
||||
#define MAXSCALED_STATE_PASSWD 2 /**< Waiting for password */
|
||||
#define MAXSCALED_STATE_DATA 3 /**< User logged in */
|
||||
#define MAXSCALED_STATE_LOGIN 1 /**< Waiting for user */
|
||||
#define MAXSCALED_STATE_PASSWD 2 /**< Waiting for password */
|
||||
#define MAXSCALED_STATE_DATA 3 /**< User logged in */
|
||||
|
||||
MXS_END_DECLS
|
||||
|
||||
|
@ -58,23 +58,23 @@
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
static int telnetd_read_event(DCB* dcb);
|
||||
static int telnetd_write_event(DCB *dcb);
|
||||
static int telnetd_write(DCB *dcb, GWBUF *queue);
|
||||
static int telnetd_error(DCB *dcb);
|
||||
static int telnetd_hangup(DCB *dcb);
|
||||
static int telnetd_accept(DCB *dcb);
|
||||
static int telnetd_close(DCB *dcb);
|
||||
static int telnetd_listen(DCB *dcb, char *config);
|
||||
static char *telnetd_default_auth();
|
||||
static int telnetd_read_event(DCB* dcb);
|
||||
static int telnetd_write_event(DCB* dcb);
|
||||
static int telnetd_write(DCB* dcb, GWBUF* queue);
|
||||
static int telnetd_error(DCB* dcb);
|
||||
static int telnetd_hangup(DCB* dcb);
|
||||
static int telnetd_accept(DCB* dcb);
|
||||
static int telnetd_close(DCB* dcb);
|
||||
static int telnetd_listen(DCB* dcb, char* config);
|
||||
static char* telnetd_default_auth();
|
||||
|
||||
/**
|
||||
* The "module object" for the telnetd protocol module.
|
||||
*/
|
||||
|
||||
|
||||
static void telnetd_command(DCB *, unsigned char *cmd);
|
||||
static void telnetd_echo(DCB *dcb, int enable);
|
||||
static void telnetd_command(DCB*, unsigned char* cmd);
|
||||
static void telnetd_echo(DCB* dcb, int enable);
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@ -86,48 +86,47 @@ extern "C"
|
||||
*
|
||||
* @return The module object
|
||||
*/
|
||||
MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{
|
||||
MXS_INFO("Initialise Telnetd Protocol module.");
|
||||
|
||||
static MXS_PROTOCOL MyObject =
|
||||
MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{
|
||||
telnetd_read_event, /**< Read - EPOLLIN handler */
|
||||
telnetd_write, /**< Write - data from gateway */
|
||||
telnetd_write_event, /**< WriteReady - EPOLLOUT handler */
|
||||
telnetd_error, /**< Error - EPOLLERR handler */
|
||||
telnetd_hangup, /**< HangUp - EPOLLHUP handler */
|
||||
telnetd_accept, /**< Accept */
|
||||
NULL, /**< Connect */
|
||||
telnetd_close, /**< Close */
|
||||
telnetd_listen, /**< Create a listener */
|
||||
NULL, /**< Authentication */
|
||||
telnetd_default_auth, /**< Default authenticator */
|
||||
NULL, /**< Connection limit reached */
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
MXS_INFO("Initialise Telnetd Protocol module.");
|
||||
|
||||
static MXS_MODULE info =
|
||||
{
|
||||
MXS_MODULE_API_PROTOCOL,
|
||||
MXS_MODULE_GA,
|
||||
MXS_PROTOCOL_VERSION,
|
||||
"A telnet deamon protocol for simple administration interface",
|
||||
"V1.1.1",
|
||||
MXS_NO_MODULE_CAPABILITIES,
|
||||
&MyObject,
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
static MXS_PROTOCOL MyObject =
|
||||
{
|
||||
{MXS_END_MODULE_PARAMS}
|
||||
}
|
||||
};
|
||||
return &info;
|
||||
}
|
||||
telnetd_read_event, /**< Read - EPOLLIN handler */
|
||||
telnetd_write, /**< Write - data from gateway */
|
||||
telnetd_write_event, /**< WriteReady - EPOLLOUT handler */
|
||||
telnetd_error, /**< Error - EPOLLERR handler */
|
||||
telnetd_hangup, /**< HangUp - EPOLLHUP handler */
|
||||
telnetd_accept, /**< Accept */
|
||||
NULL, /**< Connect */
|
||||
telnetd_close, /**< Close */
|
||||
telnetd_listen, /**< Create a listener */
|
||||
NULL, /**< Authentication */
|
||||
telnetd_default_auth, /**< Default authenticator */
|
||||
NULL, /**< Connection limit reached */
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static MXS_MODULE info =
|
||||
{
|
||||
MXS_MODULE_API_PROTOCOL,
|
||||
MXS_MODULE_GA,
|
||||
MXS_PROTOCOL_VERSION,
|
||||
"A telnet deamon protocol for simple administration interface",
|
||||
"V1.1.1",
|
||||
MXS_NO_MODULE_CAPABILITIES,
|
||||
&MyObject,
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
{
|
||||
{MXS_END_MODULE_PARAMS}
|
||||
}
|
||||
};
|
||||
return &info;
|
||||
}
|
||||
}
|
||||
/*lint +e14 */
|
||||
|
||||
@ -136,7 +135,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
||||
*
|
||||
* @return name of authenticator
|
||||
*/
|
||||
static char *telnetd_default_auth()
|
||||
static char* telnetd_default_auth()
|
||||
{
|
||||
return const_cast<char*>("NullAuthAllow");
|
||||
}
|
||||
@ -150,16 +149,16 @@ static char *telnetd_default_auth()
|
||||
static int telnetd_read_event(DCB* dcb)
|
||||
{
|
||||
int n;
|
||||
GWBUF *head = NULL;
|
||||
MXS_SESSION *session = dcb->session;
|
||||
TELNETD *telnetd = (TELNETD *)dcb->protocol;
|
||||
char *password, *t;
|
||||
GWBUF* head = NULL;
|
||||
MXS_SESSION* session = dcb->session;
|
||||
TELNETD* telnetd = (TELNETD*)dcb->protocol;
|
||||
char* password, * t;
|
||||
|
||||
if ((n = dcb_read(dcb, &head, 0)) != -1)
|
||||
{
|
||||
if (head)
|
||||
{
|
||||
unsigned char *ptr = GWBUF_DATA(head);
|
||||
unsigned char* ptr = GWBUF_DATA(head);
|
||||
ptr = GWBUF_DATA(head);
|
||||
while (GWBUF_LENGTH(head) && *ptr == TELNET_IAC)
|
||||
{
|
||||
@ -184,6 +183,7 @@ static int telnetd_read_event(DCB* dcb)
|
||||
telnetd_echo(dcb, 0);
|
||||
gwbuf_consume(head, GWBUF_LENGTH(head));
|
||||
break;
|
||||
|
||||
case TELNETD_STATE_PASSWD:
|
||||
password = strndup((char*)GWBUF_DATA(head), GWBUF_LENGTH(head));
|
||||
/* Strip the cr/lf from the username */
|
||||
@ -208,6 +208,7 @@ static int telnetd_read_event(DCB* dcb)
|
||||
gwbuf_consume(head, GWBUF_LENGTH(head));
|
||||
MXS_FREE(password);
|
||||
break;
|
||||
|
||||
case TELNETD_STATE_DATA:
|
||||
MXS_SESSION_ROUTE_QUERY(session, head);
|
||||
break;
|
||||
@ -229,7 +230,7 @@ static int telnetd_read_event(DCB* dcb)
|
||||
* @param dcb The descriptor control block
|
||||
* @return
|
||||
*/
|
||||
static int telnetd_write_event(DCB *dcb)
|
||||
static int telnetd_write_event(DCB* dcb)
|
||||
{
|
||||
return dcb_drain_writeq(dcb);
|
||||
}
|
||||
@ -243,7 +244,7 @@ static int telnetd_write_event(DCB *dcb)
|
||||
* @param dcb Descriptor Control Block for the socket
|
||||
* @param queue Linked list of buffes to write
|
||||
*/
|
||||
static int telnetd_write(DCB *dcb, GWBUF *queue)
|
||||
static int telnetd_write(DCB* dcb, GWBUF* queue)
|
||||
{
|
||||
int rc;
|
||||
rc = dcb_write(dcb, queue);
|
||||
@ -255,7 +256,7 @@ static int telnetd_write(DCB *dcb, GWBUF *queue)
|
||||
*
|
||||
* @param dcb The descriptor control block
|
||||
*/
|
||||
static int telnetd_error(DCB *dcb)
|
||||
static int telnetd_error(DCB* dcb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -265,7 +266,7 @@ static int telnetd_error(DCB *dcb)
|
||||
*
|
||||
* @param dcb The descriptor control block
|
||||
*/
|
||||
static int telnetd_hangup(DCB *dcb)
|
||||
static int telnetd_hangup(DCB* dcb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -277,23 +278,23 @@ static int telnetd_hangup(DCB *dcb)
|
||||
* @param listener The descriptor control block
|
||||
* @return The number of new connections created
|
||||
*/
|
||||
static int telnetd_accept(DCB *listener)
|
||||
static int telnetd_accept(DCB* listener)
|
||||
{
|
||||
int n_connect = 0;
|
||||
DCB *client_dcb;
|
||||
DCB* client_dcb;
|
||||
|
||||
while ((client_dcb = dcb_accept(listener)) != NULL)
|
||||
{
|
||||
TELNETD* telnetd_protocol = NULL;
|
||||
|
||||
if ((telnetd_protocol = (TELNETD *)MXS_CALLOC(1, sizeof(TELNETD))) == NULL)
|
||||
if ((telnetd_protocol = (TELNETD*)MXS_CALLOC(1, sizeof(TELNETD))) == NULL)
|
||||
{
|
||||
dcb_close(client_dcb);
|
||||
continue;
|
||||
}
|
||||
telnetd_protocol->state = TELNETD_STATE_LOGIN;
|
||||
telnetd_protocol->username = NULL;
|
||||
client_dcb->protocol = (void *)telnetd_protocol;
|
||||
client_dcb->protocol = (void*)telnetd_protocol;
|
||||
|
||||
client_dcb->session = session_alloc(listener->session->service, client_dcb);
|
||||
if (NULL == client_dcb->session || poll_add_dcb(client_dcb))
|
||||
@ -317,9 +318,9 @@ static int telnetd_accept(DCB *listener)
|
||||
* @param dcb The descriptor control block
|
||||
*/
|
||||
|
||||
static int telnetd_close(DCB *dcb)
|
||||
static int telnetd_close(DCB* dcb)
|
||||
{
|
||||
TELNETD *telnetd = static_cast<TELNETD*>(dcb->protocol);
|
||||
TELNETD* telnetd = static_cast<TELNETD*>(dcb->protocol);
|
||||
|
||||
if (telnetd && telnetd->username)
|
||||
{
|
||||
@ -335,7 +336,7 @@ static int telnetd_close(DCB *dcb)
|
||||
* @param listener The Listener DCB
|
||||
* @param config Configuration (ip:port)
|
||||
*/
|
||||
static int telnetd_listen(DCB *listener, char *config)
|
||||
static int telnetd_listen(DCB* listener, char* config)
|
||||
{
|
||||
return (dcb_listen(listener, config, "telnet") < 0) ? 0 : 1;
|
||||
}
|
||||
@ -350,7 +351,7 @@ static int telnetd_listen(DCB *listener, char *config)
|
||||
* @param dcb The client DCB
|
||||
* @param cmd The command stream
|
||||
*/
|
||||
static void telnetd_command(DCB *dcb, unsigned char *cmd)
|
||||
static void telnetd_command(DCB* dcb, unsigned char* cmd)
|
||||
{
|
||||
}
|
||||
|
||||
@ -360,10 +361,10 @@ static void telnetd_command(DCB *dcb, unsigned char *cmd)
|
||||
* @param dcb DCB of the telnet connection
|
||||
* @param enable Enable or disable echo functionality
|
||||
*/
|
||||
static void telnetd_echo(DCB *dcb, int enable)
|
||||
static void telnetd_echo(DCB* dcb, int enable)
|
||||
{
|
||||
GWBUF *gwbuf;
|
||||
unsigned char *buf;
|
||||
GWBUF* gwbuf;
|
||||
unsigned char* buf;
|
||||
|
||||
if ((gwbuf = gwbuf_alloc(3)) == NULL)
|
||||
{
|
||||
|
Reference in New Issue
Block a user