]> Pileus Git - ~andy/fetchmail/commitdiff
Revert "Use SO_???TIMEO, to fix hangs during STARTTLS negotiation."
authorMatthias Andree <matthias.andree@gmx.de>
Sun, 19 Jun 2011 17:52:20 +0000 (19:52 +0200)
committerMatthias Andree <matthias.andree@gmx.de>
Sun, 19 Jun 2011 17:52:20 +0000 (19:52 +0200)
This feature does not work on, for instance, Solaris 10 and older.

This reverts commit 1a794b3b00bd4b2f720f3426a386d5c86cc65ea8.

driver.c
imap.c
sink.c
smtp.c
socket.c
socket.h
transact.c

index f2cc13c639f733a2afb78fea188a653df0aac934..08bb9775def4280df9dd7ea7528e4dbcdacabc78 100644 (file)
--- a/driver.c
+++ b/driver.c
@@ -109,8 +109,14 @@ static void timeout_handler (int signal)
 static int cleanupSockClose (int fd)
 /* close sockets in maximum CLEANUP_TIMEOUT seconds during cleanup */
 {
-    (void)SockTimeout(fd, CLEANUP_TIMEOUT); /* ignore errors */
-    return SockClose(fd);
+    int scerror;
+    SIGHANDLERTYPE alrmsave;
+    alrmsave = set_signal_handler(SIGALRM, null_signal_handler);
+    set_timeout(CLEANUP_TIMEOUT);
+    scerror = SockClose(fd);
+    set_timeout(0);
+    set_signal_handler(SIGALRM, alrmsave);
+    return (scerror);
 }
 
 #ifdef KERBEROS_V5
diff --git a/imap.c b/imap.c
index 6dd51eeecfc9049277da35ade2b0212f526b46b7..a181b1dbaf4da4916b11ba75356a2528497fc450 100644 (file)
--- a/imap.c
+++ b/imap.c
@@ -723,6 +723,7 @@ static int imap_idle(int sock)
     }
 
     /* restore normal timeout value */
+    set_timeout(0);
     mytimeout = saved_timeout;
     stage = STAGE_GETRANGE;
 
diff --git a/sink.c b/sink.c
index 8da89f4d22bfef75818deddc8a741db198f764eb..6c9b101f74ceb1213ff5759565279dfcbfa80738 100644 (file)
--- a/sink.c
+++ b/sink.c
@@ -116,12 +116,12 @@ int smtp_setup(struct query *ctl)
        oldphase = phase;
        phase = LISTENER_WAIT;
 
