diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-06-23 14:22:34 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-06-23 14:22:34 +0000 |
commit | 5742938289524f4c5fba7883742e4dd69cccf11d (patch) | |
tree | e16fea8b9d778f9825f897237b0c1880305776a0 | |
parent | f3edb5a8d6ba6f43f5df18f2e98bc1dae90c9d7a (diff) |
refactoring ARM api to use new MQ
-rw-r--r-- | src/arm/arm_api.c | 1219 | ||||
-rw-r--r-- | src/arm/arm_monitor_api.c | 13 | ||||
-rw-r--r-- | src/arm/gnunet-arm.c | 159 | ||||
-rw-r--r-- | src/arm/test_arm_api.c | 109 | ||||
-rw-r--r-- | src/arm/test_exponential_backoff.c | 70 | ||||
-rw-r--r-- | src/arm/test_gnunet_service_arm.c | 36 | ||||
-rw-r--r-- | src/include/gnunet_arm_service.h | 109 | ||||
-rw-r--r-- | src/include/gnunet_testbed_logger_service.h | 7 | ||||
-rw-r--r-- | src/include/gnunet_testing_lib.h | 18 | ||||
-rw-r--r-- | src/testbed/gnunet-service-testbed_peers.c | 276 | ||||
-rw-r--r-- | src/testbed/test_testbed_api.c | 8 | ||||
-rw-r--r-- | src/testbed/test_testbed_logger_api.c | 87 | ||||
-rw-r--r-- | src/testing/testing.c | 67 |
13 files changed, 1066 insertions, 1112 deletions
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c index a89d423ecd..ed36c61cd5 100644 --- a/src/arm/arm_api.c +++ b/src/arm/arm_api.c @@ -32,151 +32,131 @@ #define LOG(kind,...) GNUNET_log_from (kind, "arm-api",__VA_ARGS__) + /** - * Handle for interacting with ARM. + * Entry in a doubly-linked list of operations awaiting for replies + * (in-order) from the ARM service. */ -struct GNUNET_ARM_Handle +struct GNUNET_ARM_Operation { /** - * Our control connection to the ARM service. - */ - struct GNUNET_CLIENT_Connection *client; - - /** - * The configuration that we are using. - */ - struct GNUNET_CONFIGURATION_Handle *cfg; - - /** - * Handle for our current transmission request. - */ - struct GNUNET_CLIENT_TransmitHandle *cth; - - /** - * Head of doubly-linked list of pending requests. - */ - struct ARMControlMessage *control_pending_head; - - /** - * Tail of doubly-linked list of pending requests. - */ - struct ARMControlMessage *control_pending_tail; - - /** - * Head of doubly-linked list of sent requests. + * This is a doubly-linked list. */ - struct ARMControlMessage *control_sent_head; + struct GNUNET_ARM_Operation *next; /** - * Tail of doubly-linked list of sent requests. + * This is a doubly-linked list. */ - struct ARMControlMessage *control_sent_tail; + struct GNUNET_ARM_Operation *prev; /** - * Callback to invoke on connection/disconnection. + * ARM handle. */ - GNUNET_ARM_ConnectionStatusCallback conn_status; + struct GNUNET_ARM_Handle *h; /** - * Closure for conn_status. + * Callback for service state change requests. */ - void *conn_status_cls; + GNUNET_ARM_ResultCallback result_cont; /** - * ARM control message for the 'arm_termination_handler' - * with the continuation to call once the ARM shutdown is done. + * Callback for service list requests. */ - struct ARMControlMessage *thm; + GNUNET_ARM_ServiceListCallback list_cont; /** - * ID of the reconnect task (if any). + * Closure for @e result_cont or @e list_cont. */ - struct GNUNET_SCHEDULER_Task *reconnect_task; + void *cont_cls; /** - * Current delay we use for re-trying to connect to core. + * Task for async completion. */ - struct GNUNET_TIME_Relative retry_backoff; + struct GNUNET_SCHEDULER_Task *async; /** - * Counter for request identifiers + * Unique ID for the request. */ - uint64_t request_id_counter; + uint64_t id; /** - * Are we currently disconnected and hence unable to send? + * Result of this operation for #notify_starting(). */ - unsigned char currently_down; + enum GNUNET_ARM_Result starting_ret; /** - * #GNUNET_YES if we're running a service test. + * Is this an operation to stop the ARM service? */ - unsigned char service_test_is_active; + int is_arm_stop; }; /** - * Entry in a doubly-linked list of control messages to be transmitted - * to the arm service. - * - * The actual message is allocated at the end of this struct. + * Handle for interacting with ARM. */ -struct ARMControlMessage +struct GNUNET_ARM_Handle { /** - * This is a doubly-linked list. + * Our connection to the ARM service. */ - struct ARMControlMessage *next; + struct GNUNET_MQ_Handle *mq; /** - * This is a doubly-linked list. + * The configuration that we are using. */ - struct ARMControlMessage *prev; + const struct GNUNET_CONFIGURATION_Handle *cfg; /** - * ARM handle. + * Head of doubly-linked list of pending operations. */ - struct GNUNET_ARM_Handle *h; + struct GNUNET_ARM_Operation *operation_pending_head; /** - * Message to send. + * Tail of doubly-linked list of pending operations. */ - struct GNUNET_ARM_Message *msg; + struct GNUNET_ARM_Operation *operation_pending_tail; /** - * Callback for service state change requests. + * Callback to invoke on connection/disconnection. */ - GNUNET_ARM_ResultCallback result_cont; + GNUNET_ARM_ConnectionStatusCallback conn_status; /** - * Callback for service list requests. + * Closure for @e conn_status. */ - GNUNET_ARM_ServiceListCallback list_cont; + void *conn_status_cls; /** - * Closure for @e result_cont or @e list_cont. + * ARM operation where the goal is to wait for ARM shutdown to + * complete. This operation is special in that it waits for an + * error on the @e mq. So we complete it by calling the + * continuation in the #mq_error_handler(). Note that the operation + * is no longer in the @e operation_pending_head DLL once it is + * referenced from this field. */ - void *cont_cls; + struct GNUNET_ARM_Operation *thm; /** - * Timeout for the operation. + * ID of the reconnect task (if any). */ - struct GNUNET_TIME_Absolute timeout; + struct GNUNET_SCHEDULER_Task *reconnect_task; /** - * Task to run when request times out. + * Current delay we use for re-trying to connect to core. */ - struct GNUNET_SCHEDULER_Task *timeout_task_id; + struct GNUNET_TIME_Relative retry_backoff; /** - * Flags for passing std descriptors to ARM (when starting ARM). + * Counter for request identifiers. They are used to match replies + * from ARM to operations in the @e operation_pending_head DLL. */ - enum GNUNET_OS_InheritStdioFlags std_inheritance; + uint64_t request_id_counter; /** - * Type of the request expressed as a message type (start, stop or list). + * Have we detected that ARM is up? */ - uint16_t type; + int currently_up; + }; @@ -191,18 +171,6 @@ reconnect_arm (struct GNUNET_ARM_Handle *h); /** - * Check the list of pending requests, send the next - * one to the arm. - * - * @param h arm handle - * @param ignore_currently_down transmit message even if not initialized? - */ -static void -trigger_next_request (struct GNUNET_ARM_Handle *h, - int ignore_currently_down); - - -/** * Task scheduled to try to re-connect to arm. * * @param cls the `struct GNUNET_ARM_Handle` @@ -213,8 +181,6 @@ reconnect_arm_task (void *cls) struct GNUNET_ARM_Handle *h = cls; h->reconnect_task = NULL; - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Connecting to ARM service after delay\n"); reconnect_arm (h); } @@ -228,28 +194,33 @@ reconnect_arm_task (void *cls) static void reconnect_arm_later (struct GNUNET_ARM_Handle *h) { - if (GNUNET_NO != h->currently_down) - return; - if (NULL != h->cth) - { - GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth); - h->cth = NULL; - } - if (NULL != h->client) + struct GNUNET_ARM_Operation *op; + + if (NULL != h->mq) { - GNUNET_CLIENT_disconnect (h->client); - h->client = NULL; + GNUNET_MQ_destroy (h->mq); + h->mq = NULL; } - h->currently_down = GNUNET_YES; + h->currently_up = GNUNET_NO; GNUNET_assert (NULL == h->reconnect_task); h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->retry_backoff, &reconnect_arm_task, h); - /* Don't clear pending messages on disconnection, deliver them later - clear_pending_messages (h, GNUNET_ARM_REQUEST_DISCONNECTED); - GNUNET_assert (NULL == h->control_pending_head); - */ + while (NULL != (op = h->operation_pending_head)) + { + if (NULL != op->result_cont) + op->result_cont (op->cont_cls, + GNUNET_ARM_REQUEST_DISCONNECTED, + 0); + if (NULL != op->list_cont) + op->list_cont (op->cont_cls, + GNUNET_ARM_REQUEST_DISCONNECTED, + 0, + NULL); + GNUNET_ARM_operation_cancel (op); + } + GNUNET_assert (NULL == h->operation_pending_head); h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); if (NULL != h->conn_status) h->conn_status (h->conn_status_cls, @@ -264,176 +235,50 @@ reconnect_arm_later (struct GNUNET_ARM_Handle *h) * @param id unique message ID to use for the lookup * @return NULL if not found */ -static struct ARMControlMessage * -find_cm_by_id (struct GNUNET_ARM_Handle *h, +static struct GNUNET_ARM_Operation * +find_op_by_id (struct GNUNET_ARM_Handle *h, uint64_t id) { - struct ARMControlMessage *result; + struct GNUNET_ARM_Operation *result; - for (result = h->control_sent_head; NULL != result; result = result->next) - if (id == result->msg->request_id) + for (result = h->operation_pending_head; NULL != result; result = result->next) + if (id == result->id) return result; return NULL; } /** - * Handler for ARM 'termination' reply (failure to receive). - * - * @param cls our `struct GNUNET_ARM_Handle` - * @param msg expected to be NULL - */ -static void -arm_termination_handler (void *cls, - const struct GNUNET_MessageHeader *msg) -{ - struct GNUNET_ARM_Handle *h = cls; - struct ARMControlMessage *cm; - - if (NULL != msg) - { - GNUNET_break (0); - GNUNET_CLIENT_receive (h->client, - &arm_termination_handler, - h, - GNUNET_TIME_UNIT_FOREVER_REL); - return; - } - cm = h->thm; - h->thm = NULL; - h->currently_down = GNUNET_YES; - GNUNET_CLIENT_disconnect (h->client); - h->client = NULL; - if (NULL != cm->result_cont) - cm->result_cont (cm->cont_cls, - GNUNET_ARM_REQUEST_SENT_OK, - (const char *) &cm->msg[1], - GNUNET_ARM_RESULT_STOPPED); - GNUNET_free (cm->msg); - GNUNET_free (cm); -} - - -/** * Handler for ARM replies. * * @param cls our `struct GNUNET_ARM_Handle` - * @param msg the message received from the arm service + * @param res the message received from the arm service */ static void -client_notify_handler (void *cls, - const struct GNUNET_MessageHeader *msg) +handle_arm_result (void *cls, + const struct GNUNET_ARM_ResultMessage *res) { struct GNUNET_ARM_Handle *h = cls; - const struct GNUNET_ARM_Message *arm_msg; - const struct GNUNET_ARM_ResultMessage *res; - const struct GNUNET_ARM_ListResultMessage *lres; - struct ARMControlMessage *cm; - const char **list; - const char *pos; + struct GNUNET_ARM_Operation *op; uint64_t id; enum GNUNET_ARM_Result result; - uint16_t size_check; - uint16_t rcount; - uint16_t msize; - unsigned char fail; + GNUNET_ARM_ResultCallback result_cont; + void *result_cont_cls; - list = NULL; - rcount = 0; - if (NULL == msg) - { - LOG (GNUNET_ERROR_TYPE_INFO, - _("Client was disconnected from arm service, trying to reconnect.\n")); - reconnect_arm_later (h); - return; - } - msize = ntohs (msg->size); - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Processing message of type %u and size %u from arm service\n", - ntohs (msg->type), msize); - if (msize < sizeof (struct GNUNET_ARM_Message)) - { - GNUNET_break (0); - reconnect_arm_later (h); - return; - } - arm_msg = (const struct GNUNET_ARM_Message *) msg; - GNUNET_break (0 == ntohl (arm_msg->reserved)); - id = GNUNET_ntohll (arm_msg->request_id); - cm = find_cm_by_id (h, id); - if (NULL == cm) + id = GNUNET_ntohll (res->arm_msg.request_id); + op = find_op_by_id (h, + id); + if (NULL == op) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Message with unknown id %llu\n", - id); - return; - } - fail = GNUNET_NO; - switch (ntohs (msg->type)) - { - case GNUNET_MESSAGE_TYPE_ARM_RESULT: - if (msize < sizeof (struct GNUNET_ARM_ResultMessage)) - { - GNUNET_assert (0); - fail = GNUNET_YES; - } - break; - case GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT: - if (msize < sizeof (struct GNUNET_ARM_ListResultMessage)) - { - GNUNET_break (0); - fail = GNUNET_YES; - break; - } - size_check = 0; - lres = (const struct GNUNET_ARM_ListResultMessage *) msg; - rcount = ntohs (lres->count); - { - unsigned int i; - - list = GNUNET_malloc (sizeof (const char *) * rcount); - pos = (const char *)&lres[1]; - for (i = 0; i < rcount; i++) - { - const char *end = memchr (pos, 0, msize - size_check); - if (NULL == end) - { - GNUNET_break (0); - fail = GNUNET_YES; - break; - } - list[i] = pos; - size_check += (end - pos) + 1; - pos = end + 1; - } - if (GNUNET_YES == fail) - { - GNUNET_free (list); - list = NULL; - } - } - break; - default: - fail = GNUNET_YES; - break; - } - GNUNET_assert (NULL != cm->timeout_task_id); - GNUNET_SCHEDULER_cancel (cm->timeout_task_id); - GNUNET_CONTAINER_DLL_remove (h->control_sent_head, - h->control_sent_tail, - cm); - if (GNUNET_YES == fail) - { - reconnect_arm_later (h); - GNUNET_free (cm->msg); - GNUNET_free (cm); + (unsigned long long) id); return; } - if ( (GNUNET_MESSAGE_TYPE_ARM_RESULT == ntohs (msg->type)) && - (0 == strcasecmp ((const char *) &cm->msg[1], - "arm")) && - (NULL != (res = (const struct GNUNET_ARM_ResultMessage *) msg)) && - (GNUNET_ARM_RESULT_STOPPING == ntohl (res->result)) ) + + result = (enum GNUNET_ARM_Result) ntohl (res->result); + if ( (GNUNET_YES == op->is_arm_stop) && + (GNUNET_ARM_RESULT_STOPPING == result) ) { /* special case: if we are stopping 'gnunet-service-arm', we do not just wait for the result message, but also wait for the service to close @@ -443,184 +288,159 @@ client_notify_handler (void *cls, if (NULL != h->thm) { GNUNET_break (0); - cm->result_cont (h->thm->cont_cls, + op->result_cont (h->thm->cont_cls, GNUNET_ARM_REQUEST_SENT_OK, - (const char *) &h->thm->msg[1], GNUNET_ARM_RESULT_IS_NOT_KNOWN); - GNUNET_free (h->thm->msg); GNUNET_free (h->thm); } - h->thm = cm; - GNUNET_CLIENT_receive (h->client, - &arm_termination_handler, - h, - GNUNET_TIME_UNIT_FOREVER_REL); + GNUNET_CONTAINER_DLL_remove (h->operation_pending_head, + h->operation_pending_tail, + op); + h->thm = op; return; } - GNUNET_CLIENT_receive (h->client, - &client_notify_handler, - h, - GNUNET_TIME_UNIT_FOREVER_REL); - switch (ntohs (msg->type)) - { - case GNUNET_MESSAGE_TYPE_ARM_RESULT: - res = (const struct GNUNET_ARM_ResultMessage *) msg; - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Received response from ARM for service `%s': %u\n", - (const char *) &cm->msg[1], ntohs (msg->type)); - result = (enum GNUNET_ARM_Result) ntohl (res->result); - if (NULL != cm->result_cont) - cm->result_cont (cm->cont_cls, - GNUNET_ARM_REQUEST_SENT_OK, - (const char *) &cm->msg[1], - result); - break; - case GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT: - if (NULL != cm->list_cont) - cm->list_cont (cm->cont_cls, - GNUNET_ARM_REQUEST_SENT_OK, - rcount, - list); - GNUNET_free_non_null (list); - break; - } - GNUNET_free (cm->msg); - GNUNET_free (cm); + result_cont = op->result_cont; + result_cont_cls = op->cont_cls; + GNUNET_ARM_operation_cancel (op); + if (NULL != result_cont) + result_cont (result_cont_cls, + GNUNET_ARM_REQUEST_SENT_OK, + result); } /** - * Transmit the next message to the arm service. + * Checked that list result message is well-formed. * - * @param cls closure with the `struct GNUNET_ARM_Handle` - * @param size number of bytes available in @a buf - * @param buf where the callee should write the message - * @return number of bytes written to @a buf + * @param cls our `struct GNUNET_ARM_Handle` + * @param lres the message received from the arm service + * @return #GNUNET_OK if message is well-formed */ -static size_t -transmit_arm_message (void *cls, - size_t size, - void *buf) +static int +check_arm_list_result (void *cls, + const struct GNUNET_ARM_ListResultMessage *lres) { - struct GNUNET_ARM_Handle *h = cls; - struct ARMControlMessage *cm; - struct GNUNET_ARM_Message *arm_msg; - uint64_t request_id; - int notify_connection; - uint16_t msize; + const char *pos = (const char *) &lres[1]; + uint16_t rcount = ntohs (lres->count); + uint16_t msize = ntohs (lres->arm_msg.header.size); + uint16_t size_check; - notify_connection = GNUNET_NO; - LOG (GNUNET_ERROR_TYPE_DEBUG, - "transmit_arm_message is running with %p buffer of size %lu. ARM is known to be %s\n", - buf, size, h->currently_down ? "unconnected" : "connected"); - GNUNET_assert (NULL == h->reconnect_task); - h->cth = NULL; - if ((GNUNET_YES == h->currently_down) && (NULL != buf)) - { - h->currently_down = GNUNET_NO; - notify_connection = GNUNET_YES; - h->retry_backoff = GNUNET_TIME_UNIT_MILLISECONDS; - GNUNET_CLIENT_receive (h->client, &client_notify_handler, h, - GNUNET_TIME_UNIT_FOREVER_REL); - } - if (NULL == buf) + size_check = 0; + for (unsigned int i = 0; i < rcount; i++) { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Transmission failed, initiating reconnect\n"); - reconnect_arm_later (h); - return 0; - } - if (NULL == (cm = h->control_pending_head)) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Queue is empty, not sending anything\n"); - msize = 0; - goto end; - } - GNUNET_assert (NULL != cm->msg); - msize = ntohs (cm->msg->header.size); - if (size < msize) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Request is too big (%u < %u), not sending it\n", size, msize); - trigger_next_request (h, GNUNET_NO); - msize = 0; - goto end; + const char *end = memchr (pos, 0, msize - size_check); + if (NULL == end) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + size_check += (end - pos) + 1; + pos = end + 1; } - arm_msg = cm->msg; - if (0 == h->request_id_counter) - h->request_id_counter++; - request_id = h->request_id_counter++; - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Transmitting control message with %u bytes of type %u to arm with id %llu\n", - (unsigned int) msize, - (unsigned int) ntohs (cm->msg->header.type), - request_id); - arm_msg->reserved = htonl (0); - arm_msg->request_id = GNUNET_htonll (request_id); - memcpy (buf, cm->msg, msize); - /* Otherwise we won't be able to find it later! */ - arm_msg->request_id = request_id; - GNUNET_CONTAINER_DLL_remove (h->control_pending_head, - h->control_pending_tail, - cm); - GNUNET_CONTAINER_DLL_insert_tail (h->control_sent_head, - h->control_sent_tail, - cm); - /* Don't free msg, keep it around (kind of wasteful, but then we don't - * really have many messages to handle, and it'll be freed when it times - * out anyway. - */ - trigger_next_request (h, GNUNET_NO); - - end: - if ((GNUNET_YES == notify_connection) && (NULL != h->conn_status)) - h->conn_status (h->conn_status_cls, GNUNET_YES); - return msize; + return GNUNET_OK; } /** - * Check the list of pending requests, send the next - * one to the arm. + * Handler for ARM list replies. * - * @param h arm handle - * @param ignore_currently_down transmit message even if not initialized? + * @param cls our `struct GNUNET_ARM_Handle` + * @param lres the message received from the arm service */ static void -trigger_next_request (struct GNUNET_ARM_Handle *h, - int ignore_currently_down) +handle_arm_list_result (void *cls, + const struct GNUNET_ARM_ListResultMessage *lres) { - uint16_t msize; + struct GNUNET_ARM_Handle *h = cls; + uint16_t rcount = ntohs (lres->count); + const char *list[rcount]; + const char *pos = (const char *) &lres[1]; + uint16_t msize = ntohs (lres->arm_msg.header.size); + struct GNUNET_ARM_Operation *op; + uint16_t size_check; + uint64_t id; - msize = sizeof (struct GNUNET_MessageHeader); - if ((GNUNET_YES == h->currently_down) && (ignore_currently_down == GNUNET_NO)) + id = GNUNET_ntohll (lres->arm_msg.request_id); + op = find_op_by_id (h, + id); + if (NULL == op) { LOG (GNUNET_ERROR_TYPE_DEBUG, - "ARM connection down, not processing queue\n"); + "Message with unknown id %llu\n", + (unsigned long long) id); return; } - if (NULL != h->cth) + size_check = 0; + for (unsigned int i = 0; i < rcount; i++) + { + const char *end = memchr (pos, + 0, + msize - size_check); + + /* Assert, as this was already checked in #check_arm_list_result() */ + GNUNET_assert (NULL != end); + list[i] = pos; + size_check += (end - pos) + 1; + pos = end + 1; + } + if (NULL != op->list_cont) + op->list_cont (op->cont_cls, + GNUNET_ARM_REQUEST_SENT_OK, + rcount, + list); + GNUNET_ARM_operation_cancel (op); +} + + +/** + * Receive confirmation from test, ARM service is up. + * + * @param cls closure with the `struct GNUNET_ARM_Handle` + * @param msg message received + */ +static void +handle_confirm (void *cls, + const struct GNUNET_MessageHeader *msg) +{ + struct GNUNET_ARM_Handle *h = cls; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Got confirmation from ARM that we are up!\n"); + if (GNUNET_NO == h->currently_up) { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Request pending, not processing queue\n"); - return; + h->currently_up = GNUNET_YES; + if (NULL != h->conn_status) + h->conn_status (h->conn_status_cls, + GNUNET_YES); } - if (NULL != h->control_pending_head) - msize = - ntohs (h->control_pending_head->msg->header.size); - else if (GNUNET_NO == ignore_currently_down) +} + + +/** + * Generic error handler, called with the appropriate error code and + * the same closure specified at the creation of the message queue. + * Not every message queue implementation supports an error handler. + * + * @param cls closure with the `struct GNUNET_ARM_Handle *` + * @param error error code + */ +static void +mq_error_handler (void *cls, + enum GNUNET_MQ_Error error) +{ + struct GNUNET_ARM_Handle *h = cls; + struct GNUNET_ARM_Operation *op; + + h->currently_up = GNUNET_NO; + if (NULL != (op = h->thm)) { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Request queue empty, not processing queue\n"); - return; /* no pending message */ + h->thm = NULL; + op->result_cont (op->cont_cls, + GNUNET_ARM_REQUEST_SENT_OK, + GNUNET_ARM_RESULT_STOPPED); + GNUNET_free (op); } - h->cth = - GNUNET_CLIENT_notify_transmit_ready (h->client, - msize, - GNUNET_TIME_UNIT_FOREVER_REL, - GNUNET_NO, - &transmit_arm_message, h); + reconnect_arm_later (h); } @@ -633,22 +453,47 @@ trigger_next_request (struct GNUNET_ARM_Handle *h, static int reconnect_arm (struct GNUNET_ARM_Handle *h) { - GNUNET_assert (NULL == h->client); - GNUNET_assert (GNUNET_YES == h->currently_down); - h->client = GNUNET_CLIENT_connect ("arm", h->cfg); - if (NULL == h->client) + GNUNET_MQ_hd_fixed_size (arm_result, + GNUNET_MESSAGE_TYPE_ARM_RESULT, + struct GNUNET_ARM_ResultMessage); + GNUNET_MQ_hd_var_size (arm_list_result, + GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT, + struct GNUNET_ARM_ListResultMessage); + GNUNET_MQ_hd_fixed_size (confirm, + GNUNET_MESSAGE_TYPE_TEST, + struct GNUNET_MessageHeader); + struct GNUNET_MQ_MessageHandler handlers[] = { + make_arm_result_handler (h), + make_arm_list_result_handler (h), + make_confirm_handler (h), + GNUNET_MQ_handler_end () + }; + struct GNUNET_MessageHeader *test; + struct GNUNET_MQ_Envelope *env; + + if (NULL != h->mq) + return GNUNET_OK; + GNUNET_assert (GNUNET_NO == h->currently_up); + h->mq = GNUNET_CLIENT_connecT (h->cfg, + "arm", + handlers, + &mq_error_handler, + h); + if (NULL == h->mq) { LOG (GNUNET_ERROR_TYPE_DEBUG, - "arm_api, GNUNET_CLIENT_connect returned NULL\n"); + "GNUNET_CLIENT_connect returned NULL\n"); if (NULL != h->conn_status) h->conn_status (h->conn_status_cls, GNUNET_SYSERR); return GNUNET_SYSERR; } LOG (GNUNET_ERROR_TYPE_DEBUG, - "arm_api, GNUNET_CLIENT_connect returned non-NULL\n"); - trigger_next_request (h, - GNUNET_YES); + "Sending TEST message to ARM\n"); + env = GNUNET_MQ_msg (test, + GNUNET_MESSAGE_TYPE_TEST); + GNUNET_MQ_send (h->mq, + env); return GNUNET_OK; } @@ -661,22 +506,20 @@ reconnect_arm (struct GNUNET_ARM_Handle *h) * the ARM service may internally use a different * configuration to determine how to start the service). * @param conn_status will be called when connecting/disconnecting - * @param cls closure for conn_status + * @param conn_status_cls closure for @a conn_status * @return context to use for further ARM operations, NULL on error. */ struct GNUNET_ARM_Handle * GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_ARM_ConnectionStatusCallback conn_status, - void *cls) + void *conn_status_cls) { struct GNUNET_ARM_Handle *h; h = GNUNET_new (struct GNUNET_ARM_Handle); - h->cfg = GNUNET_CONFIGURATION_dup (cfg); - h->currently_down = GNUNET_YES; - h->reconnect_task = NULL; + h->cfg = cfg; h->conn_status = conn_status; - h->conn_status_cls = cls; + h->conn_status_cls = conn_status_cls; if (GNUNET_OK != reconnect_arm (h)) { GNUNET_free (h); @@ -692,113 +535,60 @@ GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, * @param h the handle that was being used */ void -GNUNET_ARM_disconnect_and_free (struct GNUNET_ARM_Handle *h) +GNUNET_ARM_disconnect (struct GNUNET_ARM_Handle *h) { - struct ARMControlMessage *cm; + struct GNUNET_ARM_Operation *op; LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from ARM service\n"); - if (NULL != h->cth) + while (NULL != (op = h->operation_pending_head)) { - GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth); - h->cth = NULL; - } - while ((NULL != (cm = h->control_pending_head)) - || (NULL != (cm = h->control_sent_head)) ) - { - if (NULL != h->control_pending_head) - GNUNET_CONTAINER_DLL_remove (h->control_pending_head, - h->control_pending_tail, - cm); - else - GNUNET_CONTAINER_DLL_remove (h->control_sent_head, - h->control_sent_tail, - cm); - GNUNET_assert (NULL != cm->timeout_task_id); - GNUNET_SCHEDULER_cancel (cm->timeout_task_id); - if (NULL != cm->result_cont) - cm->result_cont (cm->cont_cls, + GNUNET_CONTAINER_DLL_remove (h->operation_pending_head, + h->operation_pending_tail, + op); + if (NULL != op->result_cont) + op->result_cont (op->cont_cls, GNUNET_ARM_REQUEST_DISCONNECTED, - NULL, 0); - /* FIXME: What about list callback? */ - GNUNET_free_non_null (cm->msg); - GNUNET_free (cm); + if (NULL != op->list_cont) + op->list_cont (op->cont_cls, + GNUNET_ARM_REQUEST_DISCONNECTED, + 0, + NULL); + if (NULL != op->async) + { + GNUNET_SCHEDULER_cancel (op->async); + op->async = NULL; + } + GNUNET_free (op); } - if (NULL != h->client) + if (NULL != h->mq) { - GNUNET_CLIENT_disconnect (h->client); - h->client = NULL; + GNUNET_MQ_destroy (h->mq); + h->mq = NULL; } if (NULL != h->reconnect_task) { GNUNET_SCHEDULER_cancel (h->reconnect_task); h->reconnect_task = NULL; } - if (GNUNET_NO == h->service_test_is_active) - { - GNUNET_CONFIGURATION_destroy (h->cfg); - GNUNET_free (h); - } -} - - -/** - * Message timed out. Remove it from the queue. - * - * @param cls the message (struct ARMControlMessage *) - */ -static void -control_message_timeout (void *cls) -{ - struct ARMControlMessage *cm = cls; - struct GNUNET_ARM_Message *arm_msg; - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Control message timed out\n"); - arm_msg = cm->msg; - if ((NULL == arm_msg) || (0 == arm_msg->request_id)) - { - GNUNET_CONTAINER_DLL_remove (cm->h->control_pending_head, - cm->h->control_pending_tail, - cm); - } - else - { - GNUNET_CONTAINER_DLL_remove (cm->h->control_sent_head, - cm->h->control_sent_tail, - cm); - } - if (NULL != cm->result_cont) - cm->result_cont (cm->cont_cls, - GNUNET_ARM_REQUEST_TIMEOUT, - NULL, 0); - else if (NULL != cm->list_cont) - cm->list_cont (cm->cont_cls, - GNUNET_ARM_REQUEST_TIMEOUT, - 0, NULL); - GNUNET_free_non_null (cm->msg); - GNUNET_free (cm); + GNUNET_free (h); } /** * A client specifically requested starting of ARM itself. - * This function is called with information about whether - * or not ARM is running; if it is, report success. If - * it is not, start the ARM process. + * Starts the ARM service. * - * @param cls the context for the request that we will report on (struct ARMControlMessage *) - * @param result #GNUNET_YES if ARM is running + * @param h the handle with configuration details + * @param std_inheritance inheritance of std streams + * @return operation status code */ -static void -arm_service_report (void *cls, - int result) +static enum GNUNET_ARM_Result +start_arm_service (struct GNUNET_ARM_Handle *h, + enum GNUNET_OS_InheritStdioFlags std_inheritance) { - struct ARMControlMessage *cm = cls; - struct GNUNET_ARM_Handle *h; struct GNUNET_OS_Process *proc; - unsigned char test_is_active; char *cbinary; char *binary; char *quotedbinary; @@ -806,51 +596,20 @@ arm_service_report (void *cls, char *loprefix; char *lopostfix; - test_is_active = cm->h->service_test_is_active; - if ((GNUNET_YES == test_is_active) && - (GNUNET_YES == result)) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Looks like `%s' is already running.\n", - "gnunet-service-arm"); - /* arm is running! */ - if (cm->result_cont) - cm->result_cont (cm->cont_cls, - GNUNET_ARM_REQUEST_SENT_OK, "arm", - GNUNET_ARM_RESULT_IS_STARTED_ALREADY); - } - if (GNUNET_NO == test_is_active) - { - /* User disconnected & destroyed ARM handle in the middle of - * the service test, so we kept the handle around until now. - */ - GNUNET_CONFIGURATION_destroy (cm->h->cfg); - GNUNET_free (cm->h); - } - if ((GNUNET_YES == result) || - (GNUNET_NO == test_is_active)) - { - GNUNET_free (cm); - return; - } - cm->h->service_test_is_active = GNUNET_NO; - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Looks like `%s' is not running, will start it.\n", - "gnunet-service-arm"); if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cm->h->cfg, + GNUNET_CONFIGURATION_get_value_string (h->cfg, "arm", "PREFIX", &loprefix)) loprefix = GNUNET_strdup (""); if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cm->h->cfg, + GNUNET_CONFIGURATION_get_value_string (h->cfg, "arm", "OPTIONS", &lopostfix)) lopostfix = GNUNET_strdup (""); if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cm->h->cfg, + GNUNET_CONFIGURATION_get_value_string (h->cfg, "arm", "BINARY", &cbinary)) @@ -858,18 +617,14 @@ arm_service_report (void *cls, GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING, "arm", "BINARY"); - if (cm->result_cont) - cm->result_cont (cm->cont_cls, - GNUNET_ARM_REQUEST_SENT_OK, "arm", - GNUNET_ARM_RESULT_IS_NOT_KNOWN); - GNUNET_free (cm); GNUNET_free (loprefix); GNUNET_free (lopostfix); - return; + return GNUNET_ARM_RESULT_IS_NOT_KNOWN; } if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (cm->h->cfg, - "arm", "CONFIG", + GNUNET_CONFIGURATION_get_value_filename (h->cfg, + "arm", + "CONFIG", &config)) config = NULL; binary = GNUNET_OS_get_libexec_binary_path (cbinary); @@ -878,15 +633,15 @@ arm_service_report (void *cls, binary); GNUNET_free (cbinary); if ( (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (cm->h->cfg, + GNUNET_CONFIGURATION_have_value (h->cfg, "TESTING", "WEAKRANDOM")) && (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_yesno (cm->h->cfg, + GNUNET_CONFIGURATION_get_value_yesno (h->cfg, "TESTING", "WEAKRANDOM")) && (GNUNET_NO == - GNUNET_CONFIGURATION_have_value (cm->h->cfg, + GNUNET_CONFIGURATION_have_value (h->cfg, "TESTING", "HOSTFILE"))) { @@ -894,39 +649,43 @@ arm_service_report (void *cls, /* we're clearly running a test, don't daemonize */ if (NULL == config) proc = GNUNET_OS_start_process_s (GNUNET_NO, - cm->std_inheritance, + std_inheritance, NULL, loprefix, quotedbinary, /* no daemonization! */ - lopostfix, NULL); + lopostfix, + NULL); else proc = GNUNET_OS_start_process_s (GNUNET_NO, - cm->std_inheritance, + std_inheritance, NULL, loprefix, quotedbinary, "-c", config, /* no daemonization! */ - lopostfix, NULL); + lopostfix, + NULL); } else { if (NULL == config) proc = GNUNET_OS_start_process_s (GNUNET_NO, - cm->std_inheritance, + std_inheritance, NULL, loprefix, quotedbinary, - "-d", lopostfix, NULL); + "-d", /* do daemonize */ + lopostfix, NULL); else proc = GNUNET_OS_start_process_s (GNUNET_NO, - cm->std_inheritance, + std_inheritance, NULL, loprefix, quotedbinary, "-c", config, - "-d", lopostfix, + "-d", /* do daemonize */ + lopostfix, NULL); } GNUNET_free (binary); @@ -935,22 +694,32 @@ arm_service_report (void *cls, GNUNET_free (loprefix); GNUNET_free (lopostfix); if (NULL == proc) + return GNUNET_ARM_RESULT_START_FAILED; + GNUNET_OS_process_destroy (proc); + return GNUNET_ARM_RESULT_STARTING; +} + + +/** + * Abort an operation. Only prevents the callback from being + * called, the operation may still complete. + * + * @param op operation to cancel + */ +void +GNUNET_ARM_operation_cancel (struct GNUNET_ARM_Operation *op) +{ + struct GNUNET_ARM_Handle *h = op->h; + + if (h->thm == op) { - if (cm->result_cont) - cm->result_cont (cm->cont_cls, - GNUNET_ARM_REQUEST_SENT_OK, "arm", - GNUNET_ARM_RESULT_START_FAILED); - GNUNET_free (cm); + op->result_cont = NULL; return; } - if (cm->result_cont) - cm->result_cont (cm->cont_cls, - GNUNET_ARM_REQUEST_SENT_OK, "arm", - GNUNET_ARM_RESULT_STARTING); - GNUNET_OS_process_destroy (proc); - h = cm->h; - GNUNET_free (cm); - reconnect_arm (h); + GNUNET_CONTAINER_DLL_remove (h->operation_pending_head, + h->operation_pending_tail, + op); + GNUNET_free (op); } @@ -959,21 +728,21 @@ arm_service_report (void *cls, * * @param h handle to ARM * @param service_name name of the service - * @param timeout how long to wait before failing for good * @param cb callback to invoke when service is ready * @param cb_cls closure for @a cb * @param type type of the request + * @return handle to queue, NULL on error */ -static void +static struct GNUNET_ARM_Operation * change_service (struct GNUNET_ARM_Handle *h, const char *service_name, - struct GNUNET_TIME_Relative timeout, GNUNET_ARM_ResultCallback cb, void *cb_cls, uint16_t type) { - struct ARMControlMessage *cm; + struct GNUNET_ARM_Operation *op; size_t slen; + struct GNUNET_MQ_Envelope *env; struct GNUNET_ARM_Message *msg; slen = strlen (service_name) + 1; @@ -981,38 +750,81 @@ change_service (struct GNUNET_ARM_Handle *h, GNUNET_SERVER_MAX_MESSAGE_SIZE) { GNUNET_break (0); - if (cb != NULL) - cb (cb_cls, GNUNET_ARM_REQUEST_TOO_LONG, NULL, 0); - return; + return NULL; } - LOG (GNUNET_ERROR_TYPE_DEBUG, "Requesting %s of service `%s'.\n", - (GNUNET_MESSAGE_TYPE_ARM_START == type) ? "start" : "termination", - service_name); - cm = GNUNET_malloc (sizeof (struct ARMControlMessage) + slen); - cm->h = h; - cm->result_cont = cb; - cm->cont_cls = cb_cls; - cm->timeout = GNUNET_TIME_relative_to_absolute (timeout); - memcpy (&cm[1], service_name, slen); - msg = GNUNET_malloc (sizeof (struct GNUNET_ARM_Message) + slen); - msg->header.size = htons (sizeof (struct GNUNET_ARM_Message) + slen); - msg->header.type = htons (type); + if (0 == h->request_id_counter) + h->request_id_counter++; + op = GNUNET_new (struct GNUNET_ARM_Operation); + op->h = h; + op->result_cont = cb; + op->cont_cls = cb_cls; + op->id = h->request_id_counter++; + GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head, + h->operation_pending_tail, + op); + env = GNUNET_MQ_msg_extra (msg, + slen, + type); msg->reserved = htonl (0); - memcpy (&msg[1], service_name, slen); - cm->msg = msg; + msg->request_id = GNUNET_htonll (op->id); + memcpy (&msg[1], + service_name, + slen); + GNUNET_MQ_send (h->mq, + env); + return op; +} + + +/** + * Task run to notify application that ARM is already up. + * + * @param cls the operation that asked ARM to be started + */ +static void +notify_running (void *cls) +{ + struct GNUNET_ARM_Operation *op = cls; + struct GNUNET_ARM_Handle *h = op->h; + + op->async = NULL; + GNUNET_CONTAINER_DLL_remove (h->operation_pending_head, + h->operation_pending_tail, + op); + if (NULL != op->result_cont) + op->result_cont (op->cont_cls, + GNUNET_ARM_REQUEST_SENT_OK, + GNUNET_ARM_RESULT_IS_STARTED_ALREADY); + if ( (GNUNET_YES == h->currently_up) && + (NULL != h->conn_status) ) + h->conn_status (h->conn_status_cls, + GNUNET_YES); + GNUNET_free (op); +} + + +/** + * Task run to notify application that ARM is being started. + * + * @param cls the operation that asked ARM to be started + */ +static void +notify_starting (void *cls) +{ + struct GNUNET_ARM_Operation *op = cls; + struct GNUNET_ARM_Handle *h = op->h; + + op->async = NULL; LOG (GNUNET_ERROR_TYPE_DEBUG, - "Inserting a control message into the queue. Timeout is %s\n", - GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (cm->timeout), - GNUNET_NO)); - GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head, - h->control_pending_tail, - cm); - cm->timeout_task_id = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining - (cm->timeout), - &control_message_timeout, - cm); - trigger_next_request (h, GNUNET_NO); + "Notifying client that we started the ARM service\n"); + GNUNET_CONTAINER_DLL_remove (h->operation_pending_head, + h->operation_pending_tail, + op); + if (NULL != op->result_cont) + op->result_cont (op->cont_cls, + GNUNET_ARM_REQUEST_SENT_OK, + op->starting_ret); + GNUNET_free (op); } @@ -1022,132 +834,116 @@ change_service (struct GNUNET_ARM_Handle *h, * @param h handle to ARM * @param service_name name of the service * @param std_inheritance inheritance of std streams - * @param timeout how long to wait before failing for good * @param cont callback to invoke after request is sent or not sent * @param cont_cls closure for @a cont + * @return handle for the operation, NULL on error */ -void +struct GNUNET_ARM_Operation * GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h, const char *service_name, enum GNUNET_OS_InheritStdioFlags std_inheritance, - struct GNUNET_TIME_Relative timeout, GNUNET_ARM_ResultCallback cont, void *cont_cls) { - struct ARMControlMessage *cm; - size_t slen; + struct GNUNET_ARM_Operation *op; + enum GNUNET_ARM_Result ret; LOG (GNUNET_ERROR_TYPE_DEBUG, - "Asked to start service `%s' within %s\n", service_name, - GNUNET_STRINGS_relative_time_to_string (timeout, GNUNET_NO)); - if (0 == strcasecmp ("arm", service_name)) + "Starting service `%s'\n", + service_name); + if (0 != strcasecmp ("arm", + service_name)) + return change_service (h, + service_name, + cont, + cont_cls, + GNUNET_MESSAGE_TYPE_ARM_START); + + /* Possible cases: + * 1) We're connected to ARM already. Invoke the callback immediately. + * 2) We're not connected to ARM. + * Cancel any reconnection attempts temporarily, then perform + * a service test. + */ + if (GNUNET_YES == h->currently_up) { - /* Possible cases: - * 1) We're connected to ARM already. Invoke the callback immediately. - * 2) We're not connected to ARM. - * Cancel any reconnection attempts temporarily, then perform - * a service test. - */ - if (GNUNET_NO == h->currently_down) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "ARM is already running\n"); - if (NULL != cont) - cont (cont_cls, - GNUNET_ARM_REQUEST_SENT_OK, - "arm", - GNUNET_ARM_RESULT_IS_STARTED_ALREADY); - } - else if (GNUNET_NO == h->service_test_is_active) - { - if (NULL != h->cth) - { - GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth); - h->cth = NULL; - } - if (NULL != h->client) - { - GNUNET_CLIENT_disconnect (h->client); - h->client = NULL; - } - if (NULL != h->reconnect_task) - { - GNUNET_SCHEDULER_cancel (h->reconnect_task); - h->reconnect_task = NULL; - } - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Not connected to ARM, will do a service test\n"); - - slen = strlen ("arm") + 1; - cm = GNUNET_malloc (sizeof (struct ARMControlMessage) + slen); - cm->h = h; - cm->result_cont = cont; - cm->cont_cls = cont_cls; - cm->timeout = GNUNET_TIME_relative_to_absolute (timeout); - cm->std_inheritance = std_inheritance; - memcpy (&cm[1], service_name, slen); - h->service_test_is_active = GNUNET_YES; - GNUNET_CLIENT_service_test ("arm", - h->cfg, - timeout, - &arm_service_report, - cm); - } - else - { - /* Service test is already running - tell user to chill out and try - * again later. - */ - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Service test is already in progress, we're busy\n"); - if (NULL != cont) - cont (cont_cls, - GNUNET_ARM_REQUEST_BUSY, - NULL, 0); - } - return; - } - change_service (h, - service_name, - timeout, - cont, cont_cls, - GNUNET_MESSAGE_TYPE_ARM_START); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "ARM is already running\n"); + op = GNUNET_new (struct GNUNET_ARM_Operation); + op->h = h; + op->result_cont = cont; + op->cont_cls = cont_cls; + GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head, + h->operation_pending_tail, + op); + op->async = GNUNET_SCHEDULER_add_now (¬ify_running, + op); + return op; + } + /* This is an inherently uncertain choice, as it is of course + theoretically possible that ARM is up and we just did not + yet complete the MQ handshake. However, given that users + are unlikely to hammer 'gnunet-arm -s' on a busy system, + the above check should catch 99.99% of the cases where ARM + is already running. */ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Starting ARM service\n"); + ret = start_arm_service (h, + std_inheritance); + if (GNUNET_ARM_RESULT_STARTING == ret) + reconnect_arm (h); + op = GNUNET_new (struct GNUNET_ARM_Operation); + op->h = h; + op->result_cont = cont; + op->cont_cls = cont_cls; + GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head, + h->operation_pending_tail, + op); + op->starting_ret = ret; + op->async = GNUNET_SCHEDULER_add_now (¬ify_starting, + op); + return op; } /** - * Request a service to be stopped. - * Stopping arm itself will not invalidate its handle, and - * ARM API will try to restore connection to the ARM service, - * even if ARM connection was lost because you asked for ARM to be stopped. - * Call #GNUNET_ARM_disconnect_and_free() to free the handle and prevent + * Request a service to be stopped. Stopping arm itself will not + * invalidate its handle, and ARM API will try to restore connection + * to the ARM service, even if ARM connection was lost because you + * asked for ARM to be stopped. Call + * #GNUNET_ARM_disconnect() to free the handle and prevent * further connection attempts. * * @param h handle to ARM * @param service_name name of the service - * @param timeout how long to wait before failing for good * @param cont callback to invoke after request is sent or is not sent * @param cont_cls closure for @a cont + * @return handle for the operation, NULL on error */ -void +struct GNUNET_ARM_Operation * GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h, const char *service_name, - struct GNUNET_TIME_Relative timeout, GNUNET_ARM_ResultCallback cont, void *cont_cls) { + struct GNUNET_ARM_Operation *op; + LOG (GNUNET_ERROR_TYPE_DEBUG, - "Stopping service `%s' within %s\n", - service_name, - GNUNET_STRINGS_relative_time_to_string (timeout, - GNUNET_NO)); - change_service (h, - service_name, - timeout, - cont, - cont_cls, - GNUNET_MESSAGE_TYPE_ARM_STOP); + "Stopping service `%s'\n", + service_name); + op = change_service (h, + service_name, + cont, + cont_cls, + GNUNET_MESSAGE_TYPE_ARM_STOP); + if (NULL == op) + return NULL; + /* If the service is ARM, set a flag as we will use MQ errors + to detect that the process is really gone. */ + if (0 == strcasecmp (service_name, + "arm")) + op->is_arm_stop = GNUNET_YES; + return op; } @@ -1155,43 +951,38 @@ GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h, * Request a list of running services. * * @param h handle to ARM - * @param timeout how long to wait before failing for good * @param cont callback to invoke after request is sent or is not sent * @param cont_cls closure for @a cont + * @return handle for the operation, NULL on error */ -void +struct GNUNET_ARM_Operation * GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h, - struct GNUNET_TIME_Relative timeout, GNUNET_ARM_ServiceListCallback cont, void *cont_cls) { - struct ARMControlMessage *cm; + struct GNUNET_ARM_Operation *op; + struct GNUNET_MQ_Envelope *env; struct GNUNET_ARM_Message *msg; LOG (GNUNET_ERROR_TYPE_DEBUG, - "Requesting LIST from ARM service with timeout: %s\n", - GNUNET_STRINGS_relative_time_to_string (timeout, - GNUNET_YES)); - cm = GNUNET_new (struct ARMControlMessage); - cm->h = h; - cm->list_cont = cont; - cm->cont_cls = cont_cls; - cm->timeout = GNUNET_TIME_relative_to_absolute (timeout); - msg = GNUNET_malloc (sizeof (struct GNUNET_ARM_Message)); - msg->header.size = htons (sizeof (struct GNUNET_ARM_Message)); - msg->header.type = htons (GNUNET_MESSAGE_TYPE_ARM_LIST); + "Requesting LIST from ARM service\n"); + if (0 == h->request_id_counter) + h->request_id_counter++; + op = GNUNET_new (struct GNUNET_ARM_Operation); + op->h = h; + op->list_cont = cont; + op->cont_cls = cont_cls; + op->id = h->request_id_counter++; + GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head, + h->operation_pending_tail, + op); + env = GNUNET_MQ_msg (msg, + GNUNET_MESSAGE_TYPE_ARM_LIST); msg->reserved = htonl (0); - cm->msg = msg; - GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head, - h->control_pending_tail, - cm); - cm->timeout_task_id = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining - (cm->timeout), - &control_message_timeout, - cm); - trigger_next_request (h, - GNUNET_NO); + msg->request_id = GNUNET_htonll (op->id); + GNUNET_MQ_send (h->mq, + env); + return op; } diff --git a/src/arm/arm_monitor_api.c b/src/arm/arm_monitor_api.c index 6d4129928e..1f23c1dc5e 100644 --- a/src/arm/arm_monitor_api.c +++ b/src/arm/arm_monitor_api.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2009, 2010, 2012, 2013 GNUnet e.V. + Copyright (C) 2009, 2010, 2012, 2013, 2016 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -21,7 +21,8 @@ /** * @file arm/arm_monitor_api.c * @brief API for monitoring the ARM service - * @author Christian Grothoff, LRN + * @author Christian Grothoff + * @author LRN */ #include "platform.h" #include "gnunet_arm_service.h" @@ -241,9 +242,9 @@ reconnect_arm_monitor (struct GNUNET_ARM_MonitorHandle *h) * @return context to use for further ARM monitor operations, NULL on error. */ struct GNUNET_ARM_MonitorHandle * -GNUNET_ARM_monitor (const struct GNUNET_CONFIGURATION_Handle *cfg, - GNUNET_ARM_ServiceStatusCallback cont, - void *cont_cls) +GNUNET_ARM_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg, + GNUNET_ARM_ServiceStatusCallback cont, + void *cont_cls) { struct GNUNET_ARM_MonitorHandle *h; @@ -266,7 +267,7 @@ GNUNET_ARM_monitor (const struct GNUNET_CONFIGURATION_Handle *cfg, * @param h the handle that was being used */ void -GNUNET_ARM_monitor_disconnect_and_free (struct GNUNET_ARM_MonitorHandle *h) +GNUNET_ARM_monitor_stop (struct GNUNET_ARM_MonitorHandle *h) { if (NULL != h->mq) { diff --git a/src/arm/gnunet-arm.c b/src/arm/gnunet-arm.c index 75ade59da8..3b024ea93f 100644 --- a/src/arm/gnunet-arm.c +++ b/src/arm/gnunet-arm.c @@ -29,28 +29,6 @@ #include "gnunet_util_lib.h" /** - * Timeout for stopping services. Long to give some services a real chance. - */ -#define STOP_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1) - -/** - * Timeout for stopping ARM. Extra-long since ARM needs to stop everyone else. - */ -#define STOP_TIMEOUT_ARM GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2) - -/** - * Timeout for starting services, very short because of the strange way start works - * (by checking if running before starting, so really this time is always waited on - * startup (annoying)). - */ -#define START_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) - -/** - * Timeout for listing all running services. - */ -#define LIST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2) - -/** * Set if we are to shutdown all services (including ARM). */ static int end; @@ -132,6 +110,7 @@ static unsigned int phase; /** * User defined timestamp for completing operations. + * FIXME: to be implemented! */ static struct GNUNET_TIME_Relative timeout; @@ -150,6 +129,10 @@ static unsigned int no_stderr; */ static struct GNUNET_SCHEDULER_Task *al_task; +/** + * Current operation. + */ +static struct GNUNET_ARM_Operation *op; /** * Attempts to delete configuration file and GNUNET_HOME @@ -193,14 +176,19 @@ shutdown_task (void *cls) GNUNET_SCHEDULER_cancel (al_task); al_task = NULL; } + if (NULL != op) + { + GNUNET_ARM_operation_cancel (op); + op = NULL; + } if (NULL != h) { - GNUNET_ARM_disconnect_and_free (h); + GNUNET_ARM_disconnect (h); h = NULL; } if (NULL != m) { - GNUNET_ARM_monitor_disconnect_and_free (m); + GNUNET_ARM_monitor_stop (m); m = NULL; } if ((GNUNET_YES == end) && (GNUNET_YES == delete)) @@ -229,8 +217,6 @@ req_string (enum GNUNET_ARM_RequestStatus rs) return _("We disconnected from ARM before we could send a request"); case GNUNET_ARM_REQUEST_BUSY: return _("ARM API is busy"); - case GNUNET_ARM_REQUEST_TOO_LONG: - return _("Request does not fit into a message"); case GNUNET_ARM_REQUEST_TIMEOUT: return _("Request timed out"); } @@ -289,8 +275,8 @@ action_loop (void *cls); * our first attempt. * * @param cls closure - * @param connected GNUNET_YES if connected, GNUNET_NO if disconnected, - * GNUNET_SYSERR on error. + * @param connected #GNUNET_YES if connected, #GNUNET_NO if disconnected, + * #GNUNET_SYSERR on error. */ static void conn_status (void *cls, @@ -318,18 +304,17 @@ conn_status (void *cls, * * @param cls closure unused * @param rs what happened to our request - * @param service name of the service we tried to start ("arm") * @param result if the request was processed, this is the result * according to ARM */ static void start_callback (void *cls, enum GNUNET_ARM_RequestStatus rs, - const char *service, enum GNUNET_ARM_Result result) { char *msg; + op = NULL; if (GNUNET_ARM_REQUEST_SENT_OK != rs) { GNUNET_asprintf (&msg, "%s", _("Failed to start the ARM service: %s\n")); @@ -362,18 +347,17 @@ start_callback (void *cls, * * @param cls closure unused * @param rs what happened to our request - * @param service name of the service we tried to start ("arm") * @param result if the request was processed, this is the result * according to ARM */ static void stop_callback (void *cls, enum GNUNET_ARM_RequestStatus rs, - const char *service, enum GNUNET_ARM_Result result) { char *msg; + op = NULL; if (GNUNET_ARM_REQUEST_SENT_OK != rs) { GNUNET_asprintf (&msg, "%s", @@ -416,18 +400,17 @@ stop_callback (void *cls, * * @param cls closure unused * @param rs what happened to our request - * @param service name of the service we tried to start * @param result if the request was processed, this is the result * according to ARM */ static void init_callback (void *cls, enum GNUNET_ARM_RequestStatus rs, - const char *service, enum GNUNET_ARM_Result result) { char *msg; + op = NULL; if (GNUNET_ARM_REQUEST_SENT_OK != rs) { GNUNET_asprintf (&msg, @@ -441,9 +424,11 @@ init_callback (void *cls, if ((GNUNET_ARM_RESULT_STARTING != result) && (GNUNET_ARM_RESULT_IS_STARTED_ALREADY != result)) { - GNUNET_asprintf (&msg, _("Failed to start the `%s' service: %s\n"), - init, ret_string (result)); - FPRINTF (stdout, msg, service); + GNUNET_asprintf (&msg, + _("Failed to start the `%s' service: %s\n"), + init, + ret_string (result)); + FPRINTF (stdout, "%s", msg); GNUNET_free (msg); GNUNET_SCHEDULER_shutdown (); return; @@ -465,17 +450,17 @@ init_callback (void *cls, * * @param cls closure unused * @param rs what happened to our request - * @param service name of the service we tried to start * @param result if the request was processed, this is the result * according to ARM */ static void term_callback (void *cls, enum GNUNET_ARM_RequestStatus rs, - const char *service, enum GNUNET_ARM_Result result) { char *msg; + + op = NULL; if (GNUNET_ARM_REQUEST_SENT_OK != rs) { GNUNET_asprintf (&msg, @@ -492,7 +477,7 @@ term_callback (void *cls, GNUNET_asprintf (&msg, _("Failed to kill the `%s' service: %s\n"), term, ret_string (result)); - FPRINTF (stdout, msg, service); + FPRINTF (stdout, "%s", msg); GNUNET_free (msg); GNUNET_SCHEDULER_shutdown (); return; @@ -525,6 +510,7 @@ list_callback (void *cls, { unsigned int i; + op = NULL; if (GNUNET_ARM_REQUEST_SENT_OK != rs) { char *msg; @@ -573,9 +559,10 @@ action_loop (void *cls) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Termination action\n"); - GNUNET_ARM_request_service_stop (h, term, - (0 == timeout.rel_value_us) ? STOP_TIMEOUT : timeout, - &term_callback, NULL); + op = GNUNET_ARM_request_service_stop (h, + term, + &term_callback, + NULL); return; } break; @@ -584,9 +571,10 @@ action_loop (void *cls) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "End action\n"); - GNUNET_ARM_request_service_stop (h, "arm", - (0 == timeout.rel_value_us) ? STOP_TIMEOUT_ARM : timeout, - &stop_callback, NULL); + op = GNUNET_ARM_request_service_stop (h, + "arm", + &stop_callback, + NULL); return; } break; @@ -595,11 +583,11 @@ action_loop (void *cls) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start action\n"); - GNUNET_ARM_request_service_start (h, "arm", - (no_stdout ? 0 : GNUNET_OS_INHERIT_STD_OUT) | - (no_stderr ? 0 : GNUNET_OS_INHERIT_STD_ERR), - (0 == timeout.rel_value_us) ? START_TIMEOUT: timeout, - start_callback, NULL); + op = GNUNET_ARM_request_service_start (h, "arm", + (no_stdout ? 0 : GNUNET_OS_INHERIT_STD_OUT) | + (no_stderr ? 0 : GNUNET_OS_INHERIT_STD_ERR), + &start_callback, + NULL); return; } break; @@ -608,10 +596,10 @@ action_loop (void *cls) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Initialization action\n"); - GNUNET_ARM_request_service_start (h, init, - GNUNET_OS_INHERIT_STD_NONE, - (0 == timeout.rel_value_us) ? STOP_TIMEOUT : timeout, - &init_callback, NULL); + op = GNUNET_ARM_request_service_start (h, init, + GNUNET_OS_INHERIT_STD_NONE, + &init_callback, + NULL); return; } break; @@ -620,9 +608,9 @@ action_loop (void *cls) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Going to list all running services controlled by ARM.\n"); - GNUNET_ARM_request_service_list (h, - (0 == timeout.rel_value_us) ? LIST_TIMEOUT : timeout, - &list_callback, &list); + op = GNUNET_ARM_request_service_list (h, + &list_callback, + &list); return; } break; @@ -676,13 +664,21 @@ srv_status (void *cls, break; } if (! quiet) - { - if (NULL != msg) - FPRINTF (stderr, msg, service); - else - FPRINTF (stderr, _("Unknown status %u for service %s.\n"), status, service); - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got service %s status %d\n", service, (int) status); + { + if (NULL != msg) + FPRINTF (stderr, + msg, + service); + else + FPRINTF (stderr, + _("Unknown status %u for service %s.\n"), + status, + service); + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Got service %s status %d\n", + service, (int) + status); } @@ -705,30 +701,44 @@ run (void *cls, cfg = GNUNET_CONFIGURATION_dup (c); config_file = cfgfile; if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", "GNUNET_HOME", &dir)) + GNUNET_CONFIGURATION_get_value_string (cfg, + "PATHS", + "GNUNET_HOME", + &dir)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "PATHS", "GNUNET_HOME"); + "PATHS", + "GNUNET_HOME"); return; } if (NULL != cfgfile) { if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (cfg, "arm", "CONFIG", + GNUNET_CONFIGURATION_get_value_filename (cfg, + "arm", + "CONFIG", &armconfig)) { - GNUNET_CONFIGURATION_set_value_string (cfg, "arm", "CONFIG", + GNUNET_CONFIGURATION_set_value_string (cfg, + "arm", + "CONFIG", cfgfile); } else GNUNET_free (armconfig); } - if (NULL == (h = GNUNET_ARM_connect (cfg, &conn_status, NULL))) + if (NULL == (h = GNUNET_ARM_connect (cfg, + &conn_status, + NULL))) return; if (monitor) - m = GNUNET_ARM_monitor (cfg, &srv_status, NULL); - al_task = GNUNET_SCHEDULER_add_now (&action_loop, NULL); - GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); + m = GNUNET_ARM_monitor_start (cfg, + &srv_status, + NULL); + al_task = GNUNET_SCHEDULER_add_now (&action_loop, + NULL); + GNUNET_SCHEDULER_add_shutdown (&shutdown_task, + NULL); } @@ -774,7 +784,8 @@ main (int argc, char *const *argv) GNUNET_GETOPT_OPTION_END }; - if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, + &argc, &argv)) return 2; if (GNUNET_OK == diff --git a/src/arm/test_arm_api.c b/src/arm/test_arm_api.c index f5283d714f..0449c41d4a 100644 --- a/src/arm/test_arm_api.c +++ b/src/arm/test_arm_api.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2009, 2011 GNUnet e.V. + Copyright (C) 2009, 2011, 2016 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -28,60 +28,64 @@ #define LOG(...) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) -#define START_ARM GNUNET_YES - -#define START_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 1500) - #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) static const struct GNUNET_CONFIGURATION_Handle *cfg; static struct GNUNET_ARM_Handle *arm; +static struct GNUNET_ARM_Operation *op; + static int ok = 1; static int phase = 0; + static void arm_stop_cb (void *cls, enum GNUNET_ARM_RequestStatus status, - const char *servicename, enum GNUNET_ARM_Result result) { + op = NULL; /* (6), a stop request should be sent to ARM successfully */ /* ARM should report that it is stopping */ GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK); GNUNET_break (result == GNUNET_ARM_RESULT_STOPPED); GNUNET_break (phase == 6); phase++; - LOG ("Sent 'STOP' request for arm to ARM %s\n", (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully"); + LOG ("Sent 'STOP' request for arm to ARM %s\n", + (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully"); + GNUNET_SCHEDULER_shutdown (); } static void resolver_stop_cb (void *cls, enum GNUNET_ARM_RequestStatus status, - const char *servicename, enum GNUNET_ARM_Result result) + enum GNUNET_ARM_Result result) { + op = NULL; /* (5), a stop request should be sent to ARM successfully. * ARM should report that resolver is stopped. */ GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK); GNUNET_break (result == GNUNET_ARM_RESULT_STOPPED); GNUNET_break (phase == 5); - LOG ("Sent 'STOP' request for resolver to ARM %s\n", (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully"); + LOG ("Sent 'STOP' request for resolver to ARM %s\n", + (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully"); phase++; -#if START_ARM - GNUNET_ARM_request_service_stop (arm, "arm", TIMEOUT, arm_stop_cb, NULL); -#else - arm_stop_cb (NULL, GNUNET_ARM_STATUS_SENT_OK, "arm", GNUNET_ARM_SERVICE_STOPPING); - arm_conn (NULL, GNUNET_NO); -#endif + GNUNET_assert (NULL == op); + op = GNUNET_ARM_request_service_stop (arm, + "arm", + &arm_stop_cb, + NULL); } static void -dns_notify (void *cls, const struct sockaddr *addr, socklen_t addrlen) +dns_notify (void *cls, + const struct sockaddr *addr, + socklen_t addrlen) { if (addr == NULL) { @@ -91,7 +95,11 @@ dns_notify (void *cls, const struct sockaddr *addr, socklen_t addrlen) LOG ("Finished resolving localhost\n"); if (ok != 0) ok = 2; - GNUNET_ARM_request_service_stop (arm, "resolver", TIMEOUT, resolver_stop_cb, NULL); + GNUNET_assert (NULL == op); + op = GNUNET_ARM_request_service_stop (arm, + "resolver", + &resolver_stop_cb, + NULL); return; } /* (3), resolver should resolve localhost */ @@ -106,25 +114,22 @@ dns_notify (void *cls, const struct sockaddr *addr, socklen_t addrlen) static void resolver_start_cb (void *cls, enum GNUNET_ARM_RequestStatus status, - const char *servicename, enum GNUNET_ARM_Result result) { + op = NULL; /* (2), the start request for resolver should be sent successfully * ARM should report that resolver service is starting. */ GNUNET_assert (status == GNUNET_ARM_REQUEST_SENT_OK); GNUNET_break (phase == 2); GNUNET_break (result == GNUNET_ARM_RESULT_STARTING); - LOG ("Sent 'START' request for resolver to ARM %s\n", (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully"); + LOG ("Sent 'START' request for resolver to ARM %s\n", + (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully"); phase++; - GNUNET_RESOLVER_ip_get ("localhost", AF_INET, TIMEOUT, &dns_notify, NULL); -} - - -static void -trigger_disconnect (void *cls) -{ - GNUNET_ARM_disconnect_and_free ((struct GNUNET_ARM_Handle *) cls); + GNUNET_RESOLVER_ip_get ("localhost", + AF_INET, + TIMEOUT, + &dns_notify, NULL); } @@ -146,7 +151,12 @@ arm_conn (void *cls, LOG ("Connected to ARM\n"); GNUNET_break (phase == 1); phase++; - GNUNET_ARM_request_service_start (arm, "resolver", GNUNET_OS_INHERIT_STD_OUT_AND_ERR, START_TIMEOUT, resolver_start_cb, NULL); + GNUNET_assert (NULL == op); + op = GNUNET_ARM_request_service_start (arm, + "resolver", + GNUNET_OS_INHERIT_STD_OUT_AND_ERR, + &resolver_start_cb, + NULL); } else { @@ -157,7 +167,6 @@ arm_conn (void *cls, ok = 3; else if (ok == 1) ok = 0; - GNUNET_SCHEDULER_add_now (&trigger_disconnect, arm); } } @@ -165,9 +174,9 @@ arm_conn (void *cls, static void arm_start_cb (void *cls, enum GNUNET_ARM_RequestStatus status, - const char *servicename, enum GNUNET_ARM_Result result) { + op = NULL; /* (0) The request should be "sent" successfully * ("sent", because it isn't going anywhere, ARM API starts ARM service * by itself). @@ -175,26 +184,48 @@ arm_start_cb (void *cls, */ GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK); GNUNET_break (phase == 0); - LOG ("Sent 'START' request for arm to ARM %s\n", (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully"); + LOG ("Sent 'START' request for arm to ARM %s\n", + (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully"); GNUNET_break (result == GNUNET_ARM_RESULT_STARTING); phase++; } static void -task (void *cls, char *const *args, const char *cfgfile, +do_shutdown (void *cls) +{ + if (NULL != op) + { + GNUNET_ARM_operation_cancel (op); + op = NULL; + } + if (NULL != arm) + { + GNUNET_ARM_disconnect (arm); + arm = NULL; + } +} + + +static void +task (void *cls, + char *const *args, + const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { cfg = c; - arm = GNUNET_ARM_connect (cfg, &arm_conn, NULL); + arm = GNUNET_ARM_connect (cfg, + &arm_conn, + NULL); if (NULL == arm) return; -#if START_ARM - GNUNET_ARM_request_service_start (arm, "arm", GNUNET_OS_INHERIT_STD_OUT_AND_ERR, START_TIMEOUT, arm_start_cb, NULL); -#else - arm_start_cb (NULL, arm, GNUNET_ARM_REQUEST_SENT_OK, "arm", GNUNET_ARM_RESULT_STARTING); - arm_conn (NULL, arm, GNUNET_YES); -#endif + GNUNET_SCHEDULER_add_shutdown (&do_shutdown, + NULL); + op = GNUNET_ARM_request_service_start (arm, + "arm", + GNUNET_OS_INHERIT_STD_OUT_AND_ERR, + &arm_start_cb, + NULL); } diff --git a/src/arm/test_exponential_backoff.c b/src/arm/test_exponential_backoff.c index 3f33c91e69..8135f51579 100644 --- a/src/arm/test_exponential_backoff.c +++ b/src/arm/test_exponential_backoff.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2009 GNUnet e.V. + Copyright (C) 2009, 2016 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -70,7 +70,9 @@ static char *killLogFileName; #endif -typedef void (*GNUNET_CLIENT_ShutdownTask) (void *cls, int reason); +typedef void +(*GNUNET_CLIENT_ShutdownTask) (void *cls, int reason); + /** * Context for handling the shutdown of a service. @@ -118,7 +120,8 @@ struct ShutdownContext * @param msg NULL, indicating socket closure. */ static void -service_shutdown_handler (void *cls, const struct GNUNET_MessageHeader *msg) +service_shutdown_handler (void *cls, + const struct GNUNET_MessageHeader *msg) { struct ShutdownContext *shutdown_ctx = cls; @@ -147,7 +150,8 @@ service_shutdown_cancel (void *cls) { struct ShutdownContext *shutdown_ctx = cls; - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "service_shutdown_cancel called!\n"); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "service_shutdown_cancel called!\n"); shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_SYSERR); GNUNET_CLIENT_disconnect (shutdown_ctx->sock); GNUNET_free (shutdown_ctx); @@ -207,8 +211,9 @@ write_shutdown (void *cls, size_t size, void *buf) */ static void do_nothing_service_shutdown (struct GNUNET_CLIENT_Connection *sock, - struct GNUNET_TIME_Relative timeout, - GNUNET_CLIENT_ShutdownTask cont, void *cont_cls) + struct GNUNET_TIME_Relative timeout, + GNUNET_CLIENT_ShutdownTask cont, + void *cont_cls) { struct ShutdownContext *shutdown_ctx; @@ -266,7 +271,10 @@ kill_task (void *cbData) else if (trialCount == 13) { GNUNET_CLIENT_disconnect (doNothingConnection); - GNUNET_ARM_request_service_stop (arm, SERVICE, TIMEOUT, NULL, NULL); + GNUNET_ARM_request_service_stop (arm, + SERVICE, + NULL, + NULL); if (waitedFor_prev.rel_value_us >= waitedFor.rel_value_us) ok = 9; else @@ -284,15 +292,14 @@ kill_task (void *cbData) static void trigger_disconnect (void *cls) { - GNUNET_ARM_disconnect_and_free (arm); - GNUNET_ARM_monitor_disconnect_and_free (mon); + GNUNET_ARM_disconnect (arm); + GNUNET_ARM_monitor_stop (mon); } static void arm_stop_cb (void *cls, enum GNUNET_ARM_RequestStatus status, - const char *servicename, enum GNUNET_ARM_Result result) { GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK); @@ -303,14 +310,19 @@ arm_stop_cb (void *cls, static void -srv_status (void *cls, const char *service, enum GNUNET_ARM_ServiceStatus status) +srv_status (void *cls, + const char *service, + enum GNUNET_ARM_ServiceStatus status) { LOG ("Service %s is %u, phase %u\n", service, status, phase); if (status == GNUNET_ARM_SERVICE_MONITORING_STARTED) { phase++; - GNUNET_ARM_request_service_start (arm, SERVICE, - GNUNET_OS_INHERIT_STD_OUT_AND_ERR, TIMEOUT, NULL, NULL); + GNUNET_ARM_request_service_start (arm, + SERVICE, + GNUNET_OS_INHERIT_STD_OUT_AND_ERR, + NULL, + NULL); return; } if (phase == 1) @@ -322,7 +334,8 @@ srv_status (void *cls, const char *service, enum GNUNET_ARM_ServiceStatus status phase++; ok = 1; GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, - &kill_task, NULL); + &kill_task, + NULL); } else if ((phase == 2) && (strcasecmp (SERVICE, service) == 0)) { @@ -337,14 +350,19 @@ srv_status (void *cls, const char *service, enum GNUNET_ARM_ServiceStatus status else if ((status == GNUNET_ARM_SERVICE_STOPPED) && (trialCount == 14)) { phase++; - GNUNET_ARM_request_service_stop (arm, "arm", TIMEOUT, arm_stop_cb, NULL); + GNUNET_ARM_request_service_stop (arm, + "arm", + &arm_stop_cb, + NULL); } } } static void -arm_start_cb (void *cls, enum GNUNET_ARM_RequestStatus status, const char *servicename, enum GNUNET_ARM_Result result) +arm_start_cb (void *cls, + enum GNUNET_ARM_RequestStatus status, + enum GNUNET_ARM_Result result) { GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK); GNUNET_break (result == GNUNET_ARM_RESULT_STARTING); @@ -355,26 +373,34 @@ arm_start_cb (void *cls, enum GNUNET_ARM_RequestStatus status, const char *servi static void -task (void *cls, char *const *args, const char *cfgfile, +task (void *cls, + char *const *args, + const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { cfg = c; arm = GNUNET_ARM_connect (cfg, NULL, NULL); if (NULL != arm) { - mon = GNUNET_ARM_monitor (cfg, &srv_status, NULL); + mon = GNUNET_ARM_monitor_start (cfg, &srv_status, NULL); if (NULL != mon) { #if START_ARM - GNUNET_ARM_request_service_start (arm, "arm", - GNUNET_OS_INHERIT_STD_OUT_AND_ERR, GNUNET_TIME_UNIT_ZERO, arm_start_cb, NULL); + GNUNET_ARM_request_service_start (arm, + "arm", + GNUNET_OS_INHERIT_STD_OUT_AND_ERR, + &arm_start_cb, + NULL); #else - arm_start_cb (NULL, arm, GNUNET_ARM_REQUEST_SENT_OK, "arm", GNUNET_ARM_SERVICE_STARTING); + arm_start_cb (NULL, + arm, + GNUNET_ARM_REQUEST_SENT_OK, + GNUNET_ARM_SERVICE_STARTING); #endif } else { - GNUNET_ARM_disconnect_and_free (arm); + GNUNET_ARM_disconnect (arm); arm = NULL; } } diff --git a/src/arm/test_gnunet_service_arm.c b/src/arm/test_gnunet_service_arm.c index 33662e5798..71bf550847 100644 --- a/src/arm/test_gnunet_service_arm.c +++ b/src/arm/test_gnunet_service_arm.c @@ -51,7 +51,7 @@ static struct GNUNET_ARM_Handle *arm; static void trigger_disconnect (void *cls) { - GNUNET_ARM_disconnect_and_free (arm); + GNUNET_ARM_disconnect (arm); arm = NULL; } @@ -59,7 +59,6 @@ trigger_disconnect (void *cls) static void arm_stop_cb (void *cls, enum GNUNET_ARM_RequestStatus status, - const char *servicename, enum GNUNET_ARM_Result result) { GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK); @@ -100,15 +99,15 @@ service_list (void *cls, stop_arm: GNUNET_ARM_request_service_stop (arm, "arm", - TIMEOUT, - &arm_stop_cb, NULL); + &arm_stop_cb, + NULL); } static void hostname_resolve_cb (void *cls, - const struct sockaddr *addr, - socklen_t addrlen) + const struct sockaddr *addr, + socklen_t addrlen) { if ((0 == ret) || (4 == ret) || (1 == resolved_ok)) return; @@ -120,8 +119,8 @@ hostname_resolve_cb (void *cls, ret = 3; GNUNET_ARM_request_service_stop (arm, "arm", - TIMEOUT, - &arm_stop_cb, NULL); + &arm_stop_cb, + NULL); return; } if (0 == asked_for_a_list) @@ -129,7 +128,6 @@ hostname_resolve_cb (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Resolved hostname, now checking the service list\n"); GNUNET_ARM_request_service_list (arm, - TIMEOUT, &service_list, NULL); asked_for_a_list = 1; @@ -141,7 +139,6 @@ hostname_resolve_cb (void *cls, static void arm_start_cb (void *cls, enum GNUNET_ARM_RequestStatus status, - const char *servicename, enum GNUNET_ARM_Result result) { GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK); @@ -150,7 +147,8 @@ arm_start_cb (void *cls, "Trying to resolve our own hostname!\n"); /* connect to the resolver service */ if (NULL == - GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC, TIMEOUT, + GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC, + TIMEOUT, &hostname_resolve_cb, NULL)) { @@ -159,8 +157,9 @@ arm_start_cb (void *cls, GNUNET_break (0); ret = 2; GNUNET_ARM_request_service_stop (arm, - "arm", TIMEOUT, - &arm_stop_cb, NULL); + "arm", + &arm_stop_cb, + NULL); } } @@ -171,11 +170,14 @@ run (void *cls, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { - arm = GNUNET_ARM_connect (c, NULL, NULL); - GNUNET_ARM_request_service_start (arm, "arm", + arm = GNUNET_ARM_connect (c, + NULL, + NULL); + GNUNET_ARM_request_service_start (arm, + "arm", GNUNET_OS_INHERIT_STD_OUT_AND_ERR, - START_TIMEOUT, - &arm_start_cb, NULL); + &arm_start_cb, + NULL); } diff --git a/src/include/gnunet_arm_service.h b/src/include/gnunet_arm_service.h index f215242268..7fb14d3ace 100644 --- a/src/include/gnunet_arm_service.h +++ b/src/include/gnunet_arm_service.h @@ -1,6 +1,6 @@ /* This file is part of GNUnet - Copyright (C) 2009 GNUnet e.V. + Copyright (C) 2009, 2016 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -48,7 +48,7 @@ extern "C" /** * Version of the arm API. */ -#define GNUNET_ARM_VERSION 0x00000002 +#define GNUNET_ARM_VERSION 0x00000003 /** @@ -78,12 +78,6 @@ enum GNUNET_ARM_RequestStatus GNUNET_ARM_REQUEST_BUSY = 3, /** - * It was discovered that the request would be too long to fit in a message, - * and thus it was not sent. - */ - GNUNET_ARM_REQUEST_TOO_LONG = 4, - - /** * Request time ran out before we had a chance to send it. */ GNUNET_ARM_REQUEST_TIMEOUT = 5 @@ -180,50 +174,56 @@ enum GNUNET_ARM_Result */ struct GNUNET_ARM_Handle; +/** + * Handle for an ARM operation. + */ +struct GNUNET_ARM_Operation; + /** * Function called whenever we connect to or disconnect from ARM. * * @param cls closure - * @param connected GNUNET_YES if connected, GNUNET_NO if disconnected, - * GNUNET_SYSERR if there was an error. + * @param connected #GNUNET_YES if connected, #GNUNET_NO if disconnected, + * #GNUNET_SYSERR if there was an error. */ -typedef void (*GNUNET_ARM_ConnectionStatusCallback) (void *cls, - int connected); +typedef void +(*GNUNET_ARM_ConnectionStatusCallback) (void *cls, + int connected); /** * Function called in response to a start/stop request. * Will be called when request was not sent successfully, * or when a reply comes. If the request was not sent successfully, - * 'rs' will indicate that, and 'service' and 'result' will be undefined. + * @a rs will indicate that, and @a result will be undefined. * * @param cls closure * @param rs status of the request - * @param service service name * @param result result of the operation */ -typedef void (*GNUNET_ARM_ResultCallback) (void *cls, - enum GNUNET_ARM_RequestStatus rs, - const char *service, - enum GNUNET_ARM_Result result); +typedef void +(*GNUNET_ARM_ResultCallback) (void *cls, + enum GNUNET_ARM_RequestStatus rs, + enum GNUNET_ARM_Result result); /** * Callback function invoked when list operation is complete. * Will be called when request was not sent successfully, * or when a reply comes. If the request was not sent successfully, - * 'rs' will indicate that, and 'count' and 'list' will be undefined. + * @a rs will indicate that, and @a count and @a list will be undefined. * * @param cls closure * @param rs status of the request * @param count number of strings in the list * @param list list of running services */ -typedef void (*GNUNET_ARM_ServiceListCallback) (void *cls, - enum GNUNET_ARM_RequestStatus rs, - unsigned int count, - const char *const*list); +typedef void +(*GNUNET_ARM_ServiceListCallback) (void *cls, + enum GNUNET_ARM_RequestStatus rs, + unsigned int count, + const char *const*list); /** @@ -234,13 +234,13 @@ typedef void (*GNUNET_ARM_ServiceListCallback) (void *cls, * the ARM service may internally use a different * configuration to determine how to start the service). * @param conn_status will be called when connecting/disconnecting - * @param cls closure for conn_status + * @param conn_status_cls closure for @a conn_status * @return context to use for further ARM operations, NULL on error. */ struct GNUNET_ARM_Handle * GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_ARM_ConnectionStatusCallback conn_status, - void *cls); + void *conn_status_cls); /** @@ -249,21 +249,31 @@ GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, * @param h the handle that was being used */ void -GNUNET_ARM_disconnect_and_free (struct GNUNET_ARM_Handle *h); +GNUNET_ARM_disconnect (struct GNUNET_ARM_Handle *h); + + +/** + * Abort an operation. Only prevents the callback from being + * called, the operation may still complete. + * + * @param op operation to cancel + */ +void +GNUNET_ARM_operation_cancel (struct GNUNET_ARM_Operation *op); /** * Request a list of running services. * * @param h handle to ARM - * @param timeout how long to wait before failing for good * @param cont callback to invoke after request is sent or is not sent - * @param cont_cls closure for callback + * @param cont_cls closure for @a cont + * @return handle for the operation, NULL on error */ -void +struct GNUNET_ARM_Operation * GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h, - struct GNUNET_TIME_Relative timeout, - GNUNET_ARM_ServiceListCallback cont, void *cont_cls); + GNUNET_ARM_ServiceListCallback cont, + void *cont_cls); /** @@ -271,20 +281,20 @@ GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h, * Stopping arm itself will not invalidate its handle, and * ARM API will try to restore connection to the ARM service, * even if ARM connection was lost because you asked for ARM to be stopped. - * Call GNUNET_ARM_disconnect_and_free () to free the handle and prevent + * Call #GNUNET_ARM_disconnect() to free the handle and prevent * further connection attempts. * * @param h handle to ARM * @param service_name name of the service - * @param timeout how long to wait before failing for good * @param cont callback to invoke after request is sent or is not sent - * @param cont_cls closure for callback + * @param cont_cls closure for @a cont + * @return handle for the operation, NULL on error */ -void +struct GNUNET_ARM_Operation * GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h, const char *service_name, - struct GNUNET_TIME_Relative timeout, - GNUNET_ARM_ResultCallback cont, void *cont_cls); + GNUNET_ARM_ResultCallback cont, + void *cont_cls); /** @@ -293,15 +303,14 @@ GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h, * @param h handle to ARM * @param service_name name of the service * @param std_inheritance inheritance of std streams - * @param timeout how long to wait before failing for good * @param cont callback to invoke after request is sent or not sent - * @param cont_cls closure for callback + * @param cont_cls closure for @a cont + * @return handle for the operation, NULL on error */ -void +struct GNUNET_ARM_Operation * GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h, const char *service_name, enum GNUNET_OS_InheritStdioFlags std_inheritance, - struct GNUNET_TIME_Relative timeout, GNUNET_ARM_ResultCallback cont, void *cont_cls); @@ -316,13 +325,13 @@ struct GNUNET_ARM_MonitorHandle; * Function called in when a status update arrives. * * @param cls closure - * @param arm handle to the arm connection * @param service service name * @param status status of the service */ -typedef void (*GNUNET_ARM_ServiceStatusCallback) (void *cls, - const char *service, - enum GNUNET_ARM_ServiceStatus status); +typedef void +(*GNUNET_ARM_ServiceStatusCallback) (void *cls, + const char *service, + enum GNUNET_ARM_ServiceStatus status); /** @@ -333,13 +342,13 @@ typedef void (*GNUNET_ARM_ServiceStatusCallback) (void *cls, * the ARM service may internally use a different * configuration to determine how to start the service). * @param cont callback to invoke on status updates - * @param cont_cls closure + * @param cont_cls closure for @a cont * @return context to use for further ARM monitor operations, NULL on error. */ struct GNUNET_ARM_MonitorHandle * -GNUNET_ARM_monitor (const struct GNUNET_CONFIGURATION_Handle *cfg, - GNUNET_ARM_ServiceStatusCallback cont, - void *cont_cls); +GNUNET_ARM_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg, + GNUNET_ARM_ServiceStatusCallback cont, + void *cont_cls); /** @@ -348,7 +357,7 @@ GNUNET_ARM_monitor (const struct GNUNET_CONFIGURATION_Handle *cfg, * @param h the handle that was being used */ void -GNUNET_ARM_monitor_disconnect_and_free (struct GNUNET_ARM_MonitorHandle *h); +GNUNET_ARM_monitor_stop (struct GNUNET_ARM_MonitorHandle *h); #if 0 /* keep Emacsens' auto-indent happy */ { diff --git a/src/include/gnunet_testbed_logger_service.h b/src/include/gnunet_testbed_logger_service.h index ce82da5c25..c10c2ee6b9 100644 --- a/src/include/gnunet_testbed_logger_service.h +++ b/src/include/gnunet_testbed_logger_service.h @@ -75,7 +75,9 @@ GNUNET_TESTBED_LOGGER_disconnect (struct GNUNET_TESTBED_LOGGER_Handle *h); * @param cls the closure given to GNUNET_TESTBED_LOGGER_send() * @param size the amount of data sent */ -typedef void (*GNUNET_TESTBED_LOGGER_FlushCompletion) (void *cls, size_t size); +typedef void +(*GNUNET_TESTBED_LOGGER_FlushCompletion) (void *cls, + size_t size); /** @@ -89,7 +91,8 @@ typedef void (*GNUNET_TESTBED_LOGGER_FlushCompletion) (void *cls, size_t size); */ void GNUNET_TESTBED_LOGGER_write (struct GNUNET_TESTBED_LOGGER_Handle *h, - const void *data, size_t size); + const void *data, + size_t size); /** diff --git a/src/include/gnunet_testing_lib.h b/src/include/gnunet_testing_lib.h index 72b5ede042..e09068444e 100644 --- a/src/include/gnunet_testing_lib.h +++ b/src/include/gnunet_testing_lib.h @@ -157,9 +157,7 @@ struct GNUNET_TESTING_System * GNUNET_TESTING_system_create_with_portrange (const char *testdir, const char *trusted_ip, const char *hostname, - const struct - GNUNET_TESTING_SharedService * - shared_services, + const struct GNUNET_TESTING_SharedService *shared_services, uint16_t lowport, uint16_t highport); @@ -185,12 +183,12 @@ GNUNET_TESTING_system_destroy (struct GNUNET_TESTING_System *system, * GNUnet source code. * * This is primarily a helper function used internally - * by 'GNUNET_TESTING_peer_configure'. + * by #GNUNET_TESTING_peer_configure(). * * @param system the testing system handle * @param key_number desired pre-created hostkey to obtain * @param id set to the peer's identity (hash of the public - * key; if NULL, GNUNET_SYSERR is returned immediately + * key; if NULL, #GNUNET_SYSERR is returned immediately * @return NULL on error (not enough keys) */ struct GNUNET_CRYPTO_EddsaPrivateKey * @@ -227,10 +225,10 @@ GNUNET_TESTING_release_port (struct GNUNET_TESTING_System *system, * system. The default configuration will be available in PATHS section under * the option DEFAULTCONFIG after the call. SERVICE_HOME is also set in PATHS * section to the temporary directory specific to this configuration. If we run - * out of "*port" numbers, return SYSERR. + * out of "*port" numbers, return #GNUNET_SYSERR. * * This is primarily a helper function used internally - * by 'GNUNET_TESTING_peer_configure'. + * by #GNUNET_TESTING_peer_configure(). * * @param system system to use to coordinate resource usage * @param cfg template configuration to update @@ -353,9 +351,9 @@ typedef void * * @param peer the peer to stop * @param cb the callback to signal peer shutdown - * @param cb_cls closure for the above callback - * @return GNUNET_OK upon successfully giving the request to the ARM API (this - * does not mean that the peer is successfully stopped); GNUNET_SYSERR + * @param cb_cls closure for the @a cb + * @return #GNUNET_OK upon successfully giving the request to the ARM API (this + * does not mean that the peer is successfully stopped); #GNUNET_SYSERR * upon any error. */ int diff --git a/src/testbed/gnunet-service-testbed_peers.c b/src/testbed/gnunet-service-testbed_peers.c index 9c12c25a6b..b55f5a8c8d 100644 --- a/src/testbed/gnunet-service-testbed_peers.c +++ b/src/testbed/gnunet-service-testbed_peers.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2008--2013 GNUnet e.V. + Copyright (C) 2008--2013, 2016 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -72,6 +72,11 @@ struct ManageServiceContext struct GNUNET_SERVER_Client *client; /** + * Name of the service. + */ + char *service; + + /** * The operation id of the associated request */ uint64_t op_id; @@ -421,7 +426,8 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client, &msg->header, peer_create_success_cb, fo_ctxt); fo_ctxt->timeout_task = - GNUNET_SCHEDULER_add_delayed (GST_timeout, &peer_create_forward_timeout, + GNUNET_SCHEDULER_add_delayed (GST_timeout, + &peer_create_forward_timeout, fo_ctxt); GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fo_ctxt); GNUNET_SERVER_receive_done (client, GNUNET_OK); @@ -475,7 +481,8 @@ GST_handle_peer_destroy (void *cls, fopc->operation_id, &msg->header, &peer_destroy_success_cb, fopc); fopc->timeout_task = - GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout, + GNUNET_SCHEDULER_add_delayed (GST_timeout, + &GST_forwarded_operation_timeout, fopc); GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc); GNUNET_SERVER_receive_done (client, GNUNET_OK); @@ -568,7 +575,8 @@ GST_handle_peer_start (void *cls, struct GNUNET_SERVER_Client *client, &GST_forwarded_operation_reply_relay, fopc); fopc->timeout_task = - GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout, + GNUNET_SCHEDULER_add_delayed (GST_timeout, + &GST_forwarded_operation_timeout, fopc); GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc); GNUNET_SERVER_receive_done (client, GNUNET_OK); @@ -594,14 +602,15 @@ GST_handle_peer_start (void *cls, struct GNUNET_SERVER_Client *client, /** - * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages + * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages * * @param cls NULL * @param client identification of the client * @param message the actual message */ void -GST_handle_peer_stop (void *cls, struct GNUNET_SERVER_Client *client, +GST_handle_peer_stop (void *cls, + struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { const struct GNUNET_TESTBED_PeerStopMessage *msg; @@ -612,10 +621,13 @@ GST_handle_peer_stop (void *cls, struct GNUNET_SERVER_Client *client, msg = (const struct GNUNET_TESTBED_PeerStopMessage *) message; peer_id = ntohl (msg->peer_id); - LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PEER_STOP for peer %u\n", peer_id); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Received PEER_STOP for peer %u\n", + (unsigned int) peer_id); if (!VALID_PEER_ID (peer_id)) { - GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), + GST_send_operation_fail_msg (client, + GNUNET_ntohll (msg->operation_id), "Peer not found"); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; @@ -623,8 +635,9 @@ GST_handle_peer_stop (void *cls, struct GNUNET_SERVER_Client *client, peer = GST_peer_list[peer_id]; if (GNUNET_YES == peer->is_remote) { - LOG (GNUNET_ERROR_TYPE_DEBUG, "Forwarding PEER_STOP for peer %u\n", - peer_id); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Forwarding PEER_STOP for peer %u\n", + (unsigned int) peer_id); fopc = GNUNET_new (struct ForwardedOperationContext); GNUNET_SERVER_client_keep (client); fopc->client = client; @@ -633,25 +646,35 @@ GST_handle_peer_stop (void *cls, struct GNUNET_SERVER_Client *client, fopc->opc = GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote. slave->controller, - fopc->operation_id, &msg->header, + fopc->operation_id, + &msg->header, &GST_forwarded_operation_reply_relay, fopc); fopc->timeout_task = - GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout, + GNUNET_SCHEDULER_add_delayed (GST_timeout, + &GST_forwarded_operation_timeout, + fopc); + GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, + fopcq_tail, fopc); - GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } if (GNUNET_OK != stop_peer (peer)) { - LOG (GNUNET_ERROR_TYPE_WARNING, "Stopping peer %u failed\n", peer_id); - GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), + LOG (GNUNET_ERROR_TYPE_WARNING, + "Stopping peer %u failed\n", + (unsigned int) peer_id); + GST_send_operation_fail_msg (client, + GNUNET_ntohll (msg->operation_id), "Peer not running"); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_SERVER_receive_done (client, + GNUNET_OK); return; } - LOG (GNUNET_ERROR_TYPE_DEBUG, "Peer %u successfully stopped\n", peer_id); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Peer %u successfully stopped\n", + (unsigned int) peer_id); reply = GNUNET_new (struct GNUNET_TESTBED_PeerEventMessage); reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT); reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerEventMessage)); @@ -689,10 +712,12 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client, msg = (const struct GNUNET_TESTBED_PeerGetConfigurationMessage *) message; peer_id = ntohl (msg->peer_id); - LOG_DEBUG ("Received GET_CONFIG for peer %u\n", peer_id); + LOG_DEBUG ("Received GET_CONFIG for peer %u\n", + (unsigned int) peer_id); if (!VALID_PEER_ID (peer_id)) { - GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), + GST_send_operation_fail_msg (client, + GNUNET_ntohll (msg->operation_id), "Peer not found"); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; @@ -700,7 +725,8 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client, peer = GST_peer_list[peer_id]; if (GNUNET_YES == peer->is_remote) { - LOG_DEBUG ("Forwarding PEER_GET_CONFIG for peer: %u\n", peer_id); + LOG_DEBUG ("Forwarding PEER_GET_CONFIG for peer: %u\n", + (unsigned int) peer_id); fopc = GNUNET_new (struct ForwardedOperationContext); GNUNET_SERVER_client_keep (client); fopc->client = client; @@ -709,21 +735,28 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client, fopc->opc = GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote. slave->controller, - fopc->operation_id, &msg->header, + fopc->operation_id, + &msg->header, &GST_forwarded_operation_reply_relay, fopc); fopc->timeout_task = - GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout, + GNUNET_SCHEDULER_add_delayed (GST_timeout, + &GST_forwarded_operation_timeout, + fopc); + GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, + fopcq_tail, fopc); - GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } - LOG_DEBUG ("Received PEER_GET_CONFIG for peer: %u\n", peer_id); + LOG_DEBUG ("Received PEER_GET_CONFIG for peer: %u\n", + peer_id); config = GNUNET_CONFIGURATION_serialize (GST_peer_list[peer_id]->details.local.cfg, &c_size); - xc_size = GNUNET_TESTBED_compress_config_ (config, c_size, &xconfig); + xc_size = GNUNET_TESTBED_compress_config_ (config, + c_size, + &xconfig); GNUNET_free (config); msize = xc_size + @@ -799,7 +832,8 @@ update_peer_config (struct Peer *peer, emsg = NULL; peer->details.local.peer = GNUNET_TESTING_peer_configure (GST_context->system, - peer->details.local.cfg, peer->id, + peer->details.local.cfg, + peer->id, NULL /* Peer id */ , &emsg); return emsg; @@ -811,11 +845,13 @@ update_peer_config (struct Peer *peer, * * @param cls the closure given to GNUNET_TESTING_peer_stop_async() * @param p the respective peer whose status is being reported - * @param success GNUNET_YES if the peer is stopped; GNUNET_SYSERR upon any + * @param success #GNUNET_YES if the peer is stopped; #GNUNET_SYSERR upon any * error */ static void -prc_stop_cb (void *cls, struct GNUNET_TESTING_Peer *p, int success) +prc_stop_cb (void *cls, + struct GNUNET_TESTING_Peer *p, + int success) { struct PeerReconfigureContext *prc = cls; struct Peer *peer; @@ -829,16 +865,20 @@ prc_stop_cb (void *cls, struct GNUNET_TESTING_Peer *p, int success) prc->stopped = 1; if (NULL != emsg) { - GST_send_operation_fail_msg (prc->client, prc->op_id, emsg); + GST_send_operation_fail_msg (prc->client, + prc->op_id, + emsg); goto cleanup; } if (GNUNET_OK != start_peer (peer)) { - GST_send_operation_fail_msg (prc->client, prc->op_id, + GST_send_operation_fail_msg (prc->client, + prc->op_id, "Failed to start reconfigured peer"); goto cleanup; } - GST_send_operation_success_msg (prc->client, prc->op_id); + GST_send_operation_success_msg (prc->client, + prc->op_id); cleanup: cleanup_prc (prc); @@ -847,7 +887,7 @@ prc_stop_cb (void *cls, struct GNUNET_TESTING_Peer *p, int success) /** - * Handler for GNUNET_MESSAGE_TYPDE_TESTBED_RECONFIGURE_PEER type messages. + * Handler for #GNUNET_MESSAGE_TYPDE_TESTBED_RECONFIGURE_PEER type messages. * Should stop the peer asyncronously, destroy it and create it again with the * new configuration. * @@ -856,7 +896,8 @@ prc_stop_cb (void *cls, struct GNUNET_TESTING_Peer *p, int success) * @param message the actual message */ void -GST_handle_peer_reconfigure (void *cls, struct GNUNET_SERVER_Client *client, +GST_handle_peer_reconfigure (void *cls, + struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { const struct GNUNET_TESTBED_PeerReconfigureMessage *msg; @@ -873,7 +914,8 @@ GST_handle_peer_reconfigure (void *cls, struct GNUNET_SERVER_Client *client, if (msize <= sizeof (struct GNUNET_TESTBED_PeerReconfigureMessage)) { GNUNET_break_op (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + GNUNET_SERVER_receive_done (client, + GNUNET_SYSERR); return; } msg = (const struct GNUNET_TESTBED_PeerReconfigureMessage *) message; @@ -882,8 +924,11 @@ GST_handle_peer_reconfigure (void *cls, struct GNUNET_SERVER_Client *client, if (!VALID_PEER_ID (peer_id)) { GNUNET_break (0); - GST_send_operation_fail_msg (client, op_id, "Peer not found"); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GST_send_operation_fail_msg (client, + op_id, + "Peer not found"); + GNUNET_SERVER_receive_done (client, + GNUNET_OK); return; } peer = GST_peer_list[peer_id]; @@ -898,60 +943,85 @@ GST_handle_peer_reconfigure (void *cls, struct GNUNET_SERVER_Client *client, fopc->opc = GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote. slave->controller, - fopc->operation_id, &msg->header, + fopc->operation_id, + &msg->header, &GST_forwarded_operation_reply_relay, fopc); fopc->timeout_task = - GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout, + GNUNET_SCHEDULER_add_delayed (GST_timeout, + &GST_forwarded_operation_timeout, + fopc); + GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, + fopcq_tail, fopc); - GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } - LOG_DEBUG ("Received PEER_RECONFIGURE for peer %u\n", peer_id); + LOG_DEBUG ("Received PEER_RECONFIGURE for peer %u\n", + (unsigned int) peer_id); if (0 < peer->reference_cnt) { GNUNET_break (0); - GST_send_operation_fail_msg (client, op_id, "Peer in use"); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GST_send_operation_fail_msg (client, + op_id, + "Peer in use"); + GNUNET_SERVER_receive_done (client, + GNUNET_OK); return; } if (GNUNET_YES == peer->destroy_flag) { GNUNET_break (0); - GST_send_operation_fail_msg (client, op_id, "Peer is being destroyed"); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GST_send_operation_fail_msg (client, + op_id, + "Peer is being destroyed"); + GNUNET_SERVER_receive_done (client, + GNUNET_OK); return; } cfg = GNUNET_TESTBED_extract_config_ (message); if (NULL == cfg) { GNUNET_break (0); - GST_send_operation_fail_msg (client, op_id, "Compression error"); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GST_send_operation_fail_msg (client, + op_id, + "Compression error"); + GNUNET_SERVER_receive_done (client, + GNUNET_OK); return; } if (GNUNET_NO == peer->details.local.is_running) { - emsg = update_peer_config (peer, cfg); + emsg = update_peer_config (peer, + cfg); if (NULL != emsg) - GST_send_operation_fail_msg (client, op_id, emsg); - GST_send_operation_success_msg (client, op_id); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GST_send_operation_fail_msg (client, + op_id, + emsg); + GST_send_operation_success_msg (client, + op_id); + GNUNET_SERVER_receive_done (client, + GNUNET_OK); GNUNET_free_non_null (emsg); return; } prc = GNUNET_new (struct PeerReconfigureContext); if (GNUNET_OK != - GNUNET_TESTING_peer_stop_async (peer->details.local.peer, &prc_stop_cb, + GNUNET_TESTING_peer_stop_async (peer->details.local.peer, + &prc_stop_cb, prc)) { GNUNET_assert (0 < GNUNET_asprintf (&emsg, "Error trying to stop peer %u asynchronously\n", peer_id)); - LOG (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg); - GST_send_operation_fail_msg (client, op_id, emsg); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + LOG (GNUNET_ERROR_TYPE_ERROR, + "%s\n", + emsg); + GST_send_operation_fail_msg (client, + op_id, + emsg); + GNUNET_SERVER_receive_done (client, + GNUNET_OK); GNUNET_free (prc); GNUNET_free (emsg); return; @@ -961,8 +1031,11 @@ GST_handle_peer_reconfigure (void *cls, struct GNUNET_SERVER_Client *client, prc->op_id = op_id; prc->client = client; GNUNET_SERVER_client_keep (client); - GNUNET_CONTAINER_DLL_insert_tail (prc_head, prc_tail, prc); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_CONTAINER_DLL_insert_tail (prc_head, + prc_tail, + prc); + GNUNET_SERVER_receive_done (client, + GNUNET_OK); } @@ -975,14 +1048,17 @@ static void cleanup_mctx (struct ManageServiceContext *mctx) { mctx->expired = GNUNET_YES; - GNUNET_CONTAINER_DLL_remove (mctx_head, mctx_tail, mctx); + GNUNET_CONTAINER_DLL_remove (mctx_head, + mctx_tail, + mctx); GNUNET_SERVER_client_drop (mctx->client); - GNUNET_ARM_disconnect_and_free (mctx->ah); + GNUNET_ARM_disconnect (mctx->ah); GNUNET_assert (0 < mctx->peer->reference_cnt); mctx->peer->reference_cnt--; if ( (GNUNET_YES == mctx->peer->destroy_flag) && (0 == mctx->peer->reference_cnt) ) GST_destroy_peer (mctx->peer); + GNUNET_free (mctx->service); GNUNET_free (mctx); } @@ -999,7 +1075,7 @@ GST_free_mctxq () /** - * Returns a string interpretation of 'rs' + * Returns a string interpretation of @a rs. * * @param rs the request status from ARM * @return a string interpretation of the request status @@ -1017,8 +1093,6 @@ arm_req_string (enum GNUNET_ARM_RequestStatus rs) return _("We disconnected from ARM before we could send a request"); case GNUNET_ARM_REQUEST_BUSY: return _("ARM API is busy"); - case GNUNET_ARM_REQUEST_TOO_LONG: - return _("Request doesn't fit into a message"); case GNUNET_ARM_REQUEST_TIMEOUT: return _("Request timed out"); } @@ -1027,7 +1101,7 @@ arm_req_string (enum GNUNET_ARM_RequestStatus rs) /** - * Returns a string interpretation of the 'result' + * Returns a string interpretation of the @a result. * * @param result the arm result * @return a string interpretation @@ -1066,17 +1140,16 @@ arm_ret_string (enum GNUNET_ARM_Result result) * Function called in response to a start/stop request. * Will be called when request was not sent successfully, * or when a reply comes. If the request was not sent successfully, - * 'rs' will indicate that, and 'service' and 'result' will be undefined. + * @a rs will indicate that, and @a result will be undefined. * * @param cls ManageServiceContext * @param rs status of the request - * @param service service name * @param result result of the operation */ static void service_manage_result_cb (void *cls, enum GNUNET_ARM_RequestStatus rs, - const char *service, enum GNUNET_ARM_Result result) + enum GNUNET_ARM_Result result) { struct ManageServiceContext *mctx = cls; char *emsg; @@ -1086,8 +1159,10 @@ service_manage_result_cb (void *cls, return; if (GNUNET_ARM_REQUEST_SENT_OK != rs) { - GNUNET_asprintf (&emsg, "Error communicating with Peer %u's ARM: %s", - mctx->peer->id, arm_req_string (rs)); + GNUNET_asprintf (&emsg, + "Error communicating with Peer %u's ARM: %s", + mctx->peer->id, + arm_req_string (rs)); goto ret; } if (1 == mctx->start) @@ -1098,7 +1173,9 @@ service_manage_result_cb (void *cls, || (GNUNET_ARM_RESULT_IS_STOPPED_ALREADY == result)) ) { /* stopping a service failed */ - GNUNET_asprintf (&emsg, arm_ret_string (result), service); + GNUNET_asprintf (&emsg, + arm_ret_string (result), + mctx->service); goto ret; } /* service stopped successfully */ @@ -1110,7 +1187,9 @@ service_manage_result_cb (void *cls, || (GNUNET_ARM_RESULT_IS_STARTED_ALREADY == result)) ) { /* starting a service failed */ - GNUNET_asprintf (&emsg, arm_ret_string (result), service); + GNUNET_asprintf (&emsg, + arm_ret_string (result), + mctx->service); goto ret; } /* service started successfully */ @@ -1119,10 +1198,13 @@ service_manage_result_cb (void *cls, if (NULL != emsg) { LOG_DEBUG ("%s\n", emsg); - GST_send_operation_fail_msg (mctx->client, mctx->op_id, emsg); + GST_send_operation_fail_msg (mctx->client, + mctx->op_id, + emsg); } else - GST_send_operation_success_msg (mctx->client, mctx->op_id); + GST_send_operation_success_msg (mctx->client, + mctx->op_id); GNUNET_free_non_null (emsg); cleanup_mctx (mctx); } @@ -1136,7 +1218,8 @@ service_manage_result_cb (void *cls, * @param message the actual message */ void -GST_handle_manage_peer_service (void *cls, struct GNUNET_SERVER_Client *client, +GST_handle_manage_peer_service (void *cls, + struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { const struct GNUNET_TESTBED_ManagePeerServiceMessage *msg; @@ -1202,13 +1285,17 @@ GST_handle_manage_peer_service (void *cls, struct GNUNET_SERVER_Client *client, fopc->opc = GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote. slave->controller, - fopc->operation_id, &msg->header, + fopc->operation_id, + &msg->header, &GST_forwarded_operation_reply_relay, fopc); fopc->timeout_task = - GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout, + GNUNET_SCHEDULER_add_delayed (GST_timeout, + &GST_forwarded_operation_timeout, + fopc); + GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, + fopcq_tail, fopc); - GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } @@ -1242,17 +1329,19 @@ GST_handle_manage_peer_service (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_client_keep (client); mctx->client = client; mctx->start = msg->start; - GNUNET_CONTAINER_DLL_insert_tail (mctx_head, mctx_tail, mctx); + mctx->service = GNUNET_strdup (service); + GNUNET_CONTAINER_DLL_insert_tail (mctx_head, + mctx_tail, + mctx); if (1 == mctx->start) - GNUNET_ARM_request_service_start (mctx->ah, service, + GNUNET_ARM_request_service_start (mctx->ah, + service, GNUNET_OS_INHERIT_STD_ERR, - GST_timeout, - service_manage_result_cb, + &service_manage_result_cb, mctx); else GNUNET_ARM_request_service_stop (mctx->ah, service, - GST_timeout, - service_manage_result_cb, + &service_manage_result_cb, mctx); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; @@ -1334,28 +1423,33 @@ shutdown_peers_reply_cb (void *cls, if (0 == hc->nslaves) { if (GNUNET_YES == hc->timeout) - GST_send_operation_fail_msg (fo_ctxt->client, fo_ctxt->operation_id, + GST_send_operation_fail_msg (fo_ctxt->client, + fo_ctxt->operation_id, "Timeout at a slave controller"); else - GST_send_operation_success_msg (fo_ctxt->client, fo_ctxt->operation_id); + GST_send_operation_success_msg (fo_ctxt->client, + fo_ctxt->operation_id); GNUNET_free (hc); hc = NULL; } GNUNET_SERVER_client_drop (fo_ctxt->client); - GNUNET_CONTAINER_DLL_remove (fopcq_head, fopcq_tail, fo_ctxt); + GNUNET_CONTAINER_DLL_remove (fopcq_head, + fopcq_tail, + fo_ctxt); GNUNET_free (fo_ctxt); } /** - * Handler for GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS messages + * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS messages * * @param cls NULL * @param client identification of the client * @param message the actual message */ void -GST_handle_shutdown_peers (void *cls, struct GNUNET_SERVER_Client *client, +GST_handle_shutdown_peers (void *cls, + struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { const struct GNUNET_TESTBED_ShutdownPeersMessage *msg; @@ -1398,14 +1492,18 @@ GST_handle_shutdown_peers (void *cls, struct GNUNET_SERVER_Client *client, &msg->header, shutdown_peers_reply_cb, fo_ctxt); - GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fo_ctxt); + GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, + fopcq_tail, + fo_ctxt); } LOG_DEBUG ("Shutting down peers\n"); GST_destroy_peers (); if (0 == hc->nslaves) { - GST_send_operation_success_msg (client, op_id); + GST_send_operation_success_msg (client, + op_id); GNUNET_free (hc); } - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_SERVER_receive_done (client, + GNUNET_OK); } diff --git a/src/testbed/test_testbed_api.c b/src/testbed/test_testbed_api.c index fdf9d80f9d..83203e71e3 100644 --- a/src/testbed/test_testbed_api.c +++ b/src/testbed/test_testbed_api.c @@ -219,7 +219,7 @@ arm_disconnect_adapter (void *cls, void *op_result) { FAIL_TEST (NULL != op_result, return); FAIL_TEST (op_result == arm_handle, return); - GNUNET_ARM_disconnect_and_free (arm_handle); + GNUNET_ARM_disconnect (arm_handle); arm_handle = NULL; FAIL_TEST (PEER_SERVICE_CONNECT == sub_test, return); FAIL_TEST (NULL != operation, return); @@ -451,11 +451,13 @@ run (void *cls, char *const *args, const char *cfgfile, cfg = GNUNET_CONFIGURATION_dup (config); host = GNUNET_TESTBED_host_create (NULL, NULL, cfg, 0); FAIL_TEST (NULL != host, return); - cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, status_cb, + cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, + &status_cb, NULL); abort_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MINUTES, 5), &do_abort, + (GNUNET_TIME_UNIT_MINUTES, 5), + &do_abort, NULL); } diff --git a/src/testbed/test_testbed_logger_api.c b/src/testbed/test_testbed_logger_api.c index f140dfbadc..a25c0c5f0c 100644 --- a/src/testbed/test_testbed_logger_api.c +++ b/src/testbed/test_testbed_logger_api.c @@ -17,13 +17,11 @@ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /** * @file testbed/test_testbed_logger_api.c * @brief testcases for the testbed logger api * @author Sree Harsha Totakura */ - #include "platform.h" #include "gnunet_util_lib.h" #include "gnunet_testing_lib.h" @@ -53,8 +51,8 @@ static char *search_dir; /** * Abort task identifier */ -static struct GNUNET_SCHEDULER_Task * abort_task; -static struct GNUNET_SCHEDULER_Task * write_task; +static struct GNUNET_SCHEDULER_Task *abort_task; +static struct GNUNET_SCHEDULER_Task *write_task; static int result; @@ -78,6 +76,7 @@ static int result; } \ } while (0) + /** * Shutdown nicely * @@ -99,7 +98,8 @@ shutdown_now () static void do_abort (void *cls) { - LOG (GNUNET_ERROR_TYPE_WARNING, "Aborting\n"); + LOG (GNUNET_ERROR_TYPE_WARNING, + "Aborting\n"); abort_task = NULL; shutdown_now (); } @@ -125,20 +125,34 @@ iterator_cb (void *cls, size_t len; uint64_t fs; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Iterator sees file %s\n", + filename); len = strlen (filename); - if (len < 5) /* log file: `pid'.dat */ - return GNUNET_OK; - fn = filename + len; if (0 != strcasecmp (".dat", fn - 4)) return GNUNET_OK; if (GNUNET_OK != - GNUNET_DISK_file_size (filename, &fs, - GNUNET_NO, GNUNET_YES)) + GNUNET_DISK_file_size (filename, + &fs, + GNUNET_NO, + GNUNET_YES)) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Failed to obtain file size for file %s\n", + filename); return GNUNET_SYSERR; - if ((BSIZE * 2) != fs) /* The file size should be equal to what we - have written */ + } + if ((BSIZE * 2) != fs) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Unexpected file size for file %s\n", + filename); + /* The file size should be equal to what we + have written */ return GNUNET_SYSERR; + } + result = GNUNET_OK; return GNUNET_OK; } @@ -151,11 +165,21 @@ iterator_cb (void *cls, * @param size the amount of data sent */ static void -flush_comp (void *cls, size_t size) +flush_comp (void *cls, + size_t size) { - FAIL_TEST (&write_task == cls, return); - FAIL_TEST ((BSIZE * 2) == size, return); - FAIL_TEST (GNUNET_OK == GNUNET_TESTING_peer_stop (peer), return); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Flush running\n"); + FAIL_TEST (&write_task == cls, + return); + FAIL_TEST ((BSIZE * 2) == size, + return); + FAIL_TEST (GNUNET_OK == + GNUNET_TESTING_peer_stop (peer), + return); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Peer stopped, scanning %s\n", + search_dir); FAIL_TEST (GNUNET_SYSERR != GNUNET_DISK_directory_scan (search_dir, &iterator_cb, @@ -172,17 +196,22 @@ do_write (void *cls) char buf[BSIZE]; write_task = NULL; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Write task running\n"); if (0 == i) write_task = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS(1), &do_write, NULL); (void) memset (buf, i, BSIZE); - GNUNET_TESTBED_LOGGER_write (h, buf, BSIZE); + GNUNET_TESTBED_LOGGER_write (h, + buf, + BSIZE); if (0 == i++) return; GNUNET_TESTBED_LOGGER_flush (h, GNUNET_TIME_UNIT_FOREVER_REL, - &flush_comp, &write_task); + &flush_comp, + &write_task); } @@ -199,13 +228,22 @@ test_main (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TESTING_Peer *p) { - FAIL_TEST (NULL != (h = GNUNET_TESTBED_LOGGER_connect (cfg)), return); - FAIL_TEST (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename - (cfg, "testbed-logger", "dir", &search_dir), return); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Connecting to logger\n"); + FAIL_TEST (NULL != (h = GNUNET_TESTBED_LOGGER_connect (cfg)), + return); + FAIL_TEST (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, + "testbed-logger", + "dir", + &search_dir), + return); peer = p; - write_task = GNUNET_SCHEDULER_add_now (&do_write, NULL); + write_task = GNUNET_SCHEDULER_add_now (&do_write, + NULL); abort_task = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (10), - &do_abort, NULL); + &do_abort, + NULL); } @@ -218,6 +256,9 @@ main (int argc, char **argv) int ret; result = GNUNET_SYSERR; + GNUNET_log_setup ("test-testbed-logger-api", + "WARNING", + NULL); ret = GNUNET_TESTING_service_run ("test-testbed-logger", "testbed-logger", "test_testbed_logger_api.conf", diff --git a/src/testing/testing.c b/src/testing/testing.c index 32cd09b84b..13ebabd1dc 100644 --- a/src/testing/testing.c +++ b/src/testing/testing.c @@ -1355,65 +1355,6 @@ GNUNET_TESTING_peer_start (struct GNUNET_TESTING_Peer *peer) /** - * Start a service at a peer using its ARM service - * - * @param peer the peer whose service has to be started - * @param service_name name of the service to start - * @param timeout how long should the ARM API try to send the request to start - * the service - * @param cont the callback to call with result and status from ARM API - * @param cont_cls the closure for the above callback - * @return #GNUNET_OK upon successfully queuing the service start request; - * #GNUNET_SYSERR upon error - */ -int -GNUNET_TESTING_peer_service_start (struct GNUNET_TESTING_Peer *peer, - const char *service_name, - struct GNUNET_TIME_Relative timeout, - GNUNET_ARM_ResultCallback cont, - void *cont_cls) -{ - if (NULL == peer->ah) - return GNUNET_SYSERR; - GNUNET_ARM_request_service_start (peer->ah, - service_name, - GNUNET_OS_INHERIT_STD_ALL, - timeout, - cont, cont_cls); - return GNUNET_OK; -} - - -/** - * Stop a service at a peer using its ARM service - * - * @param peer the peer whose service has to be stopped - * @param service_name name of the service to stop - * @param timeout how long should the ARM API try to send the request to stop - * the service - * @param cont the callback to call with result and status from ARM API - * @param cont_cls the closure for the above callback - * @return #GNUNET_OK upon successfully queuing the service stop request; - * #GNUNET_SYSERR upon error - */ -int -GNUNET_TESTING_peer_service_stop (struct GNUNET_TESTING_Peer *peer, - const char *service_name, - struct GNUNET_TIME_Relative timeout, - GNUNET_ARM_ResultCallback cont, - void *cont_cls) -{ - if (NULL == peer->ah) - return GNUNET_SYSERR; - GNUNET_ARM_request_service_stop (peer->ah, - service_name, - timeout, - cont, cont_cls); - return GNUNET_OK; -} - - -/** * Sends SIGTERM to the peer's main process * * @param peer the handle to the peer @@ -1510,7 +1451,7 @@ disconn_status (void *cls, return; } GNUNET_break (GNUNET_OK == GNUNET_TESTING_peer_wait (peer)); - GNUNET_ARM_disconnect_and_free (peer->ah); + GNUNET_ARM_disconnect (peer->ah); peer->ah = NULL; peer->cb (peer->cb_cls, peer, GNUNET_YES); } @@ -1556,7 +1497,7 @@ void GNUNET_TESTING_peer_stop_async_cancel (struct GNUNET_TESTING_Peer *peer) { GNUNET_assert (NULL != peer->ah); - GNUNET_ARM_disconnect_and_free (peer->ah); + GNUNET_ARM_disconnect (peer->ah); peer->ah = NULL; } @@ -1576,9 +1517,9 @@ GNUNET_TESTING_peer_destroy (struct GNUNET_TESTING_Peer *peer) if (NULL != peer->main_process) GNUNET_TESTING_peer_stop (peer); if (NULL != peer->ah) - GNUNET_ARM_disconnect_and_free (peer->ah); + GNUNET_ARM_disconnect (peer->ah); if (NULL != peer->mh) - GNUNET_ARM_monitor_disconnect_and_free (peer->mh); + GNUNET_ARM_monitor_stop (peer->mh); GNUNET_free (peer->cfgfile); if (NULL != peer->cfg) GNUNET_CONFIGURATION_destroy (peer->cfg); |