summaryrefslogtreecommitdiff
path: root/src/tools/oping/oping_client.c
diff options
context:
space:
mode:
authordimitri staessens <[email protected]>2016-10-27 17:57:16 +0200
committerdimitri staessens <[email protected]>2016-10-27 17:57:16 +0200
commitff7e5c12c9d50fb2ba79d045e99a7ede602ed6f3 (patch)
treecd630cd207a83794648bcc3f86441dc3a3c81607 /src/tools/oping/oping_client.c
parent52b411b0388cecfeff36a4098305453b4aa239da (diff)
downloadouroboros-ff7e5c12c9d50fb2ba79d045e99a7ede602ed6f3.tar.gz
ouroboros-ff7e5c12c9d50fb2ba79d045e99a7ede602ed6f3.zip
lib: Clean up flow if alloc_res fails
If alloc_res fails all resources will be cleaned, except for the assigned flow_descriptor, which must be released with a dealloc call. Calling dealloc after a failed flow_alloc will not try to destroy the already cleaned up flow in the IRMd and IPCPs. Also fixes some memleaks in the oping client.
Diffstat (limited to 'src/tools/oping/oping_client.c')
-rw-r--r--src/tools/oping/oping_client.c101
1 files changed, 64 insertions, 37 deletions
diff --git a/src/tools/oping/oping_client.c b/src/tools/oping/oping_client.c
index 85cb2880..1ce96a75 100644
--- a/src/tools/oping/oping_client.c
+++ b/src/tools/oping/oping_client.c
@@ -162,6 +162,51 @@ void * writer(void * o)
return (void *) 0;
}
+static int client_init(void)
+{
+ client.flows = flow_set_create();
+ if (client.flows == NULL)
+ return -ENOMEM;
+
+ client.fq = fqueue_create();
+ if (client.fq == NULL) {
+ flow_set_destroy(client.flows);
+ return -ENOMEM;
+ }
+
+ client.times = malloc(sizeof(struct timespec) * client.count);
+ if (client.times == NULL) {
+ flow_set_destroy(client.flows);
+ fqueue_destroy(client.fq);
+ pthread_mutex_unlock(&client.lock);
+ return -ENOMEM;
+ }
+
+ client.sent = 0;
+ client.rcvd = 0;
+ client.rtt_min = FLT_MAX;
+ client.rtt_max = 0;
+ client.rtt_avg = 0;
+ client.rtt_m2 = 0;
+
+ pthread_mutex_init(&client.lock, NULL);
+ pthread_mutex_lock(&client.lock);
+
+ return 0;
+}
+
+void client_fini(void)
+{
+ if (client.flows != NULL)
+ flow_set_destroy(client.flows);
+
+ if (client.fq != NULL)
+ fqueue_destroy(client.fq);
+
+ if (client.times != NULL)
+ free(client.times);
+}
+
int client_main(void)
{
struct sigaction sig_act;
@@ -171,18 +216,27 @@ int client_main(void)
int fd;
- client.flows = flow_set_create();
- if (client.flows == NULL)
+ memset(&sig_act, 0, sizeof sig_act);
+ sig_act.sa_sigaction = &shutdown_client;
+ sig_act.sa_flags = 0;
+
+ if (sigaction(SIGINT, &sig_act, NULL) ||
+ sigaction(SIGTERM, &sig_act, NULL) ||
+ sigaction(SIGHUP, &sig_act, NULL) ||
+ sigaction(SIGPIPE, &sig_act, NULL)) {
+ printf("Failed to install sighandler.\n");
return -1;
+ }
- client.fq = fqueue_create();
- if (client.fq == NULL) {
- flow_set_destroy(client.flows);
+ if (client_init()) {
+ printf("Failed to initialize client.\n");
return -1;
}
fd = flow_alloc(client.s_apn, NULL, NULL);
if (fd < 0) {
+ flow_set_destroy(client.flows);
+ fqueue_destroy(client.fq);
printf("Failed to allocate flow.\n");
return -1;
}
@@ -191,36 +245,12 @@ int client_main(void)
if (flow_alloc_res(fd)) {
printf("Flow allocation refused.\n");
+ flow_set_del(client.flows, fd);
flow_dealloc(fd);
+ client_fini();
return -1;
}
- memset(&sig_act, 0, sizeof sig_act);
- sig_act.sa_sigaction = &shutdown_client;
- sig_act.sa_flags = 0;
-
- if (sigaction(SIGINT, &sig_act, NULL) ||
- sigaction(SIGTERM, &sig_act, NULL) ||
- sigaction(SIGHUP, &sig_act, NULL) ||
- sigaction(SIGPIPE, &sig_act, NULL)) {
- printf("Failed to install sighandler.\n");
- return -1;
- }
-
- pthread_mutex_init(&client.lock, NULL);
- pthread_mutex_lock(&client.lock);
- client.sent = 0;
- client.rcvd = 0;
- client.rtt_min = FLT_MAX;
- client.rtt_max = 0;
- client.rtt_avg = 0;
- client.rtt_m2 = 0;
- client.times = malloc(sizeof(struct timespec) * client.count);
- if (client.times == NULL) {
- pthread_mutex_unlock(&client.lock);
- return -ENOMEM;
- }
-
pthread_mutex_unlock(&client.lock);
clock_gettime(CLOCK_REALTIME, &tic);
@@ -253,14 +283,11 @@ int client_main(void)
printf("NaN ms\n");
}
- pthread_mutex_lock(&client.lock);
- free(client.times);
- flow_set_destroy(client.flows);
- fqueue_destroy(client.fq);
- pthread_mutex_unlock(&client.lock);
- pthread_mutex_destroy(&client.lock);
+ flow_set_del(client.flows, fd);
flow_dealloc(fd);
+ client_fini();
+
return 0;
}