diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-09-28 00:56:33 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-09-28 00:56:33 +0200 |
commit | 31aee41701fa2cd92ec566bd459e3425ee1f0b7d (patch) | |
tree | 7a8e25a7eee5a0de025d6595041f96cf76a06278 /src/arm | |
parent | 9388822eb43827ee4f343a881d86a6225beca939 (diff) | |
download | gnunet-31aee41701fa2cd92ec566bd459e3425ee1f0b7d.tar.gz gnunet-31aee41701fa2cd92ec566bd459e3425ee1f0b7d.zip |
handle arm -s completion nicely via signaling pipe
Diffstat (limited to 'src/arm')
-rw-r--r-- | src/arm/arm_api.c | 107 | ||||
-rw-r--r-- | src/arm/gnunet-service-arm.c | 2320 |
2 files changed, 1254 insertions, 1173 deletions
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c index dc5c9c25b..da7268f67 100644 --- a/src/arm/arm_api.c +++ b/src/arm/arm_api.c | |||
@@ -85,6 +85,11 @@ struct GNUNET_ARM_Operation | |||
85 | enum GNUNET_ARM_Result starting_ret; | 85 | enum GNUNET_ARM_Result starting_ret; |
86 | 86 | ||
87 | /** | 87 | /** |
88 | * File descriptor to close on operation stop, if not NULL. | ||
89 | */ | ||
90 | struct GNUNET_DISK_FileHandle *rfd; | ||
91 | |||
92 | /** | ||
88 | * Is this an operation to stop the ARM service? | 93 | * Is this an operation to stop the ARM service? |
89 | */ | 94 | */ |
90 | int is_arm_stop; | 95 | int is_arm_stop; |
@@ -203,19 +208,27 @@ reconnect_arm_later (struct GNUNET_ARM_Handle *h) | |||
203 | h->currently_up = GNUNET_NO; | 208 | h->currently_up = GNUNET_NO; |
204 | GNUNET_assert (NULL == h->reconnect_task); | 209 | GNUNET_assert (NULL == h->reconnect_task); |
205 | h->reconnect_task = | 210 | h->reconnect_task = |
206 | GNUNET_SCHEDULER_add_delayed (h->retry_backoff, &reconnect_arm_task, h); | 211 | GNUNET_SCHEDULER_add_delayed (h->retry_backoff, |
212 | &reconnect_arm_task, | ||
213 | h); | ||
207 | while (NULL != (op = h->operation_pending_head)) | 214 | while (NULL != (op = h->operation_pending_head)) |
208 | { | 215 | { |
209 | if (NULL != op->result_cont) | 216 | if (NULL != op->result_cont) |
210 | op->result_cont (op->cont_cls, GNUNET_ARM_REQUEST_DISCONNECTED, 0); | 217 | op->result_cont (op->cont_cls, |
218 | GNUNET_ARM_REQUEST_DISCONNECTED, | ||
219 | 0); | ||
211 | if (NULL != op->list_cont) | 220 | if (NULL != op->list_cont) |
212 | op->list_cont (op->cont_cls, GNUNET_ARM_REQUEST_DISCONNECTED, 0, NULL); | 221 | op->list_cont (op->cont_cls, |
222 | GNUNET_ARM_REQUEST_DISCONNECTED, | ||
223 | 0, | ||
224 | NULL); | ||
213 | GNUNET_ARM_operation_cancel (op); | 225 | GNUNET_ARM_operation_cancel (op); |
214 | } | 226 | } |
215 | GNUNET_assert (NULL == h->operation_pending_head); | 227 | GNUNET_assert (NULL == h->operation_pending_head); |
216 | h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); | 228 | h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); |
217 | if (NULL != h->conn_status) | 229 | if (NULL != h->conn_status) |
218 | h->conn_status (h->conn_status_cls, GNUNET_NO); | 230 | h->conn_status (h->conn_status_cls, |
231 | GNUNET_NO); | ||
219 | } | 232 | } |
220 | 233 | ||
221 | 234 | ||
@@ -257,7 +270,8 @@ handle_arm_result (void *cls, | |||
257 | void *result_cont_cls; | 270 | void *result_cont_cls; |
258 | 271 | ||
259 | id = GNUNET_ntohll (res->arm_msg.request_id); | 272 | id = GNUNET_ntohll (res->arm_msg.request_id); |
260 | op = find_op_by_id (h, id); | 273 | op = find_op_by_id (h, |
274 | id); | ||
261 | if (NULL == op) | 275 | if (NULL == op) |
262 | { | 276 | { |
263 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 277 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -356,7 +370,9 @@ check_arm_list_result (void *cls, | |||
356 | { | 370 | { |
357 | uint16_t name_index = ntohs (ssm->name_index); | 371 | uint16_t name_index = ntohs (ssm->name_index); |
358 | uint16_t binary_index = ntohs (ssm->binary_index); | 372 | uint16_t binary_index = ntohs (ssm->binary_index); |
359 | if (NULL == pool_get (pool_start, pool_size, name_index)) | 373 | if (NULL == pool_get (pool_start, |
374 | pool_size, | ||
375 | name_index)) | ||
360 | { | 376 | { |
361 | GNUNET_break_op (0); | 377 | GNUNET_break_op (0); |
362 | return GNUNET_NO; | 378 | return GNUNET_NO; |
@@ -418,9 +434,11 @@ handle_arm_list_result (void *cls, | |||
418 | const char *name; | 434 | const char *name; |
419 | const char *binary; | 435 | const char *binary; |
420 | 436 | ||
421 | GNUNET_assert (NULL != (name = pool_get (pool_start, pool_size, | 437 | GNUNET_assert (NULL != (name = pool_get (pool_start, |
438 | pool_size, | ||
422 | name_index))); | 439 | name_index))); |
423 | GNUNET_assert (NULL != (binary = pool_get (pool_start, pool_size, | 440 | GNUNET_assert (NULL != (binary = pool_get (pool_start, |
441 | pool_size, | ||
424 | binary_index))); | 442 | binary_index))); |
425 | list[i] = (struct GNUNET_ARM_ServiceInfo) { | 443 | list[i] = (struct GNUNET_ARM_ServiceInfo) { |
426 | .name = name, | 444 | .name = name, |
@@ -630,11 +648,13 @@ GNUNET_ARM_disconnect (struct GNUNET_ARM_Handle *h) | |||
630 | * | 648 | * |
631 | * @param h the handle with configuration details | 649 | * @param h the handle with configuration details |
632 | * @param std_inheritance inheritance of std streams | 650 | * @param std_inheritance inheritance of std streams |
651 | * @param sigfd socket to pass to ARM for signalling | ||
633 | * @return operation status code | 652 | * @return operation status code |
634 | */ | 653 | */ |
635 | static enum GNUNET_ARM_Result | 654 | static enum GNUNET_ARM_Result |
636 | start_arm_service (struct GNUNET_ARM_Handle *h, | 655 | start_arm_service (struct GNUNET_ARM_Handle *h, |
637 | enum GNUNET_OS_InheritStdioFlags std_inheritance) | 656 | enum GNUNET_OS_InheritStdioFlags std_inheritance, |
657 | struct GNUNET_DISK_FileHandle *sigfd) | ||
638 | { | 658 | { |
639 | struct GNUNET_OS_Process *proc; | 659 | struct GNUNET_OS_Process *proc; |
640 | char *cbinary; | 660 | char *cbinary; |
@@ -643,7 +663,19 @@ start_arm_service (struct GNUNET_ARM_Handle *h, | |||
643 | char *config; | 663 | char *config; |
644 | char *loprefix; | 664 | char *loprefix; |
645 | char *lopostfix; | 665 | char *lopostfix; |
666 | SOCKTYPE ld[2]; | ||
667 | SOCKTYPE *lsocks; | ||
646 | 668 | ||
669 | if (NULL == sigfd) | ||
670 | { | ||
671 | lsocks = NULL; | ||
672 | } | ||
673 | else | ||
674 | { | ||
675 | ld[0] = sigfd->fd; | ||
676 | ld[1] = -1; | ||
677 | lsocks = ld; | ||
678 | } | ||
647 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (h->cfg, | 679 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (h->cfg, |
648 | "arm", | 680 | "arm", |
649 | "PREFIX", | 681 | "PREFIX", |
@@ -700,7 +732,7 @@ start_arm_service (struct GNUNET_ARM_Handle *h, | |||
700 | if (NULL == config) | 732 | if (NULL == config) |
701 | proc = GNUNET_OS_start_process_s (GNUNET_NO, | 733 | proc = GNUNET_OS_start_process_s (GNUNET_NO, |
702 | std_inheritance, | 734 | std_inheritance, |
703 | NULL, | 735 | lsocks, |
704 | loprefix, | 736 | loprefix, |
705 | quotedbinary, | 737 | quotedbinary, |
706 | /* no daemonization! */ | 738 | /* no daemonization! */ |
@@ -709,7 +741,7 @@ start_arm_service (struct GNUNET_ARM_Handle *h, | |||
709 | else | 741 | else |
710 | proc = GNUNET_OS_start_process_s (GNUNET_NO, | 742 | proc = GNUNET_OS_start_process_s (GNUNET_NO, |
711 | std_inheritance, | 743 | std_inheritance, |
712 | NULL, | 744 | lsocks, |
713 | loprefix, | 745 | loprefix, |
714 | quotedbinary, | 746 | quotedbinary, |
715 | "-c", | 747 | "-c", |
@@ -723,7 +755,7 @@ start_arm_service (struct GNUNET_ARM_Handle *h, | |||
723 | if (NULL == config) | 755 | if (NULL == config) |
724 | proc = GNUNET_OS_start_process_s (GNUNET_NO, | 756 | proc = GNUNET_OS_start_process_s (GNUNET_NO, |
725 | std_inheritance, | 757 | std_inheritance, |
726 | NULL, | 758 | lsocks, |
727 | loprefix, | 759 | loprefix, |
728 | quotedbinary, | 760 | quotedbinary, |
729 | "-d", /* do daemonize */ | 761 | "-d", /* do daemonize */ |
@@ -732,7 +764,7 @@ start_arm_service (struct GNUNET_ARM_Handle *h, | |||
732 | else | 764 | else |
733 | proc = GNUNET_OS_start_process_s (GNUNET_NO, | 765 | proc = GNUNET_OS_start_process_s (GNUNET_NO, |
734 | std_inheritance, | 766 | std_inheritance, |
735 | NULL, | 767 | lsocks, |
736 | loprefix, | 768 | loprefix, |
737 | quotedbinary, | 769 | quotedbinary, |
738 | "-c", | 770 | "-c", |
@@ -764,6 +796,16 @@ GNUNET_ARM_operation_cancel (struct GNUNET_ARM_Operation *op) | |||
764 | { | 796 | { |
765 | struct GNUNET_ARM_Handle *h = op->h; | 797 | struct GNUNET_ARM_Handle *h = op->h; |
766 | 798 | ||
799 | if (NULL != op->async) | ||
800 | { | ||
801 | GNUNET_SCHEDULER_cancel (op->async); | ||
802 | op->async = NULL; | ||
803 | } | ||
804 | if (NULL != op->rfd) | ||
805 | { | ||
806 | GNUNET_DISK_file_close (op->rfd); | ||
807 | op->rfd = NULL; | ||
808 | } | ||
767 | if (h->thm == op) | 809 | if (h->thm == op) |
768 | { | 810 | { |
769 | op->result_cont = NULL; | 811 | op->result_cont = NULL; |
@@ -895,6 +937,8 @@ GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h, | |||
895 | { | 937 | { |
896 | struct GNUNET_ARM_Operation *op; | 938 | struct GNUNET_ARM_Operation *op; |
897 | enum GNUNET_ARM_Result ret; | 939 | enum GNUNET_ARM_Result ret; |
940 | struct GNUNET_DISK_PipeHandle *sig; | ||
941 | struct GNUNET_DISK_FileHandle *wsig; | ||
898 | 942 | ||
899 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 943 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
900 | "Starting service `%s'\n", | 944 | "Starting service `%s'\n", |
@@ -933,8 +977,22 @@ GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h, | |||
933 | are unlikely to hammer 'gnunet-arm -s' on a busy system, | 977 | are unlikely to hammer 'gnunet-arm -s' on a busy system, |
934 | the above check should catch 99.99% of the cases where ARM | 978 | the above check should catch 99.99% of the cases where ARM |
935 | is already running. */ | 979 | is already running. */ |
936 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting ARM service\n"); | 980 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
937 | ret = start_arm_service (h, std_inheritance); | 981 | "Starting ARM service\n"); |
982 | if (NULL == (sig = GNUNET_DISK_pipe (GNUNET_NO, | ||
983 | GNUNET_NO, | ||
984 | GNUNET_NO, | ||
985 | GNUNET_YES))) | ||
986 | { | ||
987 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, | ||
988 | "pipe"); | ||
989 | } | ||
990 | wsig = GNUNET_DISK_pipe_detach_end (sig, | ||
991 | GNUNET_DISK_PIPE_END_WRITE); | ||
992 | ret = start_arm_service (h, | ||
993 | std_inheritance, | ||
994 | wsig); | ||
995 | GNUNET_DISK_file_close (wsig); | ||
938 | if (GNUNET_ARM_RESULT_STARTING == ret) | 996 | if (GNUNET_ARM_RESULT_STARTING == ret) |
939 | reconnect_arm (h); | 997 | reconnect_arm (h); |
940 | op = GNUNET_new (struct GNUNET_ARM_Operation); | 998 | op = GNUNET_new (struct GNUNET_ARM_Operation); |
@@ -945,8 +1003,23 @@ GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h, | |||
945 | h->operation_pending_tail, | 1003 | h->operation_pending_tail, |
946 | op); | 1004 | op); |
947 | op->starting_ret = ret; | 1005 | op->starting_ret = ret; |
948 | op->async = GNUNET_SCHEDULER_add_now (¬ify_starting, | 1006 | if (NULL != sig) |
949 | op); | 1007 | { |
1008 | op->rfd = GNUNET_DISK_pipe_detach_end (sig, | ||
1009 | GNUNET_DISK_PIPE_END_READ); | ||
1010 | /* Wait at most a minute for gnunet-service-arm to be up, as beyond | ||
1011 | that something clearly just went wrong */ | ||
1012 | op->async = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_MINUTES, | ||
1013 | op->rfd, | ||
1014 | ¬ify_starting, | ||
1015 | op); | ||
1016 | } | ||
1017 | else | ||
1018 | { | ||
1019 | op->async = GNUNET_SCHEDULER_add_now (¬ify_starting, | ||
1020 | op); | ||
1021 | } | ||
1022 | GNUNET_DISK_pipe_close (sig); | ||
950 | return op; | 1023 | return op; |
951 | } | 1024 | } |
952 | 1025 | ||
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c index 65404bbed..d13be6eb1 100644 --- a/src/arm/gnunet-service-arm.c +++ b/src/arm/gnunet-service-arm.c | |||
@@ -29,10 +29,10 @@ | |||
29 | #include "gnunet_protocols.h" | 29 | #include "gnunet_protocols.h" |
30 | #include "arm.h" | 30 | #include "arm.h" |
31 | 31 | ||
32 | #define LOG(kind, ...) GNUNET_log_from(kind, "util", __VA_ARGS__) | 32 | #define LOG(kind, ...) GNUNET_log_from (kind, "util", __VA_ARGS__) |
33 | 33 | ||
34 | #define LOG_STRERROR(kind, syscall) \ | 34 | #define LOG_STRERROR(kind, syscall) \ |
35 | GNUNET_log_from_strerror(kind, "util", syscall) | 35 | GNUNET_log_from_strerror (kind, "util", syscall) |
36 | 36 | ||
37 | 37 | ||
38 | #if HAVE_WAIT4 | 38 | #if HAVE_WAIT4 |
@@ -65,7 +65,8 @@ struct ServiceList; | |||
65 | /** | 65 | /** |
66 | * Record with information about a listen socket we have open. | 66 | * Record with information about a listen socket we have open. |
67 | */ | 67 | */ |
68 | struct ServiceListeningInfo { | 68 | struct ServiceListeningInfo |
69 | { | ||
69 | /** | 70 | /** |
70 | * This is a linked list. | 71 | * This is a linked list. |
71 | */ | 72 | */ |
@@ -106,7 +107,8 @@ struct ServiceListeningInfo { | |||
106 | /** | 107 | /** |
107 | * List of our services. | 108 | * List of our services. |
108 | */ | 109 | */ |
109 | struct ServiceList { | 110 | struct ServiceList |
111 | { | ||
110 | /** | 112 | /** |
111 | * This is a doubly-linked list. | 113 | * This is a doubly-linked list. |
112 | */ | 114 | */ |
@@ -288,30 +290,30 @@ static struct GNUNET_NotificationContext *notifier; | |||
288 | * parameter is ignore on systems other than LINUX | 290 | * parameter is ignore on systems other than LINUX |
289 | */ | 291 | */ |
290 | static void | 292 | static void |
291 | add_unixpath(struct sockaddr **saddrs, | 293 | add_unixpath (struct sockaddr **saddrs, |
292 | socklen_t *saddrlens, | 294 | socklen_t *saddrlens, |
293 | const char *unixpath, | 295 | const char *unixpath, |
294 | int abstract) | 296 | int abstract) |
295 | { | 297 | { |
296 | #ifdef AF_UNIX | 298 | #ifdef AF_UNIX |
297 | struct sockaddr_un *un; | 299 | struct sockaddr_un *un; |
298 | 300 | ||
299 | un = GNUNET_new(struct sockaddr_un); | 301 | un = GNUNET_new (struct sockaddr_un); |
300 | un->sun_family = AF_UNIX; | 302 | un->sun_family = AF_UNIX; |
301 | GNUNET_strlcpy(un->sun_path, unixpath, sizeof(un->sun_path)); | 303 | GNUNET_strlcpy (un->sun_path, unixpath, sizeof(un->sun_path)); |
302 | #ifdef LINUX | 304 | #ifdef LINUX |
303 | if (GNUNET_YES == abstract) | 305 | if (GNUNET_YES == abstract) |
304 | un->sun_path[0] = '\0'; | 306 | un->sun_path[0] = '\0'; |
305 | #endif | 307 | #endif |
306 | #if HAVE_SOCKADDR_UN_SUN_LEN | 308 | #if HAVE_SOCKADDR_UN_SUN_LEN |
307 | un->sun_len = (u_char)sizeof(struct sockaddr_un); | 309 | un->sun_len = (u_char) sizeof(struct sockaddr_un); |
308 | #endif | 310 | #endif |
309 | *saddrs = (struct sockaddr *)un; | 311 | *saddrs = (struct sockaddr *) un; |
310 | *saddrlens = sizeof(struct sockaddr_un); | 312 | *saddrlens = sizeof(struct sockaddr_un); |
311 | #else | 313 | #else |
312 | /* this function should never be called | 314 | /* this function should never be called |
313 | * unless AF_UNIX is defined! */ | 315 | * unless AF_UNIX is defined! */ |
314 | GNUNET_assert(0); | 316 | GNUNET_assert (0); |
315 | #endif | 317 | #endif |
316 | } | 318 | } |
317 | 319 | ||
@@ -337,10 +339,10 @@ add_unixpath(struct sockaddr **saddrs, | |||
337 | * set to NULL). | 339 | * set to NULL). |
338 | */ | 340 | */ |
339 | static int | 341 | static int |
340 | get_server_addresses(const char *service_name, | 342 | get_server_addresses (const char *service_name, |
341 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 343 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
342 | struct sockaddr ***addrs, | 344 | struct sockaddr ***addrs, |
343 | socklen_t **addr_lens) | 345 | socklen_t **addr_lens) |
344 | { | 346 | { |
345 | int disablev6; | 347 | int disablev6; |
346 | struct GNUNET_NETWORK_Handle *desc; | 348 | struct GNUNET_NETWORK_Handle *desc; |
@@ -361,72 +363,72 @@ get_server_addresses(const char *service_name, | |||
361 | *addrs = NULL; | 363 | *addrs = NULL; |
362 | *addr_lens = NULL; | 364 | *addr_lens = NULL; |
363 | desc = NULL; | 365 | desc = NULL; |
364 | if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "DISABLEV6")) | 366 | if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "DISABLEV6")) |
365 | { | 367 | { |
366 | if (GNUNET_SYSERR == | 368 | if (GNUNET_SYSERR == |
367 | (disablev6 = GNUNET_CONFIGURATION_get_value_yesno(cfg, | 369 | (disablev6 = GNUNET_CONFIGURATION_get_value_yesno (cfg, |
368 | service_name, | 370 | service_name, |
369 | "DISABLEV6"))) | 371 | "DISABLEV6"))) |
370 | return GNUNET_SYSERR; | 372 | return GNUNET_SYSERR; |
371 | } | 373 | } |
372 | else | 374 | else |
373 | disablev6 = GNUNET_NO; | 375 | disablev6 = GNUNET_NO; |
374 | 376 | ||
375 | if (!disablev6) | 377 | if (! disablev6) |
378 | { | ||
379 | /* probe IPv6 support */ | ||
380 | desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); | ||
381 | if (NULL == desc) | ||
376 | { | 382 | { |
377 | /* probe IPv6 support */ | 383 | if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || |
378 | desc = GNUNET_NETWORK_socket_create(PF_INET6, SOCK_STREAM, 0); | 384 | (EACCES == errno)) |
379 | if (NULL == desc) | 385 | { |
380 | { | 386 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); |
381 | if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || | 387 | return GNUNET_SYSERR; |
382 | (EACCES == errno)) | 388 | } |
383 | { | 389 | LOG (GNUNET_ERROR_TYPE_INFO, |
384 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket"); | 390 | _ ( |
385 | return GNUNET_SYSERR; | 391 | "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"), |
386 | } | 392 | service_name, |
387 | LOG(GNUNET_ERROR_TYPE_INFO, | 393 | strerror (errno)); |
388 | _( | 394 | disablev6 = GNUNET_YES; |
389 | "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"), | 395 | } |
390 | service_name, | 396 | else |
391 | strerror(errno)); | 397 | { |
392 | disablev6 = GNUNET_YES; | 398 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); |
393 | } | 399 | desc = NULL; |
394 | else | ||
395 | { | ||
396 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(desc)); | ||
397 | desc = NULL; | ||
398 | } | ||
399 | } | 400 | } |
401 | } | ||
400 | 402 | ||
401 | port = 0; | 403 | port = 0; |
402 | if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "PORT")) | 404 | if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT")) |
405 | { | ||
406 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, | ||
407 | service_name, | ||
408 | "PORT", | ||
409 | &port)) | ||
403 | { | 410 | { |
404 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg, | 411 | LOG (GNUNET_ERROR_TYPE_ERROR, |
405 | service_name, | 412 | _ ("Require valid port number for service `%s' in configuration!\n"), |
406 | "PORT", | 413 | service_name); |
407 | &port)) | ||
408 | { | ||
409 | LOG(GNUNET_ERROR_TYPE_ERROR, | ||
410 | _("Require valid port number for service `%s' in configuration!\n"), | ||
411 | service_name); | ||
412 | } | ||
413 | if (port > 65535) | ||
414 | { | ||
415 | LOG(GNUNET_ERROR_TYPE_ERROR, | ||
416 | _("Require valid port number for service `%s' in configuration!\n"), | ||
417 | service_name); | ||
418 | return GNUNET_SYSERR; | ||
419 | } | ||
420 | } | 414 | } |
421 | 415 | if (port > 65535) | |
422 | if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "BINDTO")) | ||
423 | { | 416 | { |
424 | GNUNET_break(GNUNET_OK == | 417 | LOG (GNUNET_ERROR_TYPE_ERROR, |
425 | GNUNET_CONFIGURATION_get_value_string(cfg, | 418 | _ ("Require valid port number for service `%s' in configuration!\n"), |
419 | service_name); | ||
420 | return GNUNET_SYSERR; | ||
421 | } | ||
422 | } | ||
423 | |||
424 | if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO")) | ||
425 | { | ||
426 | GNUNET_break (GNUNET_OK == | ||
427 | GNUNET_CONFIGURATION_get_value_string (cfg, | ||
426 | service_name, | 428 | service_name, |
427 | "BINDTO", | 429 | "BINDTO", |
428 | &hostname)); | 430 | &hostname)); |
429 | } | 431 | } |
430 | else | 432 | else |
431 | hostname = NULL; | 433 | hostname = NULL; |
432 | 434 | ||
@@ -434,235 +436,235 @@ get_server_addresses(const char *service_name, | |||
434 | abstract = GNUNET_NO; | 436 | abstract = GNUNET_NO; |
435 | #ifdef AF_UNIX | 437 | #ifdef AF_UNIX |
436 | if ((GNUNET_YES == | 438 | if ((GNUNET_YES == |
437 | GNUNET_CONFIGURATION_have_value(cfg, service_name, "UNIXPATH")) && | 439 | GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) && |
438 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename(cfg, | 440 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg, |
439 | service_name, | 441 | service_name, |
440 | "UNIXPATH", | 442 | "UNIXPATH", |
441 | &unixpath)) && | 443 | &unixpath)) && |
442 | (0 < strlen(unixpath))) | 444 | (0 < strlen (unixpath))) |
443 | { | 445 | { |
444 | /* probe UNIX support */ | 446 | /* probe UNIX support */ |
445 | struct sockaddr_un s_un; | 447 | struct sockaddr_un s_un; |
446 | 448 | ||
447 | if (strlen(unixpath) >= sizeof(s_un.sun_path)) | 449 | if (strlen (unixpath) >= sizeof(s_un.sun_path)) |
448 | { | 450 | { |
449 | LOG(GNUNET_ERROR_TYPE_WARNING, | 451 | LOG (GNUNET_ERROR_TYPE_WARNING, |
450 | _("UNIXPATH `%s' too long, maximum length is %llu\n"), | 452 | _ ("UNIXPATH `%s' too long, maximum length is %llu\n"), |
451 | unixpath, | 453 | unixpath, |
452 | (unsigned long long)sizeof(s_un.sun_path)); | 454 | (unsigned long long) sizeof(s_un.sun_path)); |
453 | unixpath = GNUNET_NETWORK_shorten_unixpath(unixpath); | 455 | unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath); |
454 | LOG(GNUNET_ERROR_TYPE_INFO, _("Using `%s' instead\n"), unixpath); | 456 | LOG (GNUNET_ERROR_TYPE_INFO, _ ("Using `%s' instead\n"), unixpath); |
455 | } | 457 | } |
456 | #ifdef LINUX | 458 | #ifdef LINUX |
457 | abstract = GNUNET_CONFIGURATION_get_value_yesno(cfg, | 459 | abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg, |
458 | "TESTING", | 460 | "TESTING", |
459 | "USE_ABSTRACT_SOCKETS"); | 461 | "USE_ABSTRACT_SOCKETS"); |
460 | if (GNUNET_SYSERR == abstract) | 462 | if (GNUNET_SYSERR == abstract) |
461 | abstract = GNUNET_NO; | 463 | abstract = GNUNET_NO; |
462 | #endif | 464 | #endif |
463 | if ((GNUNET_YES != abstract) && | 465 | if ((GNUNET_YES != abstract) && |
464 | (GNUNET_OK != GNUNET_DISK_directory_create_for_file(unixpath))) | 466 | (GNUNET_OK != GNUNET_DISK_directory_create_for_file (unixpath))) |
465 | GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath); | 467 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath); |
466 | } | 468 | } |
467 | if (NULL != unixpath) | 469 | if (NULL != unixpath) |
470 | { | ||
471 | desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0); | ||
472 | if (NULL == desc) | ||
468 | { | 473 | { |
469 | desc = GNUNET_NETWORK_socket_create(AF_UNIX, SOCK_STREAM, 0); | 474 | if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || |
470 | if (NULL == desc) | 475 | (EACCES == errno)) |
471 | { | 476 | { |
472 | if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || | 477 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); |
473 | (EACCES == errno)) | 478 | GNUNET_free_non_null (hostname); |
474 | { | 479 | GNUNET_free (unixpath); |
475 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket"); | 480 | return GNUNET_SYSERR; |
476 | GNUNET_free_non_null(hostname); | 481 | } |
477 | GNUNET_free(unixpath); | 482 | LOG (GNUNET_ERROR_TYPE_INFO, |
478 | return GNUNET_SYSERR; | 483 | _ ( |
479 | } | 484 | "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"), |
480 | LOG(GNUNET_ERROR_TYPE_INFO, | 485 | service_name, |
481 | _( | 486 | strerror (errno)); |
482 | "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"), | 487 | GNUNET_free (unixpath); |
483 | service_name, | 488 | unixpath = NULL; |
484 | strerror(errno)); | 489 | } |
485 | GNUNET_free(unixpath); | 490 | else |
486 | unixpath = NULL; | 491 | { |
487 | } | 492 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); |
488 | else | 493 | desc = NULL; |
489 | { | ||
490 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(desc)); | ||
491 | desc = NULL; | ||
492 | } | ||
493 | } | 494 | } |
495 | } | ||
494 | #endif | 496 | #endif |
495 | 497 | ||
496 | if ((0 == port) && (NULL == unixpath)) | 498 | if ((0 == port) && (NULL == unixpath)) |
499 | { | ||
500 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (cfg, | ||
501 | service_name, | ||
502 | "START_ON_DEMAND")) | ||
503 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
504 | _ ( | ||
505 | "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"), | ||
506 | service_name); | ||
507 | GNUNET_free_non_null (hostname); | ||
508 | return GNUNET_SYSERR; | ||
509 | } | ||
510 | if (0 == port) | ||
511 | { | ||
512 | saddrs = GNUNET_new_array (2, struct sockaddr *); | ||
513 | saddrlens = GNUNET_new_array (2, socklen_t); | ||
514 | add_unixpath (saddrs, saddrlens, unixpath, abstract); | ||
515 | GNUNET_free_non_null (unixpath); | ||
516 | GNUNET_free_non_null (hostname); | ||
517 | *addrs = saddrs; | ||
518 | *addr_lens = saddrlens; | ||
519 | return 1; | ||
520 | } | ||
521 | |||
522 | if (NULL != hostname) | ||
523 | { | ||
524 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
525 | "Resolving `%s' since that is where `%s' will bind to.\n", | ||
526 | hostname, | ||
527 | service_name); | ||
528 | memset (&hints, 0, sizeof(struct addrinfo)); | ||
529 | if (disablev6) | ||
530 | hints.ai_family = AF_INET; | ||
531 | hints.ai_protocol = IPPROTO_TCP; | ||
532 | if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) || | ||
533 | (NULL == res)) | ||
497 | { | 534 | { |
498 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno(cfg, | 535 | LOG (GNUNET_ERROR_TYPE_ERROR, |
499 | service_name, | 536 | _ ("Failed to resolve `%s': %s\n"), |
500 | "START_ON_DEMAND")) | 537 | hostname, |
501 | LOG(GNUNET_ERROR_TYPE_ERROR, | 538 | gai_strerror (ret)); |
502 | _( | 539 | GNUNET_free (hostname); |
503 | "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"), | 540 | GNUNET_free_non_null (unixpath); |
504 | service_name); | ||
505 | GNUNET_free_non_null(hostname); | ||
506 | return GNUNET_SYSERR; | 541 | return GNUNET_SYSERR; |
507 | } | 542 | } |
508 | if (0 == port) | 543 | next = res; |
544 | i = 0; | ||
545 | while (NULL != (pos = next)) | ||
509 | { | 546 | { |
510 | saddrs = GNUNET_new_array(2, struct sockaddr *); | 547 | next = pos->ai_next; |
511 | saddrlens = GNUNET_new_array(2, socklen_t); | 548 | if ((disablev6) && (pos->ai_family == AF_INET6)) |
512 | add_unixpath(saddrs, saddrlens, unixpath, abstract); | 549 | continue; |
513 | GNUNET_free_non_null(unixpath); | 550 | i++; |
514 | GNUNET_free_non_null(hostname); | ||
515 | *addrs = saddrs; | ||
516 | *addr_lens = saddrlens; | ||
517 | return 1; | ||
518 | } | 551 | } |
519 | 552 | if (0 == i) | |
520 | if (NULL != hostname) | ||
521 | { | 553 | { |
522 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 554 | LOG (GNUNET_ERROR_TYPE_ERROR, |
523 | "Resolving `%s' since that is where `%s' will bind to.\n", | 555 | _ ("Failed to find %saddress for `%s'.\n"), |
524 | hostname, | 556 | disablev6 ? "IPv4 " : "", |
525 | service_name); | 557 | hostname); |
526 | memset(&hints, 0, sizeof(struct addrinfo)); | 558 | freeaddrinfo (res); |
527 | if (disablev6) | 559 | GNUNET_free (hostname); |
528 | hints.ai_family = AF_INET; | 560 | GNUNET_free_non_null (unixpath); |
529 | hints.ai_protocol = IPPROTO_TCP; | 561 | return GNUNET_SYSERR; |
530 | if ((0 != (ret = getaddrinfo(hostname, NULL, &hints, &res))) || | 562 | } |
531 | (NULL == res)) | 563 | resi = i; |
532 | { | 564 | if (NULL != unixpath) |
533 | LOG(GNUNET_ERROR_TYPE_ERROR, | 565 | resi++; |
534 | _("Failed to resolve `%s': %s\n"), | 566 | saddrs = GNUNET_new_array (resi + 1, struct sockaddr *); |
535 | hostname, | 567 | saddrlens = GNUNET_new_array (resi + 1, socklen_t); |
536 | gai_strerror(ret)); | 568 | i = 0; |
537 | GNUNET_free(hostname); | 569 | if (NULL != unixpath) |
538 | GNUNET_free_non_null(unixpath); | 570 | { |
539 | return GNUNET_SYSERR; | 571 | add_unixpath (saddrs, saddrlens, unixpath, abstract); |
540 | } | 572 | i++; |
541 | next = res; | 573 | } |
542 | i = 0; | 574 | next = res; |
543 | while (NULL != (pos = next)) | 575 | while (NULL != (pos = next)) |
544 | { | 576 | { |
545 | next = pos->ai_next; | 577 | next = pos->ai_next; |
546 | if ((disablev6) && (pos->ai_family == AF_INET6)) | 578 | if ((disablev6) && (AF_INET6 == pos->ai_family)) |
547 | continue; | 579 | continue; |
548 | i++; | 580 | if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol)) |
549 | } | 581 | continue; /* not TCP */ |
550 | if (0 == i) | 582 | if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype)) |
551 | { | 583 | continue; /* huh? */ |
552 | LOG(GNUNET_ERROR_TYPE_ERROR, | 584 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
553 | _("Failed to find %saddress for `%s'.\n"), | 585 | "Service `%s' will bind to `%s'\n", |
554 | disablev6 ? "IPv4 " : "", | 586 | service_name, |
555 | hostname); | 587 | GNUNET_a2s (pos->ai_addr, pos->ai_addrlen)); |
556 | freeaddrinfo(res); | 588 | if (AF_INET == pos->ai_family) |
557 | GNUNET_free(hostname); | 589 | { |
558 | GNUNET_free_non_null(unixpath); | 590 | GNUNET_assert (sizeof(struct sockaddr_in) == pos->ai_addrlen); |
559 | return GNUNET_SYSERR; | 591 | saddrlens[i] = pos->ai_addrlen; |
560 | } | 592 | saddrs[i] = GNUNET_malloc (saddrlens[i]); |
561 | resi = i; | 593 | GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); |
594 | ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); | ||
595 | } | ||
596 | else | ||
597 | { | ||
598 | GNUNET_assert (AF_INET6 == pos->ai_family); | ||
599 | GNUNET_assert (sizeof(struct sockaddr_in6) == pos->ai_addrlen); | ||
600 | saddrlens[i] = pos->ai_addrlen; | ||
601 | saddrs[i] = GNUNET_malloc (saddrlens[i]); | ||
602 | GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); | ||
603 | ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); | ||
604 | } | ||
605 | i++; | ||
606 | } | ||
607 | GNUNET_free (hostname); | ||
608 | freeaddrinfo (res); | ||
609 | resi = i; | ||
610 | } | ||
611 | else | ||
612 | { | ||
613 | /* will bind against everything, just set port */ | ||
614 | if (disablev6) | ||
615 | { | ||
616 | /* V4-only */ | ||
617 | resi = 1; | ||
562 | if (NULL != unixpath) | 618 | if (NULL != unixpath) |
563 | resi++; | 619 | resi++; |
564 | saddrs = GNUNET_new_array(resi + 1, struct sockaddr *); | ||
565 | saddrlens = GNUNET_new_array(resi + 1, socklen_t); | ||
566 | i = 0; | 620 | i = 0; |
621 | saddrs = GNUNET_new_array (resi + 1, struct sockaddr *); | ||
622 | saddrlens = GNUNET_new_array (resi + 1, socklen_t); | ||
567 | if (NULL != unixpath) | 623 | if (NULL != unixpath) |
568 | { | 624 | { |
569 | add_unixpath(saddrs, saddrlens, unixpath, abstract); | 625 | add_unixpath (saddrs, saddrlens, unixpath, abstract); |
570 | i++; | 626 | i++; |
571 | } | 627 | } |
572 | next = res; | 628 | saddrlens[i] = sizeof(struct sockaddr_in); |
573 | while (NULL != (pos = next)) | 629 | saddrs[i] = GNUNET_malloc (saddrlens[i]); |
574 | { | ||
575 | next = pos->ai_next; | ||
576 | if ((disablev6) && (AF_INET6 == pos->ai_family)) | ||
577 | continue; | ||
578 | if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol)) | ||
579 | continue; /* not TCP */ | ||
580 | if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype)) | ||
581 | continue; /* huh? */ | ||
582 | LOG(GNUNET_ERROR_TYPE_DEBUG, | ||
583 | "Service `%s' will bind to `%s'\n", | ||
584 | service_name, | ||
585 | GNUNET_a2s(pos->ai_addr, pos->ai_addrlen)); | ||
586 | if (AF_INET == pos->ai_family) | ||
587 | { | ||
588 | GNUNET_assert(sizeof(struct sockaddr_in) == pos->ai_addrlen); | ||
589 | saddrlens[i] = pos->ai_addrlen; | ||
590 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | ||
591 | GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]); | ||
592 | ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); | ||
593 | } | ||
594 | else | ||
595 | { | ||
596 | GNUNET_assert(AF_INET6 == pos->ai_family); | ||
597 | GNUNET_assert(sizeof(struct sockaddr_in6) == pos->ai_addrlen); | ||
598 | saddrlens[i] = pos->ai_addrlen; | ||
599 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | ||
600 | GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]); | ||
601 | ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port); | ||
602 | } | ||
603 | i++; | ||
604 | } | ||
605 | GNUNET_free(hostname); | ||
606 | freeaddrinfo(res); | ||
607 | resi = i; | ||
608 | } | ||
609 | else | ||
610 | { | ||
611 | /* will bind against everything, just set port */ | ||
612 | if (disablev6) | ||
613 | { | ||
614 | /* V4-only */ | ||
615 | resi = 1; | ||
616 | if (NULL != unixpath) | ||
617 | resi++; | ||
618 | i = 0; | ||
619 | saddrs = GNUNET_new_array(resi + 1, struct sockaddr *); | ||
620 | saddrlens = GNUNET_new_array(resi + 1, socklen_t); | ||
621 | if (NULL != unixpath) | ||
622 | { | ||
623 | add_unixpath(saddrs, saddrlens, unixpath, abstract); | ||
624 | i++; | ||
625 | } | ||
626 | saddrlens[i] = sizeof(struct sockaddr_in); | ||
627 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | ||
628 | #if HAVE_SOCKADDR_IN_SIN_LEN | 630 | #if HAVE_SOCKADDR_IN_SIN_LEN |
629 | ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[i]; | 631 | ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i]; |
630 | #endif | 632 | #endif |
631 | ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET; | 633 | ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; |
632 | ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); | 634 | ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); |
633 | } | 635 | } |
634 | else | 636 | else |
635 | { | 637 | { |
636 | /* dual stack */ | 638 | /* dual stack */ |
637 | resi = 2; | 639 | resi = 2; |
638 | if (NULL != unixpath) | 640 | if (NULL != unixpath) |
639 | resi++; | 641 | resi++; |
640 | saddrs = GNUNET_new_array(resi + 1, struct sockaddr *); | 642 | saddrs = GNUNET_new_array (resi + 1, struct sockaddr *); |
641 | saddrlens = GNUNET_new_array(resi + 1, socklen_t); | 643 | saddrlens = GNUNET_new_array (resi + 1, socklen_t); |
642 | i = 0; | 644 | i = 0; |
643 | if (NULL != unixpath) | 645 | if (NULL != unixpath) |
644 | { | 646 | { |
645 | add_unixpath(saddrs, saddrlens, unixpath, abstract); | 647 | add_unixpath (saddrs, saddrlens, unixpath, abstract); |
646 | i++; | 648 | i++; |
647 | } | 649 | } |
648 | saddrlens[i] = sizeof(struct sockaddr_in6); | 650 | saddrlens[i] = sizeof(struct sockaddr_in6); |
649 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | 651 | saddrs[i] = GNUNET_malloc (saddrlens[i]); |
650 | #if HAVE_SOCKADDR_IN_SIN_LEN | 652 | #if HAVE_SOCKADDR_IN_SIN_LEN |
651 | ((struct sockaddr_in6 *)saddrs[i])->sin6_len = saddrlens[0]; | 653 | ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0]; |
652 | #endif | 654 | #endif |
653 | ((struct sockaddr_in6 *)saddrs[i])->sin6_family = AF_INET6; | 655 | ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6; |
654 | ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port); | 656 | ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); |
655 | i++; | 657 | i++; |
656 | saddrlens[i] = sizeof(struct sockaddr_in); | 658 | saddrlens[i] = sizeof(struct sockaddr_in); |
657 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | 659 | saddrs[i] = GNUNET_malloc (saddrlens[i]); |
658 | #if HAVE_SOCKADDR_IN_SIN_LEN | 660 | #if HAVE_SOCKADDR_IN_SIN_LEN |
659 | ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[1]; | 661 | ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1]; |
660 | #endif | 662 | #endif |
661 | ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET; | 663 | ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; |
662 | ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); | 664 | ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); |
663 | } | ||
664 | } | 665 | } |
665 | GNUNET_free_non_null(unixpath); | 666 | } |
667 | GNUNET_free_non_null (unixpath); | ||
666 | *addrs = saddrs; | 668 | *addrs = saddrs; |
667 | *addr_lens = saddrlens; | 669 | *addr_lens = saddrlens; |
668 | return resi; | 670 | return resi; |
@@ -680,19 +682,19 @@ get_server_addresses(const char *service_name, | |||
680 | * @return NULL if it was not found | 682 | * @return NULL if it was not found |
681 | */ | 683 | */ |
682 | static void | 684 | static void |
683 | signal_result(struct GNUNET_SERVICE_Client *client, | 685 | signal_result (struct GNUNET_SERVICE_Client *client, |
684 | const char *name, | 686 | const char *name, |
685 | uint64_t request_id, | 687 | uint64_t request_id, |
686 | enum GNUNET_ARM_Result result) | 688 | enum GNUNET_ARM_Result result) |
687 | { | 689 | { |
688 | struct GNUNET_MQ_Envelope *env; | 690 | struct GNUNET_MQ_Envelope *env; |
689 | struct GNUNET_ARM_ResultMessage *msg; | 691 | struct GNUNET_ARM_ResultMessage *msg; |
690 | 692 | ||
691 | (void)name; | 693 | (void) name; |
692 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_ARM_RESULT); | 694 | env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_ARM_RESULT); |
693 | msg->result = htonl(result); | 695 | msg->result = htonl (result); |
694 | msg->arm_msg.request_id = GNUNET_htonll(request_id); | 696 | msg->arm_msg.request_id = GNUNET_htonll (request_id); |
695 | GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), env); | 697 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); |
696 | } | 698 | } |
697 | 699 | ||
698 | 700 | ||
@@ -705,34 +707,34 @@ signal_result(struct GNUNET_SERVICE_Client *client, | |||
705 | * otherwise, send to all clients in the notifier | 707 | * otherwise, send to all clients in the notifier |
706 | */ | 708 | */ |
707 | static void | 709 | static void |
708 | broadcast_status(const char *name, | 710 | broadcast_status (const char *name, |
709 | enum GNUNET_ARM_ServiceMonitorStatus status, | 711 | enum GNUNET_ARM_ServiceMonitorStatus status, |
710 | struct GNUNET_SERVICE_Client *unicast) | 712 | struct GNUNET_SERVICE_Client *unicast) |
711 | { | 713 | { |
712 | struct GNUNET_MQ_Envelope *env; | 714 | struct GNUNET_MQ_Envelope *env; |
713 | struct GNUNET_ARM_StatusMessage *msg; | 715 | struct GNUNET_ARM_StatusMessage *msg; |
714 | size_t namelen; | 716 | size_t namelen; |
715 | 717 | ||
716 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 718 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
717 | "Sending status %u of service `%s' to client\n", | 719 | "Sending status %u of service `%s' to client\n", |
718 | (unsigned int)status, | 720 | (unsigned int) status, |
719 | name); | 721 | name); |
720 | namelen = strlen(name) + 1; | 722 | namelen = strlen (name) + 1; |
721 | env = GNUNET_MQ_msg_extra(msg, namelen, GNUNET_MESSAGE_TYPE_ARM_STATUS); | 723 | env = GNUNET_MQ_msg_extra (msg, namelen, GNUNET_MESSAGE_TYPE_ARM_STATUS); |
722 | msg->status = htonl((uint32_t)(status)); | 724 | msg->status = htonl ((uint32_t) (status)); |
723 | GNUNET_memcpy((char *)&msg[1], name, namelen); | 725 | GNUNET_memcpy ((char *) &msg[1], name, namelen); |
724 | if (NULL == unicast) | 726 | if (NULL == unicast) |
725 | { | 727 | { |
726 | if (NULL != notifier) | 728 | if (NULL != notifier) |
727 | GNUNET_notification_context_broadcast(notifier, | 729 | GNUNET_notification_context_broadcast (notifier, |
728 | &msg->header, | 730 | &msg->header, |
729 | GNUNET_YES); | 731 | GNUNET_YES); |
730 | GNUNET_MQ_discard(env); | 732 | GNUNET_MQ_discard (env); |
731 | } | 733 | } |
732 | else | 734 | else |
733 | { | 735 | { |
734 | GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(unicast), env); | 736 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (unicast), env); |
735 | } | 737 | } |
736 | } | 738 | } |
737 | 739 | ||
738 | 740 | ||
@@ -745,9 +747,9 @@ broadcast_status(const char *name, | |||
745 | * being started. 0 if starting was not requested. | 747 | * being started. 0 if starting was not requested. |
746 | */ | 748 | */ |
747 | static void | 749 | static void |
748 | start_process(struct ServiceList *sl, | 750 | start_process (struct ServiceList *sl, |
749 | struct GNUNET_SERVICE_Client *client, | 751 | struct GNUNET_SERVICE_Client *client, |
750 | uint64_t request_id) | 752 | uint64_t request_id) |
751 | { | 753 | { |
752 | char *loprefix; | 754 | char *loprefix; |
753 | char *options; | 755 | char *options; |
@@ -763,192 +765,192 @@ start_process(struct ServiceList *sl, | |||
763 | lsocks = NULL; | 765 | lsocks = NULL; |
764 | ls = 0; | 766 | ls = 0; |
765 | for (sli = sl->listen_head; NULL != sli; sli = sli->next) | 767 | for (sli = sl->listen_head; NULL != sli; sli = sli->next) |
768 | { | ||
769 | GNUNET_array_append (lsocks, | ||
770 | ls, | ||
771 | GNUNET_NETWORK_get_fd (sli->listen_socket)); | ||
772 | if (NULL != sli->accept_task) | ||
766 | { | 773 | { |
767 | GNUNET_array_append(lsocks, | 774 | GNUNET_SCHEDULER_cancel (sli->accept_task); |
768 | ls, | 775 | sli->accept_task = NULL; |
769 | GNUNET_NETWORK_get_fd(sli->listen_socket)); | ||
770 | if (NULL != sli->accept_task) | ||
771 | { | ||
772 | GNUNET_SCHEDULER_cancel(sli->accept_task); | ||
773 | sli->accept_task = NULL; | ||
774 | } | ||
775 | } | 776 | } |
777 | } | ||
776 | 778 | ||
777 | GNUNET_array_append(lsocks, ls, -1); | 779 | GNUNET_array_append (lsocks, ls, -1); |
778 | 780 | ||
779 | /* obtain configuration */ | 781 | /* obtain configuration */ |
780 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, | 782 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, |
781 | sl->name, | 783 | sl->name, |
782 | "PREFIX", | 784 | "PREFIX", |
783 | &loprefix)) | 785 | &loprefix)) |
784 | loprefix = GNUNET_strdup(prefix_command); | 786 | loprefix = GNUNET_strdup (prefix_command); |
785 | else | 787 | else |
786 | loprefix = GNUNET_CONFIGURATION_expand_dollar(cfg, loprefix); | 788 | loprefix = GNUNET_CONFIGURATION_expand_dollar (cfg, loprefix); |
787 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, | 789 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, |
788 | sl->name, | 790 | sl->name, |
789 | "OPTIONS", | 791 | "OPTIONS", |
790 | &options)) | 792 | &options)) |
791 | options = NULL; | 793 | options = NULL; |
792 | else | 794 | else |
793 | options = GNUNET_CONFIGURATION_expand_dollar(cfg, options); | 795 | options = GNUNET_CONFIGURATION_expand_dollar (cfg, options); |
794 | { | 796 | { |
795 | char *new_options; | 797 | char *new_options; |
796 | char *optpos; | 798 | char *optpos; |
797 | char *fin_options; | 799 | char *fin_options; |
798 | 800 | ||
799 | fin_options = GNUNET_strdup(final_option); | 801 | fin_options = GNUNET_strdup (final_option); |
800 | /* replace '{}' with service name */ | 802 | /* replace '{}' with service name */ |
801 | while (NULL != (optpos = strstr(fin_options, "{}"))) | 803 | while (NULL != (optpos = strstr (fin_options, "{}"))) |
802 | { | 804 | { |
803 | /* terminate string at opening parenthesis */ | 805 | /* terminate string at opening parenthesis */ |
804 | *optpos = 0; | 806 | *optpos = 0; |
805 | GNUNET_asprintf(&new_options, | 807 | GNUNET_asprintf (&new_options, |
806 | "%s%s%s", | 808 | "%s%s%s", |
807 | fin_options, | 809 | fin_options, |
808 | sl->name, | 810 | sl->name, |
809 | optpos + 2); | 811 | optpos + 2); |
810 | GNUNET_free(fin_options); | 812 | GNUNET_free (fin_options); |
811 | fin_options = new_options; | 813 | fin_options = new_options; |
812 | } | 814 | } |
813 | if (NULL != options) | 815 | if (NULL != options) |
814 | { | 816 | { |
815 | /* combine "fin_options" with "options" */ | 817 | /* combine "fin_options" with "options" */ |
816 | optpos = options; | 818 | optpos = options; |
817 | GNUNET_asprintf(&options, "%s %s", fin_options, optpos); | 819 | GNUNET_asprintf (&options, "%s %s", fin_options, optpos); |
818 | GNUNET_free(fin_options); | 820 | GNUNET_free (fin_options); |
819 | GNUNET_free(optpos); | 821 | GNUNET_free (optpos); |
820 | } | 822 | } |
821 | else | 823 | else |
822 | { | 824 | { |
823 | /* only have "fin_options", use that */ | 825 | /* only have "fin_options", use that */ |
824 | options = fin_options; | 826 | options = fin_options; |
825 | } | 827 | } |
826 | } | 828 | } |
827 | options = GNUNET_CONFIGURATION_expand_dollar(cfg, options); | 829 | options = GNUNET_CONFIGURATION_expand_dollar (cfg, options); |
828 | use_debug = GNUNET_CONFIGURATION_get_value_yesno(cfg, sl->name, "DEBUG"); | 830 | use_debug = GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "DEBUG"); |
829 | { | 831 | { |
830 | const char *service_type = NULL; | 832 | const char *service_type = NULL; |
831 | const char *choices[] = { "GNUNET", "SIMPLE", NULL }; | 833 | const char *choices[] = { "GNUNET", "SIMPLE", NULL }; |
832 | 834 | ||
833 | is_simple_service = GNUNET_NO; | 835 | is_simple_service = GNUNET_NO; |
834 | if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_choice(cfg, | 836 | if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_choice (cfg, |
835 | sl->name, | 837 | sl->name, |
836 | "TYPE", | 838 | "TYPE", |
837 | choices, | 839 | choices, |
838 | &service_type)) && | 840 | &service_type)) && |
839 | (0 == strcasecmp(service_type, "SIMPLE"))) | 841 | (0 == strcasecmp (service_type, "SIMPLE"))) |
840 | is_simple_service = GNUNET_YES; | 842 | is_simple_service = GNUNET_YES; |
841 | } | 843 | } |
842 | 844 | ||
843 | GNUNET_assert(NULL == sl->proc); | 845 | GNUNET_assert (NULL == sl->proc); |
844 | if (GNUNET_YES == is_simple_service) | 846 | if (GNUNET_YES == is_simple_service) |
847 | { | ||
848 | /* A simple service will receive no GNUnet specific | ||
849 | command line options. */ | ||
850 | binary = GNUNET_strdup (sl->binary); | ||
851 | binary = GNUNET_CONFIGURATION_expand_dollar (cfg, binary); | ||
852 | GNUNET_asprintf ("edbinary, "\"%s\"", sl->binary); | ||
853 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
854 | "Starting simple service `%s' using binary `%s'\n", | ||
855 | sl->name, | ||
856 | sl->binary); | ||
857 | /* FIXME: dollar expansion should only be done outside | ||
858 | * of ''-quoted strings, escaping should be considered. */ | ||
859 | if (NULL != options) | ||
860 | options = GNUNET_CONFIGURATION_expand_dollar (cfg, options); | ||
861 | sl->proc = GNUNET_OS_start_process_s (sl->pipe_control, | ||
862 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, | ||
863 | lsocks, | ||
864 | loprefix, | ||
865 | quotedbinary, | ||
866 | options, | ||
867 | NULL); | ||
868 | } | ||
869 | else | ||
870 | { | ||
871 | /* actually start process */ | ||
872 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
873 | "Starting service `%s' using binary `%s' and configuration `%s'\n", | ||
874 | sl->name, | ||
875 | sl->binary, | ||
876 | sl->config); | ||
877 | binary = GNUNET_OS_get_libexec_binary_path (sl->binary); | ||
878 | GNUNET_asprintf ("edbinary, "\"%s\"", binary); | ||
879 | |||
880 | if (GNUNET_YES == use_debug) | ||
845 | { | 881 | { |
846 | /* A simple service will receive no GNUnet specific | 882 | if (NULL == sl->config) |
847 | command line options. */ | 883 | sl->proc = GNUNET_OS_start_process_s (sl->pipe_control, |
848 | binary = GNUNET_strdup(sl->binary); | 884 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, |
849 | binary = GNUNET_CONFIGURATION_expand_dollar(cfg, binary); | 885 | lsocks, |
850 | GNUNET_asprintf("edbinary, "\"%s\"", sl->binary); | 886 | loprefix, |
851 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 887 | quotedbinary, |
852 | "Starting simple service `%s' using binary `%s'\n", | 888 | "-L", |
853 | sl->name, | 889 | "DEBUG", |
854 | sl->binary); | 890 | options, |
855 | /* FIXME: dollar expansion should only be done outside | 891 | NULL); |
856 | * of ''-quoted strings, escaping should be considered. */ | 892 | else |
857 | if (NULL != options) | 893 | sl->proc = GNUNET_OS_start_process_s (sl->pipe_control, |
858 | options = GNUNET_CONFIGURATION_expand_dollar(cfg, options); | 894 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, |
859 | sl->proc = GNUNET_OS_start_process_s(sl->pipe_control, | 895 | lsocks, |
860 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, | 896 | loprefix, |
861 | lsocks, | 897 | quotedbinary, |
862 | loprefix, | 898 | "-c", |
863 | quotedbinary, | 899 | sl->config, |
864 | options, | 900 | "-L", |
865 | NULL); | 901 | "DEBUG", |
902 | options, | ||
903 | NULL); | ||
866 | } | 904 | } |
867 | else | 905 | else |
868 | { | 906 | { |
869 | /* actually start process */ | 907 | if (NULL == sl->config) |
870 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 908 | sl->proc = GNUNET_OS_start_process_s (sl->pipe_control, |
871 | "Starting service `%s' using binary `%s' and configuration `%s'\n", | 909 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, |
872 | sl->name, | 910 | lsocks, |
873 | sl->binary, | 911 | loprefix, |
874 | sl->config); | 912 | quotedbinary, |
875 | binary = GNUNET_OS_get_libexec_binary_path(sl->binary); | 913 | options, |
876 | GNUNET_asprintf("edbinary, "\"%s\"", binary); | 914 | NULL); |
877 | |||
878 | if (GNUNET_YES == use_debug) | ||
879 | { | ||
880 | if (NULL == sl->config) | ||
881 | sl->proc = GNUNET_OS_start_process_s(sl->pipe_control, | ||
882 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, | ||
883 | lsocks, | ||
884 | loprefix, | ||
885 | quotedbinary, | ||
886 | "-L", | ||
887 | "DEBUG", | ||
888 | options, | ||
889 | NULL); | ||
890 | else | ||
891 | sl->proc = GNUNET_OS_start_process_s(sl->pipe_control, | ||
892 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, | ||
893 | lsocks, | ||
894 | loprefix, | ||
895 | quotedbinary, | ||
896 | "-c", | ||
897 | sl->config, | ||
898 | "-L", | ||
899 | "DEBUG", | ||
900 | options, | ||
901 | NULL); | ||
902 | } | ||
903 | else | 915 | else |
904 | { | 916 | sl->proc = GNUNET_OS_start_process_s (sl->pipe_control, |
905 | if (NULL == sl->config) | 917 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, |
906 | sl->proc = GNUNET_OS_start_process_s(sl->pipe_control, | 918 | lsocks, |
907 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, | 919 | loprefix, |
908 | lsocks, | 920 | quotedbinary, |
909 | loprefix, | 921 | "-c", |
910 | quotedbinary, | 922 | sl->config, |
911 | options, | 923 | options, |
912 | NULL); | 924 | NULL); |
913 | else | ||
914 | sl->proc = GNUNET_OS_start_process_s(sl->pipe_control, | ||
915 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, | ||
916 | lsocks, | ||
917 | loprefix, | ||
918 | quotedbinary, | ||
919 | "-c", | ||
920 | sl->config, | ||
921 | options, | ||
922 | NULL); | ||
923 | } | ||
924 | } | 925 | } |
925 | GNUNET_free(binary); | 926 | } |
926 | GNUNET_free(quotedbinary); | 927 | GNUNET_free (binary); |
928 | GNUNET_free (quotedbinary); | ||
927 | sl->last_started_at = GNUNET_TIME_absolute_get (); | 929 | sl->last_started_at = GNUNET_TIME_absolute_get (); |
928 | if (NULL == sl->proc) | 930 | if (NULL == sl->proc) |
929 | { | 931 | { |
930 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | 932 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
931 | _("Failed to start service `%s'\n"), | 933 | _ ("Failed to start service `%s'\n"), |
932 | sl->name); | 934 | sl->name); |
933 | if (client) | 935 | if (client) |
934 | signal_result(client, | 936 | signal_result (client, |
935 | sl->name, | 937 | sl->name, |
936 | request_id, | 938 | request_id, |
937 | GNUNET_ARM_RESULT_START_FAILED); | 939 | GNUNET_ARM_RESULT_START_FAILED); |
938 | } | 940 | } |
939 | else | 941 | else |
940 | { | 942 | { |
941 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 943 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
942 | _("Starting service `%s'\n"), | 944 | _ ("Starting service `%s'\n"), |
943 | sl->name); | 945 | sl->name); |
944 | broadcast_status(sl->name, GNUNET_ARM_SERVICE_STARTING, NULL); | 946 | broadcast_status (sl->name, GNUNET_ARM_SERVICE_STARTING, NULL); |
945 | if (client) | 947 | if (client) |
946 | signal_result(client, sl->name, request_id, GNUNET_ARM_RESULT_STARTING); | 948 | signal_result (client, sl->name, request_id, GNUNET_ARM_RESULT_STARTING); |
947 | } | 949 | } |
948 | /* clean up */ | 950 | /* clean up */ |
949 | GNUNET_free(loprefix); | 951 | GNUNET_free (loprefix); |
950 | GNUNET_free(options); | 952 | GNUNET_free (options); |
951 | GNUNET_array_grow(lsocks, ls, 0); | 953 | GNUNET_array_grow (lsocks, ls, 0); |
952 | } | 954 | } |
953 | 955 | ||
954 | 956 | ||
@@ -960,17 +962,17 @@ start_process(struct ServiceList *sl, | |||
960 | * @return NULL if it was not found | 962 | * @return NULL if it was not found |
961 | */ | 963 | */ |
962 | static struct ServiceList * | 964 | static struct ServiceList * |
963 | find_service(const char *name) | 965 | find_service (const char *name) |
964 | { | 966 | { |
965 | struct ServiceList *sl; | 967 | struct ServiceList *sl; |
966 | 968 | ||
967 | sl = running_head; | 969 | sl = running_head; |
968 | while (sl != NULL) | 970 | while (sl != NULL) |
969 | { | 971 | { |
970 | if (0 == strcasecmp(sl->name, name)) | 972 | if (0 == strcasecmp (sl->name, name)) |
971 | return sl; | 973 | return sl; |
972 | sl = sl->next; | 974 | sl = sl->next; |
973 | } | 975 | } |
974 | return NULL; | 976 | return NULL; |
975 | } | 977 | } |
976 | 978 | ||
@@ -982,14 +984,14 @@ find_service(const char *name) | |||
982 | * @param cls callback data, `struct ServiceListeningInfo` describing a listen socket | 984 | * @param cls callback data, `struct ServiceListeningInfo` describing a listen socket |
983 | */ | 985 | */ |
984 | static void | 986 | static void |
985 | accept_connection(void *cls) | 987 | accept_connection (void *cls) |
986 | { | 988 | { |
987 | struct ServiceListeningInfo *sli = cls; | 989 | struct ServiceListeningInfo *sli = cls; |
988 | struct ServiceList *sl = sli->sl; | 990 | struct ServiceList *sl = sli->sl; |
989 | 991 | ||
990 | sli->accept_task = NULL; | 992 | sli->accept_task = NULL; |
991 | GNUNET_assert(GNUNET_NO == in_shutdown); | 993 | GNUNET_assert (GNUNET_NO == in_shutdown); |
992 | start_process(sl, NULL, 0); | 994 | start_process (sl, NULL, 0); |
993 | } | 995 | } |
994 | 996 | ||
995 | 997 | ||
@@ -1002,9 +1004,9 @@ accept_connection(void *cls) | |||
1002 | * @param sl service entry for the service in question | 1004 | * @param sl service entry for the service in question |
1003 | */ | 1005 | */ |
1004 | static void | 1006 | static void |
1005 | create_listen_socket(struct sockaddr *sa, | 1007 | create_listen_socket (struct sockaddr *sa, |
1006 | socklen_t addr_len, | 1008 | socklen_t addr_len, |
1007 | struct ServiceList *sl) | 1009 | struct ServiceList *sl) |
1008 | { | 1010 | { |
1009 | static int on = 1; | 1011 | static int on = 1; |
1010 | struct GNUNET_NETWORK_Handle *sock; | 1012 | struct GNUNET_NETWORK_Handle *sock; |
@@ -1014,107 +1016,107 @@ create_listen_socket(struct sockaddr *sa, | |||
1014 | int match_gid; | 1016 | int match_gid; |
1015 | 1017 | ||
1016 | switch (sa->sa_family) | 1018 | switch (sa->sa_family) |
1017 | { | 1019 | { |
1018 | case AF_INET: | 1020 | case AF_INET: |
1019 | sock = GNUNET_NETWORK_socket_create(PF_INET, SOCK_STREAM, 0); | 1021 | sock = GNUNET_NETWORK_socket_create (PF_INET, SOCK_STREAM, 0); |
1020 | break; | 1022 | break; |
1021 | 1023 | ||
1022 | case AF_INET6: | 1024 | case AF_INET6: |
1023 | sock = GNUNET_NETWORK_socket_create(PF_INET6, SOCK_STREAM, 0); | 1025 | sock = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); |
1024 | break; | 1026 | break; |
1025 | 1027 | ||
1026 | case AF_UNIX: | 1028 | case AF_UNIX: |
1027 | if (0 == strcmp(GNUNET_a2s(sa, addr_len), | 1029 | if (0 == strcmp (GNUNET_a2s (sa, addr_len), |
1028 | "@")) /* Do not bind to blank UNIX path! */ | 1030 | "@")) /* Do not bind to blank UNIX path! */ |
1029 | return; | ||
1030 | sock = GNUNET_NETWORK_socket_create(PF_UNIX, SOCK_STREAM, 0); | ||
1031 | break; | ||
1032 | |||
1033 | default: | ||
1034 | GNUNET_break(0); | ||
1035 | sock = NULL; | ||
1036 | errno = EAFNOSUPPORT; | ||
1037 | break; | ||
1038 | } | ||
1039 | if (NULL == sock) | ||
1040 | { | ||
1041 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1042 | _("Unable to create socket for service `%s': %s\n"), | ||
1043 | sl->name, | ||
1044 | strerror(errno)); | ||
1045 | GNUNET_free(sa); | ||
1046 | return; | 1031 | return; |
1047 | } | 1032 | sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0); |
1048 | if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt(sock, | 1033 | break; |
1049 | SOL_SOCKET, | 1034 | |
1050 | SO_REUSEADDR, | 1035 | default: |
1051 | &on, | 1036 | GNUNET_break (0); |
1052 | sizeof(on))) | 1037 | sock = NULL; |
1053 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 1038 | errno = EAFNOSUPPORT; |
1054 | "setsockopt"); | 1039 | break; |
1040 | } | ||
1041 | if (NULL == sock) | ||
1042 | { | ||
1043 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1044 | _ ("Unable to create socket for service `%s': %s\n"), | ||
1045 | sl->name, | ||
1046 | strerror (errno)); | ||
1047 | GNUNET_free (sa); | ||
1048 | return; | ||
1049 | } | ||
1050 | if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (sock, | ||
1051 | SOL_SOCKET, | ||
1052 | SO_REUSEADDR, | ||
1053 | &on, | ||
1054 | sizeof(on))) | ||
1055 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1056 | "setsockopt"); | ||
1055 | #ifdef IPV6_V6ONLY | 1057 | #ifdef IPV6_V6ONLY |
1056 | if ((sa->sa_family == AF_INET6) && | 1058 | if ((sa->sa_family == AF_INET6) && |
1057 | (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt(sock, | 1059 | (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (sock, |
1058 | IPPROTO_IPV6, | 1060 | IPPROTO_IPV6, |
1059 | IPV6_V6ONLY, | 1061 | IPV6_V6ONLY, |
1060 | &on, | 1062 | &on, |
1061 | sizeof(on)))) | 1063 | sizeof(on)))) |
1062 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 1064 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
1063 | "setsockopt"); | 1065 | "setsockopt"); |
1064 | #endif | 1066 | #endif |
1065 | if (AF_UNIX == sa->sa_family) | 1067 | if (AF_UNIX == sa->sa_family) |
1066 | GNUNET_NETWORK_unix_precheck((struct sockaddr_un *)sa); | 1068 | GNUNET_NETWORK_unix_precheck ((struct sockaddr_un *) sa); |
1067 | if (GNUNET_OK != | 1069 | if (GNUNET_OK != |
1068 | GNUNET_NETWORK_socket_bind(sock, (const struct sockaddr *)sa, addr_len)) | 1070 | GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) sa, addr_len)) |
1069 | { | 1071 | { |
1070 | GNUNET_log( | 1072 | GNUNET_log ( |
1071 | GNUNET_ERROR_TYPE_WARNING, | 1073 | GNUNET_ERROR_TYPE_WARNING, |
1072 | _( | 1074 | _ ( |
1073 | "Unable to bind listening socket for service `%s' to address `%s': %s\n"), | 1075 | "Unable to bind listening socket for service `%s' to address `%s': %s\n"), |
1074 | sl->name, | 1076 | sl->name, |
1075 | GNUNET_a2s(sa, addr_len), | 1077 | GNUNET_a2s (sa, addr_len), |
1076 | strerror(errno)); | 1078 | strerror (errno)); |
1077 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock)); | 1079 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); |
1078 | GNUNET_free(sa); | 1080 | GNUNET_free (sa); |
1079 | return; | 1081 | return; |
1080 | } | 1082 | } |
1081 | if ((AF_UNIX == sa->sa_family) | 1083 | if ((AF_UNIX == sa->sa_family) |
1082 | #ifdef LINUX | 1084 | #ifdef LINUX |
1083 | /* Permission settings are not required when abstract sockets are used */ | 1085 | /* Permission settings are not required when abstract sockets are used */ |
1084 | && ('\0' != ((const struct sockaddr_un *)sa)->sun_path[0]) | 1086 | && ('\0' != ((const struct sockaddr_un *) sa)->sun_path[0]) |
1085 | #endif | 1087 | #endif |
1086 | ) | 1088 | ) |
1087 | { | 1089 | { |
1088 | match_uid = | 1090 | match_uid = |
1089 | GNUNET_CONFIGURATION_get_value_yesno(cfg, sl->name, "UNIX_MATCH_UID"); | 1091 | GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "UNIX_MATCH_UID"); |
1090 | match_gid = | 1092 | match_gid = |
1091 | GNUNET_CONFIGURATION_get_value_yesno(cfg, sl->name, "UNIX_MATCH_GID"); | 1093 | GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "UNIX_MATCH_GID"); |
1092 | GNUNET_DISK_fix_permissions(((const struct sockaddr_un *)sa)->sun_path, | 1094 | GNUNET_DISK_fix_permissions (((const struct sockaddr_un *) sa)->sun_path, |
1093 | match_uid, | 1095 | match_uid, |
1094 | match_gid); | 1096 | match_gid); |
1095 | } | 1097 | } |
1096 | if (GNUNET_OK != GNUNET_NETWORK_socket_listen(sock, 5)) | 1098 | if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5)) |
1097 | { | 1099 | { |
1098 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "listen"); | 1100 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen"); |
1099 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock)); | 1101 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); |
1100 | GNUNET_free(sa); | 1102 | GNUNET_free (sa); |
1101 | return; | 1103 | return; |
1102 | } | 1104 | } |
1103 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 1105 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1104 | _("ARM now monitors connections to service `%s' at `%s'\n"), | 1106 | _ ("ARM now monitors connections to service `%s' at `%s'\n"), |
1105 | sl->name, | 1107 | sl->name, |
1106 | GNUNET_a2s(sa, addr_len)); | 1108 | GNUNET_a2s (sa, addr_len)); |
1107 | sli = GNUNET_new(struct ServiceListeningInfo); | 1109 | sli = GNUNET_new (struct ServiceListeningInfo); |
1108 | sli->service_addr = sa; | 1110 | sli->service_addr = sa; |
1109 | sli->service_addr_len = addr_len; | 1111 | sli->service_addr_len = addr_len; |
1110 | sli->listen_socket = sock; | 1112 | sli->listen_socket = sock; |
1111 | sli->sl = sl; | 1113 | sli->sl = sl; |
1112 | sli->accept_task = | 1114 | sli->accept_task = |
1113 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 1115 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
1114 | sock, | 1116 | sock, |
1115 | &accept_connection, | 1117 | &accept_connection, |
1116 | sli); | 1118 | sli); |
1117 | GNUNET_CONTAINER_DLL_insert(sl->listen_head, sl->listen_tail, sli); | 1119 | GNUNET_CONTAINER_DLL_insert (sl->listen_head, sl->listen_tail, sli); |
1118 | } | 1120 | } |
1119 | 1121 | ||
1120 | 1122 | ||
@@ -1125,15 +1127,15 @@ create_listen_socket(struct sockaddr *sa, | |||
1125 | * @param sl entry to free | 1127 | * @param sl entry to free |
1126 | */ | 1128 | */ |
1127 | static void | 1129 | static void |
1128 | free_service(struct ServiceList *sl) | 1130 | free_service (struct ServiceList *sl) |
1129 | { | 1131 | { |
1130 | GNUNET_assert(GNUNET_YES == in_shutdown); | 1132 | GNUNET_assert (GNUNET_YES == in_shutdown); |
1131 | GNUNET_CONTAINER_DLL_remove(running_head, running_tail, sl); | 1133 | GNUNET_CONTAINER_DLL_remove (running_head, running_tail, sl); |
1132 | GNUNET_assert(NULL == sl->listen_head); | 1134 | GNUNET_assert (NULL == sl->listen_head); |
1133 | GNUNET_free_non_null(sl->config); | 1135 | GNUNET_free_non_null (sl->config); |
1134 | GNUNET_free_non_null(sl->binary); | 1136 | GNUNET_free_non_null (sl->binary); |
1135 | GNUNET_free(sl->name); | 1137 | GNUNET_free (sl->name); |
1136 | GNUNET_free(sl); | 1138 | GNUNET_free (sl); |
1137 | } | 1139 | } |
1138 | 1140 | ||
1139 | 1141 | ||
@@ -1146,10 +1148,10 @@ free_service(struct ServiceList *sl) | |||
1146 | * #GNUNET_SYSERR to close it (signal serious error) | 1148 | * #GNUNET_SYSERR to close it (signal serious error) |
1147 | */ | 1149 | */ |
1148 | static int | 1150 | static int |
1149 | check_start(void *cls, const struct GNUNET_ARM_Message *amsg) | 1151 | check_start (void *cls, const struct GNUNET_ARM_Message *amsg) |
1150 | { | 1152 | { |
1151 | (void)cls; | 1153 | (void) cls; |
1152 | GNUNET_MQ_check_zero_termination(amsg); | 1154 | GNUNET_MQ_check_zero_termination (amsg); |
1153 | return GNUNET_OK; | 1155 | return GNUNET_OK; |
1154 | } | 1156 | } |
1155 | 1157 | ||
@@ -1161,43 +1163,43 @@ check_start(void *cls, const struct GNUNET_ARM_Message *amsg) | |||
1161 | * @param amsg the actual message | 1163 | * @param amsg the actual message |
1162 | */ | 1164 | */ |
1163 | static void | 1165 | static void |
1164 | handle_start(void *cls, const struct GNUNET_ARM_Message *amsg) | 1166 | handle_start (void *cls, const struct GNUNET_ARM_Message *amsg) |
1165 | { | 1167 | { |
1166 | struct GNUNET_SERVICE_Client *client = cls; | 1168 | struct GNUNET_SERVICE_Client *client = cls; |
1167 | const char *servicename; | 1169 | const char *servicename; |
1168 | struct ServiceList *sl; | 1170 | struct ServiceList *sl; |
1169 | uint64_t request_id; | 1171 | uint64_t request_id; |
1170 | 1172 | ||
1171 | request_id = GNUNET_ntohll(amsg->request_id); | 1173 | request_id = GNUNET_ntohll (amsg->request_id); |
1172 | servicename = (const char *)&amsg[1]; | 1174 | servicename = (const char *) &amsg[1]; |
1173 | GNUNET_SERVICE_client_continue(client); | 1175 | GNUNET_SERVICE_client_continue (client); |
1174 | if (GNUNET_YES == in_shutdown) | 1176 | if (GNUNET_YES == in_shutdown) |
1175 | { | 1177 | { |
1176 | signal_result(client, | 1178 | signal_result (client, |
1177 | servicename, | 1179 | servicename, |
1178 | request_id, | 1180 | request_id, |
1179 | GNUNET_ARM_RESULT_IN_SHUTDOWN); | 1181 | GNUNET_ARM_RESULT_IN_SHUTDOWN); |
1180 | return; | 1182 | return; |
1181 | } | 1183 | } |
1182 | sl = find_service(servicename); | 1184 | sl = find_service (servicename); |
1183 | if (NULL == sl) | 1185 | if (NULL == sl) |
1184 | { | 1186 | { |
1185 | signal_result(client, | 1187 | signal_result (client, |
1186 | servicename, | 1188 | servicename, |
1187 | request_id, | 1189 | request_id, |
1188 | GNUNET_ARM_RESULT_IS_NOT_KNOWN); | 1190 | GNUNET_ARM_RESULT_IS_NOT_KNOWN); |
1189 | return; | 1191 | return; |
1190 | } | 1192 | } |
1191 | sl->force_start = GNUNET_YES; | 1193 | sl->force_start = GNUNET_YES; |
1192 | if (NULL != sl->proc) | 1194 | if (NULL != sl->proc) |
1193 | { | 1195 | { |
1194 | signal_result(client, | 1196 | signal_result (client, |
1195 | servicename, | 1197 | servicename, |
1196 | request_id, | 1198 | request_id, |
1197 | GNUNET_ARM_RESULT_IS_STARTED_ALREADY); | 1199 | GNUNET_ARM_RESULT_IS_STARTED_ALREADY); |
1198 | return; | 1200 | return; |
1199 | } | 1201 | } |
1200 | start_process(sl, client, request_id); | 1202 | start_process (sl, client, request_id); |
1201 | } | 1203 | } |
1202 | 1204 | ||
1203 | 1205 | ||
@@ -1207,11 +1209,11 @@ handle_start(void *cls, const struct GNUNET_ARM_Message *amsg) | |||
1207 | * @param cls closure (refers to service) | 1209 | * @param cls closure (refers to service) |
1208 | */ | 1210 | */ |
1209 | static void | 1211 | static void |
1210 | trigger_shutdown(void *cls) | 1212 | trigger_shutdown (void *cls) |
1211 | { | 1213 | { |
1212 | (void)cls; | 1214 | (void) cls; |
1213 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Triggering shutdown\n"); | 1215 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Triggering shutdown\n"); |
1214 | GNUNET_SCHEDULER_shutdown(); | 1216 | GNUNET_SCHEDULER_shutdown (); |
1215 | } | 1217 | } |
1216 | 1218 | ||
1217 | 1219 | ||
@@ -1224,10 +1226,10 @@ trigger_shutdown(void *cls) | |||
1224 | * #GNUNET_SYSERR to close it (signal serious error) | 1226 | * #GNUNET_SYSERR to close it (signal serious error) |
1225 | */ | 1227 | */ |
1226 | static int | 1228 | static int |
1227 | check_stop(void *cls, const struct GNUNET_ARM_Message *amsg) | 1229 | check_stop (void *cls, const struct GNUNET_ARM_Message *amsg) |
1228 | { | 1230 | { |
1229 | (void)cls; | 1231 | (void) cls; |
1230 | GNUNET_MQ_check_zero_termination(amsg); | 1232 | GNUNET_MQ_check_zero_termination (amsg); |
1231 | return GNUNET_OK; | 1233 | return GNUNET_OK; |
1232 | } | 1234 | } |
1233 | 1235 | ||
@@ -1239,72 +1241,72 @@ check_stop(void *cls, const struct GNUNET_ARM_Message *amsg) | |||
1239 | * @param amsg the actual message | 1241 | * @param amsg the actual message |
1240 | */ | 1242 | */ |
1241 | static void | 1243 | static void |
1242 | handle_stop(void *cls, const struct GNUNET_ARM_Message *amsg) | 1244 | handle_stop (void *cls, const struct GNUNET_ARM_Message *amsg) |
1243 | { | 1245 | { |
1244 | struct GNUNET_SERVICE_Client *client = cls; | 1246 | struct GNUNET_SERVICE_Client *client = cls; |
1245 | struct ServiceList *sl; | 1247 | struct ServiceList *sl; |
1246 | const char *servicename; | 1248 | const char *servicename; |
1247 | uint64_t request_id; | 1249 | uint64_t request_id; |
1248 | 1250 | ||
1249 | request_id = GNUNET_ntohll(amsg->request_id); | 1251 | request_id = GNUNET_ntohll (amsg->request_id); |
1250 | servicename = (const char *)&amsg[1]; | 1252 | servicename = (const char *) &amsg[1]; |
1251 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 1253 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1252 | _("Preparing to stop `%s'\n"), | 1254 | _ ("Preparing to stop `%s'\n"), |
1253 | servicename); | 1255 | servicename); |
1254 | GNUNET_SERVICE_client_continue(client); | 1256 | GNUNET_SERVICE_client_continue (client); |
1255 | if (0 == strcasecmp(servicename, "arm")) | 1257 | if (0 == strcasecmp (servicename, "arm")) |
1256 | { | 1258 | { |
1257 | broadcast_status(servicename, GNUNET_ARM_SERVICE_STOPPING, NULL); | 1259 | broadcast_status (servicename, GNUNET_ARM_SERVICE_STOPPING, NULL); |
1258 | signal_result(client, servicename, request_id, GNUNET_ARM_RESULT_STOPPING); | 1260 | signal_result (client, servicename, request_id, GNUNET_ARM_RESULT_STOPPING); |
1259 | GNUNET_SERVICE_client_persist(client); | 1261 | GNUNET_SERVICE_client_persist (client); |
1260 | GNUNET_SCHEDULER_add_now(&trigger_shutdown, NULL); | 1262 | GNUNET_SCHEDULER_add_now (&trigger_shutdown, NULL); |
1261 | return; | 1263 | return; |
1262 | } | 1264 | } |
1263 | sl = find_service(servicename); | 1265 | sl = find_service (servicename); |
1264 | if (NULL == sl) | 1266 | if (NULL == sl) |
1265 | { | 1267 | { |
1266 | signal_result(client, | 1268 | signal_result (client, |
1267 | servicename, | 1269 | servicename, |
1268 | request_id, | 1270 | request_id, |
1269 | GNUNET_ARM_RESULT_IS_NOT_KNOWN); | 1271 | GNUNET_ARM_RESULT_IS_NOT_KNOWN); |
1270 | return; | 1272 | return; |
1271 | } | 1273 | } |
1272 | sl->force_start = GNUNET_NO; | 1274 | sl->force_start = GNUNET_NO; |
1273 | if (GNUNET_YES == in_shutdown) | 1275 | if (GNUNET_YES == in_shutdown) |
1274 | { | 1276 | { |
1275 | /* shutdown in progress */ | 1277 | /* shutdown in progress */ |
1276 | signal_result(client, | 1278 | signal_result (client, |
1277 | servicename, | 1279 | servicename, |
1278 | request_id, | 1280 | request_id, |
1279 | GNUNET_ARM_RESULT_IN_SHUTDOWN); | 1281 | GNUNET_ARM_RESULT_IN_SHUTDOWN); |
1280 | return; | 1282 | return; |
1281 | } | 1283 | } |
1282 | if (NULL != sl->killing_client) | 1284 | if (NULL != sl->killing_client) |
1283 | { | 1285 | { |
1284 | /* killing already in progress */ | 1286 | /* killing already in progress */ |
1285 | signal_result(client, | 1287 | signal_result (client, |
1286 | servicename, | 1288 | servicename, |
1287 | request_id, | 1289 | request_id, |
1288 | GNUNET_ARM_RESULT_IS_STOPPING_ALREADY); | 1290 | GNUNET_ARM_RESULT_IS_STOPPING_ALREADY); |
1289 | return; | 1291 | return; |
1290 | } | 1292 | } |
1291 | if (NULL == sl->proc) | 1293 | if (NULL == sl->proc) |
1292 | { | 1294 | { |
1293 | /* process is down */ | 1295 | /* process is down */ |
1294 | signal_result(client, | 1296 | signal_result (client, |
1295 | servicename, | 1297 | servicename, |
1296 | request_id, | 1298 | request_id, |
1297 | GNUNET_ARM_RESULT_IS_STOPPED_ALREADY); | 1299 | GNUNET_ARM_RESULT_IS_STOPPED_ALREADY); |
1298 | return; | 1300 | return; |
1299 | } | 1301 | } |
1300 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 1302 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1301 | "Sending kill signal to service `%s', waiting for process to die.\n", | 1303 | "Sending kill signal to service `%s', waiting for process to die.\n", |
1302 | servicename); | 1304 | servicename); |
1303 | broadcast_status(servicename, GNUNET_ARM_SERVICE_STOPPING, NULL); | 1305 | broadcast_status (servicename, GNUNET_ARM_SERVICE_STOPPING, NULL); |
1304 | /* no signal_start - only when it's STOPPED */ | 1306 | /* no signal_start - only when it's STOPPED */ |
1305 | sl->killed_at = GNUNET_TIME_absolute_get(); | 1307 | sl->killed_at = GNUNET_TIME_absolute_get (); |
1306 | if (0 != GNUNET_OS_process_kill(sl->proc, GNUNET_TERM_SIG)) | 1308 | if (0 != GNUNET_OS_process_kill (sl->proc, GNUNET_TERM_SIG)) |
1307 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "kill"); | 1309 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); |
1308 | sl->killing_client = client; | 1310 | sl->killing_client = client; |
1309 | sl->killing_client_request_id = request_id; | 1311 | sl->killing_client_request_id = request_id; |
1310 | } | 1312 | } |
@@ -1322,7 +1324,7 @@ handle_stop(void *cls, const struct GNUNET_ARM_Message *amsg) | |||
1322 | * GNUNET_SYSERR otherwise | 1324 | * GNUNET_SYSERR otherwise |
1323 | */ | 1325 | */ |
1324 | static int | 1326 | static int |
1325 | pool_write(char *pool_start, size_t pool_size, size_t *pool_pos, char *str) | 1327 | pool_write (char *pool_start, size_t pool_size, size_t *pool_pos, char *str) |
1326 | { | 1328 | { |
1327 | size_t next_pos = (*pool_pos) + strlen (str) + 1; | 1329 | size_t next_pos = (*pool_pos) + strlen (str) + 1; |
1328 | 1330 | ||
@@ -1340,7 +1342,7 @@ pool_write(char *pool_start, size_t pool_size, size_t *pool_pos, char *str) | |||
1340 | * @param message the actual message | 1342 | * @param message the actual message |
1341 | */ | 1343 | */ |
1342 | static void | 1344 | static void |
1343 | handle_list(void *cls, const struct GNUNET_ARM_Message *request) | 1345 | handle_list (void *cls, const struct GNUNET_ARM_Message *request) |
1344 | { | 1346 | { |
1345 | struct GNUNET_SERVICE_Client *client = cls; | 1347 | struct GNUNET_SERVICE_Client *client = cls; |
1346 | struct GNUNET_MQ_Envelope *env; | 1348 | struct GNUNET_MQ_Envelope *env; |
@@ -1353,67 +1355,70 @@ handle_list(void *cls, const struct GNUNET_ARM_Message *request) | |||
1353 | char *pool_start; | 1355 | char *pool_start; |
1354 | struct GNUNET_ARM_ServiceInfoMessage *ssm; | 1356 | struct GNUNET_ARM_ServiceInfoMessage *ssm; |
1355 | 1357 | ||
1356 | GNUNET_break_op(0 == ntohl(request->reserved)); | 1358 | GNUNET_break_op (0 == ntohl (request->reserved)); |
1357 | count = 0; | 1359 | count = 0; |
1358 | pool_size = 0; | 1360 | pool_size = 0; |
1359 | 1361 | ||
1360 | /* Do one pass over the list to compute the number of services | 1362 | /* Do one pass over the list to compute the number of services |
1361 | * and the string pool size */ | 1363 | * and the string pool size */ |
1362 | for (sl = running_head; NULL != sl; sl = sl->next) | 1364 | for (sl = running_head; NULL != sl; sl = sl->next) |
1363 | { | 1365 | { |
1364 | pool_size += strlen(sl->name) + 1; | 1366 | pool_size += strlen (sl->name) + 1; |
1365 | pool_size += strlen(sl->binary) + 1; | 1367 | pool_size += strlen (sl->binary) + 1; |
1366 | count++; | 1368 | count++; |
1367 | } | 1369 | } |
1368 | 1370 | ||
1369 | extra_size = pool_size + (count * sizeof (struct GNUNET_ARM_ServiceInfoMessage)); | 1371 | extra_size = pool_size + (count * sizeof (struct |
1370 | env = GNUNET_MQ_msg_extra(msg, | 1372 | GNUNET_ARM_ServiceInfoMessage)); |
1371 | extra_size, | 1373 | env = GNUNET_MQ_msg_extra (msg, |
1372 | GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT); | 1374 | extra_size, |
1375 | GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT); | ||
1373 | msg->arm_msg.request_id = request->request_id; | 1376 | msg->arm_msg.request_id = request->request_id; |
1374 | msg->count = htons(count); | 1377 | msg->count = htons (count); |
1375 | 1378 | ||
1376 | ssm = (struct GNUNET_ARM_ServiceInfoMessage *) &msg[1]; | 1379 | ssm = (struct GNUNET_ARM_ServiceInfoMessage *) &msg[1]; |
1377 | pool_start = (char *) (ssm + count); | 1380 | pool_start = (char *) (ssm + count); |
1378 | pool_pos = 0; | 1381 | pool_pos = 0; |
1379 | 1382 | ||
1380 | for (sl = running_head; NULL != sl; sl = sl->next) | 1383 | for (sl = running_head; NULL != sl; sl = sl->next) |
1384 | { | ||
1385 | ssm->name_index = htons ((uint16_t) pool_pos); | ||
1386 | GNUNET_assert (GNUNET_OK == pool_write (pool_start, pool_size, &pool_pos, | ||
1387 | sl->name)); | ||
1388 | ssm->binary_index = htons ((uint16_t) pool_pos); | ||
1389 | GNUNET_assert (GNUNET_OK == pool_write (pool_start, pool_size, &pool_pos, | ||
1390 | sl->binary)); | ||
1391 | if (NULL == sl->proc) | ||
1381 | { | 1392 | { |
1382 | ssm->name_index = htons ((uint16_t) pool_pos); | 1393 | if (0 == sl->last_started_at.abs_value_us) |
1383 | GNUNET_assert (GNUNET_OK == pool_write (pool_start, pool_size, &pool_pos, sl->name)); | ||
1384 | ssm->binary_index = htons ((uint16_t) pool_pos); | ||
1385 | GNUNET_assert (GNUNET_OK == pool_write (pool_start, pool_size, &pool_pos, sl->binary)); | ||
1386 | if (NULL == sl->proc) | ||
1387 | { | 1394 | { |
1388 | if (0 == sl->last_started_at.abs_value_us) | 1395 | /* Process never started */ |
1389 | { | 1396 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_STOPPED); |
1390 | /* Process never started */ | ||
1391 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_STOPPED); | ||
1392 | } | ||
1393 | else if (0 == sl->last_exit_status) | ||
1394 | { | ||
1395 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_FINISHED); | ||
1396 | } | ||
1397 | else | ||
1398 | { | ||
1399 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_FAILED); | ||
1400 | ssm->last_exit_status = htons (sl->last_exit_status); | ||
1401 | } | ||
1402 | } | 1397 | } |
1403 | else if ((NULL != sl->killing_client) || (GNUNET_YES == in_shutdown)) | 1398 | else if (0 == sl->last_exit_status) |
1404 | { | 1399 | { |
1405 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_STOPPING); | 1400 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_FINISHED); |
1406 | } | 1401 | } |
1407 | else | 1402 | else |
1408 | { | 1403 | { |
1409 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_STARTED); | 1404 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_FAILED); |
1405 | ssm->last_exit_status = htons (sl->last_exit_status); | ||
1410 | } | 1406 | } |
1411 | ssm->last_started_at = GNUNET_TIME_absolute_hton (sl->last_started_at); | ||
1412 | ssm->restart_at = GNUNET_TIME_absolute_hton (sl->restart_at); | ||
1413 | ssm++; | ||
1414 | } | 1407 | } |
1415 | GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), env); | 1408 | else if ((NULL != sl->killing_client) || (GNUNET_YES == in_shutdown)) |
1416 | GNUNET_SERVICE_client_continue(client); | 1409 | { |
1410 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_STOPPING); | ||
1411 | } | ||
1412 | else | ||
1413 | { | ||
1414 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_STARTED); | ||
1415 | } | ||
1416 | ssm->last_started_at = GNUNET_TIME_absolute_hton (sl->last_started_at); | ||
1417 | ssm->restart_at = GNUNET_TIME_absolute_hton (sl->restart_at); | ||
1418 | ssm++; | ||
1419 | } | ||
1420 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); | ||
1421 | GNUNET_SERVICE_client_continue (client); | ||
1417 | } | 1422 | } |
1418 | 1423 | ||
1419 | 1424 | ||
@@ -1424,16 +1429,16 @@ handle_list(void *cls, const struct GNUNET_ARM_Message *request) | |||
1424 | * @param message the actual message | 1429 | * @param message the actual message |
1425 | */ | 1430 | */ |
1426 | static void | 1431 | static void |
1427 | handle_test(void *cls, const struct GNUNET_MessageHeader *message) | 1432 | handle_test (void *cls, const struct GNUNET_MessageHeader *message) |
1428 | { | 1433 | { |
1429 | struct GNUNET_SERVICE_Client *client = cls; | 1434 | struct GNUNET_SERVICE_Client *client = cls; |
1430 | struct GNUNET_MQ_Envelope *env; | 1435 | struct GNUNET_MQ_Envelope *env; |
1431 | struct GNUNET_MessageHeader *msg; | 1436 | struct GNUNET_MessageHeader *msg; |
1432 | 1437 | ||
1433 | (void)message; | 1438 | (void) message; |
1434 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_ARM_TEST); | 1439 | env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_ARM_TEST); |
1435 | GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), env); | 1440 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); |
1436 | GNUNET_SERVICE_client_continue(client); | 1441 | GNUNET_SERVICE_client_continue (client); |
1437 | } | 1442 | } |
1438 | 1443 | ||
1439 | 1444 | ||
@@ -1442,24 +1447,24 @@ handle_test(void *cls, const struct GNUNET_MessageHeader *message) | |||
1442 | * tasks, signal handler and the server. | 1447 | * tasks, signal handler and the server. |
1443 | */ | 1448 | */ |
1444 | static void | 1449 | static void |
1445 | do_shutdown() | 1450 | do_shutdown () |
1446 | { | 1451 | { |
1447 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Last shutdown phase\n"); | 1452 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Last shutdown phase\n"); |
1448 | if (NULL != notifier) | 1453 | if (NULL != notifier) |
1449 | { | 1454 | { |
1450 | GNUNET_notification_context_destroy(notifier); | 1455 | GNUNET_notification_context_destroy (notifier); |
1451 | notifier = NULL; | 1456 | notifier = NULL; |
1452 | } | 1457 | } |
1453 | if (NULL != service) | 1458 | if (NULL != service) |
1454 | { | 1459 | { |
1455 | GNUNET_SERVICE_shutdown(service); | 1460 | GNUNET_SERVICE_shutdown (service); |
1456 | service = NULL; | 1461 | service = NULL; |
1457 | } | 1462 | } |
1458 | if (NULL != child_death_task) | 1463 | if (NULL != child_death_task) |
1459 | { | 1464 | { |
1460 | GNUNET_SCHEDULER_cancel(child_death_task); | 1465 | GNUNET_SCHEDULER_cancel (child_death_task); |
1461 | child_death_task = NULL; | 1466 | child_death_task = NULL; |
1462 | } | 1467 | } |
1463 | } | 1468 | } |
1464 | 1469 | ||
1465 | 1470 | ||
@@ -1470,13 +1475,13 @@ do_shutdown() | |||
1470 | * @return number of active services found | 1475 | * @return number of active services found |
1471 | */ | 1476 | */ |
1472 | static unsigned int | 1477 | static unsigned int |
1473 | list_count(struct ServiceList *running_head) | 1478 | list_count (struct ServiceList *running_head) |
1474 | { | 1479 | { |
1475 | struct ServiceList *i; | 1480 | struct ServiceList *i; |
1476 | unsigned int res; | 1481 | unsigned int res; |
1477 | 1482 | ||
1478 | for (res = 0, i = running_head; NULL != i; i = i->next, res++) | 1483 | for (res = 0, i = running_head; NULL != i; i = i->next, res++) |
1479 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s\n", i->name); | 1484 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s\n", i->name); |
1480 | return res; | 1485 | return res; |
1481 | } | 1486 | } |
1482 | 1487 | ||
@@ -1487,61 +1492,61 @@ list_count(struct ServiceList *running_head) | |||
1487 | * @param cls closure, NULL if we need to self-restart | 1492 | * @param cls closure, NULL if we need to self-restart |
1488 | */ | 1493 | */ |
1489 | static void | 1494 | static void |
1490 | shutdown_task(void *cls) | 1495 | shutdown_task (void *cls) |
1491 | { | 1496 | { |
1492 | struct ServiceList *pos; | 1497 | struct ServiceList *pos; |
1493 | struct ServiceList *nxt; | 1498 | struct ServiceList *nxt; |
1494 | struct ServiceListeningInfo *sli; | 1499 | struct ServiceListeningInfo *sli; |
1495 | 1500 | ||
1496 | (void)cls; | 1501 | (void) cls; |
1497 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "First shutdown phase\n"); | 1502 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "First shutdown phase\n"); |
1498 | if (NULL != child_restart_task) | 1503 | if (NULL != child_restart_task) |
1499 | { | 1504 | { |
1500 | GNUNET_SCHEDULER_cancel(child_restart_task); | 1505 | GNUNET_SCHEDULER_cancel (child_restart_task); |
1501 | child_restart_task = NULL; | 1506 | child_restart_task = NULL; |
1502 | } | 1507 | } |
1503 | in_shutdown = GNUNET_YES; | 1508 | in_shutdown = GNUNET_YES; |
1504 | /* first, stop listening */ | 1509 | /* first, stop listening */ |
1505 | for (pos = running_head; NULL != pos; pos = pos->next) | 1510 | for (pos = running_head; NULL != pos; pos = pos->next) |
1511 | { | ||
1512 | while (NULL != (sli = pos->listen_head)) | ||
1506 | { | 1513 | { |
1507 | while (NULL != (sli = pos->listen_head)) | 1514 | GNUNET_CONTAINER_DLL_remove (pos->listen_head, pos->listen_tail, sli); |
1508 | { | 1515 | if (NULL != sli->accept_task) |
1509 | GNUNET_CONTAINER_DLL_remove(pos->listen_head, pos->listen_tail, sli); | 1516 | { |
1510 | if (NULL != sli->accept_task) | 1517 | GNUNET_SCHEDULER_cancel (sli->accept_task); |
1511 | { | 1518 | sli->accept_task = NULL; |
1512 | GNUNET_SCHEDULER_cancel(sli->accept_task); | 1519 | } |
1513 | sli->accept_task = NULL; | 1520 | GNUNET_break (GNUNET_OK == |
1514 | } | 1521 | GNUNET_NETWORK_socket_close (sli->listen_socket)); |
1515 | GNUNET_break(GNUNET_OK == | 1522 | GNUNET_free (sli->service_addr); |
1516 | GNUNET_NETWORK_socket_close(sli->listen_socket)); | 1523 | GNUNET_free (sli); |
1517 | GNUNET_free(sli->service_addr); | ||
1518 | GNUNET_free(sli); | ||
1519 | } | ||
1520 | } | 1524 | } |
1525 | } | ||
1521 | /* then, shutdown all existing service processes */ | 1526 | /* then, shutdown all existing service processes */ |
1522 | nxt = running_head; | 1527 | nxt = running_head; |
1523 | while (NULL != (pos = nxt)) | 1528 | while (NULL != (pos = nxt)) |
1529 | { | ||
1530 | nxt = pos->next; | ||
1531 | if (NULL != pos->proc) | ||
1524 | { | 1532 | { |
1525 | nxt = pos->next; | 1533 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping service `%s'\n", pos->name); |
1526 | if (NULL != pos->proc) | 1534 | pos->killed_at = GNUNET_TIME_absolute_get (); |
1527 | { | 1535 | if (0 != GNUNET_OS_process_kill (pos->proc, GNUNET_TERM_SIG)) |
1528 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Stopping service `%s'\n", pos->name); | 1536 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); |
1529 | pos->killed_at = GNUNET_TIME_absolute_get(); | 1537 | } |
1530 | if (0 != GNUNET_OS_process_kill(pos->proc, GNUNET_TERM_SIG)) | 1538 | else |
1531 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "kill"); | 1539 | { |
1532 | } | 1540 | free_service (pos); |
1533 | else | ||
1534 | { | ||
1535 | free_service(pos); | ||
1536 | } | ||
1537 | } | 1541 | } |
1542 | } | ||
1538 | /* finally, should all service processes be already gone, terminate for real */ | 1543 | /* finally, should all service processes be already gone, terminate for real */ |
1539 | if (NULL == running_head) | 1544 | if (NULL == running_head) |
1540 | do_shutdown(); | 1545 | do_shutdown (); |
1541 | else | 1546 | else |
1542 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 1547 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1543 | "Delaying shutdown, have %u childs still running\n", | 1548 | "Delaying shutdown, have %u childs still running\n", |
1544 | list_count(running_head)); | 1549 | list_count (running_head)); |
1545 | } | 1550 | } |
1546 | 1551 | ||
1547 | 1552 | ||
@@ -1551,73 +1556,73 @@ shutdown_task(void *cls) | |||
1551 | * @param cls closure, always NULL | 1556 | * @param cls closure, always NULL |
1552 | */ | 1557 | */ |
1553 | static void | 1558 | static void |
1554 | delayed_restart_task(void *cls) | 1559 | delayed_restart_task (void *cls) |
1555 | 1560 | ||
1556 | { | 1561 | { |
1557 | struct ServiceList *sl; | 1562 | struct ServiceList *sl; |
1558 | struct GNUNET_TIME_Relative lowestRestartDelay; | 1563 | struct GNUNET_TIME_Relative lowestRestartDelay; |
1559 | struct ServiceListeningInfo *sli; | 1564 | struct ServiceListeningInfo *sli; |
1560 | 1565 | ||
1561 | (void)cls; | 1566 | (void) cls; |
1562 | child_restart_task = NULL; | 1567 | child_restart_task = NULL; |
1563 | GNUNET_assert(GNUNET_NO == in_shutdown); | 1568 | GNUNET_assert (GNUNET_NO == in_shutdown); |
1564 | lowestRestartDelay = GNUNET_TIME_UNIT_FOREVER_REL; | 1569 | lowestRestartDelay = GNUNET_TIME_UNIT_FOREVER_REL; |
1565 | 1570 | ||
1566 | /* check for services that need to be restarted due to | 1571 | /* check for services that need to be restarted due to |
1567 | * configuration changes or because the last restart failed */ | 1572 | * configuration changes or because the last restart failed */ |
1568 | for (sl = running_head; NULL != sl; sl = sl->next) | 1573 | for (sl = running_head; NULL != sl; sl = sl->next) |
1574 | { | ||
1575 | if (NULL != sl->proc) | ||
1576 | continue; | ||
1577 | /* service is currently not running */ | ||
1578 | if (0 == GNUNET_TIME_absolute_get_remaining (sl->restart_at).rel_value_us) | ||
1569 | { | 1579 | { |
1570 | if (NULL != sl->proc) | 1580 | /* restart is now allowed */ |
1571 | continue; | 1581 | if (sl->force_start) |
1572 | /* service is currently not running */ | 1582 | { |
1573 | if (0 == GNUNET_TIME_absolute_get_remaining(sl->restart_at).rel_value_us) | 1583 | /* process should run by default, start immediately */ |
1574 | { | 1584 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1575 | /* restart is now allowed */ | 1585 | _ ("Restarting service `%s'.\n"), |
1576 | if (sl->force_start) | 1586 | sl->name); |
1577 | { | 1587 | start_process (sl, NULL, 0); |
1578 | /* process should run by default, start immediately */ | 1588 | } |
1579 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
1580 | _("Restarting service `%s'.\n"), | ||
1581 | sl->name); | ||
1582 | start_process(sl, NULL, 0); | ||
1583 | } | ||
1584 | else | ||
1585 | { | ||
1586 | /* process is run on-demand, ensure it is re-started if there is demand */ | ||
1587 | for (sli = sl->listen_head; NULL != sli; sli = sli->next) | ||
1588 | if (NULL == sli->accept_task) | ||
1589 | { | ||
1590 | /* accept was actually paused, so start it again */ | ||
1591 | sli->accept_task = | ||
1592 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | ||
1593 | sli->listen_socket, | ||
1594 | &accept_connection, | ||
1595 | sli); | ||
1596 | } | ||
1597 | } | ||
1598 | } | ||
1599 | else | 1589 | else |
1600 | { | 1590 | { |
1601 | /* update calculation for earliest time to reactivate a service */ | 1591 | /* process is run on-demand, ensure it is re-started if there is demand */ |
1602 | lowestRestartDelay = | 1592 | for (sli = sl->listen_head; NULL != sli; sli = sli->next) |
1603 | GNUNET_TIME_relative_min(lowestRestartDelay, | 1593 | if (NULL == sli->accept_task) |
1604 | GNUNET_TIME_absolute_get_remaining( | 1594 | { |
1605 | sl->restart_at)); | 1595 | /* accept was actually paused, so start it again */ |
1606 | } | 1596 | sli->accept_task = |
1597 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
1598 | sli->listen_socket, | ||
1599 | &accept_connection, | ||
1600 | sli); | ||
1601 | } | ||
1602 | } | ||
1607 | } | 1603 | } |
1604 | else | ||
1605 | { | ||
1606 | /* update calculation for earliest time to reactivate a service */ | ||
1607 | lowestRestartDelay = | ||
1608 | GNUNET_TIME_relative_min (lowestRestartDelay, | ||
1609 | GNUNET_TIME_absolute_get_remaining ( | ||
1610 | sl->restart_at)); | ||
1611 | } | ||
1612 | } | ||
1608 | if (lowestRestartDelay.rel_value_us != | 1613 | if (lowestRestartDelay.rel_value_us != |
1609 | GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) | 1614 | GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) |
1610 | { | 1615 | { |
1611 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 1616 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1612 | "Will restart process in %s\n", | 1617 | "Will restart process in %s\n", |
1613 | GNUNET_STRINGS_relative_time_to_string(lowestRestartDelay, | 1618 | GNUNET_STRINGS_relative_time_to_string (lowestRestartDelay, |
1614 | GNUNET_YES)); | 1619 | GNUNET_YES)); |
1615 | child_restart_task = | 1620 | child_restart_task = |
1616 | GNUNET_SCHEDULER_add_delayed_with_priority(lowestRestartDelay, | 1621 | GNUNET_SCHEDULER_add_delayed_with_priority (lowestRestartDelay, |
1617 | GNUNET_SCHEDULER_PRIORITY_IDLE, | 1622 | GNUNET_SCHEDULER_PRIORITY_IDLE, |
1618 | &delayed_restart_task, | 1623 | &delayed_restart_task, |
1619 | NULL); | 1624 | NULL); |
1620 | } | 1625 | } |
1621 | } | 1626 | } |
1622 | 1627 | ||
1623 | 1628 | ||
@@ -1628,7 +1633,7 @@ delayed_restart_task(void *cls) | |||
1628 | * @param cls closure, NULL | 1633 | * @param cls closure, NULL |
1629 | */ | 1634 | */ |
1630 | static void | 1635 | static void |
1631 | maint_child_death(void *cls) | 1636 | maint_child_death (void *cls) |
1632 | { | 1637 | { |
1633 | struct ServiceList *pos; | 1638 | struct ServiceList *pos; |
1634 | struct ServiceList *next; | 1639 | struct ServiceList *next; |
@@ -1641,200 +1646,200 @@ maint_child_death(void *cls) | |||
1641 | unsigned long statusCode; | 1646 | unsigned long statusCode; |
1642 | const struct GNUNET_DISK_FileHandle *pr; | 1647 | const struct GNUNET_DISK_FileHandle *pr; |
1643 | 1648 | ||
1644 | (void)cls; | 1649 | (void) cls; |
1645 | pr = GNUNET_DISK_pipe_handle(sigpipe, GNUNET_DISK_PIPE_END_READ); | 1650 | pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ); |
1646 | child_death_task = NULL; | 1651 | child_death_task = NULL; |
1647 | /* consume the signal */ | 1652 | /* consume the signal */ |
1648 | GNUNET_break(0 < GNUNET_DISK_file_read(pr, &c, sizeof(c))); | 1653 | GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof(c))); |
1649 | 1654 | ||
1650 | /* check for services that died (WAITPID) */ | 1655 | /* check for services that died (WAITPID) */ |
1651 | next = running_head; | 1656 | next = running_head; |
1652 | while (NULL != (pos = next)) | 1657 | while (NULL != (pos = next)) |
1653 | { | 1658 | { |
1654 | next = pos->next; | 1659 | next = pos->next; |
1655 | 1660 | ||
1656 | if (NULL == pos->proc) | 1661 | if (NULL == pos->proc) |
1657 | { | 1662 | { |
1658 | if (GNUNET_YES == in_shutdown) | 1663 | if (GNUNET_YES == in_shutdown) |
1659 | free_service(pos); | 1664 | free_service (pos); |
1660 | continue; | 1665 | continue; |
1661 | } | 1666 | } |
1662 | #if HAVE_WAIT4 | 1667 | #if HAVE_WAIT4 |
1663 | if (NULL != wait_file) | 1668 | if (NULL != wait_file) |
1664 | { | 1669 | { |
1665 | /* need to use 'wait4()' to obtain and log performance data */ | 1670 | /* need to use 'wait4()' to obtain and log performance data */ |
1666 | struct rusage ru; | 1671 | struct rusage ru; |
1667 | int status; | 1672 | int status; |
1668 | pid_t pid; | 1673 | pid_t pid; |
1669 | 1674 | ||
1670 | pid = GNUNET_OS_process_get_pid(pos->proc); | 1675 | pid = GNUNET_OS_process_get_pid (pos->proc); |
1671 | ret = wait4(pid, &status, WNOHANG, &ru); | 1676 | ret = wait4 (pid, &status, WNOHANG, &ru); |
1672 | if (ret <= 0) | 1677 | if (ret <= 0) |
1673 | continue; /* no process done */ | 1678 | continue; /* no process done */ |
1674 | if (WIFEXITED(status)) | 1679 | if (WIFEXITED (status)) |
1675 | { | 1680 | { |
1676 | statusType = GNUNET_OS_PROCESS_EXITED; | 1681 | statusType = GNUNET_OS_PROCESS_EXITED; |
1677 | statusCode = WEXITSTATUS(status); | 1682 | statusCode = WEXITSTATUS (status); |
1678 | } | 1683 | } |
1679 | else if (WIFSIGNALED(status)) | 1684 | else if (WIFSIGNALED (status)) |
1680 | { | 1685 | { |
1681 | statusType = GNUNET_OS_PROCESS_SIGNALED; | 1686 | statusType = GNUNET_OS_PROCESS_SIGNALED; |
1682 | statusCode = WTERMSIG(status); | 1687 | statusCode = WTERMSIG (status); |
1683 | } | 1688 | } |
1684 | else if (WIFSTOPPED(status)) | 1689 | else if (WIFSTOPPED (status)) |
1685 | { | 1690 | { |
1686 | statusType = GNUNET_OS_PROCESS_SIGNALED; | 1691 | statusType = GNUNET_OS_PROCESS_SIGNALED; |
1687 | statusCode = WSTOPSIG(status); | 1692 | statusCode = WSTOPSIG (status); |
1688 | } | 1693 | } |
1689 | #ifdef WIFCONTINUED | 1694 | #ifdef WIFCONTINUED |
1690 | else if (WIFCONTINUED(status)) | 1695 | else if (WIFCONTINUED (status)) |
1691 | { | 1696 | { |
1692 | statusType = GNUNET_OS_PROCESS_RUNNING; | 1697 | statusType = GNUNET_OS_PROCESS_RUNNING; |
1693 | statusCode = 0; | 1698 | statusCode = 0; |
1694 | } | 1699 | } |
1695 | #endif | ||
1696 | else | ||
1697 | { | ||
1698 | statusType = GNUNET_OS_PROCESS_UNKNOWN; | ||
1699 | statusCode = 0; | ||
1700 | } | ||
1701 | if ((GNUNET_OS_PROCESS_EXITED == statusType) || | ||
1702 | (GNUNET_OS_PROCESS_SIGNALED == statusType)) | ||
1703 | { | ||
1704 | double utime = ru.ru_utime.tv_sec + (ru.ru_utime.tv_usec / 10e6); | ||
1705 | double stime = ru.ru_stime.tv_sec + (ru.ru_stime.tv_usec / 10e6); | ||
1706 | fprintf(wait_file, | ||
1707 | "%s(%u) %.3f %.3f %llu %llu %llu %llu %llu\n", | ||
1708 | pos->binary, | ||
1709 | (unsigned int)pid, | ||
1710 | utime, | ||
1711 | stime, | ||
1712 | (unsigned long long)ru.ru_maxrss, | ||
1713 | (unsigned long long)ru.ru_inblock, | ||
1714 | (unsigned long long)ru.ru_oublock, | ||
1715 | (unsigned long long)ru.ru_nvcsw, | ||
1716 | (unsigned long long)ru.ru_nivcsw); | ||
1717 | } | ||
1718 | } | ||
1719 | else /* continue with JUST this "if" as "else" (intentionally no brackets!) */ | ||
1720 | #endif | 1700 | #endif |
1721 | if ((GNUNET_SYSERR == (ret = GNUNET_OS_process_status(pos->proc, | ||
1722 | &statusType, | ||
1723 | &statusCode))) || | ||
1724 | (ret == GNUNET_NO) || (statusType == GNUNET_OS_PROCESS_STOPPED) || | ||
1725 | (statusType == GNUNET_OS_PROCESS_UNKNOWN) || | ||
1726 | (statusType == GNUNET_OS_PROCESS_RUNNING)) | ||
1727 | continue; | ||
1728 | |||
1729 | if (statusType == GNUNET_OS_PROCESS_EXITED) | ||
1730 | { | ||
1731 | statstr = _(/* process termination method */ "exit"); | ||
1732 | statcode = statusCode; | ||
1733 | } | ||
1734 | else if (statusType == GNUNET_OS_PROCESS_SIGNALED) | ||
1735 | { | ||
1736 | statstr = _(/* process termination method */ "signal"); | ||
1737 | statcode = statusCode; | ||
1738 | } | ||
1739 | else | 1701 | else |
1740 | { | 1702 | { |
1741 | statstr = _(/* process termination method */ "unknown"); | 1703 | statusType = GNUNET_OS_PROCESS_UNKNOWN; |
1742 | statcode = 0; | 1704 | statusCode = 0; |
1743 | } | 1705 | } |
1744 | if (0 != pos->killed_at.abs_value_us) | 1706 | if ((GNUNET_OS_PROCESS_EXITED == statusType) || |
1745 | { | 1707 | (GNUNET_OS_PROCESS_SIGNALED == statusType)) |
1746 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 1708 | { |
1747 | _("Service `%s' took %s to terminate\n"), | 1709 | double utime = ru.ru_utime.tv_sec + (ru.ru_utime.tv_usec / 10e6); |
1710 | double stime = ru.ru_stime.tv_sec + (ru.ru_stime.tv_usec / 10e6); | ||
1711 | fprintf (wait_file, | ||
1712 | "%s(%u) %.3f %.3f %llu %llu %llu %llu %llu\n", | ||
1713 | pos->binary, | ||
1714 | (unsigned int) pid, | ||
1715 | utime, | ||
1716 | stime, | ||
1717 | (unsigned long long) ru.ru_maxrss, | ||
1718 | (unsigned long long) ru.ru_inblock, | ||
1719 | (unsigned long long) ru.ru_oublock, | ||
1720 | (unsigned long long) ru.ru_nvcsw, | ||
1721 | (unsigned long long) ru.ru_nivcsw); | ||
1722 | } | ||
1723 | } | ||
1724 | else /* continue with JUST this "if" as "else" (intentionally no brackets!) */ | ||
1725 | #endif | ||
1726 | if ((GNUNET_SYSERR == (ret = GNUNET_OS_process_status (pos->proc, | ||
1727 | &statusType, | ||
1728 | &statusCode))) || | ||
1729 | (ret == GNUNET_NO) || (statusType == GNUNET_OS_PROCESS_STOPPED) || | ||
1730 | (statusType == GNUNET_OS_PROCESS_UNKNOWN) || | ||
1731 | (statusType == GNUNET_OS_PROCESS_RUNNING)) | ||
1732 | continue; | ||
1733 | |||
1734 | if (statusType == GNUNET_OS_PROCESS_EXITED) | ||
1735 | { | ||
1736 | statstr = _ (/* process termination method */ "exit"); | ||
1737 | statcode = statusCode; | ||
1738 | } | ||
1739 | else if (statusType == GNUNET_OS_PROCESS_SIGNALED) | ||
1740 | { | ||
1741 | statstr = _ (/* process termination method */ "signal"); | ||
1742 | statcode = statusCode; | ||
1743 | } | ||
1744 | else | ||
1745 | { | ||
1746 | statstr = _ (/* process termination method */ "unknown"); | ||
1747 | statcode = 0; | ||
1748 | } | ||
1749 | if (0 != pos->killed_at.abs_value_us) | ||
1750 | { | ||
1751 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1752 | _ ("Service `%s' took %s to terminate\n"), | ||
1753 | pos->name, | ||
1754 | GNUNET_STRINGS_relative_time_to_string ( | ||
1755 | GNUNET_TIME_absolute_get_duration (pos->killed_at), | ||
1756 | GNUNET_YES)); | ||
1757 | } | ||
1758 | GNUNET_OS_process_destroy (pos->proc); | ||
1759 | pos->proc = NULL; | ||
1760 | broadcast_status (pos->name, GNUNET_ARM_SERVICE_STOPPED, NULL); | ||
1761 | if (NULL != pos->killing_client) | ||
1762 | { | ||
1763 | signal_result (pos->killing_client, | ||
1748 | pos->name, | 1764 | pos->name, |
1749 | GNUNET_STRINGS_relative_time_to_string( | 1765 | pos->killing_client_request_id, |
1750 | GNUNET_TIME_absolute_get_duration(pos->killed_at), | 1766 | GNUNET_ARM_RESULT_STOPPED); |
1751 | GNUNET_YES)); | 1767 | pos->killing_client = NULL; |
1752 | } | 1768 | pos->killing_client_request_id = 0; |
1753 | GNUNET_OS_process_destroy(pos->proc); | 1769 | } |
1754 | pos->proc = NULL; | 1770 | if (GNUNET_YES != in_shutdown) |
1755 | broadcast_status(pos->name, GNUNET_ARM_SERVICE_STOPPED, NULL); | 1771 | { |
1756 | if (NULL != pos->killing_client) | 1772 | pos->last_exit_status = statcode; |
1757 | { | 1773 | if ((statusType == GNUNET_OS_PROCESS_EXITED) && (statcode == 0)) |
1758 | signal_result(pos->killing_client, | 1774 | { |
1759 | pos->name, | 1775 | /* process terminated normally, allow restart at any time */ |
1760 | pos->killing_client_request_id, | 1776 | pos->restart_at.abs_value_us = 0; |
1761 | GNUNET_ARM_RESULT_STOPPED); | 1777 | GNUNET_log ( |
1762 | pos->killing_client = NULL; | 1778 | GNUNET_ERROR_TYPE_INFO, |
1763 | pos->killing_client_request_id = 0; | 1779 | _ ("Service `%s' terminated normally, will restart at any time\n"), |
1764 | } | 1780 | pos->name); |
1765 | if (GNUNET_YES != in_shutdown) | 1781 | /* process can still be re-started on-demand, ensure it is re-started if there is demand */ |
1782 | for (sli = pos->listen_head; NULL != sli; sli = sli->next) | ||
1766 | { | 1783 | { |
1767 | pos->last_exit_status = statcode; | 1784 | GNUNET_break (NULL == sli->accept_task); |
1768 | if ((statusType == GNUNET_OS_PROCESS_EXITED) && (statcode == 0)) | 1785 | sli->accept_task = |
1769 | { | 1786 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
1770 | /* process terminated normally, allow restart at any time */ | 1787 | sli->listen_socket, |
1771 | pos->restart_at.abs_value_us = 0; | 1788 | &accept_connection, |
1772 | GNUNET_log( | 1789 | sli); |
1773 | GNUNET_ERROR_TYPE_INFO, | ||
1774 | _("Service `%s' terminated normally, will restart at any time\n"), | ||
1775 | pos->name); | ||
1776 | /* process can still be re-started on-demand, ensure it is re-started if there is demand */ | ||
1777 | for (sli = pos->listen_head; NULL != sli; sli = sli->next) | ||
1778 | { | ||
1779 | GNUNET_break(NULL == sli->accept_task); | ||
1780 | sli->accept_task = | ||
1781 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | ||
1782 | sli->listen_socket, | ||
1783 | &accept_connection, | ||
1784 | sli); | ||
1785 | } | ||
1786 | } | ||
1787 | else | ||
1788 | { | ||
1789 | GNUNET_log( | ||
1790 | GNUNET_ERROR_TYPE_WARNING, | ||
1791 | _("Service `%s' terminated with status %s/%d, will restart in %s\n"), | ||
1792 | pos->name, | ||
1793 | statstr, | ||
1794 | statcode, | ||
1795 | GNUNET_STRINGS_relative_time_to_string(pos->backoff, GNUNET_YES)); | ||
1796 | { | ||
1797 | /* Reduce backoff based on runtime of the process, | ||
1798 | so that there is a cool-down if a process actually | ||
1799 | runs for a while. */ | ||
1800 | struct GNUNET_TIME_Relative runtime; | ||
1801 | unsigned int minutes; | ||
1802 | |||
1803 | runtime = GNUNET_TIME_absolute_get_duration(pos->restart_at); | ||
1804 | minutes = | ||
1805 | runtime.rel_value_us / GNUNET_TIME_UNIT_MINUTES.rel_value_us; | ||
1806 | if (minutes > 31) | ||
1807 | pos->backoff = GNUNET_TIME_UNIT_ZERO; | ||
1808 | else | ||
1809 | pos->backoff.rel_value_us <<= minutes; | ||
1810 | } | ||
1811 | /* schedule restart */ | ||
1812 | pos->restart_at = GNUNET_TIME_relative_to_absolute(pos->backoff); | ||
1813 | pos->backoff = GNUNET_TIME_STD_BACKOFF(pos->backoff); | ||
1814 | if (NULL != child_restart_task) | ||
1815 | GNUNET_SCHEDULER_cancel(child_restart_task); | ||
1816 | child_restart_task = | ||
1817 | GNUNET_SCHEDULER_add_with_priority(GNUNET_SCHEDULER_PRIORITY_IDLE, | ||
1818 | &delayed_restart_task, | ||
1819 | NULL); | ||
1820 | } | ||
1821 | } | 1790 | } |
1791 | } | ||
1822 | else | 1792 | else |
1793 | { | ||
1794 | GNUNET_log ( | ||
1795 | GNUNET_ERROR_TYPE_WARNING, | ||
1796 | _ ("Service `%s' terminated with status %s/%d, will restart in %s\n"), | ||
1797 | pos->name, | ||
1798 | statstr, | ||
1799 | statcode, | ||
1800 | GNUNET_STRINGS_relative_time_to_string (pos->backoff, GNUNET_YES)); | ||
1823 | { | 1801 | { |
1824 | free_service(pos); | 1802 | /* Reduce backoff based on runtime of the process, |
1803 | so that there is a cool-down if a process actually | ||
1804 | runs for a while. */ | ||
1805 | struct GNUNET_TIME_Relative runtime; | ||
1806 | unsigned int minutes; | ||
1807 | |||
1808 | runtime = GNUNET_TIME_absolute_get_duration (pos->restart_at); | ||
1809 | minutes = | ||
1810 | runtime.rel_value_us / GNUNET_TIME_UNIT_MINUTES.rel_value_us; | ||
1811 | if (minutes > 31) | ||
1812 | pos->backoff = GNUNET_TIME_UNIT_ZERO; | ||
1813 | else | ||
1814 | pos->backoff.rel_value_us <<= minutes; | ||
1825 | } | 1815 | } |
1816 | /* schedule restart */ | ||
1817 | pos->restart_at = GNUNET_TIME_relative_to_absolute (pos->backoff); | ||
1818 | pos->backoff = GNUNET_TIME_STD_BACKOFF (pos->backoff); | ||
1819 | if (NULL != child_restart_task) | ||
1820 | GNUNET_SCHEDULER_cancel (child_restart_task); | ||
1821 | child_restart_task = | ||
1822 | GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, | ||
1823 | &delayed_restart_task, | ||
1824 | NULL); | ||
1825 | } | ||
1826 | } | ||
1827 | else | ||
1828 | { | ||
1829 | free_service (pos); | ||
1826 | } | 1830 | } |
1831 | } | ||
1827 | child_death_task = | 1832 | child_death_task = |
1828 | GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL, | 1833 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, |
1829 | pr, | 1834 | pr, |
1830 | &maint_child_death, | 1835 | &maint_child_death, |
1831 | NULL); | 1836 | NULL); |
1832 | if ((NULL == running_head) && (GNUNET_YES == in_shutdown)) | 1837 | if ((NULL == running_head) && (GNUNET_YES == in_shutdown)) |
1833 | do_shutdown(); | 1838 | do_shutdown (); |
1834 | else if (GNUNET_YES == in_shutdown) | 1839 | else if (GNUNET_YES == in_shutdown) |
1835 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 1840 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1836 | "Delaying shutdown after child's death, still have %u children\n", | 1841 | "Delaying shutdown after child's death, still have %u children\n", |
1837 | list_count(running_head)); | 1842 | list_count (running_head)); |
1838 | } | 1843 | } |
1839 | 1844 | ||
1840 | 1845 | ||
@@ -1843,17 +1848,17 @@ maint_child_death(void *cls) | |||
1843 | * respective handler by writing to the trigger pipe. | 1848 | * respective handler by writing to the trigger pipe. |
1844 | */ | 1849 | */ |
1845 | static void | 1850 | static void |
1846 | sighandler_child_death() | 1851 | sighandler_child_death () |
1847 | { | 1852 | { |
1848 | static char c; | 1853 | static char c; |
1849 | int old_errno = errno; /* back-up errno */ | 1854 | int old_errno = errno; /* back-up errno */ |
1850 | 1855 | ||
1851 | GNUNET_break( | 1856 | GNUNET_break ( |
1852 | 1 == | 1857 | 1 == |
1853 | GNUNET_DISK_file_write(GNUNET_DISK_pipe_handle(sigpipe, | 1858 | GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (sigpipe, |
1854 | GNUNET_DISK_PIPE_END_WRITE), | 1859 | GNUNET_DISK_PIPE_END_WRITE), |
1855 | &c, | 1860 | &c, |
1856 | sizeof(c))); | 1861 | sizeof(c))); |
1857 | errno = old_errno; /* restore errno */ | 1862 | errno = old_errno; /* restore errno */ |
1858 | } | 1863 | } |
1859 | 1864 | ||
@@ -1867,7 +1872,7 @@ sighandler_child_death() | |||
1867 | * @return #GNUNET_OK (continue) | 1872 | * @return #GNUNET_OK (continue) |
1868 | */ | 1873 | */ |
1869 | static void | 1874 | static void |
1870 | setup_service(void *cls, const char *section) | 1875 | setup_service (void *cls, const char *section) |
1871 | { | 1876 | { |
1872 | struct ServiceList *sl; | 1877 | struct ServiceList *sl; |
1873 | char *binary; | 1878 | char *binary; |
@@ -1877,94 +1882,94 @@ setup_service(void *cls, const char *section) | |||
1877 | socklen_t *addr_lens; | 1882 | socklen_t *addr_lens; |
1878 | int ret; | 1883 | int ret; |
1879 | 1884 | ||
1880 | (void)cls; | 1885 | (void) cls; |
1881 | if (0 == strcasecmp(section, "arm")) | 1886 | if (0 == strcasecmp (section, "arm")) |
1882 | return; | 1887 | return; |
1883 | if (GNUNET_OK != | 1888 | if (GNUNET_OK != |
1884 | GNUNET_CONFIGURATION_get_value_string(cfg, section, "BINARY", &binary)) | 1889 | GNUNET_CONFIGURATION_get_value_string (cfg, section, "BINARY", &binary)) |
1885 | { | 1890 | { |
1886 | /* not a service section */ | 1891 | /* not a service section */ |
1887 | return; | 1892 | return; |
1888 | } | 1893 | } |
1889 | if ((GNUNET_YES == | 1894 | if ((GNUNET_YES == |
1890 | GNUNET_CONFIGURATION_have_value(cfg, section, "RUN_PER_USER")) && | 1895 | GNUNET_CONFIGURATION_have_value (cfg, section, "RUN_PER_USER")) && |
1891 | (GNUNET_YES == | 1896 | (GNUNET_YES == |
1892 | GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "RUN_PER_USER"))) | 1897 | GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "RUN_PER_USER"))) |
1898 | { | ||
1899 | if (GNUNET_NO == start_user) | ||
1893 | { | 1900 | { |
1894 | if (GNUNET_NO == start_user) | 1901 | GNUNET_free (binary); |
1895 | { | 1902 | return; /* user service, and we don't deal with those */ |
1896 | GNUNET_free(binary); | ||
1897 | return; /* user service, and we don't deal with those */ | ||
1898 | } | ||
1899 | } | 1903 | } |
1904 | } | ||
1900 | else | 1905 | else |
1906 | { | ||
1907 | if (GNUNET_NO == start_system) | ||
1901 | { | 1908 | { |
1902 | if (GNUNET_NO == start_system) | 1909 | GNUNET_free (binary); |
1903 | { | 1910 | return; /* system service, and we don't deal with those */ |
1904 | GNUNET_free(binary); | ||
1905 | return; /* system service, and we don't deal with those */ | ||
1906 | } | ||
1907 | } | 1911 | } |
1908 | sl = find_service(section); | 1912 | } |
1913 | sl = find_service (section); | ||
1909 | if (NULL != sl) | 1914 | if (NULL != sl) |
1910 | { | 1915 | { |
1911 | /* got the same section twice!? */ | 1916 | /* got the same section twice!? */ |
1912 | GNUNET_break(0); | 1917 | GNUNET_break (0); |
1913 | GNUNET_free(binary); | 1918 | GNUNET_free (binary); |
1914 | return; | 1919 | return; |
1915 | } | 1920 | } |
1916 | config = NULL; | 1921 | config = NULL; |
1917 | if (((GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(cfg, | 1922 | if (((GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, |
1918 | section, | 1923 | section, |
1919 | "CONFIG", | 1924 | "CONFIG", |
1920 | &config)) && | 1925 | &config)) && |
1921 | (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(cfg, | 1926 | (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, |
1922 | "PATHS", | 1927 | "PATHS", |
1923 | "DEFAULTCONFIG", | 1928 | "DEFAULTCONFIG", |
1924 | &config))) || | 1929 | &config))) || |
1925 | (0 != stat(config, &sbuf))) | 1930 | (0 != stat (config, &sbuf))) |
1931 | { | ||
1932 | if (NULL != config) | ||
1926 | { | 1933 | { |
1927 | if (NULL != config) | 1934 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, |
1928 | { | 1935 | section, |
1929 | GNUNET_log_config_invalid(GNUNET_ERROR_TYPE_WARNING, | 1936 | "CONFIG", |
1930 | section, | 1937 | strerror (errno)); |
1931 | "CONFIG", | 1938 | GNUNET_free (config); |
1932 | strerror(errno)); | 1939 | config = NULL; |
1933 | GNUNET_free(config); | ||
1934 | config = NULL; | ||
1935 | } | ||
1936 | } | 1940 | } |
1937 | sl = GNUNET_new(struct ServiceList); | 1941 | } |
1938 | sl->name = GNUNET_strdup(section); | 1942 | sl = GNUNET_new (struct ServiceList); |
1943 | sl->name = GNUNET_strdup (section); | ||
1939 | sl->binary = binary; | 1944 | sl->binary = binary; |
1940 | sl->config = config; | 1945 | sl->config = config; |
1941 | sl->backoff = GNUNET_TIME_UNIT_MILLISECONDS; | 1946 | sl->backoff = GNUNET_TIME_UNIT_MILLISECONDS; |
1942 | sl->restart_at = GNUNET_TIME_UNIT_FOREVER_ABS; | 1947 | sl->restart_at = GNUNET_TIME_UNIT_FOREVER_ABS; |
1943 | if (GNUNET_CONFIGURATION_have_value(cfg, section, "PIPECONTROL")) | 1948 | if (GNUNET_CONFIGURATION_have_value (cfg, section, "PIPECONTROL")) |
1944 | sl->pipe_control = | 1949 | sl->pipe_control = |
1945 | GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "PIPECONTROL"); | 1950 | GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "PIPECONTROL"); |
1946 | GNUNET_CONTAINER_DLL_insert(running_head, running_tail, sl); | 1951 | GNUNET_CONTAINER_DLL_insert (running_head, running_tail, sl); |
1947 | if (GNUNET_YES == | 1952 | if (GNUNET_YES == |
1948 | GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "IMMEDIATE_START")) | 1953 | GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "IMMEDIATE_START")) |
1949 | { | 1954 | { |
1950 | sl->force_start = GNUNET_YES; | 1955 | sl->force_start = GNUNET_YES; |
1951 | if (GNUNET_YES == | 1956 | if (GNUNET_YES == |
1952 | GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "NOARMBIND")) | 1957 | GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "NOARMBIND")) |
1953 | return; | 1958 | return; |
1954 | } | 1959 | } |
1955 | else | 1960 | else |
1956 | { | 1961 | { |
1957 | if (GNUNET_YES != | 1962 | if (GNUNET_YES != |
1958 | GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "START_ON_DEMAND")) | 1963 | GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "START_ON_DEMAND")) |
1959 | return; | 1964 | return; |
1960 | } | 1965 | } |
1961 | if (0 >= (ret = get_server_addresses(section, cfg, &addrs, &addr_lens))) | 1966 | if (0 >= (ret = get_server_addresses (section, cfg, &addrs, &addr_lens))) |
1962 | return; | 1967 | return; |
1963 | /* this will free (or capture) addrs[i] */ | 1968 | /* this will free (or capture) addrs[i] */ |
1964 | for (unsigned int i = 0; i < (unsigned int)ret; i++) | 1969 | for (unsigned int i = 0; i < (unsigned int) ret; i++) |
1965 | create_listen_socket(addrs[i], addr_lens[i], sl); | 1970 | create_listen_socket (addrs[i], addr_lens[i], sl); |
1966 | GNUNET_free(addrs); | 1971 | GNUNET_free (addrs); |
1967 | GNUNET_free(addr_lens); | 1972 | GNUNET_free (addr_lens); |
1968 | } | 1973 | } |
1969 | 1974 | ||
1970 | 1975 | ||
@@ -1977,16 +1982,16 @@ setup_service(void *cls, const char *section) | |||
1977 | * @return @a client | 1982 | * @return @a client |
1978 | */ | 1983 | */ |
1979 | static void * | 1984 | static void * |
1980 | client_connect_cb(void *cls, | 1985 | client_connect_cb (void *cls, |
1981 | struct GNUNET_SERVICE_Client *client, | 1986 | struct GNUNET_SERVICE_Client *client, |
1982 | struct GNUNET_MQ_Handle *mq) | 1987 | struct GNUNET_MQ_Handle *mq) |
1983 | { | 1988 | { |
1984 | /* All clients are considered to be of the "monitor" kind | 1989 | /* All clients are considered to be of the "monitor" kind |
1985 | * (that is, they don't affect ARM shutdown). | 1990 | * (that is, they don't affect ARM shutdown). |
1986 | */ | 1991 | */ |
1987 | (void)cls; | 1992 | (void) cls; |
1988 | (void)mq; | 1993 | (void) mq; |
1989 | GNUNET_SERVICE_client_mark_monitor(client); | 1994 | GNUNET_SERVICE_client_mark_monitor (client); |
1990 | return client; | 1995 | return client; |
1991 | } | 1996 | } |
1992 | 1997 | ||
@@ -1999,12 +2004,12 @@ client_connect_cb(void *cls, | |||
1999 | * @param app_ctx must match @a client | 2004 | * @param app_ctx must match @a client |
2000 | */ | 2005 | */ |
2001 | static void | 2006 | static void |
2002 | client_disconnect_cb(void *cls, | 2007 | client_disconnect_cb (void *cls, |
2003 | struct GNUNET_SERVICE_Client *client, | 2008 | struct GNUNET_SERVICE_Client *client, |
2004 | void *app_ctx) | 2009 | void *app_ctx) |
2005 | { | 2010 | { |
2006 | (void)cls; | 2011 | (void) cls; |
2007 | GNUNET_assert(client == app_ctx); | 2012 | GNUNET_assert (client == app_ctx); |
2008 | for (struct ServiceList *sl = running_head; NULL != sl; sl = sl->next) | 2013 | for (struct ServiceList *sl = running_head; NULL != sl; sl = sl->next) |
2009 | if (sl->killing_client == client) | 2014 | if (sl->killing_client == client) |
2010 | sl->killing_client = NULL; | 2015 | sl->killing_client = NULL; |
@@ -2020,18 +2025,18 @@ client_disconnect_cb(void *cls, | |||
2020 | * #GNUNET_SYSERR to close it (signal serious error) | 2025 | * #GNUNET_SYSERR to close it (signal serious error) |
2021 | */ | 2026 | */ |
2022 | static void | 2027 | static void |
2023 | handle_monitor(void *cls, const struct GNUNET_MessageHeader *message) | 2028 | handle_monitor (void *cls, const struct GNUNET_MessageHeader *message) |
2024 | { | 2029 | { |
2025 | struct GNUNET_SERVICE_Client *client = cls; | 2030 | struct GNUNET_SERVICE_Client *client = cls; |
2026 | 2031 | ||
2027 | (void)message; | 2032 | (void) message; |
2028 | /* FIXME: might want to start by letting monitor know about | 2033 | /* FIXME: might want to start by letting monitor know about |
2029 | services that are already running */ | 2034 | services that are already running */ |
2030 | /* Removal is handled by the server implementation, internally. */ | 2035 | /* Removal is handled by the server implementation, internally. */ |
2031 | GNUNET_notification_context_add(notifier, | 2036 | GNUNET_notification_context_add (notifier, |
2032 | GNUNET_SERVICE_client_get_mq(client)); | 2037 | GNUNET_SERVICE_client_get_mq (client)); |
2033 | broadcast_status("arm", GNUNET_ARM_SERVICE_MONITORING_STARTED, client); | 2038 | broadcast_status ("arm", GNUNET_ARM_SERVICE_MONITORING_STARTED, client); |
2034 | GNUNET_SERVICE_client_continue(client); | 2039 | GNUNET_SERVICE_client_continue (client); |
2035 | } | 2040 | } |
2036 | 2041 | ||
2037 | 2042 | ||
@@ -2043,71 +2048,71 @@ handle_monitor(void *cls, const struct GNUNET_MessageHeader *message) | |||
2043 | * @param c configuration to use | 2048 | * @param c configuration to use |
2044 | */ | 2049 | */ |
2045 | static void | 2050 | static void |
2046 | run(void *cls, | 2051 | run (void *cls, |
2047 | const struct GNUNET_CONFIGURATION_Handle *c, | 2052 | const struct GNUNET_CONFIGURATION_Handle *c, |
2048 | struct GNUNET_SERVICE_Handle *serv) | 2053 | struct GNUNET_SERVICE_Handle *serv) |
2049 | { | 2054 | { |
2050 | struct ServiceList *sl; | 2055 | struct ServiceList *sl; |
2051 | 2056 | ||
2052 | (void)cls; | 2057 | (void) cls; |
2053 | cfg = c; | 2058 | cfg = c; |
2054 | service = serv; | 2059 | service = serv; |
2055 | GNUNET_SCHEDULER_add_shutdown(&shutdown_task, NULL); | 2060 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); |
2056 | child_death_task = GNUNET_SCHEDULER_add_read_file( | 2061 | child_death_task = GNUNET_SCHEDULER_add_read_file ( |
2057 | GNUNET_TIME_UNIT_FOREVER_REL, | 2062 | GNUNET_TIME_UNIT_FOREVER_REL, |
2058 | GNUNET_DISK_pipe_handle(sigpipe, GNUNET_DISK_PIPE_END_READ), | 2063 | GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ), |
2059 | &maint_child_death, | 2064 | &maint_child_death, |
2060 | NULL); | 2065 | NULL); |
2061 | #if HAVE_WAIT4 | 2066 | #if HAVE_WAIT4 |
2062 | if (GNUNET_OK == | 2067 | if (GNUNET_OK == |
2063 | GNUNET_CONFIGURATION_get_value_filename(cfg, | 2068 | GNUNET_CONFIGURATION_get_value_filename (cfg, |
2064 | "ARM", | 2069 | "ARM", |
2065 | "RESOURCE_DIAGNOSTICS", | 2070 | "RESOURCE_DIAGNOSTICS", |
2066 | &wait_filename)) | 2071 | &wait_filename)) |
2072 | { | ||
2073 | wait_file = fopen (wait_filename, "w"); | ||
2074 | if (NULL == wait_file) | ||
2067 | { | 2075 | { |
2068 | wait_file = fopen(wait_filename, "w"); | 2076 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, |
2069 | if (NULL == wait_file) | 2077 | "fopen", |
2070 | { | 2078 | wait_filename); |
2071 | GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR, | ||
2072 | "fopen", | ||
2073 | wait_filename); | ||
2074 | } | ||
2075 | } | 2079 | } |
2080 | } | ||
2076 | #endif | 2081 | #endif |
2077 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, | 2082 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, |
2078 | "ARM", | 2083 | "ARM", |
2079 | "GLOBAL_PREFIX", | 2084 | "GLOBAL_PREFIX", |
2080 | &prefix_command)) | 2085 | &prefix_command)) |
2081 | prefix_command = GNUNET_strdup(""); | 2086 | prefix_command = GNUNET_strdup (""); |
2082 | else | 2087 | else |
2083 | prefix_command = GNUNET_CONFIGURATION_expand_dollar(cfg, prefix_command); | 2088 | prefix_command = GNUNET_CONFIGURATION_expand_dollar (cfg, prefix_command); |
2084 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, | 2089 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, |
2085 | "ARM", | 2090 | "ARM", |
2086 | "GLOBAL_POSTFIX", | 2091 | "GLOBAL_POSTFIX", |
2087 | &final_option)) | 2092 | &final_option)) |
2088 | final_option = GNUNET_strdup(""); | 2093 | final_option = GNUNET_strdup (""); |
2089 | else | 2094 | else |
2090 | final_option = GNUNET_CONFIGURATION_expand_dollar(cfg, final_option); | 2095 | final_option = GNUNET_CONFIGURATION_expand_dollar (cfg, final_option); |
2091 | start_user = | 2096 | start_user = |
2092 | GNUNET_CONFIGURATION_get_value_yesno(cfg, "ARM", "START_USER_SERVICES"); | 2097 | GNUNET_CONFIGURATION_get_value_yesno (cfg, "ARM", "START_USER_SERVICES"); |
2093 | start_system = | 2098 | start_system = |
2094 | GNUNET_CONFIGURATION_get_value_yesno(cfg, "ARM", "START_SYSTEM_SERVICES"); | 2099 | GNUNET_CONFIGURATION_get_value_yesno (cfg, "ARM", "START_SYSTEM_SERVICES"); |
2095 | if ((GNUNET_NO == start_user) && (GNUNET_NO == start_system)) | 2100 | if ((GNUNET_NO == start_user) && (GNUNET_NO == start_system)) |
2096 | { | 2101 | { |
2097 | GNUNET_log( | 2102 | GNUNET_log ( |
2098 | GNUNET_ERROR_TYPE_ERROR, | 2103 | GNUNET_ERROR_TYPE_ERROR, |
2099 | "Please configure either START_USER_SERVICES or START_SYSTEM_SERVICES or both.\n"); | 2104 | "Please configure either START_USER_SERVICES or START_SYSTEM_SERVICES or both.\n"); |
2100 | GNUNET_SCHEDULER_shutdown(); | 2105 | GNUNET_SCHEDULER_shutdown (); |
2101 | global_ret = 1; | 2106 | global_ret = 1; |
2102 | return; | 2107 | return; |
2103 | } | 2108 | } |
2104 | GNUNET_CONFIGURATION_iterate_sections(cfg, &setup_service, NULL); | 2109 | GNUNET_CONFIGURATION_iterate_sections (cfg, &setup_service, NULL); |
2105 | 2110 | ||
2106 | /* start default services... */ | 2111 | /* start default services... */ |
2107 | for (sl = running_head; NULL != sl; sl = sl->next) | 2112 | for (sl = running_head; NULL != sl; sl = sl->next) |
2108 | if (GNUNET_YES == sl->force_start) | 2113 | if (GNUNET_YES == sl->force_start) |
2109 | start_process(sl, NULL, 0); | 2114 | start_process (sl, NULL, 0); |
2110 | notifier = GNUNET_notification_context_create(MAX_NOTIFY_QUEUE); | 2115 | notifier = GNUNET_notification_context_create (MAX_NOTIFY_QUEUE); |
2111 | } | 2116 | } |
2112 | 2117 | ||
2113 | 2118 | ||
@@ -2119,61 +2124,64 @@ run(void *cls, | |||
2119 | * @return 0 ok, 1 on error | 2124 | * @return 0 ok, 1 on error |
2120 | */ | 2125 | */ |
2121 | int | 2126 | int |
2122 | main(int argc, char *const *argv) | 2127 | main (int argc, char *const *argv) |
2123 | { | 2128 | { |
2124 | struct GNUNET_SIGNAL_Context *shc_chld; | 2129 | struct GNUNET_SIGNAL_Context *shc_chld; |
2125 | struct GNUNET_MQ_MessageHandler handlers[] = | 2130 | struct GNUNET_MQ_MessageHandler handlers[] = { |
2126 | { GNUNET_MQ_hd_var_size(start, | 2131 | GNUNET_MQ_hd_var_size (start, |
2127 | GNUNET_MESSAGE_TYPE_ARM_START, | 2132 | GNUNET_MESSAGE_TYPE_ARM_START, |
2128 | struct GNUNET_ARM_Message, | 2133 | struct GNUNET_ARM_Message, |
2129 | NULL), | 2134 | NULL), |
2130 | GNUNET_MQ_hd_var_size(stop, | 2135 | GNUNET_MQ_hd_var_size (stop, |
2131 | GNUNET_MESSAGE_TYPE_ARM_STOP, | 2136 | GNUNET_MESSAGE_TYPE_ARM_STOP, |
2132 | struct GNUNET_ARM_Message, | 2137 | struct GNUNET_ARM_Message, |
2133 | NULL), | 2138 | NULL), |
2134 | GNUNET_MQ_hd_fixed_size(monitor, | 2139 | GNUNET_MQ_hd_fixed_size (monitor, |
2135 | GNUNET_MESSAGE_TYPE_ARM_MONITOR, | 2140 | GNUNET_MESSAGE_TYPE_ARM_MONITOR, |
2136 | struct GNUNET_MessageHeader, | 2141 | struct GNUNET_MessageHeader, |
2137 | NULL), | 2142 | NULL), |
2138 | GNUNET_MQ_hd_fixed_size(list, | 2143 | GNUNET_MQ_hd_fixed_size (list, |
2139 | GNUNET_MESSAGE_TYPE_ARM_LIST, | 2144 | GNUNET_MESSAGE_TYPE_ARM_LIST, |
2140 | struct GNUNET_ARM_Message, | 2145 | struct GNUNET_ARM_Message, |
2141 | NULL), | 2146 | NULL), |
2142 | GNUNET_MQ_hd_fixed_size(test, | 2147 | GNUNET_MQ_hd_fixed_size (test, |
2143 | GNUNET_MESSAGE_TYPE_ARM_TEST, | 2148 | GNUNET_MESSAGE_TYPE_ARM_TEST, |
2144 | struct GNUNET_MessageHeader, | 2149 | struct GNUNET_MessageHeader, |
2145 | NULL), | 2150 | NULL), |
2146 | GNUNET_MQ_handler_end() }; | 2151 | GNUNET_MQ_handler_end () |
2147 | 2152 | }; | |
2148 | sigpipe = GNUNET_DISK_pipe(GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO); | 2153 | |
2149 | GNUNET_assert(NULL != sigpipe); | 2154 | sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO); |
2155 | GNUNET_assert (NULL != sigpipe); | ||
2150 | shc_chld = | 2156 | shc_chld = |
2151 | GNUNET_SIGNAL_handler_install(GNUNET_SIGCHLD, &sighandler_child_death); | 2157 | GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, |
2152 | if (0 != GNUNET_SERVICE_run_(argc, | 2158 | &sighandler_child_death); |
2153 | argv, | 2159 | if (0 != GNUNET_SERVICE_run_ (argc, |
2154 | "arm", | 2160 | argv, |
2155 | GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN, | 2161 | "arm", |
2156 | &run, | 2162 | GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN |
2157 | &client_connect_cb, | 2163 | | GNUNET_SERVICE_OPTION_CLOSE_LSOCKS, |
2158 | &client_disconnect_cb, | 2164 | &run, |
2159 | NULL, | 2165 | &client_connect_cb, |
2160 | handlers)) | 2166 | &client_disconnect_cb, |
2167 | NULL, | ||
2168 | handlers)) | ||
2161 | global_ret = 2; | 2169 | global_ret = 2; |
2162 | #if HAVE_WAIT4 | 2170 | #if HAVE_WAIT4 |
2163 | if (NULL != wait_file) | 2171 | if (NULL != wait_file) |
2164 | { | 2172 | { |
2165 | fclose(wait_file); | 2173 | fclose (wait_file); |
2166 | wait_file = NULL; | 2174 | wait_file = NULL; |
2167 | } | 2175 | } |
2168 | if (NULL != wait_filename) | 2176 | if (NULL != wait_filename) |
2169 | { | 2177 | { |
2170 | GNUNET_free(wait_filename); | 2178 | GNUNET_free (wait_filename); |
2171 | wait_filename = NULL; | 2179 | wait_filename = NULL; |
2172 | } | 2180 | } |
2173 | #endif | 2181 | #endif |
2174 | GNUNET_SIGNAL_handler_uninstall(shc_chld); | 2182 | GNUNET_SIGNAL_handler_uninstall (shc_chld); |
2175 | shc_chld = NULL; | 2183 | shc_chld = NULL; |
2176 | GNUNET_DISK_pipe_close(sigpipe); | 2184 | GNUNET_DISK_pipe_close (sigpipe); |
2177 | sigpipe = NULL; | 2185 | sigpipe = NULL; |
2178 | return global_ret; | 2186 | return global_ret; |
2179 | } | 2187 | } |
@@ -2185,11 +2193,11 @@ main(int argc, char *const *argv) | |||
2185 | /** | 2193 | /** |
2186 | * MINIMIZE heap size (way below 128k) since this process doesn't need much. | 2194 | * MINIMIZE heap size (way below 128k) since this process doesn't need much. |
2187 | */ | 2195 | */ |
2188 | void __attribute__ ((constructor)) GNUNET_ARM_memory_init() | 2196 | void __attribute__ ((constructor)) GNUNET_ARM_memory_init () |
2189 | { | 2197 | { |
2190 | mallopt(M_TRIM_THRESHOLD, 4 * 1024); | 2198 | mallopt (M_TRIM_THRESHOLD, 4 * 1024); |
2191 | mallopt(M_TOP_PAD, 1 * 1024); | 2199 | mallopt (M_TOP_PAD, 1 * 1024); |
2192 | malloc_trim(0); | 2200 | malloc_trim (0); |
2193 | } | 2201 | } |
2194 | #endif | 2202 | #endif |
2195 | 2203 | ||