Update to version 3.2
This commit is contained in:
@@ -230,7 +230,7 @@ Socket::Device::Status Socket::setNonBlocking(bool nb) {
|
||||
|
||||
|
||||
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
Socket::Status Socket::connect(const std::string &hostname, uint16_t port) {
|
||||
Socket::Status Socket::connect(const std::string &hostname, uint16_t port, int timeout) {
|
||||
if ( _fd != -1 ) {
|
||||
//CAPS_WARNING("closing stale socket");
|
||||
close();
|
||||
@@ -250,7 +250,7 @@ Socket::Status Socket::connect(const std::string &hostname, uint16_t port) {
|
||||
|
||||
int ret = getaddrinfo(hostname.c_str(), strPort.c_str(), &hints, &res);
|
||||
if ( ret ) {
|
||||
CAPS_DEBUG("Test3 Socket::connect(%s:%d): %s",
|
||||
CAPS_DEBUG("Socket::connect(%s:%d): %s",
|
||||
hostname.c_str(), port,
|
||||
#ifndef WIN32
|
||||
strerror(errno));
|
||||
@@ -271,14 +271,46 @@ Socket::Status Socket::connect(const std::string &hostname, uint16_t port) {
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
if ( ::connect(_fd, (struct sockaddr *)&addr, addrlen) == -1 ) {
|
||||
if ( errno != EINPROGRESS ) {
|
||||
setNonBlocking(true);
|
||||
|
||||
int res2 = ::connect(_fd, &addr, addrlen);
|
||||
if ( res2 == -1 ) {
|
||||
if ( errno == EINPROGRESS || errno == EAGAIN ) {
|
||||
fd_set wfds;
|
||||
|
||||
FD_ZERO(&wfds);
|
||||
FD_SET(_fd, &wfds);
|
||||
|
||||
struct timeval tv{timeout, 0};
|
||||
|
||||
int res = select(_fd + 1, nullptr, &wfds, nullptr, &tv);
|
||||
if ( res == -1 ) {
|
||||
close();
|
||||
return ConnectError;
|
||||
}
|
||||
else if ( res ) {
|
||||
res = ::connect(_fd, &addr, addrlen);
|
||||
if ( res == -1 ) {
|
||||
close();
|
||||
CAPS_DEBUG("Socket::connect(%s:%d): %s",
|
||||
hostname.c_str(), port, strerror(errno));
|
||||
return ConnectError;
|
||||
}
|
||||
}
|
||||
else {
|
||||
close();
|
||||
return Timeout;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*CAPS_DEBUG("Socket::connect(%s:%d): %s",
|
||||
hostname.c_str(), port, strerror(errno));*/
|
||||
close();
|
||||
return errno == ETIMEDOUT?Timeout:ConnectError;
|
||||
return errno == ETIMEDOUT ? Timeout : ConnectError;
|
||||
}
|
||||
}
|
||||
|
||||
setNonBlocking(false);
|
||||
#else
|
||||
if ( ::connect(_fd, (struct sockaddr *)&addr, addrlen) == SOCKET_ERROR ) {
|
||||
int err = WSAGetLastError();
|
||||
@@ -445,7 +477,8 @@ int SSLSocket::read(char *data, int len) {
|
||||
|
||||
|
||||
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
Socket::Status SSLSocket::connect(const std::string &hostname, uint16_t port) {
|
||||
Socket::Status SSLSocket::connect(const std::string &hostname, uint16_t port,
|
||||
int timeout) {
|
||||
cleanUp();
|
||||
|
||||
_ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
@@ -469,14 +502,52 @@ Socket::Status SSLSocket::connect(const std::string &hostname, uint16_t port) {
|
||||
SSL_set_fd(_ssl, _fd);
|
||||
SSL_set_shutdown(_ssl, 0);
|
||||
SSL_set_connect_state(_ssl);
|
||||
int err = SSL_connect(_ssl);
|
||||
if ( err < 0 ) {
|
||||
CAPS_ERROR("Failed to connect with SSL, error %d",
|
||||
SSL_get_error(_ssl, err));
|
||||
close();
|
||||
return ConnectError;
|
||||
|
||||
setNonBlocking(true);
|
||||
|
||||
int res = 0;
|
||||
while ( (res = SSL_connect(_ssl)) != 1 ) {
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(_fd, &fds);
|
||||
struct timeval tv{timeout, 0};
|
||||
|
||||
switch ( SSL_get_error(_ssl, res) ) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
res = select(_fd + 1, &fds, nullptr, nullptr, &tv);
|
||||
if ( res == 0 ) {
|
||||
close();
|
||||
return Timeout;
|
||||
}
|
||||
else if ( res == - 1 ) {
|
||||
close();
|
||||
return ConnectError;
|
||||
}
|
||||
|
||||
break;
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
res = select(_fd + 1, nullptr, &fds, nullptr, &tv);
|
||||
if ( res == 0 ) {
|
||||
close();
|
||||
return Timeout;
|
||||
}
|
||||
else if ( res == - 1 ) {
|
||||
close();
|
||||
return ConnectError;
|
||||
}
|
||||
|
||||
break;
|
||||
default: {
|
||||
CAPS_ERROR("Failed to connect with SSL, error %d",
|
||||
SSL_get_error(_ssl, res));
|
||||
close();
|
||||
return ConnectError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setNonBlocking(false);
|
||||
|
||||
return Success;
|
||||
}
|
||||
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
|
||||
Reference in New Issue
Block a user