aboutsummaryrefslogtreecommitdiff
path: root/src/arm
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2013-04-01 16:38:03 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2013-04-01 16:38:03 +0000
commit122dbcd5b6ac9e0b855cb01f873b62ad35ca39ae (patch)
treef91ef6c88f0215875662cf477b148b2a1da36e35 /src/arm
parente4470b481f70375bdc0f7fe2fdce7e7c831b496b (diff)
downloadgnunet-122dbcd5b6ac9e0b855cb01f873b62ad35ca39ae.tar.gz
gnunet-122dbcd5b6ac9e0b855cb01f873b62ad35ca39ae.zip
- allow disconnecting from ARM from callbacks
Diffstat (limited to 'src/arm')
-rw-r--r--src/arm/arm_api.c197
-rw-r--r--src/arm/arm_monitor_api.c7
2 files changed, 106 insertions, 98 deletions
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c
index 9b235f023..0e96398de 100644
--- a/src/arm/arm_api.c
+++ b/src/arm/arm_api.c
@@ -36,7 +36,6 @@
36 */ 36 */
37struct GNUNET_ARM_Handle 37struct GNUNET_ARM_Handle
38{ 38{
39
40 /** 39 /**
41 * Our control connection to the ARM service. 40 * Our control connection to the ARM service.
42 */ 41 */
@@ -83,11 +82,6 @@ struct GNUNET_ARM_Handle
83 struct GNUNET_TIME_Relative retry_backoff; 82 struct GNUNET_TIME_Relative retry_backoff;
84 83
85 /** 84 /**
86 * Are we currently disconnected and hence unable to send?
87 */
88 unsigned char currently_down;
89
90 /**
91 * Callback to invoke on connection/disconnection. 85 * Callback to invoke on connection/disconnection.
92 */ 86 */
93 GNUNET_ARM_ConnectionStatusCallback conn_status; 87 GNUNET_ARM_ConnectionStatusCallback conn_status;
@@ -98,14 +92,19 @@ struct GNUNET_ARM_Handle
98 void *conn_status_cls; 92 void *conn_status_cls;
99 93
100 /** 94 /**
101 * GNUNET_YES if we're running a service test. 95 * Counter for request identifiers
102 */ 96 */
103 unsigned char service_test_is_active; 97 uint64_t request_id_counter;
104 98
105 /** 99 /**
106 * Counter for request identifiers 100 * Are we currently disconnected and hence unable to send?
107 */ 101 */
108 uint64_t request_id_counter; 102 unsigned char currently_down;
103
104 /**
105 * GNUNET_YES if we're running a service test.
106 */
107 unsigned char service_test_is_active;
109}; 108};
110 109
111 110
@@ -128,6 +127,16 @@ struct ARMControlMessage
128 struct ARMControlMessage *prev; 127 struct ARMControlMessage *prev;
129 128
130 /** 129 /**
130 * ARM handle.
131 */
132 struct GNUNET_ARM_Handle *h;
133
134 /**
135 * Message to send.
136 */
137 struct GNUNET_ARM_Message *msg;
138
139 /**
131 * Callback for service state change requests. 140 * Callback for service state change requests.
132 */ 141 */
133 GNUNET_ARM_ResultCallback result_cont; 142 GNUNET_ARM_ResultCallback result_cont;
@@ -148,29 +157,19 @@ struct ARMControlMessage
148 struct GNUNET_TIME_Absolute timeout; 157 struct GNUNET_TIME_Absolute timeout;
149 158
150 /** 159 /**
151 * Type of the request expressed as a message type (start, stop or list).
152 */
153 uint16_t type;
154
155 /**
156 * Flags for passing std descriptors to ARM (when starting ARM). 160 * Flags for passing std descriptors to ARM (when starting ARM).
157 */ 161 */
158 enum GNUNET_OS_InheritStdioFlags std_inheritance; 162 enum GNUNET_OS_InheritStdioFlags std_inheritance;
159 163
160 /** 164 /**
161 * ARM handle. 165 * Task to run when request times out.
162 */
163 struct GNUNET_ARM_Handle *h;
164
165 /**
166 * Message to send.
167 */ 166 */
168 struct GNUNET_ARM_Message *msg; 167 GNUNET_SCHEDULER_TaskIdentifier timeout_task_id;
169 168
170 /** 169 /**
171 * Task to run when request times out. 170 * Type of the request expressed as a message type (start, stop or list).
172 */ 171 */
173 GNUNET_SCHEDULER_TaskIdentifier timeout_task_id; 172 uint16_t type;
174}; 173};
175 174
176static void 175static void
@@ -232,24 +231,17 @@ reconnect_arm_later (struct GNUNET_ARM_Handle *h)
232{ 231{
233 if (GNUNET_NO != h->currently_down) 232 if (GNUNET_NO != h->currently_down)
234 return; 233 return;
235
236 if (NULL != h->cth) 234 if (NULL != h->cth)
237 { 235 {
238 GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth); 236 GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth);
239 h->cth = NULL; 237 h->cth = NULL;
240 } 238 }
241
242 if (NULL != h->client) 239 if (NULL != h->client)
243 { 240 {
244 GNUNET_CLIENT_disconnect (h->client); 241 GNUNET_CLIENT_disconnect (h->client);
245 h->client = NULL; 242 h->client = NULL;
246 } 243 }
247
248 if (NULL != h->conn_status)
249 h->conn_status (h->conn_status_cls, h, GNUNET_NO);
250
251 h->currently_down = GNUNET_YES; 244 h->currently_down = GNUNET_YES;
252
253 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->reconnect_task); 245 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->reconnect_task);
254 h->reconnect_task = 246 h->reconnect_task =
255 GNUNET_SCHEDULER_add_delayed (h->retry_backoff, &reconnect_arm_task, h); 247 GNUNET_SCHEDULER_add_delayed (h->retry_backoff, &reconnect_arm_task, h);
@@ -258,6 +250,8 @@ reconnect_arm_later (struct GNUNET_ARM_Handle *h)
258 GNUNET_assert (NULL == h->control_pending_head); 250 GNUNET_assert (NULL == h->control_pending_head);
259 */ 251 */
260 h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); 252 h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff);
253 if (NULL != h->conn_status)
254 h->conn_status (h->conn_status_cls, h, GNUNET_NO);
261} 255}
262 256
263/** 257/**
@@ -274,19 +268,20 @@ transmit_arm_message (void *cls, size_t size, void *buf)
274 struct GNUNET_ARM_Handle *h = cls; 268 struct GNUNET_ARM_Handle *h = cls;
275 struct ARMControlMessage *cm; 269 struct ARMControlMessage *cm;
276 struct GNUNET_ARM_Message *arm_msg; 270 struct GNUNET_ARM_Message *arm_msg;
277 uint16_t msize;
278 uint64_t request_id; 271 uint64_t request_id;
272 int notify_connection;
273 uint16_t msize;
279 274
275 notify_connection = GNUNET_NO;
280 LOG (GNUNET_ERROR_TYPE_DEBUG, 276 LOG (GNUNET_ERROR_TYPE_DEBUG,
281 "transmit_arm_message is running with %p buffer of size %lu. ARM is known to be %s\n", 277 "transmit_arm_message is running with %p buffer of size %lu. ARM is known to be %s\n",
282 buf, size, h->currently_down ? "unconnected" : "connected"); 278 buf, size, h->currently_down ? "unconnected" : "connected");
283 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->reconnect_task); 279 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->reconnect_task);
284 h->cth = NULL; 280 h->cth = NULL;
285 if ((GNUNET_YES == h->currently_down) && (NULL != buf)) 281 if ((GNUNET_YES == h->currently_down) && (NULL != buf))
286 { 282 {
287 h->currently_down = GNUNET_NO; 283 h->currently_down = GNUNET_NO;
288 if (NULL != h->conn_status) 284 notify_connection = GNUNET_YES;
289 h->conn_status (h->conn_status_cls, h, GNUNET_YES);
290 h->retry_backoff = GNUNET_TIME_UNIT_MILLISECONDS; 285 h->retry_backoff = GNUNET_TIME_UNIT_MILLISECONDS;
291 GNUNET_CLIENT_receive (h->client, &client_notify_handler, h, 286 GNUNET_CLIENT_receive (h->client, &client_notify_handler, h,
292 GNUNET_TIME_UNIT_FOREVER_REL); 287 GNUNET_TIME_UNIT_FOREVER_REL);
@@ -301,9 +296,9 @@ transmit_arm_message (void *cls, size_t size, void *buf)
301 if (NULL == (cm = h->control_pending_head)) 296 if (NULL == (cm = h->control_pending_head))
302 { 297 {
303 LOG (GNUNET_ERROR_TYPE_DEBUG, "Queue is empty, not sending anything\n"); 298 LOG (GNUNET_ERROR_TYPE_DEBUG, "Queue is empty, not sending anything\n");
304 return 0; 299 msize = 0;
300 goto end;
305 } 301 }
306
307 GNUNET_assert (NULL != cm->msg); 302 GNUNET_assert (NULL != cm->msg);
308 msize = ntohs (cm->msg->header.size); 303 msize = ntohs (cm->msg->header.size);
309 if (size < msize) 304 if (size < msize)
@@ -311,7 +306,8 @@ transmit_arm_message (void *cls, size_t size, void *buf)
311 LOG (GNUNET_ERROR_TYPE_DEBUG, 306 LOG (GNUNET_ERROR_TYPE_DEBUG,
312 "Request is too big (%u < %u), not sending it\n", size, msize); 307 "Request is too big (%u < %u), not sending it\n", size, msize);
313 trigger_next_request (h, GNUNET_NO); 308 trigger_next_request (h, GNUNET_NO);
314 return 0; 309 msize = 0;
310 goto end;
315 } 311 }
316 arm_msg = cm->msg; 312 arm_msg = cm->msg;
317 if (0 == h->request_id_counter) 313 if (0 == h->request_id_counter)
@@ -324,17 +320,19 @@ transmit_arm_message (void *cls, size_t size, void *buf)
324 memcpy (buf, cm->msg, msize); 320 memcpy (buf, cm->msg, msize);
325 /* Otherwise we won't be able to find it later! */ 321 /* Otherwise we won't be able to find it later! */
326 arm_msg->request_id = request_id; 322 arm_msg->request_id = request_id;
327
328 GNUNET_CONTAINER_DLL_remove (h->control_pending_head, 323 GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
329 h->control_pending_tail, cm); 324 h->control_pending_tail, cm);
330 GNUNET_CONTAINER_DLL_insert_tail (h->control_sent_head, 325 GNUNET_CONTAINER_DLL_insert_tail (h->control_sent_head,
331 h->control_sent_tail, cm); 326 h->control_sent_tail, cm);
332
333 /* Don't free msg, keep it around (kind of wasteful, but then we don't 327 /* Don't free msg, keep it around (kind of wasteful, but then we don't
334 * really have many messages to handle, and it'll be freed when it times 328 * really have many messages to handle, and it'll be freed when it times
335 * out anyway. 329 * out anyway.
336 */ 330 */
337 trigger_next_request (h, GNUNET_NO); 331 trigger_next_request (h, GNUNET_NO);
332
333 end:
334 if ((GNUNET_YES == notify_connection) && (NULL != h->conn_status))
335 h->conn_status (h->conn_status_cls, h, GNUNET_YES);
338 return msize; 336 return msize;
339} 337}
340 338
@@ -439,7 +437,6 @@ GNUNET_ARM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
439 437
440/** 438/**
441 * Disconnect from the ARM service (if connected) and destroy the context. 439 * Disconnect from the ARM service (if connected) and destroy the context.
442 * Don't call inside an ARM callback!
443 * 440 *
444 * @param h the handle that was being used 441 * @param h the handle that was being used
445 */ 442 */
@@ -520,6 +517,7 @@ static void
520arm_service_report (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 517arm_service_report (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
521{ 518{
522 struct ARMControlMessage *cm = cls; 519 struct ARMControlMessage *cm = cls;
520 struct GNUNET_ARM_Handle *h;
523 struct GNUNET_OS_Process *proc; 521 struct GNUNET_OS_Process *proc;
524 unsigned char test_is_active; 522 unsigned char test_is_active;
525 char *cbinary; 523 char *cbinary;
@@ -627,8 +625,9 @@ arm_service_report (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
627 cm->result_cont (cm->cont_cls, cm->h, GNUNET_ARM_REQUEST_SENT_OK, "arm", 625 cm->result_cont (cm->cont_cls, cm->h, GNUNET_ARM_REQUEST_SENT_OK, "arm",
628 GNUNET_ARM_RESULT_STARTING); 626 GNUNET_ARM_RESULT_STARTING);
629 GNUNET_OS_process_destroy (proc); 627 GNUNET_OS_process_destroy (proc);
630 reconnect_arm (cm->h); 628 h = cm->h;
631 GNUNET_free (cm); 629 GNUNET_free (cm);
630 reconnect_arm (h);
632} 631}
633 632
634 633
@@ -809,8 +808,9 @@ GNUNET_ARM_request_service_stop (struct GNUNET_ARM_Handle *h,
809 */ 808 */
810void 809void
811GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h, 810GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h,
812 struct GNUNET_TIME_Relative timeout, 811 struct GNUNET_TIME_Relative timeout,
813 GNUNET_ARM_ServiceListCallback cont, void *cont_cls) 812 GNUNET_ARM_ServiceListCallback cont,
813 void *cont_cls)
814{ 814{
815 struct ARMControlMessage *cm; 815 struct ARMControlMessage *cm;
816 struct GNUNET_ARM_Message *msg; 816 struct GNUNET_ARM_Message *msg;
@@ -818,7 +818,6 @@ GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h,
818 LOG (GNUNET_ERROR_TYPE_DEBUG, 818 LOG (GNUNET_ERROR_TYPE_DEBUG,
819 "Requesting LIST from ARM service with timeout: %s\n", 819 "Requesting LIST from ARM service with timeout: %s\n",
820 GNUNET_STRINGS_relative_time_to_string (timeout, GNUNET_YES)); 820 GNUNET_STRINGS_relative_time_to_string (timeout, GNUNET_YES));
821
822 cm = GNUNET_malloc (sizeof (struct ARMControlMessage)); 821 cm = GNUNET_malloc (sizeof (struct ARMControlMessage));
823 cm->h = h; 822 cm->h = h;
824 cm->list_cont = cont; 823 cm->list_cont = cont;
@@ -836,6 +835,7 @@ GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h,
836 trigger_next_request (h, GNUNET_NO); 835 trigger_next_request (h, GNUNET_NO);
837} 836}
838 837
838
839static struct ARMControlMessage * 839static struct ARMControlMessage *
840find_cm_by_id (struct GNUNET_ARM_Handle *h, uint64_t id) 840find_cm_by_id (struct GNUNET_ARM_Handle *h, uint64_t id)
841{ 841{
@@ -857,21 +857,20 @@ static void
857client_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) 857client_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
858{ 858{
859 struct GNUNET_ARM_Handle *h = cls; 859 struct GNUNET_ARM_Handle *h = cls;
860
861 uint16_t msize;
862 uint64_t id;
863 unsigned char fail;
864
865 const struct GNUNET_ARM_Message *arm_msg; 860 const struct GNUNET_ARM_Message *arm_msg;
866 const struct GNUNET_ARM_ResultMessage *res; 861 const struct GNUNET_ARM_ResultMessage *res;
867 const struct GNUNET_ARM_ListResultMessage *lres; 862 const struct GNUNET_ARM_ListResultMessage *lres;
868 enum GNUNET_ARM_Result result;
869 struct ARMControlMessage *cm; 863 struct ARMControlMessage *cm;
870 864 const char **list;
871 const char *pos; 865 const char *pos;
866 uint64_t id;
867 enum GNUNET_ARM_Result result;
872 uint16_t size_check; 868 uint16_t size_check;
873 uint16_t rcount; 869 uint16_t rcount;
870 uint16_t msize;
871 unsigned char fail;
874 872
873 list = NULL;
875 if (NULL == msg) 874 if (NULL == msg)
876 { 875 {
877 LOG (GNUNET_ERROR_TYPE_INFO, 876 LOG (GNUNET_ERROR_TYPE_INFO,
@@ -896,8 +895,7 @@ client_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
896 { 895 {
897 LOG (GNUNET_ERROR_TYPE_DEBUG, "Message with unknown id %llu\n", id); 896 LOG (GNUNET_ERROR_TYPE_DEBUG, "Message with unknown id %llu\n", id);
898 return; 897 return;
899 } 898 }
900
901 fail = GNUNET_NO; 899 fail = GNUNET_NO;
902 switch (ntohs (msg->type)) 900 switch (ntohs (msg->type))
903 { 901 {
@@ -906,70 +904,81 @@ client_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
906 { 904 {
907 GNUNET_assert (0); 905 GNUNET_assert (0);
908 fail = GNUNET_YES; 906 fail = GNUNET_YES;
909 break;
910 } 907 }
911 res = (const struct GNUNET_ARM_ResultMessage *) msg;
912 LOG (GNUNET_ERROR_TYPE_DEBUG,
913 "Received response from ARM for service `%s': %u\n",
914 (const char *) &cm->msg[1], ntohs (msg->type));
915 result = (enum GNUNET_ARM_Result) ntohl (res->result);
916 if (NULL != cm->result_cont)
917 cm->result_cont (cm->cont_cls, h, GNUNET_ARM_REQUEST_SENT_OK, (const char *) &cm->msg[1], result);
918 break; 908 break;
919 case GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT: 909 case GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT:
920 if (msize < sizeof (struct GNUNET_ARM_ListResultMessage)) 910 if (msize < sizeof (struct GNUNET_ARM_ListResultMessage))
921 { 911 {
922 GNUNET_break (0); 912 GNUNET_break (0);
923 fail = GNUNET_YES; 913 fail = GNUNET_YES;
924 return; 914 break;
925 } 915 }
926 else 916 size_check = 0;
917 lres = (const struct GNUNET_ARM_ListResultMessage *) msg;
918 rcount = ntohs (lres->count);
927 { 919 {
928 size_check = 0; 920 unsigned int i;
929 lres = (const struct GNUNET_ARM_ListResultMessage *) msg; 921
930 rcount = ntohs (lres->count); 922 list = GNUNET_malloc (sizeof (const char *) * rcount);
923 pos = (const char *)&lres[1];
924 for (i = 0; i < rcount; i++)
931 { 925 {
932 const char *list[rcount]; 926 const char *end = memchr (pos, 0, msize - size_check);
933 unsigned int i; 927 if (NULL == end)
934
935 pos = (const char *)&lres[1];
936 for (i = 0; i < rcount; i++)
937 { 928 {
938 const char *end = memchr (pos, 0, msize - size_check); 929 GNUNET_break (0);
939 if (NULL == end) 930 fail = GNUNET_YES;
940 {
941 GNUNET_break (0);
942 fail = GNUNET_YES;
943 break;
944 }
945 list[i] = pos;
946 size_check += (end - pos) + 1;
947 pos = end + 1;
948 }
949 if (GNUNET_YES == fail)
950 break; 931 break;
951 if (NULL != cm->list_cont) 932 }
952 cm->list_cont (cm->cont_cls, h, GNUNET_ARM_REQUEST_SENT_OK, rcount, list); 933 list[i] = pos;
934 size_check += (end - pos) + 1;
935 pos = end + 1;
936 }
937 if (GNUNET_YES == fail)
938 {
939 GNUNET_free (list);
940 list = NULL;
953 } 941 }
954 } 942 }
955 break; 943 break;
956 default: 944 default:
957 fail = GNUNET_YES; 945 fail = GNUNET_YES;
958 return; 946 break;
959 } 947 }
960
961 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != cm->timeout_task_id); 948 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != cm->timeout_task_id);
962 GNUNET_SCHEDULER_cancel (cm->timeout_task_id); 949 GNUNET_SCHEDULER_cancel (cm->timeout_task_id);
963 GNUNET_CONTAINER_DLL_remove (h->control_sent_head, 950 GNUNET_CONTAINER_DLL_remove (h->control_sent_head,
964 h->control_sent_tail, cm); 951 h->control_sent_tail, cm);
965 GNUNET_free (cm->msg);
966 GNUNET_free (cm);
967
968 if (GNUNET_YES == fail) 952 if (GNUNET_YES == fail)
953 {
969 reconnect_arm_later (h); 954 reconnect_arm_later (h);
970 else 955 GNUNET_free (cm->msg);
971 GNUNET_CLIENT_receive (h->client, &client_notify_handler, h, 956 GNUNET_free (cm);
972 GNUNET_TIME_UNIT_FOREVER_REL); 957 return;
958 }
959 GNUNET_CLIENT_receive (h->client, &client_notify_handler, h,
960 GNUNET_TIME_UNIT_FOREVER_REL);
961 switch (ntohs (msg->type))
962 {
963 case GNUNET_MESSAGE_TYPE_ARM_RESULT:
964 res = (const struct GNUNET_ARM_ResultMessage *) msg;
965 LOG (GNUNET_ERROR_TYPE_DEBUG,
966 "Received response from ARM for service `%s': %u\n",
967 (const char *) &cm->msg[1], ntohs (msg->type));
968 result = (enum GNUNET_ARM_Result) ntohl (res->result);
969 if (NULL != cm->result_cont)
970 cm->result_cont (cm->cont_cls, h, GNUNET_ARM_REQUEST_SENT_OK,
971 (const char *) &cm->msg[1], result);
972 break;
973 case GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT:
974 if (NULL != cm->list_cont)
975 cm->list_cont (cm->cont_cls, h, GNUNET_ARM_REQUEST_SENT_OK, rcount,
976 list);
977 GNUNET_free (list);
978 break;
979 }
980 GNUNET_free (cm->msg);
981 GNUNET_free (cm);
973} 982}
974 983
975/* end of arm_api.c */ 984/* end of arm_api.c */
diff --git a/src/arm/arm_monitor_api.c b/src/arm/arm_monitor_api.c
index 685f1c334..7fa53e732 100644
--- a/src/arm/arm_monitor_api.c
+++ b/src/arm/arm_monitor_api.c
@@ -268,7 +268,6 @@ GNUNET_ARM_monitor (const struct GNUNET_CONFIGURATION_Handle *cfg,
268 268
269/** 269/**
270 * Disconnect from the ARM service (if connected) and destroy the context. 270 * Disconnect from the ARM service (if connected) and destroy the context.
271 * Don't call inside a callback!
272 * 271 *
273 * @param h the handle that was being used 272 * @param h the handle that was being used
274 */ 273 */
@@ -345,15 +344,15 @@ monitor_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
345 "Received response from ARM for service `%s': %u\n", 344 "Received response from ARM for service `%s': %u\n",
346 (const char *) &res[1], ntohs (msg->type)); 345 (const char *) &res[1], ntohs (msg->type));
347 status = (enum GNUNET_ARM_ServiceStatus) ntohl (res->status); 346 status = (enum GNUNET_ARM_ServiceStatus) ntohl (res->status);
348 if ((NULL != h->service_status)) 347 GNUNET_CLIENT_receive (h->monitor, &monitor_notify_handler, h,
348 GNUNET_TIME_UNIT_FOREVER_REL);
349 if (NULL != h->service_status)
349 h->service_status (h->cls, h, (const char *) &res[1], status); 350 h->service_status (h->cls, h, (const char *) &res[1], status);
350 break; 351 break;
351 default: 352 default:
352 reconnect_arm_monitor_later (h); 353 reconnect_arm_monitor_later (h);
353 return; 354 return;
354 } 355 }
355 GNUNET_CLIENT_receive (h->monitor, &monitor_notify_handler, h,
356 GNUNET_TIME_UNIT_FOREVER_REL);
357} 356}
358 357
359 358