size_full(aDb_path + "/" + size_file),
db(NULL),
max_db_size(aMax_db_size),
- fs_block_size(aFs_block_size),
+ fs_block_size((aFs_block_size ? aFs_block_size : 2048)),
dbLock(db_full),
enabled_disk_store(true) {
if (db_path.empty() && !max_db_size)
throw std::runtime_error("Cannot open " + db_full + " to open");
}
-void Ssl::CertificateDb::check(std::string const & db_path, size_t max_db_size) {
- CertificateDb db(db_path, max_db_size, 0);
+void Ssl::CertificateDb::check(std::string const & db_path, size_t max_db_size, size_t fs_block_size) {
+ CertificateDb db(db_path, max_db_size, fs_block_size);
db.load();
+
+ // Call readSize to force rebuild size file in the case it is corrupted
+ (void)db.readSize();
+}
+
+size_t Ssl::CertificateDb::rebuildSize()
+{
+ size_t dbSize = 0;
+#if SQUID_SSLTXTDB_PSTRINGDATA
+ for (int i = 0; i < sk_OPENSSL_PSTRING_num(db.get()->data); ++i) {
+#if SQUID_STACKOF_PSTRINGDATA_HACK
+ const char ** current_row = ((const char **)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, db.get()->data), i));
+#else
+ const char ** current_row = ((const char **)sk_OPENSSL_PSTRING_value(db.get()->data, i));
+#endif
+#else
+ for (int i = 0; i < sk_num(db.get()->data); ++i) {
+ const char ** current_row = ((const char **)sk_value(db.get()->data, i));
+#endif
+ const std::string filename(cert_full + "/" + current_row[cnlSerial] + ".pem");
+ const size_t fSize = getFileSize(filename);
+ dbSize += fSize;
+ }
+ writeSize(dbSize);
+ return dbSize;
}
bool Ssl::CertificateDb::pure_find(std::string const & host_name, Ssl::X509_Pointer & cert, Ssl::EVP_PKEY_Pointer & pkey) {
return true;
}
-size_t Ssl::CertificateDb::size() const {
+size_t Ssl::CertificateDb::size() {
return readSize();
}
void Ssl::CertificateDb::addSize(std::string const & filename) {
- writeSize(readSize() + getFileSize(filename));
+ // readSize will rebuild 'size' file if missing or it is corrupted
+ size_t dbSize = readSize();
+ dbSize += getFileSize(filename);
+ writeSize(dbSize);
}
void Ssl::CertificateDb::subSize(std::string const & filename) {
- writeSize(readSize() - getFileSize(filename));
+ // readSize will rebuild 'size' file if missing or it is corrupted
+ size_t dbSize = readSize();
+ dbSize -= getFileSize(filename);
+ writeSize(dbSize);
}
-size_t Ssl::CertificateDb::readSize() const {
+size_t Ssl::CertificateDb::readSize() {
std::ifstream ifstr(size_full.c_str());
- if (!ifstr && enabled_disk_store)
- throw std::runtime_error("cannot open for reading: " + size_full);
size_t db_size = 0;
- if (!(ifstr >> db_size))
- throw std::runtime_error("error while reading " + size_full);
+ if (!ifstr || !(ifstr >> db_size))
+ return rebuildSize();
return db_size;
}
void Ssl::CertificateDb::writeSize(size_t db_size) {
std::ofstream ofstr(size_full.c_str());
- if (!ofstr && enabled_disk_store)
+ if (!ofstr)
throw std::runtime_error("cannot write \"" + size_full + "\" file");
ofstr << db_size;
}
size_t Ssl::CertificateDb::getFileSize(std::string const & filename) {
std::ifstream file(filename.c_str(), std::ios::binary);
+ if (!file)
+ return 0;
file.seekg(0, std::ios_base::end);
size_t file_size = file.tellg();
return ((file_size + fs_block_size - 1) / fs_block_size) * fs_block_size;
/// Create and initialize a database under the db_path
static void create(std::string const & db_path);
/// Check the database stored under the db_path.
- static void check(std::string const & db_path, size_t max_db_size);
+ static void check(std::string const & db_path, size_t max_db_size, size_t fs_block_size);
bool IsEnabledDiskStore() const; ///< Check enabled of dist store.
private:
void load(); ///< Load db from disk.
void save(); ///< Save db to disk.
- size_t size() const; ///< Get db size on disk in bytes.
+ size_t size(); ///< Get db size on disk in bytes.
/// Increase db size by the given file size and update size_file
void addSize(std::string const & filename);
/// Decrease db size by the given file size and update size_file
void subSize(std::string const & filename);
- size_t readSize() const; ///< Read size from file size_file
+ size_t readSize(); ///< Read size from file size_file
void writeSize(size_t db_size); ///< Write size to file size_file.
size_t getFileSize(std::string const & filename); ///< get file size on disk.
+ size_t rebuildSize(); ///< Rebuild size_file
/// Only find certificate in current db and return it.
bool pure_find(std::string const & host_name, Ssl::X509_Pointer & cert, Ssl::EVP_PKEY_Pointer & pkey);