diff --git a/src/conf.hpp b/src/conf.hpp index 6e460160..3c945a1d 100644 --- a/src/conf.hpp +++ b/src/conf.hpp @@ -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. diff --git a/src/crypto.cpp b/src/crypto.cpp index a7768891..165db650 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -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); diff --git a/src/crypto.hpp b/src/crypto.hpp index 5eead63c..963183d5 100644 --- a/src/crypto.hpp +++ b/src/crypto.hpp @@ -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); diff --git a/src/hpfs/hpfs_serve.cpp b/src/hpfs/hpfs_serve.cpp index 521fd5e0..37448c30 100644 --- a/src/hpfs/hpfs_serve.cpp +++ b/src/hpfs/hpfs_serve.cpp @@ -161,8 +161,9 @@ namespace hpfs if (hr.is_file) { std::vector 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 &hashes, size_t &file_length, + int hpfs_serve::get_data_block_hashes(std::vector &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. } } diff --git a/src/hpfs/hpfs_serve.hpp b/src/hpfs/hpfs_serve.hpp index ddb3dc81..9e35c3b9 100644 --- a/src/hpfs/hpfs_serve.hpp +++ b/src/hpfs/hpfs_serve.hpp @@ -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 &block, const std::string_view vpath, + const uint32_t block_id, const util::h32 expected_hash); + int get_data_block_hashes(std::vector &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 &hash_nodes, + const std::string_view vpath, const util::h32 expected_hash); protected: std::list> 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 &block, const std::string_view vpath, - const uint32_t block_id, const util::h32 expected_hash); - - int get_data_block_hashes(std::vector &hashes, size_t &file_length, - const std::string_view vpath, const util::h32 expected_hash); - - int get_fs_entry_hashes(std::vector &hash_nodes, - const std::string_view vpath, const util::h32 expected_hash); }; } // namespace hpfs diff --git a/src/hpfs/hpfs_sync.cpp b/src/hpfs/hpfs_sync.cpp index 64185938..58f9e29e 100644 --- a/src/hpfs/hpfs_sync.cpp +++ b/src/hpfs/hpfs_sync.cpp @@ -266,33 +266,31 @@ namespace hpfs std::unordered_map 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(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(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 &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 &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(&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(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 &fs_entry_map) + int hpfs_sync::handle_fs_entry_response(std::string_view vpath, const mode_t dir_mode, std::unordered_map &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 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. diff --git a/src/hpfs/hpfs_sync.hpp b/src/hpfs/hpfs_sync.hpp index ab7ad72b..97dded0a 100644 --- a/src/hpfs/hpfs_sync.hpp +++ b/src/hpfs/hpfs_sync.hpp @@ -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 &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 &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> candidate_hpfs_responses; @@ -95,27 +118,8 @@ namespace hpfs void set_target(const std::list &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 &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 &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 diff --git a/src/msg/fbuf/p2pmsg.fbs b/src/msg/fbuf/p2pmsg.fbs index ded99ad3..ca40e5e8 100644 --- a/src/msg/fbuf/p2pmsg.fbs +++ b/src/msg/fbuf/p2pmsg.fbs @@ -100,11 +100,13 @@ table HpfsResponseMsg{ } table HpfsFsEntryResponse{ + dir_mode:uint32; entries: [HpfsFSHashEntry]; } table HpfsFileHashMapResponse{ file_length:uint64; + file_mode:uint32; hash_map:[ubyte]; } diff --git a/src/msg/fbuf/p2pmsg_conversion.cpp b/src/msg/fbuf/p2pmsg_conversion.cpp index 0a30c07d..5ff823a9 100644 --- a/src/msg/fbuf/p2pmsg_conversion.cpp +++ b/src/msg/fbuf/p2pmsg_conversion.cpp @@ -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 &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 &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 &hashmap, std::size_t file_length, util::h32 expected_hash) + std::vector &hashmap, const std::size_t file_length, const mode_t file_mode, const util::h32 &expected_hash) { std::string_view hashmap_sv(reinterpret_cast(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( diff --git a/src/msg/fbuf/p2pmsg_conversion.hpp b/src/msg/fbuf/p2pmsg_conversion.hpp index 900a201a..ac6d69bb 100644 --- a/src/msg/fbuf/p2pmsg_conversion.hpp +++ b/src/msg/fbuf/p2pmsg_conversion.hpp @@ -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 &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 &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 &hashmap, std::size_t file_length, util::h32 expected_hash); + std::vector &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); diff --git a/src/msg/fbuf/p2pmsg_generated.h b/src/msg/fbuf/p2pmsg_generated.h index b59b9cc6..7227342a 100644 --- a/src/msg/fbuf/p2pmsg_generated.h +++ b/src/msg/fbuf/p2pmsg_generated.h @@ -1439,8 +1439,15 @@ inline flatbuffers::Offset 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(VT_DIR_MODE, 0); + } + bool mutate_dir_mode(uint32_t _dir_mode) { + return SetField(VT_DIR_MODE, _dir_mode, 0); + } const flatbuffers::Vector> *entries() const { return GetPointer> *>(VT_ENTRIES); } @@ -1449,6 +1456,7 @@ struct HpfsFsEntryResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && + VerifyField(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(HpfsFsEntryResponse::VT_DIR_MODE, dir_mode, 0); + } void add_entries(flatbuffers::Offset>> entries) { fbb_.AddOffset(HpfsFsEntryResponse::VT_ENTRIES, entries); } @@ -1477,18 +1488,22 @@ struct HpfsFsEntryResponseBuilder { inline flatbuffers::Offset CreateHpfsFsEntryResponse( flatbuffers::FlatBufferBuilder &_fbb, + uint32_t dir_mode = 0, flatbuffers::Offset>> entries = 0) { HpfsFsEntryResponseBuilder builder_(_fbb); builder_.add_entries(entries); + builder_.add_dir_mode(dir_mode); return builder_.Finish(); } inline flatbuffers::Offset CreateHpfsFsEntryResponseDirect( flatbuffers::FlatBufferBuilder &_fbb, + uint32_t dir_mode = 0, const std::vector> *entries = nullptr) { auto entries__ = entries ? _fbb.CreateVector>(*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(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(VT_FILE_LENGTH, _file_length, 0); } + uint32_t file_mode() const { + return GetField(VT_FILE_MODE, 0); + } + bool mutate_file_mode(uint32_t _file_mode) { + return SetField(VT_FILE_MODE, _file_mode, 0); + } const flatbuffers::Vector *hash_map() const { return GetPointer *>(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(verifier, VT_FILE_LENGTH) && + VerifyField(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(HpfsFileHashMapResponse::VT_FILE_LENGTH, file_length, 0); } + void add_file_mode(uint32_t file_mode) { + fbb_.AddElement(HpfsFileHashMapResponse::VT_FILE_MODE, file_mode, 0); + } void add_hash_map(flatbuffers::Offset> hash_map) { fbb_.AddOffset(HpfsFileHashMapResponse::VT_HASH_MAP, hash_map); } @@ -1544,21 +1570,25 @@ struct HpfsFileHashMapResponseBuilder { inline flatbuffers::Offset CreateHpfsFileHashMapResponse( flatbuffers::FlatBufferBuilder &_fbb, uint64_t file_length = 0, + uint32_t file_mode = 0, flatbuffers::Offset> 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 CreateHpfsFileHashMapResponseDirect( flatbuffers::FlatBufferBuilder &_fbb, uint64_t file_length = 0, + uint32_t file_mode = 0, const std::vector *hash_map = nullptr) { auto hash_map__ = hash_map ? _fbb.CreateVector(*hash_map) : 0; return msg::fbuf::p2pmsg::CreateHpfsFileHashMapResponse( _fbb, file_length, + file_mode, hash_map__); } diff --git a/src/util/h32.cpp b/src/util/h32.cpp index 6be61886..d5be4a0f 100644 --- a/src/util/h32.cpp +++ b/src/util/h32.cpp @@ -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 { diff --git a/src/util/h32.hpp b/src/util/h32.hpp index 3409b08d..deab6ac0 100644 --- a/src/util/h32.hpp +++ b/src/util/h32.hpp @@ -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()