diff options
author | Sander Vrijders <[email protected]> | 2016-03-11 16:52:28 +0100 |
---|---|---|
committer | Sander Vrijders <[email protected]> | 2016-03-11 16:52:28 +0100 |
commit | f5cf4e478bf7dec70dc22d80de706f82ef4b38f1 (patch) | |
tree | 60160c5cac28eb8cfcd376428429e03cf2e7e203 | |
parent | d68e4e5e540720d9b02e2062e3982f1c438eb1e0 (diff) | |
download | ouroboros-f5cf4e478bf7dec70dc22d80de706f82ef4b38f1.tar.gz ouroboros-f5cf4e478bf7dec70dc22d80de706f82ef4b38f1.zip |
lib: Add helpers for RINA names
This adds helper functions for RINA names, to aid with handling them.
-rw-r--r-- | include/ouroboros/CMakeLists.txt | 1 | ||||
-rw-r--r-- | include/ouroboros/common.h | 7 | ||||
-rw-r--r-- | include/ouroboros/da.h | 8 | ||||
-rw-r--r-- | include/ouroboros/ipcp.h | 20 | ||||
-rw-r--r-- | include/ouroboros/irm.h | 1 | ||||
-rw-r--r-- | include/ouroboros/list.h | 26 | ||||
-rw-r--r-- | include/ouroboros/rina_name.h | 102 | ||||
-rw-r--r-- | include/ouroboros/sockets.h | 3 | ||||
-rw-r--r-- | src/irmd/main.c | 164 | ||||
-rw-r--r-- | src/lib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/lib/da.c | 5 | ||||
-rw-r--r-- | src/lib/ipcp.c | 23 | ||||
-rw-r--r-- | src/lib/irm.c | 30 | ||||
-rw-r--r-- | src/lib/rina_name.c | 331 | ||||
-rw-r--r-- | src/lib/sockets.c | 33 | ||||
-rw-r--r-- | src/tools/irm/irm.c | 1 | ||||
-rw-r--r-- | src/tools/irm/irm_utils.h | 2 |
17 files changed, 654 insertions, 104 deletions
diff --git a/include/ouroboros/CMakeLists.txt b/include/ouroboros/CMakeLists.txt index dc827fbe..e862de8c 100644 --- a/include/ouroboros/CMakeLists.txt +++ b/include/ouroboros/CMakeLists.txt @@ -9,6 +9,7 @@ set(HEADER_FILES irm.h list.h logs.h + rina_name.h sockets.h ) diff --git a/include/ouroboros/common.h b/include/ouroboros/common.h index 00d1f482..1ff4267b 100644 --- a/include/ouroboros/common.h +++ b/include/ouroboros/common.h @@ -35,13 +35,6 @@ typedef struct { size_t size; } buffer_t; -typedef struct { - char * ap_name; - int api_id; - char * ae_name; - int aei_id; -} rina_name_t; - /* FIXME: may need revision */ struct qos_spec { char * qos_name; diff --git a/include/ouroboros/da.h b/include/ouroboros/da.h index 17c25203..2a046f6b 100644 --- a/include/ouroboros/da.h +++ b/include/ouroboros/da.h @@ -24,8 +24,14 @@ #define OUROBOROS_DA_H #include "common.h" +#include "rina_name.h" rina_name_t * da_resolve_daf(char * daf_name); -char ** da_resolve_dap(rina_name_t * name); +/* + * n_1_difs is an out parameter + * The amount of n_1_difs is returned + */ +ssize_t da_resolve_dap(rina_name_t * name, + char ** n_1_difs); #endif diff --git a/include/ouroboros/ipcp.h b/include/ouroboros/ipcp.h index c8682ec3..39e9c909 100644 --- a/include/ouroboros/ipcp.h +++ b/include/ouroboros/ipcp.h @@ -24,24 +24,28 @@ #define OUROBOROS_IPCP_H #include "common.h" +#include "rina_name.h" struct ipcp; -struct ipcp * ipcp_create(rina_name_t name, - char * ipcp_type); -int ipcp_destroy(struct ipcp * instance); +/* Returns the process id */ +int ipcp_create(rina_name_t name, + char * ipcp_type); +int ipcp_destroy(int pid); -int ipcp_reg(struct ipcp * instance, +int ipcp_reg(int pid, char ** difs, size_t difs_size); -int ipcp_unreg(struct ipcp * instance, +int ipcp_unreg(int pid, char ** difs, size_t difs_size); -int ipcp_bootstrap(struct ipcp * instance, +int ipcp_bootstrap(int pid, struct dif_config conf); -int ipcp_enroll(struct ipcp * instance, +int ipcp_enroll(int pid, char * dif_name, - rina_name_t member); + rina_name_t member, + char ** n_1_difs, + ssize_t n_1_difs_size); #endif diff --git a/include/ouroboros/irm.h b/include/ouroboros/irm.h index 459b0e9f..a6f0d9f3 100644 --- a/include/ouroboros/irm.h +++ b/include/ouroboros/irm.h @@ -24,6 +24,7 @@ #define OUROBOROS_IRM_H #include "common.h" +#include "rina_name.h" int irm_create_ipcp(rina_name_t name, char * ipcp_type); diff --git a/include/ouroboros/list.h b/include/ouroboros/list.h index 1a96ddb4..f446749d 100644 --- a/include/ouroboros/list.h +++ b/include/ouroboros/list.h @@ -241,30 +241,4 @@ void list_splice_init(struct list_head * list, for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_safe - iterate over list of given type safe - * against removal of list entry - * @pos: the type * to use as a loop counter. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - - #endif diff --git a/include/ouroboros/rina_name.h b/include/ouroboros/rina_name.h new file mode 100644 index 00000000..d802ae14 --- /dev/null +++ b/include/ouroboros/rina_name.h @@ -0,0 +1,102 @@ +/* + * RINA naming related utilities + * + * Sander Vrijders <[email protected]> + * Francesco Salvestrini <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef RINA_NAME_H +#define RINA_NAME_H + +#include "common.h" + +typedef struct { + char * ap_name; + unsigned int api_id; + char * ae_name; + unsigned int aei_id; +} rina_name_t; + +/* + * Allocates a new name, returning the allocated object. + * In case of an error, a NULL is returned. + */ +rina_name_t * name_create(); + +/* + * Initializes a previously dynamically allocated name (i.e. name_create()) + * or a statically one (e.g. declared into a struct not as a pointer). + * Returns the passed object pointer in case everything is ok, a NULL + * otherwise. + * + * A call to name_destroy() is allowed in case of error, in order to + * release the associated resources. + * + * It is allowed to call name_init() over an already initialized object + */ +rina_name_t * name_init_from(rina_name_t * dst, + const char * ap_name, + unsigned int api_id, + const char * ae_name, + unsigned int aei_id); + +/* Takes ownership of the passed parameters */ +rina_name_t * name_init_with(rina_name_t * dst, + char * ap_name, + unsigned int api_id, + char * ae_name, + unsigned int aei_id); + +/* + * Finalize a name object, releasing all the embedded resources (without + * releasing the object itself). After name_fini() execution the passed + * object will be in the same states as at the end of name_init(). + */ +void name_fini(rina_name_t * dst); + +/* Releases all the associated resources bound to a name object */ +void name_destroy(rina_name_t * ptr); + +/* Duplicates a name object, returning the pointer to the new object */ +rina_name_t * name_dup(const rina_name_t * src); + +/* + * Copies the source object contents into the destination object, both must + * be previously allocated + */ +int name_cpy(const rina_name_t * src, rina_name_t * dst); + +bool name_is_equal(const rina_name_t * a, const rina_name_t * b); +bool name_is_ok(const rina_name_t * n); + +#define NAME_CMP_APN 0x01 +#define NAME_CMP_API 0x02 +#define NAME_CMP_AEN 0x04 +#define NAME_CMP_AEI 0x08 +#define NAME_CMP_ALL (NAME_CMP_APN | NAME_CMP_API | NAME_CMP_AEN | NAME_CMP_AEI) + +bool name_cmp(uint8_t flags, + const rina_name_t * a, + const rina_name_t * b); + +/* Returns a name as a (newly allocated) string */ +char * name_to_string(const rina_name_t * n); + +/* Inverse of name_tostring() */ +rina_name_t * string_to_name(const char * s); + +#endif diff --git a/include/ouroboros/sockets.h b/include/ouroboros/sockets.h index e2409c2b..b34537a7 100644 --- a/include/ouroboros/sockets.h +++ b/include/ouroboros/sockets.h @@ -23,6 +23,9 @@ #ifndef OUROBOROS_SOCKETS_H #define OUROBOROS_SOCKETS_H +#include "common.h" +#include "rina_name.h" + #define IRM_SOCK_PATH "/tmp/irm_sock" #define IRM_MSG_BUF_SIZE 256 diff --git a/src/irmd/main.c b/src/irmd/main.c index f744ee7f..e28e6a28 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -28,48 +28,126 @@ #include <ouroboros/irm.h> #include <ouroboros/ipcp.h> #include <ouroboros/da.h> +#include <ouroboros/list.h> +#include <ouroboros/rina_name.h> #include <sys/socket.h> #include <sys/un.h> #include <stdlib.h> #include <errno.h> -struct irm { +struct name_to_pid_entry { + struct list_head next; + int pid; + rina_name_t * name; +}; +struct irm { + struct list_head name_to_pid; }; -static void create_ipcp(rina_name_t name, +static int find_pid_by_name(struct irm * instance, + rina_name_t * name) +{ + struct list_head * pos; + + list_for_each(pos, &instance->name_to_pid) { + struct name_to_pid_entry * tmp = + list_entry(pos, struct name_to_pid_entry, next); + + LOG_DBG("name is %s", name->ap_name); + + if (name_is_equal(name, tmp->name)) + return tmp->pid; + } + + return 0; +} + +static void create_ipcp(struct irm * instance, + rina_name_t name, char * ipcp_type) { - struct ipcp * instance = NULL; + int pid; + struct name_to_pid_entry * tmp; + rina_name_t * ipcp_name = NULL; - instance = ipcp_create(name, ipcp_type); - if (instance == NULL) + pid = ipcp_create(name, ipcp_type); + if (pid == 0) { LOG_ERR("Failed to create IPCP"); + return; + } + + tmp = malloc(sizeof(*tmp)); + if (tmp == NULL) + return; + + INIT_LIST_HEAD(&tmp->next); + + tmp->pid = pid; + tmp->name = name_dup(ipcp_name); + if (tmp->name == NULL) { + free(tmp); + return; + } + + list_add(&tmp->next, &instance->name_to_pid); } -static void destroy_ipcp(rina_name_t name) +static void destroy_ipcp(struct irm * instance, + rina_name_t name) { - struct ipcp * instance = NULL; + int pid = 0; + struct list_head * pos; - if (ipcp_destroy(instance)) + pid = find_pid_by_name(instance, &name); + if (pid == 0) { + LOG_ERR("No such IPCP"); + return; + } + + if (ipcp_destroy(pid)) LOG_ERR("Could not destroy IPCP"); + + list_for_each(pos, &instance->name_to_pid) { + struct name_to_pid_entry * tmp = + list_entry(pos, struct name_to_pid_entry, next); + + if (name_is_equal(&name, tmp->name)) + list_del(&tmp->next); + } } -static void bootstrap_ipcp(rina_name_t name, +static void bootstrap_ipcp(struct irm * instance, + rina_name_t name, struct dif_config conf) { - struct ipcp * instance = NULL; + int pid = 0; - if (ipcp_bootstrap(instance, conf)) + pid = find_pid_by_name(instance, &name); + if (pid == 0) { + LOG_ERR("No such IPCP"); + return; + } + + if (ipcp_bootstrap(pid, conf)) LOG_ERR("Could not bootstrap IPCP"); } -static void enroll_ipcp(rina_name_t name, +static void enroll_ipcp(struct irm * instance, + rina_name_t name, char * dif_name) { - struct ipcp * instance = NULL; + int pid = 0; rina_name_t * member; + char ** n_1_difs = NULL; + ssize_t n_1_difs_size = 0; + + pid = find_pid_by_name(instance, &name); + if (pid == 0) { + LOG_ERR("No such IPCP"); + return; + } member = da_resolve_daf(dif_name); if (member == NULL) { @@ -77,35 +155,60 @@ static void enroll_ipcp(rina_name_t name, return; } - if (ipcp_enroll(instance, dif_name, *member)) - LOG_ERR("Could not enroll IPCP"); + n_1_difs_size = da_resolve_dap(member, n_1_difs); + if (n_1_difs_size != 0) + if (ipcp_enroll(pid, dif_name, *member, + n_1_difs, n_1_difs_size)) + LOG_ERR("Could not enroll IPCP"); } -static void reg_ipcp(rina_name_t name, +static void reg_ipcp(struct irm * instance, + rina_name_t name, char ** difs, size_t difs_size) { - struct ipcp * instance = NULL; + int pid = 0; + + pid = find_pid_by_name(instance, &name); + if (pid == 0) { + LOG_ERR("No such IPCP"); + return; + } - if (ipcp_reg(instance, difs, difs_size)) + if (ipcp_reg(pid, difs, difs_size)) LOG_ERR("Could not register IPCP to N-1 DIF(s)"); } -static void unreg_ipcp(rina_name_t name, +static void unreg_ipcp(struct irm * instance, + rina_name_t name, char ** difs, size_t difs_size) { - struct ipcp * instance = NULL; + int pid = 0; - if (ipcp_unreg(instance, difs, difs_size)) + pid = find_pid_by_name(instance, &name); + if (pid == 0) { + LOG_ERR("No such IPCP"); + return; + } + + if (ipcp_unreg(pid, difs, difs_size)) LOG_ERR("Could not unregister IPCP from N-1 DIF(s)"); } +/* FIXME: Close sockfd on closing and release irm */ int main() { + struct irm * instance; int sockfd; uint8_t buf[IRM_MSG_BUF_SIZE]; + instance = malloc(sizeof(*instance)); + if (instance == NULL) + return -1; + + INIT_LIST_HEAD(&instance->name_to_pid); + sockfd = server_socket_open(IRM_SOCK_PATH); if (sockfd < 0) return -1; @@ -132,26 +235,33 @@ int main() switch (msg->code) { case IRM_CREATE_IPCP: - create_ipcp(*(msg->name), msg->ipcp_type); + create_ipcp(instance, + *(msg->name), + msg->ipcp_type); break; case IRM_DESTROY_IPCP: - destroy_ipcp(*(msg->name)); + destroy_ipcp(instance, + *(msg->name)); break; case IRM_BOOTSTRAP_IPCP: - bootstrap_ipcp(*(msg->name), + bootstrap_ipcp(instance, + *(msg->name), *(msg->conf)); break; case IRM_ENROLL_IPCP: - enroll_ipcp(*(msg->name), + enroll_ipcp(instance, + *(msg->name), msg->dif_name); break; case IRM_REG_IPCP: - reg_ipcp(*(msg->name), + reg_ipcp(instance, + *(msg->name), msg->difs, msg->difs_size); break; case IRM_UNREG_IPCP: - unreg_ipcp(*(msg->name), + unreg_ipcp(instance, + *(msg->name), msg->difs, msg->difs_size); break; diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 349f8d73..c52a5609 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -12,6 +12,7 @@ set(SOURCE_FILES du_buff.c ipcp.c irm.c + rina_name.c sockets.c ) diff --git a/src/lib/da.c b/src/lib/da.c index e9888d9e..ef59a409 100644 --- a/src/lib/da.c +++ b/src/lib/da.c @@ -27,7 +27,8 @@ rina_name_t * da_resolve_daf(char * daf_name) return NULL; } -char ** da_resolve_dap(rina_name_t * name) +ssize_t da_resolve_dap(rina_name_t * name, + char ** n_1_difs) { - return NULL; + return 0; } diff --git a/src/lib/ipcp.c b/src/lib/ipcp.c index 718b5f3e..935330d5 100644 --- a/src/lib/ipcp.c +++ b/src/lib/ipcp.c @@ -22,42 +22,43 @@ #include <ouroboros/ipcp.h> -struct ipcp {}; - -struct ipcp * ipcp_create(rina_name_t name, - char * ipcp_type) +int ipcp_create(rina_name_t name, + char * ipcp_type) { - return NULL; + /* zero means failure */ + return 0; } -int ipcp_destroy(struct ipcp * instance) +int ipcp_destroy(int pid) { return -1; } -int ipcp_reg(struct ipcp * instance, +int ipcp_reg(int pid, char ** difs, size_t difs_size) { return -1; } -int ipcp_unreg(struct ipcp * instance, +int ipcp_unreg(int pid, char ** difs, size_t difs_size) { return -1; } -int ipcp_bootstrap(struct ipcp * instance, +int ipcp_bootstrap(int pid, struct dif_config conf) { return -1; } -int ipcp_enroll(struct ipcp * instance, +int ipcp_enroll(int pid, char * dif_name, - rina_name_t member) + rina_name_t member, + char ** n_1_difs, + ssize_t n_1_difs_size) { return -1; } diff --git a/src/lib/irm.c b/src/lib/irm.c index 493cb71d..a1847eed 100644 --- a/src/lib/irm.c +++ b/src/lib/irm.c @@ -63,6 +63,11 @@ int irm_create_ipcp(rina_name_t name, if (ipcp_type == NULL) return -1; + if (!name_is_ok(&name)) { + LOG_ERR("Bad name"); + return -1; + } + msg.code = IRM_CREATE_IPCP; msg.name = &name; msg.ipcp_type = ipcp_type; @@ -79,6 +84,11 @@ int irm_destroy_ipcp(rina_name_t name) { struct irm_msg msg; + if (!name_is_ok(&name)) { + LOG_ERR("Bad name"); + return -1; + } + msg.code = IRM_DESTROY_IPCP; msg.name = &name; @@ -95,6 +105,11 @@ int irm_bootstrap_ipcp(rina_name_t name, { struct irm_msg msg; + if (!name_is_ok(&name)) { + LOG_ERR("Bad name"); + return -1; + } + msg.code = IRM_BOOTSTRAP_IPCP; msg.name = &name; msg.conf = &conf; @@ -112,6 +127,11 @@ int irm_enroll_ipcp(rina_name_t name, { struct irm_msg msg; + if (!name_is_ok(&name)) { + LOG_ERR("Bad name"); + return -1; + } + msg.code = IRM_ENROLL_IPCP; msg.name = &name; msg.dif_name = dif_name; @@ -130,6 +150,11 @@ int irm_reg_ipcp(rina_name_t name, { struct irm_msg msg; + if (!name_is_ok(&name)) { + LOG_ERR("Bad name"); + return -1; + } + msg.code = IRM_REG_IPCP; msg.name = &name; msg.difs = difs; @@ -149,6 +174,11 @@ int irm_unreg_ipcp(rina_name_t name, { struct irm_msg msg; + if (!name_is_ok(&name)) { + LOG_ERR("Bad name"); + return -1; + } + msg.code = IRM_UNREG_IPCP; msg.name = &name; msg.difs = difs; diff --git a/src/lib/rina_name.c b/src/lib/rina_name.c new file mode 100644 index 00000000..b9044277 --- /dev/null +++ b/src/lib/rina_name.c @@ -0,0 +1,331 @@ +/* + * RINA naming related utilities + * + * Sander Vrijders <[email protected]> + * Francesco Salvestrini <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define OUROBOROS_PREFIX "name-utils" + +#include <ouroboros/logs.h> +#include <ouroboros/common.h> +#include <ouroboros/rina_name.h> + +#include <string.h> +#include <math.h> +#include <malloc.h> +#include <stdlib.h> + +static char * strdup(const char * src) +{ + int len = 0; + char * dst = NULL; + + if (src == NULL) + return NULL; + + len = strlen(src) + 1; + + dst = malloc(len); + if (dst == NULL) + return NULL; + + memcpy(dst, src, len); + + return dst; +} + +rina_name_t * name_create() +{ + rina_name_t * tmp; + + tmp = malloc(sizeof(rina_name_t)); + + tmp->ap_name = NULL; + tmp->api_id = 0; + tmp->ae_name = NULL; + tmp->aei_id = 0; + + return tmp; +} + +rina_name_t * name_init_from(rina_name_t * dst, + const char * ap_name, + unsigned int api_id, + const char * ae_name, + unsigned int aei_id) +{ + if (dst == NULL) + return NULL; + + /* Clean up the destination, leftovers might be there ... */ + name_fini(dst); + + dst->ap_name = strdup(ap_name); + dst->api_id = api_id; + dst->ae_name = strdup(ae_name); + dst->aei_id = aei_id; + + if (dst->ap_name == NULL || + dst->ae_name == NULL) { + name_fini(dst); + return NULL; + } + + return dst; +} + +rina_name_t * name_init_with(rina_name_t * dst, + char * ap_name, + unsigned int api_id, + char * ae_name, + unsigned int aei_id) +{ + if (dst == NULL) + return NULL; + + /* Clean up the destination, leftovers might be there ... */ + name_fini(dst); + + dst->ap_name = ap_name; + dst->api_id = api_id; + dst->ae_name = ae_name; + dst->aei_id = aei_id; + + return dst; +} + +void name_fini(rina_name_t * n) +{ + if (n == NULL) + return; + + if (n->ap_name != NULL) { + free(n->ap_name); + n->ap_name = NULL; + } + + if (n->ae_name != NULL) { + free(n->ae_name); + n->ae_name = NULL; + } +} + +void name_destroy(rina_name_t * ptr) +{ + if (ptr == NULL) + return; + + name_fini(ptr); + + free(ptr); +} + +int name_cpy(const rina_name_t * src, + rina_name_t * dst) +{ + rina_name_t * res; + + if (src == NULL || dst == NULL) + return -1; + + res = name_init_from(dst, + src->ap_name, + src->api_id, + src->ae_name, + src->aei_id); + if (res == NULL) + return -1; + + return 0; +} + +rina_name_t * name_dup(const rina_name_t * src) +{ + rina_name_t * tmp; + + if (src == NULL) + return NULL; + + tmp = name_create(); + if (tmp == NULL) + return NULL; + + if (name_cpy(src, tmp)) { + name_destroy(tmp); + return NULL; + } + + return tmp; +} + +#define NAME_CMP_FIELD(X, Y, FIELD) \ + ((X->FIELD != NULL && Y->FIELD != NULL) ? \ + strcmp(X->FIELD, Y->FIELD) : \ + ((X->FIELD == NULL && Y->FIELD == NULL) ? 0 : -1)) + +bool name_is_ok(const rina_name_t * n) +{ return (n != NULL && + n->ap_name != NULL && + strlen(n->ap_name) && + n->ae_name != NULL); } + +bool name_cmp(uint8_t flags, + const rina_name_t * a, + const rina_name_t * b) +{ + if (a == b) + return true; + + if (a == NULL || b == NULL) + return false; + + if (!(flags & NAME_CMP_ALL)) + LOG_DBG("No flags, name comparison will be meaningless ..."); + + if (flags & NAME_CMP_APN) + if (NAME_CMP_FIELD(a, b, ap_name)) + return false; + + if (flags & NAME_CMP_API) + if (a->api_id != b->api_id) + return false; + + if (flags & NAME_CMP_AEN) + if (NAME_CMP_FIELD(a, b, ae_name)) + return false; + + if (flags & NAME_CMP_AEI) + if (a->aei_id != b->aei_id) + return false; + + return true; +} + +bool name_is_equal(const rina_name_t * a, + const rina_name_t * b) +{ return name_cmp(NAME_CMP_ALL, a, b); } + +static int n_digits(unsigned i) +{ + int n = 1; + + while (i > 9) { + n++; + i /= 10; + } + + return n; +} + +#define DELIMITER "/" + +char * name_to_string(const rina_name_t * n) +{ + char * tmp; + size_t size; + const char * none = ""; + size_t none_len = strlen(none); + + if (n == NULL) + return NULL; + + size = 0; + + size += (n->ap_name != NULL ? + strlen(n->ap_name) : none_len); + size += strlen(DELIMITER); + + size += (n->api_id == 0 ? + 1 : n_digits(n->api_id)); + size += strlen(DELIMITER); + + size += (n->ae_name != NULL ? + strlen(n->ae_name) : none_len); + size += strlen(DELIMITER); + + size += (n->aei_id == 0 ? + 1 : n_digits(n->aei_id)); + size += strlen(DELIMITER); + + tmp = malloc(size); + if (!tmp) + return NULL; + + if (sprintf(tmp, "%s%s%d%s%s%s%d", + (n->ap_name != NULL ? n->ap_name : none), + DELIMITER, n->api_id, + DELIMITER, (n->ae_name != NULL ? n->ae_name : none), + DELIMITER, n->aei_id) + != size - 1) { + free(tmp); + return NULL; + } + + return tmp; +} + +rina_name_t * string_to_name(const char * s) +{ + rina_name_t * name; + + char * tmp1 = NULL; + char * tmp_ap = NULL; + char * tmp_s_api = NULL; + unsigned int tmp_api = 0; + char * tmp_ae = NULL; + char * tmp_s_aei = NULL; + unsigned int tmp_aei = 0; + char * tmp2; + + if (s == NULL) + return NULL; + + tmp1 = strdup(s); + if (tmp1 == NULL) { + return NULL; + } + + tmp_ap = strtok(tmp1, DELIMITER); + tmp_s_api = strtok(NULL, DELIMITER); + if (tmp_s_api != NULL) + tmp_api = (unsigned int) strtol(tmp_s_api, &tmp2, 10); + tmp_ae = strtok(NULL, DELIMITER); + tmp_s_aei = strtok(NULL, DELIMITER); + if (tmp_s_aei != NULL) + tmp_aei = (unsigned int) strtol(tmp_s_aei, &tmp2, 10); + + name = name_create(); + if (name == NULL) { + if (tmp1 != NULL) + free(tmp1); + return NULL; + } + + if (!name_init_from(name, tmp_ap, tmp_api, + tmp_ae, tmp_aei)) { + name_destroy(name); + if (tmp1 != NULL) + free(tmp1); + return NULL; + } + + if (tmp1 != NULL) + free(tmp1); + + return name; +} diff --git a/src/lib/sockets.c b/src/lib/sockets.c index eebd223b..90117c5c 100644 --- a/src/lib/sockets.c +++ b/src/lib/sockets.c @@ -137,7 +137,7 @@ static int deser_copy_string(uint8_t * data, } static void deser_copy_int(uint8_t * data, - int * dst, + unsigned int * dst, int * offset) { *dst = 0; @@ -185,9 +185,7 @@ buffer_t * serialize_irm_msg(struct irm_msg * msg) ser_copy_value(sizeof(enum irm_msg_code), data, &msg->code, &offset); - if (msg->name == NULL || - msg->name->ap_name == NULL || - msg->name->ae_name == NULL ) { + if (!name_is_ok(msg->name)) { LOG_ERR("Null pointer passed"); free(buf->data); free(buf); @@ -285,7 +283,7 @@ struct irm_msg * deserialize_irm_msg(buffer_t * data) deser_copy_enum(data->data, &msg->code, &offset); - msg->name = malloc(sizeof(*(msg->name))); + msg->name = name_create(); if (msg->name == NULL) { LOG_ERR("Failed to alloc memory"); free(msg); @@ -295,7 +293,7 @@ struct irm_msg * deserialize_irm_msg(buffer_t * data) if (deser_copy_string(data->data, &msg->name->ap_name, &offset)) { - free(msg->name); + name_destroy(msg->name); free(msg); return NULL; } @@ -305,8 +303,7 @@ struct irm_msg * deserialize_irm_msg(buffer_t * data) if (deser_copy_string(data->data, &msg->name->ae_name, &offset)) { - free(msg->name->ap_name); - free(msg->name); + name_destroy(msg->name); free(msg); return NULL; } @@ -318,11 +315,9 @@ struct irm_msg * deserialize_irm_msg(buffer_t * data) if (deser_copy_string(data->data, &msg->ipcp_type, &offset)) { - free(msg->name->ae_name); - free(msg->name->ap_name); - free(msg->name); - free(msg); - return NULL; + name_destroy(msg->name); + free(msg); + return NULL; } break; @@ -334,9 +329,7 @@ struct irm_msg * deserialize_irm_msg(buffer_t * data) if (deser_copy_string(data->data, &msg->dif_name, &offset)) { - free(msg->name->ae_name); - free(msg->name->ap_name); - free(msg->name); + name_destroy(msg->name); free(msg); return NULL; } @@ -348,9 +341,7 @@ struct irm_msg * deserialize_irm_msg(buffer_t * data) msg->difs = malloc(sizeof(*(msg->difs)) * difs_size); if (msg->difs == NULL) { - free(msg->name->ae_name); - free(msg->name->ap_name); - free(msg->name); + name_destroy(msg->name); free(msg); return NULL; } @@ -362,9 +353,7 @@ struct irm_msg * deserialize_irm_msg(buffer_t * data) for (j = 0; j < i; j++) free(msg->difs[j]); free(msg->difs); - free(msg->name->ae_name); - free(msg->name->ap_name); - free(msg->name); + name_destroy(msg->name); free(msg); return NULL; } diff --git a/src/tools/irm/irm.c b/src/tools/irm/irm.c index 0325c810..426118d1 100644 --- a/src/tools/irm/irm.c +++ b/src/tools/irm/irm.c @@ -21,6 +21,7 @@ */ #include <ouroboros/common.h> +#include <ouroboros/rina_name.h> #include <ouroboros/irm.h> #include <stdio.h> #include <string.h> diff --git a/src/tools/irm/irm_utils.h b/src/tools/irm/irm_utils.h index 9332b108..2a478d09 100644 --- a/src/tools/irm/irm_utils.h +++ b/src/tools/irm/irm_utils.h @@ -20,6 +20,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <ouroboros/rina_name.h> + #include <stdbool.h> int matches(const char * cmd, const char * pattern); |