diff options
Diffstat (limited to 'src/ipcpd/normal/dir.c')
-rw-r--r-- | src/ipcpd/normal/dir.c | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/src/ipcpd/normal/dir.c b/src/ipcpd/normal/dir.c new file mode 100644 index 00000000..2b3742d9 --- /dev/null +++ b/src/ipcpd/normal/dir.c @@ -0,0 +1,215 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * DIF directory + * + * Sander Vrijders <[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 "directory" + +#include <ouroboros/config.h> +#include <ouroboros/logs.h> +#include <ouroboros/errno.h> + +#include "dir.h" +#include "ipcp.h" +#include "ro.h" +#include "path.h" +#include "ribmgr.h" + +#include <stdlib.h> +#include <string.h> + +char * create_path(char * name) +{ + char * path; + + path = pathname_create(RO_DIR); + if (path == NULL) + return NULL; + + path = pathname_append(path, name); + if (path == NULL) { + pathname_destroy(path); + return NULL; + } + + return path; +} + +int dir_init(void) +{ + char * path; + struct ro_attr attr; + + ro_attr_init(&attr); + attr.enrol_sync = true; + attr.recv_set = ALL_MEMBERS; + + path = pathname_create(RO_DIR); + if (path == NULL) + return -1; + + if (ro_create(path, &attr, NULL, 0)) { + pathname_destroy(path); + LOG_ERR("Failed to create RIB object."); + return -1; + } + + pathname_destroy(path); + + return 0; +} + +int dir_fini(void) +{ + char * path; + + path = pathname_create(RO_DIR); + if (path == NULL) + return -1; + + ro_delete(path); + pathname_destroy(path); + + return 0; +} + +int dir_name_reg(char * name) +{ + struct ro_attr attr; + char * path; + uint64_t * addr; + + pthread_rwlock_rdlock(&ipcpi.state_lock); + + if (ipcp_get_state() != IPCP_RUNNING) { + pthread_rwlock_unlock(&ipcpi.state_lock); + LOG_ERR("IPCP is not in RUNNING state."); + return -1; + } + + ro_attr_init(&attr); + attr.enrol_sync = true; + attr.recv_set = ALL_MEMBERS; + + path = create_path(name); + if (path == NULL) { + pthread_rwlock_unlock(&ipcpi.state_lock); + return -ENOMEM; + } + + addr = malloc(sizeof(*addr)); + if (addr == NULL) { + pthread_rwlock_unlock(&ipcpi.state_lock); + pathname_destroy(path); + return -ENOMEM; + } + *addr = ribmgr_address(); + + if (ro_create(path, &attr, (uint8_t *) addr, sizeof(*addr))) { + pthread_rwlock_unlock(&ipcpi.state_lock); + pathname_destroy(path); + LOG_ERR("Failed to create RIB object."); + return -1; + } + + pthread_rwlock_unlock(&ipcpi.state_lock); + + LOG_DBG("Registered %s.", name); + pathname_destroy(path); + + return 0; +} + +int dir_name_unreg(char * name) +{ + char * path; + + pthread_rwlock_rdlock(&ipcpi.state_lock); + + if (ipcp_get_state() != IPCP_RUNNING) { + pthread_rwlock_unlock(&ipcpi.state_lock); + LOG_ERR("IPCP is not in RUNNING state."); + return -1; + } + + path = create_path(name); + if (path == NULL) { + pthread_rwlock_unlock(&ipcpi.state_lock); + return -ENOMEM; + } + + if (ro_delete(path)) { + pthread_rwlock_unlock(&ipcpi.state_lock); + pathname_destroy(path); + LOG_ERR("No such RIB object exists."); + return -1; + } + + pthread_rwlock_unlock(&ipcpi.state_lock); + + pathname_destroy(path); + + return 0; +} + +int dir_name_query(char * name) +{ + char * path; + int ret = -1; + uint8_t * ro_data; + uint64_t addr; + struct dt_const * dtc; + + pthread_rwlock_rdlock(&ipcpi.state_lock); + + if (ipcp_get_state() != IPCP_RUNNING) { + pthread_rwlock_unlock(&ipcpi.state_lock); + return -1; + } + + path = create_path(name); + if (path == NULL) { + pthread_rwlock_unlock(&ipcpi.state_lock); + return -1; + } + + if (ro_exists(path)) { + if (ro_read(path, &ro_data) < 0) { + pathname_destroy(path); + return -1; + } + addr = *((uint64_t *) ro_data); + free(ro_data); + + dtc = ribmgr_dt_const(); + if (dtc == NULL) { + pathname_destroy(path); + return -1; + } + + ret = (addr == ribmgr_address()) ? -1 : 0; + } + + pthread_rwlock_unlock(&ipcpi.state_lock); + + pathname_destroy(path); + + return ret; +} |