diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-05-21 13:41:41 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-05-21 13:41:41 +0000 |
commit | 5eb55630a4f8bb8d0a7438dd4e75f15aeab2b876 (patch) | |
tree | 3b37a60ad94dc612e01b5040aadfd11d402bd804 /src/arm/arm_api.c | |
parent | ac8e1d62caf10cdc6f481f54f9eb92a161c02616 (diff) | |
download | gnunet-5eb55630a4f8bb8d0a7438dd4e75f15aeab2b876.tar.gz gnunet-5eb55630a4f8bb8d0a7438dd4e75f15aeab2b876.zip |
-minor code cleanup
Diffstat (limited to 'src/arm/arm_api.c')
-rw-r--r-- | src/arm/arm_api.c | 351 |
1 files changed, 188 insertions, 163 deletions
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c index 3514a8f28..eb9194eec 100644 --- a/src/arm/arm_api.c +++ b/src/arm/arm_api.c | |||
@@ -21,7 +21,8 @@ | |||
21 | /** | 21 | /** |
22 | * @file arm/arm_api.c | 22 | * @file arm/arm_api.c |
23 | * @brief API for accessing the ARM service | 23 | * @brief API for accessing 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" |
@@ -72,24 +73,24 @@ struct GNUNET_ARM_Handle | |||
72 | struct ARMControlMessage *control_sent_tail; | 73 | struct ARMControlMessage *control_sent_tail; |
73 | 74 | ||
74 | /** | 75 | /** |
75 | * ID of the reconnect task (if any). | 76 | * Callback to invoke on connection/disconnection. |
76 | */ | 77 | */ |
77 | GNUNET_SCHEDULER_TaskIdentifier reconnect_task; | 78 | GNUNET_ARM_ConnectionStatusCallback conn_status; |
78 | 79 | ||
79 | /** | 80 | /** |
80 | * Current delay we use for re-trying to connect to core. | 81 | * Closure for conn_status. |
81 | */ | 82 | */ |
82 | struct GNUNET_TIME_Relative retry_backoff; | 83 | void *conn_status_cls; |
83 | 84 | ||
84 | /** | 85 | /** |
85 | * Callback to invoke on connection/disconnection. | 86 | * ID of the reconnect task (if any). |
86 | */ | 87 | */ |
87 | GNUNET_ARM_ConnectionStatusCallback conn_status; | 88 | GNUNET_SCHEDULER_TaskIdentifier reconnect_task; |
88 | 89 | ||
89 | /** | 90 | /** |
90 | * Closure for conn_status. | 91 | * Current delay we use for re-trying to connect to core. |
91 | */ | 92 | */ |
92 | void *conn_status_cls; | 93 | struct GNUNET_TIME_Relative retry_backoff; |
93 | 94 | ||
94 | /** | 95 | /** |
95 | * Counter for request identifiers | 96 | * Counter for request identifiers |
@@ -157,14 +158,14 @@ struct ARMControlMessage | |||
157 | struct GNUNET_TIME_Absolute timeout; | 158 | struct GNUNET_TIME_Absolute timeout; |
158 | 159 | ||
159 | /** | 160 | /** |
160 | * Flags for passing std descriptors to ARM (when starting ARM). | 161 | * Task to run when request times out. |
161 | */ | 162 | */ |
162 | enum GNUNET_OS_InheritStdioFlags std_inheritance; | 163 | GNUNET_SCHEDULER_TaskIdentifier timeout_task_id; |
163 | 164 | ||
164 | /** | 165 | /** |
165 | * Task to run when request times out. | 166 | * Flags for passing std descriptors to ARM (when starting ARM). |
166 | */ | 167 | */ |
167 | GNUNET_SCHEDULER_TaskIdentifier timeout_task_id; | 168 | enum GNUNET_OS_InheritStdioFlags std_inheritance; |
168 | 169 | ||
169 | /** | 170 | /** |
170 | * Type of the request expressed as a message type (start, stop or list). | 171 | * Type of the request expressed as a message type (start, stop or list). |
@@ -172,12 +173,24 @@ struct ARMControlMessage | |||
172 | uint16_t type; | 173 | uint16_t type; |
173 | }; | 174 | }; |
174 | 175 | ||
175 | static void | ||
176 | client_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg); | ||
177 | 176 | ||
177 | /** | ||
178 | * Connect to arm. | ||
179 | * | ||
180 | * @param h arm handle | ||
181 | * @return GNUNET_OK on success, GNUNET_SYSERR on failure | ||
182 | */ | ||
178 | static int | 183 | static int |
179 | reconnect_arm (struct GNUNET_ARM_Handle *h); | 184 | reconnect_arm (struct GNUNET_ARM_Handle *h); |
180 | 185 | ||
186 | |||
187 | /** | ||
188 | * Check the list of pending requests, send the next | ||
189 | * one to the arm. | ||
190 | * | ||
191 | * @param h arm handle | ||
192 | * @param ignore_currently_down transmit message even if not initialized? | ||
193 | */ | ||
181 | static void | 194 | static void |
182 | trigger_next_request (struct GNUNET_ARM_Handle *h, int ignore_currently_down); | 195 | trigger_next_request (struct GNUNET_ARM_Handle *h, int ignore_currently_down); |
183 | 196 | ||
@@ -233,6 +246,160 @@ reconnect_arm_later (struct GNUNET_ARM_Handle *h) | |||
233 | h->conn_status (h->conn_status_cls, GNUNET_NO); | 246 | h->conn_status (h->conn_status_cls, GNUNET_NO); |
234 | } | 247 | } |
235 | 248 | ||
249 | |||
250 | /** | ||
251 | * Find a control message by its unique ID. | ||
252 | * | ||
253 | * @param h ARM handle | ||
254 | * @param id unique message ID to use for the lookup | ||
255 | * @return NULL if not found | ||
256 | */ | ||
257 | static struct ARMControlMessage * | ||
258 | find_cm_by_id (struct GNUNET_ARM_Handle *h, uint64_t id) | ||
259 | { | ||
260 | struct ARMControlMessage *result; | ||
261 | for (result = h->control_sent_head; result; result = result->next) | ||
262 | if (id == result->msg->request_id) | ||
263 | return result; | ||
264 | return NULL; | ||
265 | } | ||
266 | |||
267 | |||
268 | /** | ||
269 | * Handler for ARM replies. | ||
270 | * | ||
271 | * @param cls our "struct GNUNET_ARM_Handle" | ||
272 | * @param msg the message received from the arm service | ||
273 | */ | ||
274 | static void | ||
275 | client_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) | ||
276 | { | ||
277 | struct GNUNET_ARM_Handle *h = cls; | ||
278 | const struct GNUNET_ARM_Message *arm_msg; | ||
279 | const struct GNUNET_ARM_ResultMessage *res; | ||
280 | const struct GNUNET_ARM_ListResultMessage *lres; | ||
281 | struct ARMControlMessage *cm; | ||
282 | const char **list; | ||
283 | const char *pos; | ||
284 | uint64_t id; | ||
285 | enum GNUNET_ARM_Result result; | ||
286 | uint16_t size_check; | ||
287 | uint16_t rcount; | ||
288 | uint16_t msize; | ||
289 | unsigned char fail; | ||
290 | |||
291 | list = NULL; | ||
292 | if (NULL == msg) | ||
293 | { | ||
294 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
295 | _("Client was disconnected from arm service, trying to reconnect.\n")); | ||
296 | reconnect_arm_later (h); | ||
297 | return; | ||
298 | } | ||
299 | msize = ntohs (msg->size); | ||
300 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
301 | "Processing message of type %u and size %u from arm service\n", | ||
302 | ntohs (msg->type), msize); | ||
303 | if (msize < sizeof (struct GNUNET_ARM_Message)) | ||
304 | { | ||
305 | GNUNET_break (0); | ||
306 | reconnect_arm_later (h); | ||
307 | return; | ||
308 | } | ||
309 | arm_msg = (const struct GNUNET_ARM_Message *) msg; | ||
310 | id = GNUNET_ntohll (arm_msg->request_id); | ||
311 | cm = find_cm_by_id (h, id); | ||
312 | if (NULL == cm) | ||
313 | { | ||
314 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Message with unknown id %llu\n", id); | ||
315 | return; | ||
316 | } | ||
317 | fail = GNUNET_NO; | ||
318 | switch (ntohs (msg->type)) | ||
319 | { | ||
320 | case GNUNET_MESSAGE_TYPE_ARM_RESULT: | ||
321 | if (msize < sizeof (struct GNUNET_ARM_ResultMessage)) | ||
322 | { | ||
323 | GNUNET_assert (0); | ||
324 | fail = GNUNET_YES; | ||
325 | } | ||
326 | break; | ||
327 | case GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT: | ||
328 | if (msize < sizeof (struct GNUNET_ARM_ListResultMessage)) | ||
329 | { | ||
330 | GNUNET_break (0); | ||
331 | fail = GNUNET_YES; | ||
332 | break; | ||
333 | } | ||
334 | size_check = 0; | ||
335 | lres = (const struct GNUNET_ARM_ListResultMessage *) msg; | ||
336 | rcount = ntohs (lres->count); | ||
337 | { | ||
338 | unsigned int i; | ||
339 | |||
340 | list = GNUNET_malloc (sizeof (const char *) * rcount); | ||
341 | pos = (const char *)&lres[1]; | ||
342 | for (i = 0; i < rcount; i++) | ||
343 | { | ||
344 | const char *end = memchr (pos, 0, msize - size_check); | ||
345 | if (NULL == end) | ||
346 | { | ||
347 | GNUNET_break (0); | ||
348 | fail = GNUNET_YES; | ||
349 | break; | ||
350 | } | ||
351 | list[i] = pos; | ||
352 | size_check += (end - pos) + 1; | ||
353 | pos = end + 1; | ||
354 | } | ||
355 | if (GNUNET_YES == fail) | ||
356 | { | ||
357 | GNUNET_free (list); | ||
358 | list = NULL; | ||
359 | } | ||
360 | } | ||
361 | break; | ||
362 | default: | ||
363 | fail = GNUNET_YES; | ||
364 | break; | ||
365 | } | ||
366 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != cm->timeout_task_id); | ||
367 | GNUNET_SCHEDULER_cancel (cm->timeout_task_id); | ||
368 | GNUNET_CONTAINER_DLL_remove (h->control_sent_head, | ||
369 | h->control_sent_tail, cm); | ||
370 | if (GNUNET_YES == fail) | ||
371 | { | ||
372 | reconnect_arm_later (h); | ||
373 | GNUNET_free (cm->msg); | ||
374 | GNUNET_free (cm); | ||
375 | return; | ||
376 | } | ||
377 | GNUNET_CLIENT_receive (h->client, &client_notify_handler, h, | ||
378 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
379 | switch (ntohs (msg->type)) | ||
380 | { | ||
381 | case GNUNET_MESSAGE_TYPE_ARM_RESULT: | ||
382 | res = (const struct GNUNET_ARM_ResultMessage *) msg; | ||
383 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
384 | "Received response from ARM for service `%s': %u\n", | ||
385 | (const char *) &cm->msg[1], ntohs (msg->type)); | ||
386 | result = (enum GNUNET_ARM_Result) ntohl (res->result); | ||
387 | if (NULL != cm->result_cont) | ||
388 | cm->result_cont (cm->cont_cls, GNUNET_ARM_REQUEST_SENT_OK, | ||
389 | (const char *) &cm->msg[1], result); | ||
390 | break; | ||
391 | case GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT: | ||
392 | if (NULL != cm->list_cont) | ||
393 | cm->list_cont (cm->cont_cls, GNUNET_ARM_REQUEST_SENT_OK, rcount, | ||
394 | list); | ||
395 | GNUNET_free (list); | ||
396 | break; | ||
397 | } | ||
398 | GNUNET_free (cm->msg); | ||
399 | GNUNET_free (cm); | ||
400 | } | ||
401 | |||
402 | |||
236 | /** | 403 | /** |
237 | * Transmit the next message to the arm service. | 404 | * Transmit the next message to the arm service. |
238 | * | 405 | * |
@@ -361,6 +528,7 @@ trigger_next_request (struct GNUNET_ARM_Handle *h, int ignore_currently_down) | |||
361 | * Connect to arm. | 528 | * Connect to arm. |
362 | * | 529 | * |
363 | * @param h arm handle | 530 | * @param h arm handle |
531 | * @return GNUNET_OK on success, GNUNET_SYSERR on failure | ||
364 | */ | 532 | */ |
365 | static int | 533 | static int |
366 | reconnect_arm (struct GNUNET_ARM_Handle *h) | 534 | reconnect_arm (struct GNUNET_ARM_Handle *h) |
@@ -700,9 +868,11 @@ change_service (struct GNUNET_ARM_Handle *h, const char *service_name, | |||
700 | */ | 868 | */ |
701 | void | 869 | void |
702 | GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h, | 870 | GNUNET_ARM_request_service_start (struct GNUNET_ARM_Handle *h, |
703 | const char *service_name, enum GNUNET_OS_InheritStdioFlags std_inheritance, | 871 | const char *service_name, |
704 | struct GNUNET_TIME_Relative timeout, GNUNET_ARM_ResultCallback cont, | 872 | enum GNUNET_OS_InheritStdioFlags std_inheritance, |
705 | void *cont_cls) | 873 | struct GNUNET_TIME_Relative timeout, |
874 | GNUNET_ARM_ResultCallback cont, | ||
875 | void *cont_cls) | ||
706 | { | 876 | { |
707 | struct ARMControlMessage *cm; | 877 | struct ARMControlMessage *cm; |
708 | size_t slen; | 878 | size_t slen; |
@@ -839,149 +1009,4 @@ GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h, | |||
839 | } | 1009 | } |
840 | 1010 | ||
841 | 1011 | ||
842 | static struct ARMControlMessage * | ||
843 | find_cm_by_id (struct GNUNET_ARM_Handle *h, uint64_t id) | ||
844 | { | ||
845 | struct ARMControlMessage *result; | ||
846 | for (result = h->control_sent_head; result; result = result->next) | ||
847 | if (id == result->msg->request_id) | ||
848 | return result; | ||
849 | return NULL; | ||
850 | } | ||
851 | |||
852 | |||
853 | /** | ||
854 | * Handler for ARM replies. | ||
855 | * | ||
856 | * @param cls our "struct GNUNET_ARM_Handle" | ||
857 | * @param msg the message received from the arm service | ||
858 | */ | ||
859 | static void | ||
860 | client_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) | ||
861 | { | ||
862 | struct GNUNET_ARM_Handle *h = cls; | ||
863 | const struct GNUNET_ARM_Message *arm_msg; | ||
864 | const struct GNUNET_ARM_ResultMessage *res; | ||
865 | const struct GNUNET_ARM_ListResultMessage *lres; | ||
866 | struct ARMControlMessage *cm; | ||
867 | const char **list; | ||
868 | const char *pos; | ||
869 | uint64_t id; | ||
870 | enum GNUNET_ARM_Result result; | ||
871 | uint16_t size_check; | ||
872 | uint16_t rcount; | ||
873 | uint16_t msize; | ||
874 | unsigned char fail; | ||
875 | |||
876 | list = NULL; | ||
877 | if (NULL == msg) | ||
878 | { | ||
879 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
880 | _("Client was disconnected from arm service, trying to reconnect.\n")); | ||
881 | reconnect_arm_later (h); | ||
882 | return; | ||
883 | } | ||
884 | msize = ntohs (msg->size); | ||
885 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
886 | "Processing message of type %u and size %u from arm service\n", | ||
887 | ntohs (msg->type), msize); | ||
888 | if (msize < sizeof (struct GNUNET_ARM_Message)) | ||
889 | { | ||
890 | GNUNET_break (0); | ||
891 | reconnect_arm_later (h); | ||
892 | return; | ||
893 | } | ||
894 | arm_msg = (const struct GNUNET_ARM_Message *) msg; | ||
895 | id = GNUNET_ntohll (arm_msg->request_id); | ||
896 | cm = find_cm_by_id (h, id); | ||
897 | if (NULL == cm) | ||
898 | { | ||
899 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Message with unknown id %llu\n", id); | ||
900 | return; | ||
901 | } | ||
902 | fail = GNUNET_NO; | ||
903 | switch (ntohs (msg->type)) | ||
904 | { | ||
905 | case GNUNET_MESSAGE_TYPE_ARM_RESULT: | ||
906 | if (msize < sizeof (struct GNUNET_ARM_ResultMessage)) | ||
907 | { | ||
908 | GNUNET_assert (0); | ||
909 | fail = GNUNET_YES; | ||
910 | } | ||
911 | break; | ||
912 | case GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT: | ||
913 | if (msize < sizeof (struct GNUNET_ARM_ListResultMessage)) | ||
914 | { | ||
915 | GNUNET_break (0); | ||
916 | fail = GNUNET_YES; | ||
917 | break; | ||
918 | } | ||
919 | size_check = 0; | ||
920 | lres = (const struct GNUNET_ARM_ListResultMessage *) msg; | ||
921 | rcount = ntohs (lres->count); | ||
922 | { | ||
923 | unsigned int i; | ||
924 | |||
925 | list = GNUNET_malloc (sizeof (const char *) * rcount); | ||
926 | pos = (const char *)&lres[1]; | ||
927 | for (i = 0; i < rcount; i++) | ||
928 | { | ||
929 | const char *end = memchr (pos, 0, msize - size_check); | ||
930 | if (NULL == end) | ||
931 | { | ||
932 | GNUNET_break (0); | ||
933 | fail = GNUNET_YES; | ||
934 | break; | ||
935 | } | ||
936 | list[i] = pos; | ||
937 | size_check += (end - pos) + 1; | ||
938 | pos = end + 1; | ||
939 | } | ||
940 | if (GNUNET_YES == fail) | ||
941 | { | ||
942 | GNUNET_free (list); | ||
943 | list = NULL; | ||
944 | } | ||
945 | } | ||
946 | break; | ||
947 | default: | ||
948 | fail = GNUNET_YES; | ||
949 | break; | ||
950 | } | ||
951 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != cm->timeout_task_id); | ||
952 | GNUNET_SCHEDULER_cancel (cm->timeout_task_id); | ||
953 | GNUNET_CONTAINER_DLL_remove (h->control_sent_head, | ||
954 | h->control_sent_tail, cm); | ||
955 | if (GNUNET_YES == fail) | ||
956 | { | ||
957 | reconnect_arm_later (h); | ||
958 | GNUNET_free (cm->msg); | ||
959 | GNUNET_free (cm); | ||
960 | return; | ||
961 | } | ||
962 | GNUNET_CLIENT_receive (h->client, &client_notify_handler, h, | ||
963 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
964 | switch (ntohs (msg->type)) | ||
965 | { | ||
966 | case GNUNET_MESSAGE_TYPE_ARM_RESULT: | ||
967 | res = (const struct GNUNET_ARM_ResultMessage *) msg; | ||
968 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
969 | "Received response from ARM for service `%s': %u\n", | ||
970 | (const char *) &cm->msg[1], ntohs (msg->type)); | ||
971 | result = (enum GNUNET_ARM_Result) ntohl (res->result); | ||
972 | if (NULL != cm->result_cont) | ||
973 | cm->result_cont (cm->cont_cls, GNUNET_ARM_REQUEST_SENT_OK, | ||
974 | (const char *) &cm->msg[1], result); | ||
975 | break; | ||
976 | case GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT: | ||
977 | if (NULL != cm->list_cont) | ||
978 | cm->list_cont (cm->cont_cls, GNUNET_ARM_REQUEST_SENT_OK, rcount, | ||
979 | list); | ||
980 | GNUNET_free (list); | ||
981 | break; | ||
982 | } | ||
983 | GNUNET_free (cm->msg); | ||
984 | GNUNET_free (cm); | ||
985 | } | ||
986 | |||
987 | /* end of arm_api.c */ | 1012 | /* end of arm_api.c */ |