Started working on query parsing. Issues #158 and #152

Per issue #158:
- Created 4 new functions in class Query_Processor.
- See doc/internal/query_parser.txt
Per issue #152:
- Patched deps/libinjection/Makefile to compile with -fPIC
- Standard_MySQL_Thread is linked against libinjection
pull/190/head
René Cannaò 11 years ago
parent f868efc1ab
commit 5f179eca36

@ -3,7 +3,7 @@ AR=ar r
CC=cc
LD=ld
LDSHARED=ld -shared
CFLAGS=-Wall -Werror -ansi -g -O3
CFLAGS=-Wall -Werror -ansi -g -O3 -fPIC
# MAC
#AR=libtool -static

@ -0,0 +1,21 @@
ProxySQL implements query parsing in the Query_Processor class.
4 virtual functions are introduced in Query_Processor class:
virtual void * query_parser_init(char *query, int query_length, int flags) {return NULL;};
virtual enum MYSQL_COM_QUERY_command query_parser_command_type(void *args) {return MYSQL_COM_QUERY___UNKNOWN;}
virtual char * query_parser_first_comment(void *args) { return NULL; }
virtual void query_parser_free(void *args) {};
query_parser_init()
query_parser_init() get as arguments a pointer to the query, its length, and flags that are specific to Query_Processor implementation or simply ignored.
Because multiple implementations of the query parsing should be possible, query_parser_init() returns a generic pointer that should point to a data structure created by query_parser_init() itself. The pointer needs to be passed at the end to query_parser_free() to be freed.
query_parser_free()
Free the structure originally created by query_parser_init()
query_parser_command_type()
Accept as argument the structure created by query_parser_init() and returns the type of query processed.
query_parser_first_comment()
Not implemented yet.
In case the filterning need to be performed based on comments in the query, query_parser_first_comment() can return such comment.

@ -36,6 +36,7 @@ class MySQL_Session
int active_transactions;
bool transaction_persistent;
int to_process;
void *query_parser_args;
unsigned long long pause;
MySQL_Session_userinfo userinfo_client;
MySQL_Session_userinfo userinfo_server;

