Reindented server/core/modutil.c

This commit is contained in:
Johan Wikman
2015-11-30 15:30:16 +02:00
parent 17eb80072f
commit c0615408aa
2 changed files with 507 additions and 490 deletions

View File

@ -63,10 +63,12 @@ static void modutil_reply_routing_error(
int int
modutil_is_SQL(GWBUF *buf) modutil_is_SQL(GWBUF *buf)
{ {
unsigned char *ptr; unsigned char *ptr;
if (GWBUF_LENGTH(buf) < 5) if (GWBUF_LENGTH(buf) < 5)
{
return 0; return 0;
}
ptr = GWBUF_DATA(buf); ptr = GWBUF_DATA(buf);
return ptr[4] == 0x03; // COM_QUERY return ptr[4] == 0x03; // COM_QUERY
} }
@ -80,10 +82,12 @@ unsigned char *ptr;
int int
modutil_is_SQL_prepare(GWBUF *buf) modutil_is_SQL_prepare(GWBUF *buf)
{ {
unsigned char *ptr; unsigned char *ptr;
if (GWBUF_LENGTH(buf) < 5) if (GWBUF_LENGTH(buf) < 5)
{
return 0; return 0;
}
ptr = GWBUF_DATA(buf); ptr = GWBUF_DATA(buf);
return ptr[4] == 0x16 ; // COM_STMT_PREPARE return ptr[4] == 0x16 ; // COM_STMT_PREPARE
} }
@ -109,10 +113,12 @@ unsigned char *ptr;
int int
modutil_extract_SQL(GWBUF *buf, char **sql, int *length) modutil_extract_SQL(GWBUF *buf, char **sql, int *length)
{ {
unsigned char *ptr; unsigned char *ptr;
if (!modutil_is_SQL(buf)) if (!modutil_is_SQL(buf))
{
return 0; return 0;
}
ptr = GWBUF_DATA(buf); ptr = GWBUF_DATA(buf);
*length = *ptr++; *length = *ptr++;
*length += (*ptr++ << 8); *length += (*ptr++ << 8);
@ -144,10 +150,12 @@ unsigned char *ptr;
int int
modutil_MySQL_Query(GWBUF *buf, char **sql, int *length, int *residual) modutil_MySQL_Query(GWBUF *buf, char **sql, int *length, int *residual)
{ {
unsigned char *ptr; unsigned char *ptr;
if (!modutil_is_SQL(buf)) if (!modutil_is_SQL(buf))
{
return 0; return 0;
}
ptr = GWBUF_DATA(buf); ptr = GWBUF_DATA(buf);
*residual = *ptr++; *residual = *ptr++;
*residual += (*ptr++ << 8); *residual += (*ptr++ << 8);
@ -173,9 +181,7 @@ unsigned char *ptr;
* @return the length of MySQL packet and writes missing bytecount to * @return the length of MySQL packet and writes missing bytecount to
* nbytes_missing. * nbytes_missing.
*/ */
int modutil_MySQL_query_len( int modutil_MySQL_query_len(GWBUF* buf, int* nbytes_missing)
GWBUF* buf,
int* nbytes_missing)
{ {
int len; int len;
int buflen; int buflen;
@ -186,10 +192,10 @@ int modutil_MySQL_query_len(
goto retblock; goto retblock;
} }
len = MYSQL_GET_PACKET_LEN((uint8_t *)GWBUF_DATA(buf)); len = MYSQL_GET_PACKET_LEN((uint8_t *)GWBUF_DATA(buf));
*nbytes_missing = len-1; *nbytes_missing = len - 1;
buflen = gwbuf_length(buf); buflen = gwbuf_length(buf);
*nbytes_missing -= buflen-5; *nbytes_missing -= buflen - 5;
retblock: retblock:
return len; return len;
@ -208,12 +214,14 @@ retblock:
GWBUF * GWBUF *
modutil_replace_SQL(GWBUF *orig, char *sql) modutil_replace_SQL(GWBUF *orig, char *sql)
{ {
unsigned char *ptr; unsigned char *ptr;
int length, newlength; int length, newlength;
GWBUF *addition; GWBUF *addition;
if (!modutil_is_SQL(orig)) if (!modutil_is_SQL(orig))
{
return NULL; return NULL;
}
ptr = GWBUF_DATA(orig); ptr = GWBUF_DATA(orig);
length = *ptr++; length = *ptr++;
length += (*ptr++ << 8); length += (*ptr++ << 8);
@ -265,19 +273,23 @@ GWBUF *addition;
char * char *
modutil_get_SQL(GWBUF *buf) modutil_get_SQL(GWBUF *buf)
{ {
unsigned int len, length; unsigned int len, length;
unsigned char *ptr; unsigned char *ptr;
char *dptr, *rval = NULL; char *dptr, *rval = NULL;
if (!modutil_is_SQL(buf) && !modutil_is_SQL_prepare(buf)) if (!modutil_is_SQL(buf) && !modutil_is_SQL_prepare(buf))
{
return rval; return rval;
}
ptr = GWBUF_DATA(buf); ptr = GWBUF_DATA(buf);
length = *ptr++; length = *ptr++;
length += (*ptr++ << 8); length += (*ptr++ << 8);
length += (*ptr++ << 16); length += (*ptr++ << 16);
if ((rval = (char *)malloc(length + 1)) == NULL) if ((rval = (char *)malloc(length + 1)) == NULL)
{
return NULL; return NULL;
}
dptr = rval; dptr = rval;
ptr += 2; // Skip sequence id and COM_QUERY byte ptr += 2; // Skip sequence id and COM_QUERY byte
len = GWBUF_LENGTH(buf) - 5; len = GWBUF_LENGTH(buf) - 5;
@ -317,10 +329,11 @@ modutil_get_query(GWBUF *buf)
packet = GWBUF_DATA(buf); packet = GWBUF_DATA(buf);
packet_type = packet[4]; packet_type = packet[4];
switch (packet_type) { switch (packet_type)
{
case MYSQL_COM_QUIT: case MYSQL_COM_QUIT:
len = strlen("[Quit msg]")+1; len = strlen("[Quit msg]") + 1;
if ((query_str = (char *)malloc(len+1)) == NULL) if ((query_str = (char *)malloc(len + 1)) == NULL)
{ {
goto retblock; goto retblock;
} }
@ -329,8 +342,8 @@ modutil_get_query(GWBUF *buf)
break; break;
case MYSQL_COM_QUERY: case MYSQL_COM_QUERY:
len = MYSQL_GET_PACKET_LEN(packet)-1; /*< distract 1 for packet type byte */ len = MYSQL_GET_PACKET_LEN(packet) - 1; /*< distract 1 for packet type byte */
if (len < 1 || len > ~(size_t)0 - 1 || (query_str = (char *)malloc(len+1)) == NULL) if (len < 1 || len > ~(size_t)0 - 1 || (query_str = (char *)malloc(len + 1)) == NULL)
{ {
goto retblock; goto retblock;
} }
@ -339,8 +352,8 @@ modutil_get_query(GWBUF *buf)
break; break;
default: default:
len = strlen(STRPACKETTYPE(packet_type))+1; len = strlen(STRPACKETTYPE(packet_type)) + 1;
if (len < 1 || len > ~(size_t)0 - 1 || (query_str = (char *)malloc(len+1)) == NULL) if (len < 1 || len > ~(size_t)0 - 1 || (query_str = (char *)malloc(len + 1)) == NULL)
{ {
goto retblock; goto retblock;
} }
@ -362,9 +375,8 @@ retblock:
* @param sqlstate_msg The MySQL State Message * @param sqlstate_msg The MySQL State Message
* @param mysql_message The Error Message * @param mysql_message The Error Message
* @return The allocated GWBUF or NULL on failure * @return The allocated GWBUF or NULL on failure
*/ */
GWBUF *modutil_create_mysql_err_msg( GWBUF *modutil_create_mysql_err_msg(int packet_number,
int packet_number,
int affected_rows, int affected_rows,
int merrno, int merrno,
const char *statemsg, const char *statemsg,
@ -395,7 +407,7 @@ GWBUF *modutil_create_mysql_err_msg(
gw_mysql_set_byte2(mysql_err, mysql_errno); gw_mysql_set_byte2(mysql_err, mysql_errno);
mysql_statemsg[0]='#'; mysql_statemsg[0]='#';
memcpy(mysql_statemsg+1, mysql_state, 5); memcpy(mysql_statemsg + 1, mysql_state, 5);
mysql_payload_size = sizeof(field_count) + mysql_payload_size = sizeof(field_count) +
sizeof(mysql_err) + sizeof(mysql_err) +
@ -453,8 +465,7 @@ GWBUF *modutil_create_mysql_err_msg(
* @return 0 for successful dcb write or 1 on failure * @return 0 for successful dcb write or 1 on failure
* *
*/ */
int modutil_send_mysql_err_packet ( int modutil_send_mysql_err_packet(DCB *dcb,
DCB *dcb,
int packet_number, int packet_number,
int in_affected_rows, int in_affected_rows,
int mysql_errno, int mysql_errno,
@ -463,7 +474,8 @@ int modutil_send_mysql_err_packet (
{ {
GWBUF* buf; GWBUF* buf;
buf = modutil_create_mysql_err_msg(packet_number, in_affected_rows, mysql_errno, sqlstate_msg, mysql_message); buf = modutil_create_mysql_err_msg(packet_number, in_affected_rows, mysql_errno,
sqlstate_msg, mysql_message);
return dcb->func.write(dcb, buf); return dcb->func.write(dcb, buf);
} }
@ -475,8 +487,7 @@ int modutil_send_mysql_err_packet (
* return pointer to gwbuf containing a complete packet or * return pointer to gwbuf containing a complete packet or
* NULL if no complete packet was found. * NULL if no complete packet was found.
*/ */
GWBUF* modutil_get_next_MySQL_packet( GWBUF* modutil_get_next_MySQL_packet(GWBUF** p_readbuf)
GWBUF** p_readbuf)
{ {
GWBUF* packetbuf; GWBUF* packetbuf;
GWBUF* readbuf; GWBUF* readbuf;
@ -503,7 +514,7 @@ GWBUF* modutil_get_next_MySQL_packet(
} }
totalbuflen = gwbuf_length(readbuf); totalbuflen = gwbuf_length(readbuf);
data = (uint8_t *)GWBUF_DATA((readbuf)); data = (uint8_t *)GWBUF_DATA((readbuf));
packetlen = MYSQL_GET_PACKET_LEN(data)+4; packetlen = MYSQL_GET_PACKET_LEN(data) + 4;
/** packet is incomplete */ /** packet is incomplete */
if (packetlen > totalbuflen) if (packetlen > totalbuflen)
@ -550,9 +561,11 @@ GWBUF* modutil_get_complete_packets(GWBUF** p_readbuf)
uint8_t *ptr; uint8_t *ptr;
uint32_t len,blen,total = 0; uint32_t len,blen,total = 0;
if(p_readbuf == NULL || (*p_readbuf) == NULL || if (p_readbuf == NULL || (*p_readbuf) == NULL ||
gwbuf_length(*p_readbuf) < 3) gwbuf_length(*p_readbuf) < 3)
{
return NULL; return NULL;
}
packet = gwbuf_make_contiguous(*p_readbuf); packet = gwbuf_make_contiguous(*p_readbuf);
packet->next = NULL; packet->next = NULL;
@ -561,17 +574,17 @@ GWBUF* modutil_get_complete_packets(GWBUF** p_readbuf)
len = gw_mysql_get_byte3(ptr) + 4; len = gw_mysql_get_byte3(ptr) + 4;
blen = gwbuf_length(packet); blen = gwbuf_length(packet);
if(len == blen) if (len == blen)
{ {
*p_readbuf = NULL; *p_readbuf = NULL;
return packet; return packet;
} }
else if(len > blen) else if (len > blen)
{ {
return NULL; return NULL;
} }
while(total + len < blen) while (total + len < blen)
{ {
ptr += len; ptr += len;
total += len; total += len;
@ -587,14 +600,14 @@ GWBUF* modutil_get_complete_packets(GWBUF** p_readbuf)
} }
/** Full packets only, return original */ /** Full packets only, return original */
if(total + len == blen) if (total + len == blen)
{ {
*p_readbuf = NULL; *p_readbuf = NULL;
return packet; return packet;
} }
/** The next packet is a partial, split into complete and partial packets */ /** The next packet is a partial, split into complete and partial packets */
if((buff = gwbuf_clone_portion(packet,0,total)) == NULL) if ((buff = gwbuf_clone_portion(packet, 0, total)) == NULL)
{ {
MXS_ERROR("Failed to partially clone buffer."); MXS_ERROR("Failed to partially clone buffer.");
return NULL; return NULL;
@ -623,26 +636,25 @@ modutil_count_signal_packets(GWBUF *reply, int use_ok, int n_found, int* more)
int errlen = 0, eoflen = 0; int errlen = 0, eoflen = 0;
int iserr = 0, iseof = 0; int iserr = 0, iseof = 0;
bool moreresults = false; bool moreresults = false;
while(ptr < end) while (ptr < end)
{ {
pktlen = MYSQL_GET_PACKET_LEN(ptr) + 4; pktlen = MYSQL_GET_PACKET_LEN(ptr) + 4;
if((iserr = PTR_IS_ERR(ptr)) || (iseof = PTR_IS_EOF(ptr))) if ((iserr = PTR_IS_ERR(ptr)) || (iseof = PTR_IS_EOF(ptr)))
{ {
if(iserr) if (iserr)
{ {
err++; err++;
errlen = pktlen; errlen = pktlen;
} }
else if(iseof) else if (iseof)
{ {
eof++; eof++;
eoflen = pktlen; eoflen = pktlen;
} }
} }
if((ptr + pktlen) > end || (eof + n_found) >= 2) if ((ptr + pktlen) > end || (eof + n_found) >= 2)
{ {
moreresults = PTR_EOF_MORE_RESULTS(ptr); moreresults = PTR_EOF_MORE_RESULTS(ptr);
ptr = prev; ptr = prev;
@ -658,21 +670,25 @@ modutil_count_signal_packets(GWBUF *reply, int use_ok, int n_found, int* more)
* If there were new EOF/ERR packets found, make sure that they are the last * If there were new EOF/ERR packets found, make sure that they are the last
* packet in the buffer. * packet in the buffer.
*/ */
if((eof || err) && n_found) if ((eof || err) && n_found)
{ {
if(err) if (err)
{ {
ptr -= errlen; ptr -= errlen;
if(!PTR_IS_ERR(ptr)) if (!PTR_IS_ERR(ptr))
{
err = 0; err = 0;
} }
}
else else
{ {
ptr -= eoflen; ptr -= eoflen;
if(!PTR_IS_EOF(ptr)) if (!PTR_IS_EOF(ptr))
{
eof = 0; eof = 0;
} }
} }
}
*more = moreresults; *more = moreresults;
@ -688,8 +704,7 @@ modutil_count_signal_packets(GWBUF *reply, int use_ok, int n_found, int* more)
* @param errstr Plain-text string error * @param errstr Plain-text string error
* @param flags GWBUF type flags * @param flags GWBUF type flags
*/ */
void modutil_reply_parse_error( void modutil_reply_parse_error(DCB* backend_dcb,
DCB* backend_dcb,
char* errstr, char* errstr,
uint32_t flags) uint32_t flags)
{ {
@ -706,8 +721,7 @@ void modutil_reply_parse_error(
* @param errstr Plain-text string error * @param errstr Plain-text string error
* @param flags GWBUF type flags * @param flags GWBUF type flags
*/ */
void modutil_reply_auth_error( void modutil_reply_auth_error(DCB* backend_dcb,
DCB* backend_dcb,
char* errstr, char* errstr,
uint32_t flags) uint32_t flags)
{ {
@ -727,8 +741,7 @@ void modutil_reply_auth_error(
* @param errstr Plain-text string error * @param errstr Plain-text string error
* @param flags GWBUF type flags * @param flags GWBUF type flags
*/ */
static void modutil_reply_routing_error( static void modutil_reply_routing_error(DCB* backend_dcb,
DCB* backend_dcb,
int error, int error,
char* state, char* state,
char* errstr, char* errstr,
@ -761,33 +774,33 @@ static void modutil_reply_routing_error(
* @return Pointer to the first non-escaped, non-quoted occurrence of the character. * @return Pointer to the first non-escaped, non-quoted occurrence of the character.
* If the character is not found, NULL is returned. * If the character is not found, NULL is returned.
*/ */
void* strnchr_esc(char* ptr,char c, int len) void* strnchr_esc(char* ptr, char c, int len)
{ {
char* p = (char*)ptr; char* p = (char*)ptr;
char* start = p; char* start = p;
bool quoted = false, escaped = false; bool quoted = false, escaped = false;
char qc; char qc;
while(p < start + len) while (p < start + len)
{ {
if(escaped) if (escaped)
{ {
escaped = false; escaped = false;
} }
else if(*p == '\\') else if (*p == '\\')
{ {
escaped = true; escaped = true;
} }
else if((*p == '\'' || *p == '"') && !quoted) else if ((*p == '\'' || *p == '"') && !quoted)
{ {
quoted = true; quoted = true;
qc = *p; qc = *p;
} }
else if(quoted && *p == qc) else if (quoted && *p == qc)
{ {
quoted = false; quoted = false;
} }
else if(*p == c && !escaped && !quoted) else if (*p == c && !escaped && !quoted)
{ {
return p; return p;
} }
@ -804,14 +817,16 @@ void* strnchr_esc(char* ptr,char c, int len)
*/ */
GWBUF* modutil_create_query(char* query) GWBUF* modutil_create_query(char* query)
{ {
if(query == NULL) if (query == NULL)
{
return NULL; return NULL;
}
GWBUF* rval = gwbuf_alloc(strlen(query) + 5); GWBUF* rval = gwbuf_alloc(strlen(query) + 5);
int pktlen = strlen(query) + 1; int pktlen = strlen(query) + 1;
unsigned char* ptr; unsigned char* ptr;
if(rval) if (rval)
{ {
ptr = (unsigned char*)rval->start; ptr = (unsigned char*)rval->start;
*ptr++ = (pktlen); *ptr++ = (pktlen);
@ -837,18 +852,22 @@ int modutil_count_statements(GWBUF* buffer)
char* end = ((char*)(buffer)->end); char* end = ((char*)(buffer)->end);
int num = 1; int num = 1;
while(ptr < end && (ptr = strnchr_esc(ptr,';', end - ptr))) while (ptr < end && (ptr = strnchr_esc(ptr, ';', end - ptr)))
{ {
num++; num++;
while(*ptr == ';') while (*ptr == ';')
{
ptr++; ptr++;
} }
}
ptr = end - 1; ptr = end - 1;
while(isspace(*ptr)) while (isspace(*ptr))
{
ptr--; ptr--;
}
if(*ptr == ';') if (*ptr == ';')
{ {
num--; num--;
} }

View File

@ -49,9 +49,9 @@ extern int modutil_is_SQL(GWBUF *);
extern int modutil_is_SQL_prepare(GWBUF *); extern int modutil_is_SQL_prepare(GWBUF *);
extern int modutil_extract_SQL(GWBUF *, char **, int *); extern int modutil_extract_SQL(GWBUF *, char **, int *);
extern int modutil_MySQL_Query(GWBUF *, char **, int *, int *); extern int modutil_MySQL_Query(GWBUF *, char **, int *, int *);
extern char *modutil_get_SQL(GWBUF *); extern char* modutil_get_SQL(GWBUF *);
extern GWBUF *modutil_replace_SQL(GWBUF *, char *); extern GWBUF* modutil_replace_SQL(GWBUF *, char *);
extern char *modutil_get_query(GWBUF* buf); extern char* modutil_get_query(GWBUF* buf);
extern int modutil_send_mysql_err_packet(DCB *, int, int, int, const char *, const char *); extern int modutil_send_mysql_err_packet(DCB *, int, int, int, const char *, const char *);
GWBUF* modutil_get_next_MySQL_packet(GWBUF** p_readbuf); GWBUF* modutil_get_next_MySQL_packet(GWBUF** p_readbuf);
GWBUF* modutil_get_complete_packets(GWBUF** p_readbuf); GWBUF* modutil_get_complete_packets(GWBUF** p_readbuf);
@ -60,14 +60,12 @@ void modutil_reply_parse_error(DCB* backend_dcb, char* errstr, uint32_t flags)
void modutil_reply_auth_error(DCB* backend_dcb, char* errstr, uint32_t flags); void modutil_reply_auth_error(DCB* backend_dcb, char* errstr, uint32_t flags);
int modutil_count_statements(GWBUF* buffer); int modutil_count_statements(GWBUF* buffer);
GWBUF* modutil_create_query(char* query); GWBUF* modutil_create_query(char* query);
GWBUF* modutil_create_mysql_err_msg(int packet_number,
GWBUF *modutil_create_mysql_err_msg(
int packet_number,
int affected_rows, int affected_rows,
int merrno, int merrno,
const char *statemsg, const char *statemsg,
const char *msg); const char *msg);
int modutil_count_signal_packets(GWBUF*,int,int,int*); int modutil_count_signal_packets(GWBUF*,int,int,int*);
mxs_pcre2_result_t modutil_mysql_wildcard_match(const char* pattern, const char* string); mxs_pcre2_result_t modutil_mysql_wildcard_match(const char* pattern, const char* string);
#endif #endif