]> git.ipfire.org Git - thirdparty/squid.git/blob - src/StoreSwapLogData.cc
Docs: Copyright updates for 2018 (#114)
[thirdparty/squid.git] / src / StoreSwapLogData.cc
1 /*
2 * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 /* DEBUG: section 47 Store Directory Routines */
10
11 #include "squid.h"
12 #include "StoreSwapLogData.h"
13 #include "swap_log_op.h"
14
15 #include <ostream>
16
17 // Based on Internet Checksum (RFC 1071) algorithm but takes three 32bit ints.
18 // TODO: Consider Fletcher's checksum algorithm as a higher quality alternative
19 void
20 SwapChecksum24::set(uint32_t f1, uint32_t f2, uint32_t f3)
21 {
22 uint64_t sum = f1;
23 sum += f2;
24 sum += f3;
25
26 while (const uint64_t higherBits = sum >> 24)
27 sum = (sum & 0xFFFFFF) + higherBits;
28
29 sum = ~sum;
30
31 raw[0] = static_cast<uint8_t>(sum);
32 raw[1] = static_cast<uint8_t>(sum >> 8);
33 raw[2] = static_cast<uint8_t>(sum >> 16);
34 }
35
36 /// Same as 3-argument SwapChecksum24::set() but for int32_t and uint64_t
37 void
38 SwapChecksum24::set(int32_t f1, uint64_t f2)
39 {
40 // split the second 64bit word into two 32bit words
41 set(static_cast<uint32_t>(f1),
42 static_cast<uint32_t>(f2 >> 32),
43 static_cast<uint32_t>(f2 & 0xFFFFFFFF));
44 }
45
46 std::ostream &
47 SwapChecksum24::print(std::ostream &os) const
48 {
49 return os << raw[0] << '-' << raw[1] << '-' << raw[2];
50 }
51
52 StoreSwapLogData::StoreSwapLogData()
53 {
54 memset(this, 0, sizeof(*this));
55 }
56
57 bool
58 StoreSwapLogData::sane() const
59 {
60 SwapChecksum24 actualSum;
61 actualSum.set(swap_filen, swap_file_sz);
62 if (checksum != actualSum)
63 return false;
64
65 const time_t minTime = -2; // -1 is common; expires sometimes uses -2
66
67 // Check what we safely can; for some fields any value might be valid
68 return SWAP_LOG_NOP < op && op < SWAP_LOG_MAX &&
69 swap_filen >= 0 &&
70 timestamp >= minTime &&
71 lastref >= minTime &&
72 expires >= minTime &&
73 lastmod >= minTime &&
74 swap_file_sz > 0; // because swap headers ought to consume space
75 }
76
77 void
78 StoreSwapLogData::finalize()
79 {
80 checksum.set(swap_filen, swap_file_sz);
81 }
82
83 StoreSwapLogHeader::StoreSwapLogHeader(): op(SWAP_LOG_VERSION), version(2),
84 record_size(sizeof(StoreSwapLogData))
85 {
86 checksum.set(version, record_size, 0);
87 }
88
89 bool
90 StoreSwapLogHeader::sane() const
91 {
92 SwapChecksum24 actualSum;
93 actualSum.set(version, record_size, 0);
94 if (checksum != actualSum)
95 return false;
96
97 return op == SWAP_LOG_VERSION && version >= 2 && record_size > 0;
98 }
99
100 size_t
101 StoreSwapLogHeader::gapSize() const
102 {
103 assert(record_size > 0);
104 assert(static_cast<size_t>(record_size) > sizeof(*this));
105 return static_cast<size_t>(record_size) - sizeof(*this);
106 }
107