]> git.ipfire.org Git - thirdparty/squid.git/blame - src/StoreSwapLogData.cc
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / StoreSwapLogData.cc
CommitLineData
51ee7c82 1/*
77b1029d 2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
51ee7c82 3 *
bbc27441
AJ
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.
51ee7c82 7 */
8
bbc27441
AJ
9/* DEBUG: section 47 Store Directory Routines */
10
f7f3304a 11#include "squid.h"
51ee7c82 12#include "StoreSwapLogData.h"
4b981814 13#include "swap_log_op.h"
51ee7c82 14
394c0932
AJ
15#include <ostream>
16
786f6516
AR
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
19void
20SwapChecksum24::set(uint32_t f1, uint32_t f2, uint32_t f3)
51ee7c82 21{
786f6516
AR
22 uint64_t sum = f1;
23 sum += f2;
24 sum += f3;
25
26 while (const uint64_t higherBits = sum >> 24)
d178daf7 27 sum = (sum & 0xFFFFFF) + higherBits;
786f6516
AR
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
37void
38SwapChecksum24::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
46std::ostream &
47SwapChecksum24::print(std::ostream &os) const
48{
49 return os << raw[0] << '-' << raw[1] << '-' << raw[2];
50}
51
3f9d4dc2
AR
52bool
53StoreSwapLogData::sane() const
54{
786f6516
AR
55 SwapChecksum24 actualSum;
56 actualSum.set(swap_filen, swap_file_sz);
57 if (checksum != actualSum)
58 return false;
3f9d4dc2 59
68992b63
AR
60 const time_t minTime = -2; // -1 is common; expires sometimes uses -2
61
3f9d4dc2
AR
62 // Check what we safely can; for some fields any value might be valid
63 return SWAP_LOG_NOP < op && op < SWAP_LOG_MAX &&
4db8126a
A
64 swap_filen >= 0 &&
65 timestamp >= minTime &&
66 lastref >= minTime &&
67 expires >= minTime &&
68 lastmod >= minTime &&
69 swap_file_sz > 0; // because swap headers ought to consume space
3f9d4dc2
AR
70}
71
786f6516
AR
72void
73StoreSwapLogData::finalize()
74{
75 checksum.set(swap_filen, swap_file_sz);
76}
77
78StoreSwapLogHeader::StoreSwapLogHeader(): op(SWAP_LOG_VERSION), version(2),
f53969cc 79 record_size(sizeof(StoreSwapLogData))
786f6516
AR
80{
81 checksum.set(version, record_size, 0);
82}
83
84bool
85StoreSwapLogHeader::sane() const
86{
87 SwapChecksum24 actualSum;
88 actualSum.set(version, record_size, 0);
89 if (checksum != actualSum)
90 return false;
91
92 return op == SWAP_LOG_VERSION && version >= 2 && record_size > 0;
93}
94
95size_t
96StoreSwapLogHeader::gapSize() const
47f6e231 97{
786f6516
AR
98 assert(record_size > 0);
99 assert(static_cast<size_t>(record_size) > sizeof(*this));
100 return static_cast<size_t>(record_size) - sizeof(*this);
47f6e231 101}
f53969cc 102