From db218bbe19b66a382df5f665981b7b16f1901bc9 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Thu, 17 Aug 2017 16:35:36 +0200 Subject: irmd: Handle IPCP creation fails gracefully --- src/irmd/ipcp.c | 53 ++++++++++++++++++++++++----------------------------- src/irmd/main.c | 34 ++++++++++++++++++++++++++++------ 2 files changed, 52 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c index ade09625..f3f97811 100644 --- a/src/irmd/ipcp.c +++ b/src/irmd/ipcp.c @@ -130,13 +130,34 @@ pid_t ipcp_create(const char * name, enum ipcp_type ipcp_type) { pid_t api = -1; - size_t len = 0; char * ipcp_dir = "/sbin/"; - char * full_name = NULL; char * exec_name = NULL; char irmd_api[10]; + char full_name[256]; char * argv[5]; + switch(ipcp_type) { + case IPCP_NORMAL: + exec_name = IPCP_NORMAL_EXEC; + break; + case IPCP_SHIM_UDP: + exec_name = IPCP_SHIM_UDP_EXEC; + break; + case IPCP_SHIM_ETH_LLC: + exec_name = IPCP_SHIM_ETH_LLC_EXEC; + break; + case IPCP_LOCAL: + exec_name = IPCP_LOCAL_EXEC; + break; + default: + return -1; + } + + if (strlen(exec_name) == 0) { + log_err("IPCP type not installed."); + return -1; + } + sprintf(irmd_api, "%u", getpid()); api = fork(); @@ -148,33 +169,9 @@ pid_t ipcp_create(const char * name, if (api != 0) return api; - if (ipcp_type == IPCP_NORMAL) - exec_name = IPCP_NORMAL_EXEC; - else if (ipcp_type == IPCP_SHIM_UDP) - exec_name = IPCP_SHIM_UDP_EXEC; - else if (ipcp_type == IPCP_SHIM_ETH_LLC) - exec_name = IPCP_SHIM_ETH_LLC_EXEC; - else if (ipcp_type == IPCP_LOCAL) - exec_name = IPCP_LOCAL_EXEC; - else - exit(EXIT_FAILURE); - - len += strlen(INSTALL_PREFIX); - len += strlen(ipcp_dir); - len += strlen(exec_name); - len += 1; - - full_name = malloc(len + 1); - if (full_name == NULL) { - log_err("Failed to malloc"); - exit(EXIT_FAILURE); - } - strcpy(full_name, INSTALL_PREFIX); strcat(full_name, ipcp_dir); strcat(full_name, exec_name); - full_name[len] = '\0'; - /* log_file to be placed at the end */ argv[0] = full_name; @@ -190,9 +187,7 @@ pid_t ipcp_create(const char * name, execv(argv[0], &argv[0]); log_dbg("%s", strerror(errno)); - log_err("Failed to load IPCP daemon"); - log_err("Make sure to run the installed version"); - free(full_name); + log_err("Failed to load IPCP daemon."); exit(EXIT_FAILURE); } diff --git a/src/irmd/main.c b/src/irmd/main.c index 61ce6a49..0c157fd4 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -275,6 +275,11 @@ static pid_t create_ipcp(char * name, struct ipcp_entry * tmp = NULL; struct list_head * p = NULL; struct ipcp_entry * entry = NULL; + int ret = 0; + pthread_condattr_t cattr; + struct timespec dl; + struct timespec to = {SOCKET_TIMEOUT / 1000, + (SOCKET_TIMEOUT % 1000) * MILLION}; api = malloc(sizeof(*api)); if (api == NULL) @@ -311,13 +316,20 @@ static pid_t create_ipcp(char * name, pthread_rwlock_unlock(&irmd.reg_lock); return -1; } + pthread_condattr_init(&cattr); +#ifndef __APPLE__ + pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK); +#endif + + pthread_cond_init(&tmp->init_cond, &cattr); + + pthread_condattr_destroy(&cattr); - pthread_cond_init(&tmp->init_cond, NULL); pthread_mutex_init(&tmp->init_lock, NULL); - tmp->dif_name = NULL; - tmp->type = ipcp_type; - tmp->init = false; + tmp->dif_name = NULL; + tmp->type = ipcp_type; + tmp->init = false; tmp->dir_hash_algo = -1; list_for_each(p, &irmd.ipcps) { @@ -334,11 +346,21 @@ static pid_t create_ipcp(char * name, pthread_mutex_lock(&tmp->init_lock); - while (tmp->init == false) - pthread_cond_wait(&tmp->init_cond, &tmp->init_lock); + clock_gettime(PTHREAD_COND_CLOCK, &dl); + ts_add(&dl, &to, &dl); + while (tmp->init == false && ret != -ETIMEDOUT) + ret = -pthread_cond_timedwait(&tmp->init_cond, + &tmp->init_lock, + &dl); pthread_mutex_unlock(&tmp->init_lock); + if (ret == -ETIMEDOUT) { + log_err("Process %d failed to respond.", api->pid); + kill(api->pid, SIGKILL); + return -1; + } + log_info("Created IPCP %d.", api->pid); return api->pid; -- cgit v1.2.3