dcb.h
------- Removed DCB states DCB_STATE_IDLE, and DCB_STATE_PROCESSING. Added DCB_STATE_UNDEFINED for initial content for state variable which doesn't have any specific value set, and DCB_STATE_NOPOLLING to indicate that dcb has been removed from poll set. Added following dcb roles: DCB_ROLE_SERVICE_LISTENER for listeners of services, and DCB_ROLE_REQUEST_HANDLER for client/backend dcbs. Listeners may have state DCB_STATE_LISTENING, but not DCB_STATE_POLLING. Request handlers may have DCB_STATE_POLLING but not DCB_STATE_LISTENING. Role is passed as an argument to dcb.c:dcb_alloc. From now on, struct check numbers of DCB are included and checked in DEBUG build only. Added dcb_role_t dcb_role-member to DCB as well as SPINLOCK dcb_initlock, which protects state changes. Removed extern keyword from function declarations because functions are by default externally visible if they are declared in header. dcb.b ------ Function dcb_set_state, and dcb_set_state_nomutex provide functions for changing dcb states. Latter implements a state machine for dcb. Function dcb_add_to_zombieslist replaces dcb_free. It adds in atomic step dcb to zombieslist and changes state to DCB_STATE_ZOMBIE. Function dcb_final_free removes dcb from allDCBs list, terminates router and client sessions, and frees dcb and related memory. Function dcb_process_zombies removes executing thread from dcb's bitmask, and it there are no further thread bits, moves dcb to a victim list, and finally, for each dcb on victim list, closes fd and sets state to DCB_STATE_DISCONNECTED. Function dcb_close sets dcb state to DCB_STATE_NOPOLLIN, removes dcb from poll set and sets bit to bitmask for each server thread in an atomic step. poll.c ------ Function poll_add_dcb sets either DCB_STATE_LISTENING or DCB_STATE_POLLING state for newly created dcb, depending whether the role of dcb is DCB_ROLE_SERVICE_LISTENER, or DCB_ROLE_REQUEST_HANDLER, respectively. Then dcb is set to poll set. poll_waitevents : commented out code which skipped event if dcb was added to zombieslist or if fd was closed. Added state checks. service.c : Minor changes. httpd.c : Removed dcb state changes. They are done in core. mysql_backend.c : Added checks, removed dcb state changes. mysql_client.c : Removed dcb state changes. Added checks. mysql_common.c : Minor changes telnetd.c : Removed state changes. Replaced some typecasts and pointer references with local variable reads. skygw_debug.h : Removed two states, and added two to state printing macro.
This commit is contained in:
@ -130,8 +130,6 @@ size_t i, j;
|
||||
int headers_read = 0;
|
||||
HTTPD_session *client_data = NULL;
|
||||
|
||||
dcb->state = DCB_STATE_PROCESSING;
|
||||
|
||||
client_data = dcb->data;
|
||||
|
||||
/**
|
||||
@ -320,14 +318,13 @@ int n_connect = 0;
|
||||
else
|
||||
{
|
||||
atomic_add(&dcb->stats.n_accepts, 1);
|
||||
client = dcb_alloc();
|
||||
client = dcb_alloc(DCB_ROLE_SERVICE_LISTENER);
|
||||
client->fd = so;
|
||||
client->remote = strdup(inet_ntoa(addr.sin_addr));
|
||||
memcpy(&client->func, &MyObject, sizeof(GWPROTOCOL));
|
||||
client->session = session_alloc(dcb->session->service, client);
|
||||
ss_dassert(client->session->state != SESSION_STATE_ALLOC);
|
||||
client->state = DCB_STATE_IDLE;
|
||||
|
||||
ss_dassert(
|
||||
client->session->state != SESSION_STATE_ALLOC);
|
||||
/* create the session data for HTTPD */
|
||||
client_data = (HTTPD_session *)calloc(1, sizeof(HTTPD_session));
|
||||
client->data = client_data;
|
||||
@ -337,8 +334,6 @@ int n_connect = 0;
|
||||
return n_connect;
|
||||
}
|
||||
n_connect++;
|
||||
|
||||
client->state = DCB_STATE_POLLING;
|
||||
}
|
||||
}
|
||||
return n_connect;
|
||||
@ -391,7 +386,11 @@ short pnum;
|
||||
}
|
||||
|
||||
/* socket options */
|
||||
setsockopt(listener->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));
|
||||
setsockopt(listener->fd,
|
||||
SOL_SOCKET,
|
||||
SO_REUSEADDR,
|
||||
(char *)&one,
|
||||
sizeof(one));
|
||||
|
||||
/* set NONBLOCKING mode */
|
||||
setnonblocking(listener->fd);
|
||||
@ -401,8 +400,6 @@ short pnum;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
listener->state = DCB_STATE_LISTENING;
|
||||
listen(listener->fd, SOMAXCONN);
|
||||
|
||||
if (poll_add_dcb(listener) == -1)
|
||||
@ -461,4 +458,3 @@ static void httpd_send_headers(DCB *dcb, int final)
|
||||
dcb_printf(dcb, "\r\n");
|
||||
}
|
||||
}
|
||||
//
|
||||
|
@ -146,37 +146,21 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
MYSQL_session *current_session = NULL;
|
||||
int rc = 0;
|
||||
|
||||
dcb->state = DCB_STATE_PROCESSING;
|
||||
CHK_DCB(dcb);
|
||||
CHK_SESSION(dcb->session);
|
||||
ss_info_dassert(dcb->session != NULL,
|
||||
"Backend dcb doesn't have session");
|
||||
|
||||
ss_info_dassert(dcb->session->client != NULL,
|
||||
"Session's client dcb pointer is NULL");
|
||||
|
||||
if(dcb->session) {
|
||||
CHK_SESSION(dcb->session);
|
||||
if (dcb->session->client == NULL) {
|
||||
dcb->state = DCB_STATE_DISCONNECTED;
|
||||
skygw_log_write(
|
||||
LOGFILE_ERROR,
|
||||
"%lu [gw_read_backend_event] client dcb is NULL for backend dcb %d.",
|
||||
pthread_self(),
|
||||
dcb->fd);
|
||||
dcb->state = DCB_STATE_DISCONNECTED;
|
||||
return 1;
|
||||
}
|
||||
client_protocol = SESSION_PROTOCOL(dcb->session, MySQLProtocol);
|
||||
} else {
|
||||
skygw_log_write(
|
||||
LOGFILE_ERROR,
|
||||
"%lu [gw_read_backend_event] dcb->session is NULL for backend dcb %d.",
|
||||
pthread_self(),
|
||||
dcb->fd);
|
||||
dcb->state = DCB_STATE_DISCONNECTED;
|
||||
return 1;
|
||||
}
|
||||
backend_protocol = (MySQLProtocol *) dcb->protocol;
|
||||
client_protocol = SESSION_PROTOCOL(dcb->session, MySQLProtocol);
|
||||
backend_protocol = (MySQLProtocol *) dcb->protocol;
|
||||
|
||||
/** return only with complete session */
|
||||
current_session = gw_get_shared_session_auth_info(dcb);
|
||||
ss_dassert(current_session != NULL);
|
||||
ss_dassert(dcb->session->state != SESSION_STATE_ALLOC);
|
||||
|
||||
|
||||
/* fprintf(stderr, ">>> backend EPOLLIN from %i, command %i,protocol
|
||||
* state [%s]\n", dcb->fd, dcb->command, gw_mysql_protocol_state2string
|
||||
* (backend_protocol->state));
|
||||
@ -202,17 +186,18 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
/* ready to check the authentication reply from backend */
|
||||
|
||||
if (backend_protocol->state == MYSQL_AUTH_RECV) {
|
||||
ROUTER_OBJECT *router = NULL;
|
||||
ROUTER_OBJECT *router = NULL;
|
||||
ROUTER *router_instance = NULL;
|
||||
void *rsession = NULL;
|
||||
int rv = -1;
|
||||
SESSION *session = dcb->session;
|
||||
|
||||
if (session) {
|
||||
router = session->service->router;
|
||||
router_instance = session->service->router_instance;
|
||||
rsession = session->router_session;
|
||||
}
|
||||
CHK_SESSION(session);
|
||||
|
||||
router = session->service->router;
|
||||
router_instance = session->service->router_instance;
|
||||
rsession = session->router_session;
|
||||
|
||||
/* read backed auth reply */
|
||||
rv = gw_receive_backend_auth(backend_protocol);
|
||||
|
||||
@ -222,12 +207,17 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
LOGFILE_ERROR,
|
||||
"%lu [gw_read_backend_event] caught "
|
||||
"MYSQL_FAILED_AUTHENTICATION from "
|
||||
"gw_receive_backend_auth. Fd %d, user %s.",
|
||||
"gw_receive_backend_auth. Fd %d, "
|
||||
"user %s.",
|
||||
pthread_self(),
|
||||
dcb->fd,
|
||||
current_session->user);
|
||||
|
||||
backend_protocol->state = MYSQL_AUTH_FAILED;
|
||||
#if 0
|
||||
ss_dassert(backend_protocol->state !=
|
||||
MYSQL_AUTH_FAILED);
|
||||
#endif
|
||||
/* send an error to the client */
|
||||
mysql_send_custom_error(
|
||||
dcb->session->client,
|
||||
@ -245,17 +235,19 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
if (rsession != NULL) {
|
||||
skygw_log_write_flush(
|
||||
LOGFILE_TRACE,
|
||||
"%lu [gw_read_backend_event] Call "
|
||||
"closeSession for backend session.",
|
||||
"%lu [gw_read_backend_event] "
|
||||
"Call closeSession for backend "
|
||||
"session.",
|
||||
pthread_self());
|
||||
/* close the active session */
|
||||
router->closeSession(router_instance, rsession);
|
||||
router->closeSession(router_instance,
|
||||
rsession);
|
||||
} else {
|
||||
skygw_log_write(
|
||||
LOGFILE_TRACE,
|
||||
"%lu [gw_read_backend_event] "
|
||||
"closeSession already called for "
|
||||
"backend session.",
|
||||
"closeSession already called "
|
||||
"for backend session.",
|
||||
pthread_self());
|
||||
}
|
||||
rc = 1;
|
||||
@ -266,7 +258,8 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
LOGFILE_TRACE,
|
||||
"%lu [gw_read_backend_event] caught "
|
||||
"MYSQL_SUCCESFUL_AUTHENTICATION from "
|
||||
"gw_receive_backend_auth. Fd %d, user %s.",
|
||||
"gw_receive_backend_auth. Fd %d, "
|
||||
"user %s.",
|
||||
pthread_self(),
|
||||
dcb->fd,
|
||||
current_session->user);
|
||||
@ -276,7 +269,6 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
/* check the delay queue and flush the data */
|
||||
if(dcb->delayq) {
|
||||
backend_write_delayqueue(dcb);
|
||||
dcb->state = DCB_STATE_POLLING;
|
||||
spinlock_release(&dcb->authlock);
|
||||
rc = 1;
|
||||
goto return_rc;
|
||||
@ -304,6 +296,7 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
void *rsession = NULL;
|
||||
SESSION *session = dcb->session;
|
||||
|
||||
CHK_SESSION(session);
|
||||
/* read available backend data */
|
||||
rc = dcb_read(dcb, &head);
|
||||
|
||||
@ -312,26 +305,22 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
goto return_rc;
|
||||
}
|
||||
|
||||
if (session != NULL) {
|
||||
router = session->service->router;
|
||||
router_instance = session->service->router_instance;
|
||||
rsession = session->router_session;
|
||||
}
|
||||
|
||||
router = session->service->router;
|
||||
router_instance = session->service->router_instance;
|
||||
rsession = session->router_session;
|
||||
/* Note the gwbuf doesn't have here a valid queue->command
|
||||
* descriptions as it is a fresh new one!
|
||||
* We only have the copied value in dcb->command from previuos func.write()
|
||||
* and this will be used by the router->clientReply
|
||||
* We only have the copied value in dcb->command from
|
||||
* previuos func.write() and this will be used by the
|
||||
* router->clientReply
|
||||
* and pass now the gwbuf to the router
|
||||
*/
|
||||
|
||||
/* and pass now the gwbuf to the router */
|
||||
router->clientReply(router_instance, rsession, head, dcb);
|
||||
rc = 1;
|
||||
goto return_rc;
|
||||
}
|
||||
rc = 0;
|
||||
return_rc:
|
||||
dcb->state = DCB_STATE_POLLING;
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -347,18 +336,16 @@ static int gw_write_backend_event(DCB *dcb) {
|
||||
//fprintf(stderr, ">>> backend EPOLLOUT %i, protocol state [%s]\n", backend_protocol->fd, gw_mysql_protocol_state2string(backend_protocol->state));
|
||||
|
||||
// spinlock_acquire(&dcb->connectlock);
|
||||
dcb->state = DCB_STATE_PROCESSING;
|
||||
|
||||
/**
|
||||
* vraa: what is the logic in this?
|
||||
*/
|
||||
if (backend_protocol->state == MYSQL_PENDING_CONNECT) {
|
||||
backend_protocol->state = MYSQL_CONNECTED;
|
||||
|
||||
backend_protocol->state = MYSQL_CONNECTED;
|
||||
// spinlock_release(&dcb->connectlock);
|
||||
dcb->state = DCB_STATE_POLLING;
|
||||
return 1;
|
||||
}
|
||||
// spinlock_release(&dcb->connectlock);
|
||||
dcb_drain_writeq(dcb);
|
||||
dcb->state = DCB_STATE_POLLING;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -456,7 +443,8 @@ static int gw_create_backend_connection(
|
||||
skygw_log_write(
|
||||
LOGFILE_TRACE,
|
||||
"%lu [gw_create_backend_connection] Established "
|
||||
"connection to %s:%i, backend fd %d client fd %d.",
|
||||
"connection to %s:%i, backend fd %d client "
|
||||
"fd %d.",
|
||||
pthread_self(),
|
||||
server->name,
|
||||
server->port,
|
||||
@ -492,8 +480,6 @@ static int gw_create_backend_connection(
|
||||
session->client->fd);
|
||||
break;
|
||||
} /**< switch */
|
||||
|
||||
backend_dcb->state = DCB_STATE_POLLING;
|
||||
return_fd:
|
||||
ss_dassert(backend_dcb->fd == fd);
|
||||
ss_dassert(backend_dcb->fd == protocol->fd);
|
||||
@ -547,7 +533,6 @@ static void backend_set_delayqueue(DCB *dcb, GWBUF *queue) {
|
||||
dcb->delayq = queue;
|
||||
}
|
||||
}
|
||||
|
||||
spinlock_release(&dcb->delayqlock);
|
||||
}
|
||||
|
||||
@ -681,4 +666,3 @@ static int gw_session(DCB *backend_dcb, void *data) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
/////
|
||||
|
@ -510,22 +510,9 @@ int gw_read_client_event(DCB* dcb) {
|
||||
MySQLProtocol *protocol = NULL;
|
||||
int b = -1;
|
||||
int rc = 0;
|
||||
#if 0
|
||||
dcb->state = dcb_begin_action(dcb, DCB_ACTION_READ);
|
||||
#else
|
||||
|
||||
CHK_DCB(dcb);
|
||||
|
||||
if (dcb->state == DCB_STATE_DISCONNECTED ||
|
||||
dcb->state == DCB_STATE_FREED ||
|
||||
dcb->state == DCB_STATE_ZOMBIE ||
|
||||
dcb->state == DCB_STATE_PROCESSING)
|
||||
{
|
||||
rc = 1;
|
||||
goto return_rc;
|
||||
}
|
||||
ss_dassert(dcb->state == DCB_STATE_POLLING);
|
||||
dcb->state = DCB_STATE_PROCESSING;
|
||||
#endif
|
||||
|
||||
protocol = DCB_PROTOCOL(dcb, MySQLProtocol);
|
||||
CHK_PROTOCOL(protocol);
|
||||
/**
|
||||
@ -647,9 +634,9 @@ int gw_read_client_event(DCB* dcb) {
|
||||
if (ptr_buff) {
|
||||
mysql_command = ptr_buff[4];
|
||||
}
|
||||
|
||||
|
||||
if (mysql_command == '\x03') {
|
||||
/// this is a standard MySQL query !!!!
|
||||
/* this is a standard MySQL query !!!! */
|
||||
}
|
||||
/**
|
||||
* Routing Client input to Backend
|
||||
@ -657,24 +644,20 @@ int gw_read_client_event(DCB* dcb) {
|
||||
/* Do not route the query without session! */
|
||||
if(rsession == NULL) {
|
||||
if (mysql_command == '\x01') {
|
||||
/* COM_QUIT handling */
|
||||
/* fprintf(stderr, "COM_QUIT received with
|
||||
* no connected backends from %i\n", dcb->fd); */
|
||||
/**
|
||||
* COM_QUIT handling
|
||||
*
|
||||
* fprintf(stderr, "COM_QUIT received with
|
||||
* no connected backends from %i\n", dcb->fd);
|
||||
*/
|
||||
(dcb->func).close(dcb);
|
||||
} else {
|
||||
/* Send a custom error as MySQL command reply */
|
||||
if (dcb) {
|
||||
mysql_send_custom_error(
|
||||
dcb,
|
||||
1,
|
||||
0,
|
||||
"Connection to backend lost");
|
||||
} else {
|
||||
skygw_log_write(
|
||||
LOGFILE_ERROR,
|
||||
"%lu [mysql_send_custom_error] client dcb is NULL.",
|
||||
pthread_self());
|
||||
}
|
||||
mysql_send_custom_error(
|
||||
dcb,
|
||||
1,
|
||||
0,
|
||||
"Connection to backend lost");
|
||||
protocol->state = MYSQL_IDLE;
|
||||
}
|
||||
rc = 1;
|
||||
@ -683,19 +666,19 @@ int gw_read_client_event(DCB* dcb) {
|
||||
/* We can route the query */
|
||||
/* COM_QUIT handling */
|
||||
if (mysql_command == '\x01') {
|
||||
/* fprintf(stderr, "COM_QUIT received from %i and
|
||||
* passed to backed\n", dcb->fd); */
|
||||
/* this will propagate COM_QUIT to backend(s) */
|
||||
//fprintf(stderr, "<<< Routing the COM_QUIT ...\n");
|
||||
router->routeQuery(router_instance,
|
||||
rsession,
|
||||
queue);
|
||||
/**
|
||||
* fprintf(stderr, "COM_QUIT received from %i and
|
||||
* passed to backed\n", dcb->fd);
|
||||
* this will propagate COM_QUIT to backend(s)
|
||||
* fprintf(stderr, "<<< Routing the COM_QUIT ...\n");
|
||||
*/
|
||||
router->routeQuery(router_instance, rsession, queue);
|
||||
/* close client connection */
|
||||
(dcb->func).close(dcb);
|
||||
rc = 1;
|
||||
return rc;
|
||||
goto return_rc;
|
||||
}
|
||||
|
||||
|
||||
/* MySQL Command Routing */
|
||||
protocol->state = MYSQL_ROUTING;
|
||||
|
||||
@ -715,65 +698,66 @@ int gw_read_client_event(DCB* dcb) {
|
||||
rc = 0;
|
||||
|
||||
return_rc:
|
||||
dcb->state = DCB_STATE_POLLING;
|
||||
return rc;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// client write event to Client triggered by EPOLLOUT
|
||||
//////////////////////////////////////////////
|
||||
int gw_write_client_event(DCB *dcb) {
|
||||
int gw_write_client_event(DCB *dcb)
|
||||
{
|
||||
MySQLProtocol *protocol = NULL;
|
||||
|
||||
CHK_DCB(dcb);
|
||||
|
||||
if (dcb == NULL) {
|
||||
fprintf(stderr, "DCB is NULL, return\n");
|
||||
return 1;
|
||||
}
|
||||
ss_dassert(dcb->state != DCB_STATE_DISCONNECTED);
|
||||
|
||||
if (dcb->state == DCB_STATE_DISCONNECTED) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
dcb->state = DCB_STATE_PROCESSING;
|
||||
|
||||
if (dcb->protocol) {
|
||||
protocol = DCB_PROTOCOL(dcb, MySQLProtocol);
|
||||
} else {
|
||||
fprintf(stderr, "DCB protocol is NULL, return\n");
|
||||
dcb->state = DCB_STATE_POLLING;
|
||||
return 1;
|
||||
goto return_1;
|
||||
}
|
||||
|
||||
if (protocol->state == MYSQL_IDLE ||
|
||||
protocol->state == MYSQL_WAITING_RESULT)
|
||||
{
|
||||
dcb_drain_writeq(dcb);
|
||||
dcb->state = DCB_STATE_POLLING;
|
||||
return 1;
|
||||
goto return_1;
|
||||
}
|
||||
dcb->state = DCB_STATE_POLLING;
|
||||
return 1;
|
||||
|
||||
return_1:
|
||||
return 1;
|
||||
}
|
||||
|
||||
///
|
||||
// set listener for mysql protocol, retur 1 on success and 0 in failure
|
||||
///
|
||||
int gw_MySQLListener(DCB *listener, char *config_bind) {
|
||||
/**
|
||||
* set listener for mysql protocol, retur 1 on success and 0 in failure
|
||||
*/
|
||||
int gw_MySQLListener(
|
||||
DCB *listen_dcb,
|
||||
char *config_bind)
|
||||
{
|
||||
int l_so;
|
||||
struct sockaddr_in serv_addr;
|
||||
char *bind_address_and_port = NULL;
|
||||
char *p;
|
||||
char address[1024] = "";
|
||||
int port=0;
|
||||
int one = 1;
|
||||
int port = 0;
|
||||
int one = 1;
|
||||
|
||||
// this gateway, as default, will bind on port 4404 for localhost only
|
||||
/* this gateway, as default, will bind on port 4404 for localhost only */
|
||||
if (config_bind != NULL) {
|
||||
bind_address_and_port = config_bind;
|
||||
} else {
|
||||
bind_address_and_port = "127.0.0.1:4406";
|
||||
}
|
||||
listener->fd = -1;
|
||||
listen_dcb->fd = -1;
|
||||
memset(&serv_addr, 0, sizeof serv_addr);
|
||||
serv_addr.sin_family = AF_INET;
|
||||
p = strchr(bind_address_and_port, ':');
|
||||
@ -829,12 +813,11 @@ int gw_MySQLListener(DCB *listener, char *config_bind) {
|
||||
fprintf(stderr,
|
||||
">> GATEWAY listen backlog queue is %i\n",
|
||||
10 * SOMAXCONN);
|
||||
listener->state = DCB_STATE_IDLE;
|
||||
// assign l_so to dcb
|
||||
listener->fd = l_so;
|
||||
listen_dcb->fd = l_so;
|
||||
|
||||
// add listening socket to poll structure
|
||||
if (poll_add_dcb(listener) == -1) {
|
||||
if (poll_add_dcb(listen_dcb) == -1) {
|
||||
fprintf(stderr,
|
||||
">>> poll_add_dcb: can't add the listen_sock! Errno "
|
||||
"%i, %s\n",
|
||||
@ -842,15 +825,14 @@ int gw_MySQLListener(DCB *listener, char *config_bind) {
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
listener->func.accept = gw_MySQLAccept;
|
||||
listener->state = DCB_STATE_LISTENING;
|
||||
listen_dcb->func.accept = gw_MySQLAccept;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int gw_MySQLAccept(DCB *listener) {
|
||||
|
||||
int gw_MySQLAccept(DCB *listener)
|
||||
{
|
||||
fprintf(stderr, "MySQL Listener socket is: %i\n", listener->fd);
|
||||
|
||||
while (1) {
|
||||
@ -863,7 +845,9 @@ int gw_MySQLAccept(DCB *listener) {
|
||||
socklen_t optlen = sizeof(sendbuf);
|
||||
|
||||
// new connection from client
|
||||
c_sock = accept(listener->fd, (struct sockaddr *) &local, &addrlen);
|
||||
c_sock = accept(listener->fd,
|
||||
(struct sockaddr *) &local,
|
||||
&addrlen);
|
||||
|
||||
if (c_sock == -1) {
|
||||
if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
|
||||
@ -892,7 +876,7 @@ int gw_MySQLAccept(DCB *listener) {
|
||||
setsockopt(c_sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, optlen);
|
||||
setnonblocking(c_sock);
|
||||
|
||||
client_dcb = dcb_alloc();
|
||||
client_dcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER);
|
||||
client_dcb->service = listener->session->service;
|
||||
client_dcb->fd = c_sock;
|
||||
client_dcb->remote = strdup(inet_ntoa(local.sin_addr));
|
||||
@ -909,9 +893,6 @@ int gw_MySQLAccept(DCB *listener) {
|
||||
}
|
||||
// assign function poiters to "func" field
|
||||
memcpy(&client_dcb->func, &MyObject, sizeof(GWPROTOCOL));
|
||||
|
||||
client_dcb->state = DCB_STATE_IDLE;
|
||||
|
||||
//send handshake to the client_dcb
|
||||
MySQLSendHandshake(client_dcb);
|
||||
|
||||
@ -919,21 +900,17 @@ int gw_MySQLAccept(DCB *listener) {
|
||||
protocol->state = MYSQL_AUTH_SENT;
|
||||
|
||||
/**
|
||||
* Set new descriptor to event set. Before that
|
||||
* Set new descriptor to event set. At the same time,
|
||||
* change state to DCB_STATE_POLLING so that
|
||||
* thread which wakes up sees correct state.
|
||||
*
|
||||
*/
|
||||
client_dcb->state = DCB_STATE_POLLING;
|
||||
|
||||
if (poll_add_dcb(client_dcb) == -1)
|
||||
{
|
||||
/** Return to previous state. */
|
||||
client_dcb->state = DCB_STATE_IDLE;
|
||||
/** Previous state is recovered in poll_add_dcb. */
|
||||
skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"%lu [gw_MySQLAccept] Failed to add dcb %p for fd "
|
||||
"%d to epoll set.",
|
||||
"%lu [gw_MySQLAccept] Failed to add dcb %p for "
|
||||
"fd %d to epoll set.",
|
||||
pthread_self(),
|
||||
client_dcb,
|
||||
client_dcb->fd);
|
||||
@ -957,7 +934,7 @@ int gw_MySQLAccept(DCB *listener) {
|
||||
*/
|
||||
static int gw_error_client_event(DCB *dcb) {
|
||||
//fprintf(stderr, "#### Handle error function gw_error_client_event, for [%i] is [%s]\n", dcb->fd, gw_dcb_state2string(dcb->state));
|
||||
//dcb_close(dcb);
|
||||
dcb_close(dcb);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -71,44 +71,6 @@ return_p:
|
||||
return p;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* gw_mysql_init
|
||||
*
|
||||
* Initialize mysql protocol struct
|
||||
*
|
||||
* @param data The MySQLProtocol pointer, usually NULL
|
||||
* @return The new MySQLProtocol allocated
|
||||
*
|
||||
*/
|
||||
|
||||
MySQLProtocol *gw_mysql_init(MySQLProtocol *data) {
|
||||
MySQLProtocol *input = NULL;
|
||||
|
||||
// structure allocation
|
||||
input = calloc(1, sizeof(MySQLProtocol));
|
||||
|
||||
if (input == NULL) {
|
||||
int eno = errno;
|
||||
errno = 0;
|
||||
skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"%lu [gw_mysql_init] failed to allocate memory for MySQL "
|
||||
"protocol object. Errno %d, %s.",
|
||||
pthread_self(),
|
||||
eno,
|
||||
strerror(eno));
|
||||
return NULL;
|
||||
}
|
||||
input->protocol_chk_top = CHK_NUM_PROTOCOL;
|
||||
input->protocol_chk_tail = CHK_NUM_PROTOCOL;
|
||||
|
||||
#ifdef MYSQL_CONN_DEBUG
|
||||
fprintf(stderr, "gw_mysql_init() called\n");
|
||||
#endif
|
||||
return input;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* gw_mysql_close
|
||||
@ -502,7 +464,10 @@ int gw_do_connect_to_backend(
|
||||
struct sockaddr_in serv_addr;
|
||||
int rv;
|
||||
int so = 0;
|
||||
DCB* dcb = conn->descriptor;
|
||||
|
||||
CHK_DCB(dcb);
|
||||
|
||||
memset(&serv_addr, 0, sizeof serv_addr);
|
||||
serv_addr.sin_family = AF_INET;
|
||||
so = socket(AF_INET,SOCK_STREAM,0);
|
||||
@ -513,8 +478,9 @@ int gw_do_connect_to_backend(
|
||||
errno = 0;
|
||||
skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"%lu [gw_do_connect_to_backend] Establishing connection to "
|
||||
"back-end server failed. Socket creation failed due %d, %s.",
|
||||
"%lu [gw_do_connect_to_backend] Establishing connection "
|
||||
"to back-end server failed. Socket creation failed due "
|
||||
"%d, %s.",
|
||||
pthread_self(),
|
||||
eno,
|
||||
strerror(eno));
|
||||
@ -522,7 +488,7 @@ int gw_do_connect_to_backend(
|
||||
goto return_rv;
|
||||
}
|
||||
/* Assign so to the caller dcb, conn->descriptor */
|
||||
conn->descriptor->fd = so;
|
||||
dcb->fd = so;
|
||||
/* prepare for connect */
|
||||
setipaddress(&serv_addr.sin_addr, host);
|
||||
serv_addr.sin_port = htons(port);
|
||||
@ -552,7 +518,7 @@ int gw_do_connect_to_backend(
|
||||
/**
|
||||
* Add the dcb in the poll set
|
||||
*/
|
||||
poll_add_dcb(conn->descriptor);
|
||||
poll_add_dcb(dcb);
|
||||
return_rv:
|
||||
return rv;
|
||||
}
|
||||
@ -1007,7 +973,6 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
|
||||
|
||||
if (strlen(user_password))
|
||||
gw_hex2bin(gateway_password, user_password, SHA_DIGEST_LENGTH * 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1089,4 +1054,3 @@ mysql_send_auth_error (DCB *dcb, int packet_number, int in_affected_rows, const
|
||||
|
||||
return sizeof(mysql_packet_header) + mysql_payload_size;
|
||||
}
|
||||
///
|
||||
|
@ -144,7 +144,6 @@ char *password, *t;
|
||||
|
||||
if ((n = dcb_read(dcb, &head)) != -1)
|
||||
{
|
||||
dcb->state = DCB_STATE_PROCESSING;
|
||||
if (head)
|
||||
{
|
||||
unsigned char *ptr = GWBUF_DATA(head);
|
||||
@ -198,8 +197,6 @@ char *password, *t;
|
||||
}
|
||||
}
|
||||
}
|
||||
dcb->state = DCB_STATE_POLLING;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -269,40 +266,48 @@ int n_connect = 0;
|
||||
int so;
|
||||
struct sockaddr_in addr;
|
||||
socklen_t addrlen = sizeof(struct sockaddr);
|
||||
DCB *client;
|
||||
DCB *client_dcb;
|
||||
TELNETD* telnetd_pr = NULL;
|
||||
dcb_state_t old_state = DCB_STATE_UNDEFINED;
|
||||
bool succp = FALSE;
|
||||
|
||||
if ((so = accept(dcb->fd, (struct sockaddr *)&addr, &addrlen)) == -1)
|
||||
so = accept(dcb->fd, (struct sockaddr *)&addr, &addrlen);
|
||||
|
||||
if (so == -1)
|
||||
return n_connect;
|
||||
else
|
||||
{
|
||||
atomic_add(&dcb->stats.n_accepts, 1);
|
||||
if ((client = dcb_alloc()) == NULL)
|
||||
client_dcb = dcb_alloc(DCB_ROLE_REQUEST_HANDLER);
|
||||
|
||||
if (client_dcb == NULL)
|
||||
|
||||
{
|
||||
return n_connect;
|
||||
}
|
||||
client->fd = so;
|
||||
client->remote = strdup(inet_ntoa(addr.sin_addr));
|
||||
memcpy(&client->func, &MyObject, sizeof(GWPROTOCOL));
|
||||
client->session = session_alloc(dcb->session->service, client);
|
||||
client_dcb->fd = so;
|
||||
client_dcb->remote = strdup(inet_ntoa(addr.sin_addr));
|
||||
memcpy(&client_dcb->func, &MyObject, sizeof(GWPROTOCOL));
|
||||
client_dcb->session =
|
||||
session_alloc(dcb->session->service, client_dcb);
|
||||
telnetd_pr = (TELNETD *)malloc(sizeof(TELNETD));
|
||||
client_dcb->protocol = (void *)telnetd_pr;
|
||||
|
||||
client->state = DCB_STATE_IDLE;
|
||||
if ((client->protocol = malloc(sizeof(TELNETD))) == NULL)
|
||||
{
|
||||
dcb_free(client);
|
||||
if (telnetd_pr == NULL)
|
||||
{
|
||||
dcb_add_to_zombieslist(client_dcb);
|
||||
return n_connect;
|
||||
}
|
||||
|
||||
if (poll_add_dcb(client) == -1)
|
||||
if (poll_add_dcb(client_dcb) == -1)
|
||||
{
|
||||
dcb_free(client);
|
||||
dcb_add_to_zombieslist(dcb);
|
||||
return n_connect;
|
||||
}
|
||||
n_connect++;
|
||||
|
||||
((TELNETD *)(client->protocol))->state = TELNETD_STATE_LOGIN;
|
||||
((TELNETD *)(client->protocol))->username = NULL;
|
||||
dcb_printf(client, "MaxScale login: ");
|
||||
client->state = DCB_STATE_POLLING;
|
||||
telnetd_pr->state = TELNETD_STATE_LOGIN;
|
||||
telnetd_pr->username = NULL;
|
||||
dcb_printf(client_dcb, "MaxScale login: ");
|
||||
}
|
||||
}
|
||||
return n_connect;
|
||||
@ -368,8 +373,6 @@ short pnum;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
listener->state = DCB_STATE_LISTENING;
|
||||
listen(listener->fd, SOMAXCONN);
|
||||
|
||||
if (poll_add_dcb(listener) == -1)
|
||||
|
Reference in New Issue
Block a user