After the previous improvements, there is still an issue wherein a
private database mirror may not yet have the very latest CVD and CDIFF.
In this case, and if the clients are still using the official DNS server
to check the latest versions, then the clients will try several times to
update with CDIFFs before downloading the entire CVD. This is clearly
not desirable, especially because that CVD is probably also 1 version
older than expected.
This commit keeps track of the number of patches and will only ask for
the CVD after the patches failed if no patches were downloaded AND we're
more than 1 version behind. What that means is that if we're 1 version
behind and the server is too -- it will log some warnings but succeed.
Or if we are multple versions behind but we did get some patches, we'll
settle for a minor update.
This change will essentially allow FreshClam to be used with private
mirrors that aren't updated the second a new daily database is
published. Without this change, private mirror operators may end up
frequently serving the entire daily CVD to fussy FreshClam clients.
... | ... |
@@ -1596,7 +1596,7 @@ static fc_error_t downloadPatch( |
1596 | 1596 |
if (ret == FC_EEMPTYFILE) { |
1597 | 1597 |
logg("Empty script %s, need to download entire database\n", patch); |
1598 | 1598 |
} else { |
1599 |
- logg("%cgetpatch: Can't download %s from %s\n", logerr ? '!' : '^', patch, url); |
|
1599 |
+ logg("%cdownloadPatch: Can't download %s from %s\n", logerr ? '!' : '^', patch, url); |
|
1600 | 1600 |
} |
1601 | 1601 |
status = ret; |
1602 | 1602 |
goto done; |
... | ... |
@@ -2263,7 +2263,8 @@ fc_error_t updatedb( |
2263 | 2263 |
/* |
2264 | 2264 |
* Attempt scripted/CDIFF incremental update. |
2265 | 2265 |
*/ |
2266 |
- ret = FC_SUCCESS; |
|
2266 |
+ ret = FC_SUCCESS; |
|
2267 |
+ uint32_t numPatchesReceived = 0; |
|
2267 | 2268 |
|
2268 | 2269 |
tmpdir = cli_gentemp(g_tempDirectory); |
2269 | 2270 |
if (!tmpdir) { |
... | ... |
@@ -2304,11 +2305,19 @@ fc_error_t updatedb( |
2304 | 2304 |
break; |
2305 | 2305 |
} |
2306 | 2306 |
} |
2307 |
- if (FC_SUCCESS != ret) |
|
2307 |
+ if (FC_SUCCESS == ret) { |
|
2308 |
+ numPatchesReceived += 1; |
|
2309 |
+ } else { |
|
2308 | 2310 |
break; |
2311 |
+ } |
|
2309 | 2312 |
} |
2310 | 2313 |
|
2311 |
- if (FC_SUCCESS != ret) { |
|
2314 |
+ if ( |
|
2315 |
+ (FC_EEMPTYFILE == ret) || /* Request a new CVD if we got an empty CDIFF. */ |
|
2316 |
+ (FC_SUCCESS != ret && ( /* Or if the incremental update failed: */ |
|
2317 |
+ (0 == numPatchesReceived) && /* 1. Ask for the CVD if we didn't get any patches, */ |
|
2318 |
+ (localVersion < remoteVersion - 1) /* 2. AND if we're more than 1 version out of date. */ |
|
2319 |
+ ))) { |
|
2312 | 2320 |
/* |
2313 | 2321 |
* Incremental update failed or intentionally disabled. |
2314 | 2322 |
*/ |
... | ... |
@@ -2334,10 +2343,18 @@ fc_error_t updatedb( |
2334 | 2334 |
} |
2335 | 2335 |
|
2336 | 2336 |
newLocalFilename = cli_strdup(remoteFilename); |
2337 |
+ } else if (0 == numPatchesReceived) { |
|
2338 |
+ logg("The database server doesn't have the latest patch for the %s database (version %u). The server will likely have updated if you check again in a few hours.\n", database, remoteVersion); |
|
2339 |
+ goto up_to_date; |
|
2337 | 2340 |
} else { |
2338 | 2341 |
/* |
2339 | 2342 |
* CDIFFs downloaded; Use CDIFFs to turn old CVD/CLD into new updated CLD. |
2340 | 2343 |
*/ |
2344 |
+ if (numPatchesReceived < remoteVersion - localVersion) { |
|
2345 |
+ logg("Downloaded %u patches for %s, which is fewer than the %u expected patches.\n", numPatchesReceived, database, remoteVersion - localVersion); |
|
2346 |
+ logg("We'll settle for this partial-update, at least for now.\n"); |
|
2347 |
+ } |
|
2348 |
+ |
|
2341 | 2349 |
size_t newLocalFilenameLen = 0; |
2342 | 2350 |
if (FC_SUCCESS != buildcld(tmpdir, database, tmpfile, g_bCompressLocalDatabase)) { |
2343 | 2351 |
logg("!updatedb: Incremental update failed. Failed to build CLD.\n"); |