diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-06-23 14:22:34 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-06-23 14:22:34 +0000 |
commit | 5742938289524f4c5fba7883742e4dd69cccf11d (patch) | |
tree | e16fea8b9d778f9825f897237b0c1880305776a0 /src/arm | |
parent | f3edb5a8d6ba6f43f5df18f2e98bc1dae90c9d7a (diff) | |
download | gnunet-5742938289524f4c5fba7883742e4dd69cccf11d.tar.gz gnunet-5742938289524f4c5fba7883742e4dd69cccf11d.zip |
refactoring ARM api to use new MQ
Diffstat (limited to 'src/arm')
-rw-r--r-- | src/arm/arm_api.c | 1219 | ||||
-rw-r--r-- | src/arm/arm_monitor_api.c | 13 | ||||
-rw-r--r-- | src/arm/gnunet-arm.c | 159 | ||||
-rw-r--r-- | src/arm/test_arm_api.c | 109 | ||||
-rw-r--r-- | src/arm/test_exponential_backoff.c | 70 | ||||
-rw-r--r-- | src/arm/test_gnunet_service_arm.c | 36 |
6 files changed, 734 insertions, 872 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 | */ |
38 | struct GNUNET_ARM_Handle | 40 | struct 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 | */ |
124 | struct ARMControlMessage | 97 | struct 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 | */ | ||
200 | static void | ||
201 | trigger_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) | |||
228 | static void | 194 | static void |
229 | reconnect_arm_later (struct GNUNET_ARM_Handle *h) | 195 | reconnect_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 | */ |
267 | static struct ARMControlMessage * | 238 | static struct GNUNET_ARM_Operation * |
268 | find_cm_by_id (struct GNUNET_ARM_Handle *h, | 239 | find_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 | */ | ||
286 | static void | ||
287 | arm_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 | */ |
323 | static void | 257 | static void |
324 | client_notify_handler (void *cls, | 258 | handle_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 | */ |
500 | static size_t | 319 | static int |
501 | transmit_arm_message (void *cls, | 320 | check_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 | */ |
590 | static void | 350 | static void |
591 | trigger_next_request (struct GNUNET_ARM_Handle *h, | 351 | handle_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 | */ | ||
401 | static void | ||
402 | handle_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 | */ | ||
427 | static void | ||
428 | mq_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, | |||
633 | static int | 453 | static int |
634 | reconnect_arm (struct GNUNET_ARM_Handle *h) | 454 | reconnect_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 | */ |
667 | struct GNUNET_ARM_Handle * | 512 | struct GNUNET_ARM_Handle * |
668 | GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | 513 | GNUNET_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 | */ |
694 | void | 537 | void |
695 | GNUNET_ARM_disconnect_and_free (struct GNUNET_ARM_Handle *h) | 538 | GNUNET_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 | */ | ||
751 | static void | ||
752 | control_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 | */ |
794 | static void | 587 | static enum GNUNET_ARM_Result |
795 | arm_service_report (void *cls, | 588 | start_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 | */ | ||
709 | void | ||
710 | GNUNET_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 | */ |
967 | static void | 736 | static struct GNUNET_ARM_Operation * |
968 | change_service (struct GNUNET_ARM_Handle *h, | 737 | change_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 | */ | ||
784 | static void | ||
785 | notify_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 | */ | ||
811 | static void | ||
812 | notify_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 | */ |
1029 | void | 841 | struct GNUNET_ARM_Operation * |
1030 | GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h, | 842 | GNUNET_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 (¬ify_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 (¬ify_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 | */ |
1133 | void | 923 | struct GNUNET_ARM_Operation * |
1134 | GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h, | 924 | GNUNET_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 | */ |
1162 | void | 958 | struct GNUNET_ARM_Operation * |
1163 | GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h, | 959 | GNUNET_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 | */ |
243 | struct GNUNET_ARM_MonitorHandle * | 244 | struct GNUNET_ARM_MonitorHandle * |
244 | GNUNET_ARM_monitor (const struct GNUNET_CONFIGURATION_Handle *cfg, | 245 | GNUNET_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 | */ |
268 | void | 269 | void |
269 | GNUNET_ARM_monitor_disconnect_and_free (struct GNUNET_ARM_MonitorHandle *h) | 270 | GNUNET_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 | */ |
56 | static int end; | 34 | static 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 | */ |
136 | static struct GNUNET_TIME_Relative timeout; | 115 | static struct GNUNET_TIME_Relative timeout; |
137 | 116 | ||
@@ -150,6 +129,10 @@ static unsigned int no_stderr; | |||
150 | */ | 129 | */ |
151 | static struct GNUNET_SCHEDULER_Task *al_task; | 130 | static struct GNUNET_SCHEDULER_Task *al_task; |
152 | 131 | ||
132 | /** | ||
133 | * Current operation. | ||
134 | */ | ||
135 | static 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 | */ |
295 | static void | 281 | static void |
296 | conn_status (void *cls, | 282 | conn_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 | */ |
325 | static void | 310 | static void |
326 | start_callback (void *cls, | 311 | start_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 | */ |
369 | static void | 353 | static void |
370 | stop_callback (void *cls, | 354 | stop_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 | */ |
423 | static void | 406 | static void |
424 | init_callback (void *cls, | 407 | init_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 | */ |
472 | static void | 456 | static void |
473 | term_callback (void *cls, | 457 | term_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 | ||
37 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 33 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
38 | 34 | ||
39 | static struct GNUNET_ARM_Handle *arm; | 35 | static struct GNUNET_ARM_Handle *arm; |
40 | 36 | ||
37 | static struct GNUNET_ARM_Operation *op; | ||
38 | |||
41 | static int ok = 1; | 39 | static int ok = 1; |
42 | 40 | ||
43 | static int phase = 0; | 41 | static int phase = 0; |
44 | 42 | ||
43 | |||
45 | static void | 44 | static void |
46 | arm_stop_cb (void *cls, | 45 | arm_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 | ||
61 | static void | 62 | static void |
62 | resolver_stop_cb (void *cls, | 63 | resolver_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 | ||
83 | static void | 85 | static void |
84 | dns_notify (void *cls, const struct sockaddr *addr, socklen_t addrlen) | 86 | dns_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) | |||
106 | static void | 114 | static void |
107 | resolver_start_cb (void *cls, | 115 | resolver_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); | |
124 | static void | ||
125 | trigger_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, | |||
165 | static void | 174 | static void |
166 | arm_start_cb (void *cls, | 175 | arm_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 | ||
184 | static void | 194 | static void |
185 | task (void *cls, char *const *args, const char *cfgfile, | 195 | do_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 | |||
210 | static void | ||
211 | task (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 | ||
73 | typedef void (*GNUNET_CLIENT_ShutdownTask) (void *cls, int reason); | 73 | typedef 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 | */ |
120 | static void | 122 | static void |
121 | service_shutdown_handler (void *cls, const struct GNUNET_MessageHeader *msg) | 123 | service_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 | */ |
208 | static void | 212 | static void |
209 | do_nothing_service_shutdown (struct GNUNET_CLIENT_Connection *sock, | 213 | do_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) | |||
284 | static void | 292 | static void |
285 | trigger_disconnect (void *cls) | 293 | trigger_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 | ||
292 | static void | 300 | static void |
293 | arm_stop_cb (void *cls, | 301 | arm_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 | ||
305 | static void | 312 | static void |
306 | srv_status (void *cls, const char *service, enum GNUNET_ARM_ServiceStatus status) | 313 | srv_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 | ||
346 | static void | 362 | static void |
347 | arm_start_cb (void *cls, enum GNUNET_ARM_RequestStatus status, const char *servicename, enum GNUNET_ARM_Result result) | 363 | arm_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 | ||
357 | static void | 375 | static void |
358 | task (void *cls, char *const *args, const char *cfgfile, | 376 | task (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; | |||
51 | static void | 51 | static void |
52 | trigger_disconnect (void *cls) | 52 | trigger_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) | |||
59 | static void | 59 | static void |
60 | arm_stop_cb (void *cls, | 60 | arm_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 | ||
108 | static void | 107 | static void |
109 | hostname_resolve_cb (void *cls, | 108 | hostname_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, | |||
141 | static void | 139 | static void |
142 | arm_start_cb (void *cls, | 140 | arm_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 | ||