Connection time out.
This commit is contained in:
parent
7a51887dba
commit
d6a8b099ed
@ -99,7 +99,7 @@ void IMAPConnection::connect()
|
||||
m_timeoutHandler = store->getTimeoutHandlerFactory()->create();
|
||||
|
||||
// Create and connect the socket
|
||||
m_socket = store->getSocketFactory()->create();
|
||||
m_socket = store->getSocketFactory()->create(m_timeoutHandler);
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
if (store->isIMAPS()) // dedicated port/IMAPS
|
||||
|
@ -138,7 +138,7 @@ void POP3Store::connect()
|
||||
m_timeoutHandler = getTimeoutHandlerFactory()->create();
|
||||
|
||||
// Create and connect the socket
|
||||
m_socket = getSocketFactory()->create();
|
||||
m_socket = getSocketFactory()->create(m_timeoutHandler);
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
if (m_isPOP3S) // dedicated port/POP3S
|
||||
|
@ -100,7 +100,7 @@ void SMTPTransport::connect()
|
||||
m_timeoutHandler = getTimeoutHandlerFactory()->create();
|
||||
|
||||
// Create and connect the socket
|
||||
m_socket = getSocketFactory()->create();
|
||||
m_socket = getSocketFactory()->create(m_timeoutHandler);
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
if (m_isSMTPS) // dedicated port/SMTPS
|
||||
|
@ -49,8 +49,8 @@ namespace posix {
|
||||
// posixSocket
|
||||
//
|
||||
|
||||
posixSocket::posixSocket()
|
||||
: m_desc(-1)
|
||||
posixSocket::posixSocket(ref <vmime::net::timeoutHandler> th)
|
||||
: m_timeoutHandler(th), m_desc(-1)
|
||||
{
|
||||
}
|
||||
|
||||
@ -105,11 +105,115 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port
|
||||
if (sock < 0)
|
||||
continue; // try next
|
||||
|
||||
if (::connect(sock, res->ai_addr, res->ai_addrlen) < 0)
|
||||
if (m_timeoutHandler != NULL)
|
||||
{
|
||||
::close(sock);
|
||||
sock = -1;
|
||||
continue; // try next
|
||||
::fcntl(sock, F_SETFL, ::fcntl(sock, F_GETFL) | O_NONBLOCK);
|
||||
|
||||
if (::connect(sock, res->ai_addr, res->ai_addrlen) < 0)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
case 0:
|
||||
case EINPROGRESS:
|
||||
case EINTR:
|
||||
#if defined(EAGAIN)
|
||||
case EAGAIN:
|
||||
#endif // EAGAIN
|
||||
#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
|
||||
case EWOULDBLOCK:
|
||||
#endif // EWOULDBLOCK
|
||||
|
||||
// Connection in progress
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
::close(sock);
|
||||
sock = -1;
|
||||
continue; // try next
|
||||
}
|
||||
|
||||
// Wait for socket to be connected.
|
||||
// We will check for time out every second.
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(sock, &fds);
|
||||
|
||||
fd_set fdsError;
|
||||
FD_ZERO(&fdsError);
|
||||
FD_SET(sock, &fdsError);
|
||||
|
||||
struct timeval tm;
|
||||
tm.tv_sec = 1;
|
||||
tm.tv_usec = 0;
|
||||
|
||||
m_timeoutHandler->resetTimeOut();
|
||||
|
||||
bool connected = false;
|
||||
|
||||
do
|
||||
{
|
||||
const int ret = select(sock + 1, NULL, &fds, &fdsError, &tm);
|
||||
|
||||
// Success
|
||||
if (ret > 0)
|
||||
{
|
||||
connected = true;
|
||||
break;
|
||||
}
|
||||
// Error
|
||||
else if (ret < -1)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
{
|
||||
// Cancel connection
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 1-second timeout
|
||||
else if (ret == 0)
|
||||
{
|
||||
if (m_timeoutHandler->isTimeOut())
|
||||
{
|
||||
if (!m_timeoutHandler->handleTimeOut())
|
||||
{
|
||||
// Cancel connection
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset timeout and keep waiting for connection
|
||||
m_timeoutHandler->resetTimeOut();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keep waiting for connection
|
||||
}
|
||||
}
|
||||
|
||||
::sched_yield();
|
||||
|
||||
} while (true);
|
||||
|
||||
if (!connected)
|
||||
{
|
||||
::close(sock);
|
||||
sock = -1;
|
||||
continue; // try next
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (::connect(sock, res->ai_addr, res->ai_addrlen) < 0)
|
||||
{
|
||||
::close(sock);
|
||||
sock = -1;
|
||||
continue; // try next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,7 +429,14 @@ void posixSocket::throwSocketError(const int err)
|
||||
|
||||
ref <vmime::net::socket> posixSocketFactory::create()
|
||||
{
|
||||
return vmime::create <posixSocket>();
|
||||
ref <vmime::net::timeoutHandler> th = NULL;
|
||||
return vmime::create <posixSocket>(th);
|
||||
}
|
||||
|
||||
|
||||
ref <vmime::net::socket> posixSocketFactory::create(ref <vmime::net::timeoutHandler> th)
|
||||
{
|
||||
return vmime::create <posixSocket>(th);
|
||||
}
|
||||
|
||||
|
||||
|
@ -260,6 +260,11 @@ public:
|
||||
{
|
||||
return vmime::create <T>();
|
||||
}
|
||||
|
||||
vmime::ref <vmime::net::socket> create(vmime::ref <vmime::net::timeoutHandler> /* th */)
|
||||
{
|
||||
return vmime::create <T>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -27,6 +27,8 @@
|
||||
|
||||
#include "vmime/base.hpp"
|
||||
|
||||
#include "vmime/net/timeoutHandler.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
@ -117,7 +119,18 @@ public:
|
||||
|
||||
virtual ~socketFactory() { }
|
||||
|
||||
/** Creates a socket without timeout handler.
|
||||
*
|
||||
* @return a new socket
|
||||
*/
|
||||
virtual ref <socket> create() = 0;
|
||||
|
||||
/** Creates a socket with the specified timeout handler.
|
||||
*
|
||||
* @param th timeout handler
|
||||
* @return a new socket
|
||||
*/
|
||||
virtual ref <socket> create(ref <timeoutHandler> th) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -40,7 +40,7 @@ class posixSocket : public vmime::net::socket
|
||||
{
|
||||
public:
|
||||
|
||||
posixSocket();
|
||||
posixSocket(ref <vmime::net::timeoutHandler> th);
|
||||
~posixSocket();
|
||||
|
||||
void connect(const vmime::string& address, const vmime::port_t port);
|
||||
@ -61,6 +61,8 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
ref <vmime::net::timeoutHandler> m_timeoutHandler;
|
||||
|
||||
char m_buffer[65536];
|
||||
int m_desc;
|
||||
};
|
||||
@ -72,6 +74,7 @@ class posixSocketFactory : public vmime::net::socketFactory
|
||||
public:
|
||||
|
||||
ref <vmime::net::socket> create();
|
||||
ref <vmime::net::socket> create(ref <vmime::net::timeoutHandler> th);
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user