In gw_connect_to_backend, first create socket, and establish socket connection, then in the end, dcb is added to epoll set.
This commit is contained in:
@ -26,6 +26,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mysql_client_server_protocol.h"
|
#include "mysql_client_server_protocol.h"
|
||||||
|
#include <skygw_types.h>
|
||||||
|
#include <skygw_utils.h>
|
||||||
|
#include <log_manager.h>
|
||||||
|
|
||||||
extern int gw_read_backend_event(DCB* dcb);
|
extern int gw_read_backend_event(DCB* dcb);
|
||||||
extern int gw_write_backend_event(DCB *dcb);
|
extern int gw_write_backend_event(DCB *dcb);
|
||||||
@ -113,14 +116,12 @@ int gw_read_backend_handshake(MySQLProtocol *conn) {
|
|||||||
DCB *dcb = conn->descriptor;
|
DCB *dcb = conn->descriptor;
|
||||||
int n = -1;
|
int n = -1;
|
||||||
uint8_t *payload = NULL;
|
uint8_t *payload = NULL;
|
||||||
unsigned int packet_len = 0;
|
|
||||||
|
|
||||||
if ((n = dcb_read(dcb, &head)) != -1) {
|
if ((n = dcb_read(dcb, &head)) != -1) {
|
||||||
dcb->state = DCB_STATE_PROCESSING;
|
dcb->state = DCB_STATE_PROCESSING;
|
||||||
|
|
||||||
if (head) {
|
if (head) {
|
||||||
payload = GWBUF_DATA(head);
|
payload = GWBUF_DATA(head);
|
||||||
packet_len = gw_mysql_get_byte3(payload);
|
|
||||||
|
|
||||||
// skip the 4 bytes header
|
// skip the 4 bytes header
|
||||||
payload += 4;
|
payload += 4;
|
||||||
@ -153,7 +154,6 @@ int gw_read_backend_handshake(MySQLProtocol *conn) {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int gw_decode_mysql_server_handshake(MySQLProtocol *conn, uint8_t *payload) {
|
int gw_decode_mysql_server_handshake(MySQLProtocol *conn, uint8_t *payload) {
|
||||||
int server_protocol;
|
|
||||||
uint8_t *server_version_end = NULL;
|
uint8_t *server_version_end = NULL;
|
||||||
uint16_t mysql_server_capabilities_one;
|
uint16_t mysql_server_capabilities_one;
|
||||||
uint16_t mysql_server_capabilities_two;
|
uint16_t mysql_server_capabilities_two;
|
||||||
@ -164,9 +164,6 @@ int gw_decode_mysql_server_handshake(MySQLProtocol *conn, uint8_t *payload) {
|
|||||||
int scramble_len;
|
int scramble_len;
|
||||||
uint8_t scramble[GW_MYSQL_SCRAMBLE_SIZE];
|
uint8_t scramble[GW_MYSQL_SCRAMBLE_SIZE];
|
||||||
|
|
||||||
// Get server protocol
|
|
||||||
server_protocol= payload[0];
|
|
||||||
|
|
||||||
payload++;
|
payload++;
|
||||||
|
|
||||||
// Get server version (string)
|
// Get server version (string)
|
||||||
@ -231,14 +228,11 @@ int gw_receive_backend_auth(MySQLProtocol *conn) {
|
|||||||
GWBUF *head = NULL;
|
GWBUF *head = NULL;
|
||||||
DCB *dcb = conn->descriptor;
|
DCB *dcb = conn->descriptor;
|
||||||
uint8_t *ptr = NULL;
|
uint8_t *ptr = NULL;
|
||||||
unsigned int packet_len = 0;
|
|
||||||
|
|
||||||
if ((n = dcb_read(dcb, &head)) != -1) {
|
if ((n = dcb_read(dcb, &head)) != -1) {
|
||||||
dcb->state = DCB_STATE_PROCESSING;
|
dcb->state = DCB_STATE_PROCESSING;
|
||||||
if (head) {
|
if (head) {
|
||||||
ptr = GWBUF_DATA(head);
|
ptr = GWBUF_DATA(head);
|
||||||
packet_len = gw_mysql_get_byte3(ptr);
|
|
||||||
|
|
||||||
// check if the auth is SUCCESFUL
|
// check if the auth is SUCCESFUL
|
||||||
if (ptr[4] == '\x00') {
|
if (ptr[4] == '\x00') {
|
||||||
// Auth is OK
|
// Auth is OK
|
||||||
@ -470,55 +464,75 @@ int gw_do_connect_to_backend(char *host, int port, MySQLProtocol *conn) {
|
|||||||
struct sockaddr_in serv_addr;
|
struct sockaddr_in serv_addr;
|
||||||
int rv;
|
int rv;
|
||||||
int so = 0;
|
int so = 0;
|
||||||
|
int rc = 0; /**< "ok" */
|
||||||
memset(&serv_addr, 0, sizeof serv_addr);
|
memset(&serv_addr, 0, sizeof serv_addr);
|
||||||
serv_addr.sin_family = AF_INET;
|
serv_addr.sin_family = AF_INET;
|
||||||
|
|
||||||
so = socket(AF_INET,SOCK_STREAM,0);
|
so = socket(AF_INET,SOCK_STREAM,0);
|
||||||
|
|
||||||
conn->fd = so;
|
|
||||||
|
|
||||||
if (so < 0) {
|
if (so < 0) {
|
||||||
fprintf(stderr, "Error creating backend socket: [%s] %i\n", strerror(errno), errno);
|
int eno = errno;
|
||||||
/* this is an error */
|
errno = 0;
|
||||||
return -1;
|
skygw_log_write_flush(
|
||||||
|
LOGFILE_ERROR,
|
||||||
|
"%lu [gw_do_connect_to_backend] Failed to create socket "
|
||||||
|
"%d, %s.",
|
||||||
|
pthread_self(),
|
||||||
|
eno,
|
||||||
|
strerror(eno));
|
||||||
|
rc = -1;
|
||||||
|
goto return_rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assign so to the caller dcb, conn->descriptor */
|
/* Assign so to the caller dcb, conn->descriptor */
|
||||||
|
conn->fd = so;
|
||||||
conn->descriptor->fd = so;
|
conn->descriptor->fd = so;
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the dcb in the poll set
|
|
||||||
*/
|
|
||||||
|
|
||||||
poll_add_dcb(conn->descriptor);
|
|
||||||
|
|
||||||
/* prepare for connect */
|
/* prepare for connect */
|
||||||
|
|
||||||
setipaddress(&serv_addr.sin_addr, host);
|
setipaddress(&serv_addr.sin_addr, host);
|
||||||
serv_addr.sin_port = htons(port);
|
serv_addr.sin_port = htons(port);
|
||||||
|
|
||||||
/* set NON BLOCKING here */
|
/* set NON BLOCKING here */
|
||||||
setnonblocking(so);
|
setnonblocking(so);
|
||||||
|
|
||||||
/* do the connect */
|
/* do the connect */
|
||||||
if ((rv = connect(so, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) < 0) {
|
if ((rv = connect(so, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) < 0) {
|
||||||
/* If connection is not yet completed just return 1 */
|
int eno = errno;
|
||||||
if (errno == EINPROGRESS) {
|
errno = 0;
|
||||||
//fprintf(stderr, ">>> Connection is not yet completed for backend server [%s:%i]: errno %i, %s: RV = [%i]\n", host, port, errno, strerror(errno), rv);
|
/* If connection is not yet completed just return 1 */
|
||||||
|
if (eno == EINPROGRESS) {
|
||||||
return 1;
|
int so_error = 0;
|
||||||
|
socklen_t slen = sizeof(so_error);
|
||||||
|
|
||||||
|
rv = getsockopt(so, SOL_SOCKET, SO_ERROR, &so_error, &slen);
|
||||||
|
/**< so_error == 0 means that connect succeed */
|
||||||
|
if (rv < 0 || so_error != 0) {
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* this is a real error */
|
rc = -1;
|
||||||
fprintf(stderr, ">>> ERROR connecting to backend server [%s:%i]: errno %i, %s: RV = [%i]\n", host, port, errno, strerror(errno), rv);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rc != 0) {
|
||||||
|
skygw_log_write_flush(
|
||||||
|
LOGFILE_ERROR,
|
||||||
|
"%lu [gw_do_connect_to_backend] Failed to "
|
||||||
|
"connect to backend server at %s:%d, %d, %s.",
|
||||||
|
pthread_self(),
|
||||||
|
host,
|
||||||
|
port,
|
||||||
|
eno,
|
||||||
|
strerror(eno));
|
||||||
|
}
|
||||||
|
goto return_with_dcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The connection succesfully completed now */
|
return_with_dcb:
|
||||||
|
/**
|
||||||
return 0;
|
* Add the dcb in the poll set
|
||||||
|
*/
|
||||||
|
poll_add_dcb(conn->descriptor);
|
||||||
|
return_rc:
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user