~ubuntu-branches/ubuntu/oneiric/squid3/oneiric-security

« back to all changes in this revision

Viewing changes to src/peer_digest.cc

  • Committer: Bazaar Package Importer
  • Author(s): Luigi Gangitano
  • Date: 2007-05-13 16:03:16 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070513160316-2h6kn6h1z0q1fvyo
Tags: 3.0.PRE6-1
* New upstream release
  - Removed patches integrated upsteam:
    + 04-m68k-ftbfs

* debian/rules
  - Enable delay pools (Closes: #410785)
  - Enable cache digests (Closes: #416631)
  - Enable ICAP client
  - Raised Max Filedescriptor limit to 65536

* debian/control
  - Added real package dependency for httpd in squid3-cgi

* debian/patches/02-makefile-defaults
  - Fix default configuration file for cachemgr.cgi (Closes: #416630)

* debian/squid3.postinst
  - Fixed bashish in postinst (Closes: #411797)

* debian/patches/05-helpers-typo
  - Added upstream patch fixing compilation error in src/helpers.cc

* debian/patches/06-mem-obj-reference
  - Added upstream patch fixing a mem_obj reference in src/store.cc

* debian/patches/07-close-icap-connections
  - Added upstream patch fixing icap connection starvation

* debian/squid3.rc
  - Added LSB-compliant description to rc script

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
 
2
2
/*
3
 
 * $Id: peer_digest.cc,v 1.118 2006/08/21 00:50:41 robertc Exp $
 
3
 * $Id: peer_digest.cc,v 1.123 2007/04/30 16:56:09 wessels Exp $
4
4
 *
5
5
 * DEBUG: section 72    Peer Digest Routines
6
6
 * AUTHOR: Alex Rousskov
92
92
    assert(pd && p);
93
93
 
94
94
    memset(pd, 0, sizeof(*pd));
95
 
    pd->peer = p;
 
95
    /*
 
96
     * DPW 2007-04-12
 
97
     * Lock on to the peer here.  The corresponding cbdataReferenceDone()
 
98
     * is in peerDigestDestroy().
 
99
     */
 
100
    pd->peer = cbdataReference(p);
96
101
    /* if peer disappears, we will know it's name */
97
102
    pd->host = p->host;
98
103
 
149
154
    assert(pd);
150
155
    void * peerTmp = pd->peer;
151
156
 
152
 
    /* inform peer (if any) that we are gone */
153
 
 
 
157
    /*
 
158
     * DPW 2007-04-12
 
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.
 
162
     */
154
163
    if (cbdataReferenceValidDone(peerTmp, &p))
155
164
        peerNoteDigestGone((peer *)p);
156
165
 
178
187
static void
179
188
peerDigestDisable(PeerDigest * pd)
180
189
{
181
 
    debug(72, 2) ("peerDigestDisable: peer %s disabled for good\n",
182
 
                  pd->host.buf());
 
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;
223
231
{
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");
228
235
}
229
236
 
230
237
/*
234
241
peerDigestNotePeerGone(PeerDigest * pd)
235
242
{
236
243
    if (pd->flags.requested) {
237
 
        debug(72, 2) ("peerDigest: peer %s gone, will destroy after fetch.\n",
238
 
                      pd->host.buf());
 
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 */
240
246
    } else {
241
 
        debug(72, 2) ("peerDigest: peer %s is gone, destroying now.\n",
242
 
                      pd->host.buf());
 
247
        debugs(72, 2, "peerDigest: peer " << pd->host.buf() << " is gone, destroying now.");
243
248
        peerDigestDestroy(pd);
244
249
    }
245
250
}
262
267
        return;
263
268
    }
264
269
 
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) << ")");
268
274
 
269
275
    /* decide when we should send the request:
270
276
     * request now unless too close to other requests */
273
279
    /* per-peer limit */
274
280
 
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).");
 
286
 
279
287
        req_time = pd->times.received + PeerDigestReqMinGap;
280
288
    }
281
289
 
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).");
 
296
 
287
297
        req_time = pd_last_req_time + GlobDigestReqMinGap;
288
298
    }
289
299
 
324
334
 
325
335
    key = storeKeyPublicByRequest(req);
326
336
 
327
 
    debug(72, 2) ("peerDigestRequest: %s key: %s\n", url, storeKeyText(key));
 
