From 0c267b0873b6842cfa68229d5d11be6efe84be5f Mon Sep 17 00:00:00 2001 From: Udith Indrakantha <45740208+Udith-Gayan@users.noreply.github.com> Date: Fri, 15 Jul 2022 16:42:29 +0530 Subject: [PATCH] Changing Buffer Sizes for JSON List Command (#159) --- sashi-cli/cli-manager.cpp | 31 +++++++++++++++++++++++++------ sashi-cli/cli-manager.hpp | 2 ++ src/comm/comm_handler.cpp | 37 +++++++++++++++++++++++++++++++------ src/comm/comm_handler.hpp | 2 ++ src/msg/json/msg_json.cpp | 10 +++++++--- 5 files changed, 67 insertions(+), 15 deletions(-) diff --git a/sashi-cli/cli-manager.cpp b/sashi-cli/cli-manager.cpp index 75f20c0..b4c1e2c 100644 --- a/sashi-cli/cli-manager.cpp +++ b/sashi-cli/cli-manager.cpp @@ -162,19 +162,38 @@ namespace cli return -1; } - // Resize the message to max length and resize to original read length after reading. - message.resize(BUFFER_SIZE); - const int res = read(ctx.socket_fd, message.data(), message.length()); + // Read the length of the message to a buffer + uint8_t length_buffer[8]; + int res = read(ctx.socket_fd, length_buffer, 8); if (res == -1) { - std::cerr << errno << " :Error while reading from the sashimono socket.\n"; + std::cerr << errno << " :Error while reading message length from the sashimono socket.\n"; + return -1; + } + + const uint32_t message_length = uint32_from_bytes(length_buffer); + + // Resize the message buffer to fit to the message length + message.resize(message_length); + res = read(ctx.socket_fd, message.data(), message_length); + if (res == -1) + { + std::cerr << errno << " :Error while reading the message from the sashimono socket.\n"; return -1; } - message.resize(res); return res; } + // Convert byte buffer to uint32_t + uint32_t uint32_from_bytes(const uint8_t *data) + { + return ((uint32_t)data[0] << 24) + + ((uint32_t)data[1] << 16) + + ((uint32_t)data[2] << 8) + + ((uint32_t)data[3]); + } + int get_json_output(std::string_view json_msg, std::string &output) { if (write_to_socket(json_msg) == -1 || read_from_socket(output) == -1) @@ -229,7 +248,7 @@ namespace cli return -1; } - jsoncons::json content = jsoncons::json::parse(d["content"].as(), jsoncons::strict_json_parsing()); + jsoncons::json content = d["content"]; std::cout << jsoncons::pretty_print(content) << std::endl; } catch (const std::exception &e) diff --git a/sashi-cli/cli-manager.hpp b/sashi-cli/cli-manager.hpp index fd3fbf9..850117f 100644 --- a/sashi-cli/cli-manager.hpp +++ b/sashi-cli/cli-manager.hpp @@ -38,6 +38,8 @@ namespace cli const std::string value_to_string(const jsoncons::json &val); void deinit(); + + uint32_t uint32_from_bytes(const uint8_t *data); } #endif diff --git a/src/comm/comm_handler.cpp b/src/comm/comm_handler.cpp index c7e52ba..6da96f7 100644 --- a/src/comm/comm_handler.cpp +++ b/src/comm/comm_handler.cpp @@ -91,7 +91,7 @@ namespace comm * This accepts connections to the socket. * This only gets called whithin the comm handler thread. * @return 0 on success -1 on error. - */ + */ int connect() { ctx.data_socket = accept(ctx.connection_socket, NULL, NULL); @@ -106,7 +106,7 @@ namespace comm /** * Disconnect the session. * This only gets called whithin the comm handler thread. - */ + */ void disconnect() { close(ctx.data_socket); @@ -178,7 +178,7 @@ namespace comm * Handles the received message. * @param message_size Message size. * @return 0 on success -1 on error. - */ + */ int handle_message(const int message_size) { std::string_view msg((char *)read_buffer.data(), message_size); @@ -283,7 +283,7 @@ namespace comm } else __HANDLE_RESPONSE("error", TYPE_ERROR, -1); - + return 0; } @@ -297,10 +297,35 @@ namespace comm if (ctx.data_socket == -1) return -1; - const int ret = write(ctx.data_socket, message.data(), message.length()); + uint8_t length_buffer[8]; + // Convert message length to a byte array + uint32_to_bytes(length_buffer, message.length()); + + int res = write(ctx.data_socket, length_buffer, 8); + if (res == -1) { + disconnect(); + return -1; + } + + res = write(ctx.data_socket, message.data(), message.length()); // Close connection after sending the response to the client. disconnect(); - return ret == -1 ? -1 : 0; + + return res == -1 ? -1 : 0; + } + + + /** + * Convert the given uint32_t number to bytes in big endian format. + * @param dest Byte array pointer. + * @param x Number to be converted. + */ + void uint32_to_bytes(uint8_t *dest, const uint32_t x) + { + dest[0] = (uint8_t)((x >> 24) & 0xff); + dest[1] = (uint8_t)((x >> 16) & 0xff); + dest[2] = (uint8_t)((x >> 8) & 0xff); + dest[3] = (uint8_t)((x >> 0) & 0xff); } /** diff --git a/src/comm/comm_handler.hpp b/src/comm/comm_handler.hpp index 0662964..7e0a806 100644 --- a/src/comm/comm_handler.hpp +++ b/src/comm/comm_handler.hpp @@ -34,6 +34,8 @@ namespace comm int read_socket(); + void uint32_to_bytes(uint8_t *dest, const uint32_t x); + } // namespace comm #endif diff --git a/src/msg/json/msg_json.cpp b/src/msg/json/msg_json.cpp index 75482c1..68a0bea 100644 --- a/src/msg/json/msg_json.cpp +++ b/src/msg/json/msg_json.cpp @@ -11,6 +11,7 @@ namespace msg::json constexpr const char *DOUBLE_QUOTE = "\""; constexpr uint16_t MOMENT_SIZE = 900; // XRP ledgers per Moment. constexpr uint16_t LEDGER_TIME_APPROX = 4000; // Approx. milliseconds per XRP ledger. + constexpr uint16_t INSTANCE_INFO_SIZE = 488; // Size of a single instance info /** * Parses a json message sent by the message board. * @param d Jsoncons document to which the parsed json should be loaded. @@ -576,7 +577,8 @@ namespace msg::json */ void build_response(std::string &msg, std::string_view response_type, std::string_view content, const bool json_content) { - msg.reserve(1024); + // Extra 40 bytes added for the other data included, in addition to the content here + msg.reserve(content.length() + 40); msg += "{\""; msg += msg::FLD_TYPE; msg += SEP_COLON; @@ -663,7 +665,9 @@ namespace msg::json */ void build_list_response(std::string &msg, const std::vector &instances, const std::vector &leases) { - msg.reserve(1024); + const uint32_t message_size = (INSTANCE_INFO_SIZE * instances.size()) + 3; + msg.reserve(message_size); + msg += "["; for (size_t i = 0; i < instances.size(); i++) { @@ -775,4 +779,4 @@ namespace msg::json msg += std::to_string(instance.assigned_ports.user_port); msg += "}"; } -} // namespace msg::json \ No newline at end of file +} // namespace msg::json