aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
Diffstat (limited to 'camel')
-rw-r--r--camel/ChangeLog16
-rw-r--r--camel/camel-file-utils.c63
-rw-r--r--camel/camel-tcp-stream-ssl.c77
-rw-r--r--camel/providers/imap/camel-imap-store.c13
4 files changed, 95 insertions, 74 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index cba0110ce0..864fafa413 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,19 @@
+2004-05-06 Not Zed <NotZed@Ximian.com>
+
+ * providers/imap/camel-imap-store.c (connect_to_server): set
+ nodelay and keepalive on the socket.
+
+ * camel-file-utils.c (camel_read): put a timeout on the select.
+ Logic shuffle to match the ssl stuff.
+ (camel_write): Similar.
+
+ * camel-tcp-stream-ssl.c (stream_connect): remove timeout, use
+ CONNECT_TIMEOUT directly.
+ (stream_read): put a timeout on the poll. IO_TIMEOUT. And a
+ little logic shuffle.
+ (stream_write): similar.
+ (CONNECT_TIMEOUT): make this 4 minutes === tcp-raw timeout.
+
2004-05-05 Not Zed <NotZed@Ximian.com>
* providers/imap/camel-imap-folder.c (get_message_simple): dont
diff --git a/camel/camel-file-utils.c b/camel/camel-file-utils.c
index 0d51795e32..f04cfa8278 100644
--- a/camel/camel-file-utils.c
+++ b/camel/camel-file-utils.c
@@ -43,6 +43,7 @@
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
+#define IO_TIMEOUT (60*4)
/**
* camel_file_util_encode_uint32:
@@ -404,27 +405,32 @@ camel_read (int fd, char *buf, size_t n)
fcntl (fd, F_SETFL, flags | O_NONBLOCK);
do {
+ struct timeval tv;
+ int res;
+
FD_ZERO (&rdset);
FD_SET (fd, &rdset);
FD_SET (cancel_fd, &rdset);
fdmax = MAX (fd, cancel_fd) + 1;
-
+ tv.tv_sec = IO_TIMEOUT;
+ tv.tv_usec = 0;
nread = -1;
- if (select (fdmax, &rdset, 0, 0, NULL) != -1) {
- if (FD_ISSET (cancel_fd, &rdset)) {
- fcntl (fd, F_SETFL, flags);
- errno = EINTR;
- return -1;
- }
-
+
+ res = select(fdmax, &rdset, 0, 0, &tv);
+ if (res == -1)
+ ;
+ else if (res == 0)
+ errno = ETIMEDOUT;
+ else if (FD_ISSET (cancel_fd, &rdset)) {
+ errno = EINTR;
+ goto failed;
+ } else {
do {
nread = read (fd, buf, n);
} while (nread == -1 && errno == EINTR);
- } else if (errno == EINTR) {
- errno = EAGAIN;
}
- } while (nread == -1 && (errno == EAGAIN || errno == EWOULDBLOCK));
-
+ } while (nread == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
+ failed:
errnosav = errno;
fcntl (fd, F_SETFL, flags);
errno = errnosav;
@@ -475,36 +481,35 @@ camel_write (int fd, const char *buf, size_t n)
fdmax = MAX (fd, cancel_fd) + 1;
do {
+ struct timeval tv;
+ int res;
+
FD_ZERO (&rdset);
FD_ZERO (&wrset);
FD_SET (fd, &wrset);
FD_SET (cancel_fd, &rdset);
-
+ tv.tv_sec = IO_TIMEOUT;
+ tv.tv_usec = 0;
w = -1;
- if (select (fdmax, &rdset, &wrset, 0, NULL) != -1) {
- if (FD_ISSET (cancel_fd, &rdset)) {
- fcntl (fd, F_SETFL, flags);
- errno = EINTR;
- return -1;
- }
-
+
+ res = select (fdmax, &rdset, &wrset, 0, &tv);
+ if (res == -1) {
+ if (errno == EINTR)
+ w = 0;
+ } else if (res == 0)
+ errno = ETIMEDOUT;
+ else if (FD_ISSET (cancel_fd, &rdset))
+ errno = EINTR;
+ else {
do {
w = write (fd, buf + written, n - written);
} while (w == -1 && errno == EINTR);
if (w == -1) {
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
w = 0;
- } else {
- errnosav = errno;
- fcntl (fd, F_SETFL, flags);
- errno = errnosav;
- return -1;
- }
} else
written += w;
- } else if (errno == EINTR) {
- w = 0;
}
} while (w != -1 && written < n);
diff --git a/camel/camel-tcp-stream-ssl.c b/camel/camel-tcp-stream-ssl.c
index 1c8f1b34de..fd6f4ff550 100644
--- a/camel/camel-tcp-stream-ssl.c
+++ b/camel/camel-tcp-stream-ssl.c
@@ -65,6 +65,8 @@
/* from md5-utils.h */
void md5_get_digest (const char *buffer, int buffer_size, unsigned char digest[16]);
+#define IO_TIMEOUT (PR_TicksPerSecond() * 4 * 60)
+#define CONNECT_TIMEOUT (PR_TicksPerSecond () * 4 * 60)
static CamelTcpStreamClass *parent_class = NULL;
@@ -342,37 +344,38 @@ stream_read (CamelStream *stream, char *buffer, size_t n)
nonblock = sockopts.value.non_blocking;
sockopts.value.non_blocking = TRUE;
PR_SetSocketOption (tcp_stream_ssl->priv->sockfd, &sockopts);
-
+
pollfds[0].fd = tcp_stream_ssl->priv->sockfd;
pollfds[0].in_flags = PR_POLL_READ;
pollfds[1].fd = cancel_fd;
pollfds[1].in_flags = PR_POLL_READ;
do {
+ PRInt32 res;
+
pollfds[0].out_flags = 0;
pollfds[1].out_flags = 0;
-
nread = -1;
- if (PR_Poll (pollfds, 2, -1) != -1) {
- if (pollfds[1].out_flags == PR_POLL_READ) {
- sockopts.option = PR_SockOpt_Nonblocking;
- sockopts.value.non_blocking = nonblock;
- PR_SetSocketOption (tcp_stream_ssl->priv->sockfd, &sockopts);
- errno = EINTR;
- return -1;
- }
-
+
+ res = PR_Poll(pollfds, 2, IO_TIMEOUT);
+ if (res == -1)
+ set_errno(PR_GetError());
+ else if (res == 0)
+ errno = ETIMEDOUT;
+ else if (pollfds[1].out_flags == PR_POLL_READ) {
+ errno = EINTR;
+ goto failed;
+ } else {
do {
nread = PR_Read (tcp_stream_ssl->priv->sockfd, buffer, n);
if (nread == -1)
set_errno (PR_GetError ());
} while (nread == -1 && errno == EINTR);
- } else {
- errno = EAGAIN;
}
} while (nread == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
/* restore O_NONBLOCK options */
+ failed:
error = errno;
sockopts.option = PR_SockOpt_Nonblocking;
sockopts.value.non_blocking = nonblock;
@@ -427,19 +430,22 @@ stream_write (CamelStream *stream, const char *buffer, size_t n)
pollfds[1].in_flags = PR_POLL_READ;
do {
+ PRInt32 res;
+
pollfds[0].out_flags = 0;
pollfds[1].out_flags = 0;
-
w = -1;
- if (PR_Poll (pollfds, 2, -1) != -1) {
- if (pollfds[1].out_flags == PR_POLL_READ) {
- sockopts.option = PR_SockOpt_Nonblocking;
- sockopts.value.non_blocking = nonblock;
- PR_SetSocketOption (tcp_stream_ssl->priv->sockfd, &sockopts);
- errno = EINTR;
- return -1;
- }
-
+
+ res = PR_Poll (pollfds, 2, IO_TIMEOUT);
+ if (res == -1) {
+ set_errno(PR_GetError());
+ if (errno == EINTR)
+ w = 0;
+ } else if (res == 0)
+ errno = ETIMEDOUT;
+ else if (pollfds[1].out_flags == PR_POLL_READ) {
+ errno = EINTR;
+ } else {
do {
w = PR_Write (tcp_stream_ssl->priv->sockfd, buffer + written, n - written);
if (w == -1)
@@ -447,22 +453,10 @@ stream_write (CamelStream *stream, const char *buffer, size_t n)
} while (w == -1 && errno == EINTR);
if (w == -1) {
- if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
w = 0;
- } else {
- error = errno;
- sockopts.option = PR_SockOpt_Nonblocking;
- sockopts.value.non_blocking = nonblock;
- PR_SetSocketOption (tcp_stream_ssl->priv->sockfd, &sockopts);
- errno = error;
- return -1;
- }
} else
written += w;
- } else {
- set_errno (PR_GetError ());
- if (errno == EINTR)
- w = 0;
}
} while (w != -1 && written < n);
@@ -1028,13 +1022,10 @@ enable_ssl (CamelTcpStreamSSL *ssl, PRFileDesc *fd)
return ssl_fd;
}
-#define CONNECT_TIMEOUT PR_TicksPerSecond () * 120
-
static int
stream_connect (CamelTcpStream *stream, struct hostent *host, int port)
{
CamelTcpStreamSSL *ssl = CAMEL_TCP_STREAM_SSL (stream);
- PRIntervalTime timeout = CONNECT_TIMEOUT;
PRNetAddr netaddr;
PRFileDesc *fd;
@@ -1079,7 +1070,7 @@ stream_connect (CamelTcpStream *stream, struct hostent *host, int port)
fd = ssl_fd;
}
- if (PR_Connect (fd, &netaddr, timeout) == PR_FAILURE) {
+ if (PR_Connect (fd, &netaddr, CONNECT_TIMEOUT) == PR_FAILURE) {
int errnosave;
set_errno (PR_GetError ());
@@ -1092,9 +1083,7 @@ stream_connect (CamelTcpStream *stream, struct hostent *host, int port)
poll.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
poll.out_flags = 0;
- timeout = CONNECT_TIMEOUT;
-
- if (PR_Poll (&poll, 1, timeout) == PR_FAILURE) {
+ if (PR_Poll (&poll, 1, CONNECT_TIMEOUT) == PR_FAILURE) {
set_errno (PR_GetError ());
goto exception;
}
@@ -1121,7 +1110,7 @@ stream_connect (CamelTcpStream *stream, struct hostent *host, int port)
}
ssl->priv->sockfd = fd;
-
+
return 0;
}
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index 146585e85c..da4a57b255 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -519,6 +519,7 @@ connect_to_server (CamelService *service, int ssl_mode, int try_starttls, CamelE
CamelImapStore *store = (CamelImapStore *) service;
CamelImapResponse *response;
CamelStream *tcp_stream;
+ CamelSockOptData sockopt;
struct hostent *h;
int clean_quit;
int port, ret;
@@ -576,7 +577,17 @@ connect_to_server (CamelService *service, int ssl_mode, int try_starttls, CamelE
store->connected = TRUE;
store->preauthed = FALSE;
store->command = 0;
-
+
+ /* Disable Nagle - we send a lot of small requests which nagle slows down */
+ sockopt.option = CAMEL_SOCKOPT_NODELAY;
+ sockopt.value.no_delay = TRUE;
+ camel_tcp_stream_setsockopt((CamelTcpStream *)tcp_stream, &sockopt);
+
+ /* Set keepalive - needed for some hosts/router configurations, we're idle a lot */
+ sockopt.option = CAMEL_SOCKOPT_KEEPALIVE;
+ sockopt.value.keep_alive = TRUE;
+ camel_tcp_stream_setsockopt((CamelTcpStream *)tcp_stream, &sockopt);
+
/* Read the greeting, if any, and deal with PREAUTH */
if (camel_imap_store_readline (store, &buf, ex) < 0) {
if (store->istream) {