diff --git a/src/attr.c b/src/attr.c index daa7648b..086dc98d 100644 --- a/src/attr.c +++ b/src/attr.c @@ -149,7 +149,7 @@ static int read_server_reply( return rv; } -int do_attr_command(cmd_request_t cmd) +int do_attr_command(struct booth_config *conf, cmd_request_t cmd) { struct booth_site *site = NULL; struct boothc_header *header; @@ -160,7 +160,7 @@ int do_attr_command(cmd_request_t cmd) if (!*cl.site) site = local; else { - if (!find_site_by_name(cl.site, &site, 1)) { + if (!find_site_by_name(conf, cl.site, &site, 1)) { log_error("Site \"%s\" not configured.", cl.site); goto out_close; } diff --git a/src/attr.h b/src/attr.h index 1c680bdf..547d19a4 100644 --- a/src/attr.h +++ b/src/attr.h @@ -31,7 +31,18 @@ void print_geostore_usage(void); int test_attr_reply(cmd_result_t reply_code, cmd_request_t cmd); -int do_attr_command(cmd_request_t cmd); + +/** + * @internal + * Carry out a geo-atribute related command + * + * @param[in,out] conf config object to refer to + * @param[in] cmd what to perform + * + * @return 0 or negative value (-1 or -errno) on error + */ +int do_attr_command(struct booth_config *conf, cmd_request_t cmd); + int process_attr_request(struct client *req_client, void *buf); int attr_recv(void *buf, struct booth_site *source); int store_geo_attr(struct ticket_config *tk, const char *name, const char *val, int notime); diff --git a/src/booth.h b/src/booth.h index 0cd43c00..799cdf98 100644 --- a/src/booth.h +++ b/src/booth.h @@ -77,6 +77,10 @@ /* Says that another one should recover. */ #define TICKET_LOST CHAR2CONST('L', 'O', 'S', 'T') +struct booth_config; + +typedef void (*workfn_t)(struct booth_config *conf, int ci); + typedef char boothc_site[BOOTH_NAME_LEN]; typedef char boothc_ticket[BOOTH_NAME_LEN]; @@ -338,7 +342,7 @@ struct client { const struct booth_transport *transport; struct boothc_ticket_msg *msg; int offset; /* bytes read so far into msg */ - void (*workfn)(int); + workfn_t workfn; void (*deadfn)(int); }; @@ -347,7 +351,7 @@ extern struct pollfd *pollfds; int client_add(int fd, const struct booth_transport *tpt, - void (*workfn)(int ci), void (*deadfn)(int ci)); + workfn_t workfn, void (*deadfn)(int ci)); int find_client_by_fd(int fd); void safe_copy(char *dest, char *value, size_t buflen, const char *description); int update_authkey(void); diff --git a/src/config.c b/src/config.c index 0dcffdcf..4eafc359 100644 --- a/src/config.c +++ b/src/config.c @@ -991,16 +991,18 @@ int check_config(struct booth_config *conf, int type) } -static int get_other_site(struct booth_site **node) +static int get_other_site(struct booth_config *conf, + struct booth_site **node) { struct booth_site *n; int i; *node = NULL; - if (!booth_conf) + if (conf == NULL) { return 0; + } - FOREACH_NODE(i, n) { + FOREACH_NODE(conf, i, n) { if (n != local && n->type == SITE) { if (!*node) { *node = n; @@ -1014,18 +1016,21 @@ static int get_other_site(struct booth_site **node) } -int find_site_by_name(char *site, struct booth_site **node, int any_type) +int find_site_by_name(struct booth_config *conf, const char *site, + struct booth_site **node, int any_type) { struct booth_site *n; int i; - if (!booth_conf) + if (conf == NULL) { return 0; + } - if (!strcmp(site, OTHER_SITE)) - return get_other_site(node); + if (!strcmp(site, OTHER_SITE)) { + return get_other_site(conf, node); + } - FOREACH_NODE(i, n) { + FOREACH_NODE(conf, i, n) { if ((n->type == SITE || any_type) && strncmp(n->addr_string, site, sizeof(n->addr_string)) == 0) { *node = n; @@ -1036,7 +1041,8 @@ int find_site_by_name(char *site, struct booth_site **node, int any_type) return 0; } -int find_site_by_id(uint32_t site_id, struct booth_site **node) +int find_site_by_id(struct booth_config *conf, + uint32_t site_id, struct booth_site **node) { struct booth_site *n; int i; @@ -1046,10 +1052,11 @@ int find_site_by_id(uint32_t site_id, struct booth_site **node) return 1; } - if (!booth_conf) + if (conf == NULL) { return 0; + } - FOREACH_NODE(i, n) { + FOREACH_NODE(conf, i, n) { if (n->site_id == site_id) { *node = n; return 1; @@ -1059,7 +1066,6 @@ int find_site_by_id(uint32_t site_id, struct booth_site **node) return 0; } - const char *type_to_string(int type) { switch (type) diff --git a/src/config.h b/src/config.h index ad7aed2e..fbe90d16 100644 --- a/src/config.h +++ b/src/config.h @@ -25,6 +25,17 @@ #include "booth.h" #include "timer.h" #include "raft.h" + +/* Forward declaration of the booth config structure that will be defined later. + * This is necessary here because transport.h references booth_config, but this + * file also references transport_layer_t. We need some way to break the + * circular dependency. + * + * This also means that config.h must always be included before transport.h in + * any source files. + */ +struct booth_config; + #include "transport.h" @@ -355,8 +366,33 @@ int read_config(struct booth_config **conf, const char *path, int type); */ int check_config(struct booth_config *conf, int type); -int find_site_by_name(char *site, struct booth_site **node, int any_type); -int find_site_by_id(uint32_t site_id, struct booth_site **node); +/** + * @internal + * Find site in booth configuration by resolved host name + * + * @param[in,out] conf config object to refer to + * @param[in] site name to match against previously resolved host names + * @param[out] node relevant tracked data when found + * @param[in] any_type whether or not to consider also non-site members + * + * @return 0 if nothing found, or 1 when found (node assigned accordingly) + */ +int find_site_by_name(struct booth_config *conf, const char *site, + struct booth_site **node, int any_type); + + +/** + * @internal + * Find site in booth configuration by a hash (id) + * + * @param[in,out] conf config object to refer to + * @param[in] site_id hash (id) to match against previously resolved ones + * @param[out] node relevant tracked data when found + * + * @return 0 if nothing found, or 1 when found (node assigned accordingly) + */ +int find_site_by_id(struct booth_config *conf, uint32_t site_id, + struct booth_site **node); const char *type_to_string(int type); diff --git a/src/handler.c b/src/handler.c index 9d74f0f6..727b89cb 100644 --- a/src/handler.c +++ b/src/handler.c @@ -133,7 +133,7 @@ void wait_child(int sig) /* use waitpid(2) and not wait(2) in order not to interfere * with popen(2)/pclose(2) and system(2) used in pacemaker.c */ - FOREACH_TICKET(i, tk) { + _FOREACH_TICKET(i, tk) { if (tk_test.path && tk_test.pid > 0 && (tk_test.progstate == EXTPROG_RUNNING || tk_test.progstate == EXTPROG_IGNORE) && diff --git a/src/main.c b/src/main.c index 3ad0290f..c6f6bb6b 100644 --- a/src/main.c +++ b/src/main.c @@ -165,8 +165,7 @@ static void client_dead(int ci) } int client_add(int fd, const struct booth_transport *tpt, - void (*workfn)(int ci), - void (*deadfn)(int ci)) + workfn_t workfn, void (*deadfn)(int ci)) { int i; struct client *c; @@ -233,7 +232,7 @@ static int format_peers(char **pdata, unsigned int *len) return -ENOMEM; cp = data; - FOREACH_NODE(i, s) { + _FOREACH_NODE(i, s) { if (s == local) continue; strftime(time_str, sizeof(time_str), "%F %T", @@ -394,15 +393,15 @@ static int setup_config(struct booth_config **conf, int type) /* Set "local" pointer, ignoring errors. */ if (cl.type == DAEMON && cl.site[0]) { - if (!find_site_by_name(cl.site, &local, 1)) { + if (!find_site_by_name(booth_conf, cl.site, &local, 1)) { log_error("Cannot find \"%s\" in the configuration.", cl.site); return -EINVAL; } local->local = 1; - } else - find_myself(NULL, type == CLIENT || type == GEOSTORE); - + } else { + find_myself(booth_conf, NULL, type == CLIENT || type == GEOSTORE); + } rv = check_config(booth_conf, type); if (rv < 0) @@ -521,7 +520,7 @@ static int process_signals(void) static int loop(int fd) { - void (*workfn) (int ci); + workfn_t workfn; void (*deadfn) (int ci); int rv, i; @@ -529,9 +528,10 @@ static int loop(int fd) if (rv < 0) goto fail; - rv = setup_ticket(); - if (rv < 0) + rv = setup_ticket(booth_conf); + if (rv < 0) { goto fail; + } rv = write_daemon_state(fd, BOOTHD_STARTED); if (rv != 0) { @@ -559,8 +559,9 @@ static int loop(int fd) if (pollfds[i].revents & POLLIN) { workfn = clients[i].workfn; - if (workfn) - workfn(i); + if (workfn) { + workfn(booth_conf, i); + } } if (pollfds[i].revents & (POLLERR | POLLHUP | POLLNVAL)) { @@ -708,7 +709,7 @@ static int query_get_string_answer(cmd_request_t cmd) if (!*cl.site) site = local; - else if (!find_site_by_name(cl.site, &site, 1)) { + else if (!find_site_by_name(booth_conf, cl.site, &site, 1)) { log_error("cannot find site \"%s\"", cl.site); rv = ENOENT; goto out; @@ -782,7 +783,7 @@ static int do_command(cmd_request_t cmd) if (!*cl.site) site = local; else { - if (!find_site_by_name(cl.site, &site, 1)) { + if (!find_site_by_name(booth_conf, cl.site, &site, 1)) { log_error("Site \"%s\" not configured.", cl.site); goto out_close; } @@ -837,7 +838,7 @@ static int do_command(cmd_request_t cmd) if (rv == 1) { tpt->close(site); leader_id = ntohl(reply.ticket.leader); - if (!find_site_by_id(leader_id, &site)) { + if (!find_site_by_id(booth_conf, leader_id, &site)) { log_error("Message with unknown redirect site %x received", leader_id); rv = -1; goto out_close; @@ -1617,7 +1618,7 @@ static int do_attr(struct booth_config **conf) case ATTR_SET: case ATTR_DEL: - rv = do_attr_command(cl.op); + rv = do_attr_command(booth_conf, cl.op); break; } diff --git a/src/manual.c b/src/manual.c index ee9e858e..5fc5eebc 100644 --- a/src/manual.c +++ b/src/manual.c @@ -18,9 +18,9 @@ #include "manual.h" +#include "config.h" #include "transport.h" #include "ticket.h" -#include "config.h" #include "log.h" #include "request.h" diff --git a/src/pacemaker.c b/src/pacemaker.c index 084dd4cc..9febb087 100644 --- a/src/pacemaker.c +++ b/src/pacemaker.c @@ -151,8 +151,8 @@ static int pcmk_del_attr(struct ticket_config *tk, const char *attr) } -typedef int (*attr_f)(struct ticket_config *tk, const char *name, - const char *val); +typedef int (*attr_f)(struct booth_config *conf, struct ticket_config *tk, + const char *name, const char *val); struct attr_tab { @@ -160,15 +160,15 @@ struct attr_tab attr_f handling_f; }; -static int save_expires(struct ticket_config *tk, const char *name, - const char *val) +static int save_expires(struct booth_config *conf, struct ticket_config *tk, + const char *name, const char *val) { secs2tv(unwall_ts(atol(val)), &tk->term_expires); return 0; } -static int save_term(struct ticket_config *tk, const char *name, - const char *val) +static int save_term(struct booth_config *conf, struct ticket_config *tk, + const char *name, const char *val) { tk->current_term = atol(val); return 0; @@ -188,23 +188,23 @@ static int parse_boolean(const char *val) return v; } -static int save_granted(struct ticket_config *tk, const char *name, - const char *val) +static int save_granted(struct booth_config *conf, struct ticket_config *tk, + const char *name, const char *val) { tk->is_granted = parse_boolean(val); return 0; } -static int save_owner(struct ticket_config *tk, const char *name, - const char *val) +static int save_owner(struct booth_config *conf, struct ticket_config *tk, + const char *name, const char *val) { /* No check, node could have been deconfigured. */ tk->leader = NULL; - return !find_site_by_id(atol(val), &tk->leader); + return !find_site_by_id(conf, atol(val), &tk->leader); } -static int ignore_attr(struct ticket_config *tk, const char *name, - const char *val) +static int ignore_attr(struct booth_config *conf, struct ticket_config *tk, + const char *name, const char *val) { return 0; } @@ -276,7 +276,8 @@ static int pcmk_get_attr(struct ticket_config *tk, const char *attr, const char return rv | pipe_rv; } -static int save_attributes(struct ticket_config *tk, xmlDocPtr doc) +static int save_attributes(struct booth_config *conf, struct ticket_config *tk, + xmlDocPtr doc) { int rv = 0, rc; xmlNodePtr n; @@ -297,7 +298,8 @@ static int save_attributes(struct ticket_config *tk, xmlDocPtr doc) v = xmlGetProp(n, attr->name); for (atp = attr_handlers; atp->name; atp++) { if (!strcmp(atp->name, (const char *) attr->name)) { - rc = atp->handling_f(tk, (const char *) attr->name, + rc = atp->handling_f(conf, tk, + (const char *) attr->name, (const char *) v); break; } @@ -318,7 +320,8 @@ static int save_attributes(struct ticket_config *tk, xmlDocPtr doc) #define CHUNK_SIZE 256 -static int parse_ticket_state(struct ticket_config *tk, FILE *p) +static int parse_ticket_state(struct booth_config *conf, struct ticket_config *tk, + FILE *p) { int rv = 0; GString *input = NULL; @@ -359,7 +362,7 @@ static int parse_ticket_state(struct ticket_config *tk, FILE *p) rv = -EINVAL; goto out; } - rv = save_attributes(tk, doc); + rv = save_attributes(conf, tk, doc); out: if (doc) @@ -369,7 +372,7 @@ static int parse_ticket_state(struct ticket_config *tk, FILE *p) return rv; } -static int pcmk_load_ticket(struct ticket_config *tk) +static int pcmk_load_ticket(struct booth_config *conf, struct ticket_config *tk) { char cmd[COMMAND_MAX]; int rv = 0, pipe_rv; @@ -393,7 +396,7 @@ static int pcmk_load_ticket(struct ticket_config *tk) return (pipe_rv != 0 ? pipe_rv : EINVAL); } - rv = parse_ticket_state(tk, p); + rv = parse_ticket_state(conf, tk, p); if (!tk->leader) { /* Hmm, no site found for the ticket we have in the diff --git a/src/pacemaker.h b/src/pacemaker.h index 3a817245..412fe6f1 100644 --- a/src/pacemaker.h +++ b/src/pacemaker.h @@ -26,7 +26,7 @@ struct ticket_handler { int (*grant_ticket) (struct ticket_config *tk); int (*revoke_ticket) (struct ticket_config *tk); - int (*load_ticket) (struct ticket_config *tk); + int (*load_ticket) (struct booth_config *conf, struct ticket_config *tk); int (*set_attr) (struct ticket_config *tk, const char *a, const char *v); int (*get_attr) (struct ticket_config *tk, const char *a, const char **vp); int (*del_attr) (struct ticket_config *tk, const char *a); diff --git a/src/raft.c b/src/raft.c index dbe773c7..ec0cf99f 100644 --- a/src/raft.c +++ b/src/raft.c @@ -23,9 +23,9 @@ #include #include "booth.h" #include "timer.h" +#include "config.h" #include "transport.h" #include "inline-fn.h" -#include "config.h" #include "raft.h" #include "ticket.h" #include "request.h" @@ -40,7 +40,7 @@ inline static void clear_election(struct ticket_config *tk) tk_log_debug("clear election"); tk->votes_received = 0; - FOREACH_NODE(i, site) { + _FOREACH_NODE(i, site) { tk->votes_for[site->index] = NULL; } } diff --git a/src/ticket.c b/src/ticket.c index 1e2b50a0..353f080b 100644 --- a/src/ticket.c +++ b/src/ticket.c @@ -65,7 +65,7 @@ int find_ticket_by_name(const char *ticket, struct ticket_config **found) if (found) *found = NULL; - FOREACH_TICKET(i, tk) { + _FOREACH_TICKET(i, tk) { if (!strncmp(tk->name, ticket, sizeof(tk->name))) { if (found) *found = tk; @@ -390,7 +390,7 @@ int list_ticket(char **pdata, unsigned int *len) alloc = booth_conf->ticket_count * (BOOTH_NAME_LEN * 2 + 128 + 16); - FOREACH_TICKET(i, tk) { + _FOREACH_TICKET(i, tk) { multiple_grant_warning_length = number_sites_marked_as_granted(tk); if (multiple_grant_warning_length > 1) { @@ -404,7 +404,7 @@ int list_ticket(char **pdata, unsigned int *len) return -ENOMEM; cp = data; - FOREACH_TICKET(i, tk) { + _FOREACH_TICKET(i, tk) { if ((!is_manual(tk)) && is_time_set(&tk->term_expires)) { /* Manual tickets doesn't have term_expires defined */ ts = wall_ts(&tk->term_expires); @@ -452,7 +452,7 @@ int list_ticket(char **pdata, unsigned int *len) } } - FOREACH_TICKET(i, tk) { + _FOREACH_TICKET(i, tk) { multiple_grant_warning_length = number_sites_marked_as_granted(tk); if (multiple_grant_warning_length > 1) { @@ -461,7 +461,7 @@ int list_ticket(char **pdata, unsigned int *len) "\nWARNING: The ticket %s is granted to multiple sites: ", // ~55 characters tk->name); - FOREACH_NODE(site_index, site) { + _FOREACH_NODE(site_index, site) { if (tk->sites_where_granted[site_index] > 0) { cp += snprintf(cp, alloc - (cp - data), @@ -612,16 +612,16 @@ void update_ticket_state(struct ticket_config *tk, struct booth_site *sender) } } -int setup_ticket(void) +int setup_ticket(struct booth_config *conf) { struct ticket_config *tk; int i; - FOREACH_TICKET(i, tk) { + FOREACH_TICKET(conf, i, tk) { reset_ticket(tk); if (local->type == SITE) { - if (!pcmk_handler.load_ticket(tk)) { + if (!pcmk_handler.load_ticket(conf, tk)) { update_ticket_state(tk, NULL); } tk->update_cib = 1; @@ -844,7 +844,7 @@ static void log_lost_servers(struct ticket_config *tk) */ return; - FOREACH_NODE(i, n) { + _FOREACH_NODE(i, n) { if (!(tk->acks_received & n->bitmask)) { tk_log_warn("%s %s didn't acknowledge our %s, " "will retry %d times", @@ -864,7 +864,7 @@ static void resend_msg(struct ticket_config *tk) if (!(tk->acks_received ^ local->bitmask)) { ticket_broadcast(tk, tk->last_request, 0, RLT_SUCCESS, 0); } else { - FOREACH_NODE(i, n) { + _FOREACH_NODE(i, n) { if (!(tk->acks_received & n->bitmask)) { n->resend_cnt++; tk_log_debug("resending %s to %s", @@ -1128,7 +1128,7 @@ void process_tickets(void) int i; timetype last_cron; - FOREACH_TICKET(i, tk) { + _FOREACH_TICKET(i, tk) { if (!has_extprog_exited(tk) && is_time_set(&tk->next_cron) && !is_past(&tk->next_cron)) continue; @@ -1152,7 +1152,7 @@ void tickets_log_info(void) int i; time_t ts; - FOREACH_TICKET(i, tk) { + _FOREACH_TICKET(i, tk) { ts = wall_ts(&tk->term_expires); tk_log_info("state '%s' " "term %d " @@ -1197,7 +1197,7 @@ static void update_acks( } /* read ticket message */ -int ticket_recv(void *buf, struct booth_site *source) +int ticket_recv(struct booth_config *conf, void *buf, struct booth_site *source) { struct boothc_ticket_msg *msg; struct ticket_config *tk; @@ -1215,7 +1215,7 @@ int ticket_recv(void *buf, struct booth_site *source) leader_u = ntohl(msg->ticket.leader); - if (!find_site_by_id(leader_u, &leader)) { + if (!find_site_by_id(conf, leader_u, &leader)) { tk_log_error("message with unknown leader %u received", leader_u); source->invalid_cnt++; return -EINVAL; @@ -1350,7 +1350,7 @@ int number_sites_marked_as_granted(struct ticket_config *tk) int i, result = 0; struct booth_site *ignored __attribute__((unused)); - FOREACH_NODE(i, ignored) { + _FOREACH_NODE(i, ignored) { result += tk->sites_where_granted[i]; } diff --git a/src/ticket.h b/src/ticket.h index 805bcef2..f28ac6ec 100644 --- a/src/ticket.h +++ b/src/ticket.h @@ -35,12 +35,23 @@ extern int TIME_RES; #define DEFAULT_RETRIES 10 -#define FOREACH_TICKET(i_, t_) \ +#define FOREACH_TICKET(b_, i_, t_) \ + for (i_ = 0; \ + (t_ = (b_)->ticket + i_, i_ < (b_)->ticket_count); \ + i_++) + +#define FOREACH_NODE(b_, i_, n_) \ + for (i_ = 0; \ + (n_ = (b_)->site + i_, i_ < (b_)->site_count); \ + i_++) + + +#define _FOREACH_TICKET(i_, t_) \ for (i_ = 0; \ (t_ = booth_conf->ticket + i_, i_ < booth_conf->ticket_count); \ i_++) -#define FOREACH_NODE(i_, n_) \ +#define _FOREACH_NODE(i_, n_) \ for (i_ = 0; \ (n_ = booth_conf->site + i_, i_ < booth_conf->site_count); \ i_++) @@ -101,11 +112,32 @@ int grant_ticket(struct ticket_config *ticket); int revoke_ticket(struct ticket_config *ticket); int list_ticket(char **pdata, unsigned int *len); -int ticket_recv(void *buf, struct booth_site *source); +/** + * @internal + * Second stage of incoming datagram handling (after authentication) + * + * @param[in,out] conf config object to refer to + * @param[in] buf raw message to act upon + * @param[in] source member originating this message + * + * @return 0 on success or negative value (-1 or -errno) on error + */ +int ticket_recv(struct booth_config *conf, void *buf, struct booth_site *source); + void reset_ticket(struct ticket_config *tk); void reset_ticket_and_set_no_leader(struct ticket_config *tk); void update_ticket_state(struct ticket_config *tk, struct booth_site *sender); -int setup_ticket(void); + +/** + * @internal + * Broadcast the initial state query + * + * @param[in,out] conf config object to use as a starting point + * + * @return 0 (for the time being) + */ +int setup_ticket(struct booth_config *conf); + int check_max_len_valid(const char *s, int max); int do_grant_ticket(struct ticket_config *ticket, int options); diff --git a/src/transport.c b/src/transport.c index afd65122..791029cb 100644 --- a/src/transport.c +++ b/src/transport.c @@ -59,7 +59,7 @@ struct booth_site *local = NULL; * or positive integer to indicate sender's ID that will then be * emitted in the error log message together with the real source * address if this is available */ -static int (*deliver_fn) (void *msg, int msglen); +static int (*deliver_fn) (struct booth_config *conf, void *msg, int msglen); static void parse_rtattr(struct rtattr *tb[], @@ -78,11 +78,12 @@ enum match_type { EXACT_MATCH, }; -static int find_address(unsigned char ipaddr[BOOTH_IPADDR_LEN], - int family, int prefixlen, - int fuzzy_allowed, - struct booth_site **me, - int *address_bits_matched) +static int find_address(struct booth_config *conf, + unsigned char ipaddr[BOOTH_IPADDR_LEN], + int family, int prefixlen, + int fuzzy_allowed, + struct booth_site **me, + int *address_bits_matched) { int i; struct booth_site *node; @@ -92,13 +93,14 @@ static int find_address(unsigned char ipaddr[BOOTH_IPADDR_LEN], int matched; enum match_type did_match = NO_MATCH; + assert(conf != NULL); bytes = prefixlen / 8; bits_left = prefixlen % 8; /* One bit left to check means ignore 7 lowest bits. */ mask = ~( (1 << (8 - bits_left)) -1); - FOREACH_NODE(i, node) { + FOREACH_NODE(conf, i, node) { if (family != node->family) continue; n_a = node_to_addr_pointer(node); @@ -140,8 +142,8 @@ static int find_address(unsigned char ipaddr[BOOTH_IPADDR_LEN], } -int _find_myself(int family, struct booth_site **mep, int fuzzy_allowed); -int _find_myself(int family, struct booth_site **mep, int fuzzy_allowed) +static int _find_myself(struct booth_config *conf, int family, + struct booth_site **mep, int fuzzy_allowed) { int fd; struct sockaddr_nl nladdr; @@ -247,9 +249,9 @@ int _find_myself(int family, struct booth_site **mep, int fuzzy_allowed) * the function find_address will try to return another, most similar * address (with the longest possible number of same bytes). */ if (ifa->ifa_prefixlen > address_bits_matched) { - find_address(ipaddr, - ifa->ifa_family, ifa->ifa_prefixlen, - fuzzy_allowed, &me, &address_bits_matched); + find_address(conf, ipaddr, + ifa->ifa_family, ifa->ifa_prefixlen, + fuzzy_allowed, &me, &address_bits_matched); if (me) { log_debug("found myself at %s (%d bits matched)", @@ -263,9 +265,9 @@ int _find_myself(int family, struct booth_site **mep, int fuzzy_allowed) * call the function find_address with disabled searching of * similar addresses (fuzzy_allowed == 0) */ else if (ifa->ifa_prefixlen == address_bits_matched) { - find_address(ipaddr, - ifa->ifa_family, ifa->ifa_prefixlen, - 0 /* fuzzy_allowed */, &me, &address_bits_matched); + find_address(conf, ipaddr, + ifa->ifa_family, ifa->ifa_prefixlen, + 0 /* fuzzy_allowed */, &me, &address_bits_matched); if (me) { log_debug("found myself at %s (exact match)", @@ -290,10 +292,11 @@ int _find_myself(int family, struct booth_site **mep, int fuzzy_allowed) return 1; } -int find_myself(struct booth_site **mep, int fuzzy_allowed) +int find_myself(struct booth_config *conf, struct booth_site **mep, + int fuzzy_allowed) { - return _find_myself(AF_INET6, mep, fuzzy_allowed) || - _find_myself(AF_INET, mep, fuzzy_allowed); + return _find_myself(conf, AF_INET6, mep, fuzzy_allowed) || + _find_myself(conf, AF_INET, mep, fuzzy_allowed); } @@ -431,7 +434,7 @@ int read_client(struct client *req_cl) /* Only used for client requests (tcp) */ -static void process_connection(int ci) +static void process_connection(struct booth_config *conf, int ci) { struct client *req_cl; void *msg = NULL; @@ -507,7 +510,7 @@ static void process_connection(int ci) } -static void process_tcp_listener(int ci) +static void process_tcp_listener(struct booth_config *conf, int ci) { int fd, i, flags, one = 1; socklen_t addrlen = sizeof(struct sockaddr); @@ -803,7 +806,7 @@ static int setup_udp_server(void) /* Receive/process callback for UDP */ -static void process_recv(int ci) +static void process_recv(struct booth_config *conf, int ci) { struct sockaddr_storage sa; int rv; @@ -824,7 +827,7 @@ static void process_recv(int ci) if (rv == -1) return; - rv = deliver_fn((void*)msg, rv); + rv = deliver_fn(conf, (void*) msg, rv); if (rv > 0) { if (getnameinfo((struct sockaddr *)&sa, sa_len, buffer, sizeof(buffer), NULL, 0, @@ -900,7 +903,7 @@ static int booth_udp_broadcast_auth(void *buf, int len) return rv; rvs = 0; - FOREACH_NODE(i, site) { + _FOREACH_NODE(i, site) { if (site != local) { rv = booth_udp_send(site, buf, len); if (!rvs) @@ -1105,7 +1108,7 @@ int send_header_plus(int fd, struct boothc_hdr_msg *msg, void *data, int len) } /* UDP message receiver (see also deliver_fn declaration's comment) */ -int message_recv(void *msg, int msglen) +int message_recv(struct booth_config *conf, void *msg, int msglen) { uint32_t from; struct boothc_header *header; @@ -1114,7 +1117,7 @@ int message_recv(void *msg, int msglen) header = (struct boothc_header *)msg; from = ntohl(header->from); - if (!find_site_by_id(from, &source)) { + if (!find_site_by_id(conf, from, &source)) { /* caller knows the actual source address, pass the (assuredly) positive number and let it report */ from = from ? from : ~from; /* avoid 0 (success) */ @@ -1142,6 +1145,6 @@ int message_recv(void *msg, int msglen) */ return attr_recv(msg, source); } else { - return ticket_recv(msg, source); + return ticket_recv(conf, msg, source); } } diff --git a/src/transport.h b/src/transport.h index 41e488bc..4f4d497d 100644 --- a/src/transport.h +++ b/src/transport.h @@ -58,7 +58,19 @@ struct booth_transport { }; extern const struct booth_transport booth_transport[TRANSPORT_ENTRIES]; -int find_myself(struct booth_site **me, int fuzzy_allowed); + +/** + * @internal + * Attempts to pick identity of self from config-tracked enumeration of sites + * + * @param[in,out] conf config object to refer to + * @param[out] mep when self-discovery successful, site pointer is stored here + * @param[in] fuzzy_allowed whether it's OK to approximate the match + * + * @return 0 on success or negative value (-1 or -errno) on error + */ +int find_myself(struct booth_config *conf, struct booth_site **me, + int fuzzy_allowed); int read_client(struct client *req_cl); int check_boothc_header(struct boothc_header *data, int len_incl_data); @@ -70,7 +82,17 @@ 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); -int message_recv(void *msg, int msglen); +/** + * @internal + * First stage of incoming datagram handling (authentication) + * + * @param[in,out] conf config object to refer to + * @param[in] msg raw message to act upon + * @param[in] msglen length of #msg + * + * @return 0 on success or negative value (-1 or -errno) on error + */ +int message_recv(struct booth_config *conf, void *msg, int msglen); inline static void * node_to_addr_pointer(struct booth_site *node) { switch (node->family) {