diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-09-24 21:21:44 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-09-24 21:21:44 +0000 |
commit | 31899f01bd95f66e6cfec9b53ace071648d6b663 (patch) | |
tree | f3ce0eae1093241cd1be5fa7277d262b39f93cf8 /src/arm/gnunet-service-arm.c | |
parent | bdd2a2f82789160f7cd1d5f6d25bdcd75a90937e (diff) | |
download | gnunet-31899f01bd95f66e6cfec9b53ace071648d6b663.tar.gz gnunet-31899f01bd95f66e6cfec9b53ace071648d6b663.zip |
migrate ARM to new service API
Diffstat (limited to 'src/arm/gnunet-service-arm.c')
-rw-r--r-- | src/arm/gnunet-service-arm.c | 724 |
1 files changed, 401 insertions, 323 deletions
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c index df426bb48..995cd4489 100644 --- a/src/arm/gnunet-service-arm.c +++ b/src/arm/gnunet-service-arm.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2009, 2010, 2011, 2015 GNUnet e.V. | 3 | Copyright (C) 2009-2011, 2015, 2016 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -82,7 +82,7 @@ struct ServiceListeningInfo | |||
82 | struct ServiceList *sl; | 82 | struct ServiceList *sl; |
83 | 83 | ||
84 | /** | 84 | /** |
85 | * Number of bytes in 'service_addr' | 85 | * Number of bytes in @e service_addr |
86 | */ | 86 | */ |
87 | socklen_t service_addr_len; | 87 | socklen_t service_addr_len; |
88 | 88 | ||
@@ -143,7 +143,7 @@ struct ServiceList | |||
143 | * Client to notify upon kill completion (waitpid), NULL | 143 | * Client to notify upon kill completion (waitpid), NULL |
144 | * if we should simply restart the process. | 144 | * if we should simply restart the process. |
145 | */ | 145 | */ |
146 | struct GNUNET_SERVER_Client *killing_client; | 146 | struct GNUNET_SERVICE_Client *killing_client; |
147 | 147 | ||
148 | /** | 148 | /** |
149 | * ID of the request that killed the service (for reporting back). | 149 | * ID of the request that killed the service (for reporting back). |
@@ -242,92 +242,21 @@ static int start_user = GNUNET_YES; | |||
242 | static int start_system = GNUNET_YES; | 242 | static int start_system = GNUNET_YES; |
243 | 243 | ||
244 | /** | 244 | /** |
245 | * Handle to our server instance. Our server is a bit special in that | 245 | * Handle to our service instance. Our service is a bit special in that |
246 | * its service is not immediately stopped once we get a shutdown | 246 | * its service is not immediately stopped once we get a shutdown |
247 | * request (since we need to continue service until all of our child | 247 | * request (since we need to continue service until all of our child |
248 | * processes are dead). This handle is used to shut down the server | 248 | * processes are dead). This handle is used to shut down the service |
249 | * (and thus trigger process termination) once all child processes are | 249 | * (and thus trigger process termination) once all child processes are |
250 | * also dead. A special option in the ARM configuration modifies the | 250 | * also dead. A special option in the ARM configuration modifies the |
251 | * behaviour of the service implementation to not do the shutdown | 251 | * behaviour of the service implementation to not do the shutdown |
252 | * immediately. | 252 | * immediately. |
253 | */ | 253 | */ |
254 | static struct GNUNET_SERVER_Handle *server; | 254 | static struct GNUNET_SERVICE_Handle *service; |
255 | 255 | ||
256 | /** | 256 | /** |
257 | * Context for notifications we need to send to our clients. | 257 | * Context for notifications we need to send to our clients. |
258 | */ | 258 | */ |
259 | static struct GNUNET_SERVER_NotificationContext *notifier; | 259 | static struct GNUNET_NotificationContext *notifier; |
260 | |||
261 | |||
262 | /** | ||
263 | * Transmit a status result message. | ||
264 | * | ||
265 | * @param cls a `unit16_t *` with message type | ||
266 | * @param size number of bytes available in @a buf | ||
267 | * @param buf where to copy the message, NULL on error | ||
268 | * @return number of bytes copied to @a buf | ||
269 | */ | ||
270 | static size_t | ||
271 | write_result (void *cls, size_t size, void *buf) | ||
272 | { | ||
273 | struct GNUNET_ARM_ResultMessage *msg = cls; | ||
274 | size_t msize; | ||
275 | |||
276 | if (NULL == buf) | ||
277 | { | ||
278 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
279 | _("Could not send status result to client\n")); | ||
280 | GNUNET_free (msg); | ||
281 | return 0; /* error, not much we can do */ | ||
282 | } | ||
283 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
284 | "Sending status response %u to client\n", | ||
285 | (unsigned int) msg->result); | ||
286 | msize = msg->arm_msg.header.size; | ||
287 | GNUNET_assert (size >= msize); | ||
288 | msg->arm_msg.header.size = htons (msg->arm_msg.header.size); | ||
289 | msg->arm_msg.header.type = htons (msg->arm_msg.header.type); | ||
290 | msg->result = htonl (msg->result); | ||
291 | msg->arm_msg.request_id = GNUNET_htonll (msg->arm_msg.request_id); | ||
292 | GNUNET_memcpy (buf, msg, msize); | ||
293 | GNUNET_free (msg); | ||
294 | return msize; | ||
295 | } | ||
296 | |||
297 | |||
298 | /** | ||
299 | * Transmit the list of running services. | ||
300 | * | ||
301 | * @param cls pointer to `struct GNUNET_ARM_ListResultMessage` with the message | ||
302 | * @param size number of bytes available in @a buf | ||
303 | * @param buf where to copy the message, NULL on error | ||
304 | * @return number of bytes copied to @a buf | ||
305 | */ | ||
306 | static size_t | ||
307 | write_list_result (void *cls, size_t size, void *buf) | ||
308 | { | ||
309 | struct GNUNET_ARM_ListResultMessage *msg = cls; | ||
310 | size_t rslt_size; | ||
311 | |||
312 | if (NULL == buf) | ||
313 | { | ||
314 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
315 | _("Could not send list result to client\n")); | ||
316 | GNUNET_free (msg); | ||
317 | return 0; /* error, not much we can do */ | ||
318 | } | ||
319 | |||
320 | rslt_size = msg->arm_msg.header.size; | ||
321 | GNUNET_assert (size >= rslt_size); | ||
322 | msg->arm_msg.header.size = htons (msg->arm_msg.header.size); | ||
323 | msg->arm_msg.header.type = htons (msg->arm_msg.header.type); | ||
324 | msg->arm_msg.request_id = GNUNET_htonll (msg->arm_msg.request_id); | ||
325 | msg->count = htons (msg->count); | ||
326 | |||
327 | GNUNET_memcpy (buf, msg, rslt_size); | ||
328 | GNUNET_free (msg); | ||
329 | return rslt_size; | ||
330 | } | ||
331 | 260 | ||
332 | 261 | ||
333 | /** | 262 | /** |
@@ -341,24 +270,20 @@ write_list_result (void *cls, size_t size, void *buf) | |||
341 | * @return NULL if it was not found | 270 | * @return NULL if it was not found |
342 | */ | 271 | */ |
343 | static void | 272 | static void |
344 | signal_result (struct GNUNET_SERVER_Client *client, | 273 | signal_result (struct GNUNET_SERVICE_Client *client, |
345 | const char *name, | 274 | const char *name, |
346 | uint64_t request_id, | 275 | uint64_t request_id, |
347 | enum GNUNET_ARM_Result result) | 276 | enum GNUNET_ARM_Result result) |
348 | { | 277 | { |
278 | struct GNUNET_MQ_Envelope *env; | ||
349 | struct GNUNET_ARM_ResultMessage *msg; | 279 | struct GNUNET_ARM_ResultMessage *msg; |
350 | size_t msize; | 280 | |
351 | 281 | env = GNUNET_MQ_msg (msg, | |
352 | msize = sizeof (struct GNUNET_ARM_ResultMessage); | 282 | GNUNET_MESSAGE_TYPE_ARM_RESULT); |
353 | msg = GNUNET_malloc (msize); | 283 | msg->result = htonl (result); |
354 | msg->arm_msg.header.size = msize; | 284 | msg->arm_msg.request_id = GNUNET_htonll (request_id); |
355 | msg->arm_msg.header.type = GNUNET_MESSAGE_TYPE_ARM_RESULT; | 285 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), |
356 | msg->result = result; | 286 | env); |
357 | msg->arm_msg.request_id = request_id; | ||
358 | |||
359 | GNUNET_SERVER_notify_transmit_ready (client, msize, | ||
360 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
361 | write_result, msg); | ||
362 | } | 287 | } |
363 | 288 | ||
364 | 289 | ||
@@ -373,30 +298,36 @@ signal_result (struct GNUNET_SERVER_Client *client, | |||
373 | static void | 298 | static void |
374 | broadcast_status (const char *name, | 299 | broadcast_status (const char *name, |
375 | enum GNUNET_ARM_ServiceStatus status, | 300 | enum GNUNET_ARM_ServiceStatus status, |
376 | struct GNUNET_SERVER_Client *unicast) | 301 | struct GNUNET_SERVICE_Client *unicast) |
377 | { | 302 | { |
303 | struct GNUNET_MQ_Envelope *env; | ||
378 | struct GNUNET_ARM_StatusMessage *msg; | 304 | struct GNUNET_ARM_StatusMessage *msg; |
379 | size_t namelen; | 305 | size_t namelen; |
380 | 306 | ||
381 | if (NULL == notifier) | ||
382 | return; | ||
383 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 307 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
384 | "Sending status %u of service `%s' to client\n", | 308 | "Sending status %u of service `%s' to client\n", |
385 | (unsigned int) status, name); | 309 | (unsigned int) status, |
386 | namelen = strlen (name); | 310 | name); |
387 | msg = GNUNET_malloc (sizeof (struct GNUNET_ARM_StatusMessage) + namelen + 1); | 311 | namelen = strlen (name) + 1; |
388 | msg->header.size = htons (sizeof (struct GNUNET_ARM_StatusMessage) + namelen + 1); | 312 | env = GNUNET_MQ_msg_extra (msg, |
389 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_ARM_STATUS); | 313 | namelen, |
314 | GNUNET_MESSAGE_TYPE_ARM_STATUS); | ||
390 | msg->status = htonl ((uint32_t) (status)); | 315 | msg->status = htonl ((uint32_t) (status)); |
391 | GNUNET_memcpy ((char *) &msg[1], name, namelen + 1); | 316 | GNUNET_memcpy ((char *) &msg[1], |
392 | 317 | name, | |
318 | namelen); | ||
393 | if (NULL == unicast) | 319 | if (NULL == unicast) |
394 | GNUNET_SERVER_notification_context_broadcast (notifier, | 320 | { |
395 | (struct GNUNET_MessageHeader *) msg, GNUNET_YES); | 321 | GNUNET_notification_context_broadcast (notifier, |
322 | &msg->header, | ||
323 | GNUNET_YES); | ||
324 | GNUNET_MQ_discard (env); | ||
325 | } | ||
396 | else | 326 | else |
397 | GNUNET_SERVER_notification_context_unicast (notifier, unicast, | 327 | { |
398 | (const struct GNUNET_MessageHeader *) msg, GNUNET_NO); | 328 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (unicast), |
399 | GNUNET_free (msg); | 329 | env); |
330 | } | ||
400 | } | 331 | } |
401 | 332 | ||
402 | 333 | ||
@@ -410,7 +341,7 @@ broadcast_status (const char *name, | |||
410 | */ | 341 | */ |
411 | static void | 342 | static void |
412 | start_process (struct ServiceList *sl, | 343 | start_process (struct ServiceList *sl, |
413 | struct GNUNET_SERVER_Client *client, | 344 | struct GNUNET_SERVICE_Client *client, |
414 | uint64_t request_id) | 345 | uint64_t request_id) |
415 | { | 346 | { |
416 | char *loprefix; | 347 | char *loprefix; |
@@ -430,16 +361,20 @@ start_process (struct ServiceList *sl, | |||
430 | { | 361 | { |
431 | GNUNET_array_append (lsocks, ls, | 362 | GNUNET_array_append (lsocks, ls, |
432 | GNUNET_NETWORK_get_fd (sli->listen_socket)); | 363 | GNUNET_NETWORK_get_fd (sli->listen_socket)); |
433 | if (sli->accept_task != NULL) | 364 | if (NULL != sli->accept_task) |
434 | { | 365 | { |
435 | GNUNET_SCHEDULER_cancel (sli->accept_task); | 366 | GNUNET_SCHEDULER_cancel (sli->accept_task); |
436 | sli->accept_task = NULL; | 367 | sli->accept_task = NULL; |
437 | } | 368 | } |
438 | } | 369 | } |
439 | #if WINDOWS | 370 | #if WINDOWS |
440 | GNUNET_array_append (lsocks, ls, INVALID_SOCKET); | 371 | GNUNET_array_append (lsocks, |
372 | ls, | ||
373 | INVALID_SOCKET); | ||
441 | #else | 374 | #else |
442 | GNUNET_array_append (lsocks, ls, -1); | 375 | GNUNET_array_append (lsocks, |
376 | ls, | ||
377 | -1); | ||
443 | #endif | 378 | #endif |
444 | 379 | ||
445 | /* obtain configuration */ | 380 | /* obtain configuration */ |
@@ -463,7 +398,8 @@ start_process (struct ServiceList *sl, | |||
463 | 398 | ||
464 | fin_options = GNUNET_strdup (final_option); | 399 | fin_options = GNUNET_strdup (final_option); |
465 | /* replace '{}' with service name */ | 400 | /* replace '{}' with service name */ |
466 | while (NULL != (optpos = strstr (fin_options, "{}"))) | 401 | while (NULL != (optpos = strstr (fin_options, |
402 | "{}"))) | ||
467 | { | 403 | { |
468 | /* terminate string at opening parenthesis */ | 404 | /* terminate string at opening parenthesis */ |
469 | *optpos = 0; | 405 | *optpos = 0; |
@@ -597,7 +533,7 @@ start_process (struct ServiceList *sl, | |||
597 | } | 533 | } |
598 | GNUNET_free (binary); | 534 | GNUNET_free (binary); |
599 | GNUNET_free (quotedbinary); | 535 | GNUNET_free (quotedbinary); |
600 | if (sl->proc == NULL) | 536 | if (NULL == sl->proc) |
601 | { | 537 | { |
602 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 538 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
603 | _("Failed to start service `%s'\n"), | 539 | _("Failed to start service `%s'\n"), |
@@ -613,14 +549,21 @@ start_process (struct ServiceList *sl, | |||
613 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 549 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
614 | _("Starting service `%s'\n"), | 550 | _("Starting service `%s'\n"), |
615 | sl->name); | 551 | sl->name); |
616 | broadcast_status (sl->name, GNUNET_ARM_SERVICE_STARTING, NULL); | 552 | broadcast_status (sl->name, |
553 | GNUNET_ARM_SERVICE_STARTING, | ||
554 | NULL); | ||
617 | if (client) | 555 | if (client) |
618 | signal_result (client, sl->name, request_id, GNUNET_ARM_RESULT_STARTING); | 556 | signal_result (client, |
557 | sl->name, | ||
558 | request_id, | ||
559 | GNUNET_ARM_RESULT_STARTING); | ||
619 | } | 560 | } |
620 | /* clean up */ | 561 | /* clean up */ |
621 | GNUNET_free (loprefix); | 562 | GNUNET_free (loprefix); |
622 | GNUNET_free (options); | 563 | GNUNET_free (options); |
623 | GNUNET_array_grow (lsocks, ls, 0); | 564 | GNUNET_array_grow (lsocks, |
565 | ls, | ||
566 | 0); | ||
624 | } | 567 | } |
625 | 568 | ||
626 | 569 | ||
@@ -689,15 +632,23 @@ create_listen_socket (struct sockaddr *sa, | |||
689 | switch (sa->sa_family) | 632 | switch (sa->sa_family) |
690 | { | 633 | { |
691 | case AF_INET: | 634 | case AF_INET: |
692 | sock = GNUNET_NETWORK_socket_create (PF_INET, SOCK_STREAM, 0); | 635 | sock = GNUNET_NETWORK_socket_create (PF_INET, |
636 | SOCK_STREAM, | ||
637 | 0); | ||
693 | break; | 638 | break; |
694 | case AF_INET6: | 639 | case AF_INET6: |
695 | sock = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); | 640 | sock = GNUNET_NETWORK_socket_create (PF_INET6, |
641 | SOCK_STREAM, | ||
642 | 0); | ||
696 | break; | 643 | break; |
697 | case AF_UNIX: | 644 | case AF_UNIX: |
698 | if (strcmp (GNUNET_a2s (sa, addr_len), "@") == 0) /* Do not bind to blank UNIX path! */ | 645 | if (0 == strcmp (GNUNET_a2s (sa, |
646 | addr_len), | ||
647 | "@")) /* Do not bind to blank UNIX path! */ | ||
699 | return; | 648 | return; |
700 | sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0); | 649 | sock = GNUNET_NETWORK_socket_create (PF_UNIX, |
650 | SOCK_STREAM, | ||
651 | 0); | ||
701 | break; | 652 | break; |
702 | default: | 653 | default: |
703 | GNUNET_break (0); | 654 | GNUNET_break (0); |
@@ -709,18 +660,27 @@ create_listen_socket (struct sockaddr *sa, | |||
709 | { | 660 | { |
710 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 661 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
711 | _("Unable to create socket for service `%s': %s\n"), | 662 | _("Unable to create socket for service `%s': %s\n"), |
712 | sl->name, STRERROR (errno)); | 663 | sl->name, |
664 | STRERROR (errno)); | ||
713 | GNUNET_free (sa); | 665 | GNUNET_free (sa); |
714 | return; | 666 | return; |
715 | } | 667 | } |
716 | if (GNUNET_NETWORK_socket_setsockopt | 668 | if (GNUNET_OK != |
717 | (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK) | 669 | GNUNET_NETWORK_socket_setsockopt (sock, |
670 | SOL_SOCKET, | ||
671 | SO_REUSEADDR, | ||
672 | &on, | ||
673 | sizeof (on))) | ||
718 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 674 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
719 | "setsockopt"); | 675 | "setsockopt"); |
720 | #ifdef IPV6_V6ONLY | 676 | #ifdef IPV6_V6ONLY |
721 | if ((sa->sa_family == AF_INET6) && | 677 | if ( (sa->sa_family == AF_INET6) && |
722 | (GNUNET_NETWORK_socket_setsockopt | 678 | (GNUNET_OK != |
723 | (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) != GNUNET_OK)) | 679 | GNUNET_NETWORK_socket_setsockopt (sock, |
680 | IPPROTO_IPV6, | ||
681 | IPV6_V6ONLY, | ||
682 | &on, | ||
683 | sizeof (on))) ) | ||
724 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 684 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
725 | "setsockopt"); | 685 | "setsockopt"); |
726 | #endif | 686 | #endif |
@@ -729,14 +689,18 @@ create_listen_socket (struct sockaddr *sa, | |||
729 | GNUNET_NETWORK_unix_precheck ((struct sockaddr_un *) sa); | 689 | GNUNET_NETWORK_unix_precheck ((struct sockaddr_un *) sa); |
730 | #endif | 690 | #endif |
731 | if (GNUNET_OK != | 691 | if (GNUNET_OK != |
732 | GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) sa, addr_len)) | 692 | GNUNET_NETWORK_socket_bind (sock, |
693 | (const struct sockaddr *) sa, | ||
694 | addr_len)) | ||
733 | { | 695 | { |
734 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 696 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
735 | _("Unable to bind listening socket for service `%s' to address `%s': %s\n"), | 697 | _("Unable to bind listening socket for service `%s' to address `%s': %s\n"), |
736 | sl->name, | 698 | sl->name, |
737 | GNUNET_a2s (sa, addr_len), | 699 | GNUNET_a2s (sa, |
700 | addr_len), | ||
738 | STRERROR (errno)); | 701 | STRERROR (errno)); |
739 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | 702 | GNUNET_break (GNUNET_OK == |
703 | GNUNET_NETWORK_socket_close (sock)); | ||
740 | GNUNET_free (sa); | 704 | GNUNET_free (sa); |
741 | return; | 705 | return; |
742 | } | 706 | } |
@@ -749,10 +713,12 @@ create_listen_socket (struct sockaddr *sa, | |||
749 | ) | 713 | ) |
750 | { | 714 | { |
751 | match_uid = | 715 | match_uid = |
752 | GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, | 716 | GNUNET_CONFIGURATION_get_value_yesno (cfg, |
717 | sl->name, | ||
753 | "UNIX_MATCH_UID"); | 718 | "UNIX_MATCH_UID"); |
754 | match_gid = | 719 | match_gid = |
755 | GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, | 720 | GNUNET_CONFIGURATION_get_value_yesno (cfg, |
721 | sl->name, | ||
756 | "UNIX_MATCH_GID"); | 722 | "UNIX_MATCH_GID"); |
757 | GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sa)->sun_path, | 723 | GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sa)->sun_path, |
758 | match_uid, | 724 | match_uid, |
@@ -760,24 +726,30 @@ create_listen_socket (struct sockaddr *sa, | |||
760 | 726 | ||
761 | } | 727 | } |
762 | #endif | 728 | #endif |
763 | if (GNUNET_NETWORK_socket_listen (sock, 5) != GNUNET_OK) | 729 | if (GNUNET_OK != |
730 | GNUNET_NETWORK_socket_listen (sock, 5)) | ||
764 | { | 731 | { |
765 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen"); | 732 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, |
766 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | 733 | "listen"); |
734 | GNUNET_break (GNUNET_OK == | ||
735 | GNUNET_NETWORK_socket_close (sock)); | ||
767 | GNUNET_free (sa); | 736 | GNUNET_free (sa); |
768 | return; | 737 | return; |
769 | } | 738 | } |
770 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 739 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
771 | _("ARM now monitors connections to service `%s' at `%s'\n"), | 740 | _("ARM now monitors connections to service `%s' at `%s'\n"), |
772 | sl->name, GNUNET_a2s (sa, addr_len)); | 741 | sl->name, |
742 | GNUNET_a2s (sa, | ||
743 | addr_len)); | ||
773 | sli = GNUNET_new (struct ServiceListeningInfo); | 744 | sli = GNUNET_new (struct ServiceListeningInfo); |
774 | sli->service_addr = sa; | 745 | sli->service_addr = sa; |
775 | sli->service_addr_len = addr_len; | 746 | sli->service_addr_len = addr_len; |
776 | sli->listen_socket = sock; | 747 | sli->listen_socket = sock; |
777 | sli->sl = sl; | 748 | sli->sl = sl; |
778 | sli->accept_task = | 749 | sli->accept_task |
779 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, sock, | 750 | = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
780 | &accept_connection, sli); | 751 | sock, |
752 | &accept_connection, sli); | ||
781 | GNUNET_CONTAINER_DLL_insert (sl->listen_head, | 753 | GNUNET_CONTAINER_DLL_insert (sl->listen_head, |
782 | sl->listen_tail, | 754 | sl->listen_tail, |
783 | sli); | 755 | sli); |
@@ -794,7 +766,9 @@ static void | |||
794 | free_service (struct ServiceList *sl) | 766 | free_service (struct ServiceList *sl) |
795 | { | 767 | { |
796 | GNUNET_assert (GNUNET_YES == in_shutdown); | 768 | GNUNET_assert (GNUNET_YES == in_shutdown); |
797 | GNUNET_CONTAINER_DLL_remove (running_head, running_tail, sl); | 769 | GNUNET_CONTAINER_DLL_remove (running_head, |
770 | running_tail, | ||
771 | sl); | ||
798 | GNUNET_assert (NULL == sl->listen_head); | 772 | GNUNET_assert (NULL == sl->listen_head); |
799 | GNUNET_free_non_null (sl->config); | 773 | GNUNET_free_non_null (sl->config); |
800 | GNUNET_free_non_null (sl->binary); | 774 | GNUNET_free_non_null (sl->binary); |
@@ -804,61 +778,79 @@ free_service (struct ServiceList *sl) | |||
804 | 778 | ||
805 | 779 | ||
806 | /** | 780 | /** |
807 | * Handle START-message. | 781 | * Check START-message. |
808 | * | 782 | * |
809 | * @param cls closure (always NULL) | 783 | * @param cls identification of the client |
810 | * @param client identification of the client | 784 | * @param amsg the actual message |
811 | * @param message the actual message | ||
812 | * @return #GNUNET_OK to keep the connection open, | 785 | * @return #GNUNET_OK to keep the connection open, |
813 | * #GNUNET_SYSERR to close it (signal serious error) | 786 | * #GNUNET_SYSERR to close it (signal serious error) |
814 | */ | 787 | */ |
788 | static int | ||
789 | check_start (void *cls, | ||
790 | const struct GNUNET_ARM_Message *amsg) | ||
791 | { | ||
792 | uint16_t size; | ||
793 | const char *servicename; | ||
794 | |||
795 | size = ntohs (amsg->header.size) - sizeof (struct GNUNET_ARM_Message); | ||
796 | servicename = (const char *) &amsg[1]; | ||
797 | if ( (0 == size) || | ||
798 | (servicename[size - 1] != '\0') ) | ||
799 | { | ||
800 | GNUNET_break (0); | ||
801 | return GNUNET_SYSERR; | ||
802 | } | ||
803 | return GNUNET_OK; | ||
804 | } | ||
805 | |||
806 | |||
807 | /** | ||
808 | * Handle START-message. | ||
809 | * | ||
810 | * @param cls identification of the client | ||
811 | * @param amsg the actual message | ||
812 | */ | ||
815 | static void | 813 | static void |
816 | handle_start (void *cls, | 814 | handle_start (void *cls, |
817 | struct GNUNET_SERVER_Client *client, | 815 | const struct GNUNET_ARM_Message *amsg) |
818 | const struct GNUNET_MessageHeader *message) | ||
819 | { | 816 | { |
817 | struct GNUNET_SERVICE_Client *client = cls; | ||
820 | const char *servicename; | 818 | const char *servicename; |
821 | struct ServiceList *sl; | 819 | struct ServiceList *sl; |
822 | uint16_t size; | ||
823 | uint64_t request_id; | 820 | uint64_t request_id; |
824 | struct GNUNET_ARM_Message *amsg; | ||
825 | 821 | ||
826 | amsg = (struct GNUNET_ARM_Message *) message; | ||
827 | request_id = GNUNET_ntohll (amsg->request_id); | 822 | request_id = GNUNET_ntohll (amsg->request_id); |
828 | size = ntohs (amsg->header.size); | ||
829 | size -= sizeof (struct GNUNET_ARM_Message); | ||
830 | servicename = (const char *) &amsg[1]; | 823 | servicename = (const char *) &amsg[1]; |
831 | if ((size == 0) || (servicename[size - 1] != '\0')) | 824 | GNUNET_SERVICE_client_continue (client); |
832 | { | ||
833 | GNUNET_break (0); | ||
834 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
835 | return; | ||
836 | } | ||
837 | if (GNUNET_YES == in_shutdown) | 825 | if (GNUNET_YES == in_shutdown) |
838 | { | 826 | { |
839 | signal_result (client, servicename, request_id, | 827 | signal_result (client, |
828 | servicename, | ||
829 | request_id, | ||
840 | GNUNET_ARM_RESULT_IN_SHUTDOWN); | 830 | GNUNET_ARM_RESULT_IN_SHUTDOWN); |
841 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
842 | return; | 831 | return; |
843 | } | 832 | } |
844 | sl = find_service (servicename); | 833 | sl = find_service (servicename); |
845 | if (NULL == sl) | 834 | if (NULL == sl) |
846 | { | 835 | { |
847 | signal_result (client, servicename, request_id, | 836 | signal_result (client, |
837 | servicename, | ||
838 | request_id, | ||
848 | GNUNET_ARM_RESULT_IS_NOT_KNOWN); | 839 | GNUNET_ARM_RESULT_IS_NOT_KNOWN); |
849 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
850 | return; | 840 | return; |
851 | } | 841 | } |
852 | sl->force_start = GNUNET_YES; | 842 | sl->force_start = GNUNET_YES; |
853 | if (NULL != sl->proc) | 843 | if (NULL != sl->proc) |
854 | { | 844 | { |
855 | signal_result (client, servicename, request_id, | 845 | signal_result (client, |
846 | servicename, | ||
847 | request_id, | ||
856 | GNUNET_ARM_RESULT_IS_STARTED_ALREADY); | 848 | GNUNET_ARM_RESULT_IS_STARTED_ALREADY); |
857 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
858 | return; | 849 | return; |
859 | } | 850 | } |
860 | start_process (sl, client, request_id); | 851 | start_process (sl, |
861 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 852 | client, |
853 | request_id); | ||
862 | } | 854 | } |
863 | 855 | ||
864 | 856 | ||
@@ -877,73 +869,87 @@ trigger_shutdown (void *cls) | |||
877 | 869 | ||
878 | 870 | ||
879 | /** | 871 | /** |
880 | * Handle STOP-message. | 872 | * Check STOP-message. |
881 | * | 873 | * |
882 | * @param cls closure (always NULL) | 874 | * @param cls identification of the client |
883 | * @param client identification of the client | 875 | * @param amsg the actual message |
884 | * @param message the actual message | ||
885 | * @return #GNUNET_OK to keep the connection open, | 876 | * @return #GNUNET_OK to keep the connection open, |
886 | * #GNUNET_SYSERR to close it (signal serious error) | 877 | * #GNUNET_SYSERR to close it (signal serious error) |
887 | */ | 878 | */ |
879 | static int | ||
880 | check_stop (void *cls, | ||
881 | const struct GNUNET_ARM_Message *amsg) | ||
882 | { | ||
883 | uint16_t size; | ||
884 | const char *servicename; | ||
885 | |||
886 | size = ntohs (amsg->header.size) - sizeof (struct GNUNET_ARM_Message); | ||
887 | servicename = (const char *) &amsg[1]; | ||
888 | if ( (0 == size) || | ||
889 | (servicename[size - 1] != '\0') ) | ||
890 | { | ||
891 | GNUNET_break (0); | ||
892 | return GNUNET_SYSERR; | ||
893 | } | ||
894 | return GNUNET_OK; | ||
895 | } | ||
896 | |||
897 | |||
898 | /** | ||
899 | * Handle STOP-message. | ||
900 | * | ||
901 | * @param cls identification of the client | ||
902 | * @param amsg the actual message | ||
903 | */ | ||
888 | static void | 904 | static void |
889 | handle_stop (void *cls, | 905 | handle_stop (void *cls, |
890 | struct GNUNET_SERVER_Client *client, | 906 | const struct GNUNET_ARM_Message *amsg) |
891 | const struct GNUNET_MessageHeader *message) | ||
892 | { | 907 | { |
908 | struct GNUNET_SERVICE_Client *client = cls; | ||
893 | struct ServiceList *sl; | 909 | struct ServiceList *sl; |
894 | const char *servicename; | 910 | const char *servicename; |
895 | uint16_t size; | ||
896 | uint64_t request_id; | 911 | uint64_t request_id; |
897 | struct GNUNET_ARM_Message *amsg; | ||
898 | 912 | ||
899 | amsg = (struct GNUNET_ARM_Message *) message; | ||
900 | request_id = GNUNET_ntohll (amsg->request_id); | 913 | request_id = GNUNET_ntohll (amsg->request_id); |
901 | size = ntohs (amsg->header.size); | ||
902 | size -= sizeof (struct GNUNET_ARM_Message); | ||
903 | servicename = (const char *) &amsg[1]; | 914 | servicename = (const char *) &amsg[1]; |
904 | if ((size == 0) || (servicename[size - 1] != '\0')) | ||
905 | { | ||
906 | GNUNET_break (0); | ||
907 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
908 | return; | ||
909 | } | ||
910 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 915 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
911 | _("Preparing to stop `%s'\n"), | 916 | _("Preparing to stop `%s'\n"), |
912 | servicename); | 917 | servicename); |
913 | if (0 == strcasecmp (servicename, "arm")) | 918 | GNUNET_SERVICE_client_continue (client); |
919 | if (0 == strcasecmp (servicename, | ||
920 | "arm")) | ||
914 | { | 921 | { |
915 | broadcast_status (servicename, | 922 | broadcast_status (servicename, |
916 | GNUNET_ARM_SERVICE_STOPPING, NULL); | 923 | GNUNET_ARM_SERVICE_STOPPING, |
924 | NULL); | ||
917 | signal_result (client, | 925 | signal_result (client, |
918 | servicename, | 926 | servicename, |
919 | request_id, | 927 | request_id, |
920 | GNUNET_ARM_RESULT_STOPPING); | 928 | GNUNET_ARM_RESULT_STOPPING); |
921 | GNUNET_SERVER_client_persist_ (client); | 929 | GNUNET_SERVICE_client_persist (client); |
922 | GNUNET_SCHEDULER_add_now (&trigger_shutdown, NULL); | 930 | GNUNET_SCHEDULER_add_now (&trigger_shutdown, |
923 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 931 | NULL); |
924 | return; | 932 | return; |
925 | } | 933 | } |
926 | sl = find_service (servicename); | 934 | sl = find_service (servicename); |
927 | if (sl == NULL) | 935 | if (NULL == sl) |
928 | { | 936 | { |
929 | signal_result (client, | 937 | signal_result (client, |
930 | servicename, | 938 | servicename, |
931 | request_id, | 939 | request_id, |
932 | GNUNET_ARM_RESULT_IS_NOT_KNOWN); | 940 | GNUNET_ARM_RESULT_IS_NOT_KNOWN); |
933 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 941 | return; |
934 | return; | 942 | } |
935 | } | ||
936 | sl->force_start = GNUNET_NO; | 943 | sl->force_start = GNUNET_NO; |
937 | if (GNUNET_YES == in_shutdown) | 944 | if (GNUNET_YES == in_shutdown) |
938 | { | 945 | { |
939 | /* shutdown in progress */ | 946 | /* shutdown in progress */ |
940 | signal_result (client, | 947 | signal_result (client, |
941 | servicename, | 948 | servicename, |
942 | request_id, | 949 | request_id, |
943 | GNUNET_ARM_RESULT_IN_SHUTDOWN); | 950 | GNUNET_ARM_RESULT_IN_SHUTDOWN); |
944 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 951 | return; |
945 | return; | 952 | } |
946 | } | ||
947 | if (NULL != sl->killing_client) | 953 | if (NULL != sl->killing_client) |
948 | { | 954 | { |
949 | /* killing already in progress */ | 955 | /* killing already in progress */ |
@@ -951,7 +957,6 @@ handle_stop (void *cls, | |||
951 | servicename, | 957 | servicename, |
952 | request_id, | 958 | request_id, |
953 | GNUNET_ARM_RESULT_IS_STOPPING_ALREADY); | 959 | GNUNET_ARM_RESULT_IS_STOPPING_ALREADY); |
954 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
955 | return; | 960 | return; |
956 | } | 961 | } |
957 | if (NULL == sl->proc) | 962 | if (NULL == sl->proc) |
@@ -961,7 +966,6 @@ handle_stop (void *cls, | |||
961 | servicename, | 966 | servicename, |
962 | request_id, | 967 | request_id, |
963 | GNUNET_ARM_RESULT_IS_STOPPED_ALREADY); | 968 | GNUNET_ARM_RESULT_IS_STOPPED_ALREADY); |
964 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
965 | return; | 969 | return; |
966 | } | 970 | } |
967 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 971 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -972,41 +976,37 @@ handle_stop (void *cls, | |||
972 | NULL); | 976 | NULL); |
973 | /* no signal_start - only when it's STOPPED */ | 977 | /* no signal_start - only when it's STOPPED */ |
974 | sl->killed_at = GNUNET_TIME_absolute_get (); | 978 | sl->killed_at = GNUNET_TIME_absolute_get (); |
975 | if (0 != GNUNET_OS_process_kill (sl->proc, GNUNET_TERM_SIG)) | 979 | if (0 != GNUNET_OS_process_kill (sl->proc, |
976 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); | 980 | GNUNET_TERM_SIG)) |
981 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, | ||
982 | "kill"); | ||
977 | sl->killing_client = client; | 983 | sl->killing_client = client; |
978 | sl->killing_client_request_id = request_id; | 984 | sl->killing_client_request_id = request_id; |
979 | GNUNET_SERVER_client_keep (client); | ||
980 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
981 | } | 985 | } |
982 | 986 | ||
983 | 987 | ||
984 | /** | 988 | /** |
985 | * Handle LIST-message. | 989 | * Handle LIST-message. |
986 | * | 990 | * |
987 | * @param cls closure (always NULL) | 991 | * @param cls identification of the client |
988 | * @param client identification of the client | ||
989 | * @param message the actual message | 992 | * @param message the actual message |
990 | */ | 993 | */ |
991 | static void | 994 | static void |
992 | handle_list (void *cls, | 995 | handle_list (void *cls, |
993 | struct GNUNET_SERVER_Client *client, | 996 | const struct GNUNET_ARM_Message *request) |
994 | const struct GNUNET_MessageHeader *message) | ||
995 | { | 997 | { |
998 | struct GNUNET_SERVICE_Client *client = cls; | ||
999 | struct GNUNET_MQ_Envelope *env; | ||
996 | struct GNUNET_ARM_ListResultMessage *msg; | 1000 | struct GNUNET_ARM_ListResultMessage *msg; |
997 | struct GNUNET_ARM_Message *request; | ||
998 | size_t string_list_size; | 1001 | size_t string_list_size; |
999 | size_t total_size; | ||
1000 | struct ServiceList *sl; | 1002 | struct ServiceList *sl; |
1001 | uint16_t count; | 1003 | uint16_t count; |
1004 | char *pos; | ||
1002 | 1005 | ||
1003 | if (NULL == client) | ||
1004 | return; | ||
1005 | |||
1006 | request = (struct GNUNET_ARM_Message *) message; | ||
1007 | GNUNET_break (0 == ntohl (request->reserved)); | 1006 | GNUNET_break (0 == ntohl (request->reserved)); |
1008 | count = 0; | 1007 | count = 0; |
1009 | string_list_size = 0; | 1008 | string_list_size = 0; |
1009 | |||
1010 | /* first count the running processes get their name's size */ | 1010 | /* first count the running processes get their name's size */ |
1011 | for (sl = running_head; NULL != sl; sl = sl->next) | 1011 | for (sl = running_head; NULL != sl; sl = sl->next) |
1012 | { | 1012 | { |
@@ -1019,30 +1019,51 @@ handle_list (void *cls, | |||
1019 | } | 1019 | } |
1020 | } | 1020 | } |
1021 | 1021 | ||
1022 | total_size = sizeof (struct GNUNET_ARM_ListResultMessage) | 1022 | env = GNUNET_MQ_msg_extra (msg, |
1023 | + string_list_size; | 1023 | string_list_size, |
1024 | msg = GNUNET_malloc (total_size); | 1024 | GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT); |
1025 | msg->arm_msg.header.size = total_size; | 1025 | msg->arm_msg.request_id = request->request_id; |
1026 | msg->arm_msg.header.type = GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT; | 1026 | msg->count = htons (count); |
1027 | msg->arm_msg.reserved = htonl (0); | ||
1028 | msg->arm_msg.request_id = GNUNET_ntohll (request->request_id); | ||
1029 | msg->count = count; | ||
1030 | 1027 | ||
1031 | char *pos = (char *)&msg[1]; | 1028 | pos = (char *) &msg[1]; |
1032 | for (sl = running_head; NULL != sl; sl = sl->next) | 1029 | for (sl = running_head; NULL != sl; sl = sl->next) |
1033 | { | 1030 | { |
1034 | if (NULL != sl->proc) | 1031 | if (NULL != sl->proc) |
1035 | { | 1032 | { |
1036 | size_t s = strlen (sl->name) + strlen (sl->binary) + 4; | 1033 | size_t s = strlen (sl->name) + strlen (sl->binary) + 4; |
1037 | GNUNET_snprintf (pos, s, "%s (%s)", sl->name, sl->binary); | 1034 | GNUNET_snprintf (pos, |
1035 | s, | ||
1036 | "%s (%s)", | ||
1037 | sl->name, | ||
1038 | sl->binary); | ||
1038 | pos += s; | 1039 | pos += s; |
1039 | } | 1040 | } |
1040 | } | 1041 | } |
1041 | GNUNET_SERVER_notify_transmit_ready (client, | 1042 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), |
1042 | total_size, | 1043 | env); |
1043 | GNUNET_TIME_UNIT_FOREVER_REL, | 1044 | GNUNET_SERVICE_client_continue (client); |
1044 | &write_list_result, msg); | 1045 | } |
1045 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1046 | |
1047 | |||
1048 | /** | ||
1049 | * Handle TEST-message by sending back TEST. | ||
1050 | * | ||
1051 | * @param cls identification of the client | ||
1052 | * @param message the actual message | ||
1053 | */ | ||
1054 | static void | ||
1055 | handle_test (void *cls, | ||
1056 | const struct GNUNET_MessageHeader *message) | ||
1057 | { | ||
1058 | struct GNUNET_SERVICE_Client *client = cls; | ||
1059 | struct GNUNET_MQ_Envelope *env; | ||
1060 | struct GNUNET_MessageHeader *msg; | ||
1061 | |||
1062 | env = GNUNET_MQ_msg (msg, | ||
1063 | GNUNET_MESSAGE_TYPE_ARM_TEST); | ||
1064 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), | ||
1065 | env); | ||
1066 | GNUNET_SERVICE_client_continue (client); | ||
1046 | } | 1067 | } |
1047 | 1068 | ||
1048 | 1069 | ||
@@ -1053,22 +1074,23 @@ handle_list (void *cls, | |||
1053 | static void | 1074 | static void |
1054 | do_shutdown () | 1075 | do_shutdown () |
1055 | { | 1076 | { |
1056 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Last shutdown phase\n"); | 1077 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1078 | "Last shutdown phase\n"); | ||
1057 | if (NULL != notifier) | 1079 | if (NULL != notifier) |
1058 | { | 1080 | { |
1059 | GNUNET_SERVER_notification_context_destroy (notifier); | 1081 | GNUNET_notification_context_destroy (notifier); |
1060 | notifier = NULL; | 1082 | notifier = NULL; |
1061 | } | 1083 | } |
1062 | if (NULL != server) | 1084 | if (NULL != service) |
1063 | { | 1085 | { |
1064 | GNUNET_SERVER_destroy (server); | 1086 | GNUNET_SERVICE_shutdown (service); |
1065 | server = NULL; | 1087 | service = NULL; |
1066 | } | 1088 | } |
1067 | if (NULL != child_death_task) | 1089 | if (NULL != child_death_task) |
1068 | { | 1090 | { |
1069 | GNUNET_SCHEDULER_cancel (child_death_task); | 1091 | GNUNET_SCHEDULER_cancel (child_death_task); |
1070 | child_death_task = NULL; | 1092 | child_death_task = NULL; |
1071 | } | 1093 | } |
1072 | } | 1094 | } |
1073 | 1095 | ||
1074 | 1096 | ||
@@ -1082,7 +1104,7 @@ static unsigned int | |||
1082 | list_count (struct ServiceList *running_head) | 1104 | list_count (struct ServiceList *running_head) |
1083 | { | 1105 | { |
1084 | struct ServiceList *i; | 1106 | struct ServiceList *i; |
1085 | unsigned int res = 0; | 1107 | unsigned int res; |
1086 | 1108 | ||
1087 | for (res = 0, i = running_head; i; i = i->next, res++) | 1109 | for (res = 0, i = running_head; i; i = i->next, res++) |
1088 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1110 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1116,20 +1138,20 @@ shutdown_task (void *cls) | |||
1116 | for (pos = running_head; NULL != pos; pos = pos->next) | 1138 | for (pos = running_head; NULL != pos; pos = pos->next) |
1117 | { | 1139 | { |
1118 | while (NULL != (sli = pos->listen_head)) | 1140 | while (NULL != (sli = pos->listen_head)) |
1141 | { | ||
1142 | GNUNET_CONTAINER_DLL_remove (pos->listen_head, | ||
1143 | pos->listen_tail, | ||
1144 | sli); | ||
1145 | if (NULL != sli->accept_task) | ||
1119 | { | 1146 | { |
1120 | GNUNET_CONTAINER_DLL_remove (pos->listen_head, | 1147 | GNUNET_SCHEDULER_cancel (sli->accept_task); |
1121 | pos->listen_tail, | 1148 | sli->accept_task = NULL; |
1122 | sli); | ||
1123 | if (NULL != sli->accept_task) | ||
1124 | { | ||
1125 | GNUNET_SCHEDULER_cancel (sli->accept_task); | ||
1126 | sli->accept_task = NULL; | ||
1127 | } | ||
1128 | GNUNET_break (GNUNET_OK == | ||
1129 | GNUNET_NETWORK_socket_close (sli->listen_socket)); | ||
1130 | GNUNET_free (sli->service_addr); | ||
1131 | GNUNET_free (sli); | ||
1132 | } | 1149 | } |
1150 | GNUNET_break (GNUNET_OK == | ||
1151 | GNUNET_NETWORK_socket_close (sli->listen_socket)); | ||
1152 | GNUNET_free (sli->service_addr); | ||
1153 | GNUNET_free (sli); | ||
1154 | } | ||
1133 | } | 1155 | } |
1134 | /* then, shutdown all existing service processes */ | 1156 | /* then, shutdown all existing service processes */ |
1135 | nxt = running_head; | 1157 | nxt = running_head; |
@@ -1142,8 +1164,10 @@ shutdown_task (void *cls) | |||
1142 | "Stopping service `%s'\n", | 1164 | "Stopping service `%s'\n", |
1143 | pos->name); | 1165 | pos->name); |
1144 | pos->killed_at = GNUNET_TIME_absolute_get (); | 1166 | pos->killed_at = GNUNET_TIME_absolute_get (); |
1145 | if (0 != GNUNET_OS_process_kill (pos->proc, GNUNET_TERM_SIG)) | 1167 | if (0 != GNUNET_OS_process_kill (pos->proc, |
1146 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); | 1168 | GNUNET_TERM_SIG)) |
1169 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, | ||
1170 | "kill"); | ||
1147 | } | 1171 | } |
1148 | else | 1172 | else |
1149 | { | 1173 | { |
@@ -1193,7 +1217,9 @@ delayed_restart_task (void *cls) | |||
1193 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1217 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1194 | _("Restarting service `%s'.\n"), | 1218 | _("Restarting service `%s'.\n"), |
1195 | sl->name); | 1219 | sl->name); |
1196 | start_process (sl, NULL, 0); | 1220 | start_process (sl, |
1221 | NULL, | ||
1222 | 0); | ||
1197 | } | 1223 | } |
1198 | else | 1224 | else |
1199 | { | 1225 | { |
@@ -1202,11 +1228,11 @@ delayed_restart_task (void *cls) | |||
1202 | if (NULL == sli->accept_task) | 1228 | if (NULL == sli->accept_task) |
1203 | { | 1229 | { |
1204 | /* accept was actually paused, so start it again */ | 1230 | /* accept was actually paused, so start it again */ |
1205 | sli->accept_task = | 1231 | sli->accept_task |
1206 | GNUNET_SCHEDULER_add_read_net | 1232 | = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
1207 | (GNUNET_TIME_UNIT_FOREVER_REL, | 1233 | sli->listen_socket, |
1208 | sli->listen_socket, | 1234 | &accept_connection, |
1209 | &accept_connection, sli); | 1235 | sli); |
1210 | } | 1236 | } |
1211 | } | 1237 | } |
1212 | } | 1238 | } |
@@ -1223,11 +1249,13 @@ delayed_restart_task (void *cls) | |||
1223 | { | 1249 | { |
1224 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1250 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1225 | "Will restart process in %s\n", | 1251 | "Will restart process in %s\n", |
1226 | GNUNET_STRINGS_relative_time_to_string (lowestRestartDelay, GNUNET_YES)); | 1252 | GNUNET_STRINGS_relative_time_to_string (lowestRestartDelay, |
1253 | GNUNET_YES)); | ||
1227 | child_restart_task = | 1254 | child_restart_task = |
1228 | GNUNET_SCHEDULER_add_delayed_with_priority (lowestRestartDelay, | 1255 | GNUNET_SCHEDULER_add_delayed_with_priority (lowestRestartDelay, |
1229 | GNUNET_SCHEDULER_PRIORITY_IDLE, | 1256 | GNUNET_SCHEDULER_PRIORITY_IDLE, |
1230 | &delayed_restart_task, NULL); | 1257 | &delayed_restart_task, |
1258 | NULL); | ||
1231 | } | 1259 | } |
1232 | } | 1260 | } |
1233 | 1261 | ||
@@ -1256,7 +1284,9 @@ maint_child_death (void *cls) | |||
1256 | GNUNET_DISK_PIPE_END_READ); | 1284 | GNUNET_DISK_PIPE_END_READ); |
1257 | child_death_task = NULL; | 1285 | child_death_task = NULL; |
1258 | /* consume the signal */ | 1286 | /* consume the signal */ |
1259 | GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c))); | 1287 | GNUNET_break (0 < GNUNET_DISK_file_read (pr, |
1288 | &c, | ||
1289 | sizeof (c))); | ||
1260 | 1290 | ||
1261 | /* check for services that died (WAITPID) */ | 1291 | /* check for services that died (WAITPID) */ |
1262 | next = running_head; | 1292 | next = running_head; |
@@ -1376,7 +1406,6 @@ maint_child_death (void *cls) | |||
1376 | signal_result (pos->killing_client, pos->name, | 1406 | signal_result (pos->killing_client, pos->name, |
1377 | pos->killing_client_request_id, | 1407 | pos->killing_client_request_id, |
1378 | GNUNET_ARM_RESULT_STOPPED); | 1408 | GNUNET_ARM_RESULT_STOPPED); |
1379 | GNUNET_SERVER_client_drop (pos->killing_client); | ||
1380 | pos->killing_client = NULL; | 1409 | pos->killing_client = NULL; |
1381 | pos->killing_client_request_id = 0; | 1410 | pos->killing_client_request_id = 0; |
1382 | } | 1411 | } |
@@ -1451,9 +1480,10 @@ sighandler_child_death () | |||
1451 | int old_errno = errno; /* back-up errno */ | 1480 | int old_errno = errno; /* back-up errno */ |
1452 | 1481 | ||
1453 | GNUNET_break (1 == | 1482 | GNUNET_break (1 == |
1454 | GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle | 1483 | GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (sigpipe, |
1455 | (sigpipe, GNUNET_DISK_PIPE_END_WRITE), | 1484 | GNUNET_DISK_PIPE_END_WRITE), |
1456 | &c, sizeof (c))); | 1485 | &c, |
1486 | sizeof (c))); | ||
1457 | errno = old_errno; /* restore errno */ | 1487 | errno = old_errno; /* restore errno */ |
1458 | } | 1488 | } |
1459 | 1489 | ||
@@ -1479,7 +1509,8 @@ setup_service (void *cls, | |||
1479 | int ret; | 1509 | int ret; |
1480 | unsigned int i; | 1510 | unsigned int i; |
1481 | 1511 | ||
1482 | if (strcasecmp (section, "arm") == 0) | 1512 | if (0 == strcasecmp (section, |
1513 | "arm")) | ||
1483 | return; | 1514 | return; |
1484 | if (GNUNET_OK != | 1515 | if (GNUNET_OK != |
1485 | GNUNET_CONFIGURATION_get_value_filename (cfg, | 1516 | GNUNET_CONFIGURATION_get_value_filename (cfg, |
@@ -1597,46 +1628,71 @@ setup_service (void *cls, | |||
1597 | 1628 | ||
1598 | 1629 | ||
1599 | /** | 1630 | /** |
1600 | * A client connected, add it to the notification context. | 1631 | * A client connected, mark as a monitoring client. |
1601 | * | 1632 | * |
1602 | * @param cls closure | 1633 | * @param cls closure |
1603 | * @param client identification of the client | 1634 | * @param client identification of the client |
1635 | * @param mq queue to talk to @a client | ||
1636 | * @return @a client | ||
1604 | */ | 1637 | */ |
1605 | static void | 1638 | static void * |
1606 | handle_client_connecting (void *cls, | 1639 | client_connect_cb (void *cls, |
1607 | struct GNUNET_SERVER_Client *client) | 1640 | struct GNUNET_SERVICE_Client *client, |
1641 | struct GNUNET_MQ_Handle *mq) | ||
1608 | { | 1642 | { |
1609 | /* All clients are considered to be of the "monitor" kind | 1643 | /* All clients are considered to be of the "monitor" kind |
1610 | * (that is, they don't affect ARM shutdown). | 1644 | * (that is, they don't affect ARM shutdown). |
1611 | */ | 1645 | */ |
1612 | if (NULL != client) | 1646 | GNUNET_SERVICE_client_mark_monitor (client); |
1613 | GNUNET_SERVER_client_mark_monitor (client); | 1647 | return client; |
1614 | } | 1648 | } |
1615 | 1649 | ||
1616 | 1650 | ||
1617 | /** | 1651 | /** |
1618 | * Handle MONITOR-message. | 1652 | * A client disconnected, clean up associated state. |
1619 | * | 1653 | * |
1620 | * @param cls closure (always NULL) | 1654 | * @param cls closure |
1621 | * @param client identification of the client | 1655 | * @param client identification of the client |
1656 | * @param app_ctx must match @a client | ||
1657 | */ | ||
1658 | static void | ||
1659 | client_disconnect_cb (void *cls, | ||
1660 | struct GNUNET_SERVICE_Client *client, | ||
1661 | void *app_ctx) | ||
1662 | { | ||
1663 | struct ServiceList *sl; | ||
1664 | |||
1665 | GNUNET_assert (client == app_ctx); | ||
1666 | |||
1667 | for (sl = running_head; NULL != sl; sl = sl->next) | ||
1668 | if (sl->killing_client == client) | ||
1669 | sl->killing_client = NULL; | ||
1670 | } | ||
1671 | |||
1672 | |||
1673 | /** | ||
1674 | * Handle MONITOR-message. | ||
1675 | * | ||
1676 | * @param cls identification of the client | ||
1622 | * @param message the actual message | 1677 | * @param message the actual message |
1623 | * @return #GNUNET_OK to keep the connection open, | 1678 | * @return #GNUNET_OK to keep the connection open, |
1624 | * #GNUNET_SYSERR to close it (signal serious error) | 1679 | * #GNUNET_SYSERR to close it (signal serious error) |
1625 | */ | 1680 | */ |
1626 | static void | 1681 | static void |
1627 | handle_monitor (void *cls, | 1682 | handle_monitor (void *cls, |
1628 | struct GNUNET_SERVER_Client *client, | ||
1629 | const struct GNUNET_MessageHeader *message) | 1683 | const struct GNUNET_MessageHeader *message) |
1630 | { | 1684 | { |
1685 | struct GNUNET_SERVICE_Client *client = cls; | ||
1686 | |||
1631 | /* FIXME: might want to start by letting monitor know about | 1687 | /* FIXME: might want to start by letting monitor know about |
1632 | services that are already running */ | 1688 | services that are already running */ |
1633 | /* Removal is handled by the server implementation, internally. */ | 1689 | /* Removal is handled by the server implementation, internally. */ |
1634 | if ((NULL != client) && (NULL != notifier)) | 1690 | GNUNET_notification_context_add (notifier, |
1635 | { | 1691 | GNUNET_SERVICE_client_get_mq (client)); |
1636 | GNUNET_SERVER_notification_context_add (notifier, client); | 1692 | broadcast_status ("arm", |
1637 | broadcast_status ("arm", GNUNET_ARM_SERVICE_MONITORING_STARTED, client); | 1693 | GNUNET_ARM_SERVICE_MONITORING_STARTED, |
1638 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1694 | client); |
1639 | } | 1695 | GNUNET_SERVICE_client_continue (client); |
1640 | } | 1696 | } |
1641 | 1697 | ||
1642 | 1698 | ||
@@ -1644,34 +1700,26 @@ handle_monitor (void *cls, | |||
1644 | * Process arm requests. | 1700 | * Process arm requests. |
1645 | * | 1701 | * |
1646 | * @param cls closure | 1702 | * @param cls closure |
1647 | * @param serv the initialized server | 1703 | * @param serv the initialized service |
1648 | * @param c configuration to use | 1704 | * @param c configuration to use |
1649 | */ | 1705 | */ |
1650 | static void | 1706 | static void |
1651 | run (void *cls, struct GNUNET_SERVER_Handle *serv, | 1707 | run (void *cls, |
1652 | const struct GNUNET_CONFIGURATION_Handle *c) | 1708 | const struct GNUNET_CONFIGURATION_Handle *c, |
1709 | struct GNUNET_SERVICE_Handle *serv) | ||
1653 | { | 1710 | { |
1654 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { | ||
1655 | {&handle_start, NULL, GNUNET_MESSAGE_TYPE_ARM_START, 0}, | ||
1656 | {&handle_stop, NULL, GNUNET_MESSAGE_TYPE_ARM_STOP, 0}, | ||
1657 | {&handle_monitor, NULL, GNUNET_MESSAGE_TYPE_ARM_MONITOR, | ||
1658 | sizeof (struct GNUNET_MessageHeader)}, | ||
1659 | {&handle_list, NULL, GNUNET_MESSAGE_TYPE_ARM_LIST, | ||
1660 | sizeof (struct GNUNET_ARM_Message)}, | ||
1661 | {NULL, NULL, 0, 0} | ||
1662 | }; | ||
1663 | struct ServiceList *sl; | 1711 | struct ServiceList *sl; |
1664 | 1712 | ||
1665 | cfg = c; | 1713 | cfg = c; |
1666 | server = serv; | 1714 | service = serv; |
1667 | GNUNET_assert (NULL != serv); | ||
1668 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, | 1715 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, |
1669 | NULL); | 1716 | NULL); |
1670 | child_death_task = | 1717 | child_death_task = |
1671 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | 1718 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, |
1672 | GNUNET_DISK_pipe_handle (sigpipe, | 1719 | GNUNET_DISK_pipe_handle (sigpipe, |
1673 | GNUNET_DISK_PIPE_END_READ), | 1720 | GNUNET_DISK_PIPE_END_READ), |
1674 | &maint_child_death, NULL); | 1721 | &maint_child_death, |
1722 | NULL); | ||
1675 | #if HAVE_WAIT4 | 1723 | #if HAVE_WAIT4 |
1676 | if (GNUNET_OK == | 1724 | if (GNUNET_OK == |
1677 | GNUNET_CONFIGURATION_get_value_filename (cfg, | 1725 | GNUNET_CONFIGURATION_get_value_filename (cfg, |
@@ -1717,20 +1765,17 @@ run (void *cls, struct GNUNET_SERVER_Handle *serv, | |||
1717 | GNUNET_break (GNUNET_YES == start_system); | 1765 | GNUNET_break (GNUNET_YES == start_system); |
1718 | start_user = GNUNET_NO; | 1766 | start_user = GNUNET_NO; |
1719 | } | 1767 | } |
1720 | GNUNET_CONFIGURATION_iterate_sections (cfg, &setup_service, NULL); | 1768 | GNUNET_CONFIGURATION_iterate_sections (cfg, |
1769 | &setup_service, | ||
1770 | NULL); | ||
1721 | 1771 | ||
1722 | /* start default services... */ | 1772 | /* start default services... */ |
1723 | for (sl = running_head; NULL != sl; sl = sl->next) | 1773 | for (sl = running_head; NULL != sl; sl = sl->next) |
1724 | if (GNUNET_YES == sl->force_start) | 1774 | if (GNUNET_YES == sl->force_start) |
1725 | start_process (sl, NULL, 0); | 1775 | start_process (sl, |
1726 | notifier | 1776 | NULL, |
1727 | = GNUNET_SERVER_notification_context_create (server, | 1777 | 0); |
1728 | MAX_NOTIFY_QUEUE); | 1778 | notifier = GNUNET_notification_context_create (MAX_NOTIFY_QUEUE); |
1729 | GNUNET_SERVER_connect_notify (server, | ||
1730 | &handle_client_connecting, NULL); | ||
1731 | /* process client requests */ | ||
1732 | GNUNET_SERVER_add_handlers (server, | ||
1733 | handlers); | ||
1734 | } | 1779 | } |
1735 | 1780 | ||
1736 | 1781 | ||
@@ -1742,19 +1787,52 @@ run (void *cls, struct GNUNET_SERVER_Handle *serv, | |||
1742 | * @return 0 ok, 1 on error | 1787 | * @return 0 ok, 1 on error |
1743 | */ | 1788 | */ |
1744 | int | 1789 | int |
1745 | main (int argc, char *const *argv) | 1790 | main (int argc, |
1791 | char *const *argv) | ||
1746 | { | 1792 | { |
1747 | int ret; | 1793 | int ret; |
1748 | struct GNUNET_SIGNAL_Context *shc_chld; | 1794 | struct GNUNET_SIGNAL_Context *shc_chld; |
1795 | struct GNUNET_MQ_MessageHandler handlers[] = { | ||
1796 | GNUNET_MQ_hd_var_size (start, | ||
1797 | GNUNET_MESSAGE_TYPE_ARM_START, | ||
1798 | struct GNUNET_ARM_Message, | ||
1799 | NULL), | ||
1800 | GNUNET_MQ_hd_var_size (stop, | ||
1801 | GNUNET_MESSAGE_TYPE_ARM_STOP, | ||
1802 | struct GNUNET_ARM_Message, | ||
1803 | NULL), | ||
1804 | GNUNET_MQ_hd_fixed_size (monitor, | ||
1805 | GNUNET_MESSAGE_TYPE_ARM_MONITOR, | ||
1806 | struct GNUNET_MessageHeader, | ||
1807 | NULL), | ||
1808 | GNUNET_MQ_hd_fixed_size (list, | ||
1809 | GNUNET_MESSAGE_TYPE_ARM_LIST, | ||
1810 | struct GNUNET_ARM_Message, | ||
1811 | NULL), | ||
1812 | GNUNET_MQ_hd_fixed_size (test, | ||
1813 | GNUNET_MESSAGE_TYPE_ARM_TEST, | ||
1814 | struct GNUNET_MessageHeader, | ||
1815 | NULL), | ||
1816 | GNUNET_MQ_handler_end () | ||
1817 | }; | ||
1749 | 1818 | ||
1750 | sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO); | 1819 | sigpipe = GNUNET_DISK_pipe (GNUNET_NO, |
1751 | GNUNET_assert (sigpipe != NULL); | 1820 | GNUNET_NO, |
1821 | GNUNET_NO, | ||
1822 | GNUNET_NO); | ||
1823 | GNUNET_assert (NULL != sigpipe); | ||
1752 | shc_chld = | 1824 | shc_chld = |
1753 | GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death); | 1825 | GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, |
1754 | ret = | 1826 | &sighandler_child_death); |
1755 | (GNUNET_OK == | 1827 | ret = GNUNET_SERVICE_ruN_ (argc, |
1756 | GNUNET_SERVICE_run (argc, argv, "arm", | 1828 | argv, |
1757 | GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN, &run, NULL)) ? 0 : 1; | 1829 | "arm", |
1830 | GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN, | ||
1831 | &run, | ||
1832 | &client_connect_cb, | ||
1833 | &client_disconnect_cb, | ||
1834 | NULL, | ||
1835 | handlers); | ||
1758 | #if HAVE_WAIT4 | 1836 | #if HAVE_WAIT4 |
1759 | if (NULL != wait_file) | 1837 | if (NULL != wait_file) |
1760 | { | 1838 | { |