fix crash

This commit is contained in:
2025-09-27 18:18:32 -05:00
parent e44a42f445
commit 0edd53f5f8
3 changed files with 47 additions and 28 deletions

View File

@@ -84,46 +84,55 @@ void apply_common_socket_properties(boost::asio::ip::tcp::socket &sock) {
}
template <class op_t>
void run_with_deadline(boost::asio::io_context &io_ctx,
boost::asio::ip::tcp::socket &sock, op_t &&operation,
std::chrono::milliseconds deadline,
std::string_view event_name,
std::string_view function_name) {
static void run_with_deadline(boost::asio::io_context &io_ctx,
boost::asio::ip::tcp::socket &sock,
op_t &&operation,
std::chrono::milliseconds deadline,
const std::string &event_name,
const std::string &function_name) {
deadline = std::max(deadline, std::chrono::milliseconds{250});
bool done = false;
bool timed_out = false;
struct request_state final {
std::atomic<bool> done{false};
std::atomic<bool> timed_out{false};
boost::system::error_code err;
};
auto state = std::make_shared<request_state>();
boost::asio::steady_timer timer{io_ctx};
timer.expires_after(deadline);
timer.async_wait([&done, &sock, &timed_out](auto &&err_) {
if (not err_ && not done) {
timed_out = true;
sock.cancel();
timer.async_wait([state, &sock](auto &&err) {
if (not err && not state->done) {
state->timed_out = true;
boost::system::error_code ignored_ec;
[[maybe_unused]] auto res = sock.cancel(ignored_ec);
}
});
boost::system::error_code err{};
operation([&done, &err](auto &&err_) {
err = err_;
done = true;
operation([state](auto &&err) {
state->err = err;
state->done = true;
});
io_ctx.restart();
while (not done) {
while (not state->done && not state->timed_out) {
io_ctx.run_one();
}
timer.cancel();
if (timed_out) {
io_ctx.poll();
if (state->timed_out) {
repertory::event_system::instance().raise<repertory::packet_client_timeout>(
std::string(event_name), std::string(function_name));
throw std::runtime_error(std::string(event_name) + " timed-out");
throw std::runtime_error(event_name + " timed-out");
}
if (err) {
throw std::runtime_error(std::string(event_name) + " failed|err|" +
err.message());
if (state->err) {
throw std::runtime_error(event_name + " failed|err|" +
state->err.message());
}
}
@@ -140,7 +149,7 @@ void connect_with_deadline(
boost::asio::async_connect(
sock, endpoints, [handler](auto &&err, auto &&) { handler(err); });
},
deadline, "connect", function_name);
deadline, "connect", std::string{function_name});
}
void read_exact_with_deadline(boost::asio::io_context &io_ctx,
@@ -167,7 +176,7 @@ void read_exact_with_deadline(boost::asio::io_context &io_ctx,
handler(err);
});
},
deadline, "read", function_name);
deadline, "read", std::string{function_name});
if (bytes_read == 0U) {
throw std::runtime_error("0 bytes read");
@@ -200,7 +209,7 @@ void write_all_with_deadline(boost::asio::io_context &io_ctx,
handler(err);
});
},
deadline, "write", function_name);
deadline, "write", std::string{function_name});
if (bytes_written == 0U) {
throw std::runtime_error("0 bytes written");

View File

@@ -58,10 +58,11 @@ packet_client::~packet_client() {
void packet_client::close(client &cli) noexcept {
boost::system::error_code err1;
auto res = cli.socket.shutdown(boost::asio::socket_base::shutdown_both, err1);
[[maybe_unused]] auto res =
cli.socket.shutdown(boost::asio::socket_base::shutdown_both, err1);
boost::system::error_code err2;
res = cli.socket.close(err2);
[[maybe_unused]] auto res2 = cli.socket.close(err2);
}
void packet_client::close_all() {
@@ -244,8 +245,12 @@ auto packet_client::read_packet(client &cli, boost::asio::io_context &ctx,
std::memcpy(&to_read, buffer.data(), sizeof(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);
if (to_read > comm::max_packet_bytes) {
throw std::runtime_error(fmt::format("packet too large|size|{}", to_read));
}
if (to_read < utils::encryption::encryption_header_size) {
throw std::runtime_error(fmt::format("packet too small|size|{}", to_read));
}
buffer.resize(to_read);

View File

@@ -289,6 +289,11 @@ void packet_server::read_packet(std::shared_ptr<connection> conn,
fmt::format("packet too large|size|{}", data_size));
}
if (data_size < utils::encryption::encryption_header_size) {
throw std::runtime_error(
fmt::format("packet too small|size|{}", data_size));
}
auto should_send_response = true;
auto response = std::make_shared<packet>();
conn->buffer.resize(data_size);