git-svn: trunk@3947
Tomasz Kojm authored on 2008/07/15 02:27:10... | ... |
@@ -1,3 +1,8 @@ |
1 |
+Mon Jul 14 18:54:01 CEST 2008 (tk) |
|
2 |
+---------------------------------- |
|
3 |
+ * freshclam: try load balance update sessions between available mirrors |
|
4 |
+ (only in IPv6-aware block) |
|
5 |
+ |
|
1 | 6 |
Mon Jul 14 17:26:03 EEST 2008 (edwin) |
2 | 7 |
------------------------------------ |
3 | 8 |
* libclamav/htmlnorm.c: improve normalization of screnc encoded files(bb #1022) |
... | ... |
@@ -185,8 +185,10 @@ static int wwwconnect(const char *server, const char *proxy, int pport, char *ip |
185 | 185 |
{ |
186 | 186 |
int socketfd, port, ret; |
187 | 187 |
#ifdef SUPPORT_IPv6 |
188 |
- struct addrinfo hints, *res = NULL, *rp; |
|
189 |
- char port_s[6]; |
|
188 |
+ struct addrinfo hints, *res = NULL, *rp, *loadbal_rp = NULL; |
|
189 |
+ char port_s[6], loadbal_ipaddr[46]; |
|
190 |
+ uint32_t loadbal = 1, minsucc = 0xffffffff, minfail = 0xffffffff; |
|
191 |
+ struct mirdat_ip *md; |
|
190 | 192 |
#else |
191 | 193 |
struct sockaddr_in name; |
192 | 194 |
struct hostent *host; |
... | ... |
@@ -250,11 +252,44 @@ static int wwwconnect(const char *server, const char *proxy, int pport, char *ip |
250 | 250 |
return -1; |
251 | 251 |
} |
252 | 252 |
|
253 |
- if((ret = mirman_check(addr, rp->ai_family, mdat))) { |
|
253 |
+ if((ret = mirman_check(addr, rp->ai_family, mdat, &md))) { |
|
254 | 254 |
if(ret == 1) |
255 | 255 |
logg("Ignoring mirror %s (due to previous errors)\n", ipaddr); |
256 | 256 |
else |
257 | 257 |
logg("Ignoring mirror %s (has connected too many times with an outdated version)\n", ipaddr); |
258 |
+ |
|
259 |
+ if(!loadbal || rp->ai_next) |
|
260 |
+ continue; |
|
261 |
+ } |
|
262 |
+ |
|
263 |
+ if(loadbal) { |
|
264 |
+ if(!ret) { |
|
265 |
+ if(!md) { |
|
266 |
+ loadbal_rp = rp; |
|
267 |
+ strncpy(loadbal_ipaddr, ipaddr, sizeof(loadbal_ipaddr)); |
|
268 |
+ } else { |
|
269 |
+ if(md->succ < minsucc && md->fail <= minfail) { |
|
270 |
+ minsucc = md->succ; |
|
271 |
+ minfail = md->fail; |
|
272 |
+ loadbal_rp = rp; |
|
273 |
+ strncpy(loadbal_ipaddr, ipaddr, sizeof(loadbal_ipaddr)); |
|
274 |
+ } |
|
275 |
+ if(rp->ai_next) |
|
276 |
+ continue; |
|
277 |
+ } |
|
278 |
+ } |
|
279 |
+ |
|
280 |
+ if(!loadbal_rp) { |
|
281 |
+ if(!rp->ai_next) { |
|
282 |
+ loadbal = 0; |
|
283 |
+ rp = res; |
|
284 |
+ } |
|
285 |
+ continue; |
|
286 |
+ } |
|
287 |
+ rp = loadbal_rp; |
|
288 |
+ strncpy(ipaddr, loadbal_ipaddr, sizeof(ipaddr)); |
|
289 |
+ |
|
290 |
+ } else if(loadbal_rp == rp) { |
|
258 | 291 |
continue; |
259 | 292 |
} |
260 | 293 |
|
... | ... |
@@ -277,6 +312,10 @@ static int wwwconnect(const char *server, const char *proxy, int pport, char *ip |
277 | 277 |
#endif |
278 | 278 |
logg("Can't connect to port %d of host %s (IP: %s)\n", port, hostpt, ipaddr); |
279 | 279 |
closesocket(socketfd); |
280 |
+ if(loadbal) { |
|
281 |
+ loadbal = 0; |
|
282 |
+ rp = res; |
|
283 |
+ } |
|
280 | 284 |
continue; |
281 | 285 |
} else { |
282 | 286 |
if(rp->ai_family == AF_INET) |
... | ... |
@@ -302,7 +341,7 @@ static int wwwconnect(const char *server, const char *proxy, int pport, char *ip |
302 | 302 |
ia = (unsigned char *) host->h_addr_list[i]; |
303 | 303 |
sprintf(ipaddr, "%u.%u.%u.%u", ia[0], ia[1], ia[2], ia[3]); |
304 | 304 |
|
305 |
- if((ret = mirman_check(&((struct in_addr *) ia)->s_addr, AF_INET, mdat))) { |
|
305 |
+ if((ret = mirman_check(&((struct in_addr *) ia)->s_addr, AF_INET, mdat, NULL))) { |
|
306 | 306 |
if(ret == 1) |
307 | 307 |
logg("Ignoring mirror %s (due to previous errors)\n", ipaddr); |
308 | 308 |
else |
... | ... |
@@ -104,17 +104,26 @@ int mirman_read(const char *file, struct mirdat *mdat, uint8_t active) |
104 | 104 |
return 0; |
105 | 105 |
} |
106 | 106 |
|
107 |
-int mirman_check(uint32_t *ip, int af, struct mirdat *mdat) |
|
107 |
+int mirman_check(uint32_t *ip, int af, struct mirdat *mdat, struct mirdat_ip **md) |
|
108 | 108 |
{ |
109 | 109 |
unsigned int i, flevel = cl_retflevel(); |
110 | 110 |
|
111 | 111 |
|
112 |
+ if(md) |
|
113 |
+ *md = NULL; |
|
114 |
+ |
|
112 | 115 |
if(!mdat->active) |
113 | 116 |
return 0; |
114 | 117 |
|
115 | 118 |
for(i = 0; i < mdat->num; i++) { |
116 | 119 |
|
117 |
- if(mdat->mirtab[i].atime && ((af == AF_INET && mdat->mirtab[i].ip4 == *ip) || (af == AF_INET6 && !memcmp(mdat->mirtab[i].ip6, ip, 4)))) { |
|
120 |
+ if(((af == AF_INET && mdat->mirtab[i].ip4 == *ip) || (af == AF_INET6 && !memcmp(mdat->mirtab[i].ip6, ip, 4)))) { |
|
121 |
+ |
|
122 |
+ if(!mdat->mirtab[i].atime) { |
|
123 |
+ if(md) |
|
124 |
+ *md = &mdat->mirtab[i]; |
|
125 |
+ return 0; |
|
126 |
+ } |
|
118 | 127 |
|
119 | 128 |
if(mdat->dbflevel && (mdat->dbflevel > flevel) && (mdat->dbflevel - flevel > 3)) |
120 | 129 |
if(time(NULL) - mdat->mirtab[i].atime < 4 * 3600) |
... | ... |
@@ -123,11 +132,17 @@ int mirman_check(uint32_t *ip, int af, struct mirdat *mdat) |
123 | 123 |
if(mdat->mirtab[i].ignore) { |
124 | 124 |
if(time(NULL) - mdat->mirtab[i].atime > IGNTIME) { |
125 | 125 |
mdat->mirtab[i].ignore = 0; |
126 |
+ if(md) |
|
127 |
+ *md = &mdat->mirtab[i]; |
|
126 | 128 |
return 0; |
127 | 129 |
} else { |
128 | 130 |
return 1; |
129 | 131 |
} |
130 | 132 |
} |
133 |
+ |
|
134 |
+ if(md) |
|
135 |
+ *md = &mdat->mirtab[i]; |
|
136 |
+ return 0; |
|
131 | 137 |
} |
132 | 138 |
} |
133 | 139 |
|
... | ... |
@@ -41,7 +41,7 @@ struct mirdat { |
41 | 41 |
}; |
42 | 42 |
|
43 | 43 |
int mirman_read(const char *file, struct mirdat *mdat, uint8_t active); |
44 |
-int mirman_check(uint32_t *ip, int af, struct mirdat *mdat); |
|
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 | 47 |
int mirman_write(const char *file, struct mirdat *mdat); |