mirror of
https://github.com/EvernodeXRPL/hpcore.git
synced 2026-04-29 15:37:59 +00:00
Updated hpfs hash verification with file mode checks. (#257)
* Added file mode to hpfs responses. * Parse file mode on hpfs response read. * Apply file/dir mode. * Fixed mode apply logic. * Fixed code review comments. * Additional fix.
This commit is contained in:
@@ -181,10 +181,10 @@ namespace conf
|
||||
std::string hpfs_exe_path; // hpfs executable file path.
|
||||
|
||||
std::string contract_dir; // Contract base directory full path.
|
||||
std::string contract_hpfs_dir; // Contract hpfs metdata dir (The location of hpfs log file).
|
||||
std::string contract_hpfs_dir; // Contract hpfs metadata dir (The location of hpfs log file).
|
||||
std::string contract_hpfs_mount_dir; // Contract hpfs fuse file system mount path.
|
||||
std::string contract_hpfs_rw_dir; // Contract hpfs read/write fs session path.
|
||||
std::string ledger_hpfs_dir; // Ledger hpfs metdata dir (The location of hpfs log file).
|
||||
std::string ledger_hpfs_dir; // Ledger hpfs metadata dir (The location of hpfs log file).
|
||||
std::string ledger_hpfs_mount_dir; // Ledger hpfs fuse file system mount path.
|
||||
std::string ledger_hpfs_rw_dir; // Ledger hpfs read/write fs session path.
|
||||
std::string log_dir; // HotPocket log dir full path.
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace crypto
|
||||
* @param data_length hash data length.
|
||||
* @return The blake3 hash of the pointed buffer.
|
||||
*/
|
||||
const std::string get_hash(const unsigned char *data, size_t data_length)
|
||||
const std::string get_hash(const void *data, const size_t data_length)
|
||||
{
|
||||
std::string hash;
|
||||
hash.resize(BLAKE3_OUT_LEN);
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace crypto
|
||||
|
||||
const std::string get_hash(std::string_view data);
|
||||
|
||||
const std::string get_hash(const unsigned char *data, size_t data_length);
|
||||
const std::string get_hash(const void *data, const size_t data_length);
|
||||
|
||||
const std::string get_hash(std::string_view s1, std::string_view s2);
|
||||
|
||||
|
||||
@@ -161,8 +161,9 @@ namespace hpfs
|
||||
if (hr.is_file)
|
||||
{
|
||||
std::vector<util::h32> block_hashes;
|
||||
std::size_t file_length = 0;
|
||||
const int result = get_data_block_hashes(block_hashes, file_length, hr.parent_path, hr.expected_hash);
|
||||
size_t file_length = 0;
|
||||
mode_t file_mode = 0;
|
||||
const int result = get_data_block_hashes(block_hashes, file_length, file_mode, hr.parent_path, hr.expected_hash);
|
||||
|
||||
if (result == -1)
|
||||
{
|
||||
@@ -173,7 +174,7 @@ namespace hpfs
|
||||
{
|
||||
p2pmsg::create_msg_from_filehashmap_response(
|
||||
fbuf, hr.parent_path, fs_mount->mount_id, block_hashes,
|
||||
file_length, hr.expected_hash);
|
||||
file_length, file_mode, hr.expected_hash);
|
||||
return 1; // Success.
|
||||
}
|
||||
}
|
||||
@@ -191,8 +192,17 @@ namespace hpfs
|
||||
}
|
||||
else if (result == 1)
|
||||
{
|
||||
// Get dir mode.
|
||||
const std::string dir_path = fs_mount->rw_dir + hr.parent_path.data();
|
||||
struct stat st;
|
||||
if (stat(dir_path.data(), &st) == -1)
|
||||
{
|
||||
LOG_ERROR << errno << ": Error in getting dir metadata: " << hr.parent_path;
|
||||
return -1;
|
||||
}
|
||||
|
||||
p2pmsg::create_msg_from_fsentry_response(
|
||||
fbuf, hr.parent_path, fs_mount->mount_id, child_hash_nodes, hr.expected_hash);
|
||||
fbuf, hr.parent_path, fs_mount->mount_id, st.st_mode, child_hash_nodes, hr.expected_hash);
|
||||
return 1; // Success.
|
||||
}
|
||||
}
|
||||
@@ -283,7 +293,7 @@ namespace hpfs
|
||||
* Retrieves the specified file block hashes if expected hash matches.
|
||||
* @return 1 if block hashes were successfuly fetched. 0 if vpath does not exist. -1 on error.
|
||||
*/
|
||||
int hpfs_serve::get_data_block_hashes(std::vector<util::h32> &hashes, size_t &file_length,
|
||||
int hpfs_serve::get_data_block_hashes(std::vector<util::h32> &hashes, size_t &file_length, mode_t &file_mode,
|
||||
const std::string_view vpath, const util::h32 expected_hash)
|
||||
{
|
||||
// Check whether the existing file hash matches expected hash.
|
||||
@@ -303,15 +313,16 @@ namespace hpfs
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get actual file length.
|
||||
// Get actual file metadata.
|
||||
const std::string file_path = fs_mount->rw_dir + vpath.data();
|
||||
struct stat st;
|
||||
if (stat(file_path.c_str(), &st) == -1)
|
||||
{
|
||||
LOG_ERROR << errno << ": Stat failed when getting file length. " << file_path;
|
||||
LOG_ERROR << errno << ": Stat failed when getting file metadata. " << file_path;
|
||||
result = -1;
|
||||
}
|
||||
file_length = st.st_size;
|
||||
file_mode = st.st_mode;
|
||||
result = 1; // Success.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,13 @@ namespace hpfs
|
||||
hpfs::hpfs_mount *fs_mount = NULL;
|
||||
std::string_view name;
|
||||
void hpfs_serve_loop();
|
||||
int create_hpfs_response(flatbuffers::FlatBufferBuilder &fbuf, const p2p::hpfs_request &hr);
|
||||
int get_data_block(std::vector<uint8_t> &block, const std::string_view vpath,
|
||||
const uint32_t block_id, const util::h32 expected_hash);
|
||||
int get_data_block_hashes(std::vector<util::h32> &hashes, size_t &file_length, mode_t &file_mode,
|
||||
const std::string_view vpath, const util::h32 expected_hash);
|
||||
int get_fs_entry_hashes(std::vector<hpfs::child_hash_node> &hash_nodes,
|
||||
const std::string_view vpath, const util::h32 expected_hash);
|
||||
|
||||
protected:
|
||||
std::list<std::pair<std::string, p2p::hpfs_request>> hpfs_requests;
|
||||
@@ -26,17 +33,6 @@ namespace hpfs
|
||||
int init(std::string_view server_name, hpfs::hpfs_mount *fs_mount_ptr);
|
||||
|
||||
void deinit();
|
||||
|
||||
int create_hpfs_response(flatbuffers::FlatBufferBuilder &fbuf, const p2p::hpfs_request &hr);
|
||||
|
||||
int get_data_block(std::vector<uint8_t> &block, const std::string_view vpath,
|
||||
const uint32_t block_id, const util::h32 expected_hash);
|
||||
|
||||
int get_data_block_hashes(std::vector<util::h32> &hashes, size_t &file_length,
|
||||
const std::string_view vpath, const util::h32 expected_hash);
|
||||
|
||||
int get_fs_entry_hashes(std::vector<hpfs::child_hash_node> &hash_nodes,
|
||||
const std::string_view vpath, const util::h32 expected_hash);
|
||||
};
|
||||
} // namespace hpfs
|
||||
|
||||
|
||||
@@ -266,33 +266,31 @@ namespace hpfs
|
||||
std::unordered_map<std::string, p2p::hpfs_fs_hash_entry> peer_fs_entry_map;
|
||||
p2pmsg::flatbuf_hpfsfshashentry_to_hpfsfshashentry(peer_fs_entry_map, fs_resp.entries());
|
||||
|
||||
// Commented for now. Need to change the way the hash is calculated once the flatbuffer re-architecture finishes.
|
||||
// Validate received fs data against the hash.
|
||||
// if (!validate_fs_entry_hash(vpath, hash, peer_fs_entry_map))
|
||||
// {
|
||||
// LOG_INFO << "Hpfs " << name << " sync: Skipping hpfs response due to fs entry hash mismatch.";
|
||||
// continue;
|
||||
// }
|
||||
if (!validate_fs_entry_hash(vpath, hash, fs_resp.dir_mode(), peer_fs_entry_map))
|
||||
{
|
||||
LOG_INFO << "Hpfs " << name << " sync: Skipping hpfs response due to fs entry hash mismatch.";
|
||||
continue;
|
||||
}
|
||||
|
||||
handle_fs_entry_response(vpath, peer_fs_entry_map);
|
||||
handle_fs_entry_response(vpath, fs_resp.dir_mode(), peer_fs_entry_map);
|
||||
}
|
||||
else if (msg_type == p2pmsg::HpfsResponse_HpfsFileHashMapResponse)
|
||||
{
|
||||
const p2pmsg::HpfsFileHashMapResponse &file_resp = *resp_msg.content_as_HpfsFileHashMapResponse();
|
||||
|
||||
// File block hashes we received from the peer.
|
||||
const util::h32 *peer_hashes = reinterpret_cast<const util::h32 *>(file_resp.hash_map()->data());
|
||||
const size_t peer_hash_count = file_resp.hash_map()->size() / sizeof(util::h32);
|
||||
const util::h32 *block_hashes = reinterpret_cast<const util::h32 *>(file_resp.hash_map()->data());
|
||||
const size_t block_hash_count = file_resp.hash_map()->size() / sizeof(util::h32);
|
||||
|
||||
// Commented for now. Need to change the way the hash is calculated once the flatbuffer re-architecture finishes.
|
||||
// Validate received hashmap against the hash.
|
||||
// if (!validate_file_hashmap_hash(vpath, hash, peer_hashes, peer_hash_count))
|
||||
// {
|
||||
// LOG_INFO << "Hpfs " << name << " sync: Skipping hpfs response due to file hashmap hash mismatch.";
|
||||
// continue;
|
||||
// }
|
||||
if (!validate_file_hashmap_hash(vpath, hash, file_resp.file_mode(), block_hashes, block_hash_count))
|
||||
{
|
||||
LOG_INFO << "Hpfs " << name << " sync: Skipping hpfs response due to file hashmap hash mismatch.";
|
||||
continue;
|
||||
}
|
||||
|
||||
handle_file_hashmap_response(vpath, peer_hashes, peer_hash_count, file_resp.file_length());
|
||||
handle_file_hashmap_response(vpath, file_resp.file_mode(), block_hashes, block_hash_count, file_resp.file_length());
|
||||
}
|
||||
else if (msg_type == p2pmsg::HpfsResponse_HpfsBlockResponse)
|
||||
{
|
||||
@@ -302,13 +300,12 @@ namespace hpfs
|
||||
const uint32_t block_id = block_resp.block_id();
|
||||
std::string_view buf = msg::fbuf::flatbuf_bytes_to_sv(block_resp.data());
|
||||
|
||||
// Commented for now. Need to change the way the hash is calculated once the flatbuffer re-architecture finishes.
|
||||
// Validate received block data against the hash.
|
||||
// if (!validate_file_block_hash(hash, block_id, buf))
|
||||
// {
|
||||
// LOG_INFO << "Hpfs " << name << " sync: Skipping hpfs response due to file block hash mismatch.";
|
||||
// continue;
|
||||
// }
|
||||
if (!validate_file_block_hash(hash, block_id, buf))
|
||||
{
|
||||
LOG_INFO << "Hpfs " << name << " sync: Skipping hpfs response due to file block hash mismatch.";
|
||||
continue;
|
||||
}
|
||||
|
||||
handle_file_block_response(vpath, block_id, buf);
|
||||
}
|
||||
@@ -394,18 +391,24 @@ namespace hpfs
|
||||
* Vadidated the received hash against the received fs entry map.
|
||||
* @param vpath Virtual path of the fs.
|
||||
* @param hash Received hash.
|
||||
* @param dir_mode Metadata 'mode' of the directory containing the fs entries.
|
||||
* @param fs_entry_map Received fs entry map.
|
||||
* @returns true if hash is valid, otherwise false.
|
||||
*/
|
||||
bool hpfs_sync::validate_fs_entry_hash(std::string_view vpath, std::string_view hash, const std::unordered_map<std::string, p2p::hpfs_fs_hash_entry> &fs_entry_map)
|
||||
bool hpfs_sync::validate_fs_entry_hash(std::string_view vpath, std::string_view hash, const mode_t dir_mode,
|
||||
const std::unordered_map<std::string, p2p::hpfs_fs_hash_entry> &fs_entry_map)
|
||||
{
|
||||
util::h32 content_hash;
|
||||
|
||||
const std::string vpath_name = util::get_name(vpath);
|
||||
|
||||
// Initilal hash is vpath hash.
|
||||
// Initilal hash is vpath hash + mode hash.
|
||||
content_hash = crypto::get_hash(vpath_name);
|
||||
|
||||
uint8_t mode_bytes[4];
|
||||
util::uint32_to_bytes(mode_bytes, dir_mode);
|
||||
content_hash ^= crypto::get_hash(mode_bytes, sizeof(mode_bytes));
|
||||
|
||||
// Then XOR the file hashes to the initial hash.
|
||||
for (const auto &[name, fs_entry] : fs_entry_map)
|
||||
{
|
||||
@@ -419,19 +422,25 @@ namespace hpfs
|
||||
* Vadidated the received hash against the received file hash map.
|
||||
* @param vpath Virtual path of the file.
|
||||
* @param hash Received hash.
|
||||
* @param file_mode Metadata 'mode' of the file.
|
||||
* @param hashes Received block hashes.
|
||||
* @param hash_count Size of the hash list.
|
||||
* @returns true if hash is valid, otherwise false.
|
||||
*/
|
||||
bool hpfs_sync::validate_file_hashmap_hash(std::string_view vpath, std::string_view hash, const util::h32 *hashes, const size_t hash_count)
|
||||
bool hpfs_sync::validate_file_hashmap_hash(std::string_view vpath, std::string_view hash, const mode_t file_mode,
|
||||
const util::h32 *hashes, const size_t hash_count)
|
||||
{
|
||||
util::h32 content_hash = util::h32_empty;
|
||||
|
||||
const std::string vpath_name = util::get_name(vpath);
|
||||
|
||||
// Initilal hash is vpath hash.
|
||||
// Initilal hash is vpath hash + mode hash.
|
||||
content_hash = crypto::get_hash(vpath_name);
|
||||
|
||||
uint8_t mode_bytes[4];
|
||||
util::uint32_to_bytes(mode_bytes, file_mode);
|
||||
content_hash ^= crypto::get_hash(mode_bytes, sizeof(mode_bytes));
|
||||
|
||||
// Then XOR the block hashes to the initial hash.
|
||||
for (int32_t block_id = 0; block_id < hash_count; block_id++)
|
||||
{
|
||||
@@ -452,7 +461,9 @@ namespace hpfs
|
||||
{
|
||||
// Calculate block offset of this block.
|
||||
const off_t block_offset = block_id * hpfs::BLOCK_SIZE;
|
||||
std::string_view offset = std::string_view(reinterpret_cast<const char *>(&block_offset), sizeof(off_t));
|
||||
uint8_t bytes[8];
|
||||
util::uint64_to_bytes(bytes, block_offset);
|
||||
std::string_view offset = std::string_view(reinterpret_cast<const char *>(bytes), sizeof(bytes));
|
||||
return crypto::get_hash(offset, buf) == hash;
|
||||
}
|
||||
|
||||
@@ -514,10 +525,11 @@ namespace hpfs
|
||||
/**
|
||||
* Process dir children response.
|
||||
* @param vpath Virtual path of the fs.
|
||||
* @param dir_mode Metadata 'mode' of dir.
|
||||
* @param fs_entry_map Received fs entry map.
|
||||
* @returns 0 on success, otherwise -1.
|
||||
*/
|
||||
int hpfs_sync::handle_fs_entry_response(std::string_view vpath, std::unordered_map<std::string, p2p::hpfs_fs_hash_entry> &fs_entry_map)
|
||||
int hpfs_sync::handle_fs_entry_response(std::string_view vpath, const mode_t dir_mode, std::unordered_map<std::string, p2p::hpfs_fs_hash_entry> &fs_entry_map)
|
||||
{
|
||||
// Get the parent path of the fs entries we have received.
|
||||
LOG_DEBUG << "Hpfs " << name << " sync: Processing fs entries response for " << vpath;
|
||||
@@ -527,6 +539,10 @@ namespace hpfs
|
||||
if (util::create_dir_tree_recursive(parent_physical_path) == -1)
|
||||
return -1;
|
||||
|
||||
// Apply physical dir mode if received mode is different from our side.
|
||||
if (apply_metadata_mode(parent_physical_path, dir_mode, true) == -1)
|
||||
return -1;
|
||||
|
||||
// Get the children hash entries and compare with what we got from peer.
|
||||
std::vector<hpfs::child_hash_node> existing_fs_entries;
|
||||
if (fs_mount->get_dir_children_hashes(existing_fs_entries, hpfs::RW_SESSION_NAME, vpath) == -1)
|
||||
@@ -589,12 +605,13 @@ namespace hpfs
|
||||
/**
|
||||
* Process file block hash map response.
|
||||
* @param vpath Virtual path of the file.
|
||||
* @param hash Received hash.
|
||||
* @param file_mode Received metadata mode of the file.
|
||||
* @param hashes Received block hashes.
|
||||
* @param hash_count No. of received block hashes.
|
||||
* @param file_length Size of the file.
|
||||
* @returns 0 on success, otherwise -1.
|
||||
*/
|
||||
int hpfs_sync::handle_file_hashmap_response(std::string_view vpath, const util::h32 *hashes, const size_t hash_count, const uint64_t file_length)
|
||||
int hpfs_sync::handle_file_hashmap_response(std::string_view vpath, const mode_t file_mode, const util::h32 *hashes, const size_t hash_count, const uint64_t file_length)
|
||||
{
|
||||
// Get the file path of the block hashes we have received.
|
||||
LOG_DEBUG << "Hpfs " << name << " sync: Processing file block hashes response for " << vpath;
|
||||
@@ -623,6 +640,11 @@ namespace hpfs
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Apply physical file mode if received mode is different from our side.
|
||||
const std::string physical_path = fs_mount->rw_dir + vpath.data();
|
||||
if (apply_metadata_mode(physical_path, file_mode, false) == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -659,6 +681,49 @@ namespace hpfs
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the specified to local file/dir if different. If it's a file, this will create the file
|
||||
* if not exist.
|
||||
* @returns 0 on success, otherwise -1.
|
||||
*/
|
||||
int hpfs_sync::apply_metadata_mode(std::string_view physical_path, const mode_t mode, const bool is_dir)
|
||||
{
|
||||
// Overlay the file/dir type flags to the permission bits.
|
||||
const mode_t full_mode = (is_dir ? S_IFDIR : S_IFREG) | mode;
|
||||
|
||||
struct stat st;
|
||||
if (stat(physical_path.data(), &st) == -1)
|
||||
{
|
||||
if (!is_dir && errno == ENOENT) // File does not exist. So we must create it with the given 'mode'.
|
||||
{
|
||||
if (mknod(physical_path.data(), full_mode, 0) == -1)
|
||||
{
|
||||
LOG_ERROR << errno << ": Error in creating file node. " << physical_path;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_ERROR << errno << "," << ENOENT << ": Error in stat when applying file/dir mode. " << physical_path;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Reaching here means file/dir already exists. So we must apply the specified mode if it's different from current value.
|
||||
if (st.st_mode != full_mode)
|
||||
{
|
||||
if (chmod(physical_path.data(), mode) == -1)
|
||||
{
|
||||
LOG_ERROR << errno << ": Error in applying file/dir mode. " << physical_path;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method can be used to invoke mount specific custom logic (after overriding this method) to be executed after
|
||||
* a sync target is acheived.
|
||||
|
||||
@@ -70,6 +70,29 @@ namespace hpfs
|
||||
|
||||
int start_syncing_next_target();
|
||||
|
||||
bool validate_fs_entry_hash(std::string_view vpath, std::string_view hash, const mode_t dir_mode,
|
||||
const std::unordered_map<std::string, p2p::hpfs_fs_hash_entry> &fs_entry_map);
|
||||
|
||||
bool validate_file_hashmap_hash(std::string_view vpath, std::string_view hash, const mode_t file_mode,
|
||||
const util::h32 *hashes, const size_t hash_count);
|
||||
|
||||
bool validate_file_block_hash(std::string_view hash, const uint32_t block_id, std::string_view buf);
|
||||
|
||||
bool should_stop_request_loop(const util::h32 ¤t_target_hash);
|
||||
|
||||
void request_state_from_peer(const std::string &path, const bool is_file, const int32_t block_id,
|
||||
const util::h32 expected_hash, std::string &target_pubkey);
|
||||
|
||||
void submit_request(const backlog_item &request);
|
||||
|
||||
int handle_fs_entry_response(std::string_view vpath, const mode_t dir_mode, std::unordered_map<std::string, p2p::hpfs_fs_hash_entry> &fs_entry_map);
|
||||
|
||||
int handle_file_hashmap_response(std::string_view vpath, const mode_t file_mode, const util::h32 *hashes, const size_t hash_count, const uint64_t file_length);
|
||||
|
||||
int handle_file_block_response(std::string_view vpath, const uint32_t block_id, std::string_view buf);
|
||||
|
||||
int apply_metadata_mode(std::string_view physical_path, const mode_t mode, const bool is_dir);
|
||||
|
||||
protected:
|
||||
// List of sender pubkeys and hpfs responses(flatbuffer messages) to be processed.
|
||||
std::list<std::pair<std::string, std::string>> candidate_hpfs_responses;
|
||||
@@ -95,27 +118,8 @@ namespace hpfs
|
||||
void set_target(const std::list<sync_target> &sync_target_list);
|
||||
|
||||
void set_target_push_front(const sync_target &target);
|
||||
|
||||
|
||||
void set_target_push_back(const sync_target &target);
|
||||
|
||||
bool validate_fs_entry_hash(std::string_view vpath, std::string_view hash, const std::unordered_map<std::string, p2p::hpfs_fs_hash_entry> &fs_entry_map);
|
||||
|
||||
bool validate_file_hashmap_hash(std::string_view vpath, std::string_view hash, const util::h32 *hashes, const size_t hash_count);
|
||||
|
||||
bool validate_file_block_hash(std::string_view hash, const uint32_t block_id, std::string_view buf);
|
||||
|
||||
bool should_stop_request_loop(const util::h32 ¤t_target_hash);
|
||||
|
||||
void request_state_from_peer(const std::string &path, const bool is_file, const int32_t block_id,
|
||||
const util::h32 expected_hash, std::string &target_pubkey);
|
||||
|
||||
void submit_request(const backlog_item &request);
|
||||
|
||||
int handle_fs_entry_response(std::string_view vpath, std::unordered_map<std::string, p2p::hpfs_fs_hash_entry> &fs_entry_map);
|
||||
|
||||
int handle_file_hashmap_response(std::string_view vpath, const util::h32 *hashes, const size_t hash_count, const uint64_t file_length);
|
||||
|
||||
int handle_file_block_response(std::string_view vpath, const uint32_t block_id, std::string_view buf);
|
||||
};
|
||||
|
||||
} // namespace hpfs
|
||||
|
||||
@@ -100,11 +100,13 @@ table HpfsResponseMsg{
|
||||
}
|
||||
|
||||
table HpfsFsEntryResponse{
|
||||
dir_mode:uint32;
|
||||
entries: [HpfsFSHashEntry];
|
||||
}
|
||||
|
||||
table HpfsFileHashMapResponse{
|
||||
file_length:uint64;
|
||||
file_mode:uint32;
|
||||
hash_map:[ubyte];
|
||||
}
|
||||
|
||||
|
||||
@@ -380,11 +380,12 @@ namespace msg::fbuf::p2pmsg
|
||||
}
|
||||
|
||||
void create_msg_from_fsentry_response(
|
||||
flatbuffers::FlatBufferBuilder &builder, const std::string_view path, const uint32_t mount_id,
|
||||
std::vector<hpfs::child_hash_node> &hash_nodes, util::h32 expected_hash)
|
||||
flatbuffers::FlatBufferBuilder &builder, const std::string_view path, const uint32_t mount_id, const mode_t dir_mode,
|
||||
std::vector<hpfs::child_hash_node> &hash_nodes, const util::h32 &expected_hash)
|
||||
{
|
||||
const auto child_msg = CreateHpfsFsEntryResponse(
|
||||
builder,
|
||||
dir_mode,
|
||||
hpfsfshashentry_to_flatbuf_hpfsfshashentry(builder, hash_nodes));
|
||||
|
||||
const auto msg = CreateHpfsResponseMsg(
|
||||
@@ -400,13 +401,14 @@ namespace msg::fbuf::p2pmsg
|
||||
|
||||
void create_msg_from_filehashmap_response(
|
||||
flatbuffers::FlatBufferBuilder &builder, std::string_view path, const uint32_t mount_id,
|
||||
std::vector<util::h32> &hashmap, std::size_t file_length, util::h32 expected_hash)
|
||||
std::vector<util::h32> &hashmap, const std::size_t file_length, const mode_t file_mode, const util::h32 &expected_hash)
|
||||
{
|
||||
std::string_view hashmap_sv(reinterpret_cast<const char *>(hashmap.data()), hashmap.size() * sizeof(util::h32));
|
||||
|
||||
const auto child_msg = CreateHpfsFileHashMapResponse(
|
||||
builder,
|
||||
file_length,
|
||||
file_mode,
|
||||
sv_to_flatbuf_bytes(builder, hashmap_sv));
|
||||
|
||||
const auto msg = CreateHpfsResponseMsg(
|
||||
|
||||
@@ -70,12 +70,12 @@ namespace msg::fbuf::p2pmsg
|
||||
void create_msg_from_hpfs_request(flatbuffers::FlatBufferBuilder &builder, const p2p::hpfs_request &hr);
|
||||
|
||||
void create_msg_from_fsentry_response(
|
||||
flatbuffers::FlatBufferBuilder &builder, const std::string_view path, const uint32_t mount_id,
|
||||
std::vector<hpfs::child_hash_node> &hash_nodes, util::h32 expected_hash);
|
||||
flatbuffers::FlatBufferBuilder &builder, const std::string_view path, const uint32_t mount_id, const mode_t dir_mode,
|
||||
std::vector<hpfs::child_hash_node> &hash_nodes, const util::h32 &expected_hash);
|
||||
|
||||
void create_msg_from_filehashmap_response(
|
||||
flatbuffers::FlatBufferBuilder &builder, std::string_view path, const uint32_t mount_id,
|
||||
std::vector<util::h32> &hashmap, std::size_t file_length, util::h32 expected_hash);
|
||||
std::vector<util::h32> &hashmap, const std::size_t file_length, const mode_t file_mode, const util::h32 &expected_hash);
|
||||
|
||||
void create_msg_from_block_response(flatbuffers::FlatBufferBuilder &builder, p2p::block_response &block_resp, const uint32_t mount_id);
|
||||
|
||||
|
||||
@@ -1439,8 +1439,15 @@ inline flatbuffers::Offset<HpfsResponseMsg> CreateHpfsResponseMsgDirect(
|
||||
struct HpfsFsEntryResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
typedef HpfsFsEntryResponseBuilder Builder;
|
||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||
VT_ENTRIES = 4
|
||||
VT_DIR_MODE = 4,
|
||||
VT_ENTRIES = 6
|
||||
};
|
||||
uint32_t dir_mode() const {
|
||||
return GetField<uint32_t>(VT_DIR_MODE, 0);
|
||||
}
|
||||
bool mutate_dir_mode(uint32_t _dir_mode) {
|
||||
return SetField<uint32_t>(VT_DIR_MODE, _dir_mode, 0);
|
||||
}
|
||||
const flatbuffers::Vector<flatbuffers::Offset<msg::fbuf::p2pmsg::HpfsFSHashEntry>> *entries() const {
|
||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<msg::fbuf::p2pmsg::HpfsFSHashEntry>> *>(VT_ENTRIES);
|
||||
}
|
||||
@@ -1449,6 +1456,7 @@ struct HpfsFsEntryResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<uint32_t>(verifier, VT_DIR_MODE) &&
|
||||
VerifyOffset(verifier, VT_ENTRIES) &&
|
||||
verifier.VerifyVector(entries()) &&
|
||||
verifier.VerifyVectorOfTables(entries()) &&
|
||||
@@ -1460,6 +1468,9 @@ struct HpfsFsEntryResponseBuilder {
|
||||
typedef HpfsFsEntryResponse Table;
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_dir_mode(uint32_t dir_mode) {
|
||||
fbb_.AddElement<uint32_t>(HpfsFsEntryResponse::VT_DIR_MODE, dir_mode, 0);
|
||||
}
|
||||
void add_entries(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<msg::fbuf::p2pmsg::HpfsFSHashEntry>>> entries) {
|
||||
fbb_.AddOffset(HpfsFsEntryResponse::VT_ENTRIES, entries);
|
||||
}
|
||||
@@ -1477,18 +1488,22 @@ struct HpfsFsEntryResponseBuilder {
|
||||
|
||||
inline flatbuffers::Offset<HpfsFsEntryResponse> CreateHpfsFsEntryResponse(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
uint32_t dir_mode = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<msg::fbuf::p2pmsg::HpfsFSHashEntry>>> entries = 0) {
|
||||
HpfsFsEntryResponseBuilder builder_(_fbb);
|
||||
builder_.add_entries(entries);
|
||||
builder_.add_dir_mode(dir_mode);
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<HpfsFsEntryResponse> CreateHpfsFsEntryResponseDirect(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
uint32_t dir_mode = 0,
|
||||
const std::vector<flatbuffers::Offset<msg::fbuf::p2pmsg::HpfsFSHashEntry>> *entries = nullptr) {
|
||||
auto entries__ = entries ? _fbb.CreateVector<flatbuffers::Offset<msg::fbuf::p2pmsg::HpfsFSHashEntry>>(*entries) : 0;
|
||||
return msg::fbuf::p2pmsg::CreateHpfsFsEntryResponse(
|
||||
_fbb,
|
||||
dir_mode,
|
||||
entries__);
|
||||
}
|
||||
|
||||
@@ -1496,7 +1511,8 @@ struct HpfsFileHashMapResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Ta
|
||||
typedef HpfsFileHashMapResponseBuilder Builder;
|
||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||
VT_FILE_LENGTH = 4,
|
||||
VT_HASH_MAP = 6
|
||||
VT_FILE_MODE = 6,
|
||||
VT_HASH_MAP = 8
|
||||
};
|
||||
uint64_t file_length() const {
|
||||
return GetField<uint64_t>(VT_FILE_LENGTH, 0);
|
||||
@@ -1504,6 +1520,12 @@ struct HpfsFileHashMapResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Ta
|
||||
bool mutate_file_length(uint64_t _file_length) {
|
||||
return SetField<uint64_t>(VT_FILE_LENGTH, _file_length, 0);
|
||||
}
|
||||
uint32_t file_mode() const {
|
||||
return GetField<uint32_t>(VT_FILE_MODE, 0);
|
||||
}
|
||||
bool mutate_file_mode(uint32_t _file_mode) {
|
||||
return SetField<uint32_t>(VT_FILE_MODE, _file_mode, 0);
|
||||
}
|
||||
const flatbuffers::Vector<uint8_t> *hash_map() const {
|
||||
return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_HASH_MAP);
|
||||
}
|
||||
@@ -1513,6 +1535,7 @@ struct HpfsFileHashMapResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Ta
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<uint64_t>(verifier, VT_FILE_LENGTH) &&
|
||||
VerifyField<uint32_t>(verifier, VT_FILE_MODE) &&
|
||||
VerifyOffset(verifier, VT_HASH_MAP) &&
|
||||
verifier.VerifyVector(hash_map()) &&
|
||||
verifier.EndTable();
|
||||
@@ -1526,6 +1549,9 @@ struct HpfsFileHashMapResponseBuilder {
|
||||
void add_file_length(uint64_t file_length) {
|
||||
fbb_.AddElement<uint64_t>(HpfsFileHashMapResponse::VT_FILE_LENGTH, file_length, 0);
|
||||
}
|
||||
void add_file_mode(uint32_t file_mode) {
|
||||
fbb_.AddElement<uint32_t>(HpfsFileHashMapResponse::VT_FILE_MODE, file_mode, 0);
|
||||
}
|
||||
void add_hash_map(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> hash_map) {
|
||||
fbb_.AddOffset(HpfsFileHashMapResponse::VT_HASH_MAP, hash_map);
|
||||
}
|
||||
@@ -1544,21 +1570,25 @@ struct HpfsFileHashMapResponseBuilder {
|
||||
inline flatbuffers::Offset<HpfsFileHashMapResponse> CreateHpfsFileHashMapResponse(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
uint64_t file_length = 0,
|
||||
uint32_t file_mode = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> hash_map = 0) {
|
||||
HpfsFileHashMapResponseBuilder builder_(_fbb);
|
||||
builder_.add_file_length(file_length);
|
||||
builder_.add_hash_map(hash_map);
|
||||
builder_.add_file_mode(file_mode);
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<HpfsFileHashMapResponse> CreateHpfsFileHashMapResponseDirect(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
uint64_t file_length = 0,
|
||||
uint32_t file_mode = 0,
|
||||
const std::vector<uint8_t> *hash_map = nullptr) {
|
||||
auto hash_map__ = hash_map ? _fbb.CreateVector<uint8_t>(*hash_map) : 0;
|
||||
return msg::fbuf::p2pmsg::CreateHpfsFileHashMapResponse(
|
||||
_fbb,
|
||||
file_length,
|
||||
file_mode,
|
||||
hash_map__);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,16 @@ namespace util
|
||||
return *this;
|
||||
}
|
||||
|
||||
void h32::operator^=(std::string_view sv)
|
||||
{
|
||||
const uint64_t *rhs = (uint64_t *)sv.data();
|
||||
|
||||
this->data[0] ^= rhs[0];
|
||||
this->data[1] ^= rhs[1];
|
||||
this->data[2] ^= rhs[2];
|
||||
this->data[3] ^= rhs[3];
|
||||
}
|
||||
|
||||
// Comparison operator for std::map key support.
|
||||
bool h32::operator<(const h32 rhs) const
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace util
|
||||
void operator^=(const h32 rhs);
|
||||
std::string_view to_string_view() const;
|
||||
h32 &operator=(std::string_view sv);
|
||||
void operator^=(std::string_view sv);
|
||||
bool operator<(const h32 rhs) const;
|
||||
|
||||
h32()
|
||||
|
||||
Reference in New Issue
Block a user