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

View File

@@ -58,10 +58,11 @@ packet_client::~packet_client() {
void packet_client::close(client &cli) noexcept { void packet_client::close(client &cli) noexcept {
boost::system::error_code err1; 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; boost::system::error_code err2;
res = cli.socket.close(err2); [[maybe_unused]] auto res2 = cli.socket.close(err2);
} }
void packet_client::close_all() { 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)); 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) { if (to_read > comm::max_packet_bytes) {
return utils::from_api_error(api_error::comm_error); 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); 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)); 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 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);