Browse code

Fix crash if 1st host dies

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

Nigel Horne authored on 2004/07/25 20:53:27
Showing 3 changed files
... ...
@@ -1,3 +1,11 @@
1
+Sun Jul 25 12:52:07 BST 2004 (njh)
2
+----------------------------------
3
+  * clamav-milter:	Fixed warning message when building on FreeBSD4.9
4
+			Closed (small) memory leak
5
+			Fix crash when the 1st remote service goes down
6
+			Only use gethostbyname_r on LINUX for now
7
+			Improved load balancing a bit
8
+
1 9
 Fri Jul 23 00:40:18 CEST 2004 (tk)
2 10
 ----------------------------------
3 11
   * configure: yet another Solaris 9 fix
... ...
@@ -439,6 +439,11 @@ Changes
439 439
 		machines running Solaris
440 440
 0.74f	22/7/04	Use gethostbyname_r() if available
441 441
 0.75	22/7/04	Up-issue
442
+0.75a	25/7/04	Fixed warning message when building on FreeBSD4.9
443
+		Closed (small) memory leak
444
+		Fix crash when the 1st remote service goes down
445
+		Only use gethostbyname_r on LINUX for now
446
+		Load balancing - improved a bit - but still some way to go
442 447
 
443 448
 BUG REPORTS
444 449
 
... ...
@@ -26,6 +26,9 @@
26 26
  *
27 27
  * Change History:
28 28
  * $Log: clamav-milter.c,v $
29
+ * Revision 1.109  2004/07/25 11:51:42  nigelhorne
30
+ * Fix crash if 1st host dies
31
+ *
29 32
  * Revision 1.108  2004/07/22 15:45:03  nigelhorne
30 33
  * Up-issue
31 34
  *
... ...
@@ -335,9 +338,9 @@
335 335
  * Revision 1.6  2003/09/28 16:37:23  nigelhorne
336 336
  * Added -f flag use MaxThreads if --max-children not set
337 337
  */
338
-static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.108 2004/07/22 15:45:03 nigelhorne Exp $";
338
+static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.109 2004/07/25 11:51:42 nigelhorne Exp $";
339 339
 
340
-#define	CM_VERSION	"0.75"
340
+#define	CM_VERSION	"0.75a"
341 341
 
342 342
 /*#define	CONFDIR	"/usr/local/etc"*/
343 343
 
... ...
@@ -367,6 +370,7 @@ static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.108 2004/07/22 15:45:03 ni
367 367
 #include <string.h>
368 368
 #include <sys/wait.h>
369 369
 #include <assert.h>
370
+#include <netinet/in.h>
370 371
 #include <arpa/inet.h>
371 372
 #include <sys/socket.h>
372 373
 #include <sys/un.h>
... ...
@@ -375,7 +379,6 @@ static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.108 2004/07/22 15:45:03 ni
375 375
 #include <libmilter/mfapi.h>
376 376
 #include <pthread.h>
377 377
 #include <sys/time.h>
378
-#include <netinet/in.h>
379 378
 #include <signal.h>
380 379
 #include <regex.h>
381 380
 #include <fcntl.h>
... ...
@@ -1104,7 +1107,7 @@ main(int argc, char **argv)
1104 1104
 			if(pingServer(i))
1105 1105
 				activeServers++;
1106 1106
 			else {
1107
-				cli_warnmsg("Warning Can't talk to clamd server %s on port %d\n",
1107
+				cli_warnmsg("Can't talk to clamd server %s on port %d\n",
1108 1108
 					hostname, tcpSocket);
1109 1109
 			}
1110 1110
 			free(hostname);
... ...
@@ -1355,7 +1358,7 @@ static int
1355 1355
 findServer(void)
1356 1356
 {
1357 1357
 	struct sockaddr_in *servers, *server;
1358
-	int *socks, maxsock = 0, i;
1358
+	int *socks, maxsock = 0, i, j;
1359 1359
 	fd_set rfds;
1360 1360
 	struct timeval tv;
1361 1361
 	int retval;
... ...
@@ -1371,12 +1374,17 @@ findServer(void)
1371 1371
 
1372 1372
 	FD_ZERO(&rfds);
1373 1373
 
1374
+	j = n_children - 1;	/* Don't worry about no lock */
1375
+
1374 1376
 	for(i = 0, server = servers; i < numServers; i++, server++) {
1375 1377
 		int sock;
1376 1378
 
1377 1379
 		server->sin_family = AF_INET;
1378 1380
 		server->sin_port = (in_port_t)htons(tcpSocket);
1379
-		server->sin_addr.s_addr = serverIPs[i];
1381
+		server->sin_addr.s_addr = serverIPs[(i + j) % numServers];
1382
+
1383
+		cli_dbgmsg("findServer: try server %d\n",
1384
+			(i + j) % numServers);
1380 1385
 
1381 1386
 		sock = socks[i] = socket(AF_INET, SOCK_STREAM, 0);
1382 1387
 		if(sock < 0) {
... ...
@@ -1392,14 +1400,15 @@ findServer(void)
1392 1392
 
1393 1393
 		if((connect(sock, (struct sockaddr *)server, sizeof(struct sockaddr)) < 0) ||
1394 1394
 		   (send(sock, "PING\n", 5, 0) < 5)) {
1395
-			const char *hostname = cli_strtok(serverHostNames, i, ":");
1395
+			char *hostname = cli_strtok(serverHostNames, i, ":");
1396 1396
 			cli_warnmsg("Check clamd server %s - it may be down\n", hostname);
1397 1397
 			if(use_syslog)
1398 1398
 				syslog(LOG_WARNING,
1399 1399
 					"Check clamd server %s - it may be down",
1400 1400
 					hostname);
1401
-			socks[i] = -1;
1402 1401
 			close(sock);
1402
+			free(hostname);
1403
+			socks[i] = -1;
1403 1404
 			continue;
1404 1405
 		}
1405 1406
 
... ...
@@ -1437,10 +1446,12 @@ findServer(void)
1437 1437
 	}
1438 1438
 
1439 1439
 	for(i = 0; i < numServers; i++)
1440
-		if(FD_ISSET(socks[i], &rfds)) {
1440
+		if((socks[i] >= 0) && (FD_ISSET(socks[i], &rfds))) {
1441
+			const int server = (i + j) % numServers;
1442
+
1441 1443
 			free(socks);
1442
-			cli_dbgmsg("findServer: using server %d\n", i);
1443
-			return i;
1444
+			cli_dbgmsg("findServer: using server %d\n", server);
1445
+			return server;
1444 1446
 		}
1445 1447
 
1446 1448
 	free(socks);
... ...
@@ -1508,7 +1519,11 @@ clamfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr)
1508 1508
 	 */
1509 1509
 	if(strncasecmp(port, "inet:", 5) == 0) {
1510 1510
 		const char *hostmail;
1511
-#ifdef	HAVE_GETHOSTBYNAME_R
1511
+		/*
1512
+		 * TODO: gethostbyname_r is non-standard so different operating
1513
+		 * systems do it in different ways. Need more examples
1514
+		 */
1515
+#if	defined(HAVE_GETHOSTBYNAME_R) && defined(C_LINUX)
1512 1516
 		struct hostent *hp, hostent;
1513 1517
 		char buf[BUFSIZ];
1514 1518
 		int ret;
... ...
@@ -2009,6 +2024,11 @@ clamfi_eom(SMFICTX *ctx)
2009 2009
 			syslog(LOG_DEBUG, "clamfi_eom: read %s", mess);
2010 2010
 		cli_dbgmsg("clamfi_eom: read %s\n", mess);
2011 2011
 	} else {
2012
+		/*
2013
+		 * TODO: if more than one host has been specified, try
2014
+		 * another one - setting cl_error to SMFIS_TEMPFAIL helps
2015
+		 * by forcing a retry
2016
+		 */
2012 2017
 		clamfi_cleanup(ctx);
2013 2018
 		syslog(LOG_NOTICE, "clamfi_eom: read nothing from clamd");
2014 2019
 #ifdef	CL_DEBUG
... ...
@@ -2183,6 +2203,16 @@ clamfi_eom(SMFICTX *ctx)
2183 2183
 			 * item in the queue so there's no scanning of two
2184 2184
 			 * messages at once. It'll still be scanned, but
2185 2185
 			 * not at the same time as the incoming message
2186
+			 *
2187
+			 * FIXME: there is a race condition here. If the
2188
+			 * system is very overloaded this sendmail can
2189
+			 * take a long time to start - and may even fail
2190
+			 * is the LA is > REFUSE_LA. In all the time we're
2191
+			 * taking to start this sendmail, the sendmail that's
2192
+			 * started us may timeout waiting for a response and
2193
+			 * let the virus through (albeit tagged with
2194
+			 * X-Virus-Status: Infected) because we haven't
2195
+			 * sent SMFIS_DISCARD or SMFIS_REJECT
2186 2196
 			 */
2187 2197
 			snprintf(cmd, sizeof(cmd) - 1,
2188 2198
 				(oflag || fflag) ? "%s -t -odq" : "%s -t",
... ...
@@ -2470,9 +2500,7 @@ clamfi_free(struct privdata *privdata)
2470 2470
 		cli_dbgmsg("pthread_cond_broadcast\n");
2471 2471
 #endif
2472 2472
 		pthread_cond_broadcast(&n_children_cond);
2473
-#ifdef	CL_DEBUG
2474 2473
 		cli_dbgmsg("<n_children = %d\n", n_children);
2475
-#endif
2476 2474
 		pthread_mutex_unlock(&n_children_mutex);
2477 2475
 	}
2478 2476
 }