All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Gix, Brian" <brian.gix@intel.com>
To: "linux-bluetooth@vger.kernel.org" <linux-bluetooth@vger.kernel.org>
Cc: "michal.lowas-rzechonek@silvair.com" 
	<michal.lowas-rzechonek@silvair.com>,
	"Stotland, Inga" <inga.stotland@intel.com>
Subject: Re: [PATCH BlueZ v6 1/2] mesh: Reconfigure node storage tree
Date: Mon, 13 May 2019 19:32:47 +0000	[thread overview]
Message-ID: <1557775965.22613.0.camel@intel.com> (raw)
In-Reply-To: <20190509213321.19822-2-brian.gix@intel.com>

Patch-set applied


On Thu, 2019-05-09 at 14:33 -0700, Brian Gix wrote:
> Add a tree structure to a nodes data storage, in order to safely handle
> Replay Protection list, Refactor local Sequence Numbers, and add Key
> storage for Config Client nodes.
> ---
>  mesh/README    |  34 +++++++++++++-
>  mesh/node.c    |  16 ++++---
>  mesh/node.h    |   4 +-
>  mesh/storage.c | 144 ++++++++++++++++++++++++++++++++++-----------------------
>  4 files changed, 131 insertions(+), 67 deletions(-)
> 
> diff --git a/mesh/README b/mesh/README
> index ca223a6d8..82fd5a017 100644
> --- a/mesh/README
> +++ b/mesh/README
> @@ -36,8 +36,40 @@ Each subdirectory contains the following files:
>  		provisioner/configuration client
>  	- node.json.bak:
>  		a backup that the last known good node configuration.
> +	- seq_num:
> +		File containing next sequence number to use
> +	- seq_num.bak:
> +		Backup of the sequence number. This may be larger than the
> +		actual sequence number being used at runtime, to prevent re-use
> +		of sequence numbers in the event of an unexpected restart.
> +	- ./rpl/:
> +		Directory to store the sequence numbers of remote nodes, as
> +		required by Replay Protection List (RPL) parameters.
> +		- xxxx:
> +			Files named for remote Unicast addresses, and contain
> +			last received iv_index + seq_num from each SRC address.
> +	- ./dev_keys/:
> +		Directory to store remote Device keys. This is only created/used
> +		by Configuration Client (Network administration) nodes.
> +		- xxxx:
> +			Files named for remote Unicast addresses, and contains
> +			16 octet key.
> +	- ./net_keys/:
> +		Directory to store network subnet keys. This is only
> +		created/used by Configuration Client (Network administration)
> +		nodes.
> +		- xxx:
> +			Files named for subnet index, and contains key refresh
> +			phase, and old/new versions of the key.
> +	- ./app_keys/:
> +		Directory to store application keys. This is only created/used
> +		by Configuration Client (Network administration) nodes.
> +		- xxx:
> +			Files named for application index, and contains bound
> +			subnet index, and old/new versions of the key.
>  
> -The files are in JSON format.
> +The node.json and node.json.bak are in JSON format. All other files are stored
> +in little endian binary format.
>  
>  Information
>  ===========
> diff --git a/mesh/node.c b/mesh/node.c
> index 5904b116c..6f95c8d1c 100644
> --- a/mesh/node.c
> +++ b/mesh/node.c
> @@ -79,7 +79,7 @@ struct mesh_node {
>  	char *owner;
>  	char *path;
>  	void *jconfig;
> -	char *cfg_file;
> +	char *node_path;
>  	uint32_t disc_watch;
>  	time_t upd_sec;
>  	uint32_t seq_number;
> @@ -236,6 +236,7 @@ static void free_node_resources(void *data)
>  	l_free(node->comp);
>  	l_free(node->app_path);
>  	l_free(node->owner);
> +	l_free(node->node_path);
>  
>  	if (node->disc_watch)
>  		l_dbus_remove_watch(dbus_get_bus(), node->disc_watch);
> @@ -259,7 +260,7 @@ void node_remove(struct mesh_node *node)
>  
>  	l_queue_remove(nodes, node);
>  
> -	if (node->cfg_file)
> +	if (node->node_path)
>  		storage_remove_node_config(node);
>  
>  	free_node_resources(node);
> @@ -395,7 +396,7 @@ static void cleanup_node(void *data)
>  	struct mesh_net *net = node->net;
>  
>  	/* Save local node configuration */
> -	if (node->cfg_file) {
> +	if (node->node_path) {
>  
>  		/* Preserve the last sequence number */
>  		storage_write_sequence_number(net, mesh_net_get_seq_num(net));
> @@ -1859,14 +1860,15 @@ void *node_jconfig_get(struct mesh_node *node)
>  	return node->jconfig;
>  }
>  
> -void node_cfg_file_set(struct mesh_node *node, char *cfg)
> +void node_path_set(struct mesh_node *node, char *path)
>  {
> -	node->cfg_file = cfg;
> +	l_free(node->node_path);
> +	node->node_path = l_strdup(path);
>  }
>  
> -char *node_cfg_file_get(struct mesh_node *node)
> +char *node_path_get(struct mesh_node *node)
>  {
> -	return node->cfg_file;
> +	return node->node_path;
>  }
>  
>  struct mesh_net *node_get_net(struct mesh_node *node)
> diff --git a/mesh/node.h b/mesh/node.h
> index 1be4de1da..1194ff837 100644
> --- a/mesh/node.h
> +++ b/mesh/node.h
> @@ -95,5 +95,5 @@ bool node_dbus_init(struct l_dbus *bus);
>  void node_cleanup_all(void);
>  void node_jconfig_set(struct mesh_node *node, void *jconfig);
>  void *node_jconfig_get(struct mesh_node *node);
> -void node_cfg_file_set(struct mesh_node *node, char *cfg);
> -char *node_cfg_file_get(struct mesh_node *node);
> +void node_path_set(struct mesh_node *node, char *path);
> +char *node_path_get(struct mesh_node *node);
> diff --git a/mesh/storage.c b/mesh/storage.c
> index 2580cbe7f..f4e23bf49 100644
> --- a/mesh/storage.c
> +++ b/mesh/storage.c
> @@ -28,6 +28,7 @@
>  #include <unistd.h>
>  #include <dirent.h>
>  #include <libgen.h>
> +#include <ftw.h>
>  
>  #include <sys/types.h>
>  #include <sys/stat.h>
> @@ -49,13 +50,30 @@
>  
>  struct write_info {
>  	json_object *jnode;
> -	const char *config_name;
> +	const char *node_path;
>  	void *user_data;
>  	mesh_status_func_t cb;
>  };
>  
> +static const char *cfg_name = "/node.json";
> +static const char *bak_ext = ".bak";
> +static const char *tmp_ext = ".tmp";
>  static const char *storage_dir;
>  
> +/* This is a thread-safe always malloced version of dirname which will work
> + * regardless of which underlying dirname() implementation is used.
> + */
> +static char *alloc_dirname(const char *path)
> +{
> +	char *tmp = l_strdup(path);
> +	char *dir;
> +
> +	dir = dirname(tmp);
> +	strncpy(tmp, dir, strlen(path) + 1);
> +
> +	return tmp;
> +}
> +
>  static bool read_node_cb(struct mesh_db_node *db_node, void *user_data)
>  {
>  	struct mesh_node *node = user_data;
> @@ -166,7 +184,7 @@ static bool parse_node(struct mesh_node *node, json_object *jnode)
>  	return true;
>  }
>  
> -static bool parse_config(char *in_file, char *out_file, const uint8_t uuid[16])
> +static bool parse_config(char *in_file, char *out_dir, const uint8_t uuid[16])
>  {
>  	int fd;
>  	char *str;
> @@ -213,7 +231,7 @@ static bool parse_config(char *in_file, char *out_file, const uint8_t uuid[16])
>  	}
>  
>  	node_jconfig_set(node, jnode);
> -	node_cfg_file_set(node, out_file);
> +	node_path_set(node, out_dir);
>  
>  done:
>  	close(fd);
> @@ -430,15 +448,12 @@ static bool save_config(json_object *jnode, const char *config_name)
>  static void idle_save_config(void *user_data)
>  {
>  	struct write_info *info = user_data;
> -	size_t len = strlen(info->config_name) + 5;
> -	char *tmp = l_malloc(len);
> -	char *bak = l_malloc(len);
> +	char *tmp, *bak, *cfg;
>  	bool result = false;
>  
> -	strncpy(tmp, info->config_name, len);
> -	strncpy(bak, info->config_name, len);
> -	tmp = strncat(tmp, ".tmp", 5);
> -	bak = strncat(bak, ".bak", 5);
> +	cfg = l_strdup_printf("%s%s", info->node_path, cfg_name);
> +	tmp = l_strdup_printf("%s%s", cfg, tmp_ext);
> +	bak = l_strdup_printf("%s%s", cfg, bak_ext);
>  	remove(tmp);
>  
>  	l_debug("Storage-Wrote");
> @@ -446,13 +461,14 @@ static void idle_save_config(void *user_data)
>  
>  	if (result) {
>  		remove(bak);
> -		rename(info->config_name, bak);
> -		rename(tmp, info->config_name);
> +		rename(cfg, bak);
> +		rename(tmp, cfg);
>  	}
>  
>  	remove(tmp);
>  	l_free(tmp);
>  	l_free(bak);
> +	l_free(cfg);
>  
>  	if (info->cb)
>  		info->cb(info->user_data, result);
> @@ -467,7 +483,7 @@ void storage_save_config(struct mesh_node *node, bool no_wait,
>  
>  	info = l_new(struct write_info, 1);
>  	info->jnode = node_jconfig_get(node);
> -	info->config_name = node_cfg_file_get(node);
> +	info->node_path = node_path_get(node);
>  	info->cb = cb;
>  	info->user_data = user_data;
>  
> @@ -517,6 +533,7 @@ bool storage_load_nodes(const char *dir_name)
>  {
>  	DIR *dir;
>  	struct dirent *entry;
> +	size_t path_len = strlen(dir_name) + strlen(cfg_name) + strlen(bak_ext);
>  
>  	create_dir(dir_name);
>  	dir = opendir(dir_name);
> @@ -529,33 +546,37 @@ bool storage_load_nodes(const char *dir_name)
>  	storage_dir = dir_name;
>  
>  	while ((entry = readdir(dir)) != NULL) {
> -		char *cfg;
> -		char *bak;
> +		char *dir, *cfg, *bak;
>  		uint8_t uuid[16];
> +		size_t node_len;
>  
>  		if (entry->d_type != DT_DIR)
>  			continue;
>  
> -		if (!str2hex(entry->d_name, strlen(entry->d_name), uuid, sizeof(uuid)))
> +		/* Check path length */
> +		node_len = strlen(entry->d_name);
> +		if (path_len + node_len + 1 >= PATH_MAX)
>  			continue;
>  
> -		cfg = l_strdup_printf("%s/%s/node.json", dir_name, entry->d_name);
> -
> -		if (parse_config(cfg, cfg, uuid))
> +		if (!str2hex(entry->d_name, node_len, uuid, sizeof(uuid)))
>  			continue;
>  
> -		/* Fall-back to Backup version */
> -		bak = l_strdup_printf("%s/%s/node.json.bak", dir_name, entry->d_name);
> +		dir = l_strdup_printf("%s/%s", dir_name, entry->d_name);
> +		cfg = l_strdup_printf("%s%s", dir, cfg_name);
>  
> -		if (parse_config(bak, cfg, uuid)) {
> -			remove(cfg);
> -			rename(bak, cfg);
> -			l_free(cfg);
> -			continue;
> -		}
> +		if (!parse_config(cfg, dir, uuid)) {
>  
> +			/* Fall-back to Backup version */
> +			bak = l_strdup_printf("%s%s", cfg, bak_ext);
> +
> +			if (parse_config(bak, dir, uuid)) {
> +				remove(cfg);
> +				rename(bak, cfg);
> +			}
> +			l_free(bak);
> +		}
>  		l_free(cfg);
> -		l_free(bak);
> +		l_free(dir);
>  	}
>  
>  	return true;
> @@ -566,8 +587,8 @@ bool storage_create_node_config(struct mesh_node *node, void *data)
>  	struct mesh_db_node *db_node = data;
>  	char uuid[33];
>  	char name_buf[PATH_MAX];
> -	char *filename;
>  	json_object *jnode;
> +	size_t max_len = strlen(cfg_name) + strlen(bak_ext);
>  
>  	if (!storage_dir)
>  		return false;
> @@ -578,25 +599,26 @@ bool storage_create_node_config(struct mesh_node *node, void *data)
>  		return false;
>  
>  	if (!hex2str(node_uuid_get(node), 16, uuid, sizeof(uuid)))
> -		return false;
> +		goto fail;
>  
>  	snprintf(name_buf, PATH_MAX, "%s/%s", storage_dir, uuid);
>  
> +	if (strlen(name_buf) + max_len >= PATH_MAX)
> +		goto fail;
> +
>  	/* Create a new directory and node.json file */
>  	if (mkdir(name_buf, 0755) != 0)
>  		goto fail;
>  
> -	filename = l_strdup_printf("%s/node.json", name_buf);
> +	node_path_set(node, name_buf);
>  
> -	l_debug("New node config %s", filename);
> +	snprintf(name_buf, PATH_MAX, "%s/%s%s", storage_dir, uuid, cfg_name);
> +	l_debug("New node config %s", name_buf);
>  
> -	if (!save_config(jnode, filename)) {
> -		l_free(filename);
> +	if (!save_config(jnode, name_buf))
>  		goto fail;
> -	}
>  
>  	node_jconfig_set(node, jnode);
> -	node_cfg_file_set(node, filename);
>  
>  	return true;
>  fail:
> @@ -604,13 +626,29 @@ fail:
>  	return false;
>  }
>  
> +static int del_fobject(const char *fpath, const struct stat *sb, int typeflag,
> +						struct FTW *ftwbuf)
> +{
> +	switch (typeflag) {
> +	case FTW_DP:
> +		rmdir(fpath);
> +		l_debug("RMDIR %s", fpath);
> +		break;
> +
> +	case FTW_SL:
> +	default:
> +		remove(fpath);
> +		l_debug("RM %s", fpath);
> +		break;
> +	}
> +	return 0;
> +}
> +
>  /* Permanently remove node configuration */
>  void storage_remove_node_config(struct mesh_node *node)
>  {
> -	char *cfg;
> +	char *node_path, *mesh_path, *mesh_name;
>  	struct json_object *jnode;
> -	const char *dir_name;
> -	char *bak;
>  
>  	if (!node)
>  		return;
> @@ -621,25 +659,17 @@ void storage_remove_node_config(struct mesh_node *node)
>  		json_object_put(jnode);
>  	node_jconfig_set(node, NULL);
>  
> -	/* Delete node configuration file */
> -	cfg = node_cfg_file_get(node);
> -	if (!cfg)
> -		return;
> -
> -	l_debug("Delete node config file %s", cfg);
> -	remove(cfg);
> -
> -	/* Delete the backup file */
> -	bak = l_strdup_printf("%s.bak", cfg);
> -	remove(bak);
> -	l_free(bak);
> +	node_path = node_path_get(node);
> +	l_debug("Delete node config %s", node_path);
>  
> -	/* Delete the node directory */
> -	dir_name = dirname(cfg);
> +	/* Make sure path name of node follows expected guidelines */
> +	mesh_path = alloc_dirname(node_path);
> +	mesh_name = basename(mesh_path);
> +	if (strcmp(mesh_name, "mesh"))
> +		goto done;
>  
> -	l_debug("Delete directory %s", dir_name);
> -	rmdir(dir_name);
> +	nftw(node_path, del_fobject, 5, FTW_DEPTH | FTW_PHYS);
>  
> -	l_free(cfg);
> -	node_cfg_file_set(node, NULL);
> +done:
> +	l_free(mesh_path);
>  }

  reply	other threads:[~2019-05-13 19:32 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-09 21:33 [PATCH BlueZ v6 0/2] mesh: node dir Restructure, and keyring Brian Gix
2019-05-09 21:33 ` [PATCH BlueZ v6 1/2] mesh: Reconfigure node storage tree Brian Gix
2019-05-13 19:32   ` Gix, Brian [this message]
2019-05-09 21:33 ` [PATCH BlueZ v6 2/2] mesh: Add key storage Brian Gix

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1557775965.22613.0.camel@intel.com \
    --to=brian.gix@intel.com \
    --cc=inga.stotland@intel.com \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=michal.lowas-rzechonek@silvair.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.