fix crash
This commit is contained in:
@@ -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");
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user