Browse code

Timeout on waiting for data from clamd

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

Nigel Horne authored on 2003/12/10 21:02:26
Showing 3 changed files
... ...
@@ -1,3 +1,8 @@
1
+Wed Dec 10 12:01:27 GMT 2003 (njh)
2
+----------------------------------
3
+  * clamav-milter: Timeout on waiting for data from clamd, by honouring
4
+  	ThreadTimeout in clamav.conf
5
+
1 6
 Tue Dec  9 09:22:46 GMT 2003 (njh)
2 7
 ----------------------------------
3 8
   * clamav-milter: Use the location of sendmail discovered by configure
... ...
@@ -173,6 +173,7 @@ Changes
173 173
 		unescaped From at the start of lines properly
174 174
 		Thanks to Michael Dankov <misha@btrc.ru>
175 175
 0.65i	9/12/03	Use the location of sendmail discovered by configure
176
+0.65j	10/12/03 Timeout on waiting for data from clamd
176 177
 
177 178
 BUG REPORTS
178 179
 
... ...
@@ -176,9 +176,13 @@
176 176
  *			unescaped From at the start of lines properly
177 177
  *			Thanks to Michael Dankov <misha@btrc.ru>
178 178
  *	0.65i	9/12/03	Use the location of sendmail discovered by configure
179
+ *	0.65j	10/12/03 Timeout on waiting for data from clamd
179 180
  *
180 181
  * Change History:
181 182
  * $Log: clamav-milter.c,v $
183
+ * Revision 1.29  2003/12/10 12:00:39  nigelhorne
184
+ * Timeout on waiting for data from clamd
185
+ *
182 186
  * Revision 1.28  2003/12/09 09:22:14  nigelhorne
183 187
  * Use the location of sendmail discovered by configure
184 188
  *
... ...
@@ -248,9 +252,9 @@
248 248
  * Revision 1.6  2003/09/28 16:37:23  nigelhorne
249 249
  * Added -f flag use MaxThreads if --max-children not set
250 250
  */
251
-static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.28 2003/12/09 09:22:14 nigelhorne Exp $";
251
+static	char	const	rcsid[] = "$Id: clamav-milter.c,v 1.29 2003/12/10 12:00:39 nigelhorne Exp $";
252 252
 
253
-#define	CM_VERSION	"0.65i"
253
+#define	CM_VERSION	"0.65j"
254 254
 
255 255
 /*#define	CONFDIR	"/usr/local/etc"*/
256 256
 
... ...
@@ -339,6 +343,7 @@ static	sfsistat	clamfi_close(SMFICTX *ctx);
339 339
 static	void		clamfi_cleanup(SMFICTX *ctx);
340 340
 static	int		clamfi_send(const struct privdata *privdata, size_t len, const char *format, ...);
341 341
 static	char		*strrcpy(char *dest, const char *source);
342
+static	int	clamd_recv(int sock, char *buf, size_t len);
342 343
 
343 344
 static	char	clamav_version[128];
344 345
 static	int	fflag = 0;	/* force a scan, whatever */
... ...
@@ -380,6 +385,10 @@ static	int	cl_error = SMFIS_TEMPFAIL; /*
380 380
 				 * an error. Patch from
381 381
 				 * Joe Talbott <josepht@cstone.net>
382 382
 				 */
383
+static	int	threadtimeout = CL_DEFAULT_SCANTIMEOUT; /*
384
+				 * number of seconds to wait for clamd to
385
+				 * respond
386
+				 */
383 387
 
384 388
 #ifdef	CL_DEBUG
385 389
 static	int	debug_level = 0;
... ...
@@ -665,6 +674,15 @@ main(int argc, char **argv)
665 665
 	if((max_children == 0) && ((cpt = cfgopt(copt, "MaxThreads")) != NULL))
666 666
 		max_children = cpt->numarg;
667 667
 
668
+	if((cpt = cfgopt(copt, "ThreadTimeout")) != NULL) {
669
+		threadtimeout = cpt->numarg;
670
+
671
+		if(threadtimeout < 0) {
672
+			fprintf(stderr, "%s: ThreadTimeout must not be negative in %s\n",
673
+				argv[0], cfgfile);
674
+		}
675
+	}
676
+
668 677
 	/*
669 678
 	 * Get the outgoing socket details - the way to talk to clamd
670 679
 	 */
... ...
@@ -852,7 +870,7 @@ pingServer(void)
852 852
 
853 853
 	shutdown(sock, SHUT_WR);
854 854
 
855
-	nbytes = recv(sock, buf, sizeof(buf), 0);
855
+	nbytes = clamd_recv(sock, buf, sizeof(buf));
856 856
 
857 857
 	close(sock);
858 858
 
... ...
@@ -860,6 +878,9 @@ pingServer(void)
860 860
 		perror("recv");
861 861
 		return 0;
862 862
 	}
863
+	if(nbytes == 0)
864
+		return 0;
865
+
863 866
 	buf[nbytes] = '\0';
864 867
 
865 868
 	/* Remove the trailing new line from the reply */
... ...
@@ -1136,7 +1157,7 @@ clamfi_envfrom(SMFICTX *ctx, char **argv)
1136 1136
 
1137 1137
 		shutdown(privdata->cmdSocket, SHUT_WR);
1138 1138
 
1139
-		nbytes = recv(privdata->cmdSocket, buf, sizeof(buf), 0);
1139
+		nbytes = clamd_recv(privdata->cmdSocket, buf, sizeof(buf));
1140 1140
 		if(nbytes < 0) {
1141 1141
 			perror("recv");
1142 1142
 			close(privdata->dataSocket);
... ...
@@ -1147,10 +1168,10 @@ clamfi_envfrom(SMFICTX *ctx, char **argv)
1147 1147
 			return cl_error;
1148 1148
 		}
1149 1149
 		buf[nbytes] = '\0';
1150
-	#ifdef	CL_DEBUG
1150
+#ifdef	CL_DEBUG
1151 1151
 		if(debug_level >= 4)
1152 1152
 			printf("Received: %s", buf);
1153
-	#endif
1153
+#endif
1154 1154
 		if(sscanf(buf, "PORT %hu\n", &port) != 1) {
1155 1155
 			close(privdata->dataSocket);
1156 1156
 			close(privdata->cmdSocket);
... ...
@@ -1170,10 +1191,10 @@ clamfi_envfrom(SMFICTX *ctx, char **argv)
1170 1170
 
1171 1171
 		reply.sin_addr.s_addr = inet_addr(serverIP);
1172 1172
 
1173
-	#ifdef	CL_DEBUG
1173
+#ifdef	CL_DEBUG
1174 1174
 		if(debug_level >= 4)
1175 1175
 			printf("Connecting to local port %d\n", port);
1176
-	#endif
1176
+#endif
1177 1177
 
1178 1178
 		rc = connect(privdata->dataSocket, (struct sockaddr *)&reply, sizeof(struct sockaddr_in));
1179 1179
 
... ...
@@ -1393,7 +1414,7 @@ clamfi_eom(SMFICTX *ctx)
1393 1393
 		shutdown(privdata->cmdSocket, SHUT_WR);
1394 1394
 	}
1395 1395
 
1396
-	if(recv(privdata->cmdSocket, mess, sizeof(mess), 0) > 0) {
1396
+	if(clamd_recv(privdata->cmdSocket, mess, sizeof(mess)) > 0) {
1397 1397
 		if((ptr = strchr(mess, '\n')) != NULL)
1398 1398
 			*ptr = '\0';
1399 1399
 
... ...
@@ -1407,7 +1428,7 @@ clamfi_eom(SMFICTX *ctx)
1407 1407
 #ifdef	CL_DEBUG
1408 1408
 		puts("clamfi_eom: read nothing from clamd");
1409 1409
 #endif
1410
-		mess[0] = '\0';
1410
+		return cl_error;
1411 1411
 	}
1412 1412
 
1413 1413
 	close(privdata->cmdSocket);
... ...
@@ -1644,7 +1665,7 @@ clamfi_cleanup(SMFICTX *ctx)
1644 1644
 			/*
1645 1645
 			 * Flush the remote end so that clamd doesn't get a SIGPIPE
1646 1646
 			 */
1647
-			while(recv(privdata->cmdSocket, buf, sizeof(buf), 0) > 0)
1647
+			while(clamd_recv(privdata->cmdSocket, buf, sizeof(buf)) > 0)
1648 1648
 				;
1649 1649
 			close(privdata->cmdSocket);
1650 1650
 			privdata->cmdSocket = -1;
... ...
@@ -1741,3 +1762,33 @@ strrcpy(char *dest, const char *source)
1741 1741
 		;
1742 1742
 	return(--dest);
1743 1743
 }
1744
+
1745
+/*
1746
+ * Read from clamav - timeout if necessary
1747
+ */
1748
+static int
1749
+clamd_recv(int sock, char *buf, size_t len)
1750
+{
1751
+	fd_set rfds;
1752
+	struct timeval tv;
1753
+
1754
+	if(threadtimeout == 0)
1755
+		return recv(sock, buf, len, 0);
1756
+
1757
+	FD_ZERO(&rfds);
1758
+	FD_SET(sock, &rfds);
1759
+
1760
+	tv.tv_sec = threadtimeout;
1761
+	tv.tv_usec = 0;
1762
+
1763
+	switch(select(sock + 1, &rfds, NULL, NULL, &tv)) {
1764
+		case -1:
1765
+			perror("select");
1766
+			return -1;
1767
+		case 0:
1768
+			if(use_syslog)
1769
+				syslog(LOG_ERR, "No data received from clamd in %d seconds\n", threadtimeout);
1770
+			return 0;
1771
+	}
1772
+	return recv(sock, buf, len, 0);
1773
+}