aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dns/gnunet-service-dns.c2
-rw-r--r--src/exit/gnunet-daemon-exit.c2
-rw-r--r--src/fs/fs_dirmetascan.c4
-rw-r--r--src/include/gnunet_helper_lib.h42
-rw-r--r--src/testbed/gnunet-service-testbed.c3
-rw-r--r--src/testbed/gnunet-service-testbed_links.c57
-rw-r--r--src/testbed/test_gnunet_helper_testbed.c2
-rw-r--r--src/testbed/testbed_api_hosts.c43
-rw-r--r--src/testbed/testbed_api_hosts.h20
-rw-r--r--src/transport/plugin_transport_wlan.c2
-rw-r--r--src/transport/test_plugin_transport.c4
-rw-r--r--src/util/helper.c140
-rw-r--r--src/vpn/gnunet-service-vpn.c4
13 files changed, 222 insertions, 103 deletions
diff --git a/src/dns/gnunet-service-dns.c b/src/dns/gnunet-service-dns.c
index 5e9de5f4d..4a94283ab 100644
--- a/src/dns/gnunet-service-dns.c
+++ b/src/dns/gnunet-service-dns.c
@@ -281,7 +281,7 @@ cleanup_task (void *cls GNUNET_UNUSED,
281{ 281{
282 unsigned int i; 282 unsigned int i;
283 283
284 GNUNET_HELPER_stop (hijacker); 284 GNUNET_HELPER_stop (hijacker, GNUNET_NO);
285 hijacker = NULL; 285 hijacker = NULL;
286 for (i=0;i<7;i++) 286 for (i=0;i<7;i++)
287 GNUNET_free_non_null (helper_argv[i]); 287 GNUNET_free_non_null (helper_argv[i]);
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c
index 72522e121..fbf173086 100644
--- a/src/exit/gnunet-daemon-exit.c
+++ b/src/exit/gnunet-daemon-exit.c
@@ -3074,7 +3074,7 @@ cleanup (void *cls GNUNET_UNUSED,
3074 3074
3075 if (helper_handle != NULL) 3075 if (helper_handle != NULL)
3076 { 3076 {
3077 GNUNET_HELPER_stop (helper_handle); 3077 GNUNET_HELPER_stop (helper_handle, GNUNET_NO);
3078 helper_handle = NULL; 3078 helper_handle = NULL;
3079 } 3079 }
3080 if (mesh_handle != NULL) 3080 if (mesh_handle != NULL)
diff --git a/src/fs/fs_dirmetascan.c b/src/fs/fs_dirmetascan.c
index e5a575a51..7139ea45a 100644
--- a/src/fs/fs_dirmetascan.c
+++ b/src/fs/fs_dirmetascan.c
@@ -102,7 +102,7 @@ GNUNET_FS_directory_scan_abort (struct GNUNET_FS_DirScanner *ds)
102{ 102{
103 /* terminate helper */ 103 /* terminate helper */
104 if (NULL != ds->helper) 104 if (NULL != ds->helper)
105 GNUNET_HELPER_stop (ds->helper); 105 GNUNET_HELPER_stop (ds->helper, GNUNET_NO);
106 106
107 /* free resources */ 107 /* free resources */
108 if (NULL != ds->toplevel) 108 if (NULL != ds->toplevel)
@@ -234,7 +234,7 @@ finish_scan (void *cls,
234 ds->stop_task = GNUNET_SCHEDULER_NO_TASK; 234 ds->stop_task = GNUNET_SCHEDULER_NO_TASK;
235 if (NULL != ds->helper) 235 if (NULL != ds->helper)
236 { 236 {
237 GNUNET_HELPER_stop (ds->helper); 237 GNUNET_HELPER_stop (ds->helper, GNUNET_NO);
238 ds->helper = NULL; 238 ds->helper = NULL;
239 } 239 }
240 ds->progress_callback (ds->progress_callback_cls, 240 ds->progress_callback (ds->progress_callback_cls,
diff --git a/src/include/gnunet_helper_lib.h b/src/include/gnunet_helper_lib.h
index 191d97b80..06d65b360 100644
--- a/src/include/gnunet_helper_lib.h
+++ b/src/include/gnunet_helper_lib.h
@@ -20,7 +20,8 @@
20 20
21/** 21/**
22 * @file include/gnunet_helper_lib.h 22 * @file include/gnunet_helper_lib.h
23 * @brief API for dealing with (SUID) helper processes that communicate via GNUNET_MessageHeaders on stdin/stdout 23 * @brief API for dealing with (SUID) helper processes that communicate via
24 * GNUNET_MessageHeaders on stdin/stdout
24 * @author Philipp Toelke 25 * @author Philipp Toelke
25 * @author Christian Grothoff 26 * @author Christian Grothoff
26 */ 27 */
@@ -72,22 +73,49 @@ GNUNET_HELPER_start (int with_control_pipe,
72 73
73 74
74/** 75/**
75 * Kills the helper, closes the pipe and frees the handle 76 * Sends termination signal to the helper process. The helper process is not
77 * reaped; call GNUNET_HELPER_wait() for reaping the dead helper process.
76 * 78 *
77 * @param h handle to helper to stop 79 * @param h the helper handle
80 * @param soft_kill if GNUNET_YES, signals termination by closing the helper's
81 * stdin; GNUNET_NO to signal termination by sending SIGTERM to helper
82 * @return GNUNET_OK on success; GNUNET_SYSERR on error
83 */
84int
85GNUNET_HELPER_kill (struct GNUNET_HELPER_Handle *h, int soft_kill);
86
87
88/**
89 * Reap the helper process. This call is blocking(!). The helper process
90 * should either be sent a termination signal before or should be dead before
91 * calling this function
92 *
93 * @param h the helper handle
94 * @return GNUNET_OK on success; GNUNET_SYSERR on error
95 */
96int
97GNUNET_HELPER_wait (struct GNUNET_HELPER_Handle *h);
98
99
100/**
101 * Free's the resources occupied by the helper handle
102 *
103 * @param h the helper handle to free
78 */ 104 */
79void 105void
80GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h); 106GNUNET_HELPER_destroy (struct GNUNET_HELPER_Handle *h);
81 107
82 108
83/** 109/**
84 * Kills the helper by closing its stdin (the helper is expected to catch the 110 * Kills the helper, closes the pipe, frees the handle and calls wait() on the
85 * resulting SIGPIPE and shutdown), closes the pipe and frees the handle 111 * helper process
86 * 112 *
87 * @param h handle to helper to stop 113 * @param h handle to helper to stop
114 * @param soft_kill if GNUNET_YES, signals termination by closing the helper's
115 * stdin; GNUNET_NO to signal termination by sending SIGTERM to helper
88 */ 116 */
89void 117void
90GNUNET_HELPER_soft_stop (struct GNUNET_HELPER_Handle *h); 118GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h, int soft_kill);
91 119
92 120
93/** 121/**
diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c
index bb791988e..1b74ad1df 100644
--- a/src/testbed/gnunet-service-testbed.c
+++ b/src/testbed/gnunet-service-testbed.c
@@ -785,7 +785,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
785 uint32_t id; 785 uint32_t id;
786 786
787 shutdown_task_id = GNUNET_SCHEDULER_NO_TASK; 787 shutdown_task_id = GNUNET_SCHEDULER_NO_TASK;
788 LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down testbed service\n"); 788 LOG_DEBUG ("Shutting down testbed service\n");
789 /* cleanup any remaining forwarded operations */ 789 /* cleanup any remaining forwarded operations */
790 GST_clear_fopcq (); 790 GST_clear_fopcq ();
791 GST_free_lcfq (); 791 GST_free_lcfq ();
@@ -904,6 +904,7 @@ testbed_run (void *cls, struct GNUNET_SERVER_Handle *server,
904 char *logfile; 904 char *logfile;
905 unsigned long long num; 905 unsigned long long num;
906 906
907 LOG_DEBUG ("Starting testbed\n");
907 if (GNUNET_OK == 908 if (GNUNET_OK ==
908 GNUNET_CONFIGURATION_get_value_filename (cfg, "TESTBED", "LOG_FILE", 909 GNUNET_CONFIGURATION_get_value_filename (cfg, "TESTBED", "LOG_FILE",
909 &logfile)) 910 &logfile))
diff --git a/src/testbed/gnunet-service-testbed_links.c b/src/testbed/gnunet-service-testbed_links.c
index bcf8d91c8..7b0006d1f 100644
--- a/src/testbed/gnunet-service-testbed_links.c
+++ b/src/testbed/gnunet-service-testbed_links.c
@@ -425,32 +425,47 @@ reghost_free_iterator (void *cls, const struct GNUNET_HashCode *key,
425void 425void
426GST_slave_list_clear () 426GST_slave_list_clear ()
427{ 427{
428 unsigned int id;
429 struct HostRegistration *hr_entry; 428 struct HostRegistration *hr_entry;
429 struct GNUNET_TESTBED_ControllerProc *cproc;
430 unsigned int id;
430 431
431 for (id = 0; id < GST_slave_list_size; id++) 432 for (id = 0; id < GST_slave_list_size; id++)
432 if (NULL != GST_slave_list[id]) 433 {
434 if (NULL == GST_slave_list[id])
435 continue;
436 while (NULL != (hr_entry = GST_slave_list[id]->hr_dll_head))
433 { 437 {
434 while (NULL != (hr_entry = GST_slave_list[id]->hr_dll_head)) 438 GNUNET_CONTAINER_DLL_remove (GST_slave_list[id]->hr_dll_head,
435 { 439 GST_slave_list[id]->hr_dll_tail, hr_entry);
436 GNUNET_CONTAINER_DLL_remove (GST_slave_list[id]->hr_dll_head, 440 GNUNET_free (hr_entry);
437 GST_slave_list[id]->hr_dll_tail, hr_entry); 441 }
438 GNUNET_free (hr_entry); 442 if (NULL != GST_slave_list[id]->rhandle)
439 } 443 GNUNET_TESTBED_cancel_registration (GST_slave_list[id]->rhandle);
440 if (NULL != GST_slave_list[id]->rhandle) 444 (void)
441 GNUNET_TESTBED_cancel_registration (GST_slave_list[id]->rhandle); 445 GNUNET_CONTAINER_multihashmap_iterate (GST_slave_list
442 (void) 446 [id]->reghost_map,
443 GNUNET_CONTAINER_multihashmap_iterate (GST_slave_list 447 reghost_free_iterator,
444 [id]->reghost_map, 448 GST_slave_list[id]);
445 reghost_free_iterator, 449 GNUNET_CONTAINER_multihashmap_destroy (GST_slave_list[id]->reghost_map);
446 GST_slave_list[id]); 450 if (NULL != GST_slave_list[id]->controller)
447 GNUNET_CONTAINER_multihashmap_destroy (GST_slave_list[id]->reghost_map); 451 GNUNET_TESTBED_controller_disconnect (GST_slave_list[id]->controller);
448 if (NULL != GST_slave_list[id]->controller) 452 if (NULL != (cproc = GST_slave_list[id]->controller_proc))
449 GNUNET_TESTBED_controller_disconnect (GST_slave_list[id]->controller); 453 {
450 if (NULL != GST_slave_list[id]->controller_proc) 454 LOG_DEBUG ("Stopping a slave\n");
451 GNUNET_TESTBED_controller_stop (GST_slave_list[id]->controller_proc); 455 GNUNET_TESTBED_controller_kill_ (cproc);
452 GNUNET_free (GST_slave_list[id]);
453 } 456 }
457 }
458 for (id = 0; id < GST_slave_list_size; id++)
459 {
460 if (NULL == GST_slave_list[id])
461 continue;
462 if (NULL != (cproc = GST_slave_list[id]->controller_proc))
463 {
464 GNUNET_TESTBED_controller_destroy_ (cproc);
465 LOG_DEBUG ("Slave stopped\n");
466 }
467 GNUNET_free (GST_slave_list[id]);
468 }
454 GNUNET_free_non_null (GST_slave_list); 469 GNUNET_free_non_null (GST_slave_list);
455 GST_slave_list = NULL; 470 GST_slave_list = NULL;
456} 471}
diff --git a/src/testbed/test_gnunet_helper_testbed.c b/src/testbed/test_gnunet_helper_testbed.c
index 0c7c5f27e..cf4559c26 100644
--- a/src/testbed/test_gnunet_helper_testbed.c
+++ b/src/testbed/test_gnunet_helper_testbed.c
@@ -88,7 +88,7 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
88 if (GNUNET_SCHEDULER_NO_TASK != abort_task) 88 if (GNUNET_SCHEDULER_NO_TASK != abort_task)
89 GNUNET_SCHEDULER_cancel (abort_task); 89 GNUNET_SCHEDULER_cancel (abort_task);
90 if (NULL != helper) 90 if (NULL != helper)
91 GNUNET_HELPER_stop (helper); 91 GNUNET_HELPER_stop (helper, GNUNET_NO);
92 GNUNET_free_non_null (msg); 92 GNUNET_free_non_null (msg);
93 if (NULL != cfg) 93 if (NULL != cfg)
94 GNUNET_CONFIGURATION_destroy (cfg); 94 GNUNET_CONFIGURATION_destroy (cfg);
diff --git a/src/testbed/testbed_api_hosts.c b/src/testbed/testbed_api_hosts.c
index f61129b85..c386d18a0 100644
--- a/src/testbed/testbed_api_hosts.c
+++ b/src/testbed/testbed_api_hosts.c
@@ -1261,20 +1261,33 @@ GNUNET_TESTBED_controller_start (const char *trusted_ip,
1261 1261
1262 1262
1263/** 1263/**
1264 * Stop the controller process (also will terminate all peers and controllers 1264 * Sends termination signal to the controller's helper process
1265 * dependent on this controller). This function blocks until the testbed has
1266 * been fully terminated (!). The controller status cb from
1267 * GNUNET_TESTBED_controller_start() will not be called.
1268 * 1265 *
1269 * @param cproc the controller process handle 1266 * @param cproc the handle to the controller's helper process
1270 */ 1267 */
1271void 1268void
1272GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_ControllerProc *cproc) 1269GNUNET_TESTBED_controller_kill_ (struct GNUNET_TESTBED_ControllerProc *cproc)
1273{ 1270{
1274 if (NULL != cproc->shandle) 1271 if (NULL != cproc->shandle)
1275 GNUNET_HELPER_send_cancel (cproc->shandle); 1272 GNUNET_HELPER_send_cancel (cproc->shandle);
1276 if (NULL != cproc->helper) 1273 if (NULL != cproc->helper)
1277 GNUNET_HELPER_soft_stop (cproc->helper); 1274 GNUNET_HELPER_kill (cproc->helper, GNUNET_YES);
1275}
1276
1277
1278/**
1279 * Cleans-up the controller's helper process handle
1280 *
1281 * @param cproc the handle to the controller's helper process
1282 */
1283void
1284GNUNET_TESTBED_controller_destroy_ (struct GNUNET_TESTBED_ControllerProc *cproc)
1285{
1286 if (NULL != cproc->helper)
1287 {
1288 GNUNET_break (GNUNET_OK == GNUNET_HELPER_wait (cproc->helper));
1289 GNUNET_HELPER_destroy (cproc->helper);
1290 }
1278 if (NULL != cproc->helper_argv) 1291 if (NULL != cproc->helper_argv)
1279 free_argv (cproc->helper_argv); 1292 free_argv (cproc->helper_argv);
1280 cproc->host->controller_started = GNUNET_NO; 1293 cproc->host->controller_started = GNUNET_NO;
@@ -1284,6 +1297,22 @@ GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_ControllerProc *cproc)
1284 1297
1285 1298
1286/** 1299/**
1300 * Stop the controller process (also will terminate all peers and controllers
1301 * dependent on this controller). This function blocks until the testbed has
1302 * been fully terminated (!). The controller status cb from
1303 * GNUNET_TESTBED_controller_start() will not be called.
1304 *
1305 * @param cproc the controller process handle
1306 */
1307void
1308GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_ControllerProc *cproc)
1309{
1310 GNUNET_TESTBED_controller_kill_ (cproc);
1311 GNUNET_TESTBED_controller_destroy_ (cproc);
1312}
1313
1314
1315/**
1287 * The handle for whether a host is habitable or not 1316 * The handle for whether a host is habitable or not
1288 */ 1317 */
1289struct GNUNET_TESTBED_HostHabitableCheckHandle 1318struct GNUNET_TESTBED_HostHabitableCheckHandle
diff --git a/src/testbed/testbed_api_hosts.h b/src/testbed/testbed_api_hosts.h
index 56cca624b..3cef4412a 100644
--- a/src/testbed/testbed_api_hosts.h
+++ b/src/testbed/testbed_api_hosts.h
@@ -233,5 +233,25 @@ GNUNET_TESTBED_host_handle_addhostconfirm_ (struct GNUNET_TESTBED_Controller *c,
233 GNUNET_TESTBED_HostConfirmedMessage 233 GNUNET_TESTBED_HostConfirmedMessage
234 *msg); 234 *msg);
235 235
236
237/**
238 * Sends termination signal to the controller's helper process
239 *
240 * @param cproc the handle to the controller's helper process
241 */
242void
243GNUNET_TESTBED_controller_kill_ (struct GNUNET_TESTBED_ControllerProc *cproc);
244
245
246/**
247 * Cleans-up the controller's helper process handle
248 *
249 * @param cproc the handle to the controller's helper process
250 */
251void
252GNUNET_TESTBED_controller_destroy_ (struct GNUNET_TESTBED_ControllerProc
253 *cproc);
254
255
236#endif 256#endif
237/* end of testbed_api_hosts.h */ 257/* end of testbed_api_hosts.h */
diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c
index 223791e18..5b4e702e5 100644
--- a/src/transport/plugin_transport_wlan.c
+++ b/src/transport/plugin_transport_wlan.c
@@ -1613,7 +1613,7 @@ libgnunet_plugin_transport_wlan_done (void *cls)
1613 } 1613 }
1614 if (NULL != plugin->suid_helper) 1614 if (NULL != plugin->suid_helper)
1615 { 1615 {
1616 GNUNET_HELPER_stop (plugin->suid_helper); 1616 GNUNET_HELPER_stop (plugin->suid_helper, GNUNET_NO);
1617 plugin->suid_helper = NULL; 1617 plugin->suid_helper = NULL;
1618 } 1618 }
1619 endpoint_next = plugin->mac_head; 1619 endpoint_next = plugin->mac_head;
diff --git a/src/transport/test_plugin_transport.c b/src/transport/test_plugin_transport.c
index 58fd07c78..9b1760919 100644
--- a/src/transport/test_plugin_transport.c
+++ b/src/transport/test_plugin_transport.c
@@ -186,7 +186,7 @@ end ()
186 186
187 if (NULL != suid_helper) 187 if (NULL != suid_helper)
188 { 188 {
189 GNUNET_HELPER_stop (suid_helper); 189 GNUNET_HELPER_stop (suid_helper, GNUNET_NO);
190 suid_helper = NULL; 190 suid_helper = NULL;
191 } 191 }
192} 192}
@@ -252,7 +252,7 @@ end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
252 252
253 if (NULL != suid_helper) 253 if (NULL != suid_helper)
254 { 254 {
255 GNUNET_HELPER_stop (suid_helper); 255 GNUNET_HELPER_stop (suid_helper, GNUNET_NO);
256 suid_helper = NULL; 256 suid_helper = NULL;
257 } 257 }
258 258
diff --git a/src/util/helper.c b/src/util/helper.c
index d7a3cb271..57e5798d8 100644
--- a/src/util/helper.c
+++ b/src/util/helper.c
@@ -20,7 +20,8 @@
20 20
21/** 21/**
22 * @file util/helper.c 22 * @file util/helper.c
23 * @brief API for dealing with (SUID) helper processes that communicate via GNUNET_MessageHeaders on stdin/stdout 23 * @brief API for dealing with (SUID) helper processes that communicate via
24 * GNUNET_MessageHeaders on stdin/stdout
24 * @author Philipp Toelke 25 * @author Philipp Toelke
25 * @author Christian Grothoff 26 * @author Christian Grothoff
26 */ 27 */
@@ -162,38 +163,71 @@ struct GNUNET_HELPER_Handle
162 163
163 164
164/** 165/**
165 * Stop the helper process, we're closing down or had an error. 166 * Sends termination signal to the helper process. The helper process is not
167 * reaped; call GNUNET_HELPER_wait() for reaping the dead helper process.
166 * 168 *
167 * @param h handle to the helper process 169 * @param h the helper handle
168 * @param soft_kill if GNUNET_YES, signals termination by closing the helper's 170 * @param soft_kill if GNUNET_YES, signals termination by closing the helper's
169 * stdin; GNUNET_NO to signal termination by sending SIGTERM to helper 171 * stdin; GNUNET_NO to signal termination by sending SIGTERM to helper
172 * @return GNUNET_OK on success; GNUNET_SYSERR on error
170 */ 173 */
171static void 174int
172stop_helper (struct GNUNET_HELPER_Handle *h, int soft_kill) 175GNUNET_HELPER_kill (struct GNUNET_HELPER_Handle *h, int soft_kill)
173{ 176{
174 struct GNUNET_HELPER_SendHandle *sh; 177 struct GNUNET_HELPER_SendHandle *sh;
178 int ret;
175 179
176 if (NULL != h->helper_proc) 180 while (NULL != (sh = h->sh_head))
177 { 181 {
178 if (GNUNET_YES == soft_kill) 182 GNUNET_CONTAINER_DLL_remove (h->sh_head,
179 { 183 h->sh_tail,
180 /* soft-kill only possible with pipes */ 184 sh);
181 GNUNET_assert (NULL != h->helper_in); 185 if (NULL != sh->cont)
182 GNUNET_DISK_pipe_close (h->helper_in); 186 sh->cont (sh->cont_cls, GNUNET_NO);
183 h->helper_in = NULL; 187 GNUNET_free (sh);
184 h->fh_to_helper = NULL;
185 }
186 else
187 GNUNET_break (0 == GNUNET_OS_process_kill (h->helper_proc, SIGTERM));
188 GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (h->helper_proc));
189 GNUNET_OS_process_destroy (h->helper_proc);
190 h->helper_proc = NULL;
191 } 188 }
192 if (GNUNET_SCHEDULER_NO_TASK != h->restart_task) 189 if (GNUNET_SCHEDULER_NO_TASK != h->restart_task)
193 { 190 {
194 GNUNET_SCHEDULER_cancel (h->restart_task); 191 GNUNET_SCHEDULER_cancel (h->restart_task);
195 h->restart_task = GNUNET_SCHEDULER_NO_TASK; 192 h->restart_task = GNUNET_SCHEDULER_NO_TASK;
196 } 193 }
194 if (NULL == h->helper_proc)
195 return GNUNET_SYSERR;
196 if (GNUNET_YES == soft_kill)
197 {
198 /* soft-kill only possible with pipes */
199 GNUNET_assert (NULL != h->helper_in);
200 ret = GNUNET_DISK_pipe_close (h->helper_in);
201 h->helper_in = NULL;
202 h->fh_to_helper = NULL;
203 return ret;
204 }
205 if (0 != GNUNET_OS_process_kill (h->helper_proc, SIGTERM))
206 return GNUNET_SYSERR;
207 return GNUNET_OK;
208}
209
210
211/**
212 * Reap the helper process. This call is blocking(!). The helper process
213 * should either be sent a termination signal before or should be dead before
214 * calling this function
215 *
216 * @param h the helper handle
217 * @return GNUNET_OK on success; GNUNET_SYSERR on error
218 */
219int
220GNUNET_HELPER_wait (struct GNUNET_HELPER_Handle *h)
221{
222 struct GNUNET_HELPER_SendHandle *sh;
223 int ret;
224
225 if (NULL != h->helper_proc)
226 {
227 ret = GNUNET_OS_process_wait (h->helper_proc);
228 GNUNET_OS_process_destroy (h->helper_proc);
229 h->helper_proc = NULL;
230 }
197 if (GNUNET_SCHEDULER_NO_TASK != h->read_task) 231 if (GNUNET_SCHEDULER_NO_TASK != h->read_task)
198 { 232 {
199 GNUNET_SCHEDULER_cancel (h->read_task); 233 GNUNET_SCHEDULER_cancel (h->read_task);
@@ -227,6 +261,22 @@ stop_helper (struct GNUNET_HELPER_Handle *h, int soft_kill)
227 } 261 }
228 /* purge MST buffer */ 262 /* purge MST buffer */
229 (void) GNUNET_SERVER_mst_receive (h->mst, NULL, NULL, 0, GNUNET_YES, GNUNET_NO); 263 (void) GNUNET_SERVER_mst_receive (h->mst, NULL, NULL, 0, GNUNET_YES, GNUNET_NO);
264 return ret;
265}
266
267
268/**
269 * Stop the helper process, we're closing down or had an error.
270 *
271 * @param h handle to the helper process
272 * @param soft_kill if GNUNET_YES, signals termination by closing the helper's
273 * stdin; GNUNET_NO to signal termination by sending SIGTERM to helper
274 */
275static void
276stop_helper (struct GNUNET_HELPER_Handle *h, int soft_kill)
277{
278 GNUNET_break (GNUNET_OK == GNUNET_HELPER_kill (h, soft_kill));
279 GNUNET_break (GNUNET_OK == GNUNET_HELPER_wait (h));
230} 280}
231 281
232 282
@@ -274,7 +324,7 @@ helper_read (void *cls,
274 if (NULL != h->exp_cb) 324 if (NULL != h->exp_cb)
275 { 325 {
276 h->exp_cb (h->cb_cls); 326 h->exp_cb (h->cb_cls);
277 GNUNET_HELPER_stop (h); 327 GNUNET_HELPER_stop (h, GNUNET_NO);
278 return; 328 return;
279 } 329 }
280 stop_helper (h, GNUNET_NO); 330 stop_helper (h, GNUNET_NO);
@@ -293,7 +343,7 @@ helper_read (void *cls,
293 if (NULL != h->exp_cb) 343 if (NULL != h->exp_cb)
294 { 344 {
295 h->exp_cb (h->cb_cls); 345 h->exp_cb (h->cb_cls);
296 GNUNET_HELPER_stop (h); 346 GNUNET_HELPER_stop (h, GNUNET_NO);
297 return; 347 return;
298 } 348 }
299 stop_helper (h, GNUNET_NO); 349 stop_helper (h, GNUNET_NO);
@@ -318,7 +368,7 @@ helper_read (void *cls,
318 if (NULL != h->exp_cb) 368 if (NULL != h->exp_cb)
319 { 369 {
320 h->exp_cb (h->cb_cls); 370 h->exp_cb (h->cb_cls);
321 GNUNET_HELPER_stop (h); 371 GNUNET_HELPER_stop (h, GNUNET_NO);
322 return; 372 return;
323 } 373 }
324 stop_helper (h, GNUNET_NO); 374 stop_helper (h, GNUNET_NO);
@@ -445,30 +495,15 @@ GNUNET_HELPER_start (int with_control_pipe,
445 495
446 496
447/** 497/**
448 * @brief Kills the helper, closes the pipe and frees the h 498 * Free's the resources occupied by the helper handle
449 * 499 *
450 * @param h h to helper to stop 500 * @param h the helper handle to free
451 * @param soft_kill if GNUNET_YES, signals termination by closing the helper's
452 * stdin; GNUNET_NO to signal termination by sending SIGTERM to helper
453 */ 501 */
454static void 502void
455kill_helper (struct GNUNET_HELPER_Handle *h, int soft_kill) 503GNUNET_HELPER_destroy (struct GNUNET_HELPER_Handle *h)
456{ 504{
457 struct GNUNET_HELPER_SendHandle *sh;
458 unsigned int c; 505 unsigned int c;
459 506
460 h->exp_cb = NULL;
461 /* signal pending writes that we were stopped */
462 while (NULL != (sh = h->sh_head))
463 {
464 GNUNET_CONTAINER_DLL_remove (h->sh_head,
465 h->sh_tail,
466 sh);
467 if (NULL != sh->cont)
468 sh->cont (sh->cont_cls, GNUNET_SYSERR);
469 GNUNET_free (sh);
470 }
471 stop_helper (h, soft_kill);
472 GNUNET_SERVER_mst_destroy (h->mst); 507 GNUNET_SERVER_mst_destroy (h->mst);
473 GNUNET_free (h->binary_name); 508 GNUNET_free (h->binary_name);
474 for (c = 0; h->binary_argv[c] != NULL; c++) 509 for (c = 0; h->binary_argv[c] != NULL; c++)
@@ -482,24 +517,15 @@ kill_helper (struct GNUNET_HELPER_Handle *h, int soft_kill)
482 * Kills the helper, closes the pipe and frees the handle 517 * Kills the helper, closes the pipe and frees the handle
483 * 518 *
484 * @param h handle to helper to stop 519 * @param h handle to helper to stop
520 * @param soft_kill if GNUNET_YES, signals termination by closing the helper's
521 * stdin; GNUNET_NO to signal termination by sending SIGTERM to helper
485 */ 522 */
486void 523void
487GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h) 524GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h, int soft_kill)
488{
489 kill_helper (h, GNUNET_NO);
490}
491
492
493/**
494 * Kills the helper by closing its stdin (the helper is expected to catch the
495 * resulting SIGPIPE and shutdown), closes the pipe and frees the handle
496 *
497 * @param h handle to helper to stop
498 */
499void
500GNUNET_HELPER_soft_stop (struct GNUNET_HELPER_Handle *h)
501{ 525{
502 kill_helper (h, GNUNET_YES); 526 h->exp_cb = NULL;
527 stop_helper (h, soft_kill);
528 GNUNET_HELPER_destroy (h);
503} 529}
504 530
505 531
@@ -540,7 +566,7 @@ helper_write (void *cls,
540 if (NULL != h->exp_cb) 566 if (NULL != h->exp_cb)
541 { 567 {
542 h->exp_cb (h->cb_cls); 568 h->exp_cb (h->cb_cls);
543 GNUNET_HELPER_stop (h); 569 GNUNET_HELPER_stop (h, GNUNET_NO);
544 return; 570 return;
545 } 571 }
546 stop_helper (h, GNUNET_NO); 572 stop_helper (h, GNUNET_NO);
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c
index 61bd977bc..a56aff52a 100644
--- a/src/vpn/gnunet-service-vpn.c
+++ b/src/vpn/gnunet-service-vpn.c
@@ -2928,8 +2928,8 @@ cleanup (void *cls GNUNET_UNUSED,
2928 mesh_handle = NULL; 2928 mesh_handle = NULL;
2929 } 2929 }
2930 if (NULL != helper_handle) 2930 if (NULL != helper_handle)
2931 { 2931 {
2932 GNUNET_HELPER_stop (helper_handle); 2932 GNUNET_HELPER_stop (helper_handle, GNUNET_NO);
2933 helper_handle = NULL; 2933 helper_handle = NULL;
2934 } 2934 }
2935 if (NULL != nc) 2935 if (NULL != nc)