mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 21:45:37 +00:00
[master] Merged trac5502 (Cassandra vs OpenSSL)
This commit is contained in:
@@ -17,7 +17,7 @@ if HAVE_PGSQL
|
||||
AM_CPPFLAGS += $(PGSQL_CPPFLAGS)
|
||||
endif
|
||||
if HAVE_CQL
|
||||
AM_CPPFLAGS += $(CQL_CPPFLAGS) $(CRYPTO_INCLUDES)
|
||||
AM_CPPFLAGS += $(CQL_CPPFLAGS)
|
||||
endif
|
||||
|
||||
AM_CXXFLAGS = $(KEA_CXXFLAGS)
|
||||
|
@@ -28,13 +28,10 @@
|
||||
#include <dhcpsrv/db_exceptions.h>
|
||||
#include <dhcpsrv/dhcpsrv_log.h>
|
||||
#include <util/buffer.h>
|
||||
#include <util/hash.h>
|
||||
#include <util/optional_value.h>
|
||||
#include <asiolink/io_address.h>
|
||||
|
||||
/// @todo: With this include, Cassandra backend requires compilation with openssl.
|
||||
/// Kea supports two crypto libs: openssl and botan. The abstraction layer provided
|
||||
/// is via cryptolink.
|
||||
#include <openssl/md5.h> // for MD5_DIGEST_LENGTH
|
||||
#include <stdint.h> // for uint64_t
|
||||
|
||||
#include <boost/algorithm/string/classification.hpp> // for boost::is_any_of
|
||||
@@ -185,9 +182,8 @@ public:
|
||||
/// @brief Create unique hash for storage in table id.
|
||||
///
|
||||
/// Hash function used for creating a pseudo-unique hash from member
|
||||
/// values which uniquely determine an entry in the table. Uses OpenSSL's
|
||||
/// MD5 implementation.
|
||||
/// @todo: This must be generic and use cryptolink wrapper. See ticket #5502.
|
||||
/// values which uniquely determine an entry in the table. Uses FNV-1a
|
||||
/// on 64 bits.
|
||||
///
|
||||
/// The primary key aggregates: host_ipv4_subnet_id, host_ipv6_subnet_id,
|
||||
/// host_ipv4_address, reserved_ipv6_prefix_address,
|
||||
@@ -859,50 +855,25 @@ CqlHostExchange::createBindForMutation(const HostPtr& host,
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t
|
||||
md5Hash(const std::string& input) {
|
||||
|
||||
/// @todo: Convert this code to cryptolink calls and replace the
|
||||
/// direct use fromn md5.
|
||||
|
||||
// Prepare structures for MD5().
|
||||
const size_t word_size = MD5_DIGEST_LENGTH / sizeof(uint64_t);
|
||||
uint64_t hash[word_size];
|
||||
unsigned char* digest = reinterpret_cast<unsigned char*>(hash);
|
||||
unsigned char* string = reinterpret_cast<unsigned char*>(const_cast<char*>(input.c_str()));
|
||||
std::fill(hash, hash + word_size, 0);
|
||||
|
||||
// Get MD5 hash value.
|
||||
MD5(string, input.size(), digest);
|
||||
|
||||
// Return the first part of the hash value which still retains all
|
||||
// properties of the full hash value.
|
||||
return (hash[0]);
|
||||
}
|
||||
|
||||
cass_int64_t
|
||||
CqlHostExchange::hashIntoId() const {
|
||||
// Allocates a fixed maximum length in the stringstream for each
|
||||
// aggregated field to avoid collisions between distinct entries.
|
||||
// Add a separator between aggregated field to avoid collisions
|
||||
// between distinct entries.
|
||||
|
||||
// Get key.
|
||||
std::stringstream key_stream;
|
||||
key_stream << std::setw(10) << std::setfill('-') << host_ipv4_subnet_id_;
|
||||
key_stream << std::setw(10) << std::setfill('-') << host_ipv6_subnet_id_;
|
||||
key_stream << std::setw(V4ADDRESS_TEXT_MAX_LEN) << std::setfill('-')
|
||||
<< host_ipv4_address_;
|
||||
key_stream << std::setw(V6ADDRESS_TEXT_MAX_LEN) << std::setfill('-')
|
||||
<< reserved_ipv6_prefix_address_;
|
||||
key_stream << std::setw(4) << std::setfill('-')
|
||||
<< reserved_ipv6_prefix_length_;
|
||||
key_stream << std::setw(4) << std::setfill('-') << option_code_;
|
||||
key_stream << std::setw(OPTION_SPACE_MAX_LENGTH) << std::setfill('-')
|
||||
<< option_space_;
|
||||
key_stream << host_ipv4_subnet_id_ << "-";
|
||||
key_stream << host_ipv6_subnet_id_ << "-";
|
||||
key_stream << host_ipv4_address_ << "-";
|
||||
key_stream << reserved_ipv6_prefix_address_ << "/";
|
||||
key_stream << reserved_ipv6_prefix_length_ << "-";
|
||||
key_stream << option_code_ << "-";
|
||||
key_stream << option_space_;
|
||||
const std::string key = key_stream.str();
|
||||
|
||||
const cass_int64_t md5 = static_cast<cass_int64_t>(md5Hash(key));
|
||||
const cass_int64_t hash = static_cast<cass_int64_t>(Hash64::hash(key));
|
||||
|
||||
return (md5);
|
||||
return (hash);
|
||||
}
|
||||
|
||||
boost::any
|
||||
@@ -1287,7 +1258,7 @@ private:
|
||||
|
||||
/// @brief hash function for HostMap
|
||||
///
|
||||
/// Returns a 64-bits key value. The key is generated with MD5 hash
|
||||
/// Returns a 64-bits key value. The key is generated with FNV-1a 64 bit
|
||||
/// algorithm.
|
||||
///
|
||||
/// @param key being hashed
|
||||
@@ -1298,21 +1269,16 @@ hash_value(const HostKey& key) {
|
||||
// Get key.
|
||||
std::stringstream key_stream;
|
||||
HostIdentifier host_identifier = std::get<HOST_IDENTIFIER>(key);
|
||||
key_stream << std::setw(DUID::MAX_DUID_LEN) << std::setfill('0')
|
||||
<< DUID(host_identifier).toText();
|
||||
key_stream << std::setw(2) << std::setfill('0')
|
||||
<< std::get<HOST_IDENTIFIER_TYPE>(key);
|
||||
key_stream << std::setw(10) << std::setfill('0')
|
||||
<< std::get<IPv4_SUBNET_ID>(key);
|
||||
key_stream << std::setw(10) << std::setfill('0')
|
||||
<< std::get<IPv6_SUBNET_ID>(key);
|
||||
key_stream << std::setw(V4ADDRESS_TEXT_MAX_LEN) << std::setfill('0')
|
||||
<< std::get<IPv4_RESERVATION>(key);
|
||||
key_stream << DUID(host_identifier).toText() << "-";
|
||||
key_stream << std::get<HOST_IDENTIFIER_TYPE>(key) << "-";
|
||||
key_stream << std::get<IPv4_SUBNET_ID>(key) << "-";
|
||||
key_stream << std::get<IPv6_SUBNET_ID>(key) << "-";
|
||||
key_stream << std::get<IPv4_RESERVATION>(key);
|
||||
const std::string key_string = key_stream.str();
|
||||
|
||||
const uint64_t md5 = md5Hash(key_string);
|
||||
const uint64_t hash = Hash64::hash(key_string);
|
||||
|
||||
return (static_cast<std::size_t>(md5));
|
||||
return (static_cast<std::size_t>(hash));
|
||||
}
|
||||
|
||||
/// @brief equals operator for HostKey
|
||||
|
@@ -11,6 +11,7 @@ libkea_util_la_SOURCES = boost_time_utils.h boost_time_utils.cc
|
||||
libkea_util_la_SOURCES += buffer.h io_utilities.h
|
||||
libkea_util_la_SOURCES += csv_file.h csv_file.cc
|
||||
libkea_util_la_SOURCES += filename.h filename.cc
|
||||
libkea_util_la_SOURCES += hash.h
|
||||
libkea_util_la_SOURCES += labeled_value.h labeled_value.cc
|
||||
libkea_util_la_SOURCES += memory_segment.h
|
||||
libkea_util_la_SOURCES += memory_segment_local.h memory_segment_local.cc
|
||||
@@ -50,6 +51,7 @@ libkea_util_include_HEADERS = \
|
||||
buffer.h \
|
||||
csv_file.h \
|
||||
filename.h \
|
||||
hash.h \
|
||||
io_utilities.h \
|
||||
labeled_value.h \
|
||||
memory_segment.h \
|
||||
|
57
src/lib/util/hash.h
Normal file
57
src/lib/util/hash.h
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef HASH_H
|
||||
#define HASH_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace isc {
|
||||
namespace util {
|
||||
|
||||
/// @brief Hash implementation based on Fowler-Noll-Vo hash function
|
||||
///
|
||||
struct Hash64 {
|
||||
/// @brief Compute the hash
|
||||
///
|
||||
/// FNV-1a hash function
|
||||
///
|
||||
/// @param data data to hash
|
||||
/// @param length length of data
|
||||
/// @return the hash value
|
||||
static uint64_t hash(const uint8_t* data, size_t length) {
|
||||
uint64_t hash = FNV_offset_basis;
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
hash = hash ^ data[i];
|
||||
hash = hash * FNV_prime;
|
||||
}
|
||||
return (hash);
|
||||
}
|
||||
|
||||
/// @brief Compute the hash
|
||||
///
|
||||
/// FNV-1a hash function
|
||||
///
|
||||
/// @param str not empty string to hash
|
||||
/// @return the hash value
|
||||
static uint64_t hash(const std::string& str) {
|
||||
return (hash(reinterpret_cast<const uint8_t*>(str.c_str()),
|
||||
str.size()));
|
||||
}
|
||||
|
||||
/// @brief Offset basis
|
||||
static const uint64_t FNV_offset_basis = 14695981039346656037ull;
|
||||
|
||||
/// @brief Prime
|
||||
static const uint64_t FNV_prime = 1099511628211ull;
|
||||
};
|
||||
|
||||
} // end of namespace isc::util
|
||||
} // end of namespace isc
|
||||
|
||||
#endif
|
@@ -36,6 +36,7 @@ run_unittests_SOURCES += csv_file_unittest.cc
|
||||
run_unittests_SOURCES += fd_share_tests.cc
|
||||
run_unittests_SOURCES += fd_tests.cc
|
||||
run_unittests_SOURCES += filename_unittest.cc
|
||||
run_unittests_SOURCES += hash_unittest.cc
|
||||
run_unittests_SOURCES += hex_unittest.cc
|
||||
run_unittests_SOURCES += io_utilities_unittest.cc
|
||||
run_unittests_SOURCES += labeled_value_unittest.cc
|
||||
|
34
src/lib/util/tests/hash_unittest.cc
Normal file
34
src/lib/util/tests/hash_unittest.cc
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <util/hash.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
using namespace isc::util;
|
||||
using namespace std;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(HashTest, empty) {
|
||||
EXPECT_EQ(14695981039346656037ull, Hash64::hash(0, 0));
|
||||
}
|
||||
|
||||
TEST(HashTest, foobar) {
|
||||
EXPECT_EQ(9625390261332436968ull, Hash64::hash(string("foobar")));
|
||||
}
|
||||
|
||||
TEST(HashTest, chongo) {
|
||||
EXPECT_EQ(5080352029159061781ull,
|
||||
Hash64::hash(string("chongo was here!\n")));
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user