packet comm refactor and fixes
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
#include "utils/common.hpp"
|
#include "utils/common.hpp"
|
||||||
|
|
||||||
namespace repertory::comm {
|
namespace repertory::comm {
|
||||||
|
inline static constexpr std::uint32_t max_packet_bytes{32U * 1024U * 1024U};
|
||||||
inline constexpr const std::uint8_t max_read_attempts{5U};
|
inline constexpr const std::uint8_t max_read_attempts{5U};
|
||||||
inline constexpr const std::uint16_t packet_nonce_size{256U};
|
inline constexpr const std::uint16_t packet_nonce_size{256U};
|
||||||
inline constexpr const std::uint16_t server_handshake_timeout_ms{3000U};
|
inline constexpr const std::uint16_t server_handshake_timeout_ms{3000U};
|
||||||
|
|||||||
@@ -1,17 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to do so, subject to the
|
||||||
furnished to do so, subject to the following conditions:
|
following conditions: The above copyright notice and this permission notice
|
||||||
|
shall be included in all copies or substantial portions of the Software. THE
|
||||||
The above copyright notice and this permission notice shall be included in all
|
SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
@@ -24,6 +20,7 @@
|
|||||||
|
|
||||||
#include "comm/packet/packet.hpp"
|
#include "comm/packet/packet.hpp"
|
||||||
#include "types/remote.hpp"
|
#include "types/remote.hpp"
|
||||||
|
#include "utils/atomic.hpp"
|
||||||
|
|
||||||
using boost::asio::ip::tcp;
|
using boost::asio::ip::tcp;
|
||||||
|
|
||||||
@@ -47,24 +44,26 @@ public:
|
|||||||
auto operator=(packet_client &&) -> packet_client & = delete;
|
auto operator=(packet_client &&) -> packet_client & = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable boost::asio::io_context io_context_;
|
|
||||||
remote::remote_config cfg_;
|
remote::remote_config cfg_;
|
||||||
std::string unique_id_;
|
mutable boost::asio::io_context io_context_;
|
||||||
|
atomic<std::string> unique_id_;
|
||||||
|
boost::asio::executor_work_guard<boost::asio::io_context::executor_type>
|
||||||
|
work_guard_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool allow_connections_{true};
|
std::atomic<bool> allow_connections_{true};
|
||||||
boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::results_type
|
atomic<boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::results_type>
|
||||||
resolve_results_;
|
resolve_results_;
|
||||||
std::mutex clients_mutex_;
|
std::mutex clients_mutex_;
|
||||||
std::vector<std::shared_ptr<client>> clients_;
|
std::vector<std::shared_ptr<client>> clients_;
|
||||||
std::vector<std::thread> service_threads_;
|
std::vector<std::thread> service_threads_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void close(client &cli);
|
static void close(client &cli) noexcept;
|
||||||
|
|
||||||
void close_all();
|
void close_all();
|
||||||
|
|
||||||
void connect(client &cli);
|
[[nodiscard]] auto connect(client &cli) -> bool;
|
||||||
|
|
||||||
[[nodiscard]] auto get_client() -> std::shared_ptr<client>;
|
[[nodiscard]] auto get_client() -> std::shared_ptr<client>;
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to do so, subject to the
|
||||||
furnished to do so, subject to the following conditions:
|
following conditions: The above copyright notice and this permission notice
|
||||||
|
shall be included in all copies or substantial portions of the Software. THE
|
||||||
The above copyright notice and this permission notice shall be included in all
|
SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
@@ -26,45 +22,49 @@
|
|||||||
#include "types/repertory.hpp"
|
#include "types/repertory.hpp"
|
||||||
#include "utils/collection.hpp"
|
#include "utils/collection.hpp"
|
||||||
#include "utils/common.hpp"
|
#include "utils/common.hpp"
|
||||||
|
#include "utils/config.hpp"
|
||||||
#include "utils/error_utils.hpp"
|
#include "utils/error_utils.hpp"
|
||||||
#include "utils/utils.hpp"
|
#include "utils/utils.hpp"
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
#include <utils/config.hpp>
|
|
||||||
|
|
||||||
using namespace repertory::comm;
|
using namespace repertory::comm;
|
||||||
|
|
||||||
namespace repertory {
|
namespace repertory {
|
||||||
packet_client::packet_client(remote::remote_config cfg)
|
packet_client::packet_client(remote::remote_config cfg)
|
||||||
: cfg_(std::move(cfg)), unique_id_(utils::create_uuid_string()) {
|
: cfg_(std::move(cfg)),
|
||||||
|
io_context_(),
|
||||||
|
unique_id_(utils::create_uuid_string()),
|
||||||
|
work_guard_(boost::asio::make_work_guard(io_context_)) {
|
||||||
for (std::uint8_t idx = 0U; idx < cfg.max_connections; ++idx) {
|
for (std::uint8_t idx = 0U; idx < cfg.max_connections; ++idx) {
|
||||||
service_threads_.emplace_back([this]() { io_context_.run(); });
|
service_threads_.emplace_back([this]() { io_context_.run(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
packet_client::~packet_client() {
|
packet_client::~packet_client() {
|
||||||
allow_connections_ = false;
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
close_all();
|
|
||||||
|
|
||||||
for (std::size_t idx = 0U; idx < service_threads_.size(); ++idx) {
|
allow_connections_ = false;
|
||||||
io_context_.stop();
|
|
||||||
|
try {
|
||||||
|
close_all();
|
||||||
|
} catch (...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
work_guard_.reset();
|
||||||
|
io_context_.stop();
|
||||||
|
|
||||||
for (auto &thread : service_threads_) {
|
for (auto &thread : service_threads_) {
|
||||||
|
if (thread.joinable()) {
|
||||||
thread.join();
|
thread.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void packet_client::close(client &cli) {
|
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
|
||||||
|
|
||||||
try {
|
|
||||||
cli.socket.shutdown(boost::asio::socket_base::shutdown_both);
|
|
||||||
|
|
||||||
boost::system::error_code err;
|
|
||||||
[[maybe_unused]] auto res = cli.socket.close(err);
|
|
||||||
} catch (const std::exception &e) {
|
|
||||||
utils::error::raise_error(function_name, e, "connection handshake failed");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void packet_client::close(client &cli) noexcept {
|
||||||
|
boost::system::error_code err1;
|
||||||
|
cli.socket.shutdown(boost::asio::socket_base::shutdown_both, err1);
|
||||||
|
boost::system::error_code err2;
|
||||||
|
cli.socket.close(err2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void packet_client::close_all() {
|
void packet_client::close_all() {
|
||||||
@@ -72,9 +72,7 @@ void packet_client::close_all() {
|
|||||||
for (auto &cli : clients_) {
|
for (auto &cli : clients_) {
|
||||||
close(*cli);
|
close(*cli);
|
||||||
}
|
}
|
||||||
|
|
||||||
clients_.clear();
|
clients_.clear();
|
||||||
io_context_.restart();
|
|
||||||
resolve_results_ = {};
|
resolve_results_ = {};
|
||||||
unique_id_ = utils::create_uuid_string();
|
unique_id_ = utils::create_uuid_string();
|
||||||
}
|
}
|
||||||
@@ -119,11 +117,13 @@ auto packet_client::check_version(std::uint32_t client_version,
|
|||||||
return api_error::error;
|
return api_error::error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void packet_client::connect(client &cli) {
|
auto packet_client::connect(client &cli) -> bool {
|
||||||
try {
|
try {
|
||||||
resolve();
|
resolve();
|
||||||
|
|
||||||
connect_with_deadline(io_context_, cli.socket, resolve_results_,
|
boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::results_type cached =
|
||||||
|
resolve_results_;
|
||||||
|
connect_with_deadline(io_context_, cli.socket, cached,
|
||||||
std::chrono::milliseconds(cfg_.conn_timeout_ms));
|
std::chrono::milliseconds(cfg_.conn_timeout_ms));
|
||||||
|
|
||||||
cli.socket.set_option(boost::asio::ip::tcp::no_delay(true));
|
cli.socket.set_option(boost::asio::ip::tcp::no_delay(true));
|
||||||
@@ -133,7 +133,7 @@ void packet_client::connect(client &cli) {
|
|||||||
std::uint32_t min_version{};
|
std::uint32_t min_version{};
|
||||||
if (not handshake(cli, io_context_, min_version)) {
|
if (not handshake(cli, io_context_, min_version)) {
|
||||||
close(cli);
|
close(cli);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet response;
|
packet response;
|
||||||
@@ -141,6 +141,7 @@ void packet_client::connect(client &cli) {
|
|||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
throw std::runtime_error(fmt::format("read packet failed|err|{}", res));
|
throw std::runtime_error(fmt::format("read packet failed|err|{}", res));
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
close(cli);
|
close(cli);
|
||||||
resolve_results_ = {};
|
resolve_results_ = {};
|
||||||
@@ -151,17 +152,19 @@ void packet_client::connect(client &cli) {
|
|||||||
auto packet_client::get_client() -> std::shared_ptr<packet_client::client> {
|
auto packet_client::get_client() -> std::shared_ptr<packet_client::client> {
|
||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
unique_mutex_lock clients_lock(clients_mutex_);
|
|
||||||
if (not allow_connections_) {
|
if (not allow_connections_) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
unique_mutex_lock clients_lock(clients_mutex_);
|
||||||
if (clients_.empty()) {
|
if (clients_.empty()) {
|
||||||
clients_lock.unlock();
|
clients_lock.unlock();
|
||||||
|
|
||||||
auto cli = std::make_shared<client>(io_context_);
|
auto cli = std::make_shared<client>(io_context_);
|
||||||
connect(*cli);
|
if (!connect(*cli)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
return cli;
|
return cli;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +172,7 @@ auto packet_client::get_client() -> std::shared_ptr<packet_client::client> {
|
|||||||
utils::collection::remove_element(clients_, cli);
|
utils::collection::remove_element(clients_, cli);
|
||||||
return cli;
|
return cli;
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
utils::error::raise_error(function_name, e, "connection handshake failed");
|
utils::error::raise_error(function_name, e, "get_client failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -190,7 +193,8 @@ auto packet_client::handshake(client &cli, boost::asio::io_context &ctx,
|
|||||||
data_buffer buffer;
|
data_buffer buffer;
|
||||||
{
|
{
|
||||||
packet tmp;
|
packet tmp;
|
||||||
tmp.encode(utils::get_version_number(REPERTORY_MIN_REMOTE_VERSION));
|
tmp.encode(utils::get_version_number(project_get_version()));
|
||||||
|
tmp.encode(~utils::get_version_number(project_get_version()));
|
||||||
tmp.encode(utils::generate_random_string(packet_nonce_size));
|
tmp.encode(utils::generate_random_string(packet_nonce_size));
|
||||||
tmp.to_buffer(buffer);
|
tmp.to_buffer(buffer);
|
||||||
}
|
}
|
||||||
@@ -198,11 +202,22 @@ auto packet_client::handshake(client &cli, boost::asio::io_context &ctx,
|
|||||||
read_exact_with_deadline(ctx, cli.socket, boost::asio::buffer(buffer),
|
read_exact_with_deadline(ctx, cli.socket, boost::asio::buffer(buffer),
|
||||||
std::chrono::milliseconds(cfg_.recv_timeout_ms));
|
std::chrono::milliseconds(cfg_.recv_timeout_ms));
|
||||||
packet response(buffer);
|
packet response(buffer);
|
||||||
|
|
||||||
auto res = response.decode(min_version);
|
auto res = response.decode(min_version);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
throw std::runtime_error("failed to decode server version");
|
throw std::runtime_error("failed to decode server version");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::uint32_t min_version_check{};
|
||||||
|
res = response.decode(min_version_check);
|
||||||
|
if (res != 0) {
|
||||||
|
throw std::runtime_error("failed to decode server version");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (min_version_check != ~min_version) {
|
||||||
|
throw std::runtime_error("failed to decode server version");
|
||||||
|
}
|
||||||
|
|
||||||
response.encrypt(cfg_.encryption_token, false);
|
response.encrypt(cfg_.encryption_token, false);
|
||||||
response.to_buffer(buffer);
|
response.to_buffer(buffer);
|
||||||
|
|
||||||
@@ -210,7 +225,7 @@ auto packet_client::handshake(client &cli, boost::asio::io_context &ctx,
|
|||||||
std::chrono::milliseconds(cfg_.send_timeout_ms));
|
std::chrono::milliseconds(cfg_.send_timeout_ms));
|
||||||
return true;
|
return true;
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
utils::error::raise_error(function_name, e, "handlshake failed");
|
utils::error::raise_error(function_name, e, "handshake failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -241,6 +256,11 @@ auto packet_client::read_packet(client &cli, boost::asio::io_context &ctx,
|
|||||||
std::uint32_t to_read{};
|
std::uint32_t to_read{};
|
||||||
std::memcpy(&to_read, buffer.data(), sizeof(to_read));
|
std::memcpy(&to_read, buffer.data(), sizeof(to_read));
|
||||||
boost::endian::big_to_native_inplace(to_read);
|
boost::endian::big_to_native_inplace(to_read);
|
||||||
|
|
||||||
|
if (to_read == 0U || to_read > comm::max_packet_bytes) {
|
||||||
|
return utils::from_api_error(api_error::comm_error);
|
||||||
|
}
|
||||||
|
|
||||||
buffer.resize(to_read);
|
buffer.resize(to_read);
|
||||||
|
|
||||||
read_exact_with_deadline(ctx, cli.socket, boost::asio::buffer(buffer),
|
read_exact_with_deadline(ctx, cli.socket, boost::asio::buffer(buffer),
|
||||||
@@ -255,7 +275,9 @@ auto packet_client::read_packet(client &cli, boost::asio::io_context &ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void packet_client::resolve() {
|
void packet_client::resolve() {
|
||||||
if (not resolve_results_.empty()) {
|
boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::results_type cached =
|
||||||
|
resolve_results_;
|
||||||
|
if (not cached.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,12 +304,14 @@ auto packet_client::send(std::string_view method, packet &request,
|
|||||||
REPERTORY_USES_FUNCTION_NAME();
|
REPERTORY_USES_FUNCTION_NAME();
|
||||||
|
|
||||||
auto success = false;
|
auto success = false;
|
||||||
packet::error_type ret = utils::from_api_error(api_error::error);
|
auto ret = utils::from_api_error(api_error::error);
|
||||||
request.encode_top(method);
|
|
||||||
request.encode_top(utils::get_thread_id());
|
auto base_request = request;
|
||||||
request.encode_top(unique_id_);
|
base_request.encode_top(method);
|
||||||
request.encode_top(PACKET_SERVICE_FLAGS);
|
base_request.encode_top(utils::get_thread_id());
|
||||||
request.encode_top(std::string{project_get_version()});
|
base_request.encode_top(unique_id_.load());
|
||||||
|
base_request.encode_top(PACKET_SERVICE_FLAGS);
|
||||||
|
base_request.encode_top(std::string{project_get_version()});
|
||||||
|
|
||||||
for (std::uint8_t retry = 1U;
|
for (std::uint8_t retry = 1U;
|
||||||
allow_connections_ && not success && (retry <= max_read_attempts);
|
allow_connections_ && not success && (retry <= max_read_attempts);
|
||||||
@@ -295,12 +319,16 @@ auto packet_client::send(std::string_view method, packet &request,
|
|||||||
auto current_client = get_client();
|
auto current_client = get_client();
|
||||||
if (current_client) {
|
if (current_client) {
|
||||||
try {
|
try {
|
||||||
request.encode_top(current_client->nonce);
|
auto current_request = base_request;
|
||||||
request.encrypt(cfg_.encryption_token);
|
current_request.encode_top(current_client->nonce);
|
||||||
|
request = current_request;
|
||||||
|
|
||||||
|
current_request.encrypt(cfg_.encryption_token);
|
||||||
|
|
||||||
write_all_with_deadline(
|
write_all_with_deadline(
|
||||||
io_context_, current_client->socket,
|
io_context_, current_client->socket,
|
||||||
boost::asio::buffer(&request[0], request.get_size()),
|
boost::asio::buffer(¤t_request[0],
|
||||||
|
current_request.get_size()),
|
||||||
std::chrono::milliseconds(cfg_.send_timeout_ms));
|
std::chrono::milliseconds(cfg_.send_timeout_ms));
|
||||||
|
|
||||||
ret = read_packet(*current_client, response);
|
ret = read_packet(*current_client, response);
|
||||||
@@ -318,7 +346,6 @@ auto packet_client::send(std::string_view method, packet &request,
|
|||||||
}
|
}
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
utils::error::raise_error(function_name, e, "send failed");
|
utils::error::raise_error(function_name, e, "send failed");
|
||||||
|
|
||||||
close(*current_client);
|
close(*current_client);
|
||||||
if (allow_connections_ && (retry < max_read_attempts)) {
|
if (allow_connections_ && (retry < max_read_attempts)) {
|
||||||
std::this_thread::sleep_for(1s);
|
std::this_thread::sleep_for(1s);
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ auto packet_server::handshake(std::shared_ptr<connection> conn) const -> bool {
|
|||||||
data_buffer buffer;
|
data_buffer buffer;
|
||||||
packet request;
|
packet request;
|
||||||
request.encode(utils::get_version_number(REPERTORY_MIN_REMOTE_VERSION));
|
request.encode(utils::get_version_number(REPERTORY_MIN_REMOTE_VERSION));
|
||||||
|
request.encode(~utils::get_version_number(REPERTORY_MIN_REMOTE_VERSION));
|
||||||
request.encode(conn->nonce);
|
request.encode(conn->nonce);
|
||||||
request.to_buffer(buffer);
|
request.to_buffer(buffer);
|
||||||
auto to_read{buffer.size() + utils::encryption::encryption_header_size};
|
auto to_read{buffer.size() + utils::encryption::encryption_header_size};
|
||||||
@@ -276,6 +277,11 @@ void packet_server::read_packet(std::shared_ptr<connection> conn,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (data_size > comm::max_packet_bytes) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
fmt::format("packet too large|size|{}", data_size));
|
||||||
|
}
|
||||||
|
|
||||||
auto should_send_response = true;
|
auto should_send_response = true;
|
||||||
auto response = std::make_shared<packet>();
|
auto response = std::make_shared<packet>();
|
||||||
conn->buffer.resize(data_size);
|
conn->buffer.resize(data_size);
|
||||||
|
|||||||
Reference in New Issue
Block a user