Browse code

Fix fault tolerance problem

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@1211 77e5149b-7576-45b1-b177-96237e5ba77b

Nigel Horne authored on 2004/12/22 03:43:52
Showing 3 changed files
... ...
@@ -1,3 +1,9 @@
1
+Tue Dec 21 18:42:44 GMT 2004 (njh)
2
+----------------------------------
3
+  * clamav-milter:	Fix fault tolerance problem which could cause
4
+	clamav-milter to attempt to talk to a clamd that was down before
5
+	switching to a working clamd
6
+
1 7
 Tue Dec 21 16:44:13 GMT 2004 (njh)
2 8
 ----------------------------------
3 9
   * libclamav/blob.c:	Support for OS/2 - patch by TK
... ...
@@ -620,6 +620,8 @@ Changes
620 620
 0.80dd	19/12/04:	Tidy up non SESSION code
621 621
 0.80ee	19/12/04:	Error didn't appear in SESSIONS mode if LocalSocket set
622 622
 		and neither max-children nor MaxThreads is set.
623
+0.80ff	21/12/04:	Fault tolerance - sometimes attempted to get a STREAM
624
+		from a server that is down
623 625
 
624 626
 INTERNATIONALISATION
625 627
 
... ...
@@ -26,6 +26,9 @@
26 26
  *
27 27
  * Change History:
28 28
  * $Log: clamav-milter.c,v $
29
+ * Revision 1.166  2004/12/21 18:40:38  nigelhorne
30
+ * Fix fault tolerance problem
31
+ *
29 32
  * Revision 1.165  2004/12/19 17:00:28  nigelhorne
30 33
  * Ensure --max-children > 0 in LocalSocket mode with SESSIONS
31 34
  *
... ...
@@ -506,9 +509,9 @@
506 506
  * Revision 1.6  2003/09/28 16:37:23  nigelhorne
507 507
  * Added -f flag use MaxThreads if --max-children not set
508 508
  */
509
-static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.165 2004/12/19 17:00:28 nigelhorne Exp $";
509
+static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.166 2004/12/21 18:40:38 nigelhorne Exp $";
510 510
 
511
-#define	CM_VERSION	"0.80ee"
511
+#define	CM_VERSION	"0.80ff"
512 512
 
513 513
 #if HAVE_CONFIG_H
514 514
 #include "clamav-config.h"
... ...
@@ -1870,7 +1873,7 @@ main(int argc, char **argv)
1870 1870
 static int
1871 1871
 createSession(int s)
1872 1872
 {
1873
-	int ret = 0;
1873
+	int ret = 0, fd;
1874 1874
 	struct sockaddr_in server;
1875 1875
 	const int serverNumber = s % numServers;
1876 1876
 	struct session *session = &sessions[s];
... ...
@@ -1883,13 +1886,14 @@ createSession(int s)
1883 1883
 
1884 1884
 	server.sin_addr.s_addr = serverIPs[serverNumber];
1885 1885
 
1886
-	if((session->sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
1886
+	session->sock = -1;
1887
+	if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
1887 1888
 		perror("socket");
1888 1889
 		ret = -1;
1889
-	} else if(connect(session->sock, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0) {
1890
+	} else if(connect(fd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0) {
1890 1891
 		perror("connect");
1891 1892
 		ret = 1;
1892
-	} else if(send(session->sock, "SESSION\n", 7, 0) < 7) {
1893
+	} else if(send(fd, "SESSION\n", 7, 0) < 7) {
1893 1894
 		perror("send");
1894 1895
 		ret = 1;
1895 1896
 	}
... ...
@@ -1903,10 +1907,10 @@ createSession(int s)
1903 1903
 		char *hostname = cli_strtok(serverHostNames, serverNumber, ":");
1904 1904
 #endif
1905 1905
 
1906
-		if(session->sock >= 0) {
1907
-			close(session->sock);
1908
-			session->sock = -1;
1909
-		}
1906
+		session->status = CMDSOCKET_DOWN;
1907
+
1908
+		if(fd >= 0)
1909
+			close(fd);
1910 1910
 
1911 1911
 		cli_warnmsg(_("Check clamd server %s - it may be down\n"), hostname);
1912 1912
 #ifndef	MAXHOSTNAMELEN
... ...
@@ -1914,9 +1918,8 @@ createSession(int s)
1914 1914
 #endif
1915 1915
 
1916 1916
 		broadcast(_("Check clamd server - it may be down\n"));
1917
-
1918
-		session->status = CMDSOCKET_DOWN;
1919 1917
 	}
1918
+	session->sock = fd;
1920 1919
 
1921 1920
 	return ret;
1922 1921
 }
... ...
@@ -2057,13 +2060,14 @@ findServer(void)
2057 2057
 
2058 2058
 	pthread_mutex_lock(&sstatus_mutex);
2059 2059
 	for(; i < max_children; i++) {
2060
-		session = &sessions[(j + i) % max_children];
2061
-		cli_dbgmsg("findServer: try server %d\n",
2062
-			(j + i) % max_children);
2060
+		const int sess = (j + i) % max_children;
2061
+
2062
+		session = &sessions[sess];
2063
+		cli_dbgmsg("findServer: try server %d\n", sess);
2063 2064
 		if(session->status == CMDSOCKET_FREE) {
2064 2065
 			session->status = CMDSOCKET_INUSE;
2065 2066
 			pthread_mutex_unlock(&sstatus_mutex);
2066
-			return i;
2067
+			return sess;
2067 2068
 		}
2068 2069
 	}
2069 2070
 	pthread_mutex_unlock(&sstatus_mutex);
... ...
@@ -3859,10 +3863,10 @@ connect2clamd(struct privdata *privdata)
3859 3859
 					goto end;
3860 3860
 			}
3861 3861
 		}
3862
-		cli_dbgmsg("connect2clamd(%d): STREAM\n", freeServer);
3862
+		cli_dbgmsg("connect2clamd(%d): STREAM\n", freeServer); 
3863 3863
 
3864 3864
 		session = &sessions[freeServer];
3865
-		if(send(session->sock, "STREAM\n", 7, 0) < 7) {
3865
+		if((session->sock < 0) || send(session->sock, "STREAM\n", 7, 0) < 7) {
3866 3866
 			perror("send");
3867 3867
 			pthread_mutex_lock(&sstatus_mutex);
3868 3868
 			session->status = CMDSOCKET_DOWN;
... ...
@@ -3904,6 +3908,8 @@ connect2clamd(struct privdata *privdata)
3904 3904
 				perror("recv");
3905 3905
 				if(use_syslog)
3906 3906
 					syslog(LOG_ERR, _("recv failed from clamd getting PORT"));
3907
+				cli_warnmsg("Failed get PORT from server %d (fd %d) errno %d\n",
3908
+					freeServer, session->sock, errno);
3907 3909
 			} else if(use_syslog)
3908 3910
 				syslog(LOG_ERR, _("EOF from clamd getting PORT"));
3909 3911
 			pthread_mutex_lock(&sstatus_mutex);