Added experimental (not completed) support for SSL client side

pull/1409/head
René Cannaò 8 years ago committed by Nikolaos Vyzas
parent 486e7c41f0
commit 52a1d8a8d9

@ -5,7 +5,9 @@
#include "cpp.h"
#define QUEUE_T_DEFAULT_SIZE 32768
//#define QUEUE_T_DEFAULT_SIZE 32768
#define QUEUE_T_DEFAULT_SIZE 8192
#define MY_SSL_BUFFER 8192
typedef struct _queue_t {
void *buffer;
@ -43,12 +45,16 @@ class MyDS_real_query {
}
};
enum sslstatus { SSLSTATUS_OK, SSLSTATUS_WANT_IO, SSLSTATUS_FAIL};
class MySQL_Data_Stream
{
private:
int array2buffer();
int buffer2array();
void generate_compressed_packet();
enum sslstatus do_ssl_handshake();
void queue_encrypted_bytes(const char *buf, size_t len);
public:
void * operator new(size_t);
void operator delete(void *);
@ -90,6 +96,10 @@ class MySQL_Data_Stream
MySQL_Session *sess; // pointer to the session using this data stream
MySQL_Backend *mybe; // if this is a connection to a mysql server, this points to a backend structure
SSL *ssl;
BIO *rbio_ssl;
BIO *wbio_ssl;
char *ssl_write_buf;
size_t ssl_write_len;
struct sockaddr *client_addr;
struct {

@ -37,6 +37,7 @@
#include <signal.h>
#include <errno.h>
#include <ctype.h>
#include <openssl/bio.h>
#include <openssl/sha.h>
#include <openssl/md5.h>
#include <openssl/ssl.h>

@ -1329,14 +1329,21 @@ bool MySQL_Protocol::process_pkt_handshake_response(unsigned char *pkt, unsigned
pkt += sizeof(uint32_t);
charset = *(uint8_t *)pkt;
// see bug #810
if ( (*myds)->encrypted == false ) { // client wants to use SSL
if (len == sizeof(mysql_hdr)+32) {
(*myds)->encrypted = true;
use_ssl = true;
return false;
}
}
if (charset==0) {
charset=mysql_thread___default_charset;
}
pkt += 24;
if (len==sizeof(mysql_hdr)+32) {
(*myds)->encrypted=true;
use_ssl=true;
} else {
// if (len==sizeof(mysql_hdr)+32) {
// (*myds)->encrypted=true;
// use_ssl=true;
// } else {
user = pkt;
pkt += strlen((char *)user) + 1;
@ -1412,20 +1419,21 @@ bool MySQL_Protocol::process_pkt_handshake_response(unsigned char *pkt, unsigned
// currently proxysql doesn't know any sha1_pass for that specific user, let's set it!
GloMyAuth->set_SHA1((char *)user, USERNAME_FRONTEND,reply);
}
if (userinfo->sha1_pass) free(userinfo->sha1_pass);
if (userinfo->sha1_pass)
free(userinfo->sha1_pass);
userinfo->sha1_pass=sha1_pass_hex(reply);
}
}
}
}
}
if (_ret_use_ssl==true) {
// if we reached here, use_ssl is false , but _ret_use_ssl is true
// it means that a client is required to use SSL , but it is not
ret=false;
}
}
proxy_debug(PROXY_DEBUG_MYSQL_PROTOCOL,1,"Handshake (%s auth) <user:\"%s\" pass:\"%s\" scramble:\"%s\" db:\"%s\" max_pkt:%u>, capabilities:%u char:%u, use_ssl:%s\n",
// if (_ret_use_ssl==true) {
// // if we reached here, use_ssl is false , but _ret_use_ssl is true
// // it means that a client is required to use SSL , but it is not
// ret=false;
// }
// }
proxy_debug(PROXY_DEBUG_MYSQL_PROTOCOL,1,"Handshake (%s auth) <user:\"%s\" pass:\"%s\" scramble:\"%s\" db:\"%s\" max_pkt:%u>, capabilities:%u char:%u, use_ssl:%s\n",
(capabilities & CLIENT_SECURE_CONNECTION ? "new" : "old"), user, password, pass, db, max_pkt, capabilities, charset, ((*myds)->encrypted ? "yes" : "no"));
assert(sess);
assert(sess->client_myds);

@ -1957,7 +1957,8 @@ __get_pkts_from_client:
handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE(&pkt, &wrong_pass);
break;
case STATE_SSL_INIT:
handler___status_CONNECTING_CLIENT___STATE_SSL_INIT(&pkt);
handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE(&pkt, &wrong_pass);
//handler___status_CONNECTING_CLIENT___STATE_SSL_INIT(&pkt);
break;
default:
proxy_error("Detected not valid state client state: %d\n", client_myds->DSS);
@ -3186,8 +3187,59 @@ void MySQL_Session::handler___status_CHANGING_USER_CLIENT___STATE_CLIENT_HANDSHA
}
void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE(PtrSize_t *pkt, bool *wrong_pass) {
bool is_encrypted = client_myds->encrypted;
bool handshake_response_return = client_myds->myprot.process_pkt_handshake_response((unsigned char *)pkt->ptr,pkt->size);
if (
(is_encrypted == false) && // the connection was encrypted
(handshake_response_return == false) && // the authentication didn't complete
(client_myds->encrypted == true) // client is asking for encryption
) {
// use SSL
client_myds->DSS=STATE_SSL_INIT;
client_myds->rbio_ssl = BIO_new(BIO_s_mem());
client_myds->wbio_ssl = BIO_new(BIO_s_mem());
client_myds->ssl=SSL_new(GloVars.global.ssl_ctx);
SSL_set_fd(client_myds->ssl, client_myds->fd);
SSL_set_accept_state(client_myds->ssl);
SSL_set_bio(client_myds->ssl, client_myds->rbio_ssl, client_myds->wbio_ssl);
/*
while (!SSL_is_init_finished(client_myds->ssl)) {
int ret = SSL_do_handshake(client_myds->ssl);
int ret2;
if (ret != 1) {
//ERR_print_errors_fp(stderr);
ret2 = SSL_get_error(client_myds->ssl, ret);
fprintf(stderr,"%d\n",ret2);
}
}
*/
// if (!SSL_is_init_finished(client_myds->ssl)) {
// int n = SSL_do_handshake(client_myds->ssl);
//
// }
//ioctl_FIONBIO(client_myds->fd,0);
// bool connected = false;
// while (connected) {
// if (!SSL_accept(client_myds->ssl)==-1) {
// if (SSL_do_handshake(client_myds->ssl)==-1) {
// ERR_print_errors_fp(stderr);
// } else {
// connected = true;
// }
// }
//ioctl_FIONBIO(client_myds->fd,1);
//int my_ssl_error;
//int n = SSL_accept(client_myds->ssl);
//my_ssl_error = SSL_get_error(client_mmyds->ssl);
return;
}
if (
(client_myds->myprot.process_pkt_handshake_response((unsigned char *)pkt->ptr,pkt->size)==true)
//(client_myds->myprot.process_pkt_handshake_response((unsigned char *)pkt->ptr,pkt->size)==true)
(handshake_response_return == true)
&&
(
//(default_hostgroup<0 && ( session_type == PROXYSQL_SESSION_ADMIN || session_type == PROXYSQL_SESSION_STATS || session_type == PROXYSQL_SESSION_SQLITE) )
@ -3213,7 +3265,7 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE(
}
}
l_free(pkt->size,pkt->ptr);
if (client_myds->encrypted==false) {
//if (client_myds->encrypted==false) {
if (client_myds->myconn->userinfo->schemaname==NULL) {
client_myds->myconn->userinfo->set_schemaname(default_schema,strlen(default_schema));
}
@ -3303,25 +3355,26 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE(
(strcmp(client_addr,(char *)"::1")==0)
) {
// we are good!
client_myds->myprot.generate_pkt_OK(true,NULL,NULL,2,0,0,0,0,NULL);
client_myds->myprot.generate_pkt_OK(true,NULL,NULL, (is_encrypted ? 3 : 2), 0,0,0,0,NULL);
status=WAITING_CLIENT_DATA;
client_myds->DSS=STATE_CLIENT_AUTH_OK;
} else {
char *a=(char *)"User '%s' can only connect locally";
char *b=(char *)malloc(strlen(a)+strlen(client_myds->myconn->userinfo->username));
sprintf(b,a,client_myds->myconn->userinfo->username);
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,2,1040,(char *)"42000", b);
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL, (is_encrypted ? 3 : 2), 1040,(char *)"42000", b);
free(b);
}
free(client_addr);
} else {
// we are good!
client_myds->myprot.generate_pkt_OK(true,NULL,NULL,2,0,0,0,0,NULL);
client_myds->myprot.generate_pkt_OK(true,NULL,NULL, (is_encrypted ? 3 : 2), 0,0,0,0,NULL);
status=WAITING_CLIENT_DATA;
client_myds->DSS=STATE_CLIENT_AUTH_OK;
}
}
} else {
// } else {
/*
// use SSL
client_myds->DSS=STATE_SSL_INIT;
client_myds->ssl=SSL_new(GloVars.global.ssl_ctx);
@ -3331,7 +3384,8 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE(
ERR_print_errors_fp(stderr);
}
ioctl_FIONBIO(client_myds->fd,1);
}
*/
// }
} else {
l_free(pkt->size,pkt->ptr);
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Wrong credentials for frontend: disconnecting\n");
@ -3365,18 +3419,19 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE(
} else {
client_addr = strdup((char *)"");
}
if (client_myds->encrypted == false) {
//if (client_myds->encrypted == false) {
char *_s=(char *)malloc(strlen(client_myds->myconn->userinfo->username)+100+strlen(client_addr));
sprintf(_s,"ProxySQL Error: Access denied for user '%s'@'%s' (using password: %s)", client_myds->myconn->userinfo->username, client_addr, (client_myds->myconn->userinfo->password ? "YES" : "NO"));
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,2,1045,(char *)"28000", _s);
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL, (is_encrypted ? 3 : 2), 1045,(char *)"28000", _s);
__sync_add_and_fetch(&MyHGM->status.client_connections_aborted,1);
free(_s);
client_myds->DSS=STATE_SLEEP;
}
//}
}
}
void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SSL_INIT(PtrSize_t *pkt) {
/*
if (client_myds->myprot.process_pkt_handshake_response((unsigned char *)pkt->ptr,pkt->size)==true) {
l_free(pkt->size,pkt->ptr);
client_myds->myprot.generate_pkt_OK(true,NULL,NULL,3,0,0,0,0,NULL);
@ -3389,6 +3444,7 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SSL_INIT(PtrSize_
perror("Hitting a not implemented feature: https://github.com/sysown/proxysql-0.2/issues/124");
assert(0);
}
*/
}

@ -72,6 +72,56 @@ static void __dump_pkt(const char *func, unsigned char *_ptr, unsigned int len)
//enum sslstatus { SSLSTATUS_OK, SSLSTATUS_WANT_IO, SSLSTATUS_FAIL};
static enum sslstatus get_sslstatus(SSL* ssl, int n)
{
int err = SSL_get_error(ssl, n);
switch (err) {
case SSL_ERROR_NONE:
return SSLSTATUS_OK;
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_READ:
return SSLSTATUS_WANT_IO;
case SSL_ERROR_ZERO_RETURN:
case SSL_ERROR_SYSCALL:
default:
return SSLSTATUS_FAIL;
}
}
void MySQL_Data_Stream::queue_encrypted_bytes(const char *buf, size_t len) {
ssl_write_buf = (char*)realloc(ssl_write_buf, ssl_write_len + len);
memcpy(ssl_write_buf + ssl_write_len, buf, len);
ssl_write_len += len;
//proxy_info("New ssl_write_len size: %u\n", ssl_write_len);
}
enum sslstatus MySQL_Data_Stream::do_ssl_handshake() {
char buf[MY_SSL_BUFFER];
enum sslstatus status;
int n = SSL_do_handshake(ssl);
status = get_sslstatus(ssl, n);
//proxy_info("SSL status = %d\n", status);
/* Did SSL request to write bytes? */
if (status == SSLSTATUS_WANT_IO) {
//proxy_info("SSL status is WANT_IO %d\n", status);
do {
n = BIO_read(wbio_ssl, buf, sizeof(buf));
//proxy_info("BIO read = %d\n", n);
if (n > 0) {
//proxy_info("Queuing %d encrypted bytes\n", n);
queue_encrypted_bytes(buf, n);
} else if (!BIO_should_retry(wbio_ssl)) {
//proxy_info("BIO_should_retry failed\n");
return SSLSTATUS_FAIL;
}
} while (n>0);
}
return status;
}
void * MySQL_Data_Stream::operator new(size_t size) {
return l_alloc(size);
}
@ -122,6 +172,10 @@ MySQL_Data_Stream::MySQL_Data_Stream() {
DSS=STATE_NOT_CONNECTED;
encrypted=false;
ssl=NULL;
rbio_ssl = NULL;
wbio_ssl = NULL;
ssl_write_len = 0;
ssl_write_buf = NULL;
net_failure=false;
CompPktIN.pkt.ptr=NULL;
CompPktIN.pkt.size=0;
@ -193,6 +247,15 @@ MySQL_Data_Stream::~MySQL_Data_Stream() {
if ( (myconn) && (myds_type==MYDS_FRONTEND) ) { delete myconn; myconn=NULL; }
if (encrypted) {
if (ssl) SSL_free(ssl);
/*
SSL_free() should also take care of these
if (rbio_ssl) {
BIO_free(rbio_ssl);
}
if (wbio_ssl) {
BIO_free(wbio_ssl);
}
*/
}
if (multi_pkt.ptr) {
l_free(multi_pkt.size,multi_pkt.ptr);
@ -257,6 +320,9 @@ void MySQL_Data_Stream::shut_soft() {
void MySQL_Data_Stream::shut_hard() {
proxy_debug(PROXY_DEBUG_NET, 4, "Shutdown hard fd=%d. Session=%p, DataStream=%p\n", fd, sess, this);
set_net_failure();
if (encrypted) {
SSL_set_quiet_shutdown(ssl, 1);
}
if (fd >= 0) {
shutdown(fd, SHUT_RDWR);
close(fd);
@ -287,10 +353,125 @@ void MySQL_Data_Stream::check_data_flow() {
}
int MySQL_Data_Stream::read_from_net() {
if (encrypted) {
//proxy_info("Entering\n");
}
if ((revents & POLLIN)==0) return 0;
int r;
int r=0;
int s=queue_available(queueIN);
r = ( encrypted ? SSL_read (ssl, queue_w_ptr(queueIN), s) : recv(fd, queue_w_ptr(queueIN), s, 0) );
if (encrypted) {
// proxy_info("Queue available of %d bytes\n", s);
}
if (encrypted == false) {
if (pkts_recv) {
r = recv(fd, queue_w_ptr(queueIN), s, 0);
} else {
if (queueIN.partial == 0) {
// we are reading the very first packet
// to avoid issue with SSL, we will only read the header and eventually the first packet
r = recv(fd, queue_w_ptr(queueIN), 4, 0);
if (r == 4) {
// let's try to read a whole packet
mysql_hdr Hdr;
memcpy(&Hdr,queueIN.buffer,sizeof(mysql_hdr));
r += recv(fd, queue_w_ptr(queueIN)+4, Hdr.pkt_length, 0);
}
} else {
r = recv(fd, queue_w_ptr(queueIN), s, 0);
}
}
} else {
/*
if (!SSL_is_init_finished(ssl)) {
int ret = SSL_do_handshake(ssl);
int ret2;
if (ret != 1) {
//ERR_print_errors_fp(stderr);
ret2 = SSL_get_error(ssl, ret);
fprintf(stderr,"%d\n",ret2);
}
return 0;
} else {
r = SSL_read (ssl, queue_w_ptr(queueIN), s);
}
*/
if (s < MY_SSL_BUFFER) {
return 0; // no enough space for reads
}
char buf[MY_SSL_BUFFER];
//ssize_t n = read(fd, buf, sizeof(buf));
int n = recv(fd, buf, sizeof(buf), 0);
//proxy_info("SSL recv of %d bytes\n", n);
if (n > 0) {
//on_read_cb(buf, (size_t)n);
char buf2[MY_SSL_BUFFER];
int n2;
enum sslstatus status;
char *src = buf;
int len = n;
while (len) {
n2 = BIO_write(rbio_ssl, src, len);
//proxy_info("BIO_write with len = %d and %d bytes\n", len , n2);
if (n2 <= 0) {
shut_soft();
return -1;
}
src += n2;
len -= n2;
if (!SSL_is_init_finished(ssl)) {
//proxy_info("SSL_is_init_finished NOT completed\n");
if (do_ssl_handshake() == SSLSTATUS_FAIL) {
//proxy_info("SSL_is_init_finished failed!!\n");
shut_soft();
return -1;
}
if (!SSL_is_init_finished(ssl)) {
//proxy_info("SSL_is_init_finished yet NOT completed\n");
return 0;
}
} else {
//proxy_info("SSL_is_init_finished completed\n");
}
}
n2 = SSL_read (ssl, queue_w_ptr(queueIN), s);
r = n2;
//proxy_info("Read %d bytes from SSL\n", r);
if (n2 > 0) {
}
/*
do {
n2 = SSL_read(ssl, buf2, sizeof(buf2));
if (n2 > 0) {
}
} while (n > 0);
*/
status = get_sslstatus(ssl, n2);
//proxy_info("SSL status = %d\n", status);
if (status == SSLSTATUS_WANT_IO) {
do {
n2 = BIO_read(wbio_ssl, buf2, sizeof(buf2));
//proxy_info("BIO_read with %d bytes\n", n2);
if (n2 > 0) {
queue_encrypted_bytes(buf2, n2);
} else if (!BIO_should_retry(wbio_ssl)) {
shut_soft();
return -1;
}
} while (n2>0);
}
if (status == SSLSTATUS_FAIL) {
shut_soft();
return -1;
}
} else {
r = n;
//r += SSL_read (ssl, queue_w_ptr(queueIN), s);
//proxy_info("Read %d bytes from SSL\n", r);
}
}
//__exit_read_from_next:
proxy_debug(PROXY_DEBUG_NET, 5, "read %d bytes from fd %d into a buffer of %d bytes free\n", r, fd, s);
//proxy_error("read %d bytes from fd %d into a buffer of %d bytes free\n", r, fd, s);
if (r < 1) {
@ -314,11 +495,61 @@ int MySQL_Data_Stream::read_from_net() {
int MySQL_Data_Stream::write_to_net() {
int bytes_io=0;
int s = queue_data(queueOUT);
if (s==0) return 0;
int n;
if (encrypted) {
//proxy_info("Data in write buffer: %d bytes\n", s);
}
if (s==0) {
if (encrypted == false) {
return 0;
}
if (ssl_write_len == 0 && wbio_ssl->num_write == wbio_ssl->num_read) {
return 0;
}
}
VALGRIND_DISABLE_ERROR_REPORTING;
// splitting the ternary operation in IF condition for better readability
if (encrypted) {
bytes_io = SSL_write (ssl, queue_r_ptr(queueOUT), s);
//proxy_info("Used SSL_write to write %d bytes\n", bytes_io);
if (ssl_write_len || wbio_ssl->num_write > wbio_ssl->num_read) {
//proxy_info("ssl_write_len = %d , num_write = %d , num_read = %d\n", ssl_write_len , wbio_ssl->num_write , wbio_ssl->num_read);
char buf[MY_SSL_BUFFER];
do {
n = BIO_read(wbio_ssl, buf, sizeof(buf));
//proxy_info("BIO read = %d\n", n);
if (n > 0) {
//proxy_info("Setting %d byte in queue encrypted\n", n);
queue_encrypted_bytes(buf, n);
}
else if (!BIO_should_retry(wbio_ssl)) {
//proxy_info("BIO_should_retry failed\n");
shut_soft();
return -1;
}
} while (n>0);
}
if (ssl_write_len) {
n = write(fd, ssl_write_buf, ssl_write_len);
//proxy_info("Calling write() on SSL: %d\n", n);
if (n>0) {
if ((size_t)n < ssl_write_len) {
memmove(ssl_write_buf, ssl_write_buf+n, ssl_write_len-n);
}
ssl_write_len -= n;
ssl_write_buf = (char*)realloc(ssl_write_buf, ssl_write_len);
//proxy_info("new ssl_write_len: %u\n", ssl_write_len);
//if (ssl_write_len) {
// return n; // stop here
//} else {
// rc = n; // and continue
//}
//bytes_io += n;
} else {
shut_soft();
return -1;
}
}
} else {
#ifdef __APPLE__
bytes_io = send(fd, queue_r_ptr(queueOUT), s, 0);
@ -326,6 +557,9 @@ int MySQL_Data_Stream::write_to_net() {
bytes_io = send(fd, queue_r_ptr(queueOUT), s, MSG_NOSIGNAL);
#endif
}
if (encrypted) {
//proxy_info("bytes_io: %d\n", bytes_io);
}
VALGRIND_ENABLE_ERROR_REPORTING;
if (bytes_io < 0) {
if (encrypted==false) {
@ -374,10 +608,31 @@ void MySQL_Data_Stream::set_pollout() {
if (DSS > STATE_MARIADB_BEGIN && DSS < STATE_MARIADB_END) {
_pollfd->events = myconn->wait_events;
} else {
_pollfd->events = POLLIN;
//if (PSarrayOUT->len || available_data_out() || queueOUT.partial || (encrypted && !SSL_is_init_finished(ssl))) {
if (PSarrayOUT->len || available_data_out() || queueOUT.partial) {
_pollfd->events = POLLIN | POLLOUT;
} else {
_pollfd->events = POLLIN;
_pollfd->events |= POLLOUT;
}
if (encrypted) {
if (ssl_write_len || wbio_ssl->num_write > wbio_ssl->num_read) {
_pollfd->events |= POLLOUT;
} else {
if (!SSL_is_init_finished(ssl)) {
//proxy_info("SSL_is_init_finished NOT completed\n");
if (do_ssl_handshake() == SSLSTATUS_FAIL) {
//proxy_info("SSL_is_init_finished failed!!\n");
shut_soft();
return;
}
if (!SSL_is_init_finished(ssl)) {
//proxy_info("SSL_is_init_finished yet NOT completed\n");
return;
}
} else {
//proxy_info("SSL_is_init_finished completed\n");
}
_pollfd->events |= POLLOUT;
}
}
}
proxy_debug(PROXY_DEBUG_NET,1,"Session=%p, DataStream=%p -- Setting poll events %d for FD %d , DSS=%d , myconn=%p\n", sess, this, _pollfd->events , fd, DSS, myconn);
@ -386,18 +641,87 @@ void MySQL_Data_Stream::set_pollout() {
int MySQL_Data_Stream::write_to_net_poll() {
int rc=0;
if (active==0) return rc;
/*
if (encrypted && !SSL_is_init_finished(ssl)) {
int ret = SSL_do_handshake(ssl);
int ret2;
if (ret != 1) {
//ERR_print_errors_fp(stderr);
ret2 = SSL_get_error(ssl, ret);
fprintf(stderr,"%d\n",ret2);
}
return 0;
}
*/
if (encrypted) {
if (!SSL_is_init_finished(ssl)) {
//proxy_info("SSL_is_init_finished completed: NO!\n");
if (do_ssl_handshake() == SSLSTATUS_FAIL) {
//proxy_info("SSL_is_init_finished failed!!\n");
shut_soft();
return -1;
}
} else {
//proxy_info("SSL_is_init_finished completed: YES\n");
}
/*
if (!SSL_is_init_finished(ssl)) {
proxy_info("SSL_is_init_finished completed: NO!\n");
if (fd>0 && sess->session_type == PROXYSQL_SESSION_MYSQL) {
set_pollout();
return 0;
}
}
*/
//proxy_info("ssl_write_len: %u\n", ssl_write_len);
if (ssl_write_len) {
int n = write(fd, ssl_write_buf, ssl_write_len);
//proxy_info("Calling write() on SSL: %d\n", n);
if (n>0) {
if ((size_t)n < ssl_write_len) {
memmove(ssl_write_buf, ssl_write_buf+n, ssl_write_len-n);
}
ssl_write_len -= n;
ssl_write_buf = (char*)realloc(ssl_write_buf, ssl_write_len);
//proxy_info("new ssl_write_len: %u\n", ssl_write_len);
if (ssl_write_len) {
return n; // stop here
} else {
rc = n; // and continue
}
} else {
shut_soft();
return -1;
}
}
}
proxy_debug(PROXY_DEBUG_NET,1,"Session=%p, DataStream=%p --\n", sess, this);
bool call_write_to_net = false;
if (queue_data(queueOUT)) {
call_write_to_net = true;
}
if (call_write_to_net == false) {
if (encrypted) {
if (ssl_write_len || wbio_ssl->num_write > wbio_ssl->num_read) {
call_write_to_net = true;
}
}
}
if (call_write_to_net) {
if (sess->session_type == PROXYSQL_SESSION_MYSQL) {
if (poll_fds_idx>-1) { // NOTE: attempt to force writes
if (net_failure==false)
rc=write_to_net();
rc += write_to_net();
}
} else {
rc=write_to_net();
rc += write_to_net();
}
}
if (fd>0 && sess->session_type == PROXYSQL_SESSION_MYSQL) set_pollout();
if (fd>0 && sess->session_type == PROXYSQL_SESSION_MYSQL) {
// PROXYSQL_SESSION_MYSQL is a requirement, because it uses threads pool
// the other session types do not
set_pollout();
}
return rc;
}
@ -463,6 +787,9 @@ int MySQL_Data_Stream::buffer2array() {
memcpy((unsigned char *)queueIN.pkt.ptr + queueIN.partial, queue_r_ptr(queueIN),b);
queue_r(queueIN,b);
queueIN.partial+=b;
if (queueIN.partial == 80) {
proxy_info("Breakpoint\n");
}
ret+=b;
}
if ((queueIN.pkt.size>0) && (queueIN.pkt.size==queueIN.partial) ) {

Loading…
Cancel
Save