64
64
static drizzle_return_t _setsockopt(drizzle_st *con);
66
static void __closesocket(int& fd)
70
(void)shutdown(fd, SHUT_RDWR);
71
(void)closesocket(fd);
66
76
static bool connect_poll(drizzle_st *con)
68
78
struct pollfd fds[1];
69
79
fds[0].fd= con->fd;
70
fds[0].events= POLLOUT;
80
fds[0].events= POLLIN;
82
size_t loop_max= 5; // This should only be used for EINTR
73
83
while (--loop_max) // Should only loop on cases of ERESTART or EINTR
75
85
int error= poll(fds, 1, con->timeout);
88
if (fds[0].revents & (POLLIN))
90
drizzle_log_crazy(con, "poll(POLLIN)");
94
if (fds[0].revents & (POLLOUT))
96
drizzle_log_crazy(con, "poll(POLLOUT)");
100
if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL))
81
103
socklen_t len= sizeof (err);
94
117
// "getsockopt() failed"
100
// "timeout occurred while trying to connect"
104
default: // A real error occurred and we need to completely bail
105
switch (get_socket_errno())
127
// "timeout occurred while trying to connect"
128
drizzle_log_crazy(con, "poll(TIMEOUT) %d", con->timeout);
133
switch (get_socket_errno())
107
135
#ifdef TARGET_OS_LINUX
119
// "RLIMIT_NOFILE exceeded, or if OSX the timeout value was invalid"
122
default: // This should not happen
123
if (fds[0].revents & POLLERR)
126
socklen_t len= sizeof (err);
127
(void)getsockopt(con->fd, SOL_SOCKET, SO_ERROR, &err, &len);
132
errno= get_socket_errno();
135
//"socket error occurred");
147
// "RLIMIT_NOFILE exceeded, or if OSX the timeout value was invalid"
154
//"socket error occurred");
141
158
// This should only be possible from ERESTART or EINTR;
586
602
drizzle_return_t drizzle_quit(drizzle_st *con)
588
drizzle_return_t ret;
589
drizzle_result_st *result;
590
result= drizzle_command_write(con, NULL, DRIZZLE_COMMAND_QUIT, NULL, 0,
592
drizzle_result_free(result);
606
drizzle_log_crazy(con, "shutting down the connection");
607
con->flags.is_shutdown= true;
608
drizzle_return_t ret;
609
drizzle_result_st *result;
610
result= drizzle_command_write(con, NULL, DRIZZLE_COMMAND_QUIT, NULL, 0, 0, &ret);
611
drizzle_result_free(result);
614
if (ret == DRIZZLE_RETURN_LOST_CONNECTION)
616
return DRIZZLE_RETURN_OK;
622
return DRIZZLE_RETURN_INVALID_ARGUMENT;
597
625
drizzle_result_st *drizzle_select_db(drizzle_st *con,
786
813
switch (con->socket_type)
788
815
case DRIZZLE_CON_SOCKET_TCP:
789
tcp= &(con->socket.tcp);
791
if (tcp->addrinfo != NULL)
793
freeaddrinfo(tcp->addrinfo);
799
snprintf(port, NI_MAXSERV, "%u", tcp->port);
803
snprintf(port, NI_MAXSERV, "%u", DRIZZLE_DEFAULT_TCP_PORT);
805
port[NI_MAXSERV-1]= 0;
807
memset(&ai, 0, sizeof(struct addrinfo));
808
ai.ai_socktype= SOCK_STREAM;
809
ai.ai_protocol= IPPROTO_TCP;
810
ai.ai_flags = AI_PASSIVE;
811
ai.ai_family = AF_UNSPEC;
813
if (tcp->host == NULL)
815
host= DRIZZLE_DEFAULT_TCP_HOST;
822
ret= getaddrinfo(host, port, &ai, &(tcp->addrinfo));
825
drizzle_set_error(con, "drizzle_state_addrinfo", "getaddrinfo:%s", gai_strerror(ret));
826
return DRIZZLE_RETURN_GETADDRINFO;
829
con->addrinfo_next= tcp->addrinfo;
817
tcp= &(con->socket.tcp);
819
if (tcp->addrinfo != NULL)
821
freeaddrinfo(tcp->addrinfo);
827
snprintf(port, NI_MAXSERV, "%u", tcp->port);
831
snprintf(port, NI_MAXSERV, "%u", DRIZZLE_DEFAULT_TCP_PORT);
833
port[NI_MAXSERV-1]= 0;
835
memset(&ai, 0, sizeof(struct addrinfo));
836
ai.ai_socktype= SOCK_STREAM;
837
ai.ai_protocol= IPPROTO_TCP;
838
ai.ai_family= AF_UNSPEC;
840
if (tcp->host == NULL)
842
host= DRIZZLE_DEFAULT_TCP_HOST;
849
drizzle_log_crazy(con, "host=%s port=%s", host, port);
850
int ret= getaddrinfo(host, port, &ai, &(tcp->addrinfo));
853
drizzle_set_error(con, "drizzle_state_addrinfo", "getaddrinfo:%s", gai_strerror(ret));
854
return DRIZZLE_RETURN_GETADDRINFO;
857
con->addrinfo_next= tcp->addrinfo;
1095
1120
* returns EAGAIN. This improves performance. */
1096
1121
ret= drizzle_set_events(con, POLLIN);
1097
1122
if (ret != DRIZZLE_RETURN_OK)
1099
1127
return DRIZZLE_RETURN_IO_WAIT;
1104
size_t available_buffer= (size_t)DRIZZLE_MAX_BUFFER_SIZE -
1105
((size_t)(con->buffer_ptr - con->buffer) + con->buffer_size);
1132
size_t available_buffer= (size_t)DRIZZLE_MAX_BUFFER_SIZE - ((size_t)(con->buffer_ptr - con->buffer) + con->buffer_size);
1106
1134
#ifdef USE_OPENSSL
1107
1135
if (con->ssl_state == DRIZZLE_SSL_STATE_HANDSHAKE_COMPLETE)
1108
1137
read_size= SSL_read(con->ssl, (char*)con->buffer_ptr + con->buffer_size, available_buffer);
1111
1142
read_size= recv(con->fd, (char *)con->buffer_ptr + con->buffer_size, available_buffer, MSG_NOSIGNAL);
1113
errno = WSAGetLastError();
1116
case WSAEWOULDBLOCK:
1123
case WSAECONNREFUSED:
1124
errno= ECONNREFUSED;
1126
case WSAENETUNREACH:
1141
case WSAENOPROTOOPT:
1147
errno= WSAGetLastError();
1151
case WSAEWOULDBLOCK:
1158
case WSAECONNREFUSED:
1159
errno= ECONNREFUSED;
1161
case WSAENETUNREACH:
1176
case WSAENOPROTOOPT:
1147
1183
#endif /* _WIN32 */
1148
drizzle_log_crazy(con, "read fd=%d return=%zd ssl= %d errno=%s",
1185
drizzle_log_crazy(con, "read fd=%d recv=%zd ssl= %d errno=%s",
1149
1186
con->fd, read_size,
1150
1187
(con->ssl_state == DRIZZLE_SSL_STATE_HANDSHAKE_COMPLETE) ? 1 : 0,
1151
1188
strerror(errno));
1153
1190
if (read_size == 0)
1155
drizzle_set_error(con, __func__,
1156
"%s:%d lost connection to server (EOF)", __FILE__, __LINE__);
1192
if (con->flags.is_shutdown == false)
1194
drizzle_set_error(con, __func__,
1195
"%s:%d lost connection to server (EOF)", __FILE__, __LINE__);
1157
1198
return DRIZZLE_RETURN_LOST_CONNECTION;
1159
1200
else if (read_size == -1)
1161
if (errno == EAGAIN)
1163
/* clear the read ready flag */
1164
con->revents&= ~POLLIN;
1165
ret= drizzle_set_events(con, POLLIN);
1166
if (ret != DRIZZLE_RETURN_OK)
1169
if (con->options & DRIZZLE_CON_OPTIONS_NON_BLOCKING)
1170
return DRIZZLE_RETURN_IO_WAIT;
1172
ret= drizzle_wait(con);
1173
if (ret != DRIZZLE_RETURN_OK)
1178
else if (errno == ECONNREFUSED)
1181
drizzle_state_pop(con);
1182
drizzle_state_push(con, drizzle_state_connect);
1183
con->addrinfo_next= con->addrinfo_next->ai_next;
1184
return DRIZZLE_RETURN_OK;
1186
else if (errno == EINTR)
1190
else if (errno == EPIPE || errno == ECONNRESET)
1192
drizzle_set_error(con, __func__,
1193
"%s:%d lost connection to server (%s)",
1194
__FILE__, __LINE__, strerror(errno));
1195
return DRIZZLE_RETURN_LOST_CONNECTION;
1198
drizzle_set_error(con, __func__, "read:%s", strerror(errno));
1202
// switch (get_socket_errno())
1206
#if EWOULDBLOCK != EAGAIN
1210
/* clear the read ready flag */
1211
con->revents&= ~POLLIN;
1212
ret= drizzle_set_events(con, POLLIN);
1213
if (ret != DRIZZLE_RETURN_OK)
1218
if (con->options & DRIZZLE_CON_OPTIONS_NON_BLOCKING)
1220
return DRIZZLE_RETURN_IO_WAIT;
1223
ret= drizzle_wait(con);
1224
if (ret != DRIZZLE_RETURN_OK)
1234
drizzle_state_pop(con);
1235
drizzle_state_push(con, drizzle_state_connect);
1236
con->addrinfo_next= con->addrinfo_next->ai_next;
1237
return DRIZZLE_RETURN_OK;
1245
drizzle_log_crazy(con, "EINVAL fd=%d buffer=%p available_buffer=%zd",
1246
con->fd, (char *)con->buffer_ptr + con->buffer_size, available_buffer);
1253
drizzle_set_error(con, __func__,
1254
"%s:%d lost connection to server (%s)",
1255
__FILE__, __LINE__, strerror(errno));
1256
return DRIZZLE_RETURN_LOST_CONNECTION;
1260
drizzle_set_error(con, __func__, "recv:%s", strerror(errno));
1199
1261
con->last_errno= errno;
1200
1262
return DRIZZLE_RETURN_ERRNO;