From 869949af8d5915671b8a98cbdf0f0274113e326f Mon Sep 17 00:00:00 2001 From: bizhiyuan Date: Wed, 22 Oct 2025 11:28:23 +0800 Subject: [PATCH] Remove global booth_conf variable from notify_client list_peers and network functions (cherry picked from commit 31bf28ea8e5bf99b00ac2eb1d5d5ed3ed695471c) --- ...global-booth_conf-variable-from-list.patch | 81 + ...global-booth_conf-variable-from-netw.patch | 1319 +++++++++++++++++ ...global-booth_conf-variable-from-noti.patch | 355 +++++ booth.spec | 8 +- 4 files changed, 1762 insertions(+), 1 deletion(-) create mode 100644 backport-Refactor-Remove-global-booth_conf-variable-from-list.patch create mode 100644 backport-Refactor-Remove-global-booth_conf-variable-from-netw.patch create mode 100644 backport-Refactor-Remove-global-booth_conf-variable-from-noti.patch diff --git a/backport-Refactor-Remove-global-booth_conf-variable-from-list.patch b/backport-Refactor-Remove-global-booth_conf-variable-from-list.patch new file mode 100644 index 0000000..b69036c --- /dev/null +++ b/backport-Refactor-Remove-global-booth_conf-variable-from-list.patch @@ -0,0 +1,81 @@ +From 6f8a938be4f948626cc70656fbf24db774d36b13 Mon Sep 17 00:00:00 2001 +From: Chris Lumens +Date: Fri, 25 Oct 2024 11:05:46 -0400 +Subject: [PATCH 2/3] Refactor: Remove global booth_conf variable from + list_peers. + +Co-authored-by: Jan Pokorny +--- + src/booth.h | 10 +++++++++- + src/main.c | 8 +++++--- + src/transport.c | 2 +- + 3 files changed, 15 insertions(+), 5 deletions(-) + +diff --git a/src/booth.h b/src/booth.h +index 799cdf9..3f0c220 100644 +--- a/src/booth.h ++++ b/src/booth.h +@@ -355,7 +355,15 @@ int client_add(int fd, const struct booth_transport *tpt, + int find_client_by_fd(int fd); + void safe_copy(char *dest, char *value, size_t buflen, const char *description); + int update_authkey(void); +-void list_peers(int fd); ++ ++/** ++ * @internal ++ * Response to "get all servers we know about" ++ * ++ * @param[in,out] conf config object to refer to ++ * @param[in] fd file descriptor of the socket to respond to ++ */ ++void list_peers(struct booth_config *conf, int fd); + + + struct command_line { +diff --git a/src/main.c b/src/main.c +index 7d93296..f7343bc 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -280,21 +280,23 @@ static int format_peers(char **pdata, unsigned int *len) + } + + +-void list_peers(int fd) ++void list_peers(struct booth_config *conf, int fd) + { + char *data; + unsigned int olen; + struct boothc_hdr_msg hdr; + +- if (format_peers(&data, &olen) < 0) ++ if (format_peers(&data, &olen) < 0) { + goto out; ++ } + + init_header(&hdr.header, CL_LIST, 0, 0, RLT_SUCCESS, 0, sizeof(hdr) + olen); + (void)send_header_plus(fd, &hdr, data, olen); + + out: +- if (data) ++ if (data) { + free(data); ++ } + } + + /* trim trailing spaces if the key is ascii +diff --git a/src/transport.c b/src/transport.c +index 49217f6..d93c685 100644 +--- a/src/transport.c ++++ b/src/transport.c +@@ -468,7 +468,7 @@ static void process_connection(struct booth_config *conf, int ci) + ticket_answer_list(conf, req_cl->fd); + goto kill; + case CMD_PEERS: +- list_peers(req_cl->fd); ++ list_peers(conf, req_cl->fd); + goto kill; + + case CMD_GRANT: +-- +2.25.1 + diff --git a/backport-Refactor-Remove-global-booth_conf-variable-from-netw.patch b/backport-Refactor-Remove-global-booth_conf-variable-from-netw.patch new file mode 100644 index 0000000..fbf0b94 --- /dev/null +++ b/backport-Refactor-Remove-global-booth_conf-variable-from-netw.patch @@ -0,0 +1,1319 @@ +From cb1c9fa216c09cf0b6b7ffe9d33c6504def0d7b1 Mon Sep 17 00:00:00 2001 +From: Chris Lumens +Date: Fri, 25 Oct 2024 12:18:01 -0400 +Subject: [PATCH 3/3] Refactor: Remove global booth_conf variable from network + functions. + +* Add braces around some nearby conditional blocks. + +* Make add_hmac a static function and move it up in the source file to + avoid a function declaration. + +* Convert _FOREACH_NODE to FOREACH_NODE in booth_udp_broadcast_auth. + +* Change other network functions to be static. + +Co-authored-by: Jan Pokorny +--- + src/attr.c | 47 +++++++++++------ + src/main.c | 9 ++-- + src/manual.c | 26 +++++----- + src/manual.h | 13 ++--- + src/raft.c | 133 +++++++++++++++++++++++------------------------- + src/raft.h | 5 +- + src/ticket.c | 90 +++++++++++++++++--------------- + src/ticket.h | 34 +++++++++++-- + src/transport.c | 115 ++++++++++++++++++++++------------------- + src/transport.h | 56 ++++++++++++++++---- + 10 files changed, 311 insertions(+), 217 deletions(-) + +diff --git a/src/attr.c b/src/attr.c +index 34df335..3faa888 100644 +--- a/src/attr.c ++++ b/src/attr.c +@@ -184,9 +184,10 @@ int do_attr_command(struct booth_config *conf, cmd_request_t cmd) + if (rv < 0) + goto out_close; + +- rv = tpt->send(site, &cl.attr_msg, sendmsglen(&cl.attr_msg)); +- if (rv < 0) ++ rv = tpt->send(conf, site, &cl.attr_msg, sendmsglen(&cl.attr_msg)); ++ if (rv < 0) { + goto out_close; ++ } + + msg = malloc(MAX_MSG_LEN); + if (!msg) { +@@ -346,7 +347,8 @@ append_attr(gpointer key, gpointer value, gpointer user_data) + } + + +-static cmd_result_t attr_get(struct ticket_config *tk, int fd, struct boothc_attr_msg *msg) ++static cmd_result_t attr_get(struct booth_config *conf, struct ticket_config *tk, ++ int fd, struct boothc_attr_msg *msg) + { + cmd_result_t rv = RLT_SUCCESS; + struct boothc_hdr_msg hdr; +@@ -357,12 +359,15 @@ static cmd_result_t attr_get(struct ticket_config *tk, int fd, struct boothc_att + * lookup attr + * send value + */ +- if (!tk->attr) ++ if (!tk->attr) { + return RLT_NO_SUCH_ATTR; ++ } + + a = (struct geo_attr *)g_hash_table_lookup(tk->attr, msg->attr.name); +- if (!a) ++ if (!a) { + return RLT_NO_SUCH_ATTR; ++ } ++ + attr_val = g_string_new(NULL); + if (!attr_val) { + log_error("out of memory"); +@@ -371,14 +376,20 @@ static cmd_result_t attr_get(struct ticket_config *tk, int fd, struct boothc_att + g_string_printf(attr_val, "%s\n", a->val); + init_header(&hdr.header, ATTR_GET, 0, 0, RLT_SUCCESS, 0, + sizeof(hdr) + attr_val->len); +- if (send_header_plus(fd, &hdr, attr_val->str, attr_val->len)) ++ ++ if (send_header_plus(conf, fd, &hdr, attr_val->str, attr_val->len)) { + rv = RLT_SYNC_FAIL; +- if (attr_val) ++ } ++ ++ if (attr_val) { + g_string_free(attr_val, TRUE); ++ } ++ + return rv; + } + +-static cmd_result_t attr_list(struct ticket_config *tk, int fd, struct boothc_attr_msg *msg) ++static cmd_result_t attr_list(struct booth_config *conf, struct ticket_config *tk, ++ int fd, struct boothc_attr_msg *msg) + { + GString *data; + cmd_result_t rv; +@@ -399,10 +410,12 @@ static cmd_result_t attr_list(struct ticket_config *tk, int fd, struct boothc_at + + init_header(&hdr.header, ATTR_LIST, 0, 0, RLT_SUCCESS, 0, + sizeof(hdr) + data->len); +- rv = send_header_plus(fd, &hdr, data->str, data->len); ++ rv = send_header_plus(conf, fd, &hdr, data->str, data->len); + +- if (data) ++ if (data) { + g_string_free(data, TRUE); ++ } ++ + return rv; + } + +@@ -426,14 +439,18 @@ int process_attr_request(struct booth_config *conf, struct client *req_client, + + switch (cmd) { + case ATTR_LIST: +- rv = attr_list(tk, req_client->fd, msg); +- if (rv) ++ rv = attr_list(conf, tk, req_client->fd, msg); ++ if (rv) { + goto reply_now; ++ } ++ + return 1; + case ATTR_GET: +- rv = attr_get(tk, req_client->fd, msg); +- if (rv) ++ rv = attr_get(conf, tk, req_client->fd, msg); ++ if (rv) { + goto reply_now; ++ } ++ + return 1; + case ATTR_SET: + rv = attr_set(tk, msg); +@@ -445,7 +462,7 @@ int process_attr_request(struct booth_config *conf, struct client *req_client, + + reply_now: + init_header(&hdr.header, CL_RESULT, 0, 0, rv, 0, sizeof(hdr)); +- send_header_plus(req_client->fd, &hdr, NULL, 0); ++ send_header_plus(conf, req_client->fd, &hdr, NULL, 0); + return 1; + } + +diff --git a/src/main.c b/src/main.c +index f7343bc..cd69322 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -291,7 +291,7 @@ void list_peers(struct booth_config *conf, int fd) + } + + init_header(&hdr.header, CL_LIST, 0, 0, RLT_SUCCESS, 0, sizeof(hdr) + olen); +- (void)send_header_plus(fd, &hdr, data, olen); ++ send_header_plus(conf, fd, &hdr, data, olen); + + out: + if (data) { +@@ -721,7 +721,7 @@ static int query_get_string_answer(cmd_request_t cmd) + if (rv < 0) + goto out_close; + +- rv = tpt->send(site, request, msg_size); ++ rv = tpt->send(booth_conf, site, request, msg_size); + if (rv < 0) + goto out_close; + +@@ -822,9 +822,10 @@ redirect: + if (rv < 0) + goto out_close; + +- rv = tpt->send(site, &cl.msg, sendmsglen(&cl.msg)); +- if (rv < 0) ++ rv = tpt->send(booth_conf, site, &cl.msg, sendmsglen(&cl.msg)); ++ if (rv < 0) { + goto out_close; ++ } + + read_more: + rv = tpt->recv_auth(site, &reply, sizeof(reply)); +diff --git a/src/manual.c b/src/manual.c +index 5fc5eeb..fe6ae0b 100644 +--- a/src/manual.c ++++ b/src/manual.c +@@ -30,11 +30,13 @@ + * and the current node doesn't have to wait for any responses + * from other sites. + */ +-int manual_selection(struct ticket_config *tk, +- struct booth_site *preference, int update_term, cmd_reason_t reason) ++int manual_selection(struct booth_config *conf, struct ticket_config *tk, ++ struct booth_site *preference, int update_term, ++ cmd_reason_t reason) + { +- if (local->type != SITE) ++ if (local->type != SITE) { + return 0; ++ } + + tk_log_debug("starting manual selection (caused by %s %s)", + state_to_string(reason), +@@ -56,7 +58,7 @@ int manual_selection(struct ticket_config *tk, + save_committed_tkt(tk); + + // Inform others about the new leader +- ticket_broadcast(tk, OP_HEARTBEAT, OP_ACK, RLT_SUCCESS, 0); ++ ticket_broadcast(conf, tk, OP_HEARTBEAT, OP_ACK, RLT_SUCCESS, 0); + tk->ticket_updated = 0; + + return 0; +@@ -66,27 +68,27 @@ int manual_selection(struct ticket_config *tk, + * revoked from another site, which this site doesn't + * consider as a leader. + */ +-int process_REVOKE_for_manual_ticket ( +- struct ticket_config *tk, +- struct booth_site *sender, +- struct boothc_ticket_msg *msg) ++int process_REVOKE_for_manual_ticket(struct booth_config *conf, ++ struct ticket_config *tk, ++ struct booth_site *sender, ++ struct boothc_ticket_msg *msg) + { + int rv; + + // For manual tickets, we may end up having two leaders. + // If one of them is revoked, it will send information + // to all members of the GEO cluster. +- ++ + // We may find ourselves here if this particular site + // has not been following the leader which had been revoked + // (and which had sent this message). + + // We send the ACK, to satisfy the requestor. +- rv = send_msg(OP_ACK, tk, sender, msg); ++ rv = send_msg(conf, OP_ACK, tk, sender, msg); + + // Mark this ticket as not granted to the sender anymore. + mark_ticket_as_revoked(tk, sender); +- ++ + if (tk->state == ST_LEADER) { + tk_log_warn("%s wants to revoke ticket, " + "but this site is itself a leader", +@@ -94,7 +96,7 @@ int process_REVOKE_for_manual_ticket ( + + // Because another leader is presumably stepping down, + // let's notify other sites that now we are the only leader. +- ticket_broadcast(tk, OP_HEARTBEAT, OP_ACK, RLT_SUCCESS, 0); ++ ticket_broadcast(conf, tk, OP_HEARTBEAT, OP_ACK, RLT_SUCCESS, 0); + } else { + tk_log_warn("%s wants to revoke ticket, " + "but this site is not following it", +diff --git a/src/manual.h b/src/manual.h +index 923e116..db1748d 100644 +--- a/src/manual.h ++++ b/src/manual.h +@@ -23,13 +23,14 @@ + + struct ticket_config; + +-int manual_selection(struct ticket_config *tk, +- struct booth_site *new_leader, int update_term, cmd_reason_t reason); ++int manual_selection(struct booth_config *conf, struct ticket_config *tk, ++ struct booth_site *new_leader, int update_term, ++ cmd_reason_t reason); + +-int process_REVOKE_for_manual_ticket ( +- struct ticket_config *tk, +- struct booth_site *sender, +- struct boothc_ticket_msg *msg); ++int process_REVOKE_for_manual_ticket(struct booth_config *conf, ++ struct ticket_config *tk, ++ struct booth_site *sender, ++ struct boothc_ticket_msg *msg); + + + #endif /* _MANUAL_H */ +diff --git a/src/raft.c b/src/raft.c +index f63f14e..a91e204 100644 +--- a/src/raft.c ++++ b/src/raft.c +@@ -131,7 +131,7 @@ static void become_follower(struct ticket_config *tk, + } + + +-static void won_elections(struct ticket_config *tk) ++static void won_elections(struct booth_config *conf, struct ticket_config *tk) + { + set_leader(tk, local); + set_state(tk, ST_LEADER); +@@ -147,7 +147,7 @@ static void won_elections(struct ticket_config *tk) + + save_committed_tkt(tk); + +- ticket_broadcast(tk, OP_HEARTBEAT, OP_ACK, RLT_SUCCESS, 0); ++ ticket_broadcast(conf, tk, OP_HEARTBEAT, OP_ACK, RLT_SUCCESS, 0); + tk->ticket_updated = 0; + } + +@@ -222,7 +222,7 @@ void elections_end(struct booth_config *conf, struct ticket_config *tk) + tk->in_election = 0; + new_leader = majority_votes(tk); + if (new_leader == local) { +- won_elections(tk); ++ won_elections(conf, tk); + tk_log_info("granted successfully here"); + } else if (new_leader) { + tk_log_info("ticket granted at %s", +@@ -231,7 +231,7 @@ void elections_end(struct booth_config *conf, struct ticket_config *tk) + tk_log_info("nobody won elections, new elections"); + tk->outcome = RLT_MORE; + foreach_tkt_req(conf, tk, notify_client); +- if (!new_election(tk, NULL, is_tie(tk) ? 2 : 0, OR_AGAIN)) { ++ if (!new_election(conf, tk, NULL, is_tie(tk) ? 2 : 0, OR_AGAIN)) { + ticket_activate_timeout(tk); + } + } +@@ -291,10 +291,9 @@ static int msg_term_invalid(struct ticket_config *tk, + return 0; + } + +-static int term_too_low(struct ticket_config *tk, +- struct booth_site *sender, +- struct booth_site *leader, +- struct boothc_ticket_msg *msg) ++static int term_too_low(struct booth_config *conf, struct ticket_config *tk, ++ struct booth_site *sender, struct booth_site *leader, ++ struct boothc_ticket_msg *msg) + { + uint32_t term; + +@@ -305,7 +304,7 @@ static int term_too_low(struct ticket_config *tk, + "(%d vs. %d)", site_string(sender), + term, tk->current_term + ); +- send_reject(sender, tk, RLT_TERM_OUTDATED, msg); ++ send_reject(conf, sender, tk, RLT_TERM_OUTDATED, msg); + return 1; + } + +@@ -316,12 +315,9 @@ static int term_too_low(struct ticket_config *tk, + + + /* For follower. */ +-static int answer_HEARTBEAT ( +- struct ticket_config *tk, +- struct booth_site *sender, +- struct booth_site *leader, +- struct boothc_ticket_msg *msg +- ) ++static int answer_HEARTBEAT(struct booth_config *conf, struct ticket_config *tk, ++ struct booth_site *sender, struct booth_site *leader, ++ struct boothc_ticket_msg *msg) + { + uint32_t term; + +@@ -338,7 +334,8 @@ static int answer_HEARTBEAT ( + tk_log_warn("different leader %s with a lower term " + "(%d vs %d), sending reject", + site_string(leader), term, tk->current_term); +- return send_reject(sender, tk, RLT_TERM_OUTDATED, msg); ++ return send_reject(conf, sender, tk, RLT_TERM_OUTDATED, ++ msg); + } + } + +@@ -355,16 +352,13 @@ static int answer_HEARTBEAT ( + set_leader(tk, leader); + + /* Ack the heartbeat (we comply). */ +- return send_msg(OP_ACK, tk, sender, msg); ++ return send_msg(conf, OP_ACK, tk, sender, msg); + } + + +-static int process_UPDATE ( +- struct ticket_config *tk, +- struct booth_site *sender, +- struct booth_site *leader, +- struct boothc_ticket_msg *msg +- ) ++static int process_UPDATE (struct booth_config *conf, struct ticket_config *tk, ++ struct booth_site *sender, struct booth_site *leader, ++ struct boothc_ticket_msg *msg) + { + if (is_owned(tk) && sender != tk->leader) { + tk_log_warn("different leader %s wants to update " +@@ -372,7 +366,7 @@ static int process_UPDATE ( + site_string(leader)); + + mark_ticket_as_granted(tk, sender); +- return send_reject(sender, tk, RLT_TERM_OUTDATED, msg); ++ return send_reject(conf, sender, tk, RLT_TERM_OUTDATED, msg); + } + + tk_log_debug("leader %s wants to update our ticket", +@@ -385,21 +379,18 @@ static int process_UPDATE ( + /* run ticket_cron if the ticket expires */ + set_ticket_wakeup(tk); + +- return send_msg(OP_ACK, tk, sender, msg); ++ return send_msg(conf, OP_ACK, tk, sender, msg); + } + +-static int process_REVOKE ( +- struct ticket_config *tk, +- struct booth_site *sender, +- struct booth_site *leader, +- struct boothc_ticket_msg *msg +- ) ++static int process_REVOKE(struct booth_config *conf, struct ticket_config *tk, ++ struct booth_site *sender, struct booth_site *leader, ++ struct boothc_ticket_msg *msg) + { + int rv; + + if (tk->state == ST_INIT && tk->leader == no_leader) { + /* assume that our ack got lost */ +- rv = send_msg(OP_ACK, tk, sender, msg); ++ rv = send_msg(conf, OP_ACK, tk, sender, msg); + } else if (tk->leader != sender) { + if (!is_manual(tk)) { + tk_log_error("%s wants to revoke ticket, " +@@ -407,8 +398,8 @@ static int process_REVOKE ( + site_string(sender)); + return -1; + } else { +- rv = process_REVOKE_for_manual_ticket(tk, sender, msg); +- ++ rv = process_REVOKE_for_manual_ticket(conf, tk, sender, msg); ++ + // Ticket data stored in this site is not modified. This means + // that this site will still follow another leader (the one which + // has not been revoked) or be a leader itself. +@@ -425,7 +416,7 @@ static int process_REVOKE ( + save_committed_tkt(tk); + reset_ticket_and_set_no_leader(tk); + ticket_write(tk); +- rv = send_msg(OP_ACK, tk, sender, msg); ++ rv = send_msg(conf, OP_ACK, tk, sender, msg); + } + + return rv; +@@ -514,8 +505,9 @@ static int process_VOTE_FOR(struct booth_config *conf, struct ticket_config *tk, + return 0; + } + +- if (term_too_low(tk, sender, leader, msg)) ++ if (term_too_low(conf, tk, sender, leader, msg)) { + return 0; ++ } + + if (newer_term(tk, sender, leader, msg, 0)) { + clear_election(tk); +@@ -667,12 +659,9 @@ static int test_reason( + + + /* §5.2 */ +-static int answer_REQ_VOTE( +- struct ticket_config *tk, +- struct booth_site *sender, +- struct booth_site *leader, +- struct boothc_ticket_msg *msg +- ) ++static int answer_REQ_VOTE(struct booth_config *conf, struct ticket_config *tk, ++ struct booth_site *sender, struct booth_site *leader, ++ struct boothc_ticket_msg *msg) + { + int valid; + struct boothc_ticket_msg omsg; +@@ -680,8 +669,9 @@ static int answer_REQ_VOTE( + int reason; + + inappr_reason = test_reason(tk, sender, leader, msg); +- if (inappr_reason) +- return send_reject(sender, tk, inappr_reason, msg); ++ if (inappr_reason) { ++ return send_reject(conf, sender, tk, inappr_reason, msg); ++ } + + valid = term_time_left(tk); + reason = ntohl(msg->header.reason); +@@ -693,11 +683,12 @@ static int answer_REQ_VOTE( + "(we have %s as ticket owner), ticket still valid for %ds", + site_string(sender), state_to_string(reason), + site_string(tk->leader), valid); +- return send_reject(sender, tk, RLT_TERM_STILL_VALID, msg); ++ return send_reject(conf, sender, tk, RLT_TERM_STILL_VALID, msg); + } + +- if (term_too_low(tk, sender, leader, msg)) ++ if (term_too_low(conf, tk, sender, leader, msg)) { + return 0; ++ } + + /* set this, so that we know not to send status for the + * ticket */ +@@ -725,14 +716,14 @@ vote_for_sender: + + init_ticket_msg(&omsg, OP_VOTE_FOR, OP_REQ_VOTE, RLT_SUCCESS, 0, tk); + omsg.ticket.leader = htonl(get_node_id(tk->voted_for)); +- return booth_udp_send_auth(sender, &omsg, sendmsglen(&omsg)); ++ return booth_udp_send_auth(conf, sender, &omsg, sendmsglen(&omsg)); + } + + #define is_reason(r, tk) \ + (reason == (r) || (reason == OR_AGAIN && (tk)->election_reason == (r))) + +-int new_election(struct ticket_config *tk, +- struct booth_site *preference, int update_term, cmd_reason_t reason) ++int new_election(struct booth_config *conf, struct ticket_config *tk, ++ struct booth_site *preference, int update_term, cmd_reason_t reason) + { + struct booth_site *new_leader; + +@@ -803,7 +794,7 @@ int new_election(struct ticket_config *tk, + tk->election_reason = reason; + } + +- ticket_broadcast(tk, OP_REQ_VOTE, OP_VOTE_FOR, RLT_SUCCESS, reason); ++ ticket_broadcast(conf, tk, OP_REQ_VOTE, OP_VOTE_FOR, RLT_SUCCESS, reason); + add_random_delay(tk); + return 0; + } +@@ -842,12 +833,9 @@ static int leader_handle_newer_ticket( + } + + /* reply to STATUS */ +-static int process_MY_INDEX ( +- struct ticket_config *tk, +- struct booth_site *sender, +- struct booth_site *leader, +- struct boothc_ticket_msg *msg +- ) ++static int process_MY_INDEX(struct booth_config *conf, struct ticket_config *tk, ++ struct booth_site *sender, struct booth_site *leader, ++ struct boothc_ticket_msg *msg) + { + int i; + int expired; +@@ -858,11 +846,11 @@ static int process_MY_INDEX ( + + if (i > 0) { + /* let them know about our newer ticket */ +- send_msg(OP_MY_INDEX, tk, sender, msg); ++ send_msg(conf, OP_MY_INDEX, tk, sender, msg); + if (tk->state == ST_LEADER) { + tk_log_info("sending ticket update to %s", + site_string(sender)); +- return send_msg(OP_UPDATE, tk, sender, msg); ++ return send_msg(conf, OP_UPDATE, tk, sender, msg); + } + } + +@@ -940,7 +928,7 @@ int raft_answer(struct booth_config *conf, struct ticket_config *tk, + + switch (cmd) { + case OP_REQ_VOTE: +- rv = answer_REQ_VOTE(tk, sender, leader, msg); ++ rv = answer_REQ_VOTE(conf, tk, sender, leader, msg); + break; + case OP_VOTE_FOR: + rv = process_VOTE_FOR(conf, tk, sender, leader, msg); +@@ -954,15 +942,17 @@ int raft_answer(struct booth_config *conf, struct ticket_config *tk, + if ((tk->leader != local || !term_time_left(tk)) && + (tk->state == ST_INIT || tk->state == ST_FOLLOWER || + tk->state == ST_CANDIDATE)) +- rv = answer_HEARTBEAT(tk, sender, leader, msg); ++ rv = answer_HEARTBEAT(conf, tk, sender, leader, msg); + else { + tk_log_warn("unexpected message %s, from %s", + state_to_string(cmd), + site_string(sender)); + mark_ticket_as_granted(tk, sender); + +- if (ticket_seems_ok(tk)) +- send_reject(sender, tk, RLT_TERM_STILL_VALID, msg); ++ if (ticket_seems_ok(tk)) { ++ send_reject(conf, sender, tk, RLT_TERM_STILL_VALID, msg); ++ } ++ + rv = -EINVAL; + } + break; +@@ -970,13 +960,16 @@ int raft_answer(struct booth_config *conf, struct ticket_config *tk, + if (((tk->leader != local && tk->leader == leader) || !is_owned(tk)) && + (tk->state == ST_INIT || tk->state == ST_FOLLOWER || + tk->state == ST_CANDIDATE)) { +- rv = process_UPDATE(tk, sender, leader, msg); ++ rv = process_UPDATE(conf, tk, sender, leader, msg); + } else { + tk_log_warn("unexpected message %s, from %s", + state_to_string(cmd), + site_string(sender)); +- if (ticket_seems_ok(tk)) +- send_reject(sender, tk, RLT_TERM_STILL_VALID, msg); ++ ++ if (ticket_seems_ok(tk)) { ++ send_reject(conf, sender, tk, RLT_TERM_STILL_VALID, msg); ++ } ++ + rv = -EINVAL; + } + break; +@@ -984,14 +977,16 @@ int raft_answer(struct booth_config *conf, struct ticket_config *tk, + rv = process_REJECTED(tk, sender, leader, msg); + break; + case OP_REVOKE: +- rv = process_REVOKE(tk, sender, leader, msg); ++ rv = process_REVOKE(conf, tk, sender, leader, msg); + break; + case OP_MY_INDEX: +- rv = process_MY_INDEX(tk, sender, leader, msg); ++ rv = process_MY_INDEX(conf, tk, sender, leader, msg); + break; + case OP_STATUS: +- if (!tk->in_election) +- rv = send_msg(OP_MY_INDEX, tk, sender, msg); ++ if (!tk->in_election) { ++ rv = send_msg(conf, OP_MY_INDEX, tk, sender, msg); ++ } ++ + break; + default: + tk_log_error("unknown message %s, from %s", +diff --git a/src/raft.h b/src/raft.h +index 9e52d8d..a246244 100644 +--- a/src/raft.h ++++ b/src/raft.h +@@ -34,8 +34,9 @@ int raft_answer(struct booth_config *conf, struct ticket_config *tk, + struct booth_site *from, struct booth_site *leader, + struct boothc_ticket_msg *msg); + +-int new_election(struct ticket_config *tk, +- struct booth_site *new_leader, int update_term, cmd_reason_t reason); ++int new_election(struct booth_config *conf, struct ticket_config *tk, ++ struct booth_site *new_leader, int update_term, ++ cmd_reason_t reason); + void elections_end(struct booth_config *conf, struct ticket_config *tk); + + +diff --git a/src/ticket.c b/src/ticket.c +index e668ce0..fc5f3a7 100644 +--- a/src/ticket.c ++++ b/src/ticket.c +@@ -181,7 +181,8 @@ void save_committed_tkt(struct ticket_config *tk) + memcpy(tk->last_valid_tk, tk, sizeof(struct ticket_config)); + } + +-static void ext_prog_failed(struct ticket_config *tk, int start_election) ++static void ext_prog_failed(struct booth_config *conf, struct ticket_config *tk, ++ int start_election) + { + if (!is_manual(tk)) { + /* Give it to somebody else. +@@ -196,7 +197,8 @@ static void ext_prog_failed(struct ticket_config *tk, int start_election) + ticket_write(tk); + + if (start_election) { +- ticket_broadcast(tk, OP_VOTE_FOR, OP_REQ_VOTE, RLT_SUCCESS, OR_LOCAL_FAIL); ++ ticket_broadcast(conf, tk, OP_VOTE_FOR, OP_REQ_VOTE, ++ RLT_SUCCESS, OR_LOCAL_FAIL); + } + } else { + /* There is not much we can do now because +@@ -265,7 +267,8 @@ fail: + * != 0: executing program failed (or some other failure) + */ + +-static int do_ext_prog(struct ticket_config *tk, int start_election) ++static int do_ext_prog(struct booth_config *conf, struct ticket_config *tk, ++ int start_election) + { + int rv = 0; + +@@ -278,7 +281,7 @@ static int do_ext_prog(struct ticket_config *tk, int start_election) + rv = run_handler(tk); + if (rv == RUNCMD_ERR) { + tk_log_warn("couldn't run external test, not allowed to acquire ticket"); +- ext_prog_failed(tk, start_election); ++ ext_prog_failed(conf, tk, start_election); + } + break; + +@@ -290,7 +293,7 @@ static int do_ext_prog(struct ticket_config *tk, int start_election) + case EXTPROG_EXITED: + rv = tk_test_exit_status(tk); + if (rv) { +- ext_prog_failed(tk, start_election); ++ ext_prog_failed(conf, tk, start_election); + } + break; + +@@ -309,7 +312,8 @@ static int do_ext_prog(struct ticket_config *tk, int start_election) + * to start the program, and then to get the result and start + * elections. + */ +-static int acquire_ticket(struct ticket_config *tk, cmd_reason_t reason) ++static int acquire_ticket(struct booth_config *conf, struct ticket_config *tk, ++ cmd_reason_t reason) + { + int rv; + +@@ -317,7 +321,7 @@ static int acquire_ticket(struct ticket_config *tk, cmd_reason_t reason) + return RLT_ATTR_PREREQ; + } + +- switch(do_ext_prog(tk, 0)) { ++ switch(do_ext_prog(conf, tk, 0)) { + case 0: + /* everything fine */ + break; +@@ -331,9 +335,9 @@ static int acquire_ticket(struct ticket_config *tk, cmd_reason_t reason) + } + + if (is_manual(tk)) { +- rv = manual_selection(tk, local, 1, reason); ++ rv = manual_selection(conf, tk, local, 1, reason); + } else { +- rv = new_election(tk, local, 1, reason); ++ rv = new_election(conf, tk, local, 1, reason); + } + + return rv ? RLT_SYNC_FAIL : 0; +@@ -341,7 +345,8 @@ static int acquire_ticket(struct ticket_config *tk, cmd_reason_t reason) + + /** Try to get the ticket for the local site. + * */ +-static int do_grant_ticket(struct ticket_config *tk, int options) ++static int do_grant_ticket(struct booth_config *conf, struct ticket_config *tk, ++ int options) + { + int rv; + +@@ -373,7 +378,7 @@ static int do_grant_ticket(struct ticket_config *tk, int options) + time_reset(&tk->delay_commit); + } + +- rv = acquire_ticket(tk, OR_ADMIN); ++ rv = acquire_ticket(conf, tk, OR_ADMIN); + + if (rv) { + time_reset(&tk->delay_commit); +@@ -383,26 +388,26 @@ static int do_grant_ticket(struct ticket_config *tk, int options) + } + } + +-static void start_revoke_ticket(struct ticket_config *tk) ++static void start_revoke_ticket(struct booth_config *conf, struct ticket_config *tk) + { + tk_log_info("revoking ticket"); + + save_committed_tkt(tk); + reset_ticket_and_set_no_leader(tk); + ticket_write(tk); +- ticket_broadcast(tk, OP_REVOKE, OP_ACK, RLT_SUCCESS, OR_ADMIN); ++ ticket_broadcast(conf, tk, OP_REVOKE, OP_ACK, RLT_SUCCESS, OR_ADMIN); + } + + /** Ticket revoke. + * Only to be started from the leader. */ +-static int do_revoke_ticket(struct ticket_config *tk) ++static int do_revoke_ticket(struct booth_config *conf, struct ticket_config *tk) + { + if (tk->acks_expected) { + tk_log_info("delay ticket revoke until the current operation finishes"); + set_next_state(tk, ST_INIT); + return RLT_MORE; + } else { +- start_revoke_ticket(tk); ++ start_revoke_ticket(conf, tk); + return RLT_SUCCESS; + } + } +@@ -659,7 +664,7 @@ int setup_ticket(struct booth_config *conf) + /* wait until all send their status (or the first + * timeout) */ + tk->start_postpone = 1; +- ticket_broadcast(tk, OP_STATUS, OP_MY_INDEX, RLT_SUCCESS, 0); ++ ticket_broadcast(conf, tk, OP_STATUS, OP_MY_INDEX, RLT_SUCCESS, 0); + } + + return 0; +@@ -677,7 +682,7 @@ int ticket_answer_list(struct booth_config *conf, int fd) + } + + init_header(&hdr.header, CL_LIST, 0, 0, RLT_SUCCESS, 0, sizeof(hdr) + strlen(data)); +- rv = send_header_plus(fd, &hdr, data, strlen(data)); ++ rv = send_header_plus(conf, fd, &hdr, data, strlen(data)); + + out: + if (data != NULL) { +@@ -727,9 +732,9 @@ int process_client_request(struct booth_config *conf, struct client *req_client, + } + + if (cmd == CMD_REVOKE) { +- rv = do_revoke_ticket(tk); ++ rv = do_revoke_ticket(conf, tk); + } else { +- rv = do_grant_ticket(tk, ntohl(msg->header.options)); ++ rv = do_grant_ticket(conf, tk, ntohl(msg->header.options)); + } + + if (rv == RLT_MORE) { +@@ -743,7 +748,7 @@ int process_client_request(struct booth_config *conf, struct client *req_client, + + reply_now: + init_ticket_msg(&omsg, CL_RESULT, 0, rv, 0, tk); +- send_client_msg(req_client->fd, &omsg); ++ send_client_msg(conf, req_client->fd, &omsg); + return rc; + } + +@@ -770,7 +775,7 @@ int notify_client(struct booth_config *conf, struct ticket_config *tk, + tk_log_debug("notifying client %d (request %s)", + client_fd, state_to_string(cmd)); + init_ticket_msg(&omsg, CL_RESULT, 0, rv, 0, tk); +- rc = send_client_msg(client_fd, &omsg); ++ rc = send_client_msg(conf, client_fd, &omsg); + + if (rc == 0 && (rv == RLT_MORE || + (rv == RLT_CIB_PENDING && (options & OPT_WAIT_COMMIT)))) { +@@ -798,9 +803,9 @@ int notify_client(struct booth_config *conf, struct ticket_config *tk, + } + } + +-int ticket_broadcast(struct ticket_config *tk, cmd_request_t cmd, +- cmd_request_t expected_reply, cmd_result_t res, +- cmd_reason_t reason) ++int ticket_broadcast(struct booth_config *conf, struct ticket_config *tk, ++ cmd_request_t cmd, cmd_request_t expected_reply, ++ cmd_result_t res, cmd_reason_t reason) + { + struct boothc_ticket_msg msg; + +@@ -817,7 +822,7 @@ int ticket_broadcast(struct ticket_config *tk, cmd_request_t cmd, + } + + ticket_activate_timeout(tk); +- return transport()->broadcast_auth(&msg, sendmsglen(&msg)); ++ return transport()->broadcast_auth(conf, &msg, sendmsglen(&msg)); + } + + /* update the ticket on the leader, write it to the CIB, and +@@ -839,7 +844,7 @@ int leader_update_ticket(struct booth_config *conf, struct ticket_config *tk) + get_time(&now); + copy_time(&now, &tk->last_renewal); + set_future_time(&tk->term_expires, tk->term_duration); +- rv = ticket_broadcast(tk, OP_UPDATE, OP_ACK, RLT_SUCCESS, 0); ++ rv = ticket_broadcast(conf, tk, OP_UPDATE, OP_ACK, RLT_SUCCESS, 0); + } + + if (tk->ticket_updated < 2) { +@@ -897,7 +902,7 @@ static void resend_msg(struct booth_config *conf, struct ticket_config *tk) + int i; + + if (!(tk->acks_received ^ local->bitmask)) { +- ticket_broadcast(tk, tk->last_request, 0, RLT_SUCCESS, 0); ++ ticket_broadcast(conf, tk, tk->last_request, 0, RLT_SUCCESS, 0); + } else { + FOREACH_NODE(conf, i, n) { + if (tk->acks_received & n->bitmask) { +@@ -908,7 +913,7 @@ static void resend_msg(struct booth_config *conf, struct ticket_config *tk) + tk_log_debug("resending %s to %s", + state_to_string(tk->last_request), + site_string(n)); +- send_msg(tk->last_request, tk, n, NULL); ++ send_msg(conf, tk->last_request, tk, n, NULL); + } + + ticket_activate_timeout(tk); +@@ -974,20 +979,20 @@ static void process_next_state(struct booth_config *conf, struct ticket_config * + break; + } + +- rv = acquire_ticket(tk, OR_ADMIN); ++ rv = acquire_ticket(conf, tk, OR_ADMIN); + if (rv != 0) { /* external program failed */ + tk->outcome = rv; + foreach_tkt_req(conf, tk, notify_client); + } + } else { + log_reacquire_reason(tk); +- acquire_ticket(tk, OR_REACQUIRE); ++ acquire_ticket(conf, tk, OR_REACQUIRE); + } + break; + + case ST_INIT: + no_resends(tk); +- start_revoke_ticket(tk); ++ start_revoke_ticket(conf, tk); + tk->outcome = RLT_SUCCESS; + foreach_tkt_req(conf, tk, notify_client); + break; +@@ -1043,7 +1048,7 @@ static void next_action(struct booth_config *conf, struct ticket_config *tk) + /* and rebroadcast if stepping down */ + /* try to acquire ticket on grant */ + if (has_extprog_exited(tk)) { +- rv = acquire_ticket(tk, OR_ADMIN); ++ rv = acquire_ticket(conf, tk, OR_ADMIN); + if (rv != 0) { /* external program failed */ + tk->outcome = rv; + foreach_tkt_req(conf, tk, notify_client); +@@ -1068,7 +1073,7 @@ static void next_action(struct booth_config *conf, struct ticket_config *tk) + + if (!tk->voted_for || !tk->in_election) { + disown_ticket(tk); +- if (!new_election(tk, NULL, 1, OR_AGAIN)) { ++ if (!new_election(conf, tk, NULL, 1, OR_AGAIN)) { + ticket_activate_timeout(tk); + } + } else { +@@ -1082,7 +1087,7 @@ static void next_action(struct booth_config *conf, struct ticket_config *tk) + * in the Follower state (because we may end up having + * two Leaders) */ + if (has_extprog_exited(tk)) { +- rv = acquire_ticket(tk, OR_ADMIN); ++ rv = acquire_ticket(conf, tk, OR_ADMIN); + if (rv != 0) { /* external program failed */ + tk->outcome = rv; + foreach_tkt_req(conf, tk, notify_client); +@@ -1108,9 +1113,9 @@ static void next_action(struct booth_config *conf, struct ticket_config *tk) + if (majority_of_bits(tk, tk->acks_received)) { + leader_update_ticket(conf, tk); + } +- } else if (!do_ext_prog(tk, 1)) { ++ } else if (!do_ext_prog(conf, tk, 1)) { + /* this is ticket renewal, run local test */ +- ticket_broadcast(tk, OP_HEARTBEAT, OP_ACK, RLT_SUCCESS, 0); ++ ticket_broadcast(conf, tk, OP_HEARTBEAT, OP_ACK, RLT_SUCCESS, 0); + tk->ticket_updated = 0; + } + +@@ -1401,19 +1406,20 @@ char *state_to_string(uint32_t state_ho) + return cur->c; + } + +-int send_reject(struct booth_site *dest, struct ticket_config *tk, +- cmd_result_t code, struct boothc_ticket_msg *in_msg) ++int send_reject(struct booth_config *conf, struct booth_site *dest, ++ struct ticket_config *tk, cmd_result_t code, ++ struct boothc_ticket_msg *in_msg) + { + int req = ntohl(in_msg->header.cmd); + struct boothc_ticket_msg msg; + + tk_log_debug("sending reject to %s", site_string(dest)); + init_ticket_msg(&msg, OP_REJECTED, req, code, 0, tk); +- return booth_udp_send_auth(dest, &msg, sendmsglen(&msg)); ++ return booth_udp_send_auth(conf, dest, &msg, sendmsglen(&msg)); + } + +-int send_msg(int cmd, struct ticket_config *tk, struct booth_site *dest, +- struct boothc_ticket_msg *in_msg) ++int send_msg(struct booth_config *conf, int cmd, struct ticket_config *tk, ++ struct booth_site *dest, struct boothc_ticket_msg *in_msg) + { + int req = 0; + struct ticket_config *valid_tk = tk; +@@ -1436,5 +1442,5 @@ int send_msg(int cmd, struct ticket_config *tk, struct booth_site *dest, + } + + init_ticket_msg(&msg, cmd, req, RLT_SUCCESS, 0, valid_tk); +- return booth_udp_send_auth(dest, &msg, sendmsglen(&msg)); ++ return booth_udp_send_auth(conf, dest, &msg, sendmsglen(&msg)); + } +diff --git a/src/ticket.h b/src/ticket.h +index 22e7215..51e18b6 100644 +--- a/src/ticket.h ++++ b/src/ticket.h +@@ -208,10 +208,32 @@ void process_tickets(struct booth_config *conf); + void tickets_log_info(struct booth_config *conf); + + char *state_to_string(uint32_t state_ho); +-int send_reject(struct booth_site *dest, struct ticket_config *tk, +- cmd_result_t code, struct boothc_ticket_msg *in_msg); +-int send_msg (int cmd, struct ticket_config *tk, +- struct booth_site *dest, struct boothc_ticket_msg *in_msg); ++ ++/** ++ * @internal ++ * For a given ticket and recipient site, send a rejection ++ * ++ * @param[in,out] conf config object to refer to ++ * @param[in] dest site structure of the recipient ++ * @param[in] tk ticket at hand ++ * @param[in] code further detail for the rejection ++ * @param[in] in_msg message this is going to be a response to ++ */ ++int send_reject(struct booth_config *conf, struct booth_site *dest, ++ struct ticket_config *tk, cmd_result_t code, ++ struct boothc_ticket_msg *in_msg); ++ ++/** ++ * @internal ++ * For a given ticket, recipient site and possibly its message, send a response ++ * ++ * @param[in,out] conf config object to refer to ++ * @param[in] cmd what type of message is to be sent ++ * @param[in] dest site structure of the recipient ++ * @param[in] in_msg message this is going to be a response to ++ */ ++int send_msg(struct booth_config *conf, int cmd, struct ticket_config *tk, ++ struct booth_site *dest, struct boothc_ticket_msg *in_msg); + + /** + * @internal +@@ -225,7 +247,9 @@ int send_msg (int cmd, struct ticket_config *tk, + int notify_client(struct booth_config *conf, struct ticket_config *tk, + int client_fd, struct boothc_ticket_msg *msg); + +-int ticket_broadcast(struct ticket_config *tk, cmd_request_t cmd, cmd_request_t expected_reply, cmd_result_t res, cmd_reason_t reason); ++int ticket_broadcast(struct booth_config *conf, struct ticket_config *tk, ++ cmd_request_t cmd, cmd_request_t expected_reply, ++ cmd_result_t res, cmd_reason_t reason); + + int leader_update_ticket(struct booth_config *conf, struct ticket_config *tk); + void add_random_delay(struct ticket_config *tk); +diff --git a/src/transport.c b/src/transport.c +index d93c685..63f3acc 100644 +--- a/src/transport.c ++++ b/src/transport.c +@@ -501,7 +501,7 @@ static void process_connection(struct booth_config *conf, int ci) + + send_err: + init_header(&err_reply.header, CL_RESULT, 0, 0, errc, 0, sizeof(err_reply)); +- send_client_msg(req_cl->fd, &err_reply); ++ send_client_msg(conf, req_cl->fd, &err_reply); + + kill: + deadfn = req_cl->deadfn; +@@ -660,7 +660,7 @@ done: + return 0; + } + +-int booth_tcp_open(struct booth_site *to) ++static int booth_tcp_open(struct booth_site *to) + { + int s, rv; + +@@ -695,13 +695,42 @@ error: + return -1; + } + +-int booth_tcp_send(struct booth_site *to, void *buf, int len) ++/* data + (datalen-sizeof(struct hmac)) points to struct hmac ++ * i.e. struct hmac is always tacked on the payload ++ */ ++static int add_hmac(struct booth_config *conf, void *data, int len) ++{ ++ int rv = 0; ++#if HAVE_LIBGNUTLS || HAVE_LIBGCRYPT || HAVE_LIBMHASH ++ int payload_len; ++ struct hmac *hp; ++ ++ if (!is_auth_req()) { ++ return 0; ++ } ++ ++ payload_len = len - sizeof(struct hmac); ++ hp = (struct hmac *)((unsigned char *)data + payload_len); ++ hp->hid = htonl(BOOTH_HASH); ++ memset(hp->hash, 0, BOOTH_MAC_SIZE); ++ rv = calc_hmac(data, payload_len, BOOTH_HASH, hp->hash, ++ conf->authkey, conf->authkey_len); ++ if (rv < 0) { ++ log_error("internal error: cannot calculate mac"); ++ } ++#endif ++ return rv; ++} ++ ++static int booth_tcp_send(struct booth_config *conf, struct booth_site *to, ++ void *buf, int len) + { + int rv; + +- rv = add_hmac(buf, len); +- if (!rv) ++ rv = add_hmac(conf, buf, len); ++ if (!rv) { + rv = do_write(to->tcp_fd, buf, len); ++ } + + return rv; + } +@@ -856,7 +885,8 @@ static int booth_udp_init(void *f) + return 0; + } + +-int booth_udp_send(struct booth_site *to, void *buf, int len) ++static int booth_udp_send(struct booth_config *conf, struct booth_site *to, ++ void *buf, int len) + { + int rv; + +@@ -881,35 +911,40 @@ int booth_udp_send(struct booth_site *to, void *buf, int len) + return rv; + } + +-int booth_udp_send_auth(struct booth_site *to, void *buf, int len) ++int booth_udp_send_auth(struct booth_config *conf, struct booth_site *to, ++ void *buf, int len) + { + int rv; + +- rv = add_hmac(buf, len); +- if (rv < 0) ++ rv = add_hmac(conf, buf, len); ++ if (rv < 0) { + return rv; +- return booth_udp_send(to, buf, len); ++ } ++ ++ return booth_udp_send(conf, to, buf, len); + } + +-static int booth_udp_broadcast_auth(void *buf, int len) ++static int booth_udp_broadcast_auth(struct booth_config *conf, void *buf, int len) + { + int i, rv, rvs; + struct booth_site *site; + +- +- if (!booth_conf || !booth_conf->site_count) ++ if (!conf || !conf->site_count) { + return -1; ++ } + +- rv = add_hmac(buf, len); +- if (rv < 0) ++ rv = add_hmac(conf, buf, len); ++ if (rv < 0) { + return rv; ++ } + + rvs = 0; +- _FOREACH_NODE(i, site) { ++ FOREACH_NODE(conf, i, site) { + if (site != local) { +- rv = booth_udp_send(site, buf, len); +- if (!rvs) ++ rv = booth_udp_send(conf, site, buf, len); ++ if (!rvs) { + rvs = rv; ++ } + } + } + +@@ -927,7 +962,8 @@ static int booth_sctp_init(void *f __attribute__((unused))) + return 0; + } + +-static int booth_sctp_send(struct booth_site * to __attribute__((unused)), ++static int booth_sctp_send(struct booth_config *conf __attribute__((unused)), ++ struct booth_site *to __attribute__((unused)), + void *buf __attribute__((unused)), + int len __attribute__((unused))) + { +@@ -980,32 +1016,6 @@ const struct booth_transport booth_transport[TRANSPORT_ENTRIES] = { + } + }; + +-/* data + (datalen-sizeof(struct hmac)) points to struct hmac +- * i.e. struct hmac is always tacked on the payload +- */ +-int add_hmac(void *data, int len) +-{ +- int rv = 0; +-#if HAVE_LIBGNUTLS || HAVE_LIBGCRYPT || HAVE_LIBMHASH +- int payload_len; +- struct hmac *hp; +- +- if (!is_auth_req()) +- return 0; +- +- payload_len = len - sizeof(struct hmac); +- hp = (struct hmac *)((unsigned char *)data + payload_len); +- hp->hid = htonl(BOOTH_HASH); +- memset(hp->hash, 0, BOOTH_MAC_SIZE); +- rv = calc_hmac(data, payload_len, BOOTH_HASH, hp->hash, +- booth_conf->authkey, booth_conf->authkey_len); +- if (rv < 0) { +- log_error("internal error: cannot calculate mac"); +- } +-#endif +- return rv; +-} +- + #if HAVE_LIBGNUTLS || HAVE_LIBGCRYPT || HAVE_LIBMHASH + + /* TODO: we need some client identification for logging */ +@@ -1086,25 +1096,28 @@ int check_auth(struct booth_site *from, void *buf, int len) + return rv; + } + +-int send_data(int fd, void *data, int datalen) ++int send_data(struct booth_config *conf, int fd, void *data, int datalen) + { + int rv = 0; + +- rv = add_hmac(data, datalen); +- if (!rv) ++ rv = add_hmac(conf, data, datalen); ++ if (!rv) { + rv = do_write(fd, data, datalen); ++ } + + return rv; + } + +-int send_header_plus(int fd, struct boothc_hdr_msg *msg, void *data, int len) ++int send_header_plus(struct booth_config *conf, int fd, ++ struct boothc_hdr_msg *msg, void *data, int len) + { + int rv; + +- rv = send_data(fd, msg, sendmsglen(msg)-len); ++ rv = send_data(conf, fd, msg, sendmsglen(msg)-len); + +- if (rv >= 0 && len) ++ if (rv >= 0 && len) { + rv = do_write(fd, data, len); ++ } + + return rv; + } +diff --git a/src/transport.h b/src/transport.h +index 4f4d497..2784ce4 100644 +--- a/src/transport.h ++++ b/src/transport.h +@@ -47,12 +47,12 @@ struct booth_transport { + const char *name; + int (*init) (void *); + int (*open) (struct booth_site *); +- int (*send) (struct booth_site *, void *, int); +- int (*send_auth) (struct booth_site *, void *, int); ++ int (*send) (struct booth_config *, struct booth_site *, void *, int); ++ int (*send_auth) (struct booth_config *, struct booth_site *, void *, int); + int (*recv) (struct booth_site *, void *, int); + int (*recv_auth) (struct booth_site *, void *, int); + int (*broadcast) (void *, int); +- int (*broadcast_auth) (void *, int); ++ int (*broadcast_auth) (struct booth_config *, void *, int); + int (*close) (struct booth_site *); + int (*exit) (void); + }; +@@ -76,11 +76,20 @@ int read_client(struct client *req_cl); + int check_boothc_header(struct boothc_header *data, int len_incl_data); + + int setup_tcp_listener(int test_only); +-int booth_udp_send(struct booth_site *to, void *buf, int len); +-int booth_udp_send_auth(struct booth_site *to, void *buf, int len); + +-int booth_tcp_open(struct booth_site *to); +-int booth_tcp_send(struct booth_site *to, void *buf, int len); ++/** ++ * @internal ++ * Send data, with authentication added ++ * ++ * @param[in,out] conf config object to refer to ++ * @param[in] to site structure of the recipient ++ * @param[in] buf message itself ++ * @param[in] len length of #buf ++ * ++ * @return see @add_hmac and @booth_udp_send ++ */ ++int booth_udp_send_auth(struct booth_config *conf, struct booth_site *to, ++ void *buf, int len); + + /** + * @internal +@@ -102,11 +111,36 @@ inline static void * node_to_addr_pointer(struct booth_site *node) { + return NULL; + } + +-int send_data(int fd, void *data, int datalen); +-int send_header_plus(int fd, struct boothc_hdr_msg *hdr, void *data, int len); +-#define send_client_msg(fd, msg) send_data(fd, msg, sendmsglen(msg)) ++/** ++ * @internal ++ * Send data, with authentication added ++ * ++ * @param[in,out] conf config object to refer to ++ * @param[in] fd descriptor of the socket to respond to ++ * @param[in] data message itself ++ * @param[in] datalen length of #data ++ * ++ * @return 0 on success or negative value (-1 or -errno) on error ++ */ ++int send_data(struct booth_config *conf, int fd, void *data, int datalen); ++ ++/** ++ * @internal ++ * First stage of incoming datagram handling (authentication) ++ * ++ * @param[in,out] conf config object to refer to ++ * @param[in] fd descriptor of the socket to respond to ++ * @param[in] hdr message header ++ * @param[in] data message itself ++ * @param[in] len length of @data ++ * ++ * @return see #send_data and #do_write ++ */ ++int send_header_plus(struct booth_config *conf, int fd, ++ struct boothc_hdr_msg *hdr, void *data, int len); ++ ++#define send_client_msg(conf, fd, msg) send_data(conf, fd, msg, sendmsglen(msg)) + +-int add_hmac(void *data, int len); + int check_auth(struct booth_site *from, void *buf, int len); + + #endif /* _TRANSPORT_H */ +-- +2.25.1 + diff --git a/backport-Refactor-Remove-global-booth_conf-variable-from-noti.patch b/backport-Refactor-Remove-global-booth_conf-variable-from-noti.patch new file mode 100644 index 0000000..6b142b8 --- /dev/null +++ b/backport-Refactor-Remove-global-booth_conf-variable-from-noti.patch @@ -0,0 +1,355 @@ +From 9c4f8abdd8cb7c2d17080271f804b236c5f16476 Mon Sep 17 00:00:00 2001 +From: Chris Lumens +Date: Fri, 25 Oct 2024 10:56:54 -0400 +Subject: [PATCH 1/3] Refactor: Remove global booth_conf variable from + notify_client. + +This also requires modifying foreach_tkt_req to take a config variable +as well. + +Co-authored-by: Jan Pokorny +--- + src/raft.c | 39 +++++++++++++++------------------------ + src/raft.h | 9 ++++----- + src/request.c | 5 +++-- + src/request.h | 19 ++++++++++++++++--- + src/ticket.c | 28 ++++++++++++++-------------- + src/ticket.h | 17 ++++++++++++++--- + 6 files changed, 66 insertions(+), 51 deletions(-) + +diff --git a/src/raft.c b/src/raft.c +index ec0cf99..f63f14e 100644 +--- a/src/raft.c ++++ b/src/raft.c +@@ -210,7 +210,7 @@ static struct booth_site *majority_votes(struct ticket_config *tk) + } + + +-void elections_end(struct ticket_config *tk) ++void elections_end(struct booth_config *conf, struct ticket_config *tk) + { + struct booth_site *new_leader; + +@@ -230,7 +230,7 @@ void elections_end(struct ticket_config *tk) + } else { + tk_log_info("nobody won elections, new elections"); + tk->outcome = RLT_MORE; +- foreach_tkt_req(tk, notify_client); ++ foreach_tkt_req(conf, tk, notify_client); + if (!new_election(tk, NULL, is_tie(tk) ? 2 : 0, OR_AGAIN)) { + ticket_activate_timeout(tk); + } +@@ -433,12 +433,9 @@ static int process_REVOKE ( + + + /* For leader. */ +-static int process_ACK( +- struct ticket_config *tk, +- struct booth_site *sender, +- struct booth_site *leader, +- struct boothc_ticket_msg *msg +- ) ++static int process_ACK(struct booth_config *conf, struct ticket_config *tk, ++ struct booth_site *sender, struct booth_site *leader, ++ struct boothc_ticket_msg *msg) + { + uint32_t term; + int req; +@@ -478,7 +475,7 @@ static int process_ACK( + /* OK, at least half of the nodes are reachable; + * Update the ticket and send update messages out + */ +- return leader_update_ticket(tk); ++ return leader_update_ticket(conf, tk); + } + } + +@@ -486,12 +483,9 @@ static int process_ACK( + } + + +-static int process_VOTE_FOR( +- struct ticket_config *tk, +- struct booth_site *sender, +- struct booth_site *leader, +- struct boothc_ticket_msg *msg +- ) ++static int process_VOTE_FOR(struct booth_config *conf, struct ticket_config *tk, ++ struct booth_site *sender, struct booth_site *leader, ++ struct boothc_ticket_msg *msg) + { + if (leader == no_leader) { + /* leader wants to step down? */ +@@ -533,7 +527,7 @@ static int process_VOTE_FOR( + * wait for timeout in ticket_cron */ + if (!tk->acks_expected) { + /* §5.2 */ +- elections_end(tk); ++ elections_end(conf, tk); + } + + return 0; +@@ -916,12 +910,9 @@ static int process_MY_INDEX ( + } + + +-int raft_answer( +- struct ticket_config *tk, +- struct booth_site *sender, +- struct booth_site *leader, +- struct boothc_ticket_msg *msg +- ) ++int raft_answer(struct booth_config *conf, struct ticket_config *tk, ++ struct booth_site *sender, struct booth_site *leader, ++ struct boothc_ticket_msg *msg) + { + int cmd, req; + int rv; +@@ -952,12 +943,12 @@ int raft_answer( + rv = answer_REQ_VOTE(tk, sender, leader, msg); + break; + case OP_VOTE_FOR: +- rv = process_VOTE_FOR(tk, sender, leader, msg); ++ rv = process_VOTE_FOR(conf, tk, sender, leader, msg); + break; + case OP_ACK: + if (tk->leader == local && + tk->state == ST_LEADER) +- rv = process_ACK(tk, sender, leader, msg); ++ rv = process_ACK(conf, tk, sender, leader, msg); + break; + case OP_HEARTBEAT: + if ((tk->leader != local || !term_time_left(tk)) && +diff --git a/src/raft.h b/src/raft.h +index 0e01b48..9e52d8d 100644 +--- a/src/raft.h ++++ b/src/raft.h +@@ -30,14 +30,13 @@ typedef enum { + + struct ticket_config; + +-int raft_answer(struct ticket_config *tk, +- struct booth_site *from, +- struct booth_site *leader, +- struct boothc_ticket_msg *msg); ++int raft_answer(struct booth_config *conf, struct ticket_config *tk, ++ struct booth_site *from, struct booth_site *leader, ++ struct boothc_ticket_msg *msg); + + int new_election(struct ticket_config *tk, + struct booth_site *new_leader, int update_term, cmd_reason_t reason); +-void elections_end(struct ticket_config *tk); ++void elections_end(struct booth_config *conf, struct ticket_config *tk); + + + #endif /* _RAFT_H */ +diff --git a/src/request.c b/src/request.c +index 2503f6c..d7ff5f9 100644 +--- a/src/request.c ++++ b/src/request.c +@@ -64,7 +64,8 @@ static void del_req(GList *lp) + req_l = g_list_delete_link(req_l, lp); + } + +-void foreach_tkt_req(struct ticket_config *tk, req_fp f) ++void foreach_tkt_req(struct booth_config *conf, struct ticket_config *tk, ++ req_fp f) + { + GList *lp, *next; + struct request *rp; +@@ -74,7 +75,7 @@ void foreach_tkt_req(struct ticket_config *tk, req_fp f) + next = g_list_next(lp); + rp = (struct request *)lp->data; + if (rp->tk == tk && +- (f)(rp->tk, rp->client_fd, rp->msg) == 0) { ++ (f)(conf, rp->tk, rp->client_fd, rp->msg) == 0) { + log_debug("remove request for client %d", rp->client_fd); + del_req(lp); /* don't need this request anymore */ + } +diff --git a/src/request.h b/src/request.h +index c014a09..2b25ca7 100644 +--- a/src/request.h ++++ b/src/request.h +@@ -44,12 +44,25 @@ struct request { + void *msg; + }; + +-typedef int (*req_fp)( +- struct ticket_config *, int, struct boothc_ticket_msg *); ++typedef int (*req_fp)(struct booth_config *, struct ticket_config *, int, ++ struct boothc_ticket_msg *); + + void *add_req(struct ticket_config *tk, struct client *req_client, + struct boothc_ticket_msg *msg); +-void foreach_tkt_req(struct ticket_config *tk, req_fp f); ++ ++/** ++ * @internal ++ * Handle all pending requests for given ticket using function @p f ++ * ++ * @param[in,out] conf config object to refer to ++ * @param[in] tk ticket at hand ++ * @param[in] f handling function ++ * ++ * @return 1 on success, 0 when not done with the message, yet ++ */ ++void foreach_tkt_req(struct booth_config *conf, struct ticket_config *tk, ++ req_fp f); ++ + int get_req_id(const void *rp); + + #endif /* _REQUEST_H */ +diff --git a/src/ticket.c b/src/ticket.c +index c9147d8..e668ce0 100644 +--- a/src/ticket.c ++++ b/src/ticket.c +@@ -747,8 +747,8 @@ reply_now: + return rc; + } + +-int notify_client(struct ticket_config *tk, int client_fd, +- struct boothc_ticket_msg *msg) ++int notify_client(struct booth_config *conf, struct ticket_config *tk, ++ int client_fd, struct boothc_ticket_msg *msg) + { + struct boothc_ticket_msg omsg; + void (*deadfn) (int ci); +@@ -824,7 +824,7 @@ int ticket_broadcast(struct ticket_config *tk, cmd_request_t cmd, + send out the update message to others with the new expiry + time + */ +-int leader_update_ticket(struct ticket_config *tk) ++int leader_update_ticket(struct booth_config *conf, struct ticket_config *tk) + { + int rv = 0, rv2; + timetype now; +@@ -848,13 +848,13 @@ int leader_update_ticket(struct ticket_config *tk) + case 0: + tk->ticket_updated = 2; + tk->outcome = RLT_SUCCESS; +- foreach_tkt_req(tk, notify_client); ++ foreach_tkt_req(conf, tk, notify_client); + break; + + case 1: + if (tk->outcome != RLT_CIB_PENDING) { + tk->outcome = RLT_CIB_PENDING; +- foreach_tkt_req(tk, notify_client); ++ foreach_tkt_req(conf, tk, notify_client); + } + break; + +@@ -963,7 +963,7 @@ static int postpone_ticket_processing(struct ticket_config *tk) + + #define has_extprog_exited(tk) ((tk)->clu_test.progstate == EXTPROG_EXITED) + +-static void process_next_state(struct ticket_config *tk) ++static void process_next_state(struct booth_config *conf, struct ticket_config *tk) + { + int rv; + +@@ -977,7 +977,7 @@ static void process_next_state(struct ticket_config *tk) + rv = acquire_ticket(tk, OR_ADMIN); + if (rv != 0) { /* external program failed */ + tk->outcome = rv; +- foreach_tkt_req(tk, notify_client); ++ foreach_tkt_req(conf, tk, notify_client); + } + } else { + log_reacquire_reason(tk); +@@ -989,7 +989,7 @@ static void process_next_state(struct ticket_config *tk) + no_resends(tk); + start_revoke_ticket(tk); + tk->outcome = RLT_SUCCESS; +- foreach_tkt_req(tk, notify_client); ++ foreach_tkt_req(conf, tk, notify_client); + break; + + /* wanting to be follower is not much of an ambition; no +@@ -1046,7 +1046,7 @@ static void next_action(struct booth_config *conf, struct ticket_config *tk) + rv = acquire_ticket(tk, OR_ADMIN); + if (rv != 0) { /* external program failed */ + tk->outcome = rv; +- foreach_tkt_req(tk, notify_client); ++ foreach_tkt_req(conf, tk, notify_client); + } + } else { + if (tk->acks_expected) { +@@ -1085,7 +1085,7 @@ static void next_action(struct booth_config *conf, struct ticket_config *tk) + rv = acquire_ticket(tk, OR_ADMIN); + if (rv != 0) { /* external program failed */ + tk->outcome = rv; +- foreach_tkt_req(tk, notify_client); ++ foreach_tkt_req(conf, tk, notify_client); + } + } else { + /* Otherwise, just send ACKs if needed */ +@@ -1098,7 +1098,7 @@ static void next_action(struct booth_config *conf, struct ticket_config *tk) + + case ST_CANDIDATE: + /* elections timed out? */ +- elections_end(tk); ++ elections_end(conf, tk); + break; + + case ST_LEADER: +@@ -1106,7 +1106,7 @@ static void next_action(struct booth_config *conf, struct ticket_config *tk) + if (tk->acks_expected) { + handle_resends(conf, tk); + if (majority_of_bits(tk, tk->acks_received)) { +- leader_update_ticket(tk); ++ leader_update_ticket(conf, tk); + } + } else if (!do_ext_prog(tk, 1)) { + /* this is ticket renewal, run local test */ +@@ -1143,7 +1143,7 @@ static void ticket_cron(struct booth_config *conf, struct ticket_config *tk) + * also used for revokes which had to be delayed + */ + if (tk->next_state) { +- process_next_state(tk); ++ process_next_state(conf, tk); + goto out; + } + +@@ -1257,7 +1257,7 @@ int ticket_recv(struct booth_config *conf, void *buf, struct booth_site *source) + } + + update_acks(tk, source, leader, msg); +- return raft_answer(tk, source, leader, msg); ++ return raft_answer(conf, tk, source, leader, msg); + } + + static void log_next_wakeup(struct ticket_config *tk) +diff --git a/src/ticket.h b/src/ticket.h +index 454ebaf..22e7215 100644 +--- a/src/ticket.h ++++ b/src/ticket.h +@@ -212,11 +212,22 @@ int send_reject(struct booth_site *dest, struct ticket_config *tk, + cmd_result_t code, struct boothc_ticket_msg *in_msg); + int send_msg (int cmd, struct ticket_config *tk, + struct booth_site *dest, struct boothc_ticket_msg *in_msg); +-int notify_client(struct ticket_config *tk, int client_fd, +- struct boothc_ticket_msg *msg); ++ ++/** ++ * @internal ++ * Notify client at particular socket, regarding particular ticket ++ * ++ * @param[in,out] conf config object to refer to ++ * @param[in] tk ticket at hand ++ * @param[in] fd file descriptor of the socket to respond to ++ * @param[in] msg input message being responded to ++ */ ++int notify_client(struct booth_config *conf, struct ticket_config *tk, ++ int client_fd, struct boothc_ticket_msg *msg); ++ + int ticket_broadcast(struct ticket_config *tk, cmd_request_t cmd, cmd_request_t expected_reply, cmd_result_t res, cmd_reason_t reason); + +-int leader_update_ticket(struct ticket_config *tk); ++int leader_update_ticket(struct booth_config *conf, struct ticket_config *tk); + void add_random_delay(struct ticket_config *tk); + void schedule_election(struct ticket_config *tk, cmd_reason_t reason); + +-- +2.25.1 + diff --git a/booth.spec b/booth.spec index 2da809c..ed11166 100644 --- a/booth.spec +++ b/booth.spec @@ -24,7 +24,7 @@ %bcond_with run_build_tests %bcond_with include_unit_test -%global release 10 +%global release 11 ## User and group to use for nonprivileged services (should be in sync with pacemaker) %global uname hacluster @@ -74,6 +74,9 @@ Patch23: backport-Refactor-Remove-global-booth_conf-variable-in-ticket.pa Patch24: backport-Refactor-Mark-internal-functions-in-ticket.c-as-stat.patch #https://github.com/ClusterLabs/booth/pull/153/files Patch25: backport-Coding-style-improvements-to-ticket.c.patch +Patch26: backport-Refactor-Remove-global-booth_conf-variable-from-noti.patch +Patch27: backport-Refactor-Remove-global-booth_conf-variable-from-list.patch +Patch28: backport-Refactor-Remove-global-booth_conf-variable-from-netw.patch # direct build process dependencies BuildRequires: autoconf @@ -322,6 +325,9 @@ VERBOSE=1 make check %{_usr}/lib/ocf/resource.d/booth/sharedrsc %changelog +* Wed Oct 22 2025 bizhiyuan - 1.2-11 +- Remove global booth_conf variable from notify_client list_peers and network functions + * Mon Jun 30 2025 zouzhimin -1.2-10 - Coding style improvements to ticket.c -- Gitee