[PATCH] fud.c : timeout in do_proxy_request

Etienne Goyer etienne.goyer at linuxquebec.com
Wed Jun 4 15:45:10 EDT 2003


Hi,

The fud daemon can proxy request for mailbox that are remote (ie
Murder).  In 2.1.13, the fud daemon will just sit there if the remote
fud is not responding.  It is strange because the recvfrom() is
alarm()'ed; however, the SIGALRM handler do nothing else than clear the
signal.

I am only a beginner Unix/network C programmer so this patch may not be
the correct way to do it or have implication I cannot foresee.  However,
it should demonstrate a way to fix the problem discussed.  Basically, I
got rid of the dead alarm() code and use select() to timeout read from
the remote fud daemon.

Your comment are very welcome.

Regards,

-- 
Etienne Goyer                    Linux Québec Technologies Inc.
http://www.LinuxQuebec.com       etienne.goyer at linuxquebec.com
-------------- next part --------------
--- fud.c.orig	Wed Jun  4 14:19:43 2003
+++ fud.c	Wed Jun  4 15:28:54 2003
@@ -53,6 +53,7 @@
 #include <syslog.h>
 #include <signal.h>
 #include <sys/types.h>
+#include <sys/time.h>
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <netinet/in.h>
@@ -62,6 +63,7 @@
 #include <errno.h>
 #include <com_err.h>
 #include <pwd.h>
+#include <sys/select.h>
 
 #include "assert.h"
 #include "mboxlist.h"
@@ -196,12 +198,6 @@
     shut_down(r);
 }
 
-static void cyrus_timeout(int signo)
-{
-  signo = 0;
-  return;
-}
-
 /* Send a proxy request to the backend, send their reply to sfrom */
 int do_proxy_request(const char *who, const char *name,
 		     const char *backend_host,
@@ -210,8 +206,10 @@
     char tmpbuf[1024];
     int x, rc;
     int csoc = -1;
+    fd_set ssock;
     struct sockaddr_in cin, cout;
     struct hostent *hp;
+    struct timeval tv;
     static int backend_port = 0; /* fud port in NETWORK BYTE ORDER */
 
     /* Open a UDP socket to the Cyrus mail server */
@@ -240,14 +238,24 @@
     /* Send the query and wait for a reply */
     sendto (csoc, tmpbuf, strlen (tmpbuf), 0, (struct sockaddr *) &cin, x);
     memset (tmpbuf, '\0', strlen (tmpbuf));
-    signal (SIGALRM, cyrus_timeout);
     rc = 0;
-    alarm (1);
-    rc = recvfrom (csoc, tmpbuf, sizeof(tmpbuf), 0,
-		   (struct sockaddr *) &cout, &x);
-    alarm (0);
-    if (rc < 1) {
-	rc = IMAP_SERVER_UNAVAILABLE;
+    FD_ZERO(&ssock);
+    FD_SET(csoc, &ssock);
+    tv.tv_sec = 5;
+    tv.tv_usec = 0;
+    rc = select(csoc + 1, &ssock, NULL, NULL, &tv);
+    if (rc > 0) {
+        syslog(LOG_ERR, "Reading sock");
+	rc = recvfrom (csoc, tmpbuf, sizeof(tmpbuf), 0,
+    		   (struct sockaddr *) &cout, &x);
+        if (rc < 1) {
+	    rc = IMAP_SERVER_UNAVAILABLE;
+            send_reply(sfrom, REQ_UNK, who, name, 0, 0, 0);
+            goto done;
+        }
+    } else {
+	syslog(LOG_ERR, "FUD timeout");
+        rc = IMAP_SERVER_UNAVAILABLE;
 	send_reply(sfrom, REQ_UNK, who, name, 0, 0, 0);
 	goto done;
     }


More information about the Info-cyrus mailing list