Replace fingerprint with semver-based scheme. (#3467)
This commit is contained in:
+26
-6
@@ -5,6 +5,7 @@
|
||||
#include "util/exception_utils.hpp"
|
||||
#include "util/fingerprint.hpp"
|
||||
#include "util/log.hpp"
|
||||
#include "util/version.hpp"
|
||||
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/iostreams/seek.hpp>
|
||||
@@ -117,12 +118,31 @@ class FileReader
|
||||
|
||||
bool ReadAndCheckFingerprint()
|
||||
{
|
||||
auto fingerprint = ReadOne<util::FingerPrint>();
|
||||
const auto valid = util::FingerPrint::GetValid();
|
||||
// compare the compilation state stored in the fingerprint
|
||||
return valid.IsMagicNumberOK(fingerprint) && valid.TestContractor(fingerprint) &&
|
||||
valid.TestGraphUtil(fingerprint) && valid.TestRTree(fingerprint) &&
|
||||
valid.TestQueryObjects(fingerprint);
|
||||
auto loaded_fingerprint = ReadOne<util::FingerPrint>();
|
||||
const auto expected_fingerprint = util::FingerPrint::GetValid();
|
||||
|
||||
if (!loaded_fingerprint.IsValid())
|
||||
{
|
||||
util::Log(logERROR) << "Fingerprint magic number or checksum is invalid in "
|
||||
<< filepath.string();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!expected_fingerprint.IsDataCompatible(loaded_fingerprint))
|
||||
{
|
||||
util::Log(logERROR) << filepath.string()
|
||||
<< " is not compatible with this version of OSRM";
|
||||
|
||||
util::Log(logERROR) << "It was prepared with OSRM "
|
||||
<< loaded_fingerprint.GetMajorVersion() << "."
|
||||
<< loaded_fingerprint.GetMinorVersion() << "."
|
||||
<< loaded_fingerprint.GetPatchVersion() << " but you are running "
|
||||
<< OSRM_VERSION;
|
||||
util::Log(logERROR) << "Data is only compatible between minor releases.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::size_t Size()
|
||||
|
||||
@@ -40,13 +40,6 @@ struct HSGRHeader
|
||||
// file and returns them in a HSGRHeader struct
|
||||
inline HSGRHeader readHSGRHeader(io::FileReader &input_file)
|
||||
{
|
||||
const util::FingerPrint fingerprint_valid = util::FingerPrint::GetValid();
|
||||
const auto fingerprint_loaded = input_file.ReadOne<util::FingerPrint>();
|
||||
if (!fingerprint_loaded.TestGraphUtil(fingerprint_valid))
|
||||
{
|
||||
util::Log(logWARNING) << ".hsgr was prepared with different build.\n"
|
||||
"Reprocess to get rid of this warning.";
|
||||
}
|
||||
|
||||
HSGRHeader header;
|
||||
input_file.ReadInto(header.checksum);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#ifndef FINGERPRINT_H
|
||||
#define FINGERPRINT_H
|
||||
|
||||
#include <array>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace osrm
|
||||
@@ -14,25 +16,25 @@ class FingerPrint
|
||||
{
|
||||
public:
|
||||
static FingerPrint GetValid();
|
||||
const boost::uuids::uuid &GetFingerPrint() const;
|
||||
bool IsMagicNumberOK(const FingerPrint &other) const;
|
||||
bool TestGraphUtil(const FingerPrint &other) const;
|
||||
bool TestContractor(const FingerPrint &other) const;
|
||||
bool TestRTree(const FingerPrint &other) const;
|
||||
bool TestQueryObjects(const FingerPrint &other) const;
|
||||
|
||||
bool IsValid() const;
|
||||
bool IsDataCompatible(const FingerPrint &other) const;
|
||||
|
||||
int GetMajorVersion() const;
|
||||
int GetMinorVersion() const;
|
||||
int GetPatchVersion() const;
|
||||
|
||||
private:
|
||||
unsigned magic_number;
|
||||
char md5_prepare[33];
|
||||
char md5_tree[33];
|
||||
char md5_graph[33];
|
||||
char md5_objects[33];
|
||||
|
||||
// initialize to {6ba7b810-9dad-11d1-80b4-00c04fd430c8}
|
||||
boost::uuids::uuid named_uuid;
|
||||
std::uint8_t CalculateChecksum() const;
|
||||
// Here using std::array so that == can be used to conveniently compare contents
|
||||
std::array<std::uint8_t, 4> magic_number;
|
||||
std::uint8_t major_version;
|
||||
std::uint8_t minor_version;
|
||||
std::uint8_t patch_version;
|
||||
std::uint8_t checksum; // CRC8 of the previous bytes to ensure the fingerprint is not damaged
|
||||
};
|
||||
|
||||
static_assert(sizeof(FingerPrint) == 152, "FingerPrint has unexpected size");
|
||||
static_assert(sizeof(FingerPrint) == 8, "FingerPrint has unexpected size");
|
||||
static_assert(std::is_trivial<FingerPrint>::value, "FingerPrint needs to be trivial.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
#include "util/fingerprint.hpp"
|
||||
#include "util/exception.hpp"
|
||||
#include "util/exception_utils.hpp"
|
||||
|
||||
#include <boost/uuid/name_generator.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#cmakedefine MD5PREPARE "${MD5PREPARE}"
|
||||
#cmakedefine MD5RTREE "${MD5RTREE}"
|
||||
#cmakedefine MD5GRAPH "${MD5GRAPH}"
|
||||
#cmakedefine MD5OBJECTS "${MD5OBJECTS}"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
|
||||
FingerPrint FingerPrint::GetValid()
|
||||
{
|
||||
FingerPrint fingerprint;
|
||||
|
||||
fingerprint.magic_number = 1297240911;
|
||||
fingerprint.md5_prepare[32] = fingerprint.md5_tree[32] = fingerprint.md5_graph[32] = fingerprint.md5_objects[32] = '\0';
|
||||
|
||||
// 6ba7b810-9dad-11d1-80b4-00c04fd430c8 is a Well Known UUID representing the DNS
|
||||
// namespace. Its use here indicates that we own this part of the UUID space
|
||||
// in the DNS realm. *Usually*, we would then generate a UUID based on "something.project-osrm.org",
|
||||
// but this whole class is a hack. Anyway, named_uuid needs to be initialized to something
|
||||
// before it can be used, and this is as good as anything else for these purposes.
|
||||
fingerprint.named_uuid = boost::uuids::string_generator()( "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}");
|
||||
|
||||
boost::uuids::name_generator gen(fingerprint.named_uuid);
|
||||
std::string temp_string;
|
||||
|
||||
std::memcpy(fingerprint.md5_prepare, MD5PREPARE, 32);
|
||||
temp_string += fingerprint.md5_prepare;
|
||||
std::memcpy(fingerprint.md5_tree, MD5RTREE, 32);
|
||||
temp_string += fingerprint.md5_tree;
|
||||
std::memcpy(fingerprint.md5_graph, MD5GRAPH, 32);
|
||||
temp_string += fingerprint.md5_graph;
|
||||
std::memcpy(fingerprint.md5_objects, MD5OBJECTS, 32);
|
||||
temp_string += fingerprint.md5_objects;
|
||||
|
||||
fingerprint.named_uuid = gen(temp_string);
|
||||
|
||||
return fingerprint;
|
||||
}
|
||||
|
||||
const boost::uuids::uuid &FingerPrint::GetFingerPrint() const { return named_uuid; }
|
||||
|
||||
bool FingerPrint::IsMagicNumberOK(const FingerPrint& other) const { return other.magic_number == magic_number; }
|
||||
|
||||
bool FingerPrint::TestGraphUtil(const FingerPrint &other) const
|
||||
{
|
||||
if (!IsMagicNumberOK(other))
|
||||
{
|
||||
throw exception(std::string("hsgr input file misses magic number. Check or reprocess the file") + SOURCE_REF);
|
||||
}
|
||||
return std::equal(md5_graph, md5_graph + 32, other.md5_graph);
|
||||
}
|
||||
|
||||
bool FingerPrint::TestContractor(const FingerPrint &other) const
|
||||
{
|
||||
if (!IsMagicNumberOK(other))
|
||||
{
|
||||
throw exception(std::string("osrm input file misses magic number. Check or reprocess the file") + SOURCE_REF);
|
||||
}
|
||||
return std::equal(md5_prepare, md5_prepare + 32, other.md5_prepare);
|
||||
}
|
||||
|
||||
bool FingerPrint::TestRTree(const FingerPrint &other) const
|
||||
{
|
||||
if (!IsMagicNumberOK(other))
|
||||
{
|
||||
throw exception(std::string("r-tree input file misses magic number. Check or reprocess the file") + SOURCE_REF);
|
||||
}
|
||||
return std::equal(md5_tree, md5_tree + 32, other.md5_tree);
|
||||
}
|
||||
|
||||
bool FingerPrint::TestQueryObjects(const FingerPrint &other) const
|
||||
{
|
||||
if (!IsMagicNumberOK(other))
|
||||
{
|
||||
throw exception(std::string("missing magic number. Check or reprocess the file") + SOURCE_REF);
|
||||
}
|
||||
return std::equal(md5_objects, md5_objects + 32, other.md5_objects);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
#ifndef VERSION_HPP
|
||||
#define VERSION_HPP
|
||||
|
||||
#define OSRM_VERSION_MAJOR "@OSRM_VERSION_MAJOR@"
|
||||
#define OSRM_VERSION_MINOR "@OSRM_VERSION_MINOR@"
|
||||
#define OSRM_VERSION_PATCH "@OSRM_VERSION_PATCH@"
|
||||
#define OSRM_VERSION_MAJOR @OSRM_VERSION_MAJOR@
|
||||
#define OSRM_VERSION_MINOR @OSRM_VERSION_MINOR@
|
||||
#define OSRM_VERSION_PATCH @OSRM_VERSION_PATCH@
|
||||
|
||||
#define OSRM_VERSION "v" OSRM_VERSION_MAJOR "." OSRM_VERSION_MINOR "." OSRM_VERSION_PATCH
|
||||
#define OSRM_VERSION__(A,B,C) "v" #A "." #B "." #C
|
||||
#define OSRM_VERSION_(A,B,C) OSRM_VERSION__(A,B,C)
|
||||
#define OSRM_VERSION OSRM_VERSION_(OSRM_VERSION_MAJOR, OSRM_VERSION_MINOR, OSRM_VERSION_PATCH)
|
||||
|
||||
#endif // VERSION_HPP
|
||||
|
||||
Reference in New Issue
Block a user