94
94
memset(pd, 0, sizeof(*pd));
97
* Lock on to the peer here. The corresponding cbdataReferenceDone()
98
* is in peerDigestDestroy().
100
pd->peer = cbdataReference(p);
96
101
/* if peer disappears, we will know it's name */
97
102
pd->host = p->host;
150
155
void * peerTmp = pd->peer;
152
/* inform peer (if any) that we are gone */
159
* We locked the peer in peerDigestInit(), this is
160
* where we unlock it. If the peer is still valid,
161
* tell it that the digest is gone.
154
163
if (cbdataReferenceValidDone(peerTmp, &p))
155
164
peerNoteDigestGone((peer *)p);
179
188
peerDigestDisable(PeerDigest * pd)
181
debug(72, 2) ("peerDigestDisable: peer %s disabled for good\n",
190
debugs(72, 2, "peerDigestDisable: peer " << pd->host.buf() << " disabled for good");
183
191
pd->times.disabled = squid_curtime;
184
192
pd->times.next_check = -1; /* never */
185
193
pd->flags.usable = 0;
224
232
eventAdd("peerDigestCheck", peerDigestCheck, pd, (double) delay, 1);
225
233
pd->times.next_check = squid_curtime + delay;
226
debug(72, 3) ("peerDigestSetCheck: will check peer %s in %d secs\n",
227
pd->host.buf(), (int) delay);
234
debugs(72, 3, "peerDigestSetCheck: will check peer " << pd->host.buf() << " in " << delay << " secs");
234
241
peerDigestNotePeerGone(PeerDigest * pd)
236
243
if (pd->flags.requested) {
237
debug(72, 2) ("peerDigest: peer %s gone, will destroy after fetch.\n",
244
debugs(72, 2, "peerDigest: peer " << pd->host.buf() << " gone, will destroy after fetch.");
239
245
/* do nothing now, the fetching chain will notice and take action */
241
debug(72, 2) ("peerDigest: peer %s is gone, destroying now.\n",
247
debugs(72, 2, "peerDigest: peer " << pd->host.buf() << " is gone, destroying now.");
243
248
peerDigestDestroy(pd);
265
debug(72, 3) ("peerDigestCheck: peer %s:%d\n", pd->peer->host, pd->peer->http_port);
266
debug(72, 3) ("peerDigestCheck: time: %ld, last received: %ld (%+d)\n",
267
(long int) squid_curtime, (long int) pd->times.received, (int) (squid_curtime - pd->times.received));
270
debugs(72, 3, "peerDigestCheck: peer " << pd->peer->host << ":" << pd->peer->http_port);
271
debugs(72, 3, "peerDigestCheck: time: " << squid_curtime <<
272
", last received: " << (long int) pd->times.received << " (" <<
273
std::showpos << (int) (squid_curtime - pd->times.received) << ")");
269
275
/* decide when we should send the request:
270
276
* request now unless too close to other requests */
273
279
/* per-peer limit */
275
281
if (req_time - pd->times.received < PeerDigestReqMinGap) {
276
debug(72, 2) ("peerDigestCheck: %s, avoiding close peer requests (%d < %d secs).\n",
277
pd->host.buf(), (int) (req_time - pd->times.received),
278
(int) PeerDigestReqMinGap);
282
debugs(72, 2, "peerDigestCheck: " << pd->host.buf() <<
283
", avoiding close peer requests (" <<
284
(int) (req_time - pd->times.received) << " < " <<
285
(int) PeerDigestReqMinGap << " secs).");
279
287
req_time = pd->times.received + PeerDigestReqMinGap;
282
290
/* global limit */
283
291
if (req_time - pd_last_req_time < GlobDigestReqMinGap) {
284
debug(72, 2) ("peerDigestCheck: %s, avoiding close requests (%d < %d secs).\n",
285
pd->host.buf(), (int) (req_time - pd_last_req_time),
286
(int) GlobDigestReqMinGap);
292
debugs(72, 2, "peerDigestCheck: " << pd->host.buf() <<
293
", avoiding close requests (" <<
294
(int) (req_time - pd_last_req_time) << " < " <<
295
(int) GlobDigestReqMinGap << " secs).");
287
297
req_time = pd_last_req_time + GlobDigestReqMinGap;
325
335
key = storeKeyPublicByRequest(req);
327
debug(72, 2) ("peerDigestRequest: %s key: %s\n", url, storeKeyText(key));
337
debugs(72, 2, "peerDigestRequest: " << url << " key: " << storeKeyText(key));
329
339
/* add custom headers */
330
340
assert(!req->header.len);
364
374
old_e = fetch->old_entry = Store::Root().get(key);
367
debug(72, 5) ("peerDigestRequest: found old entry\n");
377
debugs(72, 5, "peerDigestRequest: found old entry");
372
storeCreateMemObject(old_e, url, url);
382
old_e->createMemObject(url, url);
374
384
fetch->old_sc = storeClientListAdd(old_e, fetch);
383
393
e->lastmod = old_e->lastmod;
385
395
/* push towards peer cache */
386
debug(72, 3) ("peerDigestRequest: forwarding to fwdStart...\n");
396
debugs(72, 3, "peerDigestRequest: forwarding to fwdStart...");
388
398
FwdState::fwdStart(-1, e, req);
537
547
assert (reply->sline.status != 0);
538
548
status = reply->sline.status;
539
debug(72, 3) ("peerDigestFetchReply: %s status: %d, expires: %ld (%+d)\n",
540
pd->host.buf(), status,
541
(long int) reply->expires, (int) (reply->expires - squid_curtime));
549
debugs(72, 3, "peerDigestFetchReply: " << pd->host.buf() << " status: " << status <<
550
", expires: " << (long int) reply->expires << " (" << std::showpos <<
551
(int) (reply->expires - squid_curtime) << ")");
543
553
/* this "if" is based on clientHandleIMSReply() */
558
568
old_rep->updateOnNotModified(reply);
560
storeTimestampsSet(fetch->old_entry);
570
fetch->old_entry->timestampsSet();
562
572
/* get rid of 304 reply */
563
573
storeUnregister(fetch->sc, fetch->entry, fetch);
575
585
/* get rid of old entry if any */
577
587
if (fetch->old_entry) {
578
debug(72, 3) ("peerDigestFetchReply: got new digest, releasing old one\n");
588
debugs(72, 3, "peerDigestFetchReply: got new digest, releasing old one");
579
589
storeUnregister(fetch->old_sc, fetch->old_entry, fetch);
580
storeReleaseRequest(fetch->old_entry);
590
fetch->old_entry->releaseRequest();
581
591
fetch->old_entry->unlock();
582
592
fetch->old_entry = NULL;
626
636
assert (fetch->entry->getReply()->sline.status != 0);
628
638
if (fetch->entry->getReply()->sline.status != HTTP_OK) {
629
debug(72, 1) ("peerDigestSwapInHeaders: %s status %d got cached!\n",
630
fetch->pd->host.buf(), fetch->entry->getReply()->sline.status);
639
debugs(72, 1, "peerDigestSwapInHeaders: " << fetch->pd->host.buf() <<
640
" status " << fetch->entry->getReply()->sline.status <<
631
643
peerDigestFetchAbort(fetch, buf, "internal status error");
786
798
/* finish if we have a reason */
788
800
const int level = strstr(reason, "?!") ? 1 : 3;
789
debug(72, level) ("%s: peer %s, exiting after '%s'\n",
790
step_name, host, reason);
801
debugs(72, level, "" << step_name << ": peer " << host << ", exiting after '" << reason << "'");
791
802
peerDigestReqFinish(fetch, buf,
792
803
1, pdcb_valid, pcb_valid, reason, !no_bug);
804
815
peerDigestFetchStop(DigestFetchState * fetch, char *buf, const char *reason)
807
debug(72, 2) ("peerDigestFetchStop: peer %s, reason: %s\n",
808
fetch->pd->host.buf(), reason);
818
debugs(72, 2, "peerDigestFetchStop: peer " << fetch->pd->host.buf() << ", reason: " << reason);
809
819
peerDigestReqFinish(fetch, buf, 1, 1, 1, reason, 0);
814
824
peerDigestFetchAbort(DigestFetchState * fetch, char *buf, const char *reason)
817
debug(72, 2) ("peerDigestFetchAbort: peer %s, reason: %s\n",
818
fetch->pd->host.buf(), reason);
827
debugs(72, 2, "peerDigestFetchAbort: peer " << fetch->pd->host.buf() << ", reason: " << reason);
819
828
peerDigestReqFinish(fetch, buf, 1, 1, 1, reason, 1);
875
884
pd->stats.recv.msgs += fetch->recv.msg;
878
debug(72, 1) ("%sdisabling (%s) digest from %s\n",
879
pcb_valid ? "temporary " : "",
880
pd->req_result, host);
887
debugs(72, 1, "" << (pcb_valid ? "temporary " : "" ) << "disabling (" << pd->req_result << ") digest from " << host);
883
890
cacheDigestDestroy(pd->cd);
896
903
/* XXX: ugly condition, but how? */
898
905
if (fetch->entry->store_status == STORE_OK)
899
debug(72, 2) ("re-used old digest from %s\n", host);
906
debugs(72, 2, "re-used old digest from " << host);
901
debug(72, 2) ("received valid digest from %s\n", host);
908
debugs(72, 2, "received valid digest from " << host);
904
911
cbdataReferenceDone(fetch->pd);
912
919
assert(fetch->entry && fetch->request);
914
921
if (fetch->old_entry) {
915
debug(72, 2) ("peerDigestFetchFinish: deleting old entry\n");
922
debugs(72, 2, "peerDigestFetchFinish: deleting old entry");
916
923
storeUnregister(fetch->old_sc, fetch->old_entry, fetch);
917
storeReleaseRequest(fetch->old_entry);
924
fetch->old_entry->releaseRequest();
918
925
fetch->old_entry->unlock();
919
926
fetch->old_entry = NULL;
963
970
fetch->expires = fetch->entry->expires;
964
971
fetch->resp_time = squid_curtime - fetch->start_time;
966
debug(72, 3) ("peerDigestFetchFinish: recv %d bytes in %d secs\n",
967
fetch->recv.bytes, (int) fetch->resp_time);
968
debug(72, 3) ("peerDigestFetchFinish: expires: %ld (%+d), lmt: %ld (%+d)\n",
969
(long int) fetch->expires, (int) (fetch->expires - squid_curtime),
970
(long int) fetch->entry->lastmod, (int) (fetch->entry->lastmod - squid_curtime));
973
debugs(72, 3, "peerDigestFetchFinish: recv " << fetch->recv.bytes <<
974
" bytes in " << (int) fetch->resp_time << " secs");
976
debugs(72, 3, "peerDigestFetchFinish: expires: " <<
977
(long int) fetch->expires << " (" << std::showpos <<
978
(int) (fetch->expires - squid_curtime) << "), lmt: " <<
979
std::noshowpos << (long int) fetch->entry->lastmod << " (" <<
980
std::showpos << (int) (fetch->entry->lastmod - squid_curtime) <<
986
998
cblock.count = ntohl(cblock.count);
987
999
cblock.del_count = ntohl(cblock.del_count);
988
1000
cblock.mask_size = ntohl(cblock.mask_size);
989
debug(72, 2) ("got digest cblock from %s; ver: %d (req: %d)\n",
990
host, (int) cblock.ver.current, (int) cblock.ver.required);
991
debug(72, 2) ("\t size: %d bytes, e-cnt: %d, e-util: %d%%\n",
992
cblock.mask_size, cblock.count,
993
xpercentInt(cblock.count, cblock.capacity));
1001
debugs(72, 2, "got digest cblock from " << host << "; ver: " <<
1002
(int) cblock.ver.current << " (req: " << (int) cblock.ver.required <<
1005
debugs(72, 2, "\t size: " <<
1006
cblock.mask_size << " bytes, e-cnt: " <<
1007
cblock.count << ", e-util: " <<
1008
xpercentInt(cblock.count, cblock.capacity) << "%" );
994
1009
/* check version requirements (both ways) */
996
1011
if (cblock.ver.required > CacheDigestVer.current) {
997
debug(72, 1) ("%s digest requires version %d; have: %d\n",
998
host, cblock.ver.required, CacheDigestVer.current);
1012
debugs(72, 1, "" << host << " digest requires version " <<
1013
cblock.ver.required << "; have: " << CacheDigestVer.current);
1002
1018
if (cblock.ver.current < CacheDigestVer.required) {
1003
debug(72, 1) ("%s digest is version %d; we require: %d\n",
1004
host, cblock.ver.current, CacheDigestVer.required);
1019
debugs(72, 1, "" << host << " digest is version " <<
1020
cblock.ver.current << "; we require: " <<
1021
CacheDigestVer.required);
1009
1027
if (cblock.ver.required > cblock.ver.current ||
1010
1028
cblock.mask_size <= 0 || cblock.capacity <= 0 ||
1011
1029
cblock.bits_per_entry <= 0 || cblock.hash_func_count <= 0) {
1012
debug(72, 0) ("%s digest cblock is corrupted.\n", host);
1030
debugs(72, 0, "" << host << " digest cblock is corrupted.");
1025
1043
/* there are some things we cannot do yet */
1026
1044
if (cblock.hash_func_count != CacheDigestHashFuncCount) {
1027
debug(72, 0) ("%s digest: unsupported #hash functions: %d ? %d.\n",
1028
host, cblock.hash_func_count, CacheDigestHashFuncCount);
1045
debugs(72, 0, "" << host << " digest: unsupported #hash functions: " <<
1046
cblock.hash_func_count << " ? " << CacheDigestHashFuncCount << ".");
1045
debug(72, 2) ("creating %s digest; size: %d (%+d) bytes\n",
1046
host, cblock.mask_size, (int) (cblock.mask_size - freed_size));
1063
debugs(72, 2, "creating " << host << " digest; size: " << cblock.mask_size << " (" <<
1064
std::showpos << (int) (cblock.mask_size - freed_size) << ") bytes");
1047
1065
pd->cd = cacheDigestCreate(cblock.capacity, cblock.bits_per_entry);
1049
1067
if (cblock.mask_size >= freed_size)
1064
1082
const int bit_util = cacheDigestBitUtil(pd->cd);
1066
1084
if (bit_util > 65) {
1067
debug(72, 0) ("Warning: %s peer digest has too many bits on (%d%%).\n",
1068
pd->host.buf(), bit_util);
1085
debugs(72, 0, "Warning: " << pd->host.buf() <<
1086
" peer digest has too many bits on (" << bit_util << "%%).");