diff --git a/protocol_1.0/.deps b/protocol_1.0/.deps
deleted file mode 100644
index e69de29bb..000000000
diff --git a/protocol_1.0/Makefile b/protocol_1.0/Makefile
deleted file mode 100644
index 0d6078c15..000000000
--- a/protocol_1.0/Makefile
+++ /dev/null
@@ -1,50 +0,0 @@
-##
-## Makefile -- Build procedure for sample skysql Apache module
-## Autogenerated via ``apxs -n skysql -g''.
-##
-
-builddir=.
-top_srcdir=/packages/inst/apache_2.4.2
-top_builddir=/packages/inst/apache_2.4.2
-include /packages/inst/apache_2.4.2/build/special.mk
-
-# the used tools
-APXS=apxs
-APACHECTL=apachectl
-
-# additional defines, includes and libraries
-#DEFS=-Dmy_define=my_value
-
-#INCLUDES=
-
-#LIBS=-lskysqlclient -lmysqlcompat
-
-#LDFLAGS=
-
-# the default target
-all: local-shared-build
-
-# install the shared object file into Apache
-install: install-modules-yes
-
-# cleanup
-clean:
- -rm -f mod_skysql.o mod_skysql.lo mod_skysql.slo mod_skysql.la skysql_utils.o skysql_utils.lo skysql_utils.slo skysql_utils.la
-
-# simple test
-test: reload
- lynx -mime_header http://localhost/skysql
-
-# install and activate shared object by reloading Apache to
-# force a reload of the shared object file
-reload: install restart
-
-# the general Apache start/restart/stop
-# procedures
-start:
- $(APACHECTL) start
-restart:
- $(APACHECTL) restart
-stop:
- $(APACHECTL) stop
-
diff --git a/protocol_1.0/README b/protocol_1.0/README
deleted file mode 100644
index b7d300d8c..000000000
--- a/protocol_1.0/README
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-This file is distributed as part of the SkySQL Gateway. It is free
-software: you can redistribute it and/or modify it under the terms of the
-GNU General Public License as published by the Free Software Foundation,
-version 2.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 51
-Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Copyright SkySQL Ab
-
-*/
-
-Apache 2.4.2
diff --git a/protocol_1.0/gateway.conf b/protocol_1.0/gateway.conf
deleted file mode 100644
index 23caa6041..000000000
--- a/protocol_1.0/gateway.conf
+++ /dev/null
@@ -1,27 +0,0 @@
-#Apache 2.4.2 configuration
-
-########################
-# The Mysql protocol enabled in the main server
-#
-AcceptFilter http httpready
-AcceptFilter mysqld none
-
-LoadModule skysql_module modules/mod_skysql.so
-
-Listen 4402 mysqld
-
-Timeout 300
-SkySQLProtocol On
-SkySQLPool Off
-SkySQLSingleDBbresource "Master/Slaves" "127.0.0.1:3306,127.0.0.1:3307,127.0.0.1:3308;test"
-SkySQLTimeout 300
-
-
-## HTTP on port 81, in this virtual host
-SkySQLProtocol Off
-
- SetHandler skysql
-
-
-
-########################
diff --git a/protocol_1.0/live_config.txt b/protocol_1.0/live_config.txt
deleted file mode 100644
index 748772c70..000000000
--- a/protocol_1.0/live_config.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-curl 'http://127.0.0.1:81/skycc?show=1'
-curl 'http://127.0.0.1:81/skycc?update=127.0.0.1:3306,127.0.0.1:3307,127.0.0.1:3308'
diff --git a/protocol_1.0/mod_skysql.c b/protocol_1.0/mod_skysql.c
deleted file mode 100644
index 80d5674ca..000000000
--- a/protocol_1.0/mod_skysql.c
+++ /dev/null
@@ -1,1490 +0,0 @@
-/*
-This file is distributed as part of the SkySQL Gateway. It is free
-software: you can redistribute it and/or modify it under the terms of the
-GNU General Public License as published by the Free Software Foundation,
-version 2.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 51
-Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Copyright SkySQL Ab
-
-*/
-
-//////////////////////////////////
-// SKYSQL GATEWAY main module
-// By Massimiliano Pinto 2012/2013
-//////////////////////////////////
-
-
-//////////////////////////////////
-// //
-// S K Y S Q L G A T E W A Y //
-// //
-//////////////////////////////////
-
-#include "skysql_gw.h"
-
-unsigned int mysql_errno(MYSQL_conn *mysql) {
- return 1146U;
-}
-
-
-const char *mysql_sqlstate(MYSQL_conn *mysql) {
- return "00000";
-
-}
-
-const char *mysql_error(MYSQL_conn *mysql) {
- return "error 1111";
-}
-
-static char *strend(register const char *s)
-{
- while (*s++);
- return (char*) (s-1);
-}
-
-int mysql_select_db(MYSQL_conn *conn, const char *db) {
- apr_status_t rv;
- long bytes;
- int ret = 1;
- uint8_t packet_buffer[SMALL_CHUNK] = "";
-
- // set COMM_INIT_DB
- packet_buffer[4]= '\x02';
- strncpy(packet_buffer+4+1, db, SMALL_CHUNK - 1);
-
- //COMM_INIT_DB + DBNAME = paylod
- skysql_set_byte3(packet_buffer, 1 + strlen(packet_buffer+4+1));
-
- //packet header + payload = bytes to send
- bytes = 4 + 1 + strlen(packet_buffer+4+1);
-
- // send to server
- rv = apr_socket_send(conn->socket, packet_buffer, &bytes);
-
- if (rv != APR_SUCCESS) {
- return 1;
- }
-
- // now read the response from server
- bytes = SMALL_CHUNK;
-
- memset(&packet_buffer, '\0', sizeof(packet_buffer));
-
- rv = apr_socket_recv(conn->socket, packet_buffer, &bytes);
- ret = packet_buffer[4];
-
- if (rv != APR_SUCCESS) {
- return 1;
- }
-
- if (ret == '\x00')
- return 0;
- else
- return ret;
-}
-
-///////////////////////////////////////
-// MYSQL_conn structure setup
-// A new standalone pool is allocated
-///////////////////////////////////////
-MYSQL_conn *mysql_init(MYSQL_conn *data) {
- apr_pool_t *pool = NULL;
- apr_status_t rv = -1;
-
- MYSQL_conn *input = NULL;
-
- if (input == NULL) {
- // structure allocation
- input = malloc(sizeof(MYSQL_conn));
- memset(input, '\0', sizeof(MYSQL_conn));
-
- if (input == NULL)
- return NULL;
- // new pool created
- rv = apr_pool_create_core(&pool);
-
- if (rv != APR_SUCCESS) {
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "MYSQL_INIT: apr_pool_create_core FAILED\n");
- fflush(stderr);
-#endif
- free(input);
- return NULL;
- }
-
- // the structure now has the pool
- input->pool = pool;
- }
-
- return input;
-}
-
-/////////////////////////////////////
-// Send COM_QUIT to server
-// Close socket
-// free the pool
-// free main pointer
-/////////////////////////////////////
-void mysql_close(MYSQL_conn **ptr) {
- apr_status_t rv;
- uint8_t packet_buffer[5];
- MYSQL_conn *conn = *ptr;
-
- if (conn == NULL)
- return;
-
- long bytes = 5;
-
- // Packet # is 0
- packet_buffer[3]= '\x00';
-
- // COM_QUIT is \x01
- packet_buffer[4]= '\x01';
-
- // set packet length to 1
- skysql_set_byte3(packet_buffer, 1);
-
- if (conn->socket) {
-
- // send COM_QUIT
- rv = apr_socket_send(conn->socket, packet_buffer, &bytes);
-
- // close socket & free
- apr_socket_close(conn->socket);
- }
-
- if (conn->pool) {
-
- // pool destroy
- apr_pool_destroy(conn->pool);
- conn->pool = NULL;
- }
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "Open/Close Connection %lu to backend closed/cleaned\n", conn->tid);
- fflush(stderr);
-#endif
- // free structure pointer
- if (conn != NULL) {
- free(conn);
- conn = NULL;
- *ptr = NULL;
- ptr = NULL;
- }
-
-}
-
-int mysql_query(MYSQL_conn *conn, const char *query) {
- apr_status_t rv;
- //uint8_t *packet_buffer=NULL;
- uint8_t packet_buffer[SMALL_CHUNK];
- long bytes;
- int fd;
-
- //packet_buffer = (uint8_t *) calloc(1, 5 + strlen(query) + 1);
- memset(&packet_buffer, '\0', sizeof(packet_buffer));
-
- packet_buffer[4]= '\x03';
- strcpy(packet_buffer+5, query);
-
- skysql_set_byte3(packet_buffer, 1 + strlen(query));
-
- bytes = 4 + 1 + strlen(query);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "THE QUERY is [%s] len %i\n", query, bytes);
- fprintf(stderr, "THE QUERY TID is [%lu]", conn->tid);
- fprintf(stderr, "THE QUERY scramble is [%s]", conn->scramble);
- if (conn->socket == NULL) {
- fprintf(stderr, "***** THE QUERY sock struct is NULL\n");
- }
- fwrite(packet_buffer, bytes, 1, stderr);
- fflush(stderr);
-#endif
- apr_os_sock_get(&fd,conn->socket);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "QUERY Socket FD is %i\n", fd);
- fflush(stderr);
-#endif
-
- rv = apr_socket_send(conn->socket, packet_buffer, &bytes);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "QUERY SENT [%s]\n", query);
- fflush(stderr);
-#endif
-
- if (rv != APR_SUCCESS) {
- return 1;
- }
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "Query [%s] sent\n", query);
- fflush(stderr);
-#endif
-
- return 0;
-}
-
-
-int mysql_print_result(MYSQL_conn *conn) {
- apr_status_t rv;
- uint8_t buffer[MAX_CHUNK];
- long bytes;
-
- bytes = 1024 * 16;
-
- memset(buffer, '\0', sizeof(buffer));
-
- rv = apr_socket_recv(conn->socket, buffer, &bytes);
-
- if (rv != APR_SUCCESS) {
- return 1;
- }
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "Result with %li columns\n", buffer[4]);
- fwrite(buffer, bytes, 1, stderr);
- fflush(stderr);
-#endif
-
- return (int) buffer[4];
-}
-
-static int mysql_connect(char *host, int port, char *dbname, char *user, char *passwd, MYSQL_conn *conn, int compress) {
- apr_status_t rv;
- int connect = 0;
- int ciclo = 0;
- char buffer[SMALL_CHUNK];
- uint8_t packet_buffer[SMALL_CHUNK];
- char errmesg[128];
- uint8_t *payload = NULL;
- int server_protocol;
- char server_version[100]="";
- uint8_t *server_version_end = NULL;
- uint16_t skysql_server_capabilities_one;
- uint16_t skysql_server_capabilities_two;
- int fd;
- unsigned long tid =0;
- apr_sockaddr_t *connessione;
- apr_socket_t *socket = NULL;
- long bytes;
- uint8_t scramble_data_1[8 + 1] = "";
- uint8_t scramble_data_2[12 + 1] = "";
- uint8_t scramble_data[20 + 1] = "";
- uint8_t capab_ptr[4];
- int scramble_len;
- uint8_t scramble[20 + 1];
- uint8_t client_scramble[20 + 1];
- uint8_t client_capabilities[4];
- uint32_t server_capabilities;
- uint32_t final_capabilities;
- char dbpass[500]="";
- apr_pool_t *pool = NULL;
-
- pool = conn->pool;
-
- apr_sockaddr_info_get(&connessione, host, APR_INET, port, 0, pool);
-
- if ((rv = apr_socket_create(&socket, connessione->family, SOCK_STREAM, APR_PROTO_TCP, pool)) != APR_SUCCESS) {
- fprintf(stderr, "Errore creazione socket: [%s] %i\n", strerror(errno), errno);
- exit;
- }
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "Socket initialized\n");
- fflush(stderr);
-#endif
- conn->socket=socket;
-
- rv = apr_socket_opt_set(socket, APR_TCP_NODELAY, 1);
- rv = apr_socket_opt_set(socket, APR_SO_NONBLOCK , 0);
-
- //apr_socket_timeout_set(socket, 355000);
-
- if ((rv = apr_socket_connect(socket, connessione)) != APR_SUCCESS) {
- apr_strerror(rv, errmesg, sizeof(errmesg));
- fprintf(stderr, "Errore connect %i, %s: RV = [%i], [%s]\n", errno, strerror(errno), rv, errmesg);
- apr_socket_close(socket);
-
- return -1;
-
- } else {
- connect = 1;
- }
-
- apr_os_sock_get(&fd,socket);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "CONNECT is DONE\n");
- fprintf(stderr, "Socket FD is %i\n", fd);
- fflush(stderr);
-#endif
-
- memset(&buffer, '\0', sizeof(buffer));
-
- bytes = 16384;
-
-
- rv = apr_socket_recv(socket, buffer, &bytes);
-
- if ( rv == APR_SUCCESS) {
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "RESPONSE ciclo %i HO letto [%s] bytes %li\n",ciclo, buffer, bytes);
- fflush(stderr);
-#endif
- ciclo++;
- } else {
- if (APR_STATUS_IS_EOF(rv)) {
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "EOF reached. Bytes = %li\n", bytes);
- fflush(stderr);
-#endif
- } else {
-#ifdef MYSQL_CONN_DEBUG
- apr_strerror(rv, errmesg, sizeof(errmesg));
- fprintf(stderr, "###### Receive error FINAL : connection not completed %i %s: RV = [%i], [%s]\n", errno, strerror(errno), rv, errmesg);
-#endif
- apr_socket_close(socket);
-
- return -1;
- }
- }
-
-#ifdef MYSQL_CONN_DEBUG
- fwrite(buffer, bytes, 1, stderr);
- fflush(stderr);
-#endif
-
- //decode mysql handshake
-
- payload = buffer + 4;
- server_protocol= payload[0];
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "Server Protocol [%i]\n", server_protocol);
-
-#endif
- payload++;
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "Protocol Version [%s]\n", payload);
- fflush(stderr);
-#endif
-
- server_version_end = strend((char*) payload);
- payload = server_version_end + 1;
-
- // TID
- tid = skysql_get_byte4(payload);
- memcpy(&conn->tid, &tid, 4);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "Thread ID is %lu\n", conn->tid);
- fflush(stderr);
-#endif
-
- payload +=4;
-
- // scramble_part 1
- memcpy(scramble_data_1, payload, 8);
- payload += 8;
-
- // 1 filler
- payload++;
-
- skysql_server_capabilities_one = skysql_get_byte2(payload);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "Capab_1[\n");
- fwrite(&skysql_server_capabilities_one, 2, 1, stderr);
- fflush(stderr);
-#endif
-
- //2 capab_part 1 + 1 language + 2 server_status
- payload +=5;
-
- skysql_server_capabilities_two = skysql_get_byte2(payload);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "]Capab_2[\n");
- fwrite(&skysql_server_capabilities_two, 2, 1, stderr);
- fprintf(stderr, "]\n");
- fflush(stderr);
-#endif
-
- memcpy(&capab_ptr, &skysql_server_capabilities_one, 2);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "Capab_1[\n");
- fwrite(capab_ptr, 2, 1, stderr);
- fflush(stderr);
-#endif
-
- memcpy(&(capab_ptr[2]), &skysql_server_capabilities_two, 2);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "Capab_2[\n");
- fwrite(capab_ptr, 2, 1, stderr);
- fflush(stderr);
-#endif
-
- // 2 capab_part 2
- payload+=2;
-
- scramble_len = payload[0] -1;
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "Scramble_len [%i]\n", scramble_len);
- fflush(stderr);
-#endif
-
- payload += 11;
-
- memcpy(scramble_data_2, payload, scramble_len - 8);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "Scramble_buff1[");
- fwrite(scramble_data_1, 8, 1, stderr);
- fprintf(stderr, "]\nScramble_buff2 [");
- fwrite(scramble_data_2, scramble_len - 8, 1, stderr);
- fprintf(stderr, "]\n");
- fflush(stderr);
-#endif
-
- memcpy(scramble, scramble_data_1, 8);
- memcpy(scramble + 8, scramble_data_2, scramble_len - 8);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "Full Scramble 20 bytes is [\n");
- fwrite(scramble, 20, 1, stderr);
- fprintf(stderr, "\n]\n");
- fflush(stderr);
-#endif
-
- memcpy(conn->scramble, scramble, 20);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "Scramble from MYSQL_Conn is [\n");
- fwrite(scramble, 20, 1, stderr);
- fprintf(stderr, "\n]\n");
- fflush(stderr);
- fprintf(stderr, "Now sending user, pass & db\n[");
- fwrite(&server_capabilities, 4, 1, stderr);
- fprintf(stderr, "]\n");
-#endif
-
- final_capabilities = skysql_get_byte4((uint8_t *)&server_capabilities);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "CAPABS [%u]\n", final_capabilities);
- fflush(stderr);
-#endif
- memset(packet_buffer, '\0', sizeof(packet_buffer));
- //packet_header(byte3 +1 pack#)
- packet_buffer[3] = '\x01';
-
- //final_capabilities = 1025669;
-
- final_capabilities |= SKYSQL_CAPABILITIES_PROTOCOL_41;
- final_capabilities |= SKYSQL_CAPABILITIES_CLIENT;
- if (compress) {
- final_capabilities |= SKYSQL_CAPABILITIES_COMPRESS;
- fprintf(stderr, "Backend Connection with compression\n");
- fflush(stderr);
- }
-
- if (passwd != NULL) {
- uint8_t hash1[APR_SHA1_DIGESTSIZE]="";
- uint8_t hash2[APR_SHA1_DIGESTSIZE]="";
- uint8_t new_sha[APR_SHA1_DIGESTSIZE]="";
-
-
- //skysql_sha1_str("xxxx", strlen("xxxx"), hash1);
- memcpy(hash1, passwd, 20);
- skysql_sha1_str(hash1, 20, hash2);
- bin2hex(dbpass, hash2, 20);
- skysql_sha1_2_str(scramble, 20, hash2, 20, new_sha);
- skysql_str_xor(client_scramble, new_sha, hash1, 20);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "Hash1 [%s]\n", hash1);
- fprintf(stderr, "Hash2 [%s]\n", hash2);
- fprintf(stderr, "SHA1(SHA1(password in hex)\n");
- fprintf(stderr, "PAss [%s]\n", dbpass);
- fflush(stderr);
- fprintf(stderr, "newsha [%s]\n", new_sha);
- fprintf(stderr, "Client send scramble 20 [\n");
- fwrite(client_scramble, 20, 1, stderr);
- fprintf(stderr, "\n]\n");
- fflush(stderr);
-#endif
- }
-
- if (dbname == NULL) {
- // now without db!!
- final_capabilities &= ~SKYSQL_CAPABILITIES_CONNECT_WITH_DB;
- } else {
- final_capabilities |= SKYSQL_CAPABILITIES_CONNECT_WITH_DB;
- }
-
-
- skysql_set_byte4(client_capabilities, final_capabilities);
- memcpy(packet_buffer + 4, client_capabilities, 4);
-
- //packet_buffer[4] = '\x8d';
- //packet_buffer[5] = '\xa6';
- //packet_buffer[6] = '\x0f';
- //packet_buffer[7] = '\x00';
-
- skysql_set_byte4(packet_buffer + 4 + 4, 16777216);
- packet_buffer[12] = '\x08';
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "User is [%s]\n", user);
- fflush(stderr);
-#endif
- strcpy(packet_buffer+36, user);
-
- bytes = 32 + 22 + 1 + 1;
-
- bytes += strlen(user);
-
- if (dbname == NULL) {
- //strcpy(packet_buffer+36 + 5 + 2, "mysql_native_password");
- } else {
- if (passwd != NULL) {
- *(packet_buffer+36 + 5 + 1) = 20;
- memcpy(packet_buffer+36 + 5 + 1 + 1, client_scramble, 20);
- strcpy(packet_buffer+36 + 5 + 1 + 1 + 20, dbname);
- //strcpy(packet_buffer+36 + 5 + 1 + 1 + 20 + strlen(dbname) + 1, "mysql_native_password");
- //bytes += 20 + strlen(dbname) + 1;
- bytes += strlen(dbname) -1;
- } else {
- strcpy(packet_buffer+36 + 5 + 1 + 1, dbname);
- //strcpy(packet_buffer+36 + 5 + 1 + 1 + strlen(dbname) + 1, "mysql_native_password");
- bytes += strlen(dbname) -1;
- }
- }
-
- skysql_set_byte3(packet_buffer, bytes);
-
- bytes += 4;
-
- rv = apr_socket_send(socket, packet_buffer, &bytes);
-
- if (rv != APR_SUCCESS) {
- fprintf(stderr, "CONNECT Error in send auth\n");
- }
-
- bytes = 4096;
-
- memset(buffer, '\0', sizeof (buffer));
-
- rv = apr_socket_recv(socket, buffer, &bytes);
-
-
- if (rv != APR_SUCCESS) {
- fprintf(stderr, "CONNCET Error in recv OK for auth\n");
- }
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "ok packet\[");
- fwrite(buffer, bytes, 1, stderr);
- fprintf(stderr, "]\n");
- fflush(stderr);
-#endif
- if (buffer[4] == '\x00') {
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "OK packet received, packet # %i\n", buffer[3]);
- fflush(stderr);
-#endif
-
- return 0;
- }
-
- return 1;
-}
-
-///////////////////////////////////////
-// interaction with apache scoreboard
-//message 64 bytes max
-///////////////////////////////////////
-
-static int update_gateway_child_status(ap_sb_handle_t *sbh, int status, conn_rec *c, apr_bucket_brigade *bb, char *message) {
- worker_score *ws = ap_get_scoreboard_worker(sbh);
- int old_status = ws->status;
-
- ws->status = status;
-
- if (!ap_extended_status) {
- return old_status;
- }
-
- ws->last_used = apr_time_now();
-
- /* initial pass only, please - in the name of efficiency */
- if (c) {
- apr_cpystrn(ws->client, ap_get_remote_host(c, c->base_server->lookup_defaults, REMOTE_NOLOOKUP, NULL), sizeof(ws->client));
- apr_cpystrn(ws->vhost, c->base_server->server_hostname, sizeof(ws->vhost));
- /* Deliberate trailing space - filling in string on WRITE passes */
- apr_cpystrn(ws->request, message, sizeof(ws->request));
- }
-
- return old_status;
-}
-
-///////////////////////////////////////////////////
-// custom mysqlclose for apache styart new child //
-///////////////////////////////////////////////////
-
-void child_mysql_close(MYSQL_conn *conn) {
- apr_status_t rv;
- uint8_t packet_buffer[5];
- long bytes = 5;
-
- fprintf(stderr, "SkySQL Gateway process ID %lu is exiting\n", getpid());
- fflush(stderr);
- if (conn)
- mysql_close(&conn);
-}
-
-///////////////////////////////////////////////
-// custom mysqsl_close in process_connection //
-///////////////////////////////////////////////
-
-void my_mysql_close(MYSQL_conn *conn, conn_rec *c) {
- int fd=-1;
-
- apr_os_sock_get(&fd,conn->socket);
-
- if (fd) {
- if (c !=NULL)
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "Connection TID %lu to backend server closed", conn->tid);
- } else {
- if (c !=NULL)
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "init resources free");
- }
-
- mysql_close(&conn);
-}
-
-///////////////////////////////////////////////////////////
-// the mysql protocol implementation at connection level //
-///////////////////////////////////////////////////////////
-
-static int skysql_process_connection(conn_rec *c) {
- apr_bucket_brigade *r_bb;
- apr_bucket_brigade *bb;
- apr_bucket *b;
- apr_bucket *auth_bucket;
- apr_bucket *bucket;
- apr_status_t rv;
- int seen_eos = 0;
- int child_stopped_reading = 0;
-
- int num_fields;
- int i;
- uint8_t header_result_packet[4];
- uint8_t result_column_count;
- int result_version_len = 0;
- char *query_from_client = NULL;
- int query_from_client_len = 0;
- char *client_auth_packet = NULL;
- unsigned int query_ret = 0;
- int return_data = 0;
- int input_read = 0;
- unsigned int skysql_errno = 0;
- const char *skysql_error_msg = NULL;
- const char *skysql_state = NULL;
- uint8_t *outbuf = NULL;
- uint8_t client_flags[4];
-
- int load_balancing_servers = 0;
- int current_slave = -1;
-
- skysql_server_conf *conf;
- char *current_slave_server_host = NULL;
- int current_slave_server_port = 3306;
- skysql_client_auth *mysql_client_data = NULL;
- mysql_driver_details *mysql_driver = NULL;
- MYSQL_conn *conn = NULL;
- MYSQL_conn *write_conn = NULL;
- apr_pool_t *pool = NULL;
- int max_queries_per_connection = 0;
- uint8_t mysql_command = 0;
- char tmp_buffer[10001]="";
- unsigned long tmp_buffer_len = 0L;
-
- uint8_t scramble[20]="";
- int scramble_len = 0;
-
- uint8_t stage1_hash[20 +1] ="";
-
- conn_details *find_server = NULL;
- char *selected_host_m = NULL;
- char *selected_host = NULL;
- char *selected_host_temp = NULL;
- char *selected_dbname = NULL;
- int selected_shard = 0;
- int selected_port = 0;
- int selected_port_m = 0;
-
- backend_list l;
-
- // current slave
- int curr_s = 1;
-
- //server to client socket timeout
- apr_interval_time_t timeout = 300000000;
-
- /////////////////////////////////////////
- // basic infos from configuration file
- /////////////////////////////////////////
- conf = (skysql_server_conf *)ap_get_module_config(c->base_server->module_config, &skysql_module);
-
- ///////////////////////////////////////////
- // MYSQL Protocol switch in configuration
- ///////////////////////////////////////////
- if (!conf->protocol_enabled) {
- return DECLINED;
- }
-
- ///////////////////////////////////////////////
- // now setting the timeout form configuration
- ///////////////////////////////////////////////
-
- if (conf->loop_timeout > 0) {
- timeout = conf->loop_timeout * 1000000;
- }
-
- ////////////////////////////////////
- // apache scoreboard update
- // aka, customizing server-status!!
- /////////////////////////////////////
-
- ap_time_process_request(c->sbh, START_PREQUEST);
- update_gateway_child_status(c->sbh, SERVER_READY, c, NULL, "GATEWAY: MYSQL ready ");
-
- //////////////////////////
- // now the c->pool is ok
- //////////////////////////
- pool = c->pool;
-
- ///////////////////////////////
- // mysql server/client detail
- ///////////////////////////////
- mysql_client_data = apr_pcalloc(pool, sizeof(skysql_client_auth));
- mysql_driver = apr_pcalloc(pool, sizeof(mysql_driver_details));
- mysql_client_data->driver_details = (mysql_driver_details *) mysql_driver;
-
- // yeah, one connection
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "I got a connection!, id [%i]", c->id);
-
- ////////////////////////////////////////////////////////////////////////////////
- // default scenario is to perform here protocol handshake and the autentication
- ////////////////////////////////////////////////////////////////////////////////
-
- //////////////////////////////////////
- // MYSQL 5.1/5.5 Compatible handshake
- // todo: a return structure with connection data: capabilities, scramble_buff
-
- update_gateway_child_status(c->sbh, SERVER_BUSY_WRITE, c, NULL, "GATEWAY: MYSQL handshake sent ");
-
- rv = skysql_send_handshake(c, scramble, &scramble_len);
-
- update_gateway_child_status(c->sbh, SERVER_BUSY_READ, c, NULL, "GATEWAY: MYSQL Auth read ");
-
- ///////////////////////////////////////
- // now read the client authentication
- // and return data structure with client details, dbname, username, and the stage1_hash
- // the latest is for further backend authentication with same user/pass
-
- rv = skysql_read_client_autentication(c, pool, scramble, scramble_len, mysql_client_data, stage1_hash);
-
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server, "Client MySQL Stage1 Hash [%s]", stage1_hash);
-
- // client authentication data stored
-
- if (!rv) {
- // todo implement custom error packet
- // message and return status
- skysql_send_ok(c, pool, 2, 0, NULL);
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server, "*** MySQL Authentication FALSE, thread ID is %i", getpid());
-
- return HTTP_INTERNAL_SERVER_ERROR;
- }
-
- update_gateway_child_status(c->sbh, SERVER_BUSY_WRITE, c, NULL, "GATEWAY: MYSQL Auth Done ");
-
- ///////////////////////////////
- // ok, client is autenticated
- // akwnoledge it!
- ///////////////////////////////
- skysql_send_ok(c, pool, 2, 0, NULL);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "MySQL Authentication OK, thread ID is %i", getpid());
-
- //////////////////////////////
- // check if db is in connect
- //////////////////////////////
- if (mysql_driver->connect_with_db) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "DB is in connect packet");
- }
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "current username is [%s]", mysql_client_data->username);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "current DB is [%s]", mysql_client_data->database != NULL ? mysql_client_data->database : "");
-
- ///////////////////////////
- // check for compression //
- ///////////////////////////
- if (mysql_driver->compress) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "Compress Request is in connect packet");
- }
-
- /////////////////////
- // Let's go ahead //
- /////////////////////
-
- // now the pool pointer is set to NULL
- pool = NULL;
-
- //////////////////////////
- // check pooling config
- /////////////////////////
-
- if (!conf->pool_enabled) {
- curr_s = 1;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "MySQL backend open/close");
- conn = mysql_init(NULL);
- write_conn = mysql_init(NULL);
-
- if (conn == NULL) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server, "MYSQL Read conn init Error %u: %s", 1, "No memory");
- return 500;
- }
- if (write_conn == NULL) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server, "MYSQL Write conn init Error %u: %s", 1, "No memory");
- return 500;
- }
-
- if (mysql_client_data->database != NULL) {
- selected_dbname = mysql_client_data->database;
- } else {
- selected_dbname = "test";
- }
-
-
- // backend selection: Master and Slave load balancing (if more than one slave in config)
-
- l.list = config_area;
- curr_s = select_random_slave_server(l.list, &l.num);
-
- if (l.num > 1) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SkySQL M/S RunTime config [%s], RoundRobin selected slave is [%i]", config_area, curr_s);
- } else {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SkySQL M/S RunTime config [%s]", config_area);
- }
-
- /////////////////////////////////
- // find a SLAVE in the list
- // index > 0 is for slave
- /////////////////////////////////
- get_server_from_list(&selected_host_temp, &selected_port, config_area, curr_s, c->pool);
- selected_host=apr_pstrdup(c->pool, selected_host_temp);
-
- if (mysql_connect(selected_host, selected_port, selected_dbname, mysql_client_data->username, stage1_hash, conn, mysql_driver->compress) != 0) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server, "MYSQL Read Connect [%s:%i] Error %u: %s", selected_host, selected_port, mysql_errno(conn), mysql_error(conn));
- return 500;
- } else {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SkySQL READ RunTime Opened connection to backend [%s:%i:%s]", selected_host, selected_port, selected_dbname);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "READ Backend Server TID %i, scamble_buf [%5s]", conn->tid, conn->scramble);
- }
-
- //////////////////////////////////
- // find the MASTER in the list
- //////////////////////////////////
- get_master_from_list(&selected_host_temp, &selected_port_m, config_area, c->pool);
- selected_host_m=apr_pstrdup(c->pool, selected_host_temp);
-
- if (mysql_connect(selected_host_m, selected_port_m, selected_dbname, mysql_client_data->username, stage1_hash, write_conn, mysql_driver->compress) != 0) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server, "MYSQL Write Connect [%s:%i] Error %u: %s", selected_host_m, selected_port_m, mysql_errno(write_conn), mysql_error(write_conn));
- return 500;
- } else {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SkySQL Write RunTime Opened connection to backend [%s:%i:%s]", selected_host_m, selected_port_m, selected_dbname);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "Write Backend Server TID %i, scamble_buf [%5s]", write_conn->tid, write_conn->scramble);
- }
-
- } else {
- // use the pool
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "MySQL backend pool");
- conn = conf->conn;
- }
-
- update_gateway_child_status(c->sbh, SERVER_BUSY_READ, c, NULL, apr_psprintf(c->pool, "GATEWAY: MYSQL backend selected, DB [%s] ", selected_dbname));
-
- //////////////////////////////////////////////////////
- // main loop
- // speaking MySQL protocol 5.1/5.5
- //////////////////////////////////////////////////////
-
- ////////////////////////////////////////////////////
- // here applying the timeout to the current socket
- // this protects/saves the main loop
- // so ... choose the right value
-
- apr_socket_timeout_set(ap_get_conn_socket(c), timeout);
-
- while(1) {
- char i_username[100]="";
- int query_logic=0;
- //////////////////////////////////////////////////////////////
- // the new pool is allocated on c->pool
- // this new pool is the right one for the while(1) main loop
- // it MUST BE destroyed just before exiting the loop, or on
- // a break statement
- // take care of it
- //////////////////////////////////////////////////////////////
-
- apr_pool_create(&pool, c->pool);
-
- r_bb = apr_brigade_create(pool, c->bucket_alloc);
-
- /////////////////////////
- // reading client input
- /////////////////////////
-
- child_stopped_reading = 0;
- input_read = 0;
-
- // update status for servers-status activity
- update_gateway_child_status(c->sbh, SERVER_BUSY_KEEPALIVE, c, NULL, apr_psprintf(pool, "GATEWAY: MYSQL loop, DB [%s]", selected_dbname));
-
- ///////////////////////////////////////////////
- // Get input bytes from the client, blocking
- // TODO: handle multi packet input
- // or reading larger data input
- // yes, this is only one brigade!
- ///////////////////////////////////////////////
-
- if (((rv = ap_get_brigade(c->input_filters, r_bb, AP_MODE_READBYTES, APR_BLOCK_READ, 8192)) != APR_SUCCESS) || APR_BRIGADE_EMPTY(r_bb)) {
- char errmsg[256]="";
- // is this an error?
- //apr_brigade_cleanup(r_bb);
- //apr_brigade_destroy(r_bb);
- apr_strerror(rv, errmsg, sizeof(errmsg));
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, ">>> No more data from client, in ap_get_brigade [%s]", errmsg);
-
- //apr_pool_destroy(pool);
- // this breaks the main loop
- //break;
- }
-
- /////////////////////////////////////////////
- // now extract data bucket from the brigade
- /////////////////////////////////////////////
-
- for (bucket = APR_BRIGADE_FIRST(r_bb); bucket != APR_BRIGADE_SENTINEL(r_bb); bucket = APR_BUCKET_NEXT(bucket)) {
- apr_size_t len = 0;
- const char *data = NULL;
- if (APR_BUCKET_IS_EOS(bucket)) {
- seen_eos = 1;
- break;
- }
-
- if (APR_BUCKET_IS_FLUSH(bucket)) {
- continue;
- }
-
- if (child_stopped_reading) {
- // the statement breaks this 'for' loop NOT the main loop with 'while'!
- break;
- }
-
- ///////////////////////////
- // reading a bucket
- // what to do with large input data, as 'mysql load data'????
- ///////////////////////////
- rv = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "Client Input data len [%i]", len);
-
- if (rv != APR_SUCCESS) {
- char errmsg[256]="";
- apr_strerror(rv, errmsg, sizeof(errmsg));
- child_stopped_reading = 1;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SkySQL Gateway stops reading [%s]", errmsg);
- }
-
- ////////////////////////////////////////////////////////
- // current data is copied into a pool allocated buffer
- ////////////////////////////////////////////////////////
-
- query_from_client = (char *)apr_pstrmemdup(pool, data, len);
- query_from_client_len = len;
-
- input_read = 1;
- }
-
- // let's destroy the brigate, it's useless now
- apr_brigade_destroy(r_bb);
-
- // now handle client input
- if (input_read == 1 && query_from_client != NULL) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "Client Input [%s], command [%x]", query_from_client+5, query_from_client[4]);
- } else {
- // no data read
- // input buffer NULL or empty
- // what to do?
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SkySQL Gateway main loop: input is empty, exiting");
- apr_pool_destroy(pool);
- break;
- }
-
- //prepare custom error response if max is raised
- max_queries_per_connection++;
- if (max_queries_per_connection > 1000000002) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server, "max_queries_per_connection reached = %li", max_queries_per_connection);
- gateway_send_error(c, pool, 1);
- apr_pool_destroy(pool);
-
- // if (die_on__max_queries_per_connection)
- //break;
- continue;
- }
-
- // check the mysql thread id, for pre-openend the ti is in conf->tid
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "Serving Client with Read MySQL Thread ID [%lu]", conn->tid);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "Serving Client with Write MySQL Thread ID [%lu]", write_conn->tid);
-
- mysql_command = query_from_client[4];
-
- /////////////////////////////////////
- // now processing the mysql_command
- /////////////////////////////////////
-
- update_gateway_child_status(c->sbh, SERVER_BUSY_KEEPALIVE, c, NULL, apr_psprintf(pool, "GATEWAY: MYSQL loop Command [%x], DB [%s]", mysql_command, selected_dbname));
-
- switch (mysql_command) {
- case 0x0e :
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "Protocol Command is COM_PING");
- // reponse sent directly to the client
- // no ping to backend, for now
- skysql_send_ok(c, pool, 1, 0, NULL);
-
- break;
- case 0x04 :
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "Protocol Command is COM_FIELD_LIST");
- mysql_pass_packet(conn, query_from_client, query_from_client_len);
- mysql_receive_packet(c, pool, conn);
-
- break;
- case 0x1b :
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "Protocol Command is COM_SET_OPTION");
- skysql_send_eof(c, pool, 1);
-
- break;
- case 0x0d :
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "Protocol Command is COM_DEBUG");
- skysql_send_ok(c, pool, 1, 0, NULL);
-
- break;
- case 0x03 :
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "Protocol Command is COM_QUERY, Read/write Splitting is enabled");
- ///////////////////////////////
- //read/write splitting logic
- // passing: actual backend server config, the sql statement, protocol_command, actual_slave
- ////////////////////////////////
- query_logic = query_routing(config_area, query_from_client+5, mysql_command, curr_s);
-
- if (query_logic == SKYSQL_READ) {
- // sql to the slave
- skygateway_query_result(c, pool, conn, query_from_client+5);
- } else {
- // sql to the master
- skygateway_query_result(c, pool, write_conn, query_from_client+5);
- }
- break;
- case 0x16 :
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "COM_PREPARE");
- skygateway_statement_prepare_result(c, pool, conn, query_from_client+5, query_from_client_len-5);
-
- break;
- case 0x17 :
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "COM_EXECUTE");
- skygateway_statement_execute_result(c, pool, conn, query_from_client+5, query_from_client_len-5);
-
- break;
- case 0x19 :
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "COM_CLOSE");
-
- mysql_send_command(conn, query_from_client+5, 0x19, query_from_client_len-5);
-
- break;
- case 0x02 :
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "COM_INIT_DB");
- //mysql_select_db(conn, query_from_client+5);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "COM_INIT_DB", query_from_client+5);
- // reponse sent to the client
- skysql_send_ok(c, pool, 1, 0, NULL);
-
- break;
- case 0x01 :
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "COM_QUIT");
- // QUIT received
- // close backend connection if not pooled
- // and exit the switch
-
- if (!conf->pool_enabled) {
- mysql_close(&conn);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "MYSQL_conn is NULL? %i", conn == NULL ? 1 : 0);
- }
- if (!conf->pool_enabled) {
- mysql_close(&write_conn);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "MYSQL_conn is NULL? %i", write_conn == NULL ? 1 : 0);
- }
- break;
- case 0x11 :
- strcpy(i_username, query_from_client+5);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "COM_CHANGE_USER");
- skysql_change_user(c, pool, i_username, "test", conn, stage1_hash);
- mysql_receive_packet(c, pool, conn);
- break;
-
- default :
- if (mysql_driver->compress) {
- mysql_pass_packet(conn, query_from_client, query_from_client_len);
- mysql_receive_packet(c, pool, conn);
- } else {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "UNKNOW MYSQL PROTOCOL COMMAND [%x]", mysql_command);
- // reponse sent to the client, with custom error: TODO
- skysql_send_ok(c, pool, 1, 0, "unknow command");
- }
- break;
- }
-
- /////////////////////////
- // now all is done: destroy immediately all resources in the new poll
- // the loop continues with no resources allocated
- apr_pool_destroy(pool);
-
- // if COM_QUIT terminate the main loop!
- if (mysql_command == 0x01) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "COM_QUIT has been received, the main loop now ends");
- break;
- } else {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "the main loop continues");
- continue;
- }
-
- ////////////////////////////
- // main loop now ends
- ////////////////////////////
-
- }
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "Main loop ended!");
-
- if (conn != NULL) {
- if (!conf->pool_enabled) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, ">> READ opened connection found!, close it with COM_QUIT");
-
- mysql_close(&conn);
- }
- if (!conf->pool_enabled) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, ">> WRITE opened connection found!, close it with COM_QUIT");
-
- mysql_close(&write_conn);
- }
- }
-
- // hey, it was okay to handle the protocol connectioni, is thereanything else to do?
-
- update_gateway_child_status(c->sbh, SERVER_CLOSING, c, NULL, "GATEWAY: MYSQL quit ");
-
- ap_time_process_request(c->sbh, STOP_PREQUEST);
-
- return OK;
-}
-
-/////////////////////////////////
-// The sample content handler
-// Only with HTTP protocol
-// now only configuration commands, then
-// will be useful with JSON
-////////////////////////////////
-static int skysql_handler(request_rec *r)
-{
- skysql_server_conf *conf;
-
- if (strcmp(r->handler, "skysql")) {
- return DECLINED;
- }
-
- r->content_type = "text/html";
-
- if (!r->header_only)
- ap_rputs("SkySQL Gateway HTTP Control\n", r);
-
- if (r->args != NULL) {
-
- if (strstr(r->args, "show=1")) {
- ap_rprintf(r, "Configuration M/S is [%s]", config_area);
- } else if (strstr(r->args, "update=")) {
- strcpy(config_area, r->args+7);
- ap_rputs("Configuration M/S updated\n", r);
- }
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Global M/S [%s]", config_area);
- }
- return OK;
-}
-
-/////////////////////////////////
-// Module Initialization
-// Persistent structures & data
-/////////////////////////////////
-
-static int skysql_init_module(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *base_server) {
- server_rec *s;
- int fd_mapped = -1;
- const char *userdata_key = "skysql_init_module";
- void *data = NULL;
- skysql_server_conf *conf;
-
- s = base_server;
-
- /* Handle first server startup */
- apr_pool_userdata_get(&data, userdata_key, s->process->pool);
- if (data == NULL) {
- apr_pool_userdata_set((const void *)1, userdata_key, apr_pool_cleanup_null, s->process->pool);
- return OK;
- }
-
- conf = (skysql_server_conf *)ap_get_module_config(s->module_config, &skysql_module);
-
- /* shared memory for this apache server */
- if ( (fd_mapped = open ("/dev/zero", O_RDWR) ) < 0) {
- fprintf(stderr,"Errore in mem_mapped: %i, %s\n",errno,strerror(errno));
- return 500;
- } else {
- if ( (config_area = (unsigned char *)mmap(0, 40000, PROT_READ | PROT_WRITE, MAP_SHARED, fd_mapped, 0)) == (unsigned char *) -1) {
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "SKYSQL Init: mem_mapped error [%i], [%s]", errno, strerror(errno));
- } else
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "mem_mapped OK: [%i] bytes from [%x]", 40000, config_area);
- close(fd_mapped);
- }
-
- // the following code is for the virtual hosts setup!!!
- /*
- for (; s; s = s->next) {
- if (find_config != APR_SUCCESS) {
- return HTTP_INTERNAL_SERVER_ERROR;
- }
- }
- */
- if (conf->server_list != NULL) {
- strcpy(config_area, conf->server_list);
- } else {
- strcpy(config_area, "127.0.0.1:3307,127.0.0.1:3306,192.168.57.1:3306,START:9090_NULL:config");
- }
-
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "SKYSQL Init: Internal structure done");
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "SKYSQL Init: ext file ver is [%i]", skysql_ext_file_ver());
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "SKYSQL Init: DbServers [%s], enabled [%i]", config_area, conf->protocol_enabled);
-
- return OK;
-}
-
-////////////////////////////////////////
-// Child Initialization, only for processes
-////////////////////////////////////////
-
-static void skysql_child_init(apr_pool_t *p, server_rec *s) {
- // take care of virtualhosts ...
- while(s) {
- skysql_server_conf *conf;
- conf = (skysql_server_conf *)ap_get_module_config(s->module_config, &skysql_module);
-
- if (conf->protocol_enabled && conf->pool_enabled) {
-
- // MySQL Init
- conf->conn = mysql_init(NULL);
- conf->conn->pool = p;
-
- // store child process id
- conf->gateway_id = getpid();
-
- if (conf->conn == NULL) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "MYSQL init Error %u: %s\n", mysql_errno(conf->conn), mysql_error(conf->conn));
- return;
- }
- if (mysql_connect("127.0.0.1", 3306, "test", "pippo", "pippo", conf->conn, 0) != 0) {
- //if (mysql_real_connect(conf->conn, "192.168.1.40", "root", "pippo", "test", 3306, NULL, 0) == NULL) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "MYSQL Connect Error %u: %s\n", mysql_errno(conf->conn), mysql_error(conf->conn));
- return ;
- } else {
- conf->mysql_tid = conf->conn->tid;
- //ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "PID %li SkySQL Child Init & Open connection TID %lu to backend", getpid(), conf->mysql_tid);
- }
-
- // structure deallocation & connection close
- apr_pool_cleanup_register(p, conf->conn, (apr_status_t (*)(void *)) child_mysql_close, (apr_status_t (*)(void *)) child_mysql_close);
-
- } else {
- //ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "Generic init flags %i, %i, Skip Protocol Setup & Skip database connection", conf->protocol_enabled, conf->pool_enabled);
- }
-
- // next virtual host ..
- s = s->next;
- }
-}
-
-////////////////////////////////////////
-// Creating defaulf configuration data
-////////////////////////////////////////
-static void * create_skysql_config(apr_pool_t *p, server_rec *s) {
- skysql_server_conf *ps = apr_pcalloc(p, sizeof(skysql_server_conf));
- ps->conn = NULL;
- ps->protocol_enabled = 0;
- ps->pool_enabled = 0;
- ps->resources = apr_hash_make(p);
- ps->loop_timeout = 300;
-
- return ps;
-}
-
-/////////////////////////////
-// Enabling MySQL Protocol //
-/////////////////////////////
-static const char *skysql_protocol_enable(cmd_parms *cmd, void *dummy, int arg)
-{
- skysql_server_conf *sconf = ap_get_module_config(cmd->server->module_config, &skysql_module);
- sconf->protocol_enabled = arg;
-
- return NULL;
-}
-
-/////////////////////////////////
-// Enabling MySQL loop timeout //
-/////////////////////////////////
-static const char *skysql_loop_timeout(cmd_parms *cmd, void *dummy, const char *arg)
-{
- skysql_server_conf *sconf = ap_get_module_config(cmd->server->module_config, &skysql_module);
-
- sconf->loop_timeout = atoi(arg);
-
- return NULL;
-}
-
-/////////////////////////////////////////////
-// Enabling per child persistent connection
-/////////////////////////////////////////////
-static const char *skysql_pool_enable(cmd_parms *cmd, void *dummy, int arg)
-{
- skysql_server_conf *sconf = ap_get_module_config(cmd->server->module_config, &skysql_module);
- sconf->pool_enabled = arg;
-
- return NULL;
-}
-
-static const char *skysql_single_db_resource(cmd_parms *cmd, void *dconf, const char *a1, const char *a2) {
- char *ptr_port = NULL;
- char *ptr_db = NULL;
- char *ptr_host = NULL;
- char *ptr_list = NULL;
-
- skysql_server_conf *conf = ap_get_module_config(cmd->server->module_config, &skysql_module);
-
- conn_details *newresource = apr_pcalloc(cmd->pool, sizeof(conn_details));
-
- newresource->raw_config = apr_pstrdup(cmd->pool, a2);
- newresource->name = apr_pstrdup(cmd->pool, a1);
-
- ptr_db = strchr(a2, ';');
- newresource->server_list = apr_pstrndup(cmd->pool, a2, ptr_db-a2);
- newresource->dbname = apr_pstrdup(cmd->pool, ptr_db+1);
-
- newresource->nshards = 1;
-
- ptr_list = newresource->server_list;
- ptr_host = ptr_list;
- while((ptr_host = strchr(ptr_list, ',')) != NULL) {
- newresource->nshards++;
- ptr_list = ptr_host + 1;
- }
- // now put the struct in the hash table
- apr_hash_set(conf->resources, apr_pstrdup(cmd->pool, a1), APR_HASH_KEY_STRING, newresource);
-
- // creare un contenitore, table??? da agganciare con la key a1 e value a2
- fprintf(stderr, "Config Resource [%s] with %i servers, [%s]\n", a1, newresource->nshards, newresource->server_list);
- fflush(stderr);
-
- return NULL;
-}
-
-static const char *skysql_server_list(cmd_parms *cmd, void *dconf, const char *a1, const char *a2) {
- char *ptr_port = NULL;
- char *ptr_db = NULL;
- char *ptr_host = NULL;
- char *ptr_list = NULL;
-
- skysql_server_conf *conf = ap_get_module_config(cmd->server->module_config, &skysql_module);
-
- ptr_db = strchr(a2, ';');
- conf->server_list = apr_pstrndup(cmd->pool, a2, ptr_db-a2);
-
- fprintf(stderr, "Config DBResource is [%s]\n", conf->server_list);
- fflush(stderr);
-
- return NULL;
-}
-//////////////////////////////
-// commands implemeted here //
-//////////////////////////////
-static const command_rec skysql_cmds[] = {
- AP_INIT_FLAG("SkySQLProtocol", skysql_protocol_enable, NULL, RSRC_CONF, "Run an MYSQL protocol on this host"),
- AP_INIT_FLAG("SkySQLPool", skysql_pool_enable, NULL, RSRC_CONF, "SKYSQL backend servers pool"),
- //AP_INIT_TAKE2("SkySQLSingleDBbresource", skysql_single_db_resource, NULL, OR_FILEINFO, "a single db resource name"),
- AP_INIT_TAKE2("SkySQLSingleDBbresource", skysql_server_list, NULL, OR_FILEINFO, "a single db resource name"),
- AP_INIT_TAKE1("SkySQLTimeout", skysql_loop_timeout, NULL, OR_FILEINFO, "MYSQL protocol loop timeout"),
- // SkySQLMaxQueryPerConnection
- {NULL}
-};
-
-////////////////////////////
-// hooks implemented here //
-////////////////////////////
-static void skysql_register_hooks(apr_pool_t *p)
-{
- ap_hook_post_config(skysql_init_module, NULL,NULL, APR_HOOK_MIDDLE);
- ap_hook_child_init(skysql_child_init, NULL, NULL, APR_HOOK_MIDDLE);
- ap_hook_process_connection(skysql_process_connection, NULL, NULL, APR_HOOK_MIDDLE);
- ap_hook_handler(skysql_handler, NULL, NULL, APR_HOOK_MIDDLE);
-}
-
-/////////////////////////////////
-// Dispatch list for API hooks //
-/////////////////////////////////
-
-module AP_MODULE_DECLARE_DATA skysql_module = {
- STANDARD20_MODULE_STUFF,
- NULL, /* create per-dir config structures */
- NULL, /* merge per-dir config structures */
- create_skysql_config, /* create per-server config structures */
- NULL, /* merge per-server config structures */
- skysql_cmds, /* table of config file commands */
- skysql_register_hooks /* register hooks */
-};
-
-///////////////////////////////////////////////
diff --git a/protocol_1.0/modules.mk b/protocol_1.0/modules.mk
deleted file mode 100644
index db810d1dd..000000000
--- a/protocol_1.0/modules.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-mod_skysql.la: mod_skysql.slo skysql_utils.slo skysql_backend.slo
- $(SH_LINK) -rpath $(libexecdir) -module -avoid-version mod_skysql.lo skysql_utils.lo skysql_backend.lo
-DISTCLEAN_TARGETS = modules.mk
-shared = mod_skysql.la
diff --git a/protocol_1.0/skysql_backend.c b/protocol_1.0/skysql_backend.c
deleted file mode 100644
index e5a1f55f0..000000000
--- a/protocol_1.0/skysql_backend.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
-This file is distributed as part of the SkySQL Gateway. It is free
-software: you can redistribute it and/or modify it under the terms of the
-GNU General Public License as published by the Free Software Foundation,
-version 2.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 51
-Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Copyright SkySQL Ab
-
-*/
-
-////////////////////////////////////////
-// SKYSQL Backend
-// By Massimiliano Pinto 2012/2013
-////////////////////////////////////////
-
-#include "skysql_gw.h"
-
-int skysql_ext_file_ver(void) {
- int ret = 13;
- return ret;
-}
-
-//////////////////////////////////////////////////////////////
-// The function takes the server list,
-// find the total server number
-// and return a random selection for slaves (from total -1)
-//////////////////////////////////////////////////////////////
-int select_random_slave_server(const char *server_list, int *num_slaves) {
- int nslaves = 0;
- int random_balancer = 0;
- char *p = (char *)server_list;
- while( (p = strchr(p, ',')) != NULL) {
- p++;
- nslaves++;
- }
-
- memcpy(num_slaves, &nslaves, sizeof(int));
-
- if (nslaves == 1) {
- return 1;
- }
-
- // random selection
- random_balancer = (int) ((nslaves+1) * (rand() / (RAND_MAX + 1.0)));
-
- return random_balancer;
-}
-
-///////////////////////////////////////////////////////////////
-// This takes a server from the list
-// index 0 is always the Master
-// the others refer to the salve,
-// the slave number comes from: select_random_slave_server()
-///////////////////////////////////////////////////////////////
-int get_server_from_list(char **selected_host, int *selected_port, char *server_list, int num, apr_pool_t *p) {
- int ret = -1;
- int curr_srv = 0;
- char *next = NULL;
- char *tmp = NULL;
- int port;
-
- if (num == 0) {
- port = atoi(strchr(server_list, ':') + 1), sizeof(port);
- memcpy(selected_port, &port, sizeof(int));
- *selected_host = apr_pstrndup(p, server_list, strchr(server_list, ':') - server_list);
-
- return 1;
- }
-
- next = server_list;
-
- while (curr_srv < num) {
-
- tmp = strchr(next, ',');
- if (tmp != NULL) {
- curr_srv++;
- next = tmp+1;
- } else {
- return -1;
- }
-
- if (curr_srv == num) {
- port = atoi(strchr(next, ':') + 1);
-
- memcpy(selected_port, &port, sizeof(port));
-
- // the host string must be allocated in the memory pool!
- *selected_host = apr_pstrndup(p, next, strchr(next, ':') - next);
- ret = 0;
-
- break;
- }
- }
-
- return ret;
-}
-
-
-//////////////////////////////////////////////
-// This funcion take the master from the list
-// The index is always 0
-//////////////////////////////////////////////
-int get_master_from_list(char **selected_host, int *selected_port, char *server_list, apr_pool_t *p) {
- int ret = -1;
- int curr_srv = 0;
- char *next = NULL;
- char *tmp = NULL;
- int port;
-
- port = atoi(strchr(server_list, ':') + 1), sizeof(port);
- memcpy(selected_port, &port, sizeof(int));
-
- // the host string must be allocated in the memory pool!
- *selected_host = apr_pstrndup(p, server_list, strchr(server_list, ':') - server_list);
-
- return 1;
-}
-
-///////////////////////////////////////
-// Query Routing basic implementation
-///////////////////////////////////////
-
-int query_routing(const char *server_list, const char *sql_command, int procotol_command, int current_slave) {
-
- if (strstr(sql_command, "select ")) {
- // to the slave
- return SKYSQL_READ;
- } else {
- // to the master
- return SKYSQL_WRITE;
- }
-}
-
-//////////////////
diff --git a/protocol_1.0/skysql_client.h b/protocol_1.0/skysql_client.h
deleted file mode 100644
index b6eaa36cb..000000000
--- a/protocol_1.0/skysql_client.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
-This file is distributed as part of the SkySQL Gateway. It is free
-software: you can redistribute it and/or modify it under the terms of the
-GNU General Public License as published by the Free Software Foundation,
-version 2.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 51
-Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Copyright SkySQL Ab
-
-*/
-
-////////////////////////////////////////
-// SKYSQL mysql protocol header file
-// By Massimiliano Pinto 2012/2013
-////////////////////////////////////////
-
-#include "ap_config.h"
-#include "ap_mmn.h"
-#include "httpd.h"
-#include "http_core.h"
-#include "http_main.h"
-#include "http_config.h"
-#include "http_connection.h"
-#include "http_request.h"
-#include "http_log.h"
-#include "http_protocol.h"
-#include "ap_config_auto.h"
-#include "http_connection.h"
-
-#include "util_filter.h"
-#include "util_script.h"
-#include "apr.h"
-#include "apr_general.h"
-#include "apr_buckets.h"
-#include "apr_optional.h"
-#include "apr_strings.h"
-#include "apr_tables.h"
-#include "apr_lib.h"
-#include "apr_fnmatch.h"
-#include "apr_strings.h"
-#include "apr_dbm.h"
-#include "apr_rmm.h"
-#include "apr_shm.h"
-#include "apr_global_mutex.h"
-#include "apr_time.h"
-#include "scoreboard.h"
-
-// sha1
-#include "apr_sha1.h"
-
-// getpid
-#include
-
-
-/* Protocol packing macros. */
-#define skysql_set_byte2(__buffer, __int) do { \
- (__buffer)[0]= (uint8_t)((__int) & 0xFF); \
- (__buffer)[1]= (uint8_t)(((__int) >> 8) & 0xFF); } while (0)
-#define skysql_set_byte3(__buffer, __int) do { \
- (__buffer)[0]= (uint8_t)((__int) & 0xFF); \
- (__buffer)[1]= (uint8_t)(((__int) >> 8) & 0xFF); \
- (__buffer)[2]= (uint8_t)(((__int) >> 16) & 0xFF); } while (0)
-#define skysql_set_byte4(__buffer, __int) do { \
- (__buffer)[0]= (uint8_t)((__int) & 0xFF); \
- (__buffer)[1]= (uint8_t)(((__int) >> 8) & 0xFF); \
- (__buffer)[2]= (uint8_t)(((__int) >> 16) & 0xFF); \
- (__buffer)[3]= (uint8_t)(((__int) >> 24) & 0xFF); } while (0)
-
-
-/* Protocol unpacking macros. */
-#define skysql_get_byte2(__buffer) \
- (uint16_t)((__buffer)[0] | \
- ((__buffer)[1] << 8))
-#define skysql_get_byte3(__buffer) \
- (uint32_t)((__buffer)[0] | \
- ((__buffer)[1] << 8) | \
- ((__buffer)[2] << 16))
-#define skysql_get_byte4(__buffer) \
- (uint32_t)((__buffer)[0] | \
- ((__buffer)[1] << 8) | \
- ((__buffer)[2] << 16) | \
- ((__buffer)[3] << 24))
-#define skysql_get_byte8(__buffer) \
- ((uint64_t)(__buffer)[0] | \
- ((uint64_t)(__buffer)[1] << 8) | \
- ((uint64_t)(__buffer)[2] << 16) | \
- ((uint64_t)(__buffer)[3] << 24) | \
- ((uint64_t)(__buffer)[4] << 32) | \
- ((uint64_t)(__buffer)[5] << 40) | \
- ((uint64_t)(__buffer)[6] << 48) | \
- ((uint64_t)(__buffer)[7] << 56))
-
-typedef enum
-{
- SKYSQL_CAPABILITIES_NONE= 0,
- SKYSQL_CAPABILITIES_LONG_PASSWORD= (1 << 0),
- SKYSQL_CAPABILITIES_FOUND_ROWS= (1 << 1),
- SKYSQL_CAPABILITIES_LONG_FLAG= (1 << 2),
- SKYSQL_CAPABILITIES_CONNECT_WITH_DB= (1 << 3),
- SKYSQL_CAPABILITIES_NO_SCHEMA= (1 << 4),
- SKYSQL_CAPABILITIES_COMPRESS= (1 << 5),
- SKYSQL_CAPABILITIES_ODBC= (1 << 6),
- SKYSQL_CAPABILITIES_LOCAL_FILES= (1 << 7),
- SKYSQL_CAPABILITIES_IGNORE_SPACE= (1 << 8),
- SKYSQL_CAPABILITIES_PROTOCOL_41= (1 << 9),
- SKYSQL_CAPABILITIES_INTERACTIVE= (1 << 10),
- SKYSQL_CAPABILITIES_SSL= (1 << 11),
- SKYSQL_CAPABILITIES_IGNORE_SIGPIPE= (1 << 12),
- SKYSQL_CAPABILITIES_TRANSACTIONS= (1 << 13),
- SKYSQL_CAPABILITIES_RESERVED= (1 << 14),
- SKYSQL_CAPABILITIES_SECURE_CONNECTION= (1 << 15),
- SKYSQL_CAPABILITIES_MULTI_STATEMENTS= (1 << 16),
- SKYSQL_CAPABILITIES_MULTI_RESULTS= (1 << 17),
- SKYSQL_CAPABILITIES_PS_MULTI_RESULTS= (1 << 18),
- SKYSQL_CAPABILITIES_PLUGIN_AUTH= (1 << 19),
- SKYSQL_CAPABILITIES_SSL_VERIFY_SERVER_CERT= (1 << 30),
- SKYSQL_CAPABILITIES_REMEMBER_OPTIONS= (1 << 31),
- SKYSQL_CAPABILITIES_CLIENT= (SKYSQL_CAPABILITIES_LONG_PASSWORD |
- SKYSQL_CAPABILITIES_FOUND_ROWS |
- SKYSQL_CAPABILITIES_LONG_FLAG |
- SKYSQL_CAPABILITIES_CONNECT_WITH_DB |
- SKYSQL_CAPABILITIES_LOCAL_FILES |
- SKYSQL_CAPABILITIES_PLUGIN_AUTH |
- SKYSQL_CAPABILITIES_TRANSACTIONS |
- SKYSQL_CAPABILITIES_PROTOCOL_41 |
- SKYSQL_CAPABILITIES_MULTI_STATEMENTS |
- SKYSQL_CAPABILITIES_MULTI_RESULTS |
- SKYSQL_CAPABILITIES_PS_MULTI_RESULTS |
- SKYSQL_CAPABILITIES_SECURE_CONNECTION),
- SKYSQL_CAPABILITIES_CLIENT_COMPRESS= (SKYSQL_CAPABILITIES_LONG_PASSWORD |
- SKYSQL_CAPABILITIES_FOUND_ROWS |
- SKYSQL_CAPABILITIES_LONG_FLAG |
- SKYSQL_CAPABILITIES_CONNECT_WITH_DB |
- SKYSQL_CAPABILITIES_LOCAL_FILES |
- SKYSQL_CAPABILITIES_PLUGIN_AUTH |
- SKYSQL_CAPABILITIES_TRANSACTIONS |
- SKYSQL_CAPABILITIES_PROTOCOL_41 |
- SKYSQL_CAPABILITIES_MULTI_STATEMENTS |
- SKYSQL_CAPABILITIES_MULTI_RESULTS |
- SKYSQL_CAPABILITIES_PS_MULTI_RESULTS |
- SKYSQL_CAPABILITIES_COMPRESS
- ),
-} skysql_capabilities_t;
-
-
-#define SMALL_CHUNK 1024
-#define MAX_CHUNK SMALL_CHUNK * 8 * 4
-#define ToHex(Y) (Y>='0'&&Y<='9'?Y-'0':Y-'A'+10)
-
-#define MYSQL_CONN_DEBUG
-#undef MYSQL_CONN_DEBUG
-
-typedef struct {
- apr_socket_t *socket;
- char scramble[33];
- uint32_t server_capabs;
- uint32_t client_capabs;
- unsigned long tid;
- apr_pool_t *pool;
-} MYSQL_conn;
-
diff --git a/protocol_1.0/skysql_gw.h b/protocol_1.0/skysql_gw.h
deleted file mode 100644
index c45eef3ed..000000000
--- a/protocol_1.0/skysql_gw.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
-This file is distributed as part of the SkySQL Gateway. It is free
-software: you can redistribute it and/or modify it under the terms of the
-GNU General Public License as published by the Free Software Foundation,
-version 2.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 51
-Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Copyright SkySQL Ab
-
-*/
-
-////////////////////////////////////////
-// SKYSQL header file
-// By Massimiliano Pinto 2012/2013
-////////////////////////////////////////
-
-#include "ap_config.h"
-#include "ap_mmn.h"
-#include "httpd.h"
-#include "http_core.h"
-#include "http_main.h"
-#include "http_config.h"
-#include "http_connection.h"
-#include "http_request.h"
-#include "http_log.h"
-#include "http_protocol.h"
-#include "ap_config_auto.h"
-#include "http_connection.h"
-
-#include "util_filter.h"
-#include "util_script.h"
-#include "apr.h"
-#include "apr_general.h"
-#include "apr_buckets.h"
-#include "apr_optional.h"
-#include "apr_strings.h"
-#include "apr_tables.h"
-#include "apr_lib.h"
-#include "apr_fnmatch.h"
-#include "apr_strings.h"
-#include "apr_dbm.h"
-#include "apr_rmm.h"
-#include "apr_shm.h"
-#include "apr_global_mutex.h"
-#include "apr_time.h"
-#include "scoreboard.h"
-
-// getpid
-#include
-
-// mapped I/O
-#include
-
-#include "skysql_client.h"
-
-#define SKYSQL_GATEWAY_VERSION "0.0.1"
-#define SKYSQL_VERSION "5.5.22-SKY-1.6.5"
-
-#define SKYSQL_READ 0
-#define SKYSQL_WRITE 1
-
-#define HTTP_WELCOME_MESSAGE "HTTP/1.1 200 OK\r\nConnection: Keep-Alive\r\nContent-Type: text/plain\r\n\r\nSKYSQL Gateway " SKYSQL_GATEWAY_VERSION
-
-#define SKYSQL_LISTENER_VERSION "MySQL Community Server (GPL)"
-#define SKYSQL_PROTOCOL_VERSION 10 // version is 10
-#define SKYSQL_THREAD_ID 11
-#define SKYSQL_HANDSKAKE_FILLER 0x00
-#define SKYSQL_SERVER_CAPABILITIES_BYTE1 0xff
-#define SKYSQL_SERVER_CAPABILITIES_BYTE2 0xf7
-#define SKYSQL_SERVER_LANGUAGE 0x08
-
-module AP_MODULE_DECLARE_DATA skysql_module;
-
-static unsigned char *config_area=NULL;
-
-//const int SKY_SQL_MAX_PACKET_LEN = 0xffffffL;
-
-typedef struct {
- MYSQL_conn *conn;
- unsigned long mysql_tid;
- unsigned long gateway_id;
- int protocol_enabled;
- int pool_enabled;
- char backend_servers[2][128];
- char *server_list;
- apr_hash_t *resources;
- int loop_timeout;
-} skysql_server_conf;
-
-typedef struct
-{
- char *name;
- char *raw_config;
- char *server_list;
- int r_port;
- char *dbname;
- char *defaults;
- int nshards;
-} conn_details;
-
-typedef struct {
- char *driver_name;
- char *username;
- char *password;
- char *database;
- void *driver_details;
-} skysql_client_auth;
-
-typedef struct {
- uint8_t client_flags[4];
- uint8_t max_packet_size[4];
- uint8_t charset;
- uint8_t scramble_buff;
- int connect_with_db;
- int compress;
-} mysql_driver_details;
-
-typedef struct {
- int num;
- char *list;
-} backend_list;
-
-int skysql_ext_file_ver();
-int skysql_query_is_select(const char *query);
-apr_status_t skysql_read_client_autentication(conn_rec *c, apr_pool_t *pool, uint8_t *scramble, int scramble_len, skysql_client_auth *mysql_client_data, uint8_t *stage1_hash);
-apr_status_t skysql_send_handshake(conn_rec *c, uint8_t *scramble, int *scramble_len);
-apr_status_t skysql_send_error (conn_rec *c, uint8_t packet_number, MYSQL_conn *conn);
-//apr_status_t skysql_prepare_ok(conn_rec *c, uint8_t packet_number, MYSQL_STMT *statement, MYSQL_conn *conn);
-apr_status_t skysql_send_ok(conn_rec *c, apr_pool_t *p, uint8_t packet_number, uint8_t in_affected_rows, const char* skysql_message);
-apr_status_t skysql_send_eof(conn_rec *c, apr_pool_t *p, uint8_t packet_number);
-apr_status_t skysql_send_result(conn_rec *c, uint8_t *data, uint8_t len);
-int select_random_slave_server(const char *server_listi, int *num_slaves);
-apr_status_t gateway_send_error (conn_rec *c, apr_pool_t *p, uint8_t packet_number);
-apr_status_t gateway_reply_data(conn_rec *c, apr_pool_t *pool, void *data, int len);
-char *gateway_find_user_password_sha1(char *username, void *repository, conn_rec *c, apr_pool_t *p);
-void skysql_sha1_str(const uint8_t *in, int in_len, uint8_t *out);
-int skygateway_query_result(conn_rec *c, apr_pool_t *p, MYSQL_conn *conn, const char *query);
-char *bin2hex(char *out, const uint8_t *in, unsigned int len);
-void skysql_sha1_2_str(const uint8_t *in, int in_len, const uint8_t *in2, int in2_len, uint8_t *out);
-void skysql_str_xor(char *output, const uint8_t *input1, const uint8_t *input2, unsigned int len);
-int get_server_from_list(char **selected_host, int *selected_port, char *server_list, int num, apr_pool_t *p);
-int get_master_from_list(char **selected_host, int *selected_port, char *server_list, apr_pool_t *p);
-int mysql_pass_packet(MYSQL_conn *conn, const char *command, int len);
-int mysql_receive_packet(conn_rec *c, apr_pool_t *p, MYSQL_conn *conn);
-int skygateway_statement_prepare_result(conn_rec *c, apr_pool_t *p, MYSQL_conn *conn, const char *query, int len);
-int skygateway_statement_execute_result(conn_rec *c, apr_pool_t *p, MYSQL_conn *conn, const char *query, int len);
-int mysql_send_command(MYSQL_conn *conn, const char *command, int cmd, int len);
-apr_status_t skysql_change_user(conn_rec *c, apr_pool_t *p, char *username, char *database, MYSQL_conn *conn, uint8_t *stage1_hash);
-int query_routing(const char *server_list, const char *sql_command, int procotol_command, int current_slave);
-unsigned int mysql_errno(MYSQL_conn *mysql);
-const char *mysql_error(MYSQL_conn *mysql);
-const char *mysql_sqlstate(MYSQL_conn *mysql);
-int mysql_query(MYSQL_conn *conn, const char *query);
diff --git a/protocol_1.0/skysql_utils.c b/protocol_1.0/skysql_utils.c
deleted file mode 100644
index 929fcb06b..000000000
--- a/protocol_1.0/skysql_utils.c
+++ /dev/null
@@ -1,1377 +0,0 @@
-/*
-This file is distributed as part of the SkySQL Gateway. It is free
-software: you can redistribute it and/or modify it under the terms of the
-GNU General Public License as published by the Free Software Foundation,
-version 2.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 51
-Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Copyright SkySQL Ab
-
-*/
-
-////////////////////////////////////////
-// SKYSQL Utils
-// By Massimiliano Pinto 2012/2013
-////////////////////////////////////////
-
-#include "skysql_gw.h"
-#include "apr_sha1.h"
-#include "apr_general.h"
-
-#define MYSQL_PROTOCOL_VERSION41_CHAR '*'
-
-#define char_val(X) (X >= '0' && X <= '9' ? X-'0' :\
- X >= 'A' && X <= 'Z' ? X-'A'+10 :\
- X >= 'a' && X <= 'z' ? X-'a'+10 :\
- '\177')
-
-char hex_upper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-char hex_lower[] = "0123456789abcdefghijklmnopqrstuvwxyz";
-
-/////////////////////////////////
-// binary data to hex string
-// output must be pre allocated
-/////////////////////////////////
-char *bin2hex(char *out, const uint8_t *in, unsigned int len) {
- const uint8_t *in_end= in + len;
- if (len == 0 || in == NULL) {
- return NULL;
- }
-
- for (; in != in_end; ++in) {
- *out++= hex_upper[((uint8_t) *in) >> 4];
- *out++= hex_upper[((uint8_t) *in) & 0x0F];
- }
- *out= '\0';
-
- return out;
-}
-
-/////////////////////////////////
-// hex string to binary data
-// output must be pre allocated
-/////////////////////////////////
-int hex2bin(uint8_t *out, const char *in, unsigned int len) {
- const char *in_end= in + len;
-
- if (len == 0 || in == NULL) {
- return 1;
- }
-
- while (in < in_end) {
- register char tmp_ptr = char_val(*in++);
- *out++= (tmp_ptr << 4) | char_val(*in++);
- }
-
- return 0;
-}
-
-/////////////////////////////////
-// general random string
-// output must be pre allocated
-/////////////////////////////////
-void skysql_set_random_str(uint8_t *output, unsigned int length) {
- uint8_t *ptr = output;
- apr_status_t rv = apr_generate_random_bytes(output, length);
-
- // this is for debug, the same scramble for every handshake
- //strcpy(output, "12345678abcdefjhilmn");
-}
-
-/////////////////////////////////////////////////////////////
-// fill a 20 bytes preallocated with SHA1 digest (160 bits)
-// for one input on in_len bytes
-/////////////////////////////////////////////////////////////
-void skysql_sha1_str(const uint8_t *in, int in_len, uint8_t *out) {
- int l;
- apr_sha1_ctx_t context;
- apr_byte_t digest[APR_SHA1_DIGESTSIZE];
-
- apr_sha1_init(&context);
- apr_sha1_update(&context, in, in_len);
- apr_sha1_final(digest, &context);
-
- memcpy(out, digest, APR_SHA1_DIGESTSIZE);
-}
-
-/////////////////////////////////////////////////////////////
-// fill 20 bytes preallocated with SHA1 digest (160 bits)
-// for two inputs, in_len and in2_len bytes
-/////////////////////////////////////////////////////////////
-void skysql_sha1_2_str(const uint8_t *in, int in_len, const uint8_t *in2, int in2_len, uint8_t *out) {
- int l;
- apr_sha1_ctx_t context;
- apr_byte_t digest[APR_SHA1_DIGESTSIZE];
-
- apr_sha1_init(&context);
- apr_sha1_update(&context, in, in_len);
- apr_sha1_update(&context, in2, in2_len);
- apr_sha1_final(digest, &context);
-
- memcpy(out, digest, APR_SHA1_DIGESTSIZE);
-}
-
-///////////////////////////////////////////////////////
-// fill a preallocated buffer with XOR(str1, str2)
-// XOR between 2 equal len strings
-// note that XOR(str1, XOR(str1 CONCAT str2)) == str2
-// and that XOR(str1, str2) == XOR(str2, str1)
-///////////////////////////////////////////////////////
-
-void skysql_str_xor(char *output, const uint8_t *input1, const uint8_t *input2, unsigned int len) {
- const uint8_t *input1_end = NULL;
- input1_end = input1 + len;
- while (input1 < input1_end)
- *output++= *input1++ ^ *input2++;
-
- *output = '\0';
-}
-
-//////////////////////////////////////////
-// get skygateway password from username
-// output is SHA1(SHA1(password))
-//////////////////////////////////////////
-
-char *gateway_find_user_password_sha1(char *username, void *repository, conn_rec *c, apr_pool_t *p) {
-
- uint8_t hash1[APR_SHA1_DIGESTSIZE];
- uint8_t hash2[APR_SHA1_DIGESTSIZE];
-
- skysql_sha1_str(username, strlen(username), hash1);
- skysql_sha1_str(hash1, APR_SHA1_DIGESTSIZE, hash2);
-
- return apr_pstrmemdup(p, hash2, APR_SHA1_DIGESTSIZE);
-}
-
-/////////////////////////////////////////////
-// get the SHA1(SHA1(password)) from client
-/////////////////////////////////////////////
-
-int skysql_check_scramble(conn_rec *c, apr_pool_t *p, uint8_t *token, unsigned int token_len, uint8_t *scramble, unsigned int scramble_len, char *username, uint8_t *stage1_hash) {
- uint8_t step1[APR_SHA1_DIGESTSIZE];
- uint8_t step2[APR_SHA1_DIGESTSIZE +1];
- uint8_t check_hash[APR_SHA1_DIGESTSIZE];
- char hex_double_sha1[2 * APR_SHA1_DIGESTSIZE + 1]="";
-
- uint8_t *password = gateway_find_user_password_sha1(username, NULL, c, p);
-
- bin2hex(hex_double_sha1, password, APR_SHA1_DIGESTSIZE);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "The Gateway stored hex(SHA1(SHA1(password))) for \"%s\" [%s]", username, hex_double_sha1);
-
- // possible, now skipped
- /*
- if (password == NULL) {
- ??????
- }
- */
-
- // step 1
- skysql_sha1_2_str(scramble, scramble_len, password, APR_SHA1_DIGESTSIZE, step1);
-
- //step2
- skysql_str_xor(step2, token, step1, token_len);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "skygateway SHA1(password) [%s]", step2);
- memcpy(stage1_hash, step2, 20);
-
- skysql_sha1_str(step2, APR_SHA1_DIGESTSIZE, check_hash);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SHA1 di SHA1(client password) [%s]", check_hash);
-
- if (1) {
- char inpass[100]="";
- bin2hex(inpass, check_hash, 20);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "The CLIENT hex(SHA1(SHA1(password))) for \"%s\" [%s]", username, inpass);
- }
-
- return memcmp(password, check_hash, APR_SHA1_DIGESTSIZE);
-}
-
-apr_status_t gateway_reply_data(conn_rec *c, apr_pool_t *pool, void *data, int len) {
- apr_status_t rv = APR_SUCCESS;
- apr_bucket_brigade *bb;
- apr_bucket_brigade *r_bb;
-
- // create brigade
- bb = apr_brigade_create(pool, c->bucket_alloc);
-
- apr_brigade_write(bb, ap_filter_flush, c->output_filters, data, len);
- ap_fflush(c->output_filters, bb);
-
- apr_brigade_destroy(bb);
-
- return 1;
-}
-
-apr_status_t skysql_change_user(conn_rec *c, apr_pool_t *p, char *username, char *database, MYSQL_conn *conn, uint8_t *stage1_hash) {
- uint8_t skysql_payload_size = 0;
- uint8_t skysql_packet_header[4];
- uint8_t skysql_packet_id = 0;
- uint8_t change_user_command = 0x11;
- uint8_t *outbuf = NULL;
- uint8_t token[20 + 1]="";
- uint8_t charset[2]="";
- uint8_t backend_scramble[20 +1]="";
-
- int user_len = strlen(username);
- int database_len = strlen(database);
- uint8_t *password = NULL;
-
- uint8_t temp_token[20 +1] ="";
- uint8_t stage1_password[20 +1] ="";
- apr_status_t rv = -1;
- long bytes;
-
- //get password from repository
- password = gateway_find_user_password_sha1(username, NULL, c, p);
- memcpy(backend_scramble, conn->scramble, 20);
-
- skysql_sha1_2_str(backend_scramble, 20, password, 20, temp_token);
-
- *token = '\x14';
-
- charset[0]='\x08';
- charset[1]='\x00';
-
- skysql_str_xor(token+1, temp_token, stage1_hash, 20);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "skygateway TO backend scramble [%s]", backend_scramble);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "skygateway SHA1(password) [%s]", stage1_hash);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "skygateway internal password [%s]", password);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "skygateway SHA1(scramble + SHA1(stage1_hash)) [%s]", temp_token);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "skygateway TO backend token [%s]", token+1);
-
- //skysql_payload_size = 1 + user_len + 1 + sizeof(token) + database_len + 1 + sizeof(charset) + 1 + sizeof("mysql_native_password") + 1;
- skysql_payload_size = 1 + user_len + 1 + sizeof(token) + database_len + 1 + sizeof(charset);
-
- // allocate memory for packet header + payload
- outbuf = (uint8_t *) apr_pcalloc(p, sizeof(skysql_packet_header) + skysql_payload_size);
-
- // write packet header with packet number
- skysql_set_byte3(skysql_packet_header, skysql_payload_size);
- skysql_packet_header[3] = skysql_packet_id;
-
- memcpy(outbuf, skysql_packet_header, sizeof(skysql_packet_header));
- memcpy(outbuf + sizeof(skysql_packet_header), &change_user_command, 1);
- memcpy(outbuf + sizeof(skysql_packet_header) + 1, username, user_len);
- memcpy(outbuf + sizeof(skysql_packet_header) + 1 + strlen(username) + 1, token, 21);
- memcpy(outbuf + sizeof(skysql_packet_header) + 1 + strlen(username) + 1 + 21, database, database_len);
- memcpy(outbuf + sizeof(skysql_packet_header) + 1 + strlen(username) + 1 + 21 + database_len + 1, charset, sizeof(charset));
- //memcpy(outbuf + sizeof(skysql_packet_header) + 1 + strlen(username) + 1 + 21 + database_len + 1 + sizeof(charset) + 1, "mysql_native_password", strlen("mysql_native_password"));
-
- bytes = sizeof(skysql_packet_header) + skysql_payload_size;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "skysql_change_user is %li bytes", bytes);
- rv = apr_socket_send(conn->socket, outbuf, &bytes);
-}
-
-apr_status_t skysql_read_client_autentication(conn_rec *c, apr_pool_t *pool, uint8_t *scramble, int scramble_len, skysql_client_auth *mysql_client_data, uint8_t *stage1_hash) {
- apr_bucket_brigade *r_bb;
- apr_bucket *r_b;
- apr_status_t rv;
- int seen_eos = 0;
- int child_stopped_reading = 0;
- int i;
- apr_bucket *auth_bucket;
- apr_bucket *bucket;
- const char *client_auth_packet = NULL;
- unsigned int query_ret = 0;
- int return_data = 0;
- int input_read = 0;
- uint8_t client_flags[4];
- apr_pool_t *p = NULL;
- mysql_driver_details *mysql_driver = NULL;
-
- uint8_t *token = NULL;
- unsigned int token_len = 0;
- int auth_ret = 0;
-
- // use the passed pool?
- p = pool == NULL ? c->pool : pool;
-
- // now read the client authentication
- r_bb = apr_brigade_create(p, c->bucket_alloc);
-
- if (((rv = ap_get_brigade(c->input_filters, r_bb, AP_MODE_READBYTES, APR_BLOCK_READ, 8192)) != APR_SUCCESS) || APR_BRIGADE_EMPTY(r_bb)) {
- apr_brigade_destroy(r_bb);
- return input_read;
- }
-
- for (auth_bucket = APR_BRIGADE_FIRST(r_bb); bucket != APR_BRIGADE_SENTINEL(r_bb); bucket = APR_BUCKET_NEXT(auth_bucket)) {
- apr_size_t len;
- const char *data;
-
- if (APR_BUCKET_IS_EOS(auth_bucket)) {
- seen_eos = 1;
- break;
- }
-
- if (APR_BUCKET_IS_FLUSH(auth_bucket)) {
- continue;
- }
-
- if (child_stopped_reading) {
- break;
- }
-
- rv = apr_bucket_read(auth_bucket, &data, &len, APR_BLOCK_READ);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "Auth Data len [%i]", len);
-
- if (rv != APR_SUCCESS) {
- child_stopped_reading = 1;
- }
-
- client_auth_packet = apr_pstrmemdup(p, data, len);
- input_read = 1;
- }
-
- // this brigade is useless
- apr_brigade_destroy(r_bb);
-
- if (input_read && client_auth_packet) {
- // now fill data structure for client data in driver MYSQL5
- if (mysql_client_data != NULL) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "Now decode MYSQL client auth packet");
- mysql_driver = (mysql_driver_details *)mysql_client_data->driver_details;
- if (mysql_driver != NULL) {
- uint8_t hash_stage1[20 +1];
-/*
- uint8_t hash_stage1[20];
- uint8_t hash_stage2[20];
- uint8_t temp_token[20];
- uint8_t client_token[20];
- uint8_t check_auth[20];
- uint8_t final_hash[20];
-*/
-
- // todo: insert constant values instead of numbers
- memcpy(mysql_driver->client_flags, client_auth_packet + 4, 4);
- mysql_driver->connect_with_db = SKYSQL_CAPABILITIES_CONNECT_WITH_DB & skysql_get_byte4(mysql_driver->client_flags);
- mysql_driver->compress = SKYSQL_CAPABILITIES_COMPRESS & skysql_get_byte4(mysql_driver->client_flags);
- mysql_client_data->username = apr_pstrndup(p, client_auth_packet + 4 + 4 + 4 + 1 + 23, 128);
- memcpy(&token_len, client_auth_packet + 4 + 4 + 4 + 1 + 23 + strlen(mysql_client_data->username) + 1, 1);
-
- token = apr_pstrmemdup(p, client_auth_packet + 4 + 4 + 4 + 1 + 23 + strlen(mysql_client_data->username) + 1 + 1, token_len);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "[client TO gateway] current username is [%s], token is [%s] len %i", mysql_client_data->username, token, token_len);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "[gateway TO client] server scramble was [%s], len %i", scramble, scramble_len);
-
-/*
-
- skysql_sha1_str(mysql_client_data->username, strlen(mysql_client_data->username), hash_stage1);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SHA1 di '%s' [%s]", mysql_client_data->username, hash_stage1);
- skysql_sha1_str(hash_stage1, 20, hash_stage2);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SHA1 di SHA1('%s') [%s]", mysql_client_data->username, hash_stage2);
-
-
- skysql_sha1_2_str(scramble, scramble_len, hash_stage2, 20, temp_token);
- skysql_str_xor(check_auth, hash_stage1, temp_token, 20);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "This is the client input?? [%s]", check_auth);
-
- memset(temp_token, '\0', sizeof(temp_token));
- memcpy(client_token, scramble, scramble_len);
- memcpy(client_token + scramble_len, hash_stage2, 20);
- skysql_sha1_str(client_token, scramble_len, temp_token);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "This is the client input?? [%s]", temp_token);
-
-
- skysql_str_xor(check_auth, hash_stage2, hash_stage1, scramble_len);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "XOR( client token, stage2_hash) [%s]", check_auth);
- skysql_sha1_str(check_auth, 20, final_hash);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SHA1 di check_auth [%s]", final_hash);
-*/
- // decode the token and check the password
- auth_ret = skysql_check_scramble(c, p, token, token_len, scramble, scramble_len, mysql_client_data->username, stage1_hash);
-
- if (auth_ret == 0) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SkySQL Gateway Authentication OK for [%s]", mysql_client_data->username);
- } else {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "**** SkySQL Gateway Authentication ERROR [%s], retcode = [%i]", mysql_client_data->username, auth_ret);
- }
-
- if (mysql_driver->connect_with_db) {
- mysql_client_data->database = apr_pstrndup(p, client_auth_packet + 4 + 4 + 4 + 1 + 23 + strlen(mysql_client_data->username) + 1 + 1 + token_len, 128);
- }
-
- }
- }
- }
-
- return input_read;
-}
-
-apr_status_t gateway_send_error (conn_rec *c, apr_pool_t *p, uint8_t packet_number) {
- apr_status_t rv;
- rv = APR_SUCCESS;
- apr_bucket_brigade *bb;
- apr_bucket *b;
- uint8_t *outbuf = NULL;
- uint8_t skysql_payload_size = 0;
- uint8_t skysql_packet_header[4];
- uint8_t *skysql_payload = NULL;
- uint8_t field_count = 0;
- uint8_t affected_rows = 0;
- uint8_t insert_id = 0;
- uint8_t skysql_err[2];
- uint8_t skysql_statemsg[6];
-
- unsigned int skysql_errno = 0;
- const char *skysql_error_msg = NULL;
- const char *skysql_state = NULL;
-
- skysql_errno = 6969;
- skysql_error_msg = "Too many queries in one connection";
- skysql_state = "FA5D3";
-
- field_count = 0xff;
- skysql_set_byte2(skysql_err, skysql_errno);
- skysql_statemsg[0]='#';
- memcpy(skysql_statemsg+1, skysql_state, 5);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQL_Error: Errno [%u], ErrorMessage [%s], State [%s]", skysql_errno, skysql_error_msg, skysql_state);
-
- skysql_payload_size = sizeof(field_count) + sizeof(skysql_err) + sizeof(skysql_statemsg) + strlen(skysql_error_msg);
-
- // allocate memory for packet header + payload
- outbuf = (uint8_t *) apr_pcalloc(p, sizeof(skysql_packet_header) + skysql_payload_size);
-
- // write packet header with packet number
- skysql_set_byte3(skysql_packet_header, skysql_payload_size);
- skysql_packet_header[3] = packet_number;
-
- // write header
- memcpy(outbuf, skysql_packet_header, sizeof(skysql_packet_header));
-
- skysql_payload = outbuf + sizeof(skysql_packet_header);
-
- // write field
- memcpy(skysql_payload, &field_count, sizeof(field_count));
- skysql_payload = skysql_payload + sizeof(field_count);
-
- // write errno
- memcpy(skysql_payload, skysql_err, sizeof(skysql_err));
- skysql_payload = skysql_payload + sizeof(skysql_err);
-
- // write sqlstate
- memcpy(skysql_payload, skysql_statemsg, sizeof(skysql_statemsg));
- skysql_payload = skysql_payload + sizeof(skysql_statemsg);
-
- // write err messg
- memcpy(skysql_payload, skysql_error_msg, strlen(skysql_error_msg));
-
- // create brigade
- bb = apr_brigade_create(p, c->bucket_alloc);
- b = apr_bucket_pool_create(outbuf, sizeof(skysql_packet_header) + skysql_payload_size, p, c->bucket_alloc);
- APR_BRIGADE_INSERT_HEAD(bb, b);
- b = apr_bucket_flush_create(c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(bb, b);
-
- return ap_pass_brigade(c->output_filters, bb);
-}
-
-apr_status_t skysql_send_error (conn_rec *c, uint8_t packet_number, MYSQL_conn *conn) {
- apr_status_t rv;
- rv = APR_SUCCESS;
- apr_bucket_brigade *bb;
- apr_bucket *b;
- uint8_t *outbuf = NULL;
- uint8_t skysql_payload_size = 0;
- uint8_t skysql_packet_header[4];
- uint8_t *skysql_payload = NULL;
- uint8_t field_count = 0;
- uint8_t affected_rows = 0;
- uint8_t insert_id = 0;
- uint8_t skysql_err[2];
- uint8_t skysql_statemsg[6];
-
- unsigned int skysql_errno = 0;
- const char *skysql_error_msg = NULL;
- const char *skysql_state = NULL;
-
- skysql_errno = mysql_errno(conn);
- skysql_error_msg = mysql_error(conn);
- skysql_state = mysql_sqlstate(conn);
-
- field_count = 0xff;
- skysql_set_byte2(skysql_err, skysql_errno);
- skysql_statemsg[0]='#';
- memcpy(skysql_statemsg+1, skysql_state, 5);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQL_Error: Errno [%u], ErrorMessage [%s], State [%s]", skysql_errno, skysql_error_msg, skysql_state);
-
- skysql_payload_size = sizeof(field_count) + sizeof(skysql_err) + sizeof(skysql_statemsg) + strlen(skysql_error_msg);
-
- // allocate memory for packet header + payload
- outbuf = (uint8_t *) apr_pcalloc(c->pool, sizeof(skysql_packet_header) + skysql_payload_size);
-
- // write packet header with packet number
- skysql_set_byte3(skysql_packet_header, skysql_payload_size);
- skysql_packet_header[3] = packet_number;
-
- // write header
- memcpy(outbuf, skysql_packet_header, sizeof(skysql_packet_header));
-
- skysql_payload = outbuf + sizeof(skysql_packet_header);
-
- // write field
- memcpy(skysql_payload, &field_count, sizeof(field_count));
- skysql_payload = skysql_payload + sizeof(field_count);
-
- // write errno
- memcpy(skysql_payload, skysql_err, sizeof(skysql_err));
- skysql_payload = skysql_payload + sizeof(skysql_err);
-
- // write sqlstate
- memcpy(skysql_payload, skysql_statemsg, sizeof(skysql_statemsg));
- skysql_payload = skysql_payload + sizeof(skysql_statemsg);
-
- // write err messg
- memcpy(skysql_payload, skysql_error_msg, strlen(skysql_error_msg));
-
- // create brigade
- bb = apr_brigade_create(c->pool, c->bucket_alloc);
- b = apr_bucket_pool_create(outbuf, sizeof(skysql_packet_header) + skysql_payload_size, c->pool, c->bucket_alloc);
- APR_BRIGADE_INSERT_HEAD(bb, b);
- b = apr_bucket_flush_create(c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(bb, b);
-
- return ap_pass_brigade(c->output_filters, bb);
-}
-
-apr_status_t skysql_send_result(conn_rec *c, uint8_t *data, uint8_t len) {
- apr_status_t rv;
- rv = APR_SUCCESS;
- apr_bucket_brigade *bb;
- apr_bucket *b;
-
- // create brigade
- bb = apr_brigade_create(c->pool, c->bucket_alloc);
-
- // write
- apr_brigade_write(bb, ap_filter_flush, c->output_filters, data, len);
-
- //send & flush
- return ap_fflush(c->output_filters, bb);
-}
-
-apr_status_t skysql_send_eof(conn_rec *c, apr_pool_t *p, uint8_t packet_number) {
- apr_status_t rv;
- rv = APR_SUCCESS;
- apr_bucket_brigade *bb;
- apr_bucket *b;
- uint8_t *outbuf = NULL;
- uint8_t skysql_payload_size = 0;
- uint8_t skysql_packet_header[4];
- uint8_t *skysql_payload = NULL;
- uint8_t field_count = 0;
- uint8_t skysql_server_status[2];
- uint8_t skysql_warning_count[2];
-
- field_count = 0xfe;
-
- skysql_payload_size = sizeof(field_count) + sizeof(skysql_server_status) + sizeof(skysql_warning_count);
-
- // allocate memory for packet header + payload
- outbuf = (uint8_t *) apr_pcalloc(p, sizeof(skysql_packet_header) + skysql_payload_size);
-
- // write packet header with packet number
- skysql_set_byte3(skysql_packet_header, skysql_payload_size);
- skysql_packet_header[3] = packet_number;
-
- // write header
- memcpy(outbuf, skysql_packet_header, sizeof(skysql_packet_header));
-
- skysql_payload = outbuf + sizeof(skysql_packet_header);
-
- skysql_server_status[0] = 2;
- skysql_server_status[1] = 0;
- skysql_warning_count[0] = 0;
- skysql_warning_count[1] = 0;
-
- // write data
- memcpy(skysql_payload, &field_count, sizeof(field_count));
- skysql_payload = skysql_payload + sizeof(field_count);
-
- memcpy(skysql_payload, skysql_warning_count, sizeof(skysql_warning_count));
- skysql_payload = skysql_payload + sizeof(skysql_warning_count);
-
- memcpy(skysql_payload, skysql_server_status, sizeof(skysql_server_status));
- skysql_payload = skysql_payload + sizeof(skysql_server_status);
-
- // create brigade
- bb = apr_brigade_create(p, c->bucket_alloc);
- // write
- apr_brigade_write(bb, ap_filter_flush, c->output_filters, outbuf, sizeof(skysql_packet_header) + skysql_payload_size);
- //send & flush
- return ap_fflush(c->output_filters, bb);
-}
-
-apr_status_t skysql_send_ok(conn_rec *c, apr_pool_t *p, uint8_t packet_number, uint8_t in_affected_rows, const char* skysql_message) {
- apr_status_t rv;
- rv = APR_SUCCESS;
- apr_bucket_brigade *bb;
- apr_bucket *b;
- uint8_t *outbuf = NULL;
- uint8_t skysql_payload_size = 0;
- uint8_t skysql_packet_header[4];
- uint8_t *skysql_payload = NULL;
- uint8_t field_count = 0;
- uint8_t affected_rows = 0;
- uint8_t insert_id = 0;
- uint8_t skysql_server_status[2];
- uint8_t skysql_warning_count[2];
-
- affected_rows = in_affected_rows;
-
- skysql_payload_size = sizeof(field_count) + sizeof(affected_rows) + sizeof(insert_id) + sizeof(skysql_server_status) + sizeof(skysql_warning_count);
-
- if (skysql_message != NULL) {
- skysql_payload_size += strlen(skysql_message);
- }
-
- // allocate memory for packet header + payload
- outbuf = (uint8_t *) apr_pcalloc(p, sizeof(skysql_packet_header) + skysql_payload_size);
-
- // write packet header with packet number
- skysql_set_byte3(skysql_packet_header, skysql_payload_size);
- skysql_packet_header[3] = packet_number;
-
- // write header
- memcpy(outbuf, skysql_packet_header, sizeof(skysql_packet_header));
-
- skysql_payload = outbuf + sizeof(skysql_packet_header);
-
- skysql_server_status[0] = 2;
- skysql_server_status[1] = 0;
- skysql_warning_count[0] = 0;
- skysql_warning_count[1] = 0;
-
- // write data
- memcpy(skysql_payload, &field_count, sizeof(field_count));
- skysql_payload = skysql_payload + sizeof(field_count);
-
- memcpy(skysql_payload, &affected_rows, sizeof(affected_rows));
- skysql_payload = skysql_payload + sizeof(affected_rows);
-
- memcpy(skysql_payload, &insert_id, sizeof(insert_id));
- skysql_payload = skysql_payload + sizeof(insert_id);
-
- memcpy(skysql_payload, skysql_server_status, sizeof(skysql_server_status));
- skysql_payload = skysql_payload + sizeof(skysql_server_status);
-
- memcpy(skysql_payload, skysql_warning_count, sizeof(skysql_warning_count));
- skysql_payload = skysql_payload + sizeof(skysql_warning_count);
-
- if (skysql_message != NULL) {
- memcpy(skysql_payload, skysql_message, strlen(skysql_message));
- }
-
-
- // create brigade
- bb = apr_brigade_create(p, c->bucket_alloc);
-
-/*
- b = apr_bucket_pool_create(outbuf, sizeof(skysql_packet_header) + skysql_payload_size, c->pool, c->bucket_alloc);
- APR_BRIGADE_INSERT_HEAD(bb, b);
- b = apr_bucket_flush_create(c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(bb, b);
-
- return ap_pass_brigade(c->output_filters, bb);
-*/
- apr_brigade_write(bb, ap_filter_flush, c->output_filters, outbuf, sizeof(skysql_packet_header) + skysql_payload_size);
- ap_fflush(c->output_filters, bb);
-
- apr_brigade_destroy(bb);
-
- return 1;
-}
-
-///////////////////////////
-// scramble is 20 bytes and must be pre allocated
-apr_status_t skysql_send_handshake(conn_rec *c, uint8_t *scramble, int *scramble_len) {
- apr_status_t rv;
- rv = APR_SUCCESS;
- apr_bucket_brigade *bb;
- apr_bucket *b;
- apr_pool_t *p = c->pool;
-
- uint8_t *outbuf = NULL;
- uint8_t skysql_payload_size = 0;
- uint8_t skysql_packet_header[4];
- uint8_t skysql_packet_id = 0;
- uint8_t skysql_filler = SKYSQL_HANDSKAKE_FILLER;
- uint8_t skysql_protocol_version = SKYSQL_PROTOCOL_VERSION;
- uint8_t *skysql_handshake_payload = NULL;
- uint8_t skysql_thread_id[4];
- uint8_t skysql_scramble_buf[9] = "";
- uint8_t skysql_plugin_data[13] = "";
- uint8_t skysql_server_capabilities_one[2];
- uint8_t skysql_server_capabilities_two[2];
- uint8_t skysql_server_language = 8;
- uint8_t skysql_server_status[2];
- uint8_t skysql_scramble_len = 21;
- uint8_t skysql_filler_ten[10];
- uint8_t skysql_last_byte = 0x00;
-
- uint8_t scramble_buffer[20]="";
-
- skysql_set_random_str(scramble_buffer, 20);
-
- // set len to the caller
- memset(scramble_len, 20, 1);
-
- // copy back to the caller
- memcpy(scramble, scramble_buffer, 20);
-
- memset(&skysql_filler_ten, 0x00, sizeof(skysql_filler_ten));
-
- // thread id, now put the apache child PID, then a conversion map in memory is needed!
- skysql_set_byte4(skysql_thread_id, getpid());
-
- memcpy(skysql_scramble_buf, scramble_buffer, 8);
-
- memcpy(skysql_plugin_data, scramble_buffer + 8, 12);
-
- skysql_payload_size = sizeof(skysql_protocol_version) + (strlen(SKYSQL_VERSION) + 1) + sizeof(skysql_thread_id) + 8 + sizeof(skysql_filler) + sizeof(skysql_server_capabilities_one) + sizeof(skysql_server_language) + sizeof(skysql_server_status) + sizeof(skysql_server_capabilities_two) + sizeof(skysql_scramble_len) + sizeof(skysql_filler_ten) + 12 + sizeof(skysql_last_byte) + strlen("mysql_native_password") + sizeof(skysql_last_byte);
-
- // allocate memory for packet header + payload
- outbuf = (uint8_t *) apr_pcalloc(p, sizeof(skysql_packet_header) + skysql_payload_size);
-
- // write packet heder with skysql_payload_size
- skysql_set_byte3(skysql_packet_header, skysql_payload_size);
- //skysql_packet_header[0] = skysql_payload_size;
-
- // write packent number, now is 0
- skysql_packet_header[3]= skysql_packet_id;
- memcpy(outbuf, skysql_packet_header, sizeof(skysql_packet_header));
-
- // current buffer pointer
- skysql_handshake_payload = outbuf + sizeof(skysql_packet_header);
-
- // write protocol version
- memcpy(skysql_handshake_payload, &skysql_protocol_version, sizeof(skysql_protocol_version));
- skysql_handshake_payload = skysql_handshake_payload + sizeof(skysql_protocol_version);
-
- // write server version plus 0 filler
- strcpy(skysql_handshake_payload, SKYSQL_VERSION);
- skysql_handshake_payload = skysql_handshake_payload + strlen(SKYSQL_VERSION);
- *skysql_handshake_payload = 0x00;
- skysql_handshake_payload++;
-
- // write thread id
- memcpy(skysql_handshake_payload, skysql_thread_id, sizeof(skysql_thread_id));
- skysql_handshake_payload = skysql_handshake_payload + sizeof(skysql_thread_id);
-
- // write scramble buf
- memcpy(skysql_handshake_payload, skysql_scramble_buf, 8);
- skysql_handshake_payload = skysql_handshake_payload + 8;
- *skysql_handshake_payload = SKYSQL_HANDSKAKE_FILLER;
- skysql_handshake_payload++;
-
- // write server capabilities part one
- skysql_server_capabilities_one[0] = SKYSQL_SERVER_CAPABILITIES_BYTE1;
- skysql_server_capabilities_one[1] = SKYSQL_SERVER_CAPABILITIES_BYTE2;
-
- memcpy(skysql_handshake_payload, skysql_server_capabilities_one, sizeof(skysql_server_capabilities_one));
- skysql_handshake_payload = skysql_handshake_payload + sizeof(skysql_server_capabilities_one);
-
- // write server language
- memcpy(skysql_handshake_payload, &skysql_server_language, sizeof(skysql_server_language));
- skysql_handshake_payload = skysql_handshake_payload + sizeof(skysql_server_language);
-
- //write server status
- skysql_server_status[0] = 2;
- skysql_server_status[1] = 0;
- memcpy(skysql_handshake_payload, skysql_server_status, sizeof(skysql_server_status));
- skysql_handshake_payload = skysql_handshake_payload + sizeof(skysql_server_status);
-
- //write server capabilities part two
- skysql_server_capabilities_two[0] = 15;
- skysql_server_capabilities_two[1] = 128;
-
- //skysql_server_capabilities_two[0] & SKYSQL_CAPABILITIES_COMPRESS;
-
- memcpy(skysql_handshake_payload, skysql_server_capabilities_two, sizeof(skysql_server_capabilities_two));
- skysql_handshake_payload = skysql_handshake_payload + sizeof(skysql_server_capabilities_two);
-
- // write scramble_len
- memcpy(skysql_handshake_payload, &skysql_scramble_len, sizeof(skysql_scramble_len));
- skysql_handshake_payload = skysql_handshake_payload + sizeof(skysql_scramble_len);
-
- //write 10 filler
- memcpy(skysql_handshake_payload, skysql_filler_ten, sizeof(skysql_filler_ten));
- skysql_handshake_payload = skysql_handshake_payload + sizeof(skysql_filler_ten);
-
- // write plugin data
- memcpy(skysql_handshake_payload, skysql_plugin_data, 12);
- skysql_handshake_payload = skysql_handshake_payload + 12;
-
- //write last byte, 0
- *skysql_handshake_payload = 0x00;
- skysql_handshake_payload++;
-
- // to be understanded ????
- memcpy(skysql_handshake_payload, "mysql_native_password", strlen("mysql_native_password"));
- skysql_handshake_payload = skysql_handshake_payload + strlen("mysql_native_password");
-
- //write last byte, 0
- *skysql_handshake_payload = 0x00;
- skysql_handshake_payload++;
-
-
-
- // create brigade
- bb = apr_brigade_create(p, c->bucket_alloc);
-/*
- b = apr_bucket_pool_create(outbuf, sizeof(skysql_packet_header) + skysql_payload_size, p, c->bucket_alloc);
- APR_BRIGADE_INSERT_HEAD(bb, b);
- b = apr_bucket_flush_create(c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(bb, b);
-
- ap_pass_brigade(c->output_filters, bb);
- apr_brigade_destroy(bb);
-*/
- apr_brigade_write(bb, ap_filter_flush, c->output_filters, outbuf, sizeof(skysql_packet_header) + skysql_payload_size);
- ap_fflush(c->output_filters, bb);
-
- apr_brigade_destroy(bb);
-
- return 1;
-}
-
-int skygateway_query_result(conn_rec *c, apr_pool_t *p, MYSQL_conn *conn, const char *query) {
- int query_ret = 0;
- int num_fields = 0;
- int return_data = 0;
- uint8_t result_column_count = 0;
- uint8_t header_result_packet[4];
- apr_bucket_brigade *bb1;
- apr_bucket *b1;
- uint8_t *outbuf = NULL;
- apr_status_t rv;
- uint8_t buffer[MAX_CHUNK];
- unsigned long bytes = MAX_CHUNK;
- unsigned long tot_bytes = 0;
- int cycle=0;
- apr_pollset_t *pset;
- apr_pollfd_t pfd;
- apr_int32_t nsocks=1;
- apr_status_t poll_rv;
- int is_eof = 0;
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW is sending query to backend [%lu] ...", conn->tid);
-
- // send the query to the backend
- query_ret = mysql_query(conn, query);
-
- if (query_ret) {
- // send error, packet #1
- skysql_send_error(c, 1, conn);
-
- return 1;
- }
-
- //poll_rv = apr_pollset_create(&pset, 1, p, 0);
-
- //pfd.p = p;
- //pfd.desc_type = APR_POLL_SOCKET;
- //pfd.reqevents = APR_POLLIN;
- //pfd.rtnevents = APR_POLLIN;
- //pfd.desc.s = conn->socket;
- //pfd.client_data = NULL;
-
- //rv = apr_pollset_add(pset, &pfd);
-
- //rv = apr_socket_opt_set(conn->socket, APR_SO_NONBLOCK , 1);
-
- apr_socket_timeout_set(conn->socket, 100000000);
-
- // read query resut from backend
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW is receiving query result from backend ...");
-
- while(1) {
- char errmesg_p[1000]="";
- bytes=MAX_CHUNK;
-
- memset(buffer, '\0', MAX_CHUNK);
-
- //rv = apr_wait_for_io_or_timeout(NULL, conn->socket, 1);
- //fprintf(stderr, "wait socket recv %lu\n", bytes);
- //apr_strerror(rv, errmesg_p, sizeof(errmesg_p));
- //fprintf(stderr, "wait Errore in recv, rv is %i, [%s]\n", rv, errmesg_p);
- //fflush(stderr);
-
- //apr_socket_atreadeof(conn->socket, &is_eof);
-
- rv = apr_socket_recv(conn->socket, buffer, &bytes);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW received %lu bytes", bytes);
-
- if (rv) {
- if (APR_STATUS_IS_EAGAIN(rv)) {
- continue;
- }
- }
-
- tot_bytes += bytes;
-
- if (rv != APR_SUCCESS && rv != APR_EOF && rv != APR_EAGAIN) {
- char errmesg[1000]="";
- apr_strerror(rv, errmesg, sizeof(errmesg));
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive error %i, [%s]", rv, errmesg);
-
- return 1;
- }
-
- if (rv == APR_EOF && bytes == 0) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive error: EOF");
- }
-
- bb1 = apr_brigade_create(p, c->bucket_alloc);
-
- apr_brigade_write(bb1, ap_filter_flush, c->output_filters, buffer, bytes);
- ap_fflush(c->output_filters, bb1);
-
- apr_brigade_destroy(bb1);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive, brigade sent to the client with %li bytes", bytes);
-
- cycle++;
-
-
- if (bytes < MAX_CHUNK) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive: less bytes than buffer here, Query Result: total bytes %lu in %i", tot_bytes, cycle);
-
- return 0;
- }
-
- if (bytes == MAX_CHUNK) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive: ALL bytes in the buffer here, continue");
- }
-
- }
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive: Return from query result: total bytes %lu in %i", tot_bytes, cycle);
-
- return 0;
-}
-
-int skygateway_statement_prepare_result(conn_rec *c, apr_pool_t *p, MYSQL_conn *conn, const char *query, int len) {
- int query_ret = 0;
- int num_fields = 0;
- int return_data = 0;
- uint8_t result_column_count = 0;
- uint8_t header_result_packet[4];
- apr_bucket_brigade *bb1;
- apr_bucket *b1;
- uint8_t *outbuf = NULL;
- apr_status_t rv;
- uint8_t buffer[MAX_CHUNK];
- unsigned long bytes = MAX_CHUNK;
- unsigned long tot_bytes = 0;
- int cycle=0;
- apr_pollset_t *pset;
- apr_pollfd_t pfd;
- apr_int32_t nsocks=1;
- apr_status_t poll_rv;
- int is_eof = 0;
-
- query_ret = mysql_send_command(conn, query, 0x16, len);
-
- if (query_ret) {
- // send error, packet #1
- skysql_send_error(c, 1, conn);
-
- return 1;
- }
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW is sending result set ...");
-
- poll_rv = apr_pollset_create(&pset, 1, p, 0);
-
- pfd.p = p;
- pfd.desc_type = APR_POLL_SOCKET;
- pfd.reqevents = APR_POLLIN;
- pfd.rtnevents = APR_POLLIN;
- pfd.desc.s = conn->socket;
- pfd.client_data = NULL;
-
- //rv = apr_pollset_add(pset, &pfd);
-
- //rv = apr_socket_opt_set(conn->socket, APR_SO_NONBLOCK , 1);
-
- apr_socket_timeout_set(conn->socket, 100000000);
-
- while(1) {
- char errmesg_p[1000]="";
- bytes=MAX_CHUNK;
-
- memset(buffer, '\0', MAX_CHUNK);
-
- //rv = apr_wait_for_io_or_timeout(NULL, conn->socket, 1);
- //fprintf(stderr, "wait socket recv %lu\n", bytes);
- //apr_strerror(rv, errmesg_p, sizeof(errmesg_p));
- //fprintf(stderr, "wait Errore in recv, rv is %i, [%s]\n", rv, errmesg_p);
- //fflush(stderr);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW is receiving ...");
-
- //apr_socket_atreadeof(conn->socket, &is_eof);
-
- rv = apr_socket_recv(conn->socket, buffer, &bytes);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW received %lu bytes", bytes);
-
- if (rv) {
- if (APR_STATUS_IS_EAGAIN(rv)) {
- continue;
- }
- }
-
- tot_bytes += bytes;
-
- if (rv != APR_SUCCESS && rv != APR_EOF && rv != APR_EAGAIN) {
- char errmesg[1000]="";
- apr_strerror(rv, errmesg, sizeof(errmesg));
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive error %i, [%s]", rv, errmesg);
-
- return 1;
- }
-
- if (rv == APR_EOF && bytes == 0) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive error: EOF");
- }
-
- bb1 = apr_brigade_create(p, c->bucket_alloc);
-
- apr_brigade_write(bb1, ap_filter_flush, c->output_filters, buffer, bytes);
- ap_fflush(c->output_filters, bb1);
-
- apr_brigade_destroy(bb1);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive, brigade sent with %li bytes", bytes);
-
- cycle++;
-
-
- if (bytes < MAX_CHUNK) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive: less bytes than buffer here, Return from query result: total bytes %lu in %i", tot_bytes, cycle);
-
- return 0;
- }
-
- if (bytes == MAX_CHUNK) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive: ALL bytes in the buffer here, continue");
- }
-
- }
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive: Return from query result: total bytes %lu in %i", tot_bytes, cycle);
-
- return 0;
-}
-
-int skygateway_statement_execute_result(conn_rec *c, apr_pool_t *p, MYSQL_conn *conn, const char *query, int len) {
- int query_ret = 0;
- int num_fields = 0;
- int return_data = 0;
- uint8_t result_column_count = 0;
- uint8_t header_result_packet[4];
- apr_bucket_brigade *bb1;
- apr_bucket *b1;
- uint8_t *outbuf = NULL;
- apr_status_t rv;
- uint8_t buffer[MAX_CHUNK];
- unsigned long bytes = MAX_CHUNK;
- unsigned long tot_bytes = 0;
- int cycle=0;
- apr_pollset_t *pset;
- apr_pollfd_t pfd;
- apr_int32_t nsocks=1;
- apr_status_t poll_rv;
- int is_eof = 0;
-
- query_ret = mysql_send_command(conn, query, 0x17, len);
-
- if (query_ret) {
- // send error, packet #1
- skysql_send_error(c, 1, conn);
-
- return 1;
- }
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW is sending result set ...");
-
- poll_rv = apr_pollset_create(&pset, 1, p, 0);
-
- pfd.p = p;
- pfd.desc_type = APR_POLL_SOCKET;
- pfd.reqevents = APR_POLLIN;
- pfd.rtnevents = APR_POLLIN;
- pfd.desc.s = conn->socket;
- pfd.client_data = NULL;
-
- //rv = apr_pollset_add(pset, &pfd);
-
- //rv = apr_socket_opt_set(conn->socket, APR_SO_NONBLOCK , 1);
-
- apr_socket_timeout_set(conn->socket, 100000000);
-
- while(1) {
- char errmesg_p[1000]="";
- bytes=MAX_CHUNK;
-
- memset(buffer, '\0', MAX_CHUNK);
-
- //rv = apr_wait_for_io_or_timeout(NULL, conn->socket, 1);
- //fprintf(stderr, "wait socket recv %lu\n", bytes);
- //apr_strerror(rv, errmesg_p, sizeof(errmesg_p));
- //fprintf(stderr, "wait Errore in recv, rv is %i, [%s]\n", rv, errmesg_p);
- //fflush(stderr);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW is receiving ...");
-
- //apr_socket_atreadeof(conn->socket, &is_eof);
-
- rv = apr_socket_recv(conn->socket, buffer, &bytes);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW received %lu bytes", bytes);
-
- if (rv) {
- if (APR_STATUS_IS_EAGAIN(rv)) {
- continue;
- }
- }
-
- tot_bytes += bytes;
-
- if (rv != APR_SUCCESS && rv != APR_EOF && rv != APR_EAGAIN) {
- char errmesg[1000]="";
- apr_strerror(rv, errmesg, sizeof(errmesg));
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive error %i, [%s]", rv, errmesg);
-
- return 1;
- }
-
- if (rv == APR_EOF && bytes == 0) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive error: EOF");
- }
-
- bb1 = apr_brigade_create(p, c->bucket_alloc);
-
- apr_brigade_write(bb1, ap_filter_flush, c->output_filters, buffer, bytes);
- ap_fflush(c->output_filters, bb1);
-
- apr_brigade_destroy(bb1);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive, brigade sent with %li bytes", bytes);
-
- cycle++;
-
-
- if (bytes < MAX_CHUNK) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive: less bytes than buffer here, Return from query result: total bytes %lu in %i", tot_bytes, cycle);
-
- return 0;
- }
-
- if (bytes == MAX_CHUNK) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive: ALL bytes in the buffer here, continue");
- }
-
- }
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive: Return from query result: total bytes %lu in %i", tot_bytes, cycle);
-
- return 0;
-}
-
-int mysql_send_command(MYSQL_conn *conn, const char *command, int cmd, int len) {
- apr_status_t rv;
- //uint8_t *packet_buffer=NULL;
- uint8_t packet_buffer[SMALL_CHUNK];
- long bytes;
- int fd;
-
- //packet_buffer = (uint8_t *) calloc(1, 5 + len + 1);
- memset(&packet_buffer, '\0', sizeof(packet_buffer));
-
- packet_buffer[4]= cmd;
- memcpy(packet_buffer+5, command, len);
-
- skysql_set_byte3(packet_buffer, 1 + len);
-
- bytes = 4 + 1 + len;
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "THE COMMAND is [%s] len %i\n", command, bytes);
- fprintf(stderr, "THE COMMAND TID is [%lu]", conn->tid);
- fprintf(stderr, "THE COMMAND scramble is [%s]", conn->scramble);
- if (conn->socket == NULL) {
- fprintf(stderr, "***** THE COMMAND sock struct is NULL\n");
- }
- fwrite(packet_buffer, bytes, 1, stderr);
- fflush(stderr);
-#endif
- apr_os_sock_get(&fd,conn->socket);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "COMMAND Socket FD is %i\n", fd);
- fflush(stderr);
-#endif
-
- rv = apr_socket_send(conn->socket, packet_buffer, &bytes);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "COMMAND SENT [%x] [%s]\n", cmd, command);
- fflush(stderr);
-#endif
-
- if (rv != APR_SUCCESS) {
- return 1;
- }
-
- return 0;
-}
-
-
-int mysql_pass_packet(MYSQL_conn *conn, const char *command, int len) {
- apr_status_t rv;
- //uint8_t *packet_buffer=NULL;
- uint8_t packet_buffer[SMALL_CHUNK];
- long bytes;
- int fd;
-
- //packet_buffer = (uint8_t *) calloc(1, 5 + len + 1);
- memset(&packet_buffer, '\0', sizeof(packet_buffer));
-
- memcpy(packet_buffer, command, len);
-
- bytes = len;
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "THE COMMAND is [%s] len %i\n", command, bytes);
- fprintf(stderr, "THE COMMAND TID is [%lu]", conn->tid);
- fprintf(stderr, "THE COMMAND scramble is [%s]", conn->scramble);
- if (conn->socket == NULL) {
- fprintf(stderr, "***** THE COMMAND sock struct is NULL\n");
- }
- fwrite(packet_buffer, bytes, 1, stderr);
- fflush(stderr);
-#endif
- apr_os_sock_get(&fd,conn->socket);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "PACKET Socket FD is %i\n", fd);
- fflush(stderr);
-#endif
-
- rv = apr_socket_send(conn->socket, packet_buffer, &bytes);
-
-#ifdef MYSQL_CONN_DEBUG
- fprintf(stderr, "PACKET SENT [%s]\n", command);
- fflush(stderr);
-#endif
-
- if (rv != APR_SUCCESS) {
- return 1;
- }
-
- return 0;
-}
-
-int mysql_receive_packet(conn_rec *c, apr_pool_t *p, MYSQL_conn *conn) {
- apr_bucket_brigade *bb1;
- apr_bucket *b1;
- apr_status_t rv;
- uint8_t buffer[MAX_CHUNK];
- unsigned long bytes = MAX_CHUNK;
- unsigned long tot_bytes = 0;
- int cycle=0;
- int is_eof = 0;
- apr_socket_timeout_set(conn->socket, 100000000);
-
- while(1) {
- char errmesg_p[1000]="";
- bytes=MAX_CHUNK;
-
- memset(buffer, '\0', MAX_CHUNK);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW is receiving ...");
-
- rv = apr_socket_recv(conn->socket, buffer, &bytes);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW received %lu bytes", bytes);
-
- if (rv) {
- if (APR_STATUS_IS_EAGAIN(rv)) {
- continue;
- }
- }
-
- tot_bytes += bytes;
-
- if (rv != APR_SUCCESS && rv != APR_EOF && rv != APR_EAGAIN) {
- char errmesg[1000]="";
- apr_strerror(rv, errmesg, sizeof(errmesg));
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive error %i, [%s]", rv, errmesg);
-
- return 1;
- }
-
- if (rv == APR_EOF && bytes == 0) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive error: EOF");
- }
-
- bb1 = apr_brigade_create(p, c->bucket_alloc);
-
- apr_brigade_write(bb1, ap_filter_flush, c->output_filters, buffer, bytes);
- ap_fflush(c->output_filters, bb1);
-
- apr_brigade_destroy(bb1);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive, brigade sent with %li bytes", bytes);
-
- cycle++;
-
- if (bytes < MAX_CHUNK) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive: less bytes than buffer here, Return from query result: total bytes %lu in %i", tot_bytes, cycle);
-
- return 0;
- }
-
- if (bytes == MAX_CHUNK) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive: ALL bytes in the buffer here, continue");
- }
-
- }
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "SKYSQLGW receive: Return from query result: total bytes %lu in %i", tot_bytes, cycle);
-
- return 0;
-}
-
-
-backend_list select_backend_servers() {
- backend_list l;
-
- memset(&l, '\0', sizeof(backend_list));
-
- l.num = 2;
- l.list = "127.0.0.1:3307,127.0.0.1:3306,xxxx:11";
-
- return l;
-}