337
    debugs(72, 2, "peerDigestRequest: " << url << " key: " << storeKeyText(key));
328
338
 
329
339
    /* add custom headers */
330
340
    assert(!req->header.len);
364
374
    old_e = fetch->old_entry = Store::Root().get(key);
365
375
 
366
376
    if (old_e) {
367
 
        debug(72, 5) ("peerDigestRequest: found old entry\n");
 
377
        debugs(72, 5, "peerDigestRequest: found old entry");
368
378
 
369
379
        old_e->lock()
370
380
 
371
381
        ;
372
 
        storeCreateMemObject(old_e, url, url);
 
382
        old_e->createMemObject(url, url);
373
383
 
374
384
        fetch->old_sc = storeClientListAdd(old_e, fetch);
375
385
    }
383
393
        e->lastmod = old_e->lastmod;
384
394
 
385
395
    /* push towards peer cache */
386
 
    debug(72, 3) ("peerDigestRequest: forwarding to fwdStart...\n");
 
396
    debugs(72, 3, "peerDigestRequest: forwarding to fwdStart...");
387
397
 
388
398
    FwdState::fwdStart(-1, e, req);
389
399
 
536
546
        assert(reply);
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) << ")");
542
552
 
543
553
        /* this "if" is based on clientHandleIMSReply() */
544
554
 
557
567
 
558
568
            old_rep->updateOnNotModified(reply);
559
569
 
560
 
            storeTimestampsSet(fetch->old_entry);
 
570
            fetch->old_entry->timestampsSet();
561
571
 
562
572
            /* get rid of 304 reply */
563
573
            storeUnregister(fetch->sc, fetch->entry, fetch);
575
585
            /* get rid of old entry if any */
576
586
 
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;
583
593
            }
626
636
        assert (fetch->entry->getReply()->sline.status != 0);
627
637
 
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 <<
 
641
                   " got cached!");
 
642
 
631
643
            peerDigestFetchAbort(fetch, buf, "internal status error");
632
644
            return -1;
633
645
        }
786
798
    /* finish if we have a reason */
787
799
    if (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);
793
804
    } else {
804
815
peerDigestFetchStop(DigestFetchState * fetch, char *buf, const char *reason)
805
816
{
806
817
    assert(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);
810
820
}
811
821
 
814
824
peerDigestFetchAbort(DigestFetchState * fetch, char *buf, const char *reason)
815
825
{
816
826
    assert(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);
820
829
}
821
830
 
875
884
    pd->stats.recv.msgs += fetch->recv.msg;
876
885
 
877
886
    if (err) {
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);
881
888
 
882
889
        if (pd->cd) {
883
890
            cacheDigestDestroy(pd->cd);
896
903
        /* XXX: ugly condition, but how? */
897
904
 
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);
900
907
        else
901
 
            debug(72, 2) ("received valid digest from %s\n", host);
 
908
            debugs(72, 2, "received valid digest from " << host);
902
909
    }
903
910
 
904
911
    cbdataReferenceDone(fetch->pd);
912
919
    assert(fetch->entry && fetch->request);
913
920
 
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;
920
927
    }
963
970
    fetch->expires = fetch->entry->expires;
964
971
    fetch->resp_time = squid_curtime - fetch->start_time;
965
972
 
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");
 
975
 
 
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) <<
 
981
           ")");
 
982
 
971
983
}
972
984
 
973
985
 
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 <<
 
1003
           ")");
 
1004
 
 
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) */
995
1010
 
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);
 
1014
 
999
1015
        return 0;
1000
1016
    }
1001
1017
 
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);
 
1022
 
1005
1023
        return 0;
1006
1024
    }
1007
1025
 
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.");
1013
1031
        return 0;
1014
1032
    }
1015
1033
 
1024
1042
 
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 << ".");
1029
1047
        return 0;
1030
1048
    }
1031
1049
 
1042
1060
    }
1043
1061
 
1044
1062
    if (!pd->cd) {
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);
1048
1066
 
1049
1067
        if (cblock.mask_size >= freed_size)
1064
1082
    const int bit_util = cacheDigestBitUtil(pd->cd);
1065
1083
 
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 << "%%).");
 
1087
 
1069
1088
        return 0;
1070
1089
    }
1071
1090