Connection time out.
This commit is contained in:
parent
7a51887dba
commit
d6a8b099ed
@ -99,7 +99,7 @@ void IMAPConnection::connect()
|
|||||||
m_timeoutHandler = store->getTimeoutHandlerFactory()->create();
|
m_timeoutHandler = store->getTimeoutHandlerFactory()->create();
|
||||||
|
|
||||||
// Create and connect the socket
|
// Create and connect the socket
|
||||||
m_socket = store->getSocketFactory()->create();
|
m_socket = store->getSocketFactory()->create(m_timeoutHandler);
|
||||||
|
|
||||||
#if VMIME_HAVE_TLS_SUPPORT
|
#if VMIME_HAVE_TLS_SUPPORT
|
||||||
if (store->isIMAPS()) // dedicated port/IMAPS
|
if (store->isIMAPS()) // dedicated port/IMAPS
|
||||||
|
@ -138,7 +138,7 @@ void POP3Store::connect()
|
|||||||
m_timeoutHandler = getTimeoutHandlerFactory()->create();
|
m_timeoutHandler = getTimeoutHandlerFactory()->create();
|
||||||
|
|
||||||
// Create and connect the socket
|
// Create and connect the socket
|
||||||
m_socket = getSocketFactory()->create();
|
m_socket = getSocketFactory()->create(m_timeoutHandler);
|
||||||
|
|
||||||
#if VMIME_HAVE_TLS_SUPPORT
|
#if VMIME_HAVE_TLS_SUPPORT
|
||||||
if (m_isPOP3S) // dedicated port/POP3S
|
if (m_isPOP3S) // dedicated port/POP3S
|
||||||
|
@ -100,7 +100,7 @@ void SMTPTransport::connect()
|
|||||||
m_timeoutHandler = getTimeoutHandlerFactory()->create();
|
m_timeoutHandler = getTimeoutHandlerFactory()->create();
|
||||||
|
|
||||||
// Create and connect the socket
|
// Create and connect the socket
|
||||||
m_socket = getSocketFactory()->create();
|
m_socket = getSocketFactory()->create(m_timeoutHandler);
|
||||||
|
|
||||||
#if VMIME_HAVE_TLS_SUPPORT
|
#if VMIME_HAVE_TLS_SUPPORT
|
||||||
if (m_isSMTPS) // dedicated port/SMTPS
|
if (m_isSMTPS) // dedicated port/SMTPS
|
||||||
|
@ -49,8 +49,8 @@ namespace posix {
|
|||||||
// posixSocket
|
// posixSocket
|
||||||
//
|
//
|
||||||
|
|
||||||
posixSocket::posixSocket()
|
posixSocket::posixSocket(ref <vmime::net::timeoutHandler> th)
|
||||||
: m_desc(-1)
|
: 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)
|
if (sock < 0)
|
||||||
continue; // try next
|
continue; // try next
|
||||||
|
|
||||||
if (::connect(sock, res->ai_addr, res->ai_addrlen) < 0)
|
if (m_timeoutHandler != NULL)
|
||||||
{
|
{
|
||||||
::close(sock);
|
::fcntl(sock, F_SETFL, ::fcntl(sock, F_GETFL) | O_NONBLOCK);
|
||||||
sock = -1;
|
|
||||||
continue; // try next
|
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()
|
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>();
|
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/base.hpp"
|
||||||
|
|
||||||
|
#include "vmime/net/timeoutHandler.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime {
|
namespace vmime {
|
||||||
namespace net {
|
namespace net {
|
||||||
@ -117,7 +119,18 @@ public:
|
|||||||
|
|
||||||
virtual ~socketFactory() { }
|
virtual ~socketFactory() { }
|
||||||
|
|
||||||
|
/** Creates a socket without timeout handler.
|
||||||
|
*
|
||||||
|
* @return a new socket
|
||||||
|
*/
|
||||||
virtual ref <socket> create() = 0;
|
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:
|
public:
|
||||||
|
|
||||||
posixSocket();
|
posixSocket(ref <vmime::net::timeoutHandler> th);
|
||||||
~posixSocket();
|
~posixSocket();
|
||||||
|
|
||||||
void connect(const vmime::string& address, const vmime::port_t port);
|
void connect(const vmime::string& address, const vmime::port_t port);
|
||||||
@ -61,6 +61,8 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
ref <vmime::net::timeoutHandler> m_timeoutHandler;
|
||||||
|
|
||||||
char m_buffer[65536];
|
char m_buffer[65536];
|
||||||
int m_desc;
|
int m_desc;
|
||||||
};
|
};
|
||||||
@ -72,6 +74,7 @@ class posixSocketFactory : public vmime::net::socketFactory
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
ref <vmime::net::socket> create();
|
ref <vmime::net::socket> create();
|
||||||
|
ref <vmime::net::socket> create(ref <vmime::net::timeoutHandler> th);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user