@ -3,6 +3,53 @@
#include "proxysql.h"
#include "cpp.h"
enum MYSQL_COM_QUERY_command {
MYSQL_COM_QUERY_ALTER_TABLE,
MYSQL_COM_QUERY_ANALYZE,
MYSQL_COM_QUERY_BEGIN,
MYSQL_COM_QUERY_CHANGE_MASTER,
MYSQL_COM_QUERY_CREATE_DATABASE,
MYSQL_COM_QUERY_CREATE_INDEX,
MYSQL_COM_QUERY_CREATE_TABLE,
MYSQL_COM_QUERY_CREATE_TEMPORARY,
MYSQL_COM_QUERY_CREATE_TRIGGER,
MYSQL_COM_QUERY_CREATE_USER,
MYSQL_COM_QUERY_DELETE,
MYSQL_COM_QUERY_DESCRIBE,
MYSQL_COM_QUERY_DROP_DATABASE,
MYSQL_COM_QUERY_DROP_INDEX,
MYSQL_COM_QUERY_DROP_TABLE,
MYSQL_COM_QUERY_DROP_TRIGGER,
MYSQL_COM_QUERY_DROP_USER,
MYSQL_COM_QUERY_GRANT,
MYSQL_COM_QUERY_EXPLAIN,
MYSQL_COM_QUERY_FLUSH,
MYSQL_COM_QUERY_INSERT,
MYSQL_COM_QUERY_KILL,
MYSQL_COM_QUERY_LOAD,
MYSQL_COM_QUERY_LOCK_TABLE,
MYSQL_COM_QUERY_OPTIMIZE,
MYSQL_COM_QUERY_PREPARE,
MYSQL_COM_QUERY_PURGE,
MYSQL_COM_QUERY_RENAME_TABLE,
MYSQL_COM_QUERY_RESET_MASTER,
MYSQL_COM_QUERY_RESET_SLAVE,
MYSQL_COM_QUERY_REPLACE,
MYSQL_COM_QUERY_REVOKE,
MYSQL_COM_QUERY_ROLLBACK,
MYSQL_COM_QUERY_SAVEPOINT,
MYSQL_COM_QUERY_SELECT,
MYSQL_COM_QUERY_SELECT_FOR_UPDATE,
MYSQL_COM_QUERY_SET,
MYSQL_COM_QUERY_START_TRANSACTION,
MYSQL_COM_QUERY_UNLOCK_TABLES,
MYSQL_COM_QUERY_UPDATE,
MYSQL_COM_QUERY_USE,
MYSQL_COM_QUERY_SHOW,
MYSQL_COM_QUERY___UNKNOWN
};
struct _Query_Processor_rule_t {
int rule_id;
bool active;
@ -61,9 +108,15 @@ class Query_Processor {
virtual void end_thread() {};
virtual void commit() {}; // this applies all the changes in memory
virtual SQLite3_result * get_current_query_rules() {return NULL;};
virtual SQLite3_result * get_stats_query_rules() {return NULL;};
virtual void update_query_processor_stats() {};
virtual void * query_parser_init(char *query, int query_length, int flags) {return NULL;};
virtual enum MYSQL_COM_QUERY_command query_parser_command_type(void *args) {return MYSQL_COM_QUERY___UNKNOWN;}
virtual char * query_parser_first_comment(void *args) { return NULL; }
virtual void query_parser_free(void *args) {};
};

@ -23,6 +23,10 @@ LIBCONFIG_PATH=$(DEPS_PATH)/libconfig/libconfig-1.4.9
LIBCONFIG_IDIR=-I$(LIBCONFIG_PATH)/lib
INJECTION_PATH=$(DEPS_PATH)/libinjection
INJECTION_IDIR=$(INJECTION_PATH)
RE2_PATH=$(DEPS_PATH)/re2/re2
RE2_IDIR=$(RE2_PATH)
@ -31,7 +35,7 @@ IDIR=../include
#IDIRS=-I$(IDIR) -I$(JEMALLOC_IDIR) -I$(MARIADB_IDIR) $(LIBEVENT_IDIR) $(GLIB_IDIRS) $(LIBCONFIG_IDIR)
IDIRS=-I$(IDIR) -I$(JEMALLOC_IDIR) -I$(MARIADB_IDIR) $(LIBCONFIG_IDIR) -I$(RE2_IDIR)
LDIRS=-L$(JEMALLOC_PATH)/lib -L$(RE2_PATH)/obj
LDIRS=-L$(JEMALLOC_PATH)/lib -L$(RE2_PATH)/obj -L$(INJECTION_PATH)
LIBS=-rdynamic -Wl,-Bstatic -ljemalloc_pic -lre2 -Wl,-Bdynamic -ldl -lpthread -lm -lz -lrt
@ -64,7 +68,7 @@ Standard_ProxySQL_Admin.so: Standard_ProxySQL_Admin.ko Standard_MySQL_Thread.ko
$(CPP) -shared -fPIC -o $@ $(CPPFLAGS) Standard_ProxySQL_Admin.ko Standard_MySQL_Thread.ko libproxysql.a -lcrypto $(LIBS)
Standard_Query_Processor.so: Standard_Query_Processor.ko libproxysql.a
$(CPP) -shared -fPIC -o $@ $(CPPFLAGS) Standard_Query_Processor.ko libproxysql.a -lcrypto $(LIBS)
$(CPP) -shared -fPIC -o $@ $(CPPFLAGS) Standard_Query_Processor.ko libproxysql.a -lcrypto $(LIBS) -linjection
Standard_MySQL_Authentication.so: Standard_MySQL_Authentication.ko libproxysql.a
$(CPP) -shared -fPIC -o $@ $(CPPFLAGS) Standard_MySQL_Authentication.ko libproxysql.a -lcrypto $(LIBS)

@ -5,7 +5,8 @@
#include "re2/regexp.h"
#include "proxysql.h"
#include "cpp.h"
#include "../deps/libinjection/libinjection.h"
#include "../deps/libinjection/libinjection_sqli.h"
#define QUERY_PROCESSOR_VERSION "0.1.728"
@ -108,6 +109,13 @@ class QP_rule_text {
};
struct __SQP_query_parser_t {
sfilter sf;
};
typedef struct __SQP_query_parser_t SQP_par_t;
struct __RE2_objects_t {
re2::RE2::Options *opt;
RE2 *re;
@ -505,8 +513,27 @@ virtual void update_query_processor_stats() {
}
}
spin_rdunlock(&rwlock);
};
virtual void * query_parser_init(char *query, int query_length, int flags) {
SQP_par_t *qp=(SQP_par_t *)malloc(sizeof(SQP_par_t));
libinjection_sqli_init(&qp->sf, query, query_length, FLAG_SQL_MYSQL);
return (void *)qp;
};
virtual enum MYSQL_COM_QUERY_command query_parser_command_type(void *args) {
SQP_par_t *qp=(SQP_par_t *)args;
return MYSQL_COM_QUERY___UNKNOWN;
}
virtual char * query_parser_first_comment(void *args) { return NULL; }
virtual void query_parser_free(void *args) {
SQP_par_t *qp=(SQP_par_t *)args;
free(qp);
};
};
extern "C" Query_Processor * create_Query_Processor_func() {

@ -344,6 +344,8 @@ int MySQL_Session::handler() {
switch ((enum_mysql_command)c) {
case _MYSQL_COM_QUERY:
if (admin==false) {
query_parser_args=GloQPro->query_parser_init((char *)pkt.ptr+5, pkt.size-5, 0);
GloQPro->query_parser_free(query_parser_args);
myprot_client.process_pkt_COM_QUERY((unsigned char *)pkt.ptr,pkt.size);
qpo=GloQPro->process_mysql_query(this,pkt.ptr,pkt.size,false);
if (qpo) {

Loading…
Cancel
Save