From 886cc02c63ee9ce031d09446e68583c13d3ea82e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Thu, 18 Dec 2014 03:22:02 +0000 Subject: [PATCH] First draft for issue #45 --- include/mysql_session.h | 1 + include/proxysql_structs.h | 2 +- lib/Makefile | 2 +- lib/MySQL_Protocol.cpp | 2 +- lib/mysql_session.cpp | 99 ++++++++++++++++++++++++++++++++++++-- 5 files changed, 99 insertions(+), 7 deletions(-) diff --git a/include/mysql_session.h b/include/mysql_session.h index 3de9d17f6..4b03fb15f 100644 --- a/include/mysql_session.h +++ b/include/mysql_session.h @@ -12,6 +12,7 @@ class MySQL_Session_userinfo { ~MySQL_Session_userinfo(); void set(char *, char *, char *); void set(MySQL_Session_userinfo *); + bool set_schemaname(char *, int); }; class MySQL_Session diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index 310bec56f..f3ca3398a 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -54,7 +54,7 @@ enum session_status { CONNECTING_SERVER, WAITING_CLIENT_DATA, WAITING_SERVER_DATA, - + CHANGING_SCHEMA, NONE }; diff --git a/lib/Makefile b/lib/Makefile index 9de45977a..8bcc3c332 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -47,7 +47,7 @@ O0=-O0 O2=-O2 O1=-O1 O3=-O3 -mtune=native -OPTZ=$(O2) +OPTZ=$(O0) CFLAGS=$(IDIRS) $(OPTZ) $(DEBUG) -Wall #-lcrypto CPPFLAGS=-std=c++0x $(CFLAGS) $(LDIRS) $(LIBS) diff --git a/lib/MySQL_Protocol.cpp b/lib/MySQL_Protocol.cpp index 08d9054a6..3dbae2612 100644 --- a/lib/MySQL_Protocol.cpp +++ b/lib/MySQL_Protocol.cpp @@ -882,7 +882,7 @@ bool MySQL_Protocol::generate_COM_INIT_DB(bool send, void **ptr, unsigned int *l //Copy4B(_ptr, &myhdr); int l=sizeof(mysql_hdr); _ptr[l]=0x02; l++; - memcpy(_ptr+l, &schema, schema_len); + memcpy(_ptr+l, schema, schema_len); if (send==true) { (*myds)->PSarrayOUT->add((void *)_ptr,size); } if (len) { *len=size; } diff --git a/lib/mysql_session.cpp b/lib/mysql_session.cpp index 4227e2522..d7ef8052d 100644 --- a/lib/mysql_session.cpp +++ b/lib/mysql_session.cpp @@ -49,6 +49,18 @@ void MySQL_Session_userinfo::set(MySQL_Session_userinfo *ui) { */ } + +bool MySQL_Session_userinfo::set_schemaname(char *_new, int l) { + if (strncmp(_new,schemaname,l)) { + l_free_string(schemaname); + schemaname=(char *)l_alloc(l+1); + memcpy(schemaname,_new,l); + schemaname[l]=0; + return true; + } + return false; +} + void * MySQL_Session::operator new(size_t size) { return l_alloc(size); } @@ -299,6 +311,7 @@ int MySQL_Session::handler() { case WAITING_CLIENT_DATA: switch (client_myds->DSS) { case STATE_SLEEP: + proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Statuses: WAITING_CLIENT_DATA - STATE_SLEEP\n"); //unsigned char c; c=*((unsigned char *)pkt.ptr+sizeof(mysql_hdr)); switch ((enum_mysql_command)c) { @@ -369,9 +382,17 @@ int MySQL_Session::handler() { server_myds->DSS=STATE_NOT_CONNECTED; server_myds->PSarrayOUTpending->add(pkt.ptr, pkt.size); } else { - server_myds->PSarrayOUT->add(pkt.ptr, pkt.size); - server_myds->DSS=STATE_QUERY_SENT; - status=WAITING_SERVER_DATA; + if (strcmp(userinfo_client.schemaname,userinfo_server.schemaname)==0) { + server_myds->PSarrayOUT->add(pkt.ptr, pkt.size); + server_myds->DSS=STATE_QUERY_SENT; + status=WAITING_SERVER_DATA; + } else { + userinfo_server.set_schemaname(userinfo_client.schemaname,strlen(userinfo_client.schemaname)); + server_myds->PSarrayOUTpending->add(pkt.ptr, pkt.size); + myprot_server.generate_COM_INIT_DB(true,NULL,NULL,userinfo_server.schemaname); + server_myds->DSS=STATE_QUERY_SENT; + status=CHANGING_SCHEMA; + } } client_myds->DSS=STATE_QUERY_SENT; } else { @@ -381,27 +402,75 @@ int MySQL_Session::handler() { } break; case _MYSQL_COM_QUIT: + proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Got COM_QUIT packet\n"); l_free(pkt.size,pkt.ptr); return -1; break; case _MYSQL_COM_PING: + proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Got COM_PING packet\n"); l_free(pkt.size,pkt.ptr); client_myds->DSS=STATE_QUERY_SENT; myprot_client.generate_pkt_OK(true,NULL,NULL,1,0,0,2,0,NULL); client_myds->DSS=STATE_SLEEP; break; case _MYSQL_COM_STATISTICS: + proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Got COM_STATISTICS packet\n"); l_free(pkt.size,pkt.ptr); client_myds->DSS=STATE_QUERY_SENT; myprot_client.generate_statistics_response(true,NULL,NULL); client_myds->DSS=STATE_SLEEP; break; + case _MYSQL_COM_INIT_DB: + proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Got COM_INIT_DB packet\n"); + if (admin==false) { + userinfo_client.set_schemaname((char *)pkt.ptr+sizeof(mysql_hdr)+1,pkt.size-sizeof(mysql_hdr)-1); +/* + char *_new_schema=(char *)l_alloc(pkt.size-sizeof(mysql_hdr)); + memcpy(_new_schema,(char *)pkt.ptr+sizeof(mysql_hdr)+1,pkt.size-sizeof(mysql_hdr)-1); + _new_schema[pkt.size-sizeof(mysql_hdr)-1]=0; + if (strcmp(_new_schema,userinfo_client.schemaname)) { + l_free_string(userinfo_client.schemaname); + userinfo_client.schemaname=_new_schema; + } else { + l_free_string(_new_schema); + } +*/ + l_free(pkt.size,pkt.ptr); + client_myds->DSS=STATE_QUERY_SENT; + myprot_client.generate_pkt_OK(true,NULL,NULL,1,0,0,2,0,NULL); + client_myds->DSS=STATE_SLEEP; + } else { + l_free(pkt.size,pkt.ptr); + client_myds->DSS=STATE_QUERY_SENT; + myprot_client.generate_pkt_OK(true,NULL,NULL,1,0,0,2,0,NULL); + client_myds->DSS=STATE_SLEEP; + } + break; + case _MYSQL_COM_FIELD_LIST: + if (admin==false) { + /* FIXME: temporary */ + l_free(pkt.size,pkt.ptr); + client_myds->DSS=STATE_QUERY_SENT; + myprot_client.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Command not supported"); + client_myds->DSS=STATE_SLEEP; + } else { + l_free(pkt.size,pkt.ptr); + client_myds->DSS=STATE_QUERY_SENT; + myprot_client.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Command not supported"); + client_myds->DSS=STATE_SLEEP; + } + break; +// case _MYSQL_COM_QUIT: +// l_free(pkt.size,pkt.ptr); +// healthy=0; +// break; default: assert(0); break; } break; default: + proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Statuses: WAITING_CLIENT_DATA - STATE_UNKNOWN\n"); assert(0); // FIXME: this should become close connection } @@ -409,7 +478,7 @@ int MySQL_Session::handler() { case NONE: default: - assert(0); + assert(0); } } /* @@ -441,6 +510,7 @@ int MySQL_Session::handler() { switch (server_myds->DSS) { case STATE_NOT_CONNECTED: + proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Statuses: CONNECTING_SERVER - STATE_NOT_CONNECTED\n"); if (myprot_server.process_pkt_initial_handshake((unsigned char *)pkt.ptr,pkt.size)==true) { l_free(pkt.size,pkt.ptr); //myprot_server.generate_pkt_handshake_response(server_myds,true,NULL,NULL); @@ -452,6 +522,7 @@ int MySQL_Session::handler() { } break; case STATE_CLIENT_HANDSHAKE: + proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Statuses: CONNECTING_SERVER - STATE_CLIENT_HANDSHAKE\n"); if (myprot_server.process_pkt_OK((unsigned char *)pkt.ptr,pkt.size)==true) { l_free(pkt.size,pkt.ptr); server_myds->DSS=STATE_READY; @@ -478,6 +549,7 @@ int MySQL_Session::handler() { switch (server_myds->DSS) { case STATE_QUERY_SENT: + proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Statuses: WAITING_SERVER_DATA - STATE_QUERY_SENT\n"); //unsigned char c; c=*((unsigned char *)pkt.ptr+sizeof(mysql_hdr)); if (c==0 || c==0xff) { @@ -542,6 +614,25 @@ int MySQL_Session::handler() { } break; + case CHANGING_SCHEMA: + proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Statuses: CHANGING_SCHEMA - UNKNWON\n"); + if (myprot_server.process_pkt_OK((unsigned char *)pkt.ptr,pkt.size)==true) { + l_free(pkt.size,pkt.ptr); + server_myds->DSS=STATE_READY; + mybe->myconn=server_myds->myconn; + status=WAITING_SERVER_DATA; + unsigned int k; + PtrSize_t pkt2; + for (k=0; kPSarrayOUTpending->len;) { + server_myds->PSarrayOUTpending->remove_index(0,&pkt2); + server_myds->PSarrayOUT->add(pkt2.ptr, pkt2.size); + server_myds->DSS=STATE_QUERY_SENT; + } + } else { + l_free(pkt.size,pkt.ptr); + } + break; + default: assert(0); }