/* * Copyright (C) 1996-2023 The Squid Software Foundation and contributors * * Squid software is distributed under GPLv2+ license and includes * contributions from numerous individuals and organizations. * Please see the COPYING and CONTRIBUTORS files for details. */ #ifndef SQUID_SRC_STORESWAPLOGDATA_H #define SQUID_SRC_STORESWAPLOGDATA_H /** \defgroup FileFormatSwapStateAPI swap.state File Structure \ingroup FileSystems \section ImplementationNotes Implementation Notes \par * When writing an object to disk, we must first write the meta data. * Store::PackSwapMeta() serializes that meta data * into a character buffer that we can write. * \note MemObject has a MemObject::swap_hdr_sz. * This value is the size of that character buffer; the size of the * swap file meta data. The StoreEntry has a member * StoreEntry::swap_file_sz that represents the size of the disk file. * Thus, the size of the object "content" is \code StoreEntry->swap_file_sz - MemObject->swap_hdr_sz; \endcode \note The swap file content includes the HTTP reply headers and the HTTP reply body (if any). * \par * When reading a swap file, Store::Unpack*SwapMeta*() functions iterate * over stored swap meta data header fields and also extract * the value for MemObject->swap_hdr_sz. */ #include "md5.h" #include "mem/forward.h" #include "store/forward.h" /// maintains a 24-bit checksum over integer fields class SwapChecksum24 { public: SwapChecksum24() { raw[0] = raw[1] = raw[2] = 0; } bool operator ==(const SwapChecksum24 &o) const { return raw[0] == o.raw[0] && raw[1] == o.raw[1] && raw[2] == o.raw[2]; } bool operator !=(const SwapChecksum24 &o) const { return !(*this == o); } /// compute and store checksum based on three 32bit integers void set(uint32_t f1, uint32_t f2, uint32_t f3); /// compute and store checksum based on int32_t and uint64_t integers void set(int32_t f1, uint64_t f2); // printing for debugging std::ostream &print(std::ostream &os) const; private: uint8_t raw[3]; // designed to follow "op" members, in padding space }; inline std::ostream & operator <<(std::ostream &os, const SwapChecksum24 &sum) { return sum.print(os); } /** \ingroup FielFormatSwapStateAPI * \par * Defines the structure of a binary swap.state file entry for UFS stores. * TODO: Move to fs/ufs * \note StoreSwapLogData entries are written in native machine byte order * They are not necessarily portable across architectures. */ class StoreSwapLogData { MEMPROXY_CLASS(StoreSwapLogData); public: /// type to use for storing time-related members; must be signed typedef int64_t SwappedTime; /// consistency self-check: whether the data appears to make sense bool sane() const; /// call this before storing the log entry void finalize(); /** * Either SWAP_LOG_ADD when an object is added to the disk storage, * or SWAP_LOG_DEL when an object is deleted. */ uint8_t op = 0; /** * Fingerprint to weed out bogus/corrupted swap.state entries. */ SwapChecksum24 checksum; // follows "op" because compiler will pad anyway /** * The 32-bit file number which maps to a pathname. * Only the low 24-bits are relevant. The high 8-bits are * used as an index to an array of storage directories, and * are set at run time because the order of storage directories * may change over time. */ sfileno swap_filen = 0; /** * A Unix time value that represents the time when * the origin server generated this response. If the response * has a valid Date: header, this timestamp corresponds * to that time. Otherwise, it is set to the Squid process time * when the response is read (as soon as the end of headers are found). */ SwappedTime timestamp = 0; /** * The last time that a client requested this object. */ SwappedTime lastref = 0; /** * The value of the response's Expires: header, if any. * If the response does not have an Expires: header, this * is set to -1. * If the response has an invalid (unparsable) * Expires: header, it is also set to -1. There are some cases * where Squid sets expires to -2. This happens for the * internal "netdb" object and for FTP URL responses. */ SwappedTime expires = 0; /** * The value of the response's Last-modified: header, if any. * This is set to -1 if there is no Last-modified: header, * or if it is unparsable. */ SwappedTime lastmod = 0; /** * This is the number of bytes that the object occupies on * disk. It includes the Squid "swap file header". */ uint64_t swap_file_sz = 0; /** * The number of times that this object has been accessed (referenced). * Since its a 16-bit quantity, it is susceptible to overflow * if a single object is accessed 65,536 times before being replaced. */ uint16_t refcount; /** * A copy of the StoreEntry flags field. Used as a sanity * check when rebuilding the cache at startup. Objects that * have the KEY_PRIVATE flag set are not added back to the cache. */ uint16_t flags = 0; /** * The 128-bit MD5 hash for this object. */ unsigned char key[SQUID_MD5_DIGEST_LENGTH] = {}; }; /// \ingroup FileFormatSwapStateAPI /// Swap log starts with this binary structure. class StoreSwapLogHeader { public: // sets default values for this Squid version; loaded values may differ StoreSwapLogHeader(); /// consistency self-check: whether the data appears to make sense bool sane() const; /// number of bytes after the log header before the first log entry size_t gapSize() const; uint8_t op; SwapChecksum24 checksum; // follows "op" because compiler will pad anyway int32_t version; int32_t record_size; }; #endif /* SQUID_SRC_STORESWAPLOGDATA_H */