Skip to content

Commit

Permalink
Add a callback to handle misbehaving messages from peer (eBay#537)
Browse files Browse the repository at this point in the history
* Callback can decide whether to ignore or to die.
  • Loading branch information
greensky00 authored Sep 24, 2024
1 parent 6741a45 commit 092997a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 2 deletions.
21 changes: 21 additions & 0 deletions include/libnuraft/callback.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ limitations under the License.
#ifndef _CALLBACK_H_
#define _CALLBACK_H_

#include "req_msg.hxx"
#include "resp_msg.hxx"

#include <cstdint>
#include <functional>
#include <string>
Expand Down Expand Up @@ -214,6 +217,18 @@ public:
* ctx: null.
*/
FollowerLost = 28,

/**
* When the server receives a misbehaving message from a peer,
* the callback has the ability to either ignore the message
* or respond normally by adjusting ReqResp.resp as indicated by ctx.
*
* Furthermore, the callback can opt to terminate
* if the situation is deemed critical.
*
* ctx: pointer to `ReqResp` instance.
*/
ReceivedMisbehavingMessage = 29,
};

struct Param {
Expand All @@ -232,6 +247,12 @@ public:
void* ctx;
};

struct ReqResp {
ReqResp() : req(nullptr), resp(nullptr) {}
req_msg* req;
ptr<resp_msg> resp;
};

enum ReturnCode {
Ok = 0,
ReturnNull = -1,
Expand Down
16 changes: 14 additions & 2 deletions src/handle_append_entries.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -593,9 +593,21 @@ ptr<resp_msg> raft_server::handle_append_entries(req_msg& req)
become_follower();
} else if (role_ == srv_role::leader) {
p_wn( "Receive AppendEntriesRequest from another leader (%d) "
"with same term, there must be a bug. Ignore it instead of exit.",
"with same term, there must be a bug. Invoking the callback.",
req.get_src() );
return nullptr;

cb_func::Param param(id_, leader_, -1, &req);
cb_func::ReqResp req_resp;
req_resp.req = &req;

ctx_->cb_func_.call(cb_func::ReceivedMisbehavingMessage, &param);
if (!req_resp.resp.get()) {
p_wn("callback function didn't return response, ignore this request");
} else {
p_wn("callback function returned response, send it back");
}
return req_resp.resp;

} else {
update_target_priority();
// Modified by JungSang Ahn, Mar 28 2018:
Expand Down

0 comments on commit 092997a

Please sign in to comment.