mirror of https://github.com/sysown/proxysql
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
4.9 KiB
167 lines
4.9 KiB
#include "proxysql.h"
|
|
#include "cpp.h"
|
|
|
|
|
|
|
|
MySQL_Thread::MySQL_Thread() {
|
|
}
|
|
|
|
void MySQL_Thread::init() {
|
|
mysql_sessions=g_ptr_array_new();
|
|
assert(mysql_sessions);
|
|
shutdown=0;
|
|
init_epoll(MYSQL_THREAD_EPOLL_MAXEVENTS);
|
|
}
|
|
|
|
int MySQL_Thread::init_epoll(int me) {
|
|
epoll_maxevents=me; // define maximum number of events for epoll()
|
|
epollfd=epoll_create(epoll_maxevents); // create epoll
|
|
if (epollfd==-1) {
|
|
perror("epoll_create");
|
|
assert(0);
|
|
//exit(EXIT_FAILURE);
|
|
}
|
|
events=(struct epoll_event *)malloc(sizeof(struct epoll_event)*epoll_maxevents);
|
|
assert(events);
|
|
return epollfd;
|
|
}
|
|
|
|
|
|
void MySQL_Thread::epoll_listener_add(int sock) {
|
|
struct epoll_event ev;
|
|
int rc;
|
|
MySQL_Data_Stream *listener_DS = new MySQL_Data_Stream;
|
|
listener_DS->listener=1;
|
|
listener_DS->fd=sock;
|
|
memset(&ev,0,sizeof(struct epoll_event));
|
|
//ev.events = EPOLLIN | EPOLLERR | EPOLLHUP ;
|
|
ev.events = EPOLLIN;
|
|
ev.data.ptr=listener_DS;
|
|
rc=epoll_ctl(epollfd, EPOLL_CTL_ADD, sock, &ev);
|
|
if (rc==-1) {
|
|
perror("epoll_ctl");
|
|
assert(0);
|
|
//exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
// main loop
|
|
void MySQL_Thread::run() {
|
|
int n;
|
|
int arg_on=1;
|
|
while (shutdown==0) {
|
|
nfds=epoll_wait(epollfd, events, epoll_maxevents, 1000);
|
|
for (n = 0; n < nfds; ++n) {
|
|
MySQL_Data_Stream *myds=(MySQL_Data_Stream *)events[n].data.ptr;
|
|
if (myds->listener==1) {
|
|
// we got a new connection!
|
|
int c=accept(myds->fd, NULL, NULL);
|
|
if (c>-1) {
|
|
MySQL_Session *sess=new MySQL_Session;
|
|
proxy_debug(PROXY_DEBUG_NET,1,"Created new Session %p\n", sess);
|
|
sess->client_fd=c;
|
|
setsockopt(sess->client_fd, IPPROTO_TCP, TCP_NODELAY, (char *) &arg_on, sizeof(int));
|
|
|
|
sess->client_myds = new MySQL_Data_Stream();
|
|
sess->client_myds->init();
|
|
sess->client_myds->sess=sess;
|
|
proxy_debug(PROXY_DEBUG_NET,1,"Created new DS %p sess %p\n", sess->client_myds, sess);
|
|
sess->client_myds->fd=sess->client_fd;
|
|
sess->server_fd=connect_socket((char *)"127.0.0.1", 3306);
|
|
setsockopt(sess->server_fd, IPPROTO_TCP, TCP_NODELAY, (char *) &arg_on, sizeof(int));
|
|
sess->server_myds = new MySQL_Data_Stream();
|
|
sess->server_myds->init();
|
|
sess->server_myds->sess=sess;
|
|
proxy_debug(PROXY_DEBUG_NET,1,"Created new DS %p sess %p\n", sess->server_myds, sess);
|
|
sess->server_myds->fd=sess->server_fd;
|
|
|
|
ioctl_FIONBIO(sess->client_fd, 1);
|
|
ioctl_FIONBIO(sess->server_fd, 1);
|
|
|
|
|
|
|
|
sess->client_myds->epollfd=epollfd;
|
|
sess->server_myds->epollfd=epollfd;
|
|
|
|
//sess->client_myds->ev.events = EPOLLIN | EPOLLOUT | EPOLLERR | EPOLLHUP ;
|
|
sess->client_myds->ev.events = EPOLLIN | EPOLLOUT;
|
|
sess->client_myds->ev.data.ptr=sess->client_myds;
|
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, sess->client_fd, &sess->client_myds->ev);
|
|
//sess->server_myds->ev.events = EPOLLIN | EPOLLOUT | EPOLLERR | EPOLLHUP ;
|
|
sess->server_myds->ev.events = EPOLLIN | EPOLLOUT;
|
|
sess->server_myds->ev.data.ptr=sess->server_myds;
|
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, sess->server_fd, &sess->server_myds->ev);
|
|
proxy_debug(PROXY_DEBUG_NET,1,"Adding client FD %d and server FD %d\n", sess->client_fd, sess->server_fd);
|
|
|
|
}
|
|
continue;
|
|
} else {
|
|
// data on exiting connection
|
|
MySQL_Session *sess=myds->sess;
|
|
|
|
|
|
|
|
myds->rev=&events[n];
|
|
myds->read_from_net();
|
|
myds->read_pkts();
|
|
|
|
if (myds->fd==sess->client_fd) {
|
|
unsigned char *pkt;
|
|
/*while ((pkt=(unsigned char *)g_queue_pop_head(sess->client_myds->queueIN))!=NULL) {
|
|
g_queue_push_tail(sess->server_myds->queueOUT,pkt);
|
|
}*/
|
|
while (sess->client_myds->QarrayIN->len) {
|
|
pkt=(unsigned char *)g_ptr_array_remove_index(sess->client_myds->QarrayIN,0);
|
|
proxy_debug(PROXY_DEBUG_NET,1,"Session %p\n", sess);
|
|
parse_mysql_pkt(pkt, &sess->sess_states, 1);
|
|
if (sess->server_myds) {
|
|
g_ptr_array_add(sess->server_myds->QarrayOUT,pkt);
|
|
} else {
|
|
free(pkt);
|
|
}
|
|
}
|
|
}
|
|
if (myds->fd==sess->server_fd) {
|
|
unsigned char *pkt;
|
|
/*while ((pkt=(unsigned char *)g_queue_pop_head(sess->server_myds->queueIN))!=NULL) {
|
|
g_queue_push_tail(sess->client_myds->queueOUT,pkt);
|
|
}*/
|
|
while (sess->server_myds->QarrayIN->len) {
|
|
pkt=(unsigned char *)g_ptr_array_remove_index(sess->server_myds->QarrayIN,0);
|
|
proxy_debug(PROXY_DEBUG_NET,1,"Session %p\n", sess);
|
|
parse_mysql_pkt(pkt, &sess->sess_states, 0);
|
|
if (sess->client_myds) {
|
|
g_ptr_array_add(sess->client_myds->QarrayOUT,pkt);
|
|
} else {
|
|
free(pkt);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (myds->active==FALSE) {
|
|
epoll_ctl(epollfd, EPOLL_CTL_DEL, myds->fd, NULL);
|
|
proxy_debug(PROXY_DEBUG_NET,1, "Deleting FD %d\n", myds->fd);
|
|
myds->shut_hard();
|
|
if (sess->client_myds==myds) sess->client_myds=NULL;
|
|
if (sess->server_myds==myds) sess->server_myds=NULL;
|
|
delete myds;
|
|
if (sess->client_myds==NULL && sess->server_myds==NULL) {
|
|
delete sess;
|
|
continue;
|
|
}
|
|
//exit(1);
|
|
}
|
|
|
|
// always move pkts from queue to evbuffer
|
|
sess->writeout();
|
|
|
|
myds->write_to_net_epoll();
|
|
|
|
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|