fix(libmsg): security audit round 3 - add server send timeout + harden RPC validation
This commit is contained in:
1 parent
3c50a862d3
commit
63c22a3d60
3 files changed
+102
-10
No files matched your search
@@ -217,7 +217,10 @@ public:
|
||||
try {
|
||||
pmsg_send(sockfd, msg);
|
||||
} catch (const MsgException&) {
|
||||
// 连接可能已断开,静默忽略
|
||||
// 发送失败(连接断开或发送超时),标记为 failed 由主循环清理。
|
||||
// 与 broadcast() 保持一致,避免连接残留。
|
||||
std::lock_guard<std::mutex> flk(_failed_mtx);
|
||||
_failed.insert(sockfd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -439,6 +442,16 @@ private:
|
||||
// 禁用 Nagle 算法,降低小包延迟
|
||||
int flag = 1;
|
||||
::setsockopt(client_fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
|
||||
|
||||
// 设置发送超时:防止慢客户端不读数据导致发送缓冲区填满,
|
||||
// 使 reply()/broadcast() 的 send() 永久阻塞(拒绝服务)。
|
||||
// 超时后 sendAll() 抛 MsgTimeoutException,被 reply/broadcast 捕获并标记 failed 清理。
|
||||
struct timeval sndtv {};
|
||||
constexpr double kServerSendTimeout = 5.0; // 秒
|
||||
sndtv.tv_sec = static_cast<time_t>(kServerSendTimeout);
|
||||
sndtv.tv_usec = static_cast<long>(
|
||||
(kServerSendTimeout - static_cast<double>(sndtv.tv_sec)) * 1'000'000.0);
|
||||
::setsockopt(client_fd, SOL_SOCKET, SO_SNDTIMEO, &sndtv, sizeof(sndtv));
|
||||
}
|
||||
|
||||
void _handle_client(int fd) {
|
||||
|
||||
@@ -126,7 +126,12 @@ public:
|
||||
if (!obj.contains("success")) {
|
||||
throw RpcError("非法 RPC 响应(缺少 success 字段): " + resp_str.substr(0, 200));
|
||||
}
|
||||
if (!obj.at("success").as_bool()) {
|
||||
const json::value& success = obj.at("success");
|
||||
if (!success.is_bool()) {
|
||||
// 类型不符时不要调用 as_bool()(会抛未捕获的 boost system_error),统一抛 RpcError
|
||||
throw RpcError("非法 RPC 响应(success 字段不是 bool)");
|
||||
}
|
||||
if (!success.as_bool()) {
|
||||
std::string err = "未知错误";
|
||||
if (auto it = obj.find("error"); it != obj.end() && it->value().is_string()) {
|
||||
err = it->value().as_string().c_str();
|
||||
|
||||
Reference in new issue
Block a user