Browse code

freshclam: short-term blacklisting of faulty mirrors; better handling of 404 errors (bb#1516)

git-svn: trunk@5021

Tomasz Kojm authored on 2009/04/03 22:32:28
Showing 4 changed files
... ...
@@ -1,3 +1,8 @@
1
+Fri Apr  3 15:30:34 CEST 2009 (tk)
2
+----------------------------------
3
+ * freshclam: short-term blacklisting of faulty mirrors;
4
+	      better handling of 404 errors (bb#1516)
5
+
1 6
 Fri Apr  3 13:05:44 CEST 2009 (acab)
2 7
 ------------------------------------
3 8
  * shared/optparser.c, docs: limit options expressing sizes to
... ...
@@ -271,9 +271,9 @@ static int wwwconnect(const char *server, const char *proxy, int pport, char *ip
271 271
 
272 272
 	if(mdat && (ret = mirman_check(addr, rp->ai_family, mdat, &md))) {
273 273
 	    if(ret == 1)
274
-		logg("Ignoring mirror %s (due to previous errors)\n", ipaddr);
274
+		logg("*Ignoring mirror %s (due to previous errors)\n", ipaddr);
275 275
 	    else
276
-		logg("Ignoring mirror %s (has connected too many times with an outdated version)\n", ipaddr);
276
+		logg("*Ignoring mirror %s (has connected too many times with an outdated version)\n", ipaddr);
277 277
 
278 278
 	    ignored++;
279 279
 	    if(!loadbal || rp->ai_next)
... ...
@@ -364,9 +364,9 @@ static int wwwconnect(const char *server, const char *proxy, int pport, char *ip
364 364
 	ips++;
365 365
 	if(mdat && (ret = mirman_check(&((struct in_addr *) ia)->s_addr, AF_INET, mdat, NULL))) {
366 366
 	    if(ret == 1)
367
-		logg("Ignoring mirror %s (due to previous errors)\n", ipaddr);
367
+		logg("*Ignoring mirror %s (due to previous errors)\n", ipaddr);
368 368
 	    else
369
-		logg("Ignoring mirror %s (has connected too many times with an outdated version)\n", ipaddr);
369
+		logg("*Ignoring mirror %s (has connected too many times with an outdated version)\n", ipaddr);
370 370
 	    ignored++;
371 371
 	    continue;
372 372
 	}
... ...
@@ -405,7 +405,7 @@ static int wwwconnect(const char *server, const char *proxy, int pport, char *ip
405 405
 #endif
406 406
 
407 407
     if(mdat && can_whitelist && ips && (ips == ignored))
408
-	mirman_whitelist(mdat);
408
+	mirman_whitelist(mdat, 1);
409 409
 
410 410
     return -2;
411 411
 }
... ...
@@ -925,7 +925,7 @@ static struct cl_cvd *remote_cvdhead(const char *cvdfile, const char *localfile,
925 925
 
926 926
     if((strstr(buffer, "HTTP/1.1 404")) != NULL || (strstr(buffer, "HTTP/1.0 404")) != NULL) { 
927 927
 	logg("%cCVD file not found on remote server\n", logerr ? '!' : '^');
928
-	/* mirman_update(mdat->currip, mdat, 1); */
928
+	mirman_update(mdat->currip, mdat->af, mdat, 2);
929 929
 	return NULL;
930 930
     }
931 931
 
... ...
@@ -1085,7 +1085,7 @@ static int getfile(const char *srcfile, const char *destfile, const char *hostna
1085 1085
     /* check whether the resource actually existed or not */
1086 1086
     if((strstr(buffer, "HTTP/1.1 404")) != NULL || (strstr(buffer, "HTTP/1.0 404")) != NULL) { 
1087 1087
 	logg("^getfile: %s not found on remote server (IP: %s)\n", srcfile, ipaddr);
1088
-	/* mirman_update(mdat->currip, mdat, 1); */
1088
+	mirman_update(mdat->currip, mdat->af, mdat, 2);
1089 1089
 	closesocket(sd);
1090 1090
 	return 58;
1091 1091
     }
... ...
@@ -1192,6 +1192,7 @@ static int getcvd(const char *cvdfile, const char *newfile, const char *hostname
1192 1192
 
1193 1193
     if(cvd->version < newver) {
1194 1194
 	logg("^Mirror %s is not synchronized.\n", ip);
1195
+	mirman_update(mdat->currip, mdat->af, mdat, 2);
1195 1196
     	cl_cvdfree(cvd);
1196 1197
 	unlink(newfile);
1197 1198
 	return 59;
... ...
@@ -1648,6 +1649,7 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig
1648 1648
 	    cli_rmdirs(tmpdir);
1649 1649
 	    free(tmpdir);
1650 1650
 	    logg("^Incremental update failed, trying to download %s\n", cvdfile);
1651
+	    mirman_whitelist(mdat, 2);
1651 1652
 	    ret = getcvd(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, newver, ctimeout, rtimeout, mdat, logerr, can_whitelist);
1652 1653
 	    if(ret) {
1653 1654
 		free(newfile);
... ...
@@ -62,7 +62,8 @@
62 62
 #endif
63 63
 #endif
64 64
 
65
-#define IGNTIME 3 * 86400
65
+#define IGNORE_LONG	3 * 86400
66
+#define IGNORE_SHORT	1800
66 67
 
67 68
 void mirman_free(struct mirdat *mdat)
68 69
 {
... ...
@@ -125,7 +126,7 @@ int mirman_check(uint32_t *ip, int af, struct mirdat *mdat, struct mirdat_ip **m
125 125
 
126 126
 	if((af == AF_INET && mdat->mirtab[i].ip4 == *ip) || (af == AF_INET6 && !memcmp(mdat->mirtab[i].ip6, ip, 4 * sizeof(uint32_t)))) {
127 127
 
128
-	    if(!mdat->mirtab[i].atime) {
128
+	    if(!mdat->mirtab[i].atime && !mdat->mirtab[i].ignore) {
129 129
 		if(md)
130 130
 		    *md = &mdat->mirtab[i];
131 131
 		return 0;
... ...
@@ -136,12 +137,20 @@ int mirman_check(uint32_t *ip, int af, struct mirdat *mdat, struct mirdat_ip **m
136 136
 		    return 2;
137 137
 
138 138
 	    if(mdat->mirtab[i].ignore) {
139
-		if(time(NULL) - mdat->mirtab[i].atime > IGNTIME) {
139
+		if(!mdat->mirtab[i].atime)
140
+		    return 1;
141
+
142
+		if(time(NULL) - mdat->mirtab[i].atime > IGNORE_LONG) {
140 143
 		    mdat->mirtab[i].ignore = 0;
141 144
 		    if(md)
142 145
 			*md = &mdat->mirtab[i];
143 146
 		    return 0;
144 147
 		} else {
148
+		    if(mdat->mirtab[i].ignore == 2 && (time(NULL) - mdat->mirtab[i].atime > IGNORE_SHORT)) {
149
+			if(md)
150
+			    *md = &mdat->mirtab[i];
151
+			return 0;
152
+		    }
145 153
 		    return 1;
146 154
 		}
147 155
 	    }
... ...
@@ -177,14 +186,18 @@ int mirman_update(uint32_t *ip, int af, struct mirdat *mdat, uint8_t broken)
177 177
 	else
178 178
 	    mdat->mirtab[i].succ++;
179 179
 
180
-	/*
181
-	 * If the total number of failures is less than 3 then never
182
-	 * enable the ignore flag, in other case use the real status.
183
-	 */
184
-	if(mdat->mirtab[i].fail < 3)
185
-	    mdat->mirtab[i].ignore = 0;
186
-	else
187
-	    mdat->mirtab[i].ignore = broken;
180
+	if(broken == 2) {
181
+	    mdat->mirtab[i].ignore = 2;
182
+	} else {
183
+	    /*
184
+	     * If the total number of failures is less than 3 then never
185
+	     * mark a permanent failure, in other case use the real status.
186
+	     */
187
+	    if(mdat->mirtab[i].fail < 3)
188
+		mdat->mirtab[i].ignore = 0;
189
+	    else
190
+		mdat->mirtab[i].ignore = broken;
191
+	}
188 192
 
189 193
     } else {
190 194
 	mdat->mirtab = (struct mirdat_ip *) realloc(mdat->mirtab, (mdat->num + 1) * sizeof(struct mirdat_ip));
... ...
@@ -201,7 +214,7 @@ int mirman_update(uint32_t *ip, int af, struct mirdat *mdat, uint8_t broken)
201 201
 	mdat->mirtab[mdat->num].atime = 0;
202 202
 	mdat->mirtab[mdat->num].succ = 0;
203 203
 	mdat->mirtab[mdat->num].fail = 0;
204
-	mdat->mirtab[mdat->num].ignore = 0;
204
+	mdat->mirtab[mdat->num].ignore = (broken == 2) ? 2 : 0;
205 205
 	memset(&mdat->mirtab[mdat->num].res, 0xff, sizeof(mdat->mirtab[mdat->num].res));
206 206
 	if(broken)
207 207
 	    mdat->mirtab[mdat->num].fail++;
... ...
@@ -241,13 +254,14 @@ void mirman_list(const struct mirdat *mdat)
241 241
     }
242 242
 }
243 243
 
244
-void mirman_whitelist(struct mirdat *mdat)
244
+void mirman_whitelist(struct mirdat *mdat, unsigned int mode)
245 245
 {
246 246
 	unsigned int i;
247 247
 
248
-    logg("Whitelisting all mirrors\n");
248
+    logg("*Whitelisting %s blacklisted mirrors\n", mode == 1 ? "all" : "short-term");
249 249
     for(i = 0; i < mdat->num; i++)
250
-	mdat->mirtab[i].ignore = 0;
250
+	if(mode == 1 || (mode == 2 && mdat->mirtab[i].ignore == 2))
251
+	    mdat->mirtab[i].ignore = 0;
251 252
 }
252 253
 
253 254
 int mirman_write(const char *file, struct mirdat *mdat)
... ...
@@ -44,7 +44,7 @@ int mirman_read(const char *file, struct mirdat *mdat, uint8_t active);
44 44
 int mirman_check(uint32_t *ip, int af, struct mirdat *mdat, struct mirdat_ip **md);
45 45
 int mirman_update(uint32_t *ip, int af, struct mirdat *mdat, uint8_t broken);
46 46
 void mirman_list(const struct mirdat *mdat);
47
-void mirman_whitelist(struct mirdat *mdat);
47
+void mirman_whitelist(struct mirdat *mdat, unsigned int mode);
48 48
 int mirman_write(const char *file, struct mirdat *mdat);
49 49
 void mirman_free(struct mirdat *mdat);
50 50