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 [EMAIL PROTECTED]
--- 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; }