Skip to content

Commit

Permalink
Prevent duplicated nodes and force argmap for modules
Browse files Browse the repository at this point in the history
  • Loading branch information
joente committed Feb 16, 2024
1 parent 7a3163b commit 60e94cc
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
* Removed the `<` and `>` from returning a room to a client to be consistent.
* Allow explicit variable list for empty future using a direct closure.
* Return value of `mod_procedure(..)` as changed to `nil` on success.
* Enfore `argmap` property for exposed module methods.
* Prevent adding a dupicated node _(based on address and port)_.

# v1.4.16

Expand Down
2 changes: 1 addition & 1 deletion inc/ti/fn/fnnewnode.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static int do__f_new_node(ti_query_t * query, cleri_node_t * nd, ex_t * e)
port = TI_DEFAULT_NODE_PORT;
}

if (ti_nodes_check_add(e))
if (ti_nodes_check_add(addrstr, port, e))
goto fail1;

cryptx_gen_salt(salt);
Expand Down
2 changes: 1 addition & 1 deletion inc/ti/nodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ int ti_nodes_to_pk(msgpack_packer * pk);
int ti_nodes_from_up(mp_unp_t * up);
ti_nodes_ignore_t ti_nodes_ignore_sync(uint8_t retry_offline);
_Bool ti_nodes_require_sync(void);
int ti_nodes_check_add(ex_t * e);
int ti_nodes_check_add(const char * addr, uint16_t port, ex_t * e);
uint64_t ti_nodes_ccid(void);
uint64_t ti_nodes_scid(void);
uint32_t ti_nodes_next_id(void);
Expand Down
2 changes: 1 addition & 1 deletion inc/ti/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* "-rc0"
* ""
*/
#define TI_VERSION_PRE_RELEASE "-alpha16"
#define TI_VERSION_PRE_RELEASE "-alpha17"

#define TI_MAINTAINER \
"Jeroen van der Heijden <[email protected]>"
Expand Down
4 changes: 4 additions & 0 deletions src/ti/mod/expose.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ int ti_mod_expose_call(

query->rval = NULL;

/*
* We do not crash on argmap is NULL, however, the argmap is always set
* unless some allocation error has occurred.
*/
if (expose->argmap)
{
size_t sz = expose->argmap->n + defaults_n;
Expand Down
40 changes: 40 additions & 0 deletions src/ti/mod/manifest.c
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,42 @@ static inline int manifest__has_key(vec_t * defaults, ti_raw_t * key)
return 0;
}

static void manifest__force_argmap(ti_mod_expose_t * expose)
{
/* argmap is not critical as the code works without argmap too;
* However, no argmap is the same as ["*"] which is helpful information
* to the user and we therefore should make this map. Note that an
* empty argmap is also possible and serves a different purpose, namely,
* explicitly sending no arguments to the module; we must therefore
* leave empty argmap alone;
*/
ti_item_t * item;
if (expose->argmap)
return;

expose->argmap = vec_new(1);
if (!expose->argmap)
return;

item = malloc(sizeof(ti_item_t));
if (!item)
goto fail0;

item->val = NULL;
item->key = ti_str_create("*", 1);
if (!item->key)
goto fail1;

VEC_push(expose->argmap, item);
return;

fail1:
free(item);
fail0:
vec_destroy(expose->argmap, NULL);
expose->argmap = NULL;
}

/*
* Return 0 on success, -1 allocation error
*/
Expand Down Expand Up @@ -1100,6 +1136,10 @@ static int manifest__exposes_cb(
*expose->load = *manifest->load;
}

/* this may fail in which case argmap is still NULL; this is okay and can
* be ignored; */
manifest__force_argmap(expose);

if (expose->argmap) for (vec_each(expose->argmap, ti_item_t, item_map))
{
if (expose->defaults) for (vec_each(expose->defaults, ti_item_t, item))
Expand Down
9 changes: 8 additions & 1 deletion src/ti/nodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1527,7 +1527,7 @@ _Bool ti_nodes_require_sync(void)
* nodes. The rule is that at least a quorum can still be reached, even if the
* new node fails to connect.
*/
int ti_nodes_check_add(ex_t * e)
int ti_nodes_check_add(const char * addr, uint16_t port, ex_t * e)
{
vec_t * nodes_vec = nodes->vec;
uint8_t may_skip = nodes_vec->n >= 4
Expand All @@ -1542,6 +1542,13 @@ int ti_nodes_check_add(ex_t * e)

for (vec_each(nodes_vec, ti_node_t, node))
{
if (node->addr == addr && node->port == port)
{
ex_set(e, EX_LOOKUP_ERROR,
"node with `%s:%u` already exists ("TI_NODE_ID")",
addr, port, node->id);
return e->nr;
}
if (node->status <= TI_NODE_STAT_CONNECTED && !may_skip--)
{
ex_set(e, EX_OPERATION,
Expand Down

0 comments on commit 60e94cc

Please sign in to comment.