aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arm/arm_api.c1219
-rw-r--r--src/arm/arm_monitor_api.c13
-rw-r--r--src/arm/gnunet-arm.c159
-rw-r--r--src/arm/test_arm_api.c109
-rw-r--r--src/arm/test_exponential_backoff.c70
-rw-r--r--src/arm/test_gnunet_service_arm.c36
-rw-r--r--src/include/gnunet_arm_service.h109
-rw-r--r--src/include/gnunet_testbed_logger_service.h7
-rw-r--r--src/include/gnunet_testing_lib.h18
-rw-r--r--src/testbed/gnunet-service-testbed_peers.c276
-rw-r--r--src/testbed/test_testbed_api.c8
-rw-r--r--src/testbed/test_testbed_logger_api.c87
-rw-r--r--src/testing/testing.c67
13 files changed, 1066 insertions, 1112 deletions
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c
index a89d423ec..ed36c61cd 100644
--- a/src/arm/arm_api.c
+++ b/src/arm/arm_api.c
@@ -32,151 +32,131 @@
32 32
33#define LOG(kind,...) GNUNET_log_from (kind, "arm-api",__VA_ARGS__) 33#define LOG(kind,...) GNUNET_log_from (kind, "arm-api",__VA_ARGS__)
34 34
35
35/** 36/**
36 * Handle for interacting with ARM. 37 * Entry in a doubly-linked list of operations awaiting for replies
38 * (in-order) from the ARM service.
37 */ 39 */
38struct GNUNET_ARM_Handle 40struct GNUNET_ARM_Operation
39{ 41{
40 /** 42 /**
41 * Our control connection to the ARM service. 43 * This is a doubly-linked list.
42 */
43 struct GNUNET_CLIENT_Connection *client;
44
45 /**
46 * The configuration that we are using.
47 */
48 struct GNUNET_CONFIGURATION_Handle *cfg;
49
50 /**
51 * Handle for our current transmission request.
52 */
53 struct GNUNET_CLIENT_TransmitHandle *cth;
54
55 /**
56 * Head of doubly-linked list of pending requests.
57 */
58 struct ARMControlMessage *control_pending_head;
59
60 /**
61 * Tail of doubly-linked list of pending requests.
62 */
63 struct ARMControlMessage *control_pending_tail;
64
65 /**
66 * Head of doubly-linked list of sent requests.
67 */ 44 */
68 struct ARMControlMessage *control_sent_head; 45 struct GNUNET_ARM_Operation *next;
69 46
70 /** 47 /**
71 * Tail of doubly-linked list of sent requests. 48 * This is a doubly-linked list.
72 */ 49 */
73 struct ARMControlMessage *control_sent_tail; 50 struct GNUNET_ARM_Operation *prev;
74 51
75 /** 52 /**
76 * Callback to invoke on connection/disconnection. 53 * ARM handle.
77 */ 54 */
78 GNUNET_ARM_ConnectionStatusCallback conn_status; 55 struct GNUNET_ARM_Handle *h;
79 56
80 /** 57 /**
81 * Closure for conn_status. 58 * Callback for service state change requests.
82 */ 59 */
83 void *conn_status_cls; 60 GNUNET_ARM_ResultCallback result_cont;
84 61
85 /** 62 /**
86 * ARM control message for the 'arm_termination_handler' 63 * Callback for service list requests.
87 * with the continuation to call once the ARM shutdown is done.
88 */ 64 */
89 struct ARMControlMessage *thm; 65 GNUNET_ARM_ServiceListCallback list_cont;
90 66
91 /** 67 /**
92 * ID of the reconnect task (if any). 68 * Closure for @e result_cont or @e list_cont.
93 */ 69 */
94 struct GNUNET_SCHEDULER_Task *reconnect_task; 70 void *cont_cls;
95 71
96 /** 72 /**
97 * Current delay we use for re-trying to connect to core. 73 * Task for async completion.
98 */ 74 */
99 struct GNUNET_TIME_Relative retry_backoff; 75 struct GNUNET_SCHEDULER_Task *async;
100 76
101 /** 77 /**
102 * Counter for request identifiers 78 * Unique ID for the request.
103 */ 79 */
104 uint64_t request_id_counter; 80 uint64_t id;
105 81
106 /** 82 /**
107 * Are we currently disconnected and hence unable to send? 83 * Result of this operation for #notify_starting().
108 */ 84 */
109 unsigned char currently_down; 85 enum GNUNET_ARM_Result starting_ret;
110 86
111 /** 87 /**
112 * #GNUNET_YES if we're running a service test. 88 * Is this an operation to stop the ARM service?
113 */ 89 */
114 unsigned char service_test_is_active; 90 int is_arm_stop;
115}; 91};
116 92
117 93
118/** 94/**
119 * Entry in a doubly-linked list of control messages to be transmitted 95 * Handle for interacting with ARM.
120 * to the arm service.
121 *
122 * The actual message is allocated at the end of this struct.
123 */ 96 */
124struct ARMControlMessage 97struct GNUNET_ARM_Handle
125{ 98{
126 /** 99 /**
127 * This is a doubly-linked list. 100 * Our connection to the ARM service.
128 */ 101 */
129 struct ARMControlMessage *next; 102 struct GNUNET_MQ_Handle *mq;
130 103
131 /** 104 /**
132 * This is a doubly-linked list. 105 * The configuration that we are using.
133 */ 106 */
134 struct ARMControlMessage *prev; 107 const struct GNUNET_CONFIGURATION_Handle *cfg;
135 108
136 /** 109 /**
137 * ARM handle. 110 * Head of doubly-linked list of pending operations.
138 */ 111 */
139 struct GNUNET_ARM_Handle *h; 112 struct GNUNET_ARM_Operation *operation_pending_head;
140 113
141 /** 114 /**
142 * Message to send. 115 * Tail of doubly-linked list of pending operations.
143 */ 116 */
144 struct GNUNET_ARM_Message *msg; 117 struct GNUNET_ARM_Operation *operation_pending_tail;
145 118
146 /** 119 /**
147 * Callback for service state change requests. 120 * Callback to invoke on connection/disconnection.
148 */ 121 */
149 GNUNET_ARM_ResultCallback result_cont; 122 GNUNET_ARM_ConnectionStatusCallback conn_status;
150 123
151 /** 124 /**
152 * Callback for service list requests. 125 * Closure for @e conn_status.
153 */ 126 */
154 GNUNET_ARM_ServiceListCallback list_cont; 127 void *conn_status_cls;
155 128
156 /** 129 /**
157 * Closure for @e result_cont or @e list_cont. 130 * ARM operation where the goal is to wait for ARM shutdown to
131 * complete. This operation is special in that it waits for an
132 * error on the @e mq. So we complete it by calling the
133 * continuation in the #mq_error_handler(). Note that the operation
134 * is no longer in the @e operation_pending_head DLL once it is
135 * referenced from this field.
158 */ 136 */
159 void *cont_cls; 137 struct GNUNET_ARM_Operation *thm;
160 138
161 /** 139 /**
162 * Timeout for the operation. 140 * ID of the reconnect task (if any).
163 */ 141 */
164 struct GNUNET_TIME_Absolute timeout; 142 struct GNUNET_SCHEDULER_Task *reconnect_task;
165 143
166 /** 144 /**
167 * Task to run when request times out. 145 * Current delay we use for re-trying to connect to core.
168 */ 146 */
169 struct GNUNET_SCHEDULER_Task *timeout_task_id; 147 struct GNUNET_TIME_Relative retry_backoff;
170 148
171 /** 149 /**
172 * Flags for passing std descriptors to ARM (when starting ARM). 150 * Counter for request identifiers. They are used to match replies
151 * from ARM to operations in the @e operation_pending_head DLL.
173 */ 152 */
174 enum GNUNET_OS_InheritStdioFlags std_inheritance; 153 uint64_t request_id_counter;
175 154
176 /** 155 /**
177 * Type of the request expressed as a message type (start, stop or list). 156 * Have we detected that ARM is up?
178 */ 157 */
179 uint16_t type; 158 int currently_up;
159
180}; 160};
181 161
182 162
@@ -191,18 +171,6 @@ reconnect_arm (struct GNUNET_ARM_Handle *h);
191 171
192 172
193/** 173/**
194 * Check the list of pending requests, send the next
195 * one to the arm.
196 *
197 * @param h arm handle
198 * @param ignore_currently_down transmit message even if not initialized?
199 */
200static void
201trigger_next_request (struct GNUNET_ARM_Handle *h,
202 int ignore_currently_down);
203
204
205/**
206 * Task scheduled to try to re-connect to arm. 174 * Task scheduled to try to re-connect to arm.
207 * 175 *
208 * @param cls the `struct GNUNET_ARM_Handle` 176 * @param cls the `struct GNUNET_ARM_Handle`
@@ -213,8 +181,6 @@ reconnect_arm_task (void *cls)
213 struct GNUNET_ARM_Handle *h = cls; 181 struct GNUNET_ARM_Handle *h = cls;
214 182
215 h->reconnect_task = NULL; 183 h->reconnect_task = NULL;
216 LOG (GNUNET_ERROR_TYPE_DEBUG,
217 "Connecting to ARM service after delay\n");
218 reconnect_arm (h); 184 reconnect_arm (h);
219} 185}
220 186
@@ -228,28 +194,33 @@ reconnect_arm_task (void *cls)
228static void 194static void
229reconnect_arm_later (struct GNUNET_ARM_Handle *h) 195reconnect_arm_later (struct GNUNET_ARM_Handle *h)
230{ 196{
231 if (GNUNET_NO != h->currently_down) 197 struct GNUNET_ARM_Operation *op;
232 return; 198
233 if (NULL != h->cth) 199 if (NULL != h->mq)
234 {
235 GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth);
236 h->cth = NULL;
237 }
238 if (NULL != h->client)
239 { 200 {
240 GNUNET_CLIENT_disconnect (h->client); 201 GNUNET_MQ_destroy (h->mq);
241 h->client = NULL; 202 h->mq = NULL;
242 } 203 }
243 h->currently_down = GNUNET_YES; 204 h->currently_up = GNUNET_NO;
244 GNUNET_assert (NULL == h->reconnect_task); 205 GNUNET_assert (NULL == h->reconnect_task);
245 h->reconnect_task = 206 h->reconnect_task =
246 GNUNET_SCHEDULER_add_delayed (h->retry_backoff, 207 GNUNET_SCHEDULER_add_delayed (h->retry_backoff,
247 &reconnect_arm_task, 208 &reconnect_arm_task,
248 h); 209 h);
249 /* Don't clear pending messages on disconnection, deliver them later 210 while (NULL != (op = h->operation_pending_head))
250 clear_pending_messages (h, GNUNET_ARM_REQUEST_DISCONNECTED); 211 {
251 GNUNET_assert (NULL == h->control_pending_head); 212 if (NULL != op->result_cont)
252 */ 213 op->result_cont (op->cont_cls,
214 GNUNET_ARM_REQUEST_DISCONNECTED,
215 0);
216 if (NULL != op->list_cont)
217 op->list_cont (op->cont_cls,
218 GNUNET_ARM_REQUEST_DISCONNECTED,
219 0,
220 NULL);
221 GNUNET_ARM_operation_cancel (op);
222 }
223 GNUNET_assert (NULL == h->operation_pending_head);
253 h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); 224 h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff);
254 if (NULL != h->conn_status) 225 if (NULL != h->conn_status)
255 h->conn_status (h->conn_status_cls, 226 h->conn_status (h->conn_status_cls,
@@ -264,176 +235,50 @@ reconnect_arm_later (struct GNUNET_ARM_Handle *h)
264 * @param id unique message ID to use for the lookup 235 * @param id unique message ID to use for the lookup
265 * @return NULL if not found 236 * @return NULL if not found
266 */ 237 */
267static struct ARMControlMessage * 238static struct GNUNET_ARM_Operation *
268find_cm_by_id (struct GNUNET_ARM_Handle *h, 239find_op_by_id (struct GNUNET_ARM_Handle *h,
269 uint64_t id) 240 uint64_t id)
270{ 241{
271 struct ARMControlMessage *result; 242 struct GNUNET_ARM_Operation *result;
272 243
273 for (result = h->control_sent_head; NULL != result; result = result->next) 244 for (result = h->operation_pending_head; NULL != result; result = result->next)
274 if (id == result->msg->request_id) 245 if (id == result->id)
275 return result; 246 return result;
276 return NULL; 247 return NULL;
277} 248}
278 249
279 250
280/** 251/**
281 * Handler for ARM 'termination' reply (failure to receive).
282 *
283 * @param cls our `struct GNUNET_ARM_Handle`
284 * @param msg expected to be NULL
285 */
286static void
287arm_termination_handler (void *cls,
288 const struct GNUNET_MessageHeader *msg)
289{
290 struct GNUNET_ARM_Handle *h = cls;
291 struct ARMControlMessage *cm;
292
293 if (NULL != msg)
294 {
295 GNUNET_break (0);
296 GNUNET_CLIENT_receive (h->client,
297 &arm_termination_handler,
298 h,
299 GNUNET_TIME_UNIT_FOREVER_REL);
300 return;
301 }
302 cm = h->thm;
303 h->thm = NULL;
304 h->currently_down = GNUNET_YES;
305 GNUNET_CLIENT_disconnect (h->client);
306 h->client = NULL;
307 if (NULL != cm->result_cont)
308 cm->result_cont (cm->cont_cls,
309 GNUNET_ARM_REQUEST_SENT_OK,
310 (const char *) &cm->msg[1],
311 GNUNET_ARM_RESULT_STOPPED);
312 GNUNET_free (cm->msg);
313 GNUNET_free (cm);
314}
315
316
317/**
318 * Handler for ARM replies. 252 * Handler for ARM replies.
319 * 253 *
320 * @param cls our `struct GNUNET_ARM_Handle` 254 * @param cls our `struct GNUNET_ARM_Handle`
321 * @param msg the message received from the arm service 255 * @param res the message received from the arm service
322 */ 256 */
323static void 257static void
324client_notify_handler (void *cls, 258handle_arm_result (void *cls,
325 const struct GNUNET_MessageHeader *msg) 259 const struct GNUNET_ARM_ResultMessage *res)
326{ 260{
327 struct GNUNET_ARM_Handle *h = cls; 261 struct GNUNET_ARM_Handle *h = cls;
328 const struct GNUNET_ARM_Message *arm_msg; 262 struct GNUNET_ARM_Operation *op;
329 const struct GNUNET_ARM_ResultMessage *res;
330 const struct GNUNET_ARM_ListResultMessage *lres;
331 struct ARMControlMessage *cm;
332 const char **list;
333 const char *pos;
334 uint64_t id; 263 uint64_t id;
335 enum GNUNET_ARM_Result result; 264 enum GNUNET_ARM_Result result;
336 uint16_t size_check; 265 GNUNET_ARM_ResultCallback result_cont;
337 uint16_t rcount; 266 void *result_cont_cls;
338 uint16_t msize;
339 unsigned char fail;
340 267
341 list = NULL; 268 id = GNUNET_ntohll (res->arm_msg.request_id);
342 rcount = 0; 269 op = find_op_by_id (h,
343 if (NULL == msg) 270 id);
344 { 271 if (NULL == op)
345 LOG (GNUNET_ERROR_TYPE_INFO,
346 _("Client was disconnected from arm service, trying to reconnect.\n"));
347 reconnect_arm_later (h);
348 return;
349 }
350 msize = ntohs (msg->size);
351 LOG (GNUNET_ERROR_TYPE_DEBUG,
352 "Processing message of type %u and size %u from arm service\n",
353 ntohs (msg->type), msize);
354 if (msize < sizeof (struct GNUNET_ARM_Message))
355 {
356 GNUNET_break (0);
357 reconnect_arm_later (h);
358 return;
359 }
360 arm_msg = (const struct GNUNET_ARM_Message *) msg;
361 GNUNET_break (0 == ntohl (arm_msg->reserved));
362 id = GNUNET_ntohll (arm_msg->request_id);
363 cm = find_cm_by_id (h, id);
364 if (NULL == cm)
365 { 272 {
366 LOG (GNUNET_ERROR_TYPE_DEBUG, 273 LOG (GNUNET_ERROR_TYPE_DEBUG,
367 "Message with unknown id %llu\n", 274 "Message with unknown id %llu\n",
368 id); 275 (unsigned long long) id);
369 return;
370 }
371 fail = GNUNET_NO;
372 switch (ntohs (msg->type))
373 {
374 case GNUNET_MESSAGE_TYPE_ARM_RESULT:
375 if (msize < sizeof (struct GNUNET_ARM_ResultMessage))
376 {
377 GNUNET_assert (0);
378 fail = GNUNET_YES;
379 }
380 break;
381 case GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT:
382 if (msize < sizeof (struct GNUNET_ARM_ListResultMessage))
383 {
384 GNUNET_break (0);
385 fail = GNUNET_YES;
386 break;
387 }
388 size_check = 0;
389 lres = (const struct GNUNET_ARM_ListResultMessage *) msg;
390 rcount = ntohs (lres->count);
391 {
392 unsigned int i;
393
394 list = GNUNET_malloc (sizeof (const char *) * rcount);
395 pos = (const char *)&lres[1];
396 for (i = 0; i < rcount; i++)
397 {
398 const char *end = memchr (pos, 0, msize - size_check);
399 if (NULL == end)
400 {
401 GNUNET_break (0);
402 fail = GNUNET_YES;
403 break;
404 }
405 list[i] = pos;
406 size_check += (end - pos) + 1;
407 pos = end + 1;
408 }
409 if (GNUNET_YES == fail)
410 {
411 GNUNET_free (list);
412 list = NULL;
413 }
414 }
415 break;
416 default:
417 fail = GNUNET_YES;
418 break;
419 }
420 GNUNET_assert (NULL != cm->timeout_task_id);
421 GNUNET_SCHEDULER_cancel (cm->timeout_task_id);
422 GNUNET_CONTAINER_DLL_remove (h->control_sent_head,
423 h->control_sent_tail,
424 cm);
425 if (GNUNET_YES == fail)
426 {
427 reconnect_arm_later (h);
428 GNUNET_free (cm->msg);
429 GNUNET_free (cm);
430 return; 276 return;
431 } 277 }
432 if ( (GNUNET_MESSAGE_TYPE_ARM_RESULT == ntohs (msg->type)) && 278
433 (0 == strcasecmp ((const char *) &cm->msg[1], 279 result = (enum GNUNET_ARM_Result) ntohl (res->result);
434 "arm")) && 280 if ( (GNUNET_YES == op->is_arm_stop) &&
435 (NULL != (res = (const struct GNUNET_ARM_ResultMessage *) msg)) && 281 (GNUNET_ARM_RESULT_STOPPING == result) )
436 (GNUNET_ARM_RESULT_STOPPING == ntohl (res->result)) )
437 { 282 {
438 /* special case: if we are stopping 'gnunet-service-arm', we do not just 283 /* special case: if we are stopping 'gnunet-service-arm', we do not just
439 wait for the result message, but also wait for the service to close 284 wait for the result message, but also wait for the service to close
@@ -443,184 +288,159 @@ client_notify_handler (void *cls,
443 if (NULL != h->thm) 288 if (NULL != h->thm)
444 { 289 {
445 GNUNET_break (0); 290 GNUNET_break (0);
446 cm->result_cont (h->thm->cont_cls, 291 op->result_cont (h->thm->cont_cls,
447 GNUNET_ARM_REQUEST_SENT_OK, 292 GNUNET_ARM_REQUEST_SENT_OK,
448 (const char *) &h->thm->msg[1],
449 GNUNET_ARM_RESULT_IS_NOT_KNOWN); 293 GNUNET_ARM_RESULT_IS_NOT_KNOWN);
450 GNUNET_free (h->thm->msg);
451 GNUNET_free (h->thm); 294 GNUNET_free (h->thm);
452 } 295 }
453 h->thm = cm; 296 GNUNET_CONTAINER_DLL_remove (h->operation_pending_head,
454 GNUNET_CLIENT_receive (h->client, 297 h->operation_pending_tail,
455 &arm_termination_handler, 298 op);
456 h, 299 h->thm = op;
457 GNUNET_TIME_UNIT_FOREVER_REL);
458 return; 300 return;
459 } 301 }
460 GNUNET_CLIENT_receive (h->client, 302 result_cont = op->result_cont;
461 &client_notify_handler, 303 result_cont_cls = op->cont_cls;
462 h, 304 GNUNET_ARM_operation_cancel (op);
463 GNUNET_TIME_UNIT_FOREVER_REL); 305 if (NULL != result_cont)
464 switch (ntohs (msg->type)) 306 result_cont (result_cont_cls,
465 { 307 GNUNET_ARM_REQUEST_SENT_OK,
466 case GNUNET_MESSAGE_TYPE_ARM_RESULT: 308 result);
467 res = (const struct GNUNET_ARM_ResultMessage *) msg;
468 LOG (GNUNET_ERROR_TYPE_DEBUG,
469 "Received response from ARM for service `%s': %u\n",
470 (const char *) &cm->msg[1], ntohs (msg->type));
471 result = (enum GNUNET_ARM_Result) ntohl (res->result);
472 if (NULL != cm->result_cont)
473 cm->result_cont (cm->cont_cls,
474 GNUNET_ARM_REQUEST_SENT_OK,
475 (const char *) &cm->msg[1],
476 result);
477 break;
478 case GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT:
479 if (NULL != cm->list_cont)
480 cm->list_cont (cm->cont_cls,
481 GNUNET_ARM_REQUEST_SENT_OK,
482 rcount,
483 list);
484 GNUNET_free_non_null (list);
485 break;
486 }
487 GNUNET_free (cm->msg);
488 GNUNET_free (cm);
489} 309}
490 310
491 311
492/** 312/**
493 * Transmit the next message to the arm service. 313 * Checked that list result message is well-formed.
494 * 314 *
495 * @param cls closure with the `struct GNUNET_ARM_Handle` 315 * @param cls our `struct GNUNET_ARM_Handle`
496 * @param size number of bytes available in @a buf 316 * @param lres the message received from the arm service
497 * @param buf where the callee should write the message 317 * @return #GNUNET_OK if message is well-formed
498 * @return number of bytes written to @a buf
499 */ 318 */
500static size_t 319static int
501transmit_arm_message (void *cls, 320check_arm_list_result (void *cls,
502 size_t size, 321 const struct GNUNET_ARM_ListResultMessage *lres)
503 void *buf)
504{ 322{
505 struct GNUNET_ARM_Handle *h = cls; 323 const char *pos = (const char *) &lres[1];
506 struct ARMControlMessage *cm; 324 uint16_t rcount = ntohs (lres->count);
507 struct GNUNET_ARM_Message *arm_msg; 325 uint16_t msize = ntohs (lres->arm_msg.header.size);
508 uint64_t request_id; 326 uint16_t size_check;
509 int notify_connection;
510 uint16_t msize;
511 327
512 notify_connection = GNUNET_NO; 328 size_check = 0;
513 LOG (GNUNET_ERROR_TYPE_DEBUG, 329 for (unsigned int i = 0; i < rcount; i++)
514 "transmit_arm_message is running with %p buffer of size %lu. ARM is known to be %s\n",
515 buf, size, h->currently_down ? "unconnected" : "connected");
516 GNUNET_assert (NULL == h->reconnect_task);
517 h->cth = NULL;
518 if ((GNUNET_YES == h->currently_down) && (NULL != buf))
519 {
520 h->currently_down = GNUNET_NO;
521 notify_connection = GNUNET_YES;
522 h->retry_backoff = GNUNET_TIME_UNIT_MILLISECONDS;
523 GNUNET_CLIENT_receive (h->client, &client_notify_handler, h,
524 GNUNET_TIME_UNIT_FOREVER_REL);
525 }
526 if (NULL == buf)
527 { 330 {
528 LOG (GNUNET_ERROR_TYPE_DEBUG, 331 const char *end = memchr (pos, 0, msize - size_check);
529 "Transmission failed, initiating reconnect\n"); 332 if (NULL == end)
530 reconnect_arm_later (h); 333 {
531 return 0; 334 GNUNET_break (0);
532 } 335 return GNUNET_SYSERR;
533 if (NULL == (cm = h->control_pending_head)) 336 }
534 { 337 size_check += (end - pos) + 1;
535 LOG (GNUNET_ERROR_TYPE_DEBUG, 338 pos = end + 1;
536 "Queue is empty, not sending anything\n");
537 msize = 0;
538 goto end;
539 }
540 GNUNET_assert (NULL != cm->msg);
541 msize = ntohs (cm->msg->header.size);
542 if (size < msize)
543 {
544 LOG (GNUNET_ERROR_TYPE_DEBUG,
545 "Request is too big (%u < %u), not sending it\n", size, msize);
546 trigger_next_request (h, GNUNET_NO);
547 msize = 0;
548 goto end;
549 } 339 }
550 arm_msg = cm->msg; 340 return GNUNET_OK;
551 if (0 == h->request_id_counter)
552 h->request_id_counter++;
553 request_id = h->request_id_counter++;
554 LOG (GNUNET_ERROR_TYPE_DEBUG,
555 "Transmitting control message with %u bytes of type %u to arm with id %llu\n",
556 (unsigned int) msize,
557 (unsigned int) ntohs (cm->msg->header.type),
558 request_id);
559 arm_msg->reserved = htonl (0);
560 arm_msg->request_id = GNUNET_htonll (request_id);
561 memcpy (buf, cm->msg, msize);
562 /* Otherwise we won't be able to find it later! */
563 arm_msg->request_id = request_id;
564 GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
565 h->control_pending_tail,
566 cm);
567 GNUNET_CONTAINER_DLL_insert_tail (h->control_sent_head,
568 h->control_sent_tail,
569 cm);
570 /* Don't free msg, keep it around (kind of wasteful, but then we don't
571 * really have many messages to handle, and it'll be freed when it times
572 * out anyway.
573 */
574 trigger_next_request (h, GNUNET_NO);
575
576 end:
577 if ((GNUNET_YES == notify_connection) && (NULL != h->conn_status))
578 h->conn_status (h->conn_status_cls, GNUNET_YES);
579 return msize;
580} 341}
581 342
582 343
583/** 344/**
584 * Check the list of pending requests, send the next 345 * Handler for ARM list replies.
585 * one to the arm.
586 * 346 *
587 * @param h arm handle 347 * @param cls our `struct GNUNET_ARM_Handle`
588 * @param ignore_currently_down transmit message even if not initialized? 348 * @param lres the message received from the arm service
589 */ 349 */
590static void 350static void
591trigger_next_request (struct GNUNET_ARM_Handle *h, 351handle_arm_list_result (void *cls,
592 int ignore_currently_down) 352 const struct GNUNET_ARM_ListResultMessage *lres)
593{ 353{
594 uint16_t msize; 354 struct GNUNET_ARM_Handle *h = cls;
355 uint16_t rcount = ntohs (lres->count);
356 const char *list[rcount];
357 const char *pos = (const char *) &lres[1];
358 uint16_t msize = ntohs (lres->arm_msg.header.size);
359 struct GNUNET_ARM_Operation *op;
360 uint16_t size_check;
361 uint64_t id;
595 362
596 msize = sizeof (struct GNUNET_MessageHeader); 363 id = GNUNET_ntohll (lres->arm_msg.request_id);
597 if ((GNUNET_YES == h->currently_down) && (ignore_currently_down == GNUNET_NO)) 364 op = find_op_by_id (h,
365 id);
366 if (NULL == op)
598 { 367 {
599 LOG (GNUNET_ERROR_TYPE_DEBUG, 368 LOG (GNUNET_ERROR_TYPE_DEBUG,
600 "ARM connection down, not processing queue\n"); 369 "Message with unknown id %llu\n",
370 (unsigned long long) id);
601 return; 371 return;
602 } 372 }
603 if (NULL != h->cth) 373 size_check = 0;
374 for (unsigned int i = 0; i < rcount; i++)
375 {
376 const char *end = memchr (pos,
377 0,
378 msize - size_check);
379
380 /* Assert, as this was already checked in #check_arm_list_result() */
381 GNUNET_assert (NULL != end);
382 list[i] = pos;
383 size_check += (end - pos) + 1;
384 pos = end + 1;
385 }
386 if (NULL != op->list_cont)
387 op->list_cont (op->cont_cls,
388 GNUNET_ARM_REQUEST_SENT_OK,
389 rcount,
390 list);
391 GNUNET_ARM_operation_cancel (op);
392}
393
394
395/**
396 * Receive confirmation from test, ARM service is up.
397 *
398 * @param cls closure with the `struct GNUNET_ARM_Handle`
399 * @param msg message received
400 */
401static void
402handle_confirm (void *cls,
403 const struct GNUNET_MessageHeader *msg)
404{
405 struct GNUNET_ARM_Handle *h = cls;
406
407 LOG (GNUNET_ERROR_TYPE_DEBUG,
408 "Got confirmation from ARM that we are up!\n");
409 if (GNUNET_NO == h->currently_up)
604 { 410 {
605 LOG (GNUNET_ERROR_TYPE_DEBUG, 411 h->currently_up = GNUNET_YES;
606 "Request pending, not processing queue\n"); 412 if (NULL != h->conn_status)
607 return; 413 h->conn_status (h->conn_status_cls,
414 GNUNET_YES);
608 } 415 }
609 if (NULL != h->control_pending_head) 416}
610 msize = 417
611 ntohs (h->control_pending_head->msg->header.size); 418
612 else if (GNUNET_NO == ignore_currently_down) 419/**
420 * Generic error handler, called with the appropriate error code and
421 * the same closure specified at the creation of the message queue.
422 * Not every message queue implementation supports an error handler.
423 *
424 * @param cls closure with the `struct GNUNET_ARM_Handle *`
425 * @param error error code
426 */
427static void
428mq_error_handler (void *cls,
429 enum GNUNET_MQ_Error error)
430{
431 struct GNUNET_ARM_Handle *h = cls;
432 struct GNUNET_ARM_Operation *op;
433
434 h->currently_up = GNUNET_NO;
435 if (NULL != (op = h->thm))
613 { 436 {
614 LOG (GNUNET_ERROR_TYPE_DEBUG, 437 h->thm = NULL;
615 "Request queue empty, not processing queue\n"); 438 op->result_cont (op->cont_cls,
616 return; /* no pending message */ 439 GNUNET_ARM_REQUEST_SENT_OK,
440 GNUNET_ARM_RESULT_STOPPED);
441 GNUNET_free (op);
617 } 442 }
618 h->cth = 443 reconnect_arm_later (h);
619 GNUNET_CLIENT_notify_transmit_ready (h->client,
620 msize,
621 GNUNET_TIME_UNIT_FOREVER_REL,
622 GNUNET_NO,
623 &transmit_arm_message, h);
624} 444}
625 445
626 446
@@ -633,22 +453,47 @@ trigger_next_request (struct GNUNET_ARM_Handle *h,
633static int 453static int
634reconnect_arm (struct GNUNET_ARM_Handle *h) 454reconnect_arm (struct GNUNET_ARM_Handle *h)
635{ 455{
636 GNUNET_assert (NULL == h->client); 456 GNUNET_MQ_hd_fixed_size (arm_result,
637 GNUNET_assert (GNUNET_YES == h->currently_down); 457 GNUNET_MESSAGE_TYPE_ARM_RESULT,
638 h->client = GNUNET_CLIENT_connect ("arm", h->cfg); 458 struct GNUNET_ARM_ResultMessage);
639 if (NULL == h->client) 459 GNUNET_MQ_hd_var_size (arm_list_result,
460 GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT,
461 struct GNUNET_ARM_ListResultMessage);
462 GNUNET_MQ_hd_fixed_size (confirm,
463 GNUNET_MESSAGE_TYPE_TEST,
464 struct GNUNET_MessageHeader);
465 struct GNUNET_MQ_MessageHandler handlers[] = {
466 make_arm_result_handler (h),
467 make_arm_list_result_handler (h),
468 make_confirm_handler (h),
469 GNUNET_MQ_handler_end ()
470 };
471 struct GNUNET_MessageHeader *test;
472 struct GNUNET_MQ_Envelope *env;
473
474 if (NULL != h->mq)
475 return GNUNET_OK;
476 GNUNET_assert (GNUNET_NO == h->currently_up);
477 h->mq = GNUNET_CLIENT_connecT (h->cfg,
478 "arm",
479 handlers,
480 &mq_error_handler,
481 h);
482 if (NULL == h->mq)
640 { 483 {
641 LOG (GNUNET_ERROR_TYPE_DEBUG, 484 LOG (GNUNET_ERROR_TYPE_DEBUG,
642 "arm_api, GNUNET_CLIENT_connect returned NULL\n"); 485 "GNUNET_CLIENT_connect returned NULL\n");
643 if (NULL != h->conn_status) 486 if (NULL != h->conn_status)
644 h->conn_status (h->conn_status_cls, 487 h->conn_status (h->conn_status_cls,
645 GNUNET_SYSERR); 488 GNUNET_SYSERR);
646 return GNUNET_SYSERR; 489 return GNUNET_SYSERR;
647 } 490 }
648 LOG (GNUNET_ERROR_TYPE_DEBUG, 491 LOG (GNUNET_ERROR_TYPE_DEBUG,
649 "arm_api, GNUNET_CLIENT_connect returned non-NULL\n"); 492 "Sending TEST message to ARM\n");
650 trigger_next_request (h, 493 env = GNUNET_MQ_msg (test,
651 GNUNET_YES); 494 GNUNET_MESSAGE_TYPE_TEST);
495 GNUNET_MQ_send (h->mq,
496 env);
652 return GNUNET_OK; 497 return GNUNET_OK;
653} 498}
654 499
@@ -661,22 +506,20 @@ reconnect_arm (struct GNUNET_ARM_Handle *h)
661 * the ARM service may internally use a different 506 * the ARM service may internally use a different
662 * configuration to determine how to start the service). 507 * configuration to determine how to start the service).
663 * @param conn_status will be called when connecting/disconnecting 508 * @param conn_status will be called when connecting/disconnecting
664 * @param cls closure for conn_status 509 * @param conn_status_cls closure for @a conn_status
665 * @return context to use for further ARM operations, NULL on error. 510 * @return context to use for further ARM operations, NULL on error.
666 */ 511 */
667struct GNUNET_ARM_Handle * 512struct GNUNET_ARM_Handle *
668GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, 513GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
669 GNUNET_ARM_ConnectionStatusCallback conn_status, 514 GNUNET_ARM_ConnectionStatusCallback conn_status,
670 void *cls) 515 void *conn_status_cls)
671{ 516{
672 struct GNUNET_ARM_Handle *h; 517 struct GNUNET_ARM_Handle *h;
673 518
674 h = GNUNET_new (struct GNUNET_ARM_Handle); 519 h = GNUNET_new (struct GNUNET_ARM_Handle);
675 h->cfg = GNUNET_CONFIGURATION_dup (cfg); 520 h->cfg = cfg;
676 h->currently_down = GNUNET_YES;
677 h->reconnect_task = NULL;
678 h->conn_status = conn_status; 521 h->conn_status = conn_status;
679 h->conn_status_cls = cls; 522 h->conn_status_cls = conn_status_cls;
680 if (GNUNET_OK != reconnect_arm (h)) 523 if (GNUNET_OK != reconnect_arm (h))
681 { 524 {
682 GNUNET_free (h); 525 GNUNET_free (h);
@@ -692,113 +535,60 @@ GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
692 * @param h the handle that was being used 535 * @param h the handle that was being used
693 */ 536 */
694void 537void
695GNUNET_ARM_disconnect_and_free (struct GNUNET_ARM_Handle *h) 538GNUNET_ARM_disconnect (struct GNUNET_ARM_Handle *h)
696{ 539{
697 struct ARMControlMessage *cm; 540 struct GNUNET_ARM_Operation *op;
698 541
699 LOG (GNUNET_ERROR_TYPE_DEBUG, 542 LOG (GNUNET_ERROR_TYPE_DEBUG,
700 "Disconnecting from ARM service\n"); 543 "Disconnecting from ARM service\n");
701 if (NULL != h->cth) 544 while (NULL != (op = h->operation_pending_head))
702 { 545 {
703 GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth); 546 GNUNET_CONTAINER_DLL_remove (h->operation_pending_head,
704 h->cth = NULL; 547 h->operation_pending_tail,
705 } 548 op);
706 while ((NULL != (cm = h->control_pending_head)) 549 if (NULL != op->result_cont)
707 || (NULL != (cm = h->control_sent_head)) ) 550 op->result_cont (op->cont_cls,
708 {
709 if (NULL != h->control_pending_head)
710 GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
711 h->control_pending_tail,
712 cm);
713 else
714 GNUNET_CONTAINER_DLL_remove (h->control_sent_head,
715 h->control_sent_tail,
716 cm);
717 GNUNET_assert (NULL != cm->timeout_task_id);
718 GNUNET_SCHEDULER_cancel (cm->timeout_task_id);
719 if (NULL != cm->result_cont)
720 cm->result_cont (cm->cont_cls,
721 GNUNET_ARM_REQUEST_DISCONNECTED, 551 GNUNET_ARM_REQUEST_DISCONNECTED,
722 NULL,
723 0); 552 0);
724 /* FIXME: What about list callback? */ 553 if (NULL != op->list_cont)
725 GNUNET_free_non_null (cm->msg); 554 op->list_cont (op->cont_cls,
726 GNUNET_free (cm); 555 GNUNET_ARM_REQUEST_DISCONNECTED,
556 0,
557 NULL);
558 if (NULL != op->async)
559 {
560 GNUNET_SCHEDULER_cancel (op->async);
561 op->async = NULL;
562 }
563 GNUNET_free (op);
727 } 564 }
728 if (NULL != h->client) 565 if (NULL != h->mq)
729 { 566 {
730 GNUNET_CLIENT_disconnect (h->client); 567 GNUNET_MQ_destroy (h->mq);
731 h->client = NULL; 568 h->mq = NULL;
732 } 569 }
733 if (NULL != h->reconnect_task) 570 if (NULL != h->reconnect_task)
734 { 571 {
735 GNUNET_SCHEDULER_cancel (h->reconnect_task); 572 GNUNET_SCHEDULER_cancel (h->reconnect_task);
736 h->reconnect_task = NULL; 573 h->reconnect_task = NULL;
737 } 574 }
738 if (GNUNET_NO == h->service_test_is_active) 575 GNUNET_free (h);
739 {
740 GNUNET_CONFIGURATION_destroy (h->cfg);
741 GNUNET_free (h);
742 }
743}
744
745
746/**
747 * Message timed out. Remove it from the queue.
748 *
749 * @param cls the message (struct ARMControlMessage *)
750 */
751static void
752control_message_timeout (void *cls)
753{
754 struct ARMControlMessage *cm = cls;
755 struct GNUNET_ARM_Message *arm_msg;
756
757 LOG (GNUNET_ERROR_TYPE_DEBUG,
758 "Control message timed out\n");
759 arm_msg = cm->msg;
760 if ((NULL == arm_msg) || (0 == arm_msg->request_id))
761 {
762 GNUNET_CONTAINER_DLL_remove (cm->h->control_pending_head,
763 cm->h->control_pending_tail,
764 cm);
765 }
766 else
767 {
768 GNUNET_CONTAINER_DLL_remove (cm->h->control_sent_head,
769 cm->h->control_sent_tail,
770 cm);
771 }
772 if (NULL != cm->result_cont)
773 cm->result_cont (cm->cont_cls,
774 GNUNET_ARM_REQUEST_TIMEOUT,
775 NULL, 0);
776 else if (NULL != cm->list_cont)
777 cm->list_cont (cm->cont_cls,
778 GNUNET_ARM_REQUEST_TIMEOUT,
779 0, NULL);
780 GNUNET_free_non_null (cm->msg);
781 GNUNET_free (cm);
782} 576}
783 577
784 578
785/** 579/**
786 * A client specifically requested starting of ARM itself. 580 * A client specifically requested starting of ARM itself.
787 * This function is called with information about whether 581 * Starts the ARM service.
788 * or not ARM is running; if it is, report success. If
789 * it is not, start the ARM process.
790 * 582 *
791 * @param cls the context for the request that we will report on (struct ARMControlMessage *) 583 * @param h the handle with configuration details
792 * @param result #GNUNET_YES if ARM is running 584 * @param std_inheritance inheritance of std streams
585 * @return operation status code
793 */ 586 */
794static void 587static enum GNUNET_ARM_Result
795arm_service_report (void *cls, 588start_arm_service (struct GNUNET_ARM_Handle *h,
796 int result) 589 enum GNUNET_OS_InheritStdioFlags std_inheritance)
797{ 590{
798 struct ARMControlMessage *cm = cls;
799 struct GNUNET_ARM_Handle *h;
800 struct GNUNET_OS_Process *proc; 591 struct GNUNET_OS_Process *proc;
801 unsigned char test_is_active;
802 char *cbinary; 592 char *cbinary;
803 char *binary; 593 char *binary;
804 char *quotedbinary; 594 char *quotedbinary;
@@ -806,51 +596,20 @@ arm_service_report (void *cls,
806 char *loprefix; 596 char *loprefix;
807 char *lopostfix; 597 char *lopostfix;
808 598
809 test_is_active = cm->h->service_test_is_active;
810 if ((GNUNET_YES == test_is_active) &&
811 (GNUNET_YES == result))
812 {
813 LOG (GNUNET_ERROR_TYPE_DEBUG,
814 "Looks like `%s' is already running.\n",
815 "gnunet-service-arm");
816 /* arm is running! */
817 if (cm->result_cont)
818 cm->result_cont (cm->cont_cls,
819 GNUNET_ARM_REQUEST_SENT_OK, "arm",
820 GNUNET_ARM_RESULT_IS_STARTED_ALREADY);
821 }
822 if (GNUNET_NO == test_is_active)
823 {
824 /* User disconnected & destroyed ARM handle in the middle of
825 * the service test, so we kept the handle around until now.
826 */
827 GNUNET_CONFIGURATION_destroy (cm->h->cfg);
828 GNUNET_free (cm->h);
829 }
830 if ((GNUNET_YES == result) ||
831 (GNUNET_NO == test_is_active))
832 {
833 GNUNET_free (cm);
834 return;
835 }
836 cm->h->service_test_is_active = GNUNET_NO;
837 LOG (GNUNET_ERROR_TYPE_DEBUG,
838 "Looks like `%s' is not running, will start it.\n",
839 "gnunet-service-arm");
840 if (GNUNET_OK != 599 if (GNUNET_OK !=
841 GNUNET_CONFIGURATION_get_value_string (cm->h->cfg, 600 GNUNET_CONFIGURATION_get_value_string (h->cfg,
842 "arm", 601 "arm",
843 "PREFIX", 602 "PREFIX",
844 &loprefix)) 603 &loprefix))
845 loprefix = GNUNET_strdup (""); 604 loprefix = GNUNET_strdup ("");
846 if (GNUNET_OK != 605 if (GNUNET_OK !=
847 GNUNET_CONFIGURATION_get_value_string (cm->h->cfg, 606 GNUNET_CONFIGURATION_get_value_string (h->cfg,
848 "arm", 607 "arm",
849 "OPTIONS", 608 "OPTIONS",
850 &lopostfix)) 609 &lopostfix))
851 lopostfix = GNUNET_strdup (""); 610 lopostfix = GNUNET_strdup ("");
852 if (GNUNET_OK != 611 if (GNUNET_OK !=
853 GNUNET_CONFIGURATION_get_value_string (cm->h->cfg, 612 GNUNET_CONFIGURATION_get_value_string (h->cfg,
854 "arm", 613 "arm",
855 "BINARY", 614 "BINARY",
856 &cbinary)) 615 &cbinary))
@@ -858,18 +617,14 @@ arm_service_report (void *cls,
858 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING, 617 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
859 "arm", 618 "arm",
860 "BINARY"); 619 "BINARY");
861 if (cm->result_cont)
862 cm->result_cont (cm->cont_cls,
863 GNUNET_ARM_REQUEST_SENT_OK, "arm",
864 GNUNET_ARM_RESULT_IS_NOT_KNOWN);
865 GNUNET_free (cm);
866 GNUNET_free (loprefix); 620 GNUNET_free (loprefix);
867 GNUNET_free (lopostfix); 621 GNUNET_free (lopostfix);
868 return; 622 return GNUNET_ARM_RESULT_IS_NOT_KNOWN;
869 } 623 }
870 if (GNUNET_OK != 624 if (GNUNET_OK !=
871 GNUNET_CONFIGURATION_get_value_filename (cm->h->cfg, 625 GNUNET_CONFIGURATION_get_value_filename (h->cfg,
872 "arm", "CONFIG", 626 "arm",
627 "CONFIG",
873 &config)) 628 &config))
874 config = NULL; 629 config = NULL;
875 binary = GNUNET_OS_get_libexec_binary_path (cbinary); 630 binary = GNUNET_OS_get_libexec_binary_path (cbinary);
@@ -878,15 +633,15 @@ arm_service_report (void *cls,
878 binary); 633 binary);
879 GNUNET_free (cbinary); 634 GNUNET_free (cbinary);
880 if ( (GNUNET_YES == 635 if ( (GNUNET_YES ==
881 GNUNET_CONFIGURATION_have_value (cm->h->cfg, 636 GNUNET_CONFIGURATION_have_value (h->cfg,
882 "TESTING", 637 "TESTING",
883 "WEAKRANDOM")) && 638 "WEAKRANDOM")) &&
884 (GNUNET_YES == 639 (GNUNET_YES ==
885 GNUNET_CONFIGURATION_get_value_yesno (cm->h->cfg, 640 GNUNET_CONFIGURATION_get_value_yesno (h->cfg,
886 "TESTING", 641 "TESTING",
887 "WEAKRANDOM")) && 642 "WEAKRANDOM")) &&
888 (GNUNET_NO == 643 (GNUNET_NO ==
889 GNUNET_CONFIGURATION_have_value (cm->h->cfg, 644 GNUNET_CONFIGURATION_have_value (h->cfg,
890 "TESTING", 645 "TESTING",
891 "HOSTFILE"))) 646 "HOSTFILE")))
892 { 647 {
@@ -894,39 +649,43 @@ arm_service_report (void *cls,
894 /* we're clearly running a test, don't daemonize */ 649 /* we're clearly running a test, don't daemonize */
895 if (NULL == config) 650 if (NULL == config)
896 proc = GNUNET_OS_start_process_s (GNUNET_NO, 651 proc = GNUNET_OS_start_process_s (GNUNET_NO,
897 cm->std_inheritance, 652 std_inheritance,
898 NULL, 653 NULL,
899 loprefix, 654 loprefix,
900 quotedbinary, 655 quotedbinary,
901 /* no daemonization! */ 656 /* no daemonization! */
902 lopostfix, NULL); 657 lopostfix,
658 NULL);
903 else 659 else
904 proc = GNUNET_OS_start_process_s (GNUNET_NO, 660 proc = GNUNET_OS_start_process_s (GNUNET_NO,
905 cm->std_inheritance, 661 std_inheritance,
906 NULL, 662 NULL,
907 loprefix, 663 loprefix,
908 quotedbinary, 664 quotedbinary,
909 "-c", config, 665 "-c", config,
910 /* no daemonization! */ 666 /* no daemonization! */
911 lopostfix, NULL); 667 lopostfix,
668 NULL);
912 } 669 }
913 else 670 else
914 { 671 {
915 if (NULL == config) 672 if (NULL == config)
916 proc = GNUNET_OS_start_process_s (GNUNET_NO, 673 proc = GNUNET_OS_start_process_s (GNUNET_NO,
917 cm->std_inheritance, 674 std_inheritance,
918 NULL, 675 NULL,
919 loprefix, 676 loprefix,
920 quotedbinary, 677 quotedbinary,
921 "-d", lopostfix, NULL); 678 "-d", /* do daemonize */
679 lopostfix, NULL);
922 else 680 else
923 proc = GNUNET_OS_start_process_s (GNUNET_NO, 681 proc = GNUNET_OS_start_process_s (GNUNET_NO,
924 cm->std_inheritance, 682 std_inheritance,
925 NULL, 683 NULL,
926 loprefix, 684 loprefix,
927 quotedbinary, 685 quotedbinary,
928 "-c", config, 686 "-c", config,
929 "-d", lopostfix, 687 "-d", /* do daemonize */
688 lopostfix,
930 NULL); 689 NULL);
931 } 690 }
932 GNUNET_free (binary); 691 GNUNET_free (binary);
@@ -935,22 +694,32 @@ arm_service_report (void *cls,
935 GNUNET_free (loprefix); 694 GNUNET_free (loprefix);
936 GNUNET_free (lopostfix); 695 GNUNET_free (lopostfix);
937 if (NULL == proc) 696 if (NULL == proc)
697 return GNUNET_ARM_RESULT_START_FAILED;
698 GNUNET_OS_process_destroy (proc);
699 return GNUNET_ARM_RESULT_STARTING;
700}
701
702
703/**
704 * Abort an operation. Only prevents the callback from being
705 * called, the operation may still complete.
706 *
707 * @param op operation to cancel
708 */
709void
710GNUNET_ARM_operation_cancel (struct GNUNET_ARM_Operation *op)
711{
712 struct GNUNET_ARM_Handle *h = op->h;
713
714 if (h->thm == op)
938 { 715 {
939 if (cm->result_cont) 716 op->result_cont = NULL;
940 cm->result_cont (cm->cont_cls,
941 GNUNET_ARM_REQUEST_SENT_OK, "arm",
942 GNUNET_ARM_RESULT_START_FAILED);
943 GNUNET_free (cm);
944 return; 717 return;
945 } 718 }
946 if (cm->result_cont) 719 GNUNET_CONTAINER_DLL_remove (h->operation_pending_head,
947 cm->result_cont (cm->cont_cls, 720 h->operation_pending_tail,
948 GNUNET_ARM_REQUEST_SENT_OK, "arm", 721 op);
949 GNUNET_ARM_RESULT_STARTING); 722 GNUNET_free (op);
950 GNUNET_OS_process_destroy (proc);
951 h = cm->h;
952 GNUNET_free (cm);
953 reconnect_arm (h);
954} 723}
955 724
956 725
@@ -959,21 +728,21 @@ arm_service_report (void *cls,
959 * 728 *
960 * @param h handle to ARM 729 * @param h handle to ARM
961 * @param service_name name of the service 730 * @param service_name name of the service
962 * @param timeout how long to wait before failing for good
963 * @param cb callback to invoke when service is ready 731 * @param cb callback to invoke when service is ready
964 * @param cb_cls closure for @a cb 732 * @param cb_cls closure for @a cb
965 * @param type type of the request 733 * @param type type of the request
734 * @return handle to queue, NULL on error
966 */ 735 */
967static void 736static struct GNUNET_ARM_Operation *
968change_service (struct GNUNET_ARM_Handle *h, 737change_service (struct GNUNET_ARM_Handle *h,
969 const char *service_name, 738 const char *service_name,
970 struct GNUNET_TIME_Relative timeout,
971 GNUNET_ARM_ResultCallback cb, 739 GNUNET_ARM_ResultCallback cb,
972 void *cb_cls, 740 void *cb_cls,
973 uint16_t type) 741 uint16_t type)
974{ 742{
975 struct ARMControlMessage *cm; 743 struct GNUNET_ARM_Operation *op;
976 size_t slen; 744 size_t slen;
745 struct GNUNET_MQ_Envelope *env;
977 struct GNUNET_ARM_Message *msg; 746 struct GNUNET_ARM_Message *msg;
978 747
979 slen = strlen (service_name) + 1; 748 slen = strlen (service_name) + 1;
@@ -981,38 +750,81 @@ change_service (struct GNUNET_ARM_Handle *h,
981 GNUNET_SERVER_MAX_MESSAGE_SIZE) 750 GNUNET_SERVER_MAX_MESSAGE_SIZE)
982 { 751 {
983 GNUNET_break (0); 752 GNUNET_break (0);
984 if (cb != NULL) 753 return NULL;
985 cb (cb_cls, GNUNET_ARM_REQUEST_TOO_LONG, NULL, 0);
986 return;
987 } 754 }
988 LOG (GNUNET_ERROR_TYPE_DEBUG, "Requesting %s of service `%s'.\n", 755 if (0 == h->request_id_counter)
989 (GNUNET_MESSAGE_TYPE_ARM_START == type) ? "start" : "termination", 756 h->request_id_counter++;
990 service_name); 757 op = GNUNET_new (struct GNUNET_ARM_Operation);
991 cm = GNUNET_malloc (sizeof (struct ARMControlMessage) + slen); 758 op->h = h;
992 cm->h = h; 759 op->result_cont = cb;
993 cm->result_cont = cb; 760 op->cont_cls = cb_cls;
994 cm->cont_cls = cb_cls; 761 op->id = h->request_id_counter++;
995 cm->timeout = GNUNET_TIME_relative_to_absolute (timeout); 762 GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head,
996 memcpy (&cm[1], service_name, slen); 763 h->operation_pending_tail,
997 msg = GNUNET_malloc (sizeof (struct GNUNET_ARM_Message) + slen); 764 op);
998 msg->header.size = htons (sizeof (struct GNUNET_ARM_Message) + slen); 765 env = GNUNET_MQ_msg_extra (msg,
999 msg->header.type = htons (type); 766 slen,
767 type);
1000 msg->reserved = htonl (0); 768 msg->reserved = htonl (0);
1001 memcpy (&msg[1], service_name, slen); 769 msg->request_id = GNUNET_htonll (op->id);
1002 cm->msg = msg; 770 memcpy (&msg[1],
771 service_name,
772 slen);
773 GNUNET_MQ_send (h->mq,
774 env);
775 return op;
776}
777
778
779/**
780 * Task run to notify application that ARM is already up.
781 *
782 * @param cls the operation that asked ARM to be started
783 */
784static void
785notify_running (void *cls)
786{
787 struct GNUNET_ARM_Operation *op = cls;
788 struct GNUNET_ARM_Handle *h = op->h;
789
790 op->async = NULL;
791 GNUNET_CONTAINER_DLL_remove (h->operation_pending_head,
792 h->operation_pending_tail,
793 op);
794 if (NULL != op->result_cont)
795 op->result_cont (op->cont_cls,
796 GNUNET_ARM_REQUEST_SENT_OK,
797 GNUNET_ARM_RESULT_IS_STARTED_ALREADY);
798 if ( (GNUNET_YES == h->currently_up) &&
799 (NULL != h->conn_status) )
800 h->conn_status (h->conn_status_cls,
801 GNUNET_YES);
802 GNUNET_free (op);
803}
804
805
806/**
807 * Task run to notify application that ARM is being started.
808 *
809 * @param cls the operation that asked ARM to be started
810 */
811static void
812notify_starting (void *cls)
813{
814 struct GNUNET_ARM_Operation *op = cls;
815 struct GNUNET_ARM_Handle *h = op->h;
816
817 op->async = NULL;
1003 LOG (GNUNET_ERROR_TYPE_DEBUG, 818 LOG (GNUNET_ERROR_TYPE_DEBUG,
1004 "Inserting a control message into the queue. Timeout is %s\n", 819 "Notifying client that we started the ARM service\n");
1005 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (cm->timeout), 820 GNUNET_CONTAINER_DLL_remove (h->operation_pending_head,
1006 GNUNET_NO)); 821 h->operation_pending_tail,
1007 GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head, 822 op);
1008 h->control_pending_tail, 823 if (NULL != op->result_cont)
1009 cm); 824 op->result_cont (op->cont_cls,
1010 cm->timeout_task_id = 825 GNUNET_ARM_REQUEST_SENT_OK,
1011 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining 826 op->starting_ret);
1012 (cm->timeout), 827 GNUNET_free (op);
1013 &control_message_timeout,
1014 cm);
1015 trigger_next_request (h, GNUNET_NO);
1016} 828}
1017 829
1018 830
@@ -1022,132 +834,116 @@ change_service (struct GNUNET_ARM_Handle *h,
1022 * @param h handle to ARM 834 * @param h handle to ARM
1023 * @param service_name name of the service 835 * @param service_name name of the service
1024 * @param std_inheritance inheritance of std streams 836 * @param std_inheritance inheritance of std streams
1025 * @param timeout how long to wait before failing for good
1026 * @param cont callback to invoke after request is sent or not sent 837 * @param cont callback to invoke after request is sent or not sent
1027 * @param cont_cls closure for @a cont 838 * @param cont_cls closure for @a cont
839 * @return handle for the operation, NULL on error
1028 */ 840 */
1029void 841struct GNUNET_ARM_Operation *
1030GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h, 842GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h,
1031 const char *service_name, 843 const char *service_name,
1032 enum GNUNET_OS_InheritStdioFlags std_inheritance, 844 enum GNUNET_OS_InheritStdioFlags std_inheritance,
1033 struct GNUNET_TIME_Relative timeout,
1034 GNUNET_ARM_ResultCallback cont, 845 GNUNET_ARM_ResultCallback cont,
1035 void *cont_cls) 846 void *cont_cls)
1036{ 847{
1037 struct ARMControlMessage *cm; 848 struct GNUNET_ARM_Operation *op;
1038 size_t slen; 849 enum GNUNET_ARM_Result ret;
1039 850
1040 LOG (GNUNET_ERROR_TYPE_DEBUG, 851 LOG (GNUNET_ERROR_TYPE_DEBUG,
1041 "Asked to start service `%s' within %s\n", service_name, 852 "Starting service `%s'\n",
1042 GNUNET_STRINGS_relative_time_to_string (timeout, GNUNET_NO)); 853 service_name);
1043 if (0 == strcasecmp ("arm", service_name)) 854 if (0 != strcasecmp ("arm",
855 service_name))
856 return change_service (h,
857 service_name,
858 cont,
859 cont_cls,
860 GNUNET_MESSAGE_TYPE_ARM_START);
861
862 /* Possible cases:
863 * 1) We're connected to ARM already. Invoke the callback immediately.
864 * 2) We're not connected to ARM.
865 * Cancel any reconnection attempts temporarily, then perform
866 * a service test.
867 */
868 if (GNUNET_YES == h->currently_up)
1044 { 869 {
1045 /* Possible cases: 870 LOG (GNUNET_ERROR_TYPE_DEBUG,
1046 * 1) We're connected to ARM already. Invoke the callback immediately. 871 "ARM is already running\n");
1047 * 2) We're not connected to ARM. 872 op = GNUNET_new (struct GNUNET_ARM_Operation);
1048 * Cancel any reconnection attempts temporarily, then perform 873 op->h = h;
1049 * a service test. 874 op->result_cont = cont;
1050 */ 875 op->cont_cls = cont_cls;
1051 if (GNUNET_NO == h->currently_down) 876 GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head,
1052 { 877 h->operation_pending_tail,
1053 LOG (GNUNET_ERROR_TYPE_DEBUG, 878 op);
1054 "ARM is already running\n"); 879 op->async = GNUNET_SCHEDULER_add_now (&notify_running,
1055 if (NULL != cont) 880 op);
1056 cont (cont_cls, 881 return op;
1057 GNUNET_ARM_REQUEST_SENT_OK, 882 }
1058 "arm", 883 /* This is an inherently uncertain choice, as it is of course
1059 GNUNET_ARM_RESULT_IS_STARTED_ALREADY); 884 theoretically possible that ARM is up and we just did not
1060 } 885 yet complete the MQ handshake. However, given that users
1061 else if (GNUNET_NO == h->service_test_is_active) 886 are unlikely to hammer 'gnunet-arm -s' on a busy system,
1062 { 887 the above check should catch 99.99% of the cases where ARM
1063 if (NULL != h->cth) 888 is already running. */
1064 { 889 LOG (GNUNET_ERROR_TYPE_DEBUG,
1065 GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth); 890 "Starting ARM service\n");
1066 h->cth = NULL; 891 ret = start_arm_service (h,
1067 } 892 std_inheritance);
1068 if (NULL != h->client) 893 if (GNUNET_ARM_RESULT_STARTING == ret)
1069 { 894 reconnect_arm (h);
1070 GNUNET_CLIENT_disconnect (h->client); 895 op = GNUNET_new (struct GNUNET_ARM_Operation);
1071 h->client = NULL; 896 op->h = h;
1072 } 897 op->result_cont = cont;
1073 if (NULL != h->reconnect_task) 898 op->cont_cls = cont_cls;
1074 { 899 GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head,
1075 GNUNET_SCHEDULER_cancel (h->reconnect_task); 900 h->operation_pending_tail,
1076 h->reconnect_task = NULL; 901 op);
1077 } 902 op->starting_ret = ret;
1078 903 op->async = GNUNET_SCHEDULER_add_now (&notify_starting,
1079 LOG (GNUNET_ERROR_TYPE_DEBUG, 904 op);
1080 "Not connected to ARM, will do a service test\n"); 905 return op;
1081
1082 slen = strlen ("arm") + 1;
1083 cm = GNUNET_malloc (sizeof (struct ARMControlMessage) + slen);
1084 cm->h = h;
1085 cm->result_cont = cont;
1086 cm->cont_cls = cont_cls;
1087 cm->timeout = GNUNET_TIME_relative_to_absolute (timeout);
1088 cm->std_inheritance = std_inheritance;
1089 memcpy (&cm[1], service_name, slen);
1090 h->service_test_is_active = GNUNET_YES;
1091 GNUNET_CLIENT_service_test ("arm",
1092 h->cfg,
1093 timeout,
1094 &arm_service_report,
1095 cm);
1096 }
1097 else
1098 {
1099 /* Service test is already running - tell user to chill out and try
1100 * again later.
1101 */
1102 LOG (GNUNET_ERROR_TYPE_DEBUG,
1103 "Service test is already in progress, we're busy\n");
1104 if (NULL != cont)
1105 cont (cont_cls,
1106 GNUNET_ARM_REQUEST_BUSY,
1107 NULL, 0);
1108 }
1109 return;
1110 }
1111 change_service (h,
1112 service_name,
1113 timeout,
1114 cont, cont_cls,
1115 GNUNET_MESSAGE_TYPE_ARM_START);
1116} 906}
1117 907
1118 908
1119/** 909/**
1120 * Request a service to be stopped. 910 * Request a service to be stopped. Stopping arm itself will not
1121 * Stopping arm itself will not invalidate its handle, and 911 * invalidate its handle, and ARM API will try to restore connection
1122 * ARM API will try to restore connection to the ARM service, 912 * to the ARM service, even if ARM connection was lost because you
1123 * even if ARM connection was lost because you asked for ARM to be stopped. 913 * asked for ARM to be stopped. Call
1124 * Call #GNUNET_ARM_disconnect_and_free() to free the handle and prevent 914 * #GNUNET_ARM_disconnect() to free the handle and prevent
1125 * further connection attempts. 915 * further connection attempts.
1126 * 916 *
1127 * @param h handle to ARM 917 * @param h handle to ARM
1128 * @param service_name name of the service 918 * @param service_name name of the service
1129 * @param timeout how long to wait before failing for good
1130 * @param cont callback to invoke after request is sent or is not sent 919 * @param cont callback to invoke after request is sent or is not sent
1131 * @param cont_cls closure for @a cont 920 * @param cont_cls closure for @a cont
921 * @return handle for the operation, NULL on error
1132 */ 922 */
1133void 923struct GNUNET_ARM_Operation *
1134GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h, 924GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h,
1135 const char *service_name, 925 const char *service_name,
1136 struct GNUNET_TIME_Relative timeout,
1137 GNUNET_ARM_ResultCallback cont, 926 GNUNET_ARM_ResultCallback cont,
1138 void *cont_cls) 927 void *cont_cls)
1139{ 928{
929 struct GNUNET_ARM_Operation *op;
930
1140 LOG (GNUNET_ERROR_TYPE_DEBUG, 931 LOG (GNUNET_ERROR_TYPE_DEBUG,
1141 "Stopping service `%s' within %s\n", 932 "Stopping service `%s'\n",
1142 service_name, 933 service_name);
1143 GNUNET_STRINGS_relative_time_to_string (timeout, 934 op = change_service (h,
1144 GNUNET_NO)); 935 service_name,
1145 change_service (h, 936 cont,
1146 service_name, 937 cont_cls,
1147 timeout, 938 GNUNET_MESSAGE_TYPE_ARM_STOP);
1148 cont, 939 if (NULL == op)
1149 cont_cls, 940 return NULL;
1150 GNUNET_MESSAGE_TYPE_ARM_STOP); 941 /* If the service is ARM, set a flag as we will use MQ errors
942 to detect that the process is really gone. */
943 if (0 == strcasecmp (service_name,
944 "arm"))
945 op->is_arm_stop = GNUNET_YES;
946 return op;
1151} 947}
1152 948
1153 949
@@ -1155,43 +951,38 @@ GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h,
1155 * Request a list of running services. 951 * Request a list of running services.
1156 * 952 *
1157 * @param h handle to ARM 953 * @param h handle to ARM
1158 * @param timeout how long to wait before failing for good
1159 * @param cont callback to invoke after request is sent or is not sent 954 * @param cont callback to invoke after request is sent or is not sent
1160 * @param cont_cls closure for @a cont 955 * @param cont_cls closure for @a cont
956 * @return handle for the operation, NULL on error
1161 */ 957 */
1162void 958struct GNUNET_ARM_Operation *
1163GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h, 959GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h,
1164 struct GNUNET_TIME_Relative timeout,
1165 GNUNET_ARM_ServiceListCallback cont, 960 GNUNET_ARM_ServiceListCallback cont,
1166 void *cont_cls) 961 void *cont_cls)
1167{ 962{
1168 struct ARMControlMessage *cm; 963 struct GNUNET_ARM_Operation *op;
964 struct GNUNET_MQ_Envelope *env;
1169 struct GNUNET_ARM_Message *msg; 965 struct GNUNET_ARM_Message *msg;
1170 966
1171 LOG (GNUNET_ERROR_TYPE_DEBUG, 967 LOG (GNUNET_ERROR_TYPE_DEBUG,
1172 "Requesting LIST from ARM service with timeout: %s\n", 968 "Requesting LIST from ARM service\n");
1173 GNUNET_STRINGS_relative_time_to_string (timeout, 969 if (0 == h->request_id_counter)
1174 GNUNET_YES)); 970 h->request_id_counter++;
1175 cm = GNUNET_new (struct ARMControlMessage); 971 op = GNUNET_new (struct GNUNET_ARM_Operation);
1176 cm->h = h; 972 op->h = h;
1177 cm->list_cont = cont; 973 op->list_cont = cont;
1178 cm->cont_cls = cont_cls; 974 op->cont_cls = cont_cls;
1179 cm->timeout = GNUNET_TIME_relative_to_absolute (timeout); 975 op->id = h->request_id_counter++;
1180 msg = GNUNET_malloc (sizeof (struct GNUNET_ARM_Message)); 976 GNUNET_CONTAINER_DLL_insert_tail (h->operation_pending_head,
1181 msg->header.size = htons (sizeof (struct GNUNET_ARM_Message)); 977 h->operation_pending_tail,
1182 msg->header.type = htons (GNUNET_MESSAGE_TYPE_ARM_LIST); 978 op);
979 env = GNUNET_MQ_msg (msg,
980 GNUNET_MESSAGE_TYPE_ARM_LIST);
1183 msg->reserved = htonl (0); 981 msg->reserved = htonl (0);
1184 cm->msg = msg; 982 msg->request_id = GNUNET_htonll (op->id);
1185 GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head, 983 GNUNET_MQ_send (h->mq,
1186 h->control_pending_tail, 984 env);
1187 cm); 985 return op;
1188 cm->timeout_task_id =
1189 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining
1190 (cm->timeout),
1191 &control_message_timeout,
1192 cm);
1193 trigger_next_request (h,
1194 GNUNET_NO);
1195} 986}
1196 987
1197 988
diff --git a/src/arm/arm_monitor_api.c b/src/arm/arm_monitor_api.c
index 6d4129928..1f23c1dc5 100644
--- a/src/arm/arm_monitor_api.c
+++ b/src/arm/arm_monitor_api.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2012, 2013 GNUnet e.V. 3 Copyright (C) 2009, 2010, 2012, 2013, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -21,7 +21,8 @@
21/** 21/**
22 * @file arm/arm_monitor_api.c 22 * @file arm/arm_monitor_api.c
23 * @brief API for monitoring the ARM service 23 * @brief API for monitoring the ARM service
24 * @author Christian Grothoff, LRN 24 * @author Christian Grothoff
25 * @author LRN
25 */ 26 */
26#include "platform.h" 27#include "platform.h"
27#include "gnunet_arm_service.h" 28#include "gnunet_arm_service.h"
@@ -241,9 +242,9 @@ reconnect_arm_monitor (struct GNUNET_ARM_MonitorHandle *h)
241 * @return context to use for further ARM monitor operations, NULL on error. 242 * @return context to use for further ARM monitor operations, NULL on error.
242 */ 243 */
243struct GNUNET_ARM_MonitorHandle * 244struct GNUNET_ARM_MonitorHandle *
244GNUNET_ARM_monitor (const struct GNUNET_CONFIGURATION_Handle *cfg, 245GNUNET_ARM_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
245 GNUNET_ARM_ServiceStatusCallback cont, 246 GNUNET_ARM_ServiceStatusCallback cont,
246 void *cont_cls) 247 void *cont_cls)
247{ 248{
248 struct GNUNET_ARM_MonitorHandle *h; 249 struct GNUNET_ARM_MonitorHandle *h;
249 250
@@ -266,7 +267,7 @@ GNUNET_ARM_monitor (const struct GNUNET_CONFIGURATION_Handle *cfg,
266 * @param h the handle that was being used 267 * @param h the handle that was being used
267 */ 268 */
268void 269void
269GNUNET_ARM_monitor_disconnect_and_free (struct GNUNET_ARM_MonitorHandle *h) 270GNUNET_ARM_monitor_stop (struct GNUNET_ARM_MonitorHandle *h)
270{ 271{
271 if (NULL != h->mq) 272 if (NULL != h->mq)
272 { 273 {
diff --git a/src/arm/gnunet-arm.c b/src/arm/gnunet-arm.c
index 75ade59da..3b024ea93 100644
--- a/src/arm/gnunet-arm.c
+++ b/src/arm/gnunet-arm.c
@@ -29,28 +29,6 @@
29#include "gnunet_util_lib.h" 29#include "gnunet_util_lib.h"
30 30
31/** 31/**
32 * Timeout for stopping services. Long to give some services a real chance.
33 */
34#define STOP_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1)
35
36/**
37 * Timeout for stopping ARM. Extra-long since ARM needs to stop everyone else.
38 */
39#define STOP_TIMEOUT_ARM GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2)
40
41/**
42 * Timeout for starting services, very short because of the strange way start works
43 * (by checking if running before starting, so really this time is always waited on
44 * startup (annoying)).
45 */
46#define START_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
47
48/**
49 * Timeout for listing all running services.
50 */
51#define LIST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2)
52
53/**
54 * Set if we are to shutdown all services (including ARM). 32 * Set if we are to shutdown all services (including ARM).
55 */ 33 */
56static int end; 34static int end;
@@ -132,6 +110,7 @@ static unsigned int phase;
132 110
133/** 111/**
134 * User defined timestamp for completing operations. 112 * User defined timestamp for completing operations.
113 * FIXME: to be implemented!
135 */ 114 */
136static struct GNUNET_TIME_Relative timeout; 115static struct GNUNET_TIME_Relative timeout;
137 116
@@ -150,6 +129,10 @@ static unsigned int no_stderr;
150 */ 129 */
151static struct GNUNET_SCHEDULER_Task *al_task; 130static struct GNUNET_SCHEDULER_Task *al_task;
152 131
132/**
133 * Current operation.
134 */
135static struct GNUNET_ARM_Operation *op;
153 136
154/** 137/**
155 * Attempts to delete configuration file and GNUNET_HOME 138 * Attempts to delete configuration file and GNUNET_HOME
@@ -193,14 +176,19 @@ shutdown_task (void *cls)
193 GNUNET_SCHEDULER_cancel (al_task); 176 GNUNET_SCHEDULER_cancel (al_task);
194 al_task = NULL; 177 al_task = NULL;
195 } 178 }
179 if (NULL != op)
180 {
181 GNUNET_ARM_operation_cancel (op);
182 op = NULL;
183 }
196 if (NULL != h) 184 if (NULL != h)
197 { 185 {
198 GNUNET_ARM_disconnect_and_free (h); 186 GNUNET_ARM_disconnect (h);
199 h = NULL; 187 h = NULL;
200 } 188 }
201 if (NULL != m) 189 if (NULL != m)
202 { 190 {
203 GNUNET_ARM_monitor_disconnect_and_free (m); 191 GNUNET_ARM_monitor_stop (m);
204 m = NULL; 192 m = NULL;
205 } 193 }
206 if ((GNUNET_YES == end) && (GNUNET_YES == delete)) 194 if ((GNUNET_YES == end) && (GNUNET_YES == delete))
@@ -229,8 +217,6 @@ req_string (enum GNUNET_ARM_RequestStatus rs)
229 return _("We disconnected from ARM before we could send a request"); 217 return _("We disconnected from ARM before we could send a request");
230 case GNUNET_ARM_REQUEST_BUSY: 218 case GNUNET_ARM_REQUEST_BUSY:
231 return _("ARM API is busy"); 219 return _("ARM API is busy");
232 case GNUNET_ARM_REQUEST_TOO_LONG:
233 return _("Request does not fit into a message");
234 case GNUNET_ARM_REQUEST_TIMEOUT: 220 case GNUNET_ARM_REQUEST_TIMEOUT:
235 return _("Request timed out"); 221 return _("Request timed out");
236 } 222 }
@@ -289,8 +275,8 @@ action_loop (void *cls);
289 * our first attempt. 275 * our first attempt.
290 * 276 *
291 * @param cls closure 277 * @param cls closure
292 * @param connected GNUNET_YES if connected, GNUNET_NO if disconnected, 278 * @param connected #GNUNET_YES if connected, #GNUNET_NO if disconnected,
293 * GNUNET_SYSERR on error. 279 * #GNUNET_SYSERR on error.
294 */ 280 */
295static void 281static void
296conn_status (void *cls, 282conn_status (void *cls,
@@ -318,18 +304,17 @@ conn_status (void *cls,
318 * 304 *
319 * @param cls closure unused 305 * @param cls closure unused
320 * @param rs what happened to our request 306 * @param rs what happened to our request
321 * @param service name of the service we tried to start ("arm")
322 * @param result if the request was processed, this is the result 307 * @param result if the request was processed, this is the result
323 * according to ARM 308 * according to ARM
324 */ 309 */
325static void 310static void
326start_callback (void *cls, 311start_callback (void *cls,
327 enum GNUNET_ARM_RequestStatus rs, 312 enum GNUNET_ARM_RequestStatus rs,
328 const char *service,
329 enum GNUNET_ARM_Result result) 313 enum GNUNET_ARM_Result result)
330{ 314{
331 char *msg; 315 char *msg;
332 316
317 op = NULL;
333 if (GNUNET_ARM_REQUEST_SENT_OK != rs) 318 if (GNUNET_ARM_REQUEST_SENT_OK != rs)
334 { 319 {
335 GNUNET_asprintf (&msg, "%s", _("Failed to start the ARM service: %s\n")); 320 GNUNET_asprintf (&msg, "%s", _("Failed to start the ARM service: %s\n"));
@@ -362,18 +347,17 @@ start_callback (void *cls,
362 * 347 *
363 * @param cls closure unused 348 * @param cls closure unused
364 * @param rs what happened to our request 349 * @param rs what happened to our request
365 * @param service name of the service we tried to start ("arm")
366 * @param result if the request was processed, this is the result 350 * @param result if the request was processed, this is the result
367 * according to ARM 351 * according to ARM
368 */ 352 */
369static void 353static void
370stop_callback (void *cls, 354stop_callback (void *cls,
371 enum GNUNET_ARM_RequestStatus rs, 355 enum GNUNET_ARM_RequestStatus rs,
372 const char *service,
373 enum GNUNET_ARM_Result result) 356 enum GNUNET_ARM_Result result)
374{ 357{
375 char *msg; 358 char *msg;
376 359
360 op = NULL;
377 if (GNUNET_ARM_REQUEST_SENT_OK != rs) 361 if (GNUNET_ARM_REQUEST_SENT_OK != rs)
378 { 362 {
379 GNUNET_asprintf (&msg, "%s", 363 GNUNET_asprintf (&msg, "%s",
@@ -416,18 +400,17 @@ stop_callback (void *cls,
416 * 400 *
417 * @param cls closure unused 401 * @param cls closure unused
418 * @param rs what happened to our request 402 * @param rs what happened to our request
419 * @param service name of the service we tried to start
420 * @param result if the request was processed, this is the result 403 * @param result if the request was processed, this is the result
421 * according to ARM 404 * according to ARM
422 */ 405 */
423static void 406static void
424init_callback (void *cls, 407init_callback (void *cls,
425 enum GNUNET_ARM_RequestStatus rs, 408 enum GNUNET_ARM_RequestStatus rs,
426 const char *service,
427 enum GNUNET_ARM_Result result) 409 enum GNUNET_ARM_Result result)
428{ 410{
429 char *msg; 411 char *msg;
430 412
413 op = NULL;
431 if (GNUNET_ARM_REQUEST_SENT_OK != rs) 414 if (GNUNET_ARM_REQUEST_SENT_OK != rs)
432 { 415 {
433 GNUNET_asprintf (&msg, 416 GNUNET_asprintf (&msg,
@@ -441,9 +424,11 @@ init_callback (void *cls,
441 if ((GNUNET_ARM_RESULT_STARTING != result) && 424 if ((GNUNET_ARM_RESULT_STARTING != result) &&
442 (GNUNET_ARM_RESULT_IS_STARTED_ALREADY != result)) 425 (GNUNET_ARM_RESULT_IS_STARTED_ALREADY != result))
443 { 426 {
444 GNUNET_asprintf (&msg, _("Failed to start the `%s' service: %s\n"), 427 GNUNET_asprintf (&msg,
445 init, ret_string (result)); 428 _("Failed to start the `%s' service: %s\n"),
446 FPRINTF (stdout, msg, service); 429 init,
430 ret_string (result));
431 FPRINTF (stdout, "%s", msg);
447 GNUNET_free (msg); 432 GNUNET_free (msg);
448 GNUNET_SCHEDULER_shutdown (); 433 GNUNET_SCHEDULER_shutdown ();
449 return; 434 return;
@@ -465,17 +450,17 @@ init_callback (void *cls,
465 * 450 *
466 * @param cls closure unused 451 * @param cls closure unused
467 * @param rs what happened to our request 452 * @param rs what happened to our request
468 * @param service name of the service we tried to start
469 * @param result if the request was processed, this is the result 453 * @param result if the request was processed, this is the result
470 * according to ARM 454 * according to ARM
471 */ 455 */
472static void 456static void
473term_callback (void *cls, 457term_callback (void *cls,
474 enum GNUNET_ARM_RequestStatus rs, 458 enum GNUNET_ARM_RequestStatus rs,
475 const char *service,
476 enum GNUNET_ARM_Result result) 459 enum GNUNET_ARM_Result result)
477{ 460{
478 char *msg; 461 char *msg;
462
463 op = NULL;
479 if (GNUNET_ARM_REQUEST_SENT_OK != rs) 464 if (GNUNET_ARM_REQUEST_SENT_OK != rs)
480 { 465 {
481 GNUNET_asprintf (&msg, 466 GNUNET_asprintf (&msg,
@@ -492,7 +477,7 @@ term_callback (void *cls,
492 GNUNET_asprintf (&msg, 477 GNUNET_asprintf (&msg,
493 _("Failed to kill the `%s' service: %s\n"), 478 _("Failed to kill the `%s' service: %s\n"),
494 term, ret_string (result)); 479 term, ret_string (result));
495 FPRINTF (stdout, msg, service); 480 FPRINTF (stdout, "%s", msg);
496 GNUNET_free (msg); 481 GNUNET_free (msg);
497 GNUNET_SCHEDULER_shutdown (); 482 GNUNET_SCHEDULER_shutdown ();
498 return; 483 return;
@@ -525,6 +510,7 @@ list_callback (void *cls,
525{ 510{
526 unsigned int i; 511 unsigned int i;
527 512
513 op = NULL;
528 if (GNUNET_ARM_REQUEST_SENT_OK != rs) 514 if (GNUNET_ARM_REQUEST_SENT_OK != rs)
529 { 515 {
530 char *msg; 516 char *msg;
@@ -573,9 +559,10 @@ action_loop (void *cls)
573 { 559 {
574 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 560 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
575 "Termination action\n"); 561 "Termination action\n");
576 GNUNET_ARM_request_service_stop (h, term, 562 op = GNUNET_ARM_request_service_stop (h,
577 (0 == timeout.rel_value_us) ? STOP_TIMEOUT : timeout, 563 term,
578 &term_callback, NULL); 564 &term_callback,
565 NULL);
579 return; 566 return;
580 } 567 }
581 break; 568 break;
@@ -584,9 +571,10 @@ action_loop (void *cls)
584 { 571 {
585 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 572 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
586 "End action\n"); 573 "End action\n");
587 GNUNET_ARM_request_service_stop (h, "arm", 574 op = GNUNET_ARM_request_service_stop (h,
588 (0 == timeout.rel_value_us) ? STOP_TIMEOUT_ARM : timeout, 575 "arm",
589 &stop_callback, NULL); 576 &stop_callback,
577 NULL);
590 return; 578 return;
591 } 579 }
592 break; 580 break;
@@ -595,11 +583,11 @@ action_loop (void *cls)
595 { 583 {
596 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 584 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
597 "Start action\n"); 585 "Start action\n");
598 GNUNET_ARM_request_service_start (h, "arm", 586 op = GNUNET_ARM_request_service_start (h, "arm",
599 (no_stdout ? 0 : GNUNET_OS_INHERIT_STD_OUT) | 587 (no_stdout ? 0 : GNUNET_OS_INHERIT_STD_OUT) |
600 (no_stderr ? 0 : GNUNET_OS_INHERIT_STD_ERR), 588 (no_stderr ? 0 : GNUNET_OS_INHERIT_STD_ERR),
601 (0 == timeout.rel_value_us) ? START_TIMEOUT: timeout, 589 &start_callback,
602 start_callback, NULL); 590 NULL);
603 return; 591 return;
604 } 592 }
605 break; 593 break;
@@ -608,10 +596,10 @@ action_loop (void *cls)
608 { 596 {
609 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 597 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
610 "Initialization action\n"); 598 "Initialization action\n");
611 GNUNET_ARM_request_service_start (h, init, 599 op = GNUNET_ARM_request_service_start (h, init,
612 GNUNET_OS_INHERIT_STD_NONE, 600 GNUNET_OS_INHERIT_STD_NONE,
613 (0 == timeout.rel_value_us) ? STOP_TIMEOUT : timeout, 601 &init_callback,
614 &init_callback, NULL); 602 NULL);
615 return; 603 return;
616 } 604 }
617 break; 605 break;
@@ -620,9 +608,9 @@ action_loop (void *cls)
620 { 608 {
621 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 609 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
622 "Going to list all running services controlled by ARM.\n"); 610 "Going to list all running services controlled by ARM.\n");
623 GNUNET_ARM_request_service_list (h, 611 op = GNUNET_ARM_request_service_list (h,
624 (0 == timeout.rel_value_us) ? LIST_TIMEOUT : timeout, 612 &list_callback,
625 &list_callback, &list); 613 &list);
626 return; 614 return;
627 } 615 }
628 break; 616 break;
@@ -676,13 +664,21 @@ srv_status (void *cls,
676 break; 664 break;
677 } 665 }
678 if (! quiet) 666 if (! quiet)
679 { 667 {
680 if (NULL != msg) 668 if (NULL != msg)
681 FPRINTF (stderr, msg, service); 669 FPRINTF (stderr,
682 else 670 msg,
683 FPRINTF (stderr, _("Unknown status %u for service %s.\n"), status, service); 671 service);
684 } 672 else
685 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got service %s status %d\n", service, (int) status); 673 FPRINTF (stderr,
674 _("Unknown status %u for service %s.\n"),
675 status,
676 service);
677 }
678 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
679 "Got service %s status %d\n",
680 service, (int)
681 status);
686} 682}
687 683
688 684
@@ -705,30 +701,44 @@ run (void *cls,
705 cfg = GNUNET_CONFIGURATION_dup (c); 701 cfg = GNUNET_CONFIGURATION_dup (c);
706 config_file = cfgfile; 702 config_file = cfgfile;
707 if (GNUNET_OK != 703 if (GNUNET_OK !=
708 GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", "GNUNET_HOME", &dir)) 704 GNUNET_CONFIGURATION_get_value_string (cfg,
705 "PATHS",
706 "GNUNET_HOME",
707 &dir))
709 { 708 {
710 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 709 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
711 "PATHS", "GNUNET_HOME"); 710 "PATHS",
711 "GNUNET_HOME");
712 return; 712 return;
713 } 713 }
714 if (NULL != cfgfile) 714 if (NULL != cfgfile)
715 { 715 {
716 if (GNUNET_OK != 716 if (GNUNET_OK !=
717 GNUNET_CONFIGURATION_get_value_filename (cfg, "arm", "CONFIG", 717 GNUNET_CONFIGURATION_get_value_filename (cfg,
718 "arm",
719 "CONFIG",
718 &armconfig)) 720 &armconfig))
719 { 721 {
720 GNUNET_CONFIGURATION_set_value_string (cfg, "arm", "CONFIG", 722 GNUNET_CONFIGURATION_set_value_string (cfg,
723 "arm",
724 "CONFIG",
721 cfgfile); 725 cfgfile);
722 } 726 }
723 else 727 else
724 GNUNET_free (armconfig); 728 GNUNET_free (armconfig);
725 } 729 }
726 if (NULL == (h = GNUNET_ARM_connect (cfg, &conn_status, NULL))) 730 if (NULL == (h = GNUNET_ARM_connect (cfg,
731 &conn_status,
732 NULL)))
727 return; 733 return;
728 if (monitor) 734 if (monitor)
729 m = GNUNET_ARM_monitor (cfg, &srv_status, NULL); 735 m = GNUNET_ARM_monitor_start (cfg,
730 al_task = GNUNET_SCHEDULER_add_now (&action_loop, NULL); 736 &srv_status,
731 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); 737 NULL);
738 al_task = GNUNET_SCHEDULER_add_now (&action_loop,
739 NULL);
740 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
741 NULL);
732} 742}
733 743
734 744
@@ -774,7 +784,8 @@ main (int argc, char *const *argv)
774 GNUNET_GETOPT_OPTION_END 784 GNUNET_GETOPT_OPTION_END
775 }; 785 };
776 786
777 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 787 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv,
788 &argc, &argv))
778 return 2; 789 return 2;
779 790
780 if (GNUNET_OK == 791 if (GNUNET_OK ==
diff --git a/src/arm/test_arm_api.c b/src/arm/test_arm_api.c
index f5283d714..0449c41d4 100644
--- a/src/arm/test_arm_api.c
+++ b/src/arm/test_arm_api.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2009, 2011 GNUnet e.V. 3 Copyright (C) 2009, 2011, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -28,60 +28,64 @@
28 28
29#define LOG(...) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) 29#define LOG(...) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
30 30
31#define START_ARM GNUNET_YES
32
33#define START_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 1500)
34
35#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) 31#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
36 32
37static const struct GNUNET_CONFIGURATION_Handle *cfg; 33static const struct GNUNET_CONFIGURATION_Handle *cfg;
38 34
39static struct GNUNET_ARM_Handle *arm; 35static struct GNUNET_ARM_Handle *arm;
40 36
37static struct GNUNET_ARM_Operation *op;
38
41static int ok = 1; 39static int ok = 1;
42 40
43static int phase = 0; 41static int phase = 0;
44 42
43
45static void 44static void
46arm_stop_cb (void *cls, 45arm_stop_cb (void *cls,
47 enum GNUNET_ARM_RequestStatus status, 46 enum GNUNET_ARM_RequestStatus status,
48 const char *servicename,
49 enum GNUNET_ARM_Result result) 47 enum GNUNET_ARM_Result result)
50{ 48{
49 op = NULL;
51 /* (6), a stop request should be sent to ARM successfully */ 50 /* (6), a stop request should be sent to ARM successfully */
52 /* ARM should report that it is stopping */ 51 /* ARM should report that it is stopping */
53 GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK); 52 GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
54 GNUNET_break (result == GNUNET_ARM_RESULT_STOPPED); 53 GNUNET_break (result == GNUNET_ARM_RESULT_STOPPED);
55 GNUNET_break (phase == 6); 54 GNUNET_break (phase == 6);
56 phase++; 55 phase++;
57 LOG ("Sent 'STOP' request for arm to ARM %s\n", (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully"); 56 LOG ("Sent 'STOP' request for arm to ARM %s\n",
57 (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully");
58 GNUNET_SCHEDULER_shutdown ();
58} 59}
59 60
60 61
61static void 62static void
62resolver_stop_cb (void *cls, 63resolver_stop_cb (void *cls,
63 enum GNUNET_ARM_RequestStatus status, 64 enum GNUNET_ARM_RequestStatus status,
64 const char *servicename, enum GNUNET_ARM_Result result) 65 enum GNUNET_ARM_Result result)
65{ 66{
67 op = NULL;
66 /* (5), a stop request should be sent to ARM successfully. 68 /* (5), a stop request should be sent to ARM successfully.
67 * ARM should report that resolver is stopped. 69 * ARM should report that resolver is stopped.
68 */ 70 */
69 GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK); 71 GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
70 GNUNET_break (result == GNUNET_ARM_RESULT_STOPPED); 72 GNUNET_break (result == GNUNET_ARM_RESULT_STOPPED);
71 GNUNET_break (phase == 5); 73 GNUNET_break (phase == 5);
72 LOG ("Sent 'STOP' request for resolver to ARM %s\n", (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully"); 74 LOG ("Sent 'STOP' request for resolver to ARM %s\n",
75 (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully");
73 phase++; 76 phase++;
74#if START_ARM 77 GNUNET_assert (NULL == op);
75 GNUNET_ARM_request_service_stop (arm, "arm", TIMEOUT, arm_stop_cb, NULL); 78 op = GNUNET_ARM_request_service_stop (arm,
76#else 79 "arm",
77 arm_stop_cb (NULL, GNUNET_ARM_STATUS_SENT_OK, "arm", GNUNET_ARM_SERVICE_STOPPING); 80 &arm_stop_cb,
78 arm_conn (NULL, GNUNET_NO); 81 NULL);
79#endif
80} 82}
81 83
82 84
83static void 85static void
84dns_notify (void *cls, const struct sockaddr *addr, socklen_t addrlen) 86dns_notify (void *cls,
87 const struct sockaddr *addr,
88 socklen_t addrlen)
85{ 89{
86 if (addr == NULL) 90 if (addr == NULL)
87 { 91 {
@@ -91,7 +95,11 @@ dns_notify (void *cls, const struct sockaddr *addr, socklen_t addrlen)
91 LOG ("Finished resolving localhost\n"); 95 LOG ("Finished resolving localhost\n");
92 if (ok != 0) 96 if (ok != 0)
93 ok = 2; 97 ok = 2;
94 GNUNET_ARM_request_service_stop (arm, "resolver", TIMEOUT, resolver_stop_cb, NULL); 98 GNUNET_assert (NULL == op);
99 op = GNUNET_ARM_request_service_stop (arm,
100 "resolver",
101 &resolver_stop_cb,
102 NULL);
95 return; 103 return;
96 } 104 }
97 /* (3), resolver should resolve localhost */ 105 /* (3), resolver should resolve localhost */
@@ -106,25 +114,22 @@ dns_notify (void *cls, const struct sockaddr *addr, socklen_t addrlen)
106static void 114static void
107resolver_start_cb (void *cls, 115resolver_start_cb (void *cls,
108 enum GNUNET_ARM_RequestStatus status, 116 enum GNUNET_ARM_RequestStatus status,
109 const char *servicename,
110 enum GNUNET_ARM_Result result) 117 enum GNUNET_ARM_Result result)
111{ 118{
119 op = NULL;
112 /* (2), the start request for resolver should be sent successfully 120 /* (2), the start request for resolver should be sent successfully
113 * ARM should report that resolver service is starting. 121 * ARM should report that resolver service is starting.
114 */ 122 */
115 GNUNET_assert (status == GNUNET_ARM_REQUEST_SENT_OK); 123 GNUNET_assert (status == GNUNET_ARM_REQUEST_SENT_OK);
116 GNUNET_break (phase == 2); 124 GNUNET_break (phase == 2);
117 GNUNET_break (result == GNUNET_ARM_RESULT_STARTING); 125 GNUNET_break (result == GNUNET_ARM_RESULT_STARTING);
118 LOG ("Sent 'START' request for resolver to ARM %s\n", (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully"); 126 LOG ("Sent 'START' request for resolver to ARM %s\n",
127 (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully");
119 phase++; 128 phase++;
120 GNUNET_RESOLVER_ip_get ("localhost", AF_INET, TIMEOUT, &dns_notify, NULL); 129 GNUNET_RESOLVER_ip_get ("localhost",
121} 130 AF_INET,
122 131 TIMEOUT,
123 132 &dns_notify, NULL);
124static void
125trigger_disconnect (void *cls)
126{
127 GNUNET_ARM_disconnect_and_free ((struct GNUNET_ARM_Handle *) cls);
128} 133}
129 134
130 135
@@ -146,7 +151,12 @@ arm_conn (void *cls,
146 LOG ("Connected to ARM\n"); 151 LOG ("Connected to ARM\n");
147 GNUNET_break (phase == 1); 152 GNUNET_break (phase == 1);
148 phase++; 153 phase++;
149 GNUNET_ARM_request_service_start (arm, "resolver", GNUNET_OS_INHERIT_STD_OUT_AND_ERR, START_TIMEOUT, resolver_start_cb, NULL); 154 GNUNET_assert (NULL == op);
155 op = GNUNET_ARM_request_service_start (arm,
156 "resolver",
157 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
158 &resolver_start_cb,
159 NULL);
150 } 160 }
151 else 161 else
152 { 162 {
@@ -157,7 +167,6 @@ arm_conn (void *cls,
157 ok = 3; 167 ok = 3;
158 else if (ok == 1) 168 else if (ok == 1)
159 ok = 0; 169 ok = 0;
160 GNUNET_SCHEDULER_add_now (&trigger_disconnect, arm);
161 } 170 }
162} 171}
163 172
@@ -165,9 +174,9 @@ arm_conn (void *cls,
165static void 174static void
166arm_start_cb (void *cls, 175arm_start_cb (void *cls,
167 enum GNUNET_ARM_RequestStatus status, 176 enum GNUNET_ARM_RequestStatus status,
168 const char *servicename,
169 enum GNUNET_ARM_Result result) 177 enum GNUNET_ARM_Result result)
170{ 178{
179 op = NULL;
171 /* (0) The request should be "sent" successfully 180 /* (0) The request should be "sent" successfully
172 * ("sent", because it isn't going anywhere, ARM API starts ARM service 181 * ("sent", because it isn't going anywhere, ARM API starts ARM service
173 * by itself). 182 * by itself).
@@ -175,26 +184,48 @@ arm_start_cb (void *cls,
175 */ 184 */
176 GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK); 185 GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
177 GNUNET_break (phase == 0); 186 GNUNET_break (phase == 0);
178 LOG ("Sent 'START' request for arm to ARM %s\n", (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully"); 187 LOG ("Sent 'START' request for arm to ARM %s\n",
188 (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully");
179 GNUNET_break (result == GNUNET_ARM_RESULT_STARTING); 189 GNUNET_break (result == GNUNET_ARM_RESULT_STARTING);
180 phase++; 190 phase++;
181} 191}
182 192
183 193
184static void 194static void
185task (void *cls, char *const *args, const char *cfgfile, 195do_shutdown (void *cls)
196{
197 if (NULL != op)
198 {
199 GNUNET_ARM_operation_cancel (op);
200 op = NULL;
201 }
202 if (NULL != arm)
203 {
204 GNUNET_ARM_disconnect (arm);
205 arm = NULL;
206 }
207}
208
209
210static void
211task (void *cls,
212 char *const *args,
213 const char *cfgfile,
186 const struct GNUNET_CONFIGURATION_Handle *c) 214 const struct GNUNET_CONFIGURATION_Handle *c)
187{ 215{
188 cfg = c; 216 cfg = c;
189 arm = GNUNET_ARM_connect (cfg, &arm_conn, NULL); 217 arm = GNUNET_ARM_connect (cfg,
218 &arm_conn,
219 NULL);
190 if (NULL == arm) 220 if (NULL == arm)
191 return; 221 return;
192#if START_ARM 222 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
193 GNUNET_ARM_request_service_start (arm, "arm", GNUNET_OS_INHERIT_STD_OUT_AND_ERR, START_TIMEOUT, arm_start_cb, NULL); 223 NULL);
194#else 224 op = GNUNET_ARM_request_service_start (arm,
195 arm_start_cb (NULL, arm, GNUNET_ARM_REQUEST_SENT_OK, "arm", GNUNET_ARM_RESULT_STARTING); 225 "arm",
196 arm_conn (NULL, arm, GNUNET_YES); 226 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
197#endif 227 &arm_start_cb,
228 NULL);
198} 229}
199 230
200 231
diff --git a/src/arm/test_exponential_backoff.c b/src/arm/test_exponential_backoff.c
index 3f33c91e6..8135f5157 100644
--- a/src/arm/test_exponential_backoff.c
+++ b/src/arm/test_exponential_backoff.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2009 GNUnet e.V. 3 Copyright (C) 2009, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -70,7 +70,9 @@ static char *killLogFileName;
70#endif 70#endif
71 71
72 72
73typedef void (*GNUNET_CLIENT_ShutdownTask) (void *cls, int reason); 73typedef void
74(*GNUNET_CLIENT_ShutdownTask) (void *cls, int reason);
75
74 76
75/** 77/**
76 * Context for handling the shutdown of a service. 78 * Context for handling the shutdown of a service.
@@ -118,7 +120,8 @@ struct ShutdownContext
118 * @param msg NULL, indicating socket closure. 120 * @param msg NULL, indicating socket closure.
119 */ 121 */
120static void 122static void
121service_shutdown_handler (void *cls, const struct GNUNET_MessageHeader *msg) 123service_shutdown_handler (void *cls,
124 const struct GNUNET_MessageHeader *msg)
122{ 125{
123 struct ShutdownContext *shutdown_ctx = cls; 126 struct ShutdownContext *shutdown_ctx = cls;
124 127
@@ -147,7 +150,8 @@ service_shutdown_cancel (void *cls)
147{ 150{
148 struct ShutdownContext *shutdown_ctx = cls; 151 struct ShutdownContext *shutdown_ctx = cls;
149 152
150 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "service_shutdown_cancel called!\n"); 153 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
154 "service_shutdown_cancel called!\n");
151 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_SYSERR); 155 shutdown_ctx->cont (shutdown_ctx->cont_cls, GNUNET_SYSERR);
152 GNUNET_CLIENT_disconnect (shutdown_ctx->sock); 156 GNUNET_CLIENT_disconnect (shutdown_ctx->sock);
153 GNUNET_free (shutdown_ctx); 157 GNUNET_free (shutdown_ctx);
@@ -207,8 +211,9 @@ write_shutdown (void *cls, size_t size, void *buf)
207 */ 211 */
208static void 212static void
209do_nothing_service_shutdown (struct GNUNET_CLIENT_Connection *sock, 213do_nothing_service_shutdown (struct GNUNET_CLIENT_Connection *sock,
210 struct GNUNET_TIME_Relative timeout, 214 struct GNUNET_TIME_Relative timeout,
211 GNUNET_CLIENT_ShutdownTask cont, void *cont_cls) 215 GNUNET_CLIENT_ShutdownTask cont,
216 void *cont_cls)
212{ 217{
213 struct ShutdownContext *shutdown_ctx; 218 struct ShutdownContext *shutdown_ctx;
214 219
@@ -266,7 +271,10 @@ kill_task (void *cbData)
266 else if (trialCount == 13) 271 else if (trialCount == 13)
267 { 272 {
268 GNUNET_CLIENT_disconnect (doNothingConnection); 273 GNUNET_CLIENT_disconnect (doNothingConnection);
269 GNUNET_ARM_request_service_stop (arm, SERVICE, TIMEOUT, NULL, NULL); 274 GNUNET_ARM_request_service_stop (arm,
275 SERVICE,
276 NULL,
277 NULL);
270 if (waitedFor_prev.rel_value_us >= waitedFor.rel_value_us) 278 if (waitedFor_prev.rel_value_us >= waitedFor.rel_value_us)
271 ok = 9; 279 ok = 9;
272 else 280 else
@@ -284,15 +292,14 @@ kill_task (void *cbData)
284static void 292static void
285trigger_disconnect (void *cls) 293trigger_disconnect (void *cls)
286{ 294{
287 GNUNET_ARM_disconnect_and_free (arm); 295 GNUNET_ARM_disconnect (arm);
288 GNUNET_ARM_monitor_disconnect_and_free (mon); 296 GNUNET_ARM_monitor_stop (mon);
289} 297}
290 298
291 299
292static void 300static void
293arm_stop_cb (void *cls, 301arm_stop_cb (void *cls,
294 enum GNUNET_ARM_RequestStatus status, 302 enum GNUNET_ARM_RequestStatus status,
295 const char *servicename,
296 enum GNUNET_ARM_Result result) 303 enum GNUNET_ARM_Result result)
297{ 304{
298 GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK); 305 GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
@@ -303,14 +310,19 @@ arm_stop_cb (void *cls,
303 310
304 311
305static void 312static void
306srv_status (void *cls, const char *service, enum GNUNET_ARM_ServiceStatus status) 313srv_status (void *cls,
314 const char *service,
315 enum GNUNET_ARM_ServiceStatus status)
307{ 316{
308 LOG ("Service %s is %u, phase %u\n", service, status, phase); 317 LOG ("Service %s is %u, phase %u\n", service, status, phase);
309 if (status == GNUNET_ARM_SERVICE_MONITORING_STARTED) 318 if (status == GNUNET_ARM_SERVICE_MONITORING_STARTED)
310 { 319 {
311 phase++; 320 phase++;
312 GNUNET_ARM_request_service_start (arm, SERVICE, 321 GNUNET_ARM_request_service_start (arm,
313 GNUNET_OS_INHERIT_STD_OUT_AND_ERR, TIMEOUT, NULL, NULL); 322 SERVICE,
323 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
324 NULL,
325 NULL);
314 return; 326 return;
315 } 327 }
316 if (phase == 1) 328 if (phase == 1)
@@ -322,7 +334,8 @@ srv_status (void *cls, const char *service, enum GNUNET_ARM_ServiceStatus status
322 phase++; 334 phase++;
323 ok = 1; 335 ok = 1;
324 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, 336 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
325 &kill_task, NULL); 337 &kill_task,
338 NULL);
326 } 339 }
327 else if ((phase == 2) && (strcasecmp (SERVICE, service) == 0)) 340 else if ((phase == 2) && (strcasecmp (SERVICE, service) == 0))
328 { 341 {
@@ -337,14 +350,19 @@ srv_status (void *cls, const char *service, enum GNUNET_ARM_ServiceStatus status
337 else if ((status == GNUNET_ARM_SERVICE_STOPPED) && (trialCount == 14)) 350 else if ((status == GNUNET_ARM_SERVICE_STOPPED) && (trialCount == 14))
338 { 351 {
339 phase++; 352 phase++;
340 GNUNET_ARM_request_service_stop (arm, "arm", TIMEOUT, arm_stop_cb, NULL); 353 GNUNET_ARM_request_service_stop (arm,
354 "arm",
355 &arm_stop_cb,
356 NULL);
341 } 357 }
342 } 358 }
343} 359}
344 360
345 361
346static void 362static void
347arm_start_cb (void *cls, enum GNUNET_ARM_RequestStatus status, const char *servicename, enum GNUNET_ARM_Result result) 363arm_start_cb (void *cls,
364 enum GNUNET_ARM_RequestStatus status,
365 enum GNUNET_ARM_Result result)
348{ 366{
349 GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK); 367 GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
350 GNUNET_break (result == GNUNET_ARM_RESULT_STARTING); 368 GNUNET_break (result == GNUNET_ARM_RESULT_STARTING);
@@ -355,26 +373,34 @@ arm_start_cb (void *cls, enum GNUNET_ARM_RequestStatus status, const char *servi
355 373
356 374
357static void 375static void
358task (void *cls, char *const *args, const char *cfgfile, 376task (void *cls,
377 char *const *args,
378 const char *cfgfile,
359 const struct GNUNET_CONFIGURATION_Handle *c) 379 const struct GNUNET_CONFIGURATION_Handle *c)
360{ 380{
361 cfg = c; 381 cfg = c;
362 arm = GNUNET_ARM_connect (cfg, NULL, NULL); 382 arm = GNUNET_ARM_connect (cfg, NULL, NULL);
363 if (NULL != arm) 383 if (NULL != arm)
364 { 384 {
365 mon = GNUNET_ARM_monitor (cfg, &srv_status, NULL); 385 mon = GNUNET_ARM_monitor_start (cfg, &srv_status, NULL);
366 if (NULL != mon) 386 if (NULL != mon)
367 { 387 {
368#if START_ARM 388#if START_ARM
369 GNUNET_ARM_request_service_start (arm, "arm", 389 GNUNET_ARM_request_service_start (arm,
370 GNUNET_OS_INHERIT_STD_OUT_AND_ERR, GNUNET_TIME_UNIT_ZERO, arm_start_cb, NULL); 390 "arm",
391 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
392 &arm_start_cb,
393 NULL);
371#else 394#else
372 arm_start_cb (NULL, arm, GNUNET_ARM_REQUEST_SENT_OK, "arm", GNUNET_ARM_SERVICE_STARTING); 395 arm_start_cb (NULL,
396 arm,
397 GNUNET_ARM_REQUEST_SENT_OK,
398 GNUNET_ARM_SERVICE_STARTING);
373#endif 399#endif
374 } 400 }
375 else 401 else
376 { 402 {
377 GNUNET_ARM_disconnect_and_free (arm); 403 GNUNET_ARM_disconnect (arm);
378 arm = NULL; 404 arm = NULL;
379 } 405 }
380 } 406 }
diff --git a/src/arm/test_gnunet_service_arm.c b/src/arm/test_gnunet_service_arm.c
index 33662e579..71bf55084 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;
51static void 51static void
52trigger_disconnect (void *cls) 52trigger_disconnect (void *cls)
53{ 53{
54 GNUNET_ARM_disconnect_and_free (arm); 54 GNUNET_ARM_disconnect (arm);
55 arm = NULL; 55 arm = NULL;
56} 56}
57 57
@@ -59,7 +59,6 @@ trigger_disconnect (void *cls)
59static void 59static void
60arm_stop_cb (void *cls, 60arm_stop_cb (void *cls,
61 enum GNUNET_ARM_RequestStatus status, 61 enum GNUNET_ARM_RequestStatus status,
62 const char *servicename,
63 enum GNUNET_ARM_Result result) 62 enum GNUNET_ARM_Result result)
64{ 63{
65 GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK); 64 GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
@@ -100,15 +99,15 @@ service_list (void *cls,
100 stop_arm: 99 stop_arm:
101 GNUNET_ARM_request_service_stop (arm, 100 GNUNET_ARM_request_service_stop (arm,
102 "arm", 101 "arm",
103 TIMEOUT, 102 &arm_stop_cb,
104 &arm_stop_cb, NULL); 103 NULL);
105} 104}
106 105
107 106
108static void 107static void
109hostname_resolve_cb (void *cls, 108hostname_resolve_cb (void *cls,
110 const struct sockaddr *addr, 109 const struct sockaddr *addr,
111 socklen_t addrlen) 110 socklen_t addrlen)
112{ 111{
113 if ((0 == ret) || (4 == ret) || (1 == resolved_ok)) 112 if ((0 == ret) || (4 == ret) || (1 == resolved_ok))
114 return; 113 return;
@@ -120,8 +119,8 @@ hostname_resolve_cb (void *cls,
120 ret = 3; 119 ret = 3;
121 GNUNET_ARM_request_service_stop (arm, 120 GNUNET_ARM_request_service_stop (arm,
122 "arm", 121 "arm",
123 TIMEOUT, 122 &arm_stop_cb,
124 &arm_stop_cb, NULL); 123 NULL);
125 return; 124 return;
126 } 125 }
127 if (0 == asked_for_a_list) 126 if (0 == asked_for_a_list)
@@ -129,7 +128,6 @@ hostname_resolve_cb (void *cls,
129 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 128 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
130 "Resolved hostname, now checking the service list\n"); 129 "Resolved hostname, now checking the service list\n");
131 GNUNET_ARM_request_service_list (arm, 130 GNUNET_ARM_request_service_list (arm,
132 TIMEOUT,
133 &service_list, 131 &service_list,
134 NULL); 132 NULL);
135 asked_for_a_list = 1; 133 asked_for_a_list = 1;
@@ -141,7 +139,6 @@ hostname_resolve_cb (void *cls,
141static void 139static void
142arm_start_cb (void *cls, 140arm_start_cb (void *cls,
143 enum GNUNET_ARM_RequestStatus status, 141 enum GNUNET_ARM_RequestStatus status,
144 const char *servicename,
145 enum GNUNET_ARM_Result result) 142 enum GNUNET_ARM_Result result)
146{ 143{
147 GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK); 144 GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
@@ -150,7 +147,8 @@ arm_start_cb (void *cls,
150 "Trying to resolve our own hostname!\n"); 147 "Trying to resolve our own hostname!\n");
151 /* connect to the resolver service */ 148 /* connect to the resolver service */
152 if (NULL == 149 if (NULL ==
153 GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC, TIMEOUT, 150 GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC,
151 TIMEOUT,
154 &hostname_resolve_cb, 152 &hostname_resolve_cb,
155 NULL)) 153 NULL))
156 { 154 {
@@ -159,8 +157,9 @@ arm_start_cb (void *cls,
159 GNUNET_break (0); 157 GNUNET_break (0);
160 ret = 2; 158 ret = 2;
161 GNUNET_ARM_request_service_stop (arm, 159 GNUNET_ARM_request_service_stop (arm,
162 "arm", TIMEOUT, 160 "arm",
163 &arm_stop_cb, NULL); 161 &arm_stop_cb,
162 NULL);
164 } 163 }
165} 164}
166 165
@@ -171,11 +170,14 @@ run (void *cls,
171 const char *cfgfile, 170 const char *cfgfile,
172 const struct GNUNET_CONFIGURATION_Handle *c) 171 const struct GNUNET_CONFIGURATION_Handle *c)
173{ 172{
174 arm = GNUNET_ARM_connect (c, NULL, NULL); 173 arm = GNUNET_ARM_connect (c,
175 GNUNET_ARM_request_service_start (arm, "arm", 174 NULL,
175 NULL);
176 GNUNET_ARM_request_service_start (arm,
177 "arm",
176 GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 178 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
177 START_TIMEOUT, 179 &arm_start_cb,
178 &arm_start_cb, NULL); 180 NULL);
179} 181}
180 182
181 183
diff --git a/src/include/gnunet_arm_service.h b/src/include/gnunet_arm_service.h
index f21524226..7fb14d3ac 100644
--- a/src/include/gnunet_arm_service.h
+++ b/src/include/gnunet_arm_service.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2009 GNUnet e.V. 3 Copyright (C) 2009, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -48,7 +48,7 @@ extern "C"
48/** 48/**
49 * Version of the arm API. 49 * Version of the arm API.
50 */ 50 */
51#define GNUNET_ARM_VERSION 0x00000002 51#define GNUNET_ARM_VERSION 0x00000003
52 52
53 53
54/** 54/**
@@ -78,12 +78,6 @@ enum GNUNET_ARM_RequestStatus
78 GNUNET_ARM_REQUEST_BUSY = 3, 78 GNUNET_ARM_REQUEST_BUSY = 3,
79 79
80 /** 80 /**
81 * It was discovered that the request would be too long to fit in a message,
82 * and thus it was not sent.
83 */
84 GNUNET_ARM_REQUEST_TOO_LONG = 4,
85
86 /**
87 * Request time ran out before we had a chance to send it. 81 * Request time ran out before we had a chance to send it.
88 */ 82 */
89 GNUNET_ARM_REQUEST_TIMEOUT = 5 83 GNUNET_ARM_REQUEST_TIMEOUT = 5
@@ -180,50 +174,56 @@ enum GNUNET_ARM_Result
180 */ 174 */
181struct GNUNET_ARM_Handle; 175struct GNUNET_ARM_Handle;
182 176
177/**
178 * Handle for an ARM operation.
179 */
180struct GNUNET_ARM_Operation;
181
183 182
184/** 183/**
185 * Function called whenever we connect to or disconnect from ARM. 184 * Function called whenever we connect to or disconnect from ARM.
186 * 185 *
187 * @param cls closure 186 * @param cls closure
188 * @param connected GNUNET_YES if connected, GNUNET_NO if disconnected, 187 * @param connected #GNUNET_YES if connected, #GNUNET_NO if disconnected,
189 * GNUNET_SYSERR if there was an error. 188 * #GNUNET_SYSERR if there was an error.
190 */ 189 */
191typedef void (*GNUNET_ARM_ConnectionStatusCallback) (void *cls, 190typedef void
192 int connected); 191(*GNUNET_ARM_ConnectionStatusCallback) (void *cls,
192 int connected);
193 193
194 194
195/** 195/**
196 * Function called in response to a start/stop request. 196 * Function called in response to a start/stop request.
197 * Will be called when request was not sent successfully, 197 * Will be called when request was not sent successfully,
198 * or when a reply comes. If the request was not sent successfully, 198 * or when a reply comes. If the request was not sent successfully,
199 * 'rs' will indicate that, and 'service' and 'result' will be undefined. 199 * @a rs will indicate that, and @a result will be undefined.
200 * 200 *
201 * @param cls closure 201 * @param cls closure
202 * @param rs status of the request 202 * @param rs status of the request
203 * @param service service name
204 * @param result result of the operation 203 * @param result result of the operation
205 */ 204 */
206typedef void (*GNUNET_ARM_ResultCallback) (void *cls, 205typedef void
207 enum GNUNET_ARM_RequestStatus rs, 206(*GNUNET_ARM_ResultCallback) (void *cls,
208 const char *service, 207 enum GNUNET_ARM_RequestStatus rs,
209 enum GNUNET_ARM_Result result); 208 enum GNUNET_ARM_Result result);
210 209
211 210
212/** 211/**
213 * Callback function invoked when list operation is complete. 212 * Callback function invoked when list operation is complete.
214 * Will be called when request was not sent successfully, 213 * Will be called when request was not sent successfully,
215 * or when a reply comes. If the request was not sent successfully, 214 * or when a reply comes. If the request was not sent successfully,
216 * 'rs' will indicate that, and 'count' and 'list' will be undefined. 215 * @a rs will indicate that, and @a count and @a list will be undefined.
217 * 216 *
218 * @param cls closure 217 * @param cls closure
219 * @param rs status of the request 218 * @param rs status of the request
220 * @param count number of strings in the list 219 * @param count number of strings in the list
221 * @param list list of running services 220 * @param list list of running services
222 */ 221 */
223typedef void (*GNUNET_ARM_ServiceListCallback) (void *cls, 222typedef void
224 enum GNUNET_ARM_RequestStatus rs, 223(*GNUNET_ARM_ServiceListCallback) (void *cls,
225 unsigned int count, 224 enum GNUNET_ARM_RequestStatus rs,
226 const char *const*list); 225 unsigned int count,
226 const char *const*list);
227 227
228 228
229/** 229/**
@@ -234,13 +234,13 @@ typedef void (*GNUNET_ARM_ServiceListCallback) (void *cls,
234 * the ARM service may internally use a different 234 * the ARM service may internally use a different
235 * configuration to determine how to start the service). 235 * configuration to determine how to start the service).
236 * @param conn_status will be called when connecting/disconnecting 236 * @param conn_status will be called when connecting/disconnecting
237 * @param cls closure for conn_status 237 * @param conn_status_cls closure for @a conn_status
238 * @return context to use for further ARM operations, NULL on error. 238 * @return context to use for further ARM operations, NULL on error.
239 */ 239 */
240struct GNUNET_ARM_Handle * 240struct GNUNET_ARM_Handle *
241GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, 241GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
242 GNUNET_ARM_ConnectionStatusCallback conn_status, 242 GNUNET_ARM_ConnectionStatusCallback conn_status,
243 void *cls); 243 void *conn_status_cls);
244 244
245 245
246/** 246/**
@@ -249,21 +249,31 @@ GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
249 * @param h the handle that was being used 249 * @param h the handle that was being used
250 */ 250 */
251void 251void
252GNUNET_ARM_disconnect_and_free (struct GNUNET_ARM_Handle *h); 252GNUNET_ARM_disconnect (struct GNUNET_ARM_Handle *h);
253
254
255/**
256 * Abort an operation. Only prevents the callback from being
257 * called, the operation may still complete.
258 *
259 * @param op operation to cancel
260 */
261void
262GNUNET_ARM_operation_cancel (struct GNUNET_ARM_Operation *op);
253 263
254 264
255/** 265/**
256 * Request a list of running services. 266 * Request a list of running services.
257 * 267 *
258 * @param h handle to ARM 268 * @param h handle to ARM
259 * @param timeout how long to wait before failing for good
260 * @param cont callback to invoke after request is sent or is not sent 269 * @param cont callback to invoke after request is sent or is not sent
261 * @param cont_cls closure for callback 270 * @param cont_cls closure for @a cont
271 * @return handle for the operation, NULL on error
262 */ 272 */
263void 273struct GNUNET_ARM_Operation *
264GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h, 274GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h,
265 struct GNUNET_TIME_Relative timeout, 275 GNUNET_ARM_ServiceListCallback cont,
266 GNUNET_ARM_ServiceListCallback cont, void *cont_cls); 276 void *cont_cls);
267 277
268 278
269/** 279/**
@@ -271,20 +281,20 @@ GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h,
271 * Stopping arm itself will not invalidate its handle, and 281 * Stopping arm itself will not invalidate its handle, and
272 * ARM API will try to restore connection to the ARM service, 282 * ARM API will try to restore connection to the ARM service,
273 * even if ARM connection was lost because you asked for ARM to be stopped. 283 * even if ARM connection was lost because you asked for ARM to be stopped.
274 * Call GNUNET_ARM_disconnect_and_free () to free the handle and prevent 284 * Call #GNUNET_ARM_disconnect() to free the handle and prevent
275 * further connection attempts. 285 * further connection attempts.
276 * 286 *
277 * @param h handle to ARM 287 * @param h handle to ARM
278 * @param service_name name of the service 288 * @param service_name name of the service
279 * @param timeout how long to wait before failing for good
280 * @param cont callback to invoke after request is sent or is not sent 289 * @param cont callback to invoke after request is sent or is not sent
281 * @param cont_cls closure for callback 290 * @param cont_cls closure for @a cont
291 * @return handle for the operation, NULL on error
282 */ 292 */
283void 293struct GNUNET_ARM_Operation *
284GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h, 294GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h,
285 const char *service_name, 295 const char *service_name,
286 struct GNUNET_TIME_Relative timeout, 296 GNUNET_ARM_ResultCallback cont,
287 GNUNET_ARM_ResultCallback cont, void *cont_cls); 297 void *cont_cls);
288 298
289 299
290/** 300/**
@@ -293,15 +303,14 @@ GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h,
293 * @param h handle to ARM 303 * @param h handle to ARM
294 * @param service_name name of the service 304 * @param service_name name of the service
295 * @param std_inheritance inheritance of std streams 305 * @param std_inheritance inheritance of std streams
296 * @param timeout how long to wait before failing for good
297 * @param cont callback to invoke after request is sent or not sent 306 * @param cont callback to invoke after request is sent or not sent
298 * @param cont_cls closure for callback 307 * @param cont_cls closure for @a cont
308 * @return handle for the operation, NULL on error
299 */ 309 */
300void 310struct GNUNET_ARM_Operation *
301GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h, 311GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h,
302 const char *service_name, 312 const char *service_name,
303 enum GNUNET_OS_InheritStdioFlags std_inheritance, 313 enum GNUNET_OS_InheritStdioFlags std_inheritance,
304 struct GNUNET_TIME_Relative timeout,
305 GNUNET_ARM_ResultCallback cont, 314 GNUNET_ARM_ResultCallback cont,
306 void *cont_cls); 315 void *cont_cls);
307 316
@@ -316,13 +325,13 @@ struct GNUNET_ARM_MonitorHandle;
316 * Function called in when a status update arrives. 325 * Function called in when a status update arrives.
317 * 326 *
318 * @param cls closure 327 * @param cls closure
319 * @param arm handle to the arm connection
320 * @param service service name 328 * @param service service name
321 * @param status status of the service 329 * @param status status of the service
322 */ 330 */
323typedef void (*GNUNET_ARM_ServiceStatusCallback) (void *cls, 331typedef void
324 const char *service, 332(*GNUNET_ARM_ServiceStatusCallback) (void *cls,
325 enum GNUNET_ARM_ServiceStatus status); 333 const char *service,
334 enum GNUNET_ARM_ServiceStatus status);
326 335
327 336
328/** 337/**
@@ -333,13 +342,13 @@ typedef void (*GNUNET_ARM_ServiceStatusCallback) (void *cls,
333 * the ARM service may internally use a different 342 * the ARM service may internally use a different
334 * configuration to determine how to start the service). 343 * configuration to determine how to start the service).
335 * @param cont callback to invoke on status updates 344 * @param cont callback to invoke on status updates
336 * @param cont_cls closure 345 * @param cont_cls closure for @a cont
337 * @return context to use for further ARM monitor operations, NULL on error. 346 * @return context to use for further ARM monitor operations, NULL on error.
338 */ 347 */
339struct GNUNET_ARM_MonitorHandle * 348struct GNUNET_ARM_MonitorHandle *
340GNUNET_ARM_monitor (const struct GNUNET_CONFIGURATION_Handle *cfg, 349GNUNET_ARM_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
341 GNUNET_ARM_ServiceStatusCallback cont, 350 GNUNET_ARM_ServiceStatusCallback cont,
342 void *cont_cls); 351 void *cont_cls);
343 352
344 353
345/** 354/**
@@ -348,7 +357,7 @@ GNUNET_ARM_monitor (const struct GNUNET_CONFIGURATION_Handle *cfg,
348 * @param h the handle that was being used 357 * @param h the handle that was being used
349 */ 358 */
350void 359void
351GNUNET_ARM_monitor_disconnect_and_free (struct GNUNET_ARM_MonitorHandle *h); 360GNUNET_ARM_monitor_stop (struct GNUNET_ARM_MonitorHandle *h);
352 361
353#if 0 /* keep Emacsens' auto-indent happy */ 362#if 0 /* keep Emacsens' auto-indent happy */
354{ 363{
diff --git a/src/include/gnunet_testbed_logger_service.h b/src/include/gnunet_testbed_logger_service.h
index ce82da5c2..c10c2ee6b 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);
75 * @param cls the closure given to GNUNET_TESTBED_LOGGER_send() 75 * @param cls the closure given to GNUNET_TESTBED_LOGGER_send()
76 * @param size the amount of data sent 76 * @param size the amount of data sent
77 */ 77 */
78typedef void (*GNUNET_TESTBED_LOGGER_FlushCompletion) (void *cls, size_t size); 78typedef void
79(*GNUNET_TESTBED_LOGGER_FlushCompletion) (void *cls,
80 size_t size);
79 81
80 82
81/** 83/**
@@ -89,7 +91,8 @@ typedef void (*GNUNET_TESTBED_LOGGER_FlushCompletion) (void *cls, size_t size);
89 */ 91 */
90void 92void
91GNUNET_TESTBED_LOGGER_write (struct GNUNET_TESTBED_LOGGER_Handle *h, 93GNUNET_TESTBED_LOGGER_write (struct GNUNET_TESTBED_LOGGER_Handle *h,
92 const void *data, size_t size); 94 const void *data,
95 size_t size);
93 96
94 97
95/** 98/**
diff --git a/src/include/gnunet_testing_lib.h b/src/include/gnunet_testing_lib.h
index 72b5ede04..e09068444 100644
--- a/src/include/gnunet_testing_lib.h
+++ b/src/include/gnunet_testing_lib.h
@@ -157,9 +157,7 @@ struct GNUNET_TESTING_System *
157GNUNET_TESTING_system_create_with_portrange (const char *testdir, 157GNUNET_TESTING_system_create_with_portrange (const char *testdir,
158 const char *trusted_ip, 158 const char *trusted_ip,
159 const char *hostname, 159 const char *hostname,
160 const struct 160 const struct GNUNET_TESTING_SharedService *shared_services,
161 GNUNET_TESTING_SharedService *
162 shared_services,
163 uint16_t lowport, 161 uint16_t lowport,
164 uint16_t highport); 162 uint16_t highport);
165 163
@@ -185,12 +183,12 @@ GNUNET_TESTING_system_destroy (struct GNUNET_TESTING_System *system,
185 * GNUnet source code. 183 * GNUnet source code.
186 * 184 *
187 * This is primarily a helper function used internally 185 * This is primarily a helper function used internally
188 * by 'GNUNET_TESTING_peer_configure'. 186 * by #GNUNET_TESTING_peer_configure().
189 * 187 *
190 * @param system the testing system handle 188 * @param system the testing system handle
191 * @param key_number desired pre-created hostkey to obtain 189 * @param key_number desired pre-created hostkey to obtain
192 * @param id set to the peer's identity (hash of the public 190 * @param id set to the peer's identity (hash of the public
193 * key; if NULL, GNUNET_SYSERR is returned immediately 191 * key; if NULL, #GNUNET_SYSERR is returned immediately
194 * @return NULL on error (not enough keys) 192 * @return NULL on error (not enough keys)
195 */ 193 */
196struct GNUNET_CRYPTO_EddsaPrivateKey * 194struct GNUNET_CRYPTO_EddsaPrivateKey *
@@ -227,10 +225,10 @@ GNUNET_TESTING_release_port (struct GNUNET_TESTING_System *system,
227 * system. The default configuration will be available in PATHS section under 225 * system. The default configuration will be available in PATHS section under
228 * the option DEFAULTCONFIG after the call. SERVICE_HOME is also set in PATHS 226 * the option DEFAULTCONFIG after the call. SERVICE_HOME is also set in PATHS
229 * section to the temporary directory specific to this configuration. If we run 227 * section to the temporary directory specific to this configuration. If we run
230 * out of "*port" numbers, return SYSERR. 228 * out of "*port" numbers, return #GNUNET_SYSERR.
231 * 229 *
232 * This is primarily a helper function used internally 230 * This is primarily a helper function used internally
233 * by 'GNUNET_TESTING_peer_configure'. 231 * by #GNUNET_TESTING_peer_configure().
234 * 232 *
235 * @param system system to use to coordinate resource usage 233 * @param system system to use to coordinate resource usage
236 * @param cfg template configuration to update 234 * @param cfg template configuration to update
@@ -353,9 +351,9 @@ typedef void
353 * 351 *
354 * @param peer the peer to stop 352 * @param peer the peer to stop
355 * @param cb the callback to signal peer shutdown 353 * @param cb the callback to signal peer shutdown
356 * @param cb_cls closure for the above callback 354 * @param cb_cls closure for the @a cb
357 * @return GNUNET_OK upon successfully giving the request to the ARM API (this 355 * @return #GNUNET_OK upon successfully giving the request to the ARM API (this
358 * does not mean that the peer is successfully stopped); GNUNET_SYSERR 356 * does not mean that the peer is successfully stopped); #GNUNET_SYSERR
359 * upon any error. 357 * upon any error.
360 */ 358 */
361int 359int
diff --git a/src/testbed/gnunet-service-testbed_peers.c b/src/testbed/gnunet-service-testbed_peers.c
index 9c12c25a6..b55f5a8c8 100644
--- a/src/testbed/gnunet-service-testbed_peers.c
+++ b/src/testbed/gnunet-service-testbed_peers.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2008--2013 GNUnet e.V. 3 Copyright (C) 2008--2013, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -72,6 +72,11 @@ struct ManageServiceContext
72 struct GNUNET_SERVER_Client *client; 72 struct GNUNET_SERVER_Client *client;
73 73
74 /** 74 /**
75 * Name of the service.
76 */
77 char *service;
78
79 /**
75 * The operation id of the associated request 80 * The operation id of the associated request
76 */ 81 */
77 uint64_t op_id; 82 uint64_t op_id;
@@ -421,7 +426,8 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client,
421 &msg->header, 426 &msg->header,
422 peer_create_success_cb, fo_ctxt); 427 peer_create_success_cb, fo_ctxt);
423 fo_ctxt->timeout_task = 428 fo_ctxt->timeout_task =
424 GNUNET_SCHEDULER_add_delayed (GST_timeout, &peer_create_forward_timeout, 429 GNUNET_SCHEDULER_add_delayed (GST_timeout,
430 &peer_create_forward_timeout,
425 fo_ctxt); 431 fo_ctxt);
426 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fo_ctxt); 432 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fo_ctxt);
427 GNUNET_SERVER_receive_done (client, GNUNET_OK); 433 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -475,7 +481,8 @@ GST_handle_peer_destroy (void *cls,
475 fopc->operation_id, &msg->header, 481 fopc->operation_id, &msg->header,
476 &peer_destroy_success_cb, fopc); 482 &peer_destroy_success_cb, fopc);
477 fopc->timeout_task = 483 fopc->timeout_task =
478 GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout, 484 GNUNET_SCHEDULER_add_delayed (GST_timeout,
485 &GST_forwarded_operation_timeout,
479 fopc); 486 fopc);
480 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc); 487 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
481 GNUNET_SERVER_receive_done (client, GNUNET_OK); 488 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -568,7 +575,8 @@ GST_handle_peer_start (void *cls, struct GNUNET_SERVER_Client *client,
568 &GST_forwarded_operation_reply_relay, 575 &GST_forwarded_operation_reply_relay,
569 fopc); 576 fopc);
570 fopc->timeout_task = 577 fopc->timeout_task =
571 GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout, 578 GNUNET_SCHEDULER_add_delayed (GST_timeout,
579 &GST_forwarded_operation_timeout,
572 fopc); 580 fopc);
573 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc); 581 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
574 GNUNET_SERVER_receive_done (client, GNUNET_OK); 582 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -594,14 +602,15 @@ GST_handle_peer_start (void *cls, struct GNUNET_SERVER_Client *client,
594 602
595 603
596/** 604/**
597 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages 605 * Message handler for #GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages
598 * 606 *
599 * @param cls NULL 607 * @param cls NULL
600 * @param client identification of the client 608 * @param client identification of the client
601 * @param message the actual message 609 * @param message the actual message
602 */ 610 */
603void 611void
604GST_handle_peer_stop (void *cls, struct GNUNET_SERVER_Client *client, 612GST_handle_peer_stop (void *cls,
613 struct GNUNET_SERVER_Client *client,
605 const struct GNUNET_MessageHeader *message) 614 const struct GNUNET_MessageHeader *message)
606{ 615{
607 const struct GNUNET_TESTBED_PeerStopMessage *msg; 616 const struct GNUNET_TESTBED_PeerStopMessage *msg;
@@ -612,10 +621,13 @@ GST_handle_peer_stop (void *cls, struct GNUNET_SERVER_Client *client,
612 621
613 msg = (const struct GNUNET_TESTBED_PeerStopMessage *) message; 622 msg = (const struct GNUNET_TESTBED_PeerStopMessage *) message;
614 peer_id = ntohl (msg->peer_id); 623 peer_id = ntohl (msg->peer_id);
615 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PEER_STOP for peer %u\n", peer_id); 624 LOG (GNUNET_ERROR_TYPE_DEBUG,
625 "Received PEER_STOP for peer %u\n",
626 (unsigned int) peer_id);
616 if (!VALID_PEER_ID (peer_id)) 627 if (!VALID_PEER_ID (peer_id))
617 { 628 {
618 GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), 629 GST_send_operation_fail_msg (client,
630 GNUNET_ntohll (msg->operation_id),
619 "Peer not found"); 631 "Peer not found");
620 GNUNET_SERVER_receive_done (client, GNUNET_OK); 632 GNUNET_SERVER_receive_done (client, GNUNET_OK);
621 return; 633 return;
@@ -623,8 +635,9 @@ GST_handle_peer_stop (void *cls, struct GNUNET_SERVER_Client *client,
623 peer = GST_peer_list[peer_id]; 635 peer = GST_peer_list[peer_id];
624 if (GNUNET_YES == peer->is_remote) 636 if (GNUNET_YES == peer->is_remote)
625 { 637 {
626 LOG (GNUNET_ERROR_TYPE_DEBUG, "Forwarding PEER_STOP for peer %u\n", 638 LOG (GNUNET_ERROR_TYPE_DEBUG,
627 peer_id); 639 "Forwarding PEER_STOP for peer %u\n",
640 (unsigned int) peer_id);
628 fopc = GNUNET_new (struct ForwardedOperationContext); 641 fopc = GNUNET_new (struct ForwardedOperationContext);
629 GNUNET_SERVER_client_keep (client); 642 GNUNET_SERVER_client_keep (client);
630 fopc->client = client; 643 fopc->client = client;
@@ -633,25 +646,35 @@ GST_handle_peer_stop (void *cls, struct GNUNET_SERVER_Client *client,
633 fopc->opc = 646 fopc->opc =
634 GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote. 647 GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
635 slave->controller, 648 slave->controller,
636 fopc->operation_id, &msg->header, 649 fopc->operation_id,
650 &msg->header,
637 &GST_forwarded_operation_reply_relay, 651 &GST_forwarded_operation_reply_relay,
638 fopc); 652 fopc);
639 fopc->timeout_task = 653 fopc->timeout_task =
640 GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout, 654 GNUNET_SCHEDULER_add_delayed (GST_timeout,
655 &GST_forwarded_operation_timeout,
656 fopc);
657 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
658 fopcq_tail,
641 fopc); 659 fopc);
642 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
643 GNUNET_SERVER_receive_done (client, GNUNET_OK); 660 GNUNET_SERVER_receive_done (client, GNUNET_OK);
644 return; 661 return;
645 } 662 }
646 if (GNUNET_OK != stop_peer (peer)) 663 if (GNUNET_OK != stop_peer (peer))
647 { 664 {
648 LOG (GNUNET_ERROR_TYPE_WARNING, "Stopping peer %u failed\n", peer_id); 665 LOG (GNUNET_ERROR_TYPE_WARNING,
649 GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), 666 "Stopping peer %u failed\n",
667 (unsigned int) peer_id);
668 GST_send_operation_fail_msg (client,
669 GNUNET_ntohll (msg->operation_id),
650 "Peer not running"); 670 "Peer not running");
651 GNUNET_SERVER_receive_done (client, GNUNET_OK); 671 GNUNET_SERVER_receive_done (client,
672 GNUNET_OK);
652 return; 673 return;
653 } 674 }
654 LOG (GNUNET_ERROR_TYPE_DEBUG, "Peer %u successfully stopped\n", peer_id); 675 LOG (GNUNET_ERROR_TYPE_DEBUG,
676 "Peer %u successfully stopped\n",
677 (unsigned int) peer_id);
655 reply = GNUNET_new (struct GNUNET_TESTBED_PeerEventMessage); 678 reply = GNUNET_new (struct GNUNET_TESTBED_PeerEventMessage);
656 reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT); 679 reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT);
657 reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerEventMessage)); 680 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,
689 712
690 msg = (const struct GNUNET_TESTBED_PeerGetConfigurationMessage *) message; 713 msg = (const struct GNUNET_TESTBED_PeerGetConfigurationMessage *) message;
691 peer_id = ntohl (msg->peer_id); 714 peer_id = ntohl (msg->peer_id);
692 LOG_DEBUG ("Received GET_CONFIG for peer %u\n", peer_id); 715 LOG_DEBUG ("Received GET_CONFIG for peer %u\n",
716 (unsigned int) peer_id);
693 if (!VALID_PEER_ID (peer_id)) 717 if (!VALID_PEER_ID (peer_id))
694 { 718 {
695 GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), 719 GST_send_operation_fail_msg (client,
720 GNUNET_ntohll (msg->operation_id),
696 "Peer not found"); 721 "Peer not found");
697 GNUNET_SERVER_receive_done (client, GNUNET_OK); 722 GNUNET_SERVER_receive_done (client, GNUNET_OK);
698 return; 723 return;
@@ -700,7 +725,8 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client,
700 peer = GST_peer_list[peer_id]; 725 peer = GST_peer_list[peer_id];
701 if (GNUNET_YES == peer->is_remote) 726 if (GNUNET_YES == peer->is_remote)
702 { 727 {
703 LOG_DEBUG ("Forwarding PEER_GET_CONFIG for peer: %u\n", peer_id); 728 LOG_DEBUG ("Forwarding PEER_GET_CONFIG for peer: %u\n",
729 (unsigned int) peer_id);
704 fopc = GNUNET_new (struct ForwardedOperationContext); 730 fopc = GNUNET_new (struct ForwardedOperationContext);
705 GNUNET_SERVER_client_keep (client); 731 GNUNET_SERVER_client_keep (client);
706 fopc->client = client; 732 fopc->client = client;
@@ -709,21 +735,28 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client,
709 fopc->opc = 735 fopc->opc =
710 GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote. 736 GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
711 slave->controller, 737 slave->controller,
712 fopc->operation_id, &msg->header, 738 fopc->operation_id,
739 &msg->header,
713 &GST_forwarded_operation_reply_relay, 740 &GST_forwarded_operation_reply_relay,
714 fopc); 741 fopc);
715 fopc->timeout_task = 742 fopc->timeout_task =
716 GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout, 743 GNUNET_SCHEDULER_add_delayed (GST_timeout,
744 &GST_forwarded_operation_timeout,
745 fopc);
746 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
747 fopcq_tail,
717 fopc); 748 fopc);
718 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
719 GNUNET_SERVER_receive_done (client, GNUNET_OK); 749 GNUNET_SERVER_receive_done (client, GNUNET_OK);
720 return; 750 return;
721 } 751 }
722 LOG_DEBUG ("Received PEER_GET_CONFIG for peer: %u\n", peer_id); 752 LOG_DEBUG ("Received PEER_GET_CONFIG for peer: %u\n",
753 peer_id);
723 config = 754 config =
724 GNUNET_CONFIGURATION_serialize (GST_peer_list[peer_id]->details.local.cfg, 755 GNUNET_CONFIGURATION_serialize (GST_peer_list[peer_id]->details.local.cfg,
725 &c_size); 756 &c_size);
726 xc_size = GNUNET_TESTBED_compress_config_ (config, c_size, &xconfig); 757 xc_size = GNUNET_TESTBED_compress_config_ (config,
758 c_size,
759 &xconfig);
727 GNUNET_free (config); 760 GNUNET_free (config);
728 msize = 761 msize =
729 xc_size + 762 xc_size +
@@ -799,7 +832,8 @@ update_peer_config (struct Peer *peer,
799 emsg = NULL; 832 emsg = NULL;
800 peer->details.local.peer 833 peer->details.local.peer
801 = GNUNET_TESTING_peer_configure (GST_context->system, 834 = GNUNET_TESTING_peer_configure (GST_context->system,
802 peer->details.local.cfg, peer->id, 835 peer->details.local.cfg,
836 peer->id,
803 NULL /* Peer id */ , 837 NULL /* Peer id */ ,
804 &emsg); 838 &emsg);
805 return emsg; 839 return emsg;
@@ -811,11 +845,13 @@ update_peer_config (struct Peer *peer,
811 * 845 *
812 * @param cls the closure given to GNUNET_TESTING_peer_stop_async() 846 * @param cls the closure given to GNUNET_TESTING_peer_stop_async()
813 * @param p the respective peer whose status is being reported 847 * @param p the respective peer whose status is being reported
814 * @param success GNUNET_YES if the peer is stopped; GNUNET_SYSERR upon any 848 * @param success #GNUNET_YES if the peer is stopped; #GNUNET_SYSERR upon any
815 * error 849 * error
816 */ 850 */
817static void 851static void
818prc_stop_cb (void *cls, struct GNUNET_TESTING_Peer *p, int success) 852prc_stop_cb (void *cls,
853 struct GNUNET_TESTING_Peer *p,
854 int success)
819{ 855{
820 struct PeerReconfigureContext *prc = cls; 856 struct PeerReconfigureContext *prc = cls;
821 struct Peer *peer; 857 struct Peer *peer;
@@ -829,16 +865,20 @@ prc_stop_cb (void *cls, struct GNUNET_TESTING_Peer *p, int success)
829 prc->stopped = 1; 865 prc->stopped = 1;
830 if (NULL != emsg) 866 if (NULL != emsg)
831 { 867 {
832 GST_send_operation_fail_msg (prc->client, prc->op_id, emsg); 868 GST_send_operation_fail_msg (prc->client,
869 prc->op_id,
870 emsg);
833 goto cleanup; 871 goto cleanup;
834 } 872 }
835 if (GNUNET_OK != start_peer (peer)) 873 if (GNUNET_OK != start_peer (peer))
836 { 874 {
837 GST_send_operation_fail_msg (prc->client, prc->op_id, 875 GST_send_operation_fail_msg (prc->client,
876 prc->op_id,
838 "Failed to start reconfigured peer"); 877 "Failed to start reconfigured peer");
839 goto cleanup; 878 goto cleanup;
840 } 879 }
841 GST_send_operation_success_msg (prc->client, prc->op_id); 880 GST_send_operation_success_msg (prc->client,
881 prc->op_id);
842 882
843 cleanup: 883 cleanup:
844 cleanup_prc (prc); 884 cleanup_prc (prc);
@@ -847,7 +887,7 @@ prc_stop_cb (void *cls, struct GNUNET_TESTING_Peer *p, int success)
847 887
848 888
849/** 889/**
850 * Handler for GNUNET_MESSAGE_TYPDE_TESTBED_RECONFIGURE_PEER type messages. 890 * Handler for #GNUNET_MESSAGE_TYPDE_TESTBED_RECONFIGURE_PEER type messages.
851 * Should stop the peer asyncronously, destroy it and create it again with the 891 * Should stop the peer asyncronously, destroy it and create it again with the
852 * new configuration. 892 * new configuration.
853 * 893 *
@@ -856,7 +896,8 @@ prc_stop_cb (void *cls, struct GNUNET_TESTING_Peer *p, int success)
856 * @param message the actual message 896 * @param message the actual message
857 */ 897 */
858void 898void
859GST_handle_peer_reconfigure (void *cls, struct GNUNET_SERVER_Client *client, 899GST_handle_peer_reconfigure (void *cls,
900 struct GNUNET_SERVER_Client *client,
860 const struct GNUNET_MessageHeader *message) 901 const struct GNUNET_MessageHeader *message)
861{ 902{
862 const struct GNUNET_TESTBED_PeerReconfigureMessage *msg; 903 const struct GNUNET_TESTBED_PeerReconfigureMessage *msg;
@@ -873,7 +914,8 @@ GST_handle_peer_reconfigure (void *cls, struct GNUNET_SERVER_Client *client,
873 if (msize <= sizeof (struct GNUNET_TESTBED_PeerReconfigureMessage)) 914 if (msize <= sizeof (struct GNUNET_TESTBED_PeerReconfigureMessage))
874 { 915 {
875 GNUNET_break_op (0); 916 GNUNET_break_op (0);
876 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 917 GNUNET_SERVER_receive_done (client,
918 GNUNET_SYSERR);
877 return; 919 return;
878 } 920 }
879 msg = (const struct GNUNET_TESTBED_PeerReconfigureMessage *) message; 921 msg = (const struct GNUNET_TESTBED_PeerReconfigureMessage *) message;
@@ -882,8 +924,11 @@ GST_handle_peer_reconfigure (void *cls, struct GNUNET_SERVER_Client *client,
882 if (!VALID_PEER_ID (peer_id)) 924 if (!VALID_PEER_ID (peer_id))
883 { 925 {
884 GNUNET_break (0); 926 GNUNET_break (0);
885 GST_send_operation_fail_msg (client, op_id, "Peer not found"); 927 GST_send_operation_fail_msg (client,
886 GNUNET_SERVER_receive_done (client, GNUNET_OK); 928 op_id,
929 "Peer not found");
930 GNUNET_SERVER_receive_done (client,
931 GNUNET_OK);
887 return; 932 return;
888 } 933 }
889 peer = GST_peer_list[peer_id]; 934 peer = GST_peer_list[peer_id];
@@ -898,60 +943,85 @@ GST_handle_peer_reconfigure (void *cls, struct GNUNET_SERVER_Client *client,
898 fopc->opc = 943 fopc->opc =
899 GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote. 944 GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
900 slave->controller, 945 slave->controller,
901 fopc->operation_id, &msg->header, 946 fopc->operation_id,
947 &msg->header,
902 &GST_forwarded_operation_reply_relay, 948 &GST_forwarded_operation_reply_relay,
903 fopc); 949 fopc);
904 fopc->timeout_task = 950 fopc->timeout_task =
905 GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout, 951 GNUNET_SCHEDULER_add_delayed (GST_timeout,
952 &GST_forwarded_operation_timeout,
953 fopc);
954 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
955 fopcq_tail,
906 fopc); 956 fopc);
907 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
908 GNUNET_SERVER_receive_done (client, GNUNET_OK); 957 GNUNET_SERVER_receive_done (client, GNUNET_OK);
909 return; 958 return;
910 } 959 }
911 LOG_DEBUG ("Received PEER_RECONFIGURE for peer %u\n", peer_id); 960 LOG_DEBUG ("Received PEER_RECONFIGURE for peer %u\n",
961 (unsigned int) peer_id);
912 if (0 < peer->reference_cnt) 962 if (0 < peer->reference_cnt)
913 { 963 {
914 GNUNET_break (0); 964 GNUNET_break (0);
915 GST_send_operation_fail_msg (client, op_id, "Peer in use"); 965 GST_send_operation_fail_msg (client,
916 GNUNET_SERVER_receive_done (client, GNUNET_OK); 966 op_id,
967 "Peer in use");
968 GNUNET_SERVER_receive_done (client,
969 GNUNET_OK);
917 return; 970 return;
918 } 971 }
919 if (GNUNET_YES == peer->destroy_flag) 972 if (GNUNET_YES == peer->destroy_flag)
920 { 973 {
921 GNUNET_break (0); 974 GNUNET_break (0);
922 GST_send_operation_fail_msg (client, op_id, "Peer is being destroyed"); 975 GST_send_operation_fail_msg (client,
923 GNUNET_SERVER_receive_done (client, GNUNET_OK); 976 op_id,
977 "Peer is being destroyed");
978 GNUNET_SERVER_receive_done (client,
979 GNUNET_OK);
924 return; 980 return;
925 } 981 }
926 cfg = GNUNET_TESTBED_extract_config_ (message); 982 cfg = GNUNET_TESTBED_extract_config_ (message);
927 if (NULL == cfg) 983 if (NULL == cfg)
928 { 984 {
929 GNUNET_break (0); 985 GNUNET_break (0);
930 GST_send_operation_fail_msg (client, op_id, "Compression error"); 986 GST_send_operation_fail_msg (client,
931 GNUNET_SERVER_receive_done (client, GNUNET_OK); 987 op_id,
988 "Compression error");
989 GNUNET_SERVER_receive_done (client,
990 GNUNET_OK);
932 return; 991 return;
933 } 992 }
934 if (GNUNET_NO == peer->details.local.is_running) 993 if (GNUNET_NO == peer->details.local.is_running)
935 { 994 {
936 emsg = update_peer_config (peer, cfg); 995 emsg = update_peer_config (peer,
996 cfg);
937 if (NULL != emsg) 997 if (NULL != emsg)
938 GST_send_operation_fail_msg (client, op_id, emsg); 998 GST_send_operation_fail_msg (client,
939 GST_send_operation_success_msg (client, op_id); 999 op_id,
940 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1000 emsg);
1001 GST_send_operation_success_msg (client,
1002 op_id);
1003 GNUNET_SERVER_receive_done (client,
1004 GNUNET_OK);
941 GNUNET_free_non_null (emsg); 1005 GNUNET_free_non_null (emsg);
942 return; 1006 return;
943 } 1007 }
944 prc = GNUNET_new (struct PeerReconfigureContext); 1008 prc = GNUNET_new (struct PeerReconfigureContext);
945 if (GNUNET_OK != 1009 if (GNUNET_OK !=
946 GNUNET_TESTING_peer_stop_async (peer->details.local.peer, &prc_stop_cb, 1010 GNUNET_TESTING_peer_stop_async (peer->details.local.peer,
1011 &prc_stop_cb,
947 prc)) 1012 prc))
948 { 1013 {
949 GNUNET_assert (0 < GNUNET_asprintf (&emsg, 1014 GNUNET_assert (0 < GNUNET_asprintf (&emsg,
950 "Error trying to stop peer %u asynchronously\n", 1015 "Error trying to stop peer %u asynchronously\n",
951 peer_id)); 1016 peer_id));
952 LOG (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg); 1017 LOG (GNUNET_ERROR_TYPE_ERROR,
953 GST_send_operation_fail_msg (client, op_id, emsg); 1018 "%s\n",
954 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1019 emsg);
1020 GST_send_operation_fail_msg (client,
1021 op_id,
1022 emsg);
1023 GNUNET_SERVER_receive_done (client,
1024 GNUNET_OK);
955 GNUNET_free (prc); 1025 GNUNET_free (prc);
956 GNUNET_free (emsg); 1026 GNUNET_free (emsg);
957 return; 1027 return;
@@ -961,8 +1031,11 @@ GST_handle_peer_reconfigure (void *cls, struct GNUNET_SERVER_Client *client,
961 prc->op_id = op_id; 1031 prc->op_id = op_id;
962 prc->client = client; 1032 prc->client = client;
963 GNUNET_SERVER_client_keep (client); 1033 GNUNET_SERVER_client_keep (client);
964 GNUNET_CONTAINER_DLL_insert_tail (prc_head, prc_tail, prc); 1034 GNUNET_CONTAINER_DLL_insert_tail (prc_head,
965 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1035 prc_tail,
1036 prc);
1037 GNUNET_SERVER_receive_done (client,
1038 GNUNET_OK);
966} 1039}
967 1040
968 1041
@@ -975,14 +1048,17 @@ static void
975cleanup_mctx (struct ManageServiceContext *mctx) 1048cleanup_mctx (struct ManageServiceContext *mctx)
976{ 1049{
977 mctx->expired = GNUNET_YES; 1050 mctx->expired = GNUNET_YES;
978 GNUNET_CONTAINER_DLL_remove (mctx_head, mctx_tail, mctx); 1051 GNUNET_CONTAINER_DLL_remove (mctx_head,
1052 mctx_tail,
1053 mctx);
979 GNUNET_SERVER_client_drop (mctx->client); 1054 GNUNET_SERVER_client_drop (mctx->client);
980 GNUNET_ARM_disconnect_and_free (mctx->ah); 1055 GNUNET_ARM_disconnect (mctx->ah);
981 GNUNET_assert (0 < mctx->peer->reference_cnt); 1056 GNUNET_assert (0 < mctx->peer->reference_cnt);
982 mctx->peer->reference_cnt--; 1057 mctx->peer->reference_cnt--;
983 if ( (GNUNET_YES == mctx->peer->destroy_flag) 1058 if ( (GNUNET_YES == mctx->peer->destroy_flag)
984 && (0 == mctx->peer->reference_cnt) ) 1059 && (0 == mctx->peer->reference_cnt) )
985 GST_destroy_peer (mctx->peer); 1060 GST_destroy_peer (mctx->peer);
1061 GNUNET_free (mctx->service);
986 GNUNET_free (mctx); 1062 GNUNET_free (mctx);
987} 1063}
988 1064
@@ -999,7 +1075,7 @@ GST_free_mctxq ()
999 1075
1000 1076
1001/** 1077/**
1002 * Returns a string interpretation of 'rs' 1078 * Returns a string interpretation of @a rs.
1003 * 1079 *
1004 * @param rs the request status from ARM 1080 * @param rs the request status from ARM
1005 * @return a string interpretation of the request status 1081 * @return a string interpretation of the request status
@@ -1017,8 +1093,6 @@ arm_req_string (enum GNUNET_ARM_RequestStatus rs)
1017 return _("We disconnected from ARM before we could send a request"); 1093 return _("We disconnected from ARM before we could send a request");
1018 case GNUNET_ARM_REQUEST_BUSY: 1094 case GNUNET_ARM_REQUEST_BUSY:
1019 return _("ARM API is busy"); 1095 return _("ARM API is busy");
1020 case GNUNET_ARM_REQUEST_TOO_LONG:
1021 return _("Request doesn't fit into a message");
1022 case GNUNET_ARM_REQUEST_TIMEOUT: 1096 case GNUNET_ARM_REQUEST_TIMEOUT:
1023 return _("Request timed out"); 1097 return _("Request timed out");
1024 } 1098 }
@@ -1027,7 +1101,7 @@ arm_req_string (enum GNUNET_ARM_RequestStatus rs)
1027 1101
1028 1102
1029/** 1103/**
1030 * Returns a string interpretation of the 'result' 1104 * Returns a string interpretation of the @a result.
1031 * 1105 *
1032 * @param result the arm result 1106 * @param result the arm result
1033 * @return a string interpretation 1107 * @return a string interpretation
@@ -1066,17 +1140,16 @@ arm_ret_string (enum GNUNET_ARM_Result result)
1066 * Function called in response to a start/stop request. 1140 * Function called in response to a start/stop request.
1067 * Will be called when request was not sent successfully, 1141 * Will be called when request was not sent successfully,
1068 * or when a reply comes. If the request was not sent successfully, 1142 * or when a reply comes. If the request was not sent successfully,
1069 * 'rs' will indicate that, and 'service' and 'result' will be undefined. 1143 * @a rs will indicate that, and @a result will be undefined.
1070 * 1144 *
1071 * @param cls ManageServiceContext 1145 * @param cls ManageServiceContext
1072 * @param rs status of the request 1146 * @param rs status of the request
1073 * @param service service name
1074 * @param result result of the operation 1147 * @param result result of the operation
1075 */ 1148 */
1076static void 1149static void
1077service_manage_result_cb (void *cls, 1150service_manage_result_cb (void *cls,
1078 enum GNUNET_ARM_RequestStatus rs, 1151 enum GNUNET_ARM_RequestStatus rs,
1079 const char *service, enum GNUNET_ARM_Result result) 1152 enum GNUNET_ARM_Result result)
1080{ 1153{
1081 struct ManageServiceContext *mctx = cls; 1154 struct ManageServiceContext *mctx = cls;
1082 char *emsg; 1155 char *emsg;
@@ -1086,8 +1159,10 @@ service_manage_result_cb (void *cls,
1086 return; 1159 return;
1087 if (GNUNET_ARM_REQUEST_SENT_OK != rs) 1160 if (GNUNET_ARM_REQUEST_SENT_OK != rs)
1088 { 1161 {
1089 GNUNET_asprintf (&emsg, "Error communicating with Peer %u's ARM: %s", 1162 GNUNET_asprintf (&emsg,
1090 mctx->peer->id, arm_req_string (rs)); 1163 "Error communicating with Peer %u's ARM: %s",
1164 mctx->peer->id,
1165 arm_req_string (rs));
1091 goto ret; 1166 goto ret;
1092 } 1167 }
1093 if (1 == mctx->start) 1168 if (1 == mctx->start)
@@ -1098,7 +1173,9 @@ service_manage_result_cb (void *cls,
1098 || (GNUNET_ARM_RESULT_IS_STOPPED_ALREADY == result)) ) 1173 || (GNUNET_ARM_RESULT_IS_STOPPED_ALREADY == result)) )
1099 { 1174 {
1100 /* stopping a service failed */ 1175 /* stopping a service failed */
1101 GNUNET_asprintf (&emsg, arm_ret_string (result), service); 1176 GNUNET_asprintf (&emsg,
1177 arm_ret_string (result),
1178 mctx->service);
1102 goto ret; 1179 goto ret;
1103 } 1180 }
1104 /* service stopped successfully */ 1181 /* service stopped successfully */
@@ -1110,7 +1187,9 @@ service_manage_result_cb (void *cls,
1110 || (GNUNET_ARM_RESULT_IS_STARTED_ALREADY == result)) ) 1187 || (GNUNET_ARM_RESULT_IS_STARTED_ALREADY == result)) )
1111 { 1188 {
1112 /* starting a service failed */ 1189 /* starting a service failed */
1113 GNUNET_asprintf (&emsg, arm_ret_string (result), service); 1190 GNUNET_asprintf (&emsg,
1191 arm_ret_string (result),
1192 mctx->service);
1114 goto ret; 1193 goto ret;
1115 } 1194 }
1116 /* service started successfully */ 1195 /* service started successfully */
@@ -1119,10 +1198,13 @@ service_manage_result_cb (void *cls,
1119 if (NULL != emsg) 1198 if (NULL != emsg)
1120 { 1199 {
1121 LOG_DEBUG ("%s\n", emsg); 1200 LOG_DEBUG ("%s\n", emsg);
1122 GST_send_operation_fail_msg (mctx->client, mctx->op_id, emsg); 1201 GST_send_operation_fail_msg (mctx->client,
1202 mctx->op_id,
1203 emsg);
1123 } 1204 }
1124 else 1205 else
1125 GST_send_operation_success_msg (mctx->client, mctx->op_id); 1206 GST_send_operation_success_msg (mctx->client,
1207 mctx->op_id);
1126 GNUNET_free_non_null (emsg); 1208 GNUNET_free_non_null (emsg);
1127 cleanup_mctx (mctx); 1209 cleanup_mctx (mctx);
1128} 1210}
@@ -1136,7 +1218,8 @@ service_manage_result_cb (void *cls,
1136 * @param message the actual message 1218 * @param message the actual message
1137 */ 1219 */
1138void 1220void
1139GST_handle_manage_peer_service (void *cls, struct GNUNET_SERVER_Client *client, 1221GST_handle_manage_peer_service (void *cls,
1222 struct GNUNET_SERVER_Client *client,
1140 const struct GNUNET_MessageHeader *message) 1223 const struct GNUNET_MessageHeader *message)
1141{ 1224{
1142 const struct GNUNET_TESTBED_ManagePeerServiceMessage *msg; 1225 const struct GNUNET_TESTBED_ManagePeerServiceMessage *msg;
@@ -1202,13 +1285,17 @@ GST_handle_manage_peer_service (void *cls, struct GNUNET_SERVER_Client *client,
1202 fopc->opc = 1285 fopc->opc =
1203 GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote. 1286 GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote.
1204 slave->controller, 1287 slave->controller,
1205 fopc->operation_id, &msg->header, 1288 fopc->operation_id,
1289 &msg->header,
1206 &GST_forwarded_operation_reply_relay, 1290 &GST_forwarded_operation_reply_relay,
1207 fopc); 1291 fopc);
1208 fopc->timeout_task = 1292 fopc->timeout_task =
1209 GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout, 1293 GNUNET_SCHEDULER_add_delayed (GST_timeout,
1294 &GST_forwarded_operation_timeout,
1295 fopc);
1296 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
1297 fopcq_tail,
1210 fopc); 1298 fopc);
1211 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc);
1212 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1299 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1213 return; 1300 return;
1214 } 1301 }
@@ -1242,17 +1329,19 @@ GST_handle_manage_peer_service (void *cls, struct GNUNET_SERVER_Client *client,
1242 GNUNET_SERVER_client_keep (client); 1329 GNUNET_SERVER_client_keep (client);
1243 mctx->client = client; 1330 mctx->client = client;
1244 mctx->start = msg->start; 1331 mctx->start = msg->start;
1245 GNUNET_CONTAINER_DLL_insert_tail (mctx_head, mctx_tail, mctx); 1332 mctx->service = GNUNET_strdup (service);
1333 GNUNET_CONTAINER_DLL_insert_tail (mctx_head,
1334 mctx_tail,
1335 mctx);
1246 if (1 == mctx->start) 1336 if (1 == mctx->start)
1247 GNUNET_ARM_request_service_start (mctx->ah, service, 1337 GNUNET_ARM_request_service_start (mctx->ah,
1338 service,
1248 GNUNET_OS_INHERIT_STD_ERR, 1339 GNUNET_OS_INHERIT_STD_ERR,
1249 GST_timeout, 1340 &service_manage_result_cb,
1250 service_manage_result_cb,
1251 mctx); 1341 mctx);
1252 else 1342 else
1253 GNUNET_ARM_request_service_stop (mctx->ah, service, 1343 GNUNET_ARM_request_service_stop (mctx->ah, service,
1254 GST_timeout, 1344 &service_manage_result_cb,
1255 service_manage_result_cb,
1256 mctx); 1345 mctx);
1257 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1346 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1258 return; 1347 return;
@@ -1334,28 +1423,33 @@ shutdown_peers_reply_cb (void *cls,
1334 if (0 == hc->nslaves) 1423 if (0 == hc->nslaves)
1335 { 1424 {
1336 if (GNUNET_YES == hc->timeout) 1425 if (GNUNET_YES == hc->timeout)
1337 GST_send_operation_fail_msg (fo_ctxt->client, fo_ctxt->operation_id, 1426 GST_send_operation_fail_msg (fo_ctxt->client,
1427 fo_ctxt->operation_id,
1338 "Timeout at a slave controller"); 1428 "Timeout at a slave controller");
1339 else 1429 else
1340 GST_send_operation_success_msg (fo_ctxt->client, fo_ctxt->operation_id); 1430 GST_send_operation_success_msg (fo_ctxt->client,
1431 fo_ctxt->operation_id);
1341 GNUNET_free (hc); 1432 GNUNET_free (hc);
1342 hc = NULL; 1433 hc = NULL;
1343 } 1434 }
1344 GNUNET_SERVER_client_drop (fo_ctxt->client); 1435 GNUNET_SERVER_client_drop (fo_ctxt->client);
1345 GNUNET_CONTAINER_DLL_remove (fopcq_head, fopcq_tail, fo_ctxt); 1436 GNUNET_CONTAINER_DLL_remove (fopcq_head,
1437 fopcq_tail,
1438 fo_ctxt);
1346 GNUNET_free (fo_ctxt); 1439 GNUNET_free (fo_ctxt);
1347} 1440}
1348 1441
1349 1442
1350/** 1443/**
1351 * Handler for GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS messages 1444 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS messages
1352 * 1445 *
1353 * @param cls NULL 1446 * @param cls NULL
1354 * @param client identification of the client 1447 * @param client identification of the client
1355 * @param message the actual message 1448 * @param message the actual message
1356 */ 1449 */
1357void 1450void
1358GST_handle_shutdown_peers (void *cls, struct GNUNET_SERVER_Client *client, 1451GST_handle_shutdown_peers (void *cls,
1452 struct GNUNET_SERVER_Client *client,
1359 const struct GNUNET_MessageHeader *message) 1453 const struct GNUNET_MessageHeader *message)
1360{ 1454{
1361 const struct GNUNET_TESTBED_ShutdownPeersMessage *msg; 1455 const struct GNUNET_TESTBED_ShutdownPeersMessage *msg;
@@ -1398,14 +1492,18 @@ GST_handle_shutdown_peers (void *cls, struct GNUNET_SERVER_Client *client,
1398 &msg->header, 1492 &msg->header,
1399 shutdown_peers_reply_cb, 1493 shutdown_peers_reply_cb,
1400 fo_ctxt); 1494 fo_ctxt);
1401 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fo_ctxt); 1495 GNUNET_CONTAINER_DLL_insert_tail (fopcq_head,
1496 fopcq_tail,
1497 fo_ctxt);
1402 } 1498 }
1403 LOG_DEBUG ("Shutting down peers\n"); 1499 LOG_DEBUG ("Shutting down peers\n");
1404 GST_destroy_peers (); 1500 GST_destroy_peers ();
1405 if (0 == hc->nslaves) 1501 if (0 == hc->nslaves)
1406 { 1502 {
1407 GST_send_operation_success_msg (client, op_id); 1503 GST_send_operation_success_msg (client,
1504 op_id);
1408 GNUNET_free (hc); 1505 GNUNET_free (hc);
1409 } 1506 }
1410 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1507 GNUNET_SERVER_receive_done (client,
1508 GNUNET_OK);
1411} 1509}
diff --git a/src/testbed/test_testbed_api.c b/src/testbed/test_testbed_api.c
index fdf9d80f9..83203e71e 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)
219{ 219{
220 FAIL_TEST (NULL != op_result, return); 220 FAIL_TEST (NULL != op_result, return);
221 FAIL_TEST (op_result == arm_handle, return); 221 FAIL_TEST (op_result == arm_handle, return);
222 GNUNET_ARM_disconnect_and_free (arm_handle); 222 GNUNET_ARM_disconnect (arm_handle);
223 arm_handle = NULL; 223 arm_handle = NULL;
224 FAIL_TEST (PEER_SERVICE_CONNECT == sub_test, return); 224 FAIL_TEST (PEER_SERVICE_CONNECT == sub_test, return);
225 FAIL_TEST (NULL != operation, return); 225 FAIL_TEST (NULL != operation, return);
@@ -451,11 +451,13 @@ run (void *cls, char *const *args, const char *cfgfile,
451 cfg = GNUNET_CONFIGURATION_dup (config); 451 cfg = GNUNET_CONFIGURATION_dup (config);
452 host = GNUNET_TESTBED_host_create (NULL, NULL, cfg, 0); 452 host = GNUNET_TESTBED_host_create (NULL, NULL, cfg, 0);
453 FAIL_TEST (NULL != host, return); 453 FAIL_TEST (NULL != host, return);
454 cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, status_cb, 454 cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host,
455 &status_cb,
455 NULL); 456 NULL);
456 abort_task = 457 abort_task =
457 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply 458 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
458 (GNUNET_TIME_UNIT_MINUTES, 5), &do_abort, 459 (GNUNET_TIME_UNIT_MINUTES, 5),
460 &do_abort,
459 NULL); 461 NULL);
460} 462}
461 463
diff --git a/src/testbed/test_testbed_logger_api.c b/src/testbed/test_testbed_logger_api.c
index f140dfbad..a25c0c5f0 100644
--- a/src/testbed/test_testbed_logger_api.c
+++ b/src/testbed/test_testbed_logger_api.c
@@ -17,13 +17,11 @@
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA. 18 Boston, MA 02110-1301, USA.
19 */ 19 */
20
21/** 20/**
22 * @file testbed/test_testbed_logger_api.c 21 * @file testbed/test_testbed_logger_api.c
23 * @brief testcases for the testbed logger api 22 * @brief testcases for the testbed logger api
24 * @author Sree Harsha Totakura 23 * @author Sree Harsha Totakura
25 */ 24 */
26
27#include "platform.h" 25#include "platform.h"
28#include "gnunet_util_lib.h" 26#include "gnunet_util_lib.h"
29#include "gnunet_testing_lib.h" 27#include "gnunet_testing_lib.h"
@@ -53,8 +51,8 @@ static char *search_dir;
53/** 51/**
54 * Abort task identifier 52 * Abort task identifier
55 */ 53 */
56static struct GNUNET_SCHEDULER_Task * abort_task; 54static struct GNUNET_SCHEDULER_Task *abort_task;
57static struct GNUNET_SCHEDULER_Task * write_task; 55static struct GNUNET_SCHEDULER_Task *write_task;
58 56
59static int result; 57static int result;
60 58
@@ -78,6 +76,7 @@ static int result;
78 } \ 76 } \
79 } while (0) 77 } while (0)
80 78
79
81/** 80/**
82 * Shutdown nicely 81 * Shutdown nicely
83 * 82 *
@@ -99,7 +98,8 @@ shutdown_now ()
99static void 98static void
100do_abort (void *cls) 99do_abort (void *cls)
101{ 100{
102 LOG (GNUNET_ERROR_TYPE_WARNING, "Aborting\n"); 101 LOG (GNUNET_ERROR_TYPE_WARNING,
102 "Aborting\n");
103 abort_task = NULL; 103 abort_task = NULL;
104 shutdown_now (); 104 shutdown_now ();
105} 105}
@@ -125,20 +125,34 @@ iterator_cb (void *cls,
125 size_t len; 125 size_t len;
126 uint64_t fs; 126 uint64_t fs;
127 127
128 LOG (GNUNET_ERROR_TYPE_DEBUG,
129 "Iterator sees file %s\n",
130 filename);
128 len = strlen (filename); 131 len = strlen (filename);
129 if (len < 5) /* log file: `pid'.dat */
130 return GNUNET_OK;
131
132 fn = filename + len; 132 fn = filename + len;
133 if (0 != strcasecmp (".dat", fn - 4)) 133 if (0 != strcasecmp (".dat", fn - 4))
134 return GNUNET_OK; 134 return GNUNET_OK;
135 if (GNUNET_OK != 135 if (GNUNET_OK !=
136 GNUNET_DISK_file_size (filename, &fs, 136 GNUNET_DISK_file_size (filename,
137 GNUNET_NO, GNUNET_YES)) 137 &fs,
138 GNUNET_NO,
139 GNUNET_YES))
140 {
141 LOG (GNUNET_ERROR_TYPE_DEBUG,
142 "Failed to obtain file size for file %s\n",
143 filename);
138 return GNUNET_SYSERR; 144 return GNUNET_SYSERR;
139 if ((BSIZE * 2) != fs) /* The file size should be equal to what we 145 }
140 have written */ 146 if ((BSIZE * 2) != fs)
147 {
148 LOG (GNUNET_ERROR_TYPE_DEBUG,
149 "Unexpected file size for file %s\n",
150 filename);
151 /* The file size should be equal to what we
152 have written */
141 return GNUNET_SYSERR; 153 return GNUNET_SYSERR;
154 }
155 result = GNUNET_OK;
142 return GNUNET_OK; 156 return GNUNET_OK;
143} 157}
144 158
@@ -151,11 +165,21 @@ iterator_cb (void *cls,
151 * @param size the amount of data sent 165 * @param size the amount of data sent
152 */ 166 */
153static void 167static void
154flush_comp (void *cls, size_t size) 168flush_comp (void *cls,
169 size_t size)
155{ 170{
156 FAIL_TEST (&write_task == cls, return); 171 LOG (GNUNET_ERROR_TYPE_DEBUG,
157 FAIL_TEST ((BSIZE * 2) == size, return); 172 "Flush running\n");
158 FAIL_TEST (GNUNET_OK == GNUNET_TESTING_peer_stop (peer), return); 173 FAIL_TEST (&write_task == cls,
174 return);
175 FAIL_TEST ((BSIZE * 2) == size,
176 return);
177 FAIL_TEST (GNUNET_OK ==
178 GNUNET_TESTING_peer_stop (peer),
179 return);
180 LOG (GNUNET_ERROR_TYPE_DEBUG,
181 "Peer stopped, scanning %s\n",
182 search_dir);
159 FAIL_TEST (GNUNET_SYSERR != 183 FAIL_TEST (GNUNET_SYSERR !=
160 GNUNET_DISK_directory_scan (search_dir, 184 GNUNET_DISK_directory_scan (search_dir,
161 &iterator_cb, 185 &iterator_cb,
@@ -172,17 +196,22 @@ do_write (void *cls)
172 char buf[BSIZE]; 196 char buf[BSIZE];
173 197
174 write_task = NULL; 198 write_task = NULL;
199 LOG (GNUNET_ERROR_TYPE_DEBUG,
200 "Write task running\n");
175 if (0 == i) 201 if (0 == i)
176 write_task = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS(1), 202 write_task = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS(1),
177 &do_write, 203 &do_write,
178 NULL); 204 NULL);
179 (void) memset (buf, i, BSIZE); 205 (void) memset (buf, i, BSIZE);
180 GNUNET_TESTBED_LOGGER_write (h, buf, BSIZE); 206 GNUNET_TESTBED_LOGGER_write (h,
207 buf,
208 BSIZE);
181 if (0 == i++) 209 if (0 == i++)
182 return; 210 return;
183 GNUNET_TESTBED_LOGGER_flush (h, 211 GNUNET_TESTBED_LOGGER_flush (h,
184 GNUNET_TIME_UNIT_FOREVER_REL, 212 GNUNET_TIME_UNIT_FOREVER_REL,
185 &flush_comp, &write_task); 213 &flush_comp,
214 &write_task);
186} 215}
187 216
188 217
@@ -199,13 +228,22 @@ test_main (void *cls,
199 const struct GNUNET_CONFIGURATION_Handle *cfg, 228 const struct GNUNET_CONFIGURATION_Handle *cfg,
200 struct GNUNET_TESTING_Peer *p) 229 struct GNUNET_TESTING_Peer *p)
201{ 230{
202 FAIL_TEST (NULL != (h = GNUNET_TESTBED_LOGGER_connect (cfg)), return); 231 LOG (GNUNET_ERROR_TYPE_DEBUG,
203 FAIL_TEST (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename 232 "Connecting to logger\n");
204 (cfg, "testbed-logger", "dir", &search_dir), return); 233 FAIL_TEST (NULL != (h = GNUNET_TESTBED_LOGGER_connect (cfg)),
234 return);
235 FAIL_TEST (GNUNET_OK ==
236 GNUNET_CONFIGURATION_get_value_filename (cfg,
237 "testbed-logger",
238 "dir",
239 &search_dir),
240 return);
205 peer = p; 241 peer = p;
206 write_task = GNUNET_SCHEDULER_add_now (&do_write, NULL); 242 write_task = GNUNET_SCHEDULER_add_now (&do_write,
243 NULL);
207 abort_task = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (10), 244 abort_task = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (10),
208 &do_abort, NULL); 245 &do_abort,
246 NULL);
209} 247}
210 248
211 249
@@ -218,6 +256,9 @@ main (int argc, char **argv)
218 int ret; 256 int ret;
219 257
220 result = GNUNET_SYSERR; 258 result = GNUNET_SYSERR;
259 GNUNET_log_setup ("test-testbed-logger-api",
260 "WARNING",
261 NULL);
221 ret = GNUNET_TESTING_service_run ("test-testbed-logger", 262 ret = GNUNET_TESTING_service_run ("test-testbed-logger",
222 "testbed-logger", 263 "testbed-logger",
223 "test_testbed_logger_api.conf", 264 "test_testbed_logger_api.conf",
diff --git a/src/testing/testing.c b/src/testing/testing.c
index 32cd09b84..13ebabd1d 100644
--- a/src/testing/testing.c
+++ b/src/testing/testing.c
@@ -1355,65 +1355,6 @@ GNUNET_TESTING_peer_start (struct GNUNET_TESTING_Peer *peer)
1355 1355
1356 1356
1357/** 1357/**
1358 * Start a service at a peer using its ARM service
1359 *
1360 * @param peer the peer whose service has to be started
1361 * @param service_name name of the service to start
1362 * @param timeout how long should the ARM API try to send the request to start
1363 * the service
1364 * @param cont the callback to call with result and status from ARM API
1365 * @param cont_cls the closure for the above callback
1366 * @return #GNUNET_OK upon successfully queuing the service start request;
1367 * #GNUNET_SYSERR upon error
1368 */
1369int
1370GNUNET_TESTING_peer_service_start (struct GNUNET_TESTING_Peer *peer,
1371 const char *service_name,
1372 struct GNUNET_TIME_Relative timeout,
1373 GNUNET_ARM_ResultCallback cont,
1374 void *cont_cls)
1375{
1376 if (NULL == peer->ah)
1377 return GNUNET_SYSERR;
1378 GNUNET_ARM_request_service_start (peer->ah,
1379 service_name,
1380 GNUNET_OS_INHERIT_STD_ALL,
1381 timeout,
1382 cont, cont_cls);
1383 return GNUNET_OK;
1384}
1385
1386
1387/**
1388 * Stop a service at a peer using its ARM service
1389 *
1390 * @param peer the peer whose service has to be stopped
1391 * @param service_name name of the service to stop
1392 * @param timeout how long should the ARM API try to send the request to stop
1393 * the service
1394 * @param cont the callback to call with result and status from ARM API
1395 * @param cont_cls the closure for the above callback
1396 * @return #GNUNET_OK upon successfully queuing the service stop request;
1397 * #GNUNET_SYSERR upon error
1398 */
1399int
1400GNUNET_TESTING_peer_service_stop (struct GNUNET_TESTING_Peer *peer,
1401 const char *service_name,
1402 struct GNUNET_TIME_Relative timeout,
1403 GNUNET_ARM_ResultCallback cont,
1404 void *cont_cls)
1405{
1406 if (NULL == peer->ah)
1407 return GNUNET_SYSERR;
1408 GNUNET_ARM_request_service_stop (peer->ah,
1409 service_name,
1410 timeout,
1411 cont, cont_cls);
1412 return GNUNET_OK;
1413}
1414
1415
1416/**
1417 * Sends SIGTERM to the peer's main process 1358 * Sends SIGTERM to the peer's main process
1418 * 1359 *
1419 * @param peer the handle to the peer 1360 * @param peer the handle to the peer
@@ -1510,7 +1451,7 @@ disconn_status (void *cls,
1510 return; 1451 return;
1511 } 1452 }
1512 GNUNET_break (GNUNET_OK == GNUNET_TESTING_peer_wait (peer)); 1453 GNUNET_break (GNUNET_OK == GNUNET_TESTING_peer_wait (peer));
1513 GNUNET_ARM_disconnect_and_free (peer->ah); 1454 GNUNET_ARM_disconnect (peer->ah);
1514 peer->ah = NULL; 1455 peer->ah = NULL;
1515 peer->cb (peer->cb_cls, peer, GNUNET_YES); 1456 peer->cb (peer->cb_cls, peer, GNUNET_YES);
1516} 1457}
@@ -1556,7 +1497,7 @@ void
1556GNUNET_TESTING_peer_stop_async_cancel (struct GNUNET_TESTING_Peer *peer) 1497GNUNET_TESTING_peer_stop_async_cancel (struct GNUNET_TESTING_Peer *peer)
1557{ 1498{
1558 GNUNET_assert (NULL != peer->ah); 1499 GNUNET_assert (NULL != peer->ah);
1559 GNUNET_ARM_disconnect_and_free (peer->ah); 1500 GNUNET_ARM_disconnect (peer->ah);
1560 peer->ah = NULL; 1501 peer->ah = NULL;
1561} 1502}
1562 1503
@@ -1576,9 +1517,9 @@ GNUNET_TESTING_peer_destroy (struct GNUNET_TESTING_Peer *peer)
1576 if (NULL != peer->main_process) 1517 if (NULL != peer->main_process)
1577 GNUNET_TESTING_peer_stop (peer); 1518 GNUNET_TESTING_peer_stop (peer);
1578 if (NULL != peer->ah) 1519 if (NULL != peer->ah)
1579 GNUNET_ARM_disconnect_and_free (peer->ah); 1520 GNUNET_ARM_disconnect (peer->ah);
1580 if (NULL != peer->mh) 1521 if (NULL != peer->mh)
1581 GNUNET_ARM_monitor_disconnect_and_free (peer->mh); 1522 GNUNET_ARM_monitor_stop (peer->mh);
1582 GNUNET_free (peer->cfgfile); 1523 GNUNET_free (peer->cfgfile);
1583 if (NULL != peer->cfg) 1524 if (NULL != peer->cfg)
1584 GNUNET_CONFIGURATION_destroy (peer->cfg); 1525 GNUNET_CONFIGURATION_destroy (peer->cfg);