+       set_timeout(ctl->server.timeout);
        for (idp = ctl->smtphunt; idp; idp = idp->next)
        {
            char        *cp;
            const char  *portnum = SMTP_PORT;
 
-           set_timeout(ctl->server.timeout);
            ctl->smtphost = idp->id;  /* remember last host tried. */
            if (ctl->smtphost[0]=='/')
            {
@@ -169,7 +169,6 @@ int smtp_setup(struct query *ctl)
             * so it's safest not to assume the socket will still be good.
             */
            smtp_close(ctl, 0);
-           set_timeout(ctl->server.timeout);
 
            /* if opening for ESMTP failed, try SMTP */
            if (ctl->smtphost[0]=='/')
diff --git a/smtp.c b/smtp.c
index d14766019e0525cf03016a4a92b029fc2fc1c451..d831249243192b401831e4ce1ed7f93a0ce0f560 100644 (file)
--- a/smtp.c
+++ b/smtp.c
@@ -171,22 +171,24 @@ int SMTP_ehlo(int sock, char smtp_mode, const char *host, char *name, char *pass
 {
   struct opt *hp;
   char auth_response[511];
+  SIGHANDLERTYPE alrmsave;
   const int tmout = (mytimeout >= TIMEOUT_HELO ? mytimeout : TIMEOUT_HELO);
 
-  if (SockTimeout(sock, tmout) != 0)
-      return SM_UNRECOVERABLE;
-
   SockPrintf(sock,"%cHLO %s\r\n", (smtp_mode == 'S') ? 'E' : smtp_mode, host);
   if (outlevel >= O_MONITOR)
       report(stdout, "%cMTP> %cHLO %s\n", 
            smtp_mode, (smtp_mode == 'S') ? 'E' : smtp_mode, host);
 
+  alrmsave = set_signal_handler(SIGALRM, null_signal_handler);
+  set_timeout(tmout);
+
   *opt = 0;
   while ((SockRead(sock, smtp_response, sizeof(smtp_response)-1)) != -1)
   {
       size_t n;
 
       set_timeout(0);
+      (void)set_signal_handler(SIGALRM, alrmsave);
 
       n = strlen(smtp_response);
       if (n > 0 && smtp_response[n-1] == '\n')
@@ -212,6 +214,9 @@ int SMTP_ehlo(int sock, char smtp_mode, const char *host, char *name, char *pass
       }
       else if (smtp_response[3] != '-')
          return SM_ERROR;
+
+      alrmsave = set_signal_handler(SIGALRM, null_signal_handler);
+      set_timeout(tmout);
   }
   return SM_UNRECOVERABLE;
 }
@@ -306,18 +311,23 @@ int SMTP_ok(int sock, char smtp_mode, int mintimeout)
  * smtp_response, without trailing [CR]LF, but with normalized CRLF
  * between multiple lines of multi-line replies */
 {
+    SIGHANDLERTYPE alrmsave;
     char reply[MSGBUFSIZE], *i;
-    int tmo = mytimeout >= mintimeout ? mytimeout : mintimeout;
 
-    smtp_response[0] = '\0';
+    /* set an alarm for smtp ok */
+    alrmsave = set_signal_handler(SIGALRM, null_signal_handler);
+    set_timeout(mytimeout >= mintimeout ? mytimeout : mintimeout);
 
-    if (SockTimeout(sock, tmo))
-       return SM_UNRECOVERABLE;
+    smtp_response[0] = '\0';
 
     while ((SockRead(sock, reply, sizeof(reply)-1)) != -1)
     {
        size_t n;
 
+       /* restore alarm */
+       set_timeout(0);
+       set_signal_handler(SIGALRM, alrmsave);
+
        n = strlen(reply);
        if (n > 0 && reply[n-1] == '\n')
            reply[--n] = '\0';
@@ -353,8 +363,16 @@ int SMTP_ok(int sock, char smtp_mode, int mintimeout)
            return SM_ERROR;
 
        strlcat(smtp_response, "\r\n", sizeof(smtp_response));
+
+       /* set an alarm for smtp ok */
+       set_signal_handler(SIGALRM, null_signal_handler);
+       set_timeout(mytimeout);
     }
 
+    /* restore alarm */
+    set_timeout(0);
+    set_signal_handler(SIGALRM, alrmsave);
+
     if (outlevel >= O_MONITOR)
        report(stderr, GT_("smtp listener protocol error\n"));
     return SM_UNRECOVERABLE;
index c8117a554ed759ae6f28522d924d17d6515994d9..ab283780bb02056915210a94e4c457ee79a66e57 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -135,10 +135,6 @@ static int handle_plugin(const char *host,
        report(stderr, GT_("fetchmail: socketpair failed\n"));
        return -1;
     }
-
-    if (SockTimeout(fds[0], mytimeout)) return -1;
-    if (SockTimeout(fds[1], mytimeout)) return -1;
-
     switch (fork()) {
        case -1:
                /* error */
@@ -170,32 +166,6 @@ static int handle_plugin(const char *host,
     return fds[1];
 }
 
-static int setsocktimeout(int sock, int which, int timeout) {
-    struct timeval tv;
-    int rc;
-
-    tv.tv_sec = timeout;
-    tv.tv_usec = 0;
-    rc = setsockopt(sock, SOL_SOCKET, which, &tv, sizeof(tv));
-    if (rc) {
-       report(stderr, GT_("setsockopt(%d, SOL_SOCKET) failed: %s"), sock, strerror(errno));
-    }
-    return rc;
-}
-
-/** Configure socket options such as send/receive timeout at the socket
- * level, to avoid network-induced stalls. \return 0 for success, 1 for
- * error.
- */
-int SockTimeout(int sock, int timeout)
-{
-    int err = 0;
-
-    if (setsocktimeout(sock, SO_RCVTIMEO, timeout)) err = 1;
-    if (setsocktimeout(sock, SO_SNDTIMEO, timeout)) err = 1;
-    return err;
-}
-
 /** Set socket to SO_KEEPALIVE. \return 0 for success. */
 int SockKeepalive(int sock) {
     int keepalive = 1;
index 80decac2fb7304f014ed9a5544797b3992724c05..9d9406d958c4eae21dfe3d901807dce816bcf4bf 100644 (file)
--- a/socket.h
+++ b/socket.h
@@ -16,10 +16,6 @@ struct addrinfo;
 /** Create a new client socket; returns -1 on error */
 int SockOpen(const char *host, const char *service, const char *plugin, struct addrinfo **);
 
-/** Sets the send/receive timeouts for socket \a sock to \a timeout
- * seconds. \return zero on success. */
-int SockTimeout(int sock, int timeout);
-
 /** 
 Get a string terminated by an '\n' (matches interface of fgets).
 Pass it a valid socket, a buffer for the string, and
index b36c8d791a10b66aaec5c86ed37aeaa3bc05e623..07aab00eb82b6f78a43f1903c756d5b6511b729a 100644 (file)
@@ -472,13 +472,13 @@ int readheaders(int sock,
            do {
                char    *sp, *tp;
 
-               SockTimeout(sock, mytimeout);
-               n = SockRead(sock, buf, sizeof(buf) - 1);
-
-               if (n == -1) {
+               set_timeout(mytimeout);
+               if ((n = SockRead(sock, buf, sizeof(buf)-1)) == -1) {
+                   set_timeout(0);
                    free(line);
                    return(PS_SOCKET);
                }
+               set_timeout(0);
 
                /*
                 * Smash out any NULs, they could wreak havoc later on.
@@ -603,8 +603,9 @@ eoh:
            }
 
            /* check for RFC822 continuations */
-           SockTimeout(sock, mytimeout);
+           set_timeout(mytimeout);
            ch = SockPeek(sock);
+           set_timeout(0);
        } while
            (ch == ' ' || ch == '\t');  /* continuation to next line? */
 
@@ -1387,16 +1388,17 @@ int readbody(int sock, struct query *ctl, flag forward, int len)
      */
     while (protocol->delimited || len > 0)
     {
-       SockTimeout(sock, mytimeout);
+       set_timeout(mytimeout);
        /* XXX FIXME: for undelimited protocols that ship the size, such
         * as IMAP, we might want to use the count of remaining characters
         * instead of the buffer size -- not for fetchmail 6.3.X though */
-       linelen = SockRead(sock, inbufp, sizeof(buf)-4-(inbufp-buf));
-       if (linelen == -1)
+       if ((linelen = SockRead(sock, inbufp, sizeof(buf)-4-(inbufp-buf)))==-1)
        {
+           set_timeout(0);
            release_sink(ctl);
            return(PS_SOCKET);
        }
+       set_timeout(0);
 
        /* write the message size dots */
        if (linelen > 0)
@@ -1547,15 +1549,13 @@ int gen_recv(int sock  /** socket to which server is connected */,
 {
     size_t n;
     int oldphase = phase;      /* we don't have to be re-entrant */
-    int retval;
 
     phase = SERVER_WAIT;
-    SockTimeout(sock, mytimeout);
-    retval = SockRead(sock, buf, size);
-    phase = oldphase;
-
-    if (retval == -1)
+    set_timeout(mytimeout);
+    if (SockRead(sock, buf, size) == -1)
     {
+       set_timeout(0);
+       phase = oldphase;
        if(is_idletimeout())
        {
          resetidletimeout();
@@ -1574,6 +1574,7 @@ int gen_recv(int sock  /** socket to which server is connected */,
            buf[--n] = '\0';
        if (outlevel >= O_MONITOR)
            report(stdout, "%s< %s\n", protocol->name, buf);
+       phase = oldphase;
        return(PS_SUCCESS);
     }
 }