diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arm/arm_api.c | 174 | ||||
-rwxr-xr-x | src/arm/test_gnunet_arm.sh | 2 | ||||
-rw-r--r-- | src/core/core_api.c | 10 | ||||
-rw-r--r-- | src/datastore/Makefile.am | 1 | ||||
-rw-r--r-- | src/datastore/datastore_api.c | 132 | ||||
-rw-r--r-- | src/datastore/perf_datastore_api.c | 4 | ||||
-rw-r--r-- | src/datastore/test_datastore_api.c | 4 | ||||
-rw-r--r-- | src/datastore/test_datastore_api_data.conf | 17 | ||||
-rw-r--r-- | src/datastore/test_datastore_api_management.c | 4 | ||||
-rw-r--r-- | src/fs/fs.h | 2 | ||||
-rw-r--r-- | src/fs/fs_download.c | 11 | ||||
-rw-r--r-- | src/fs/fs_list_indexed.c | 59 | ||||
-rw-r--r-- | src/fs/fs_publish.c | 1 | ||||
-rw-r--r-- | src/fs/fs_search.c | 2 | ||||
-rw-r--r-- | src/fs/fs_unindex.c | 1 | ||||
-rw-r--r-- | src/include/gnunet_client_lib.h | 35 | ||||
-rw-r--r-- | src/peerinfo/peerinfo_api.c | 50 | ||||
-rw-r--r-- | src/statistics/statistics_api.c | 4 | ||||
-rw-r--r-- | src/transport/transport_api.c | 7 | ||||
-rw-r--r-- | src/util/client.c | 295 | ||||
-rw-r--r-- | src/util/resolver_api.c | 114 | ||||
-rw-r--r-- | src/util/test_client.c | 3 | ||||
-rw-r--r-- | src/util/test_server_disconnect.c | 1 | ||||
-rw-r--r-- | src/util/test_server_with_client.c | 1 | ||||
-rw-r--r-- | src/util/test_service.c | 2 |
25 files changed, 449 insertions, 487 deletions
diff --git a/src/arm/arm_api.c b/src/arm/arm_api.c index 49e25b38d..00ddddaab 100644 --- a/src/arm/arm_api.c +++ b/src/arm/arm_api.c | |||
@@ -32,19 +32,6 @@ | |||
32 | #include "gnunet_server_lib.h" | 32 | #include "gnunet_server_lib.h" |
33 | #include "arm.h" | 33 | #include "arm.h" |
34 | 34 | ||
35 | /** | ||
36 | * How often do we re-try tranmsitting requests to ARM before | ||
37 | * giving up? Note that if we succeeded transmitting a request | ||
38 | * but failed to read a response, we do NOT re-try (since that | ||
39 | * might result in ARM getting a request twice). | ||
40 | */ | ||
41 | #define MAX_ATTEMPTS 4 | ||
42 | |||
43 | /** | ||
44 | * Minimum delay between attempts to talk to ARM. | ||
45 | */ | ||
46 | #define MIN_RETRY_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100) | ||
47 | |||
48 | 35 | ||
49 | /** | 36 | /** |
50 | * How long are we willing to wait for a service operation during the multi-operation | 37 | * How long are we willing to wait for a service operation during the multi-operation |
@@ -143,28 +130,11 @@ struct RequestContext | |||
143 | void *cls; | 130 | void *cls; |
144 | 131 | ||
145 | /** | 132 | /** |
146 | * The service that is being manipulated. Do not free. | ||
147 | */ | ||
148 | const char *service_name; | ||
149 | |||
150 | /** | ||
151 | * Timeout for the operation. | 133 | * Timeout for the operation. |
152 | */ | 134 | */ |
153 | struct GNUNET_TIME_Absolute timeout; | 135 | struct GNUNET_TIME_Absolute timeout; |
154 | 136 | ||
155 | /** | 137 | /** |
156 | * Length of service_name plus one. | ||
157 | */ | ||
158 | size_t slen; | ||
159 | |||
160 | /** | ||
161 | * Number of attempts left for transmitting the request to ARM. | ||
162 | * We may fail the first time (say because ARM is not yet up), | ||
163 | * in which case we wait a bit and re-try (timeout permitting). | ||
164 | */ | ||
165 | unsigned int attempts_left; | ||
166 | |||
167 | /** | ||
168 | * Type of the request expressed as a message type (start or stop). | 138 | * Type of the request expressed as a message type (start or stop). |
169 | */ | 139 | */ |
170 | uint16_t type; | 140 | uint16_t type; |
@@ -303,121 +273,6 @@ handle_response (void *cls, const struct GNUNET_MessageHeader *msg) | |||
303 | 273 | ||
304 | 274 | ||
305 | /** | 275 | /** |
306 | * We've failed to transmit the request to the ARM service. | ||
307 | * Report our failure and clean up the state. | ||
308 | * | ||
309 | * @param sctx the state of the (now failed) request | ||
310 | */ | ||
311 | static void | ||
312 | report_transmit_failure (struct RequestContext *sctx) | ||
313 | { | ||
314 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
315 | _("Error while trying to transmit to ARM service\n")); | ||
316 | if (sctx->callback != NULL) | ||
317 | sctx->callback (sctx->cls, GNUNET_SYSERR); | ||
318 | GNUNET_free (sctx); | ||
319 | } | ||
320 | |||
321 | |||
322 | /** | ||
323 | * Transmit a request for a service status change to the | ||
324 | * ARM service. | ||
325 | * | ||
326 | * @param cls the "struct RequestContext" identifying the request | ||
327 | * @param size how many bytes are available in buf | ||
328 | * @param buf where to write the request, NULL on error | ||
329 | * @return number of bytes written to buf | ||
330 | */ | ||
331 | static size_t | ||
332 | send_service_msg (void *cls, size_t size, void *buf); | ||
333 | |||
334 | |||
335 | /** | ||
336 | * We've failed to transmit the request to the ARM service but | ||
337 | * are now going to try again. | ||
338 | * | ||
339 | * @param cls state of the request | ||
340 | * @param tc task context (unused) | ||
341 | */ | ||
342 | static void | ||
343 | retry_request (void *cls, | ||
344 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
345 | { | ||
346 | struct RequestContext *sctx = cls; | ||
347 | |||
348 | if (NULL == | ||
349 | GNUNET_CLIENT_notify_transmit_ready (sctx->h->client, | ||
350 | sctx->slen + | ||
351 | sizeof (struct | ||
352 | GNUNET_MessageHeader), | ||
353 | GNUNET_TIME_absolute_get_remaining (sctx->timeout), | ||
354 | &send_service_msg, | ||
355 | sctx)) | ||
356 | { | ||
357 | report_transmit_failure (sctx); | ||
358 | return; | ||
359 | } | ||
360 | } | ||
361 | |||
362 | |||
363 | /** | ||
364 | * Transmit a request for a service status change to the | ||
365 | * ARM service. | ||
366 | * | ||
367 | * @param cls the "struct RequestContext" identifying the request | ||
368 | * @param size how many bytes are available in buf | ||
369 | * @param buf where to write the request, NULL on error | ||
370 | * @return number of bytes written to buf | ||
371 | */ | ||
372 | static size_t | ||
373 | send_service_msg (void *cls, size_t size, void *buf) | ||
374 | { | ||
375 | struct RequestContext *sctx = cls; | ||
376 | struct GNUNET_MessageHeader *msg; | ||
377 | struct GNUNET_TIME_Relative rem; | ||
378 | |||
379 | if (buf == NULL) | ||
380 | { | ||
381 | GNUNET_CLIENT_disconnect (sctx->h->client); | ||
382 | sctx->h->client = GNUNET_CLIENT_connect (sctx->h->sched, | ||
383 | "arm", | ||
384 | sctx->h->cfg); | ||
385 | GNUNET_assert (sctx->h->client != NULL); | ||
386 | rem = GNUNET_TIME_absolute_get_remaining (sctx->timeout); | ||
387 | if ( (sctx->attempts_left-- > 0) && | ||
388 | (rem.value > 0) ) | ||
389 | { | ||
390 | GNUNET_SCHEDULER_add_delayed (sctx->h->sched, | ||
391 | GNUNET_NO, | ||
392 | GNUNET_SCHEDULER_PRIORITY_KEEP, | ||
393 | GNUNET_SCHEDULER_NO_TASK, | ||
394 | GNUNET_TIME_relative_min (MIN_RETRY_DELAY, | ||
395 | rem), | ||
396 | &retry_request, | ||
397 | sctx); | ||
398 | return 0; | ||
399 | } | ||
400 | report_transmit_failure (sctx); | ||
401 | return 0; | ||
402 | } | ||
403 | #if DEBUG_ARM | ||
404 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
405 | _("Transmitting service request to ARM.\n")); | ||
406 | #endif | ||
407 | GNUNET_assert (size >= sctx->slen); | ||
408 | msg = buf; | ||
409 | msg->size = htons (sizeof (struct GNUNET_MessageHeader) + sctx->slen); | ||
410 | msg->type = htons (sctx->type); | ||
411 | memcpy (&msg[1], sctx->service_name, sctx->slen); | ||
412 | GNUNET_CLIENT_receive (sctx->h->client, | ||
413 | &handle_response, | ||
414 | sctx, | ||
415 | GNUNET_TIME_absolute_get_remaining (sctx->timeout)); | ||
416 | return sctx->slen + sizeof (struct GNUNET_MessageHeader); | ||
417 | } | ||
418 | |||
419 | |||
420 | /** | ||
421 | * Start or stop a service. | 276 | * Start or stop a service. |
422 | * | 277 | * |
423 | * @param h handle to ARM | 278 | * @param h handle to ARM |
@@ -435,6 +290,7 @@ change_service (struct GNUNET_ARM_Handle *h, | |||
435 | { | 290 | { |
436 | struct RequestContext *sctx; | 291 | struct RequestContext *sctx; |
437 | size_t slen; | 292 | size_t slen; |
293 | struct GNUNET_MessageHeader *msg; | ||
438 | 294 | ||
439 | slen = strlen (service_name) + 1; | 295 | slen = strlen (service_name) + 1; |
440 | if (slen + sizeof (struct GNUNET_MessageHeader) > | 296 | if (slen + sizeof (struct GNUNET_MessageHeader) > |
@@ -453,15 +309,29 @@ change_service (struct GNUNET_ARM_Handle *h, | |||
453 | sctx->h = h; | 309 | sctx->h = h; |
454 | sctx->callback = cb; | 310 | sctx->callback = cb; |
455 | sctx->cls = cb_cls; | 311 | sctx->cls = cb_cls; |
456 | sctx->service_name = (const char*) &sctx[1]; | ||
457 | memcpy (&sctx[1], | ||
458 | service_name, | ||
459 | slen); | ||
460 | sctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); | 312 | sctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); |
461 | sctx->slen = slen; | ||
462 | sctx->attempts_left = MAX_ATTEMPTS; | ||
463 | sctx->type = type; | 313 | sctx->type = type; |
464 | retry_request (sctx, NULL); | 314 | msg = GNUNET_malloc (sizeof (struct GNUNET_MessageHeader) + slen); |
315 | msg->size = htons (sizeof (struct GNUNET_MessageHeader) + slen); | ||
316 | msg->type = htons (sctx->type); | ||
317 | memcpy (&msg[1], service_name, slen); | ||
318 | if (GNUNET_OK != | ||
319 | GNUNET_CLIENT_transmit_and_get_response (sctx->h->client, | ||
320 | msg, | ||
321 | GNUNET_TIME_absolute_get_remaining (sctx->timeout), | ||
322 | GNUNET_YES, | ||
323 | &handle_response, | ||
324 | sctx)) | ||
325 | { | ||
326 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
327 | _("Error while trying to transmit to ARM service\n")); | ||
328 | if (cb != NULL) | ||
329 | cb (cb_cls, GNUNET_SYSERR); | ||
330 | GNUNET_free (sctx); | ||
331 | GNUNET_free (msg); | ||
332 | return; | ||
333 | } | ||
334 | GNUNET_free (msg); | ||
465 | } | 335 | } |
466 | 336 | ||
467 | 337 | ||
diff --git a/src/arm/test_gnunet_arm.sh b/src/arm/test_gnunet_arm.sh index ce4396cfb..d36c2ca38 100755 --- a/src/arm/test_gnunet_arm.sh +++ b/src/arm/test_gnunet_arm.sh | |||
@@ -1,7 +1,7 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | exe="./gnunet-arm -c test_arm_api_data.conf" | 3 | exe="./gnunet-arm -c test_arm_api_data.conf" |
4 | out=`mktemp /tmp/test-gnunetd-arm-logXXXXXXXX` | 4 | out=`mktemp /tmp/test-gnunet-arm-logXXXXXXXX` |
5 | #DEBUG="-L DEBUG" | 5 | #DEBUG="-L DEBUG" |
6 | 6 | ||
7 | 7 | ||
diff --git a/src/core/core_api.c b/src/core/core_api.c index 89bae0525..2157584ab 100644 --- a/src/core/core_api.c +++ b/src/core/core_api.c | |||
@@ -94,7 +94,7 @@ struct GNUNET_CORE_Handle | |||
94 | /** | 94 | /** |
95 | * Handle for our current transmission request. | 95 | * Handle for our current transmission request. |
96 | */ | 96 | */ |
97 | struct GNUNET_CONNECTION_TransmitHandle *th; | 97 | struct GNUNET_CLIENT_TransmitHandle *th; |
98 | 98 | ||
99 | /** | 99 | /** |
100 | * Head of doubly-linked list of pending requests. | 100 | * Head of doubly-linked list of pending requests. |
@@ -257,6 +257,7 @@ reconnect (struct GNUNET_CORE_Handle *h) | |||
257 | sizeof (struct InitMessage) + | 257 | sizeof (struct InitMessage) + |
258 | sizeof (uint16_t) * h->hcnt, | 258 | sizeof (uint16_t) * h->hcnt, |
259 | GNUNET_TIME_UNIT_SECONDS, | 259 | GNUNET_TIME_UNIT_SECONDS, |
260 | GNUNET_NO, | ||
260 | &transmit_start, h); | 261 | &transmit_start, h); |
261 | } | 262 | } |
262 | 263 | ||
@@ -346,7 +347,9 @@ trigger_next_request (struct GNUNET_CORE_Handle *h) | |||
346 | h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, | 347 | h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, |
347 | th->msize, | 348 | th->msize, |
348 | GNUNET_TIME_absolute_get_remaining | 349 | GNUNET_TIME_absolute_get_remaining |
349 | (th->timeout), &request_start, | 350 | (th->timeout), |
351 | GNUNET_NO, | ||
352 | &request_start, | ||
350 | h); | 353 | h); |
351 | } | 354 | } |
352 | 355 | ||
@@ -821,6 +824,7 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched, | |||
821 | GNUNET_CLIENT_notify_transmit_ready (h->client, | 824 | GNUNET_CLIENT_notify_transmit_ready (h->client, |
822 | sizeof (struct InitMessage) + | 825 | sizeof (struct InitMessage) + |
823 | sizeof (uint16_t) * h->hcnt, timeout, | 826 | sizeof (uint16_t) * h->hcnt, timeout, |
827 | GNUNET_YES, | ||
824 | &transmit_start, h); | 828 | &transmit_start, h); |
825 | } | 829 | } |
826 | 830 | ||
@@ -834,7 +838,7 @@ void | |||
834 | GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle) | 838 | GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle) |
835 | { | 839 | { |
836 | if (handle->th != NULL) | 840 | if (handle->th != NULL) |
837 | GNUNET_CONNECTION_notify_transmit_ready_cancel (handle->th); | 841 | GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th); |
838 | if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK) | 842 | if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK) |
839 | GNUNET_SCHEDULER_cancel (handle->sched, handle->reconnect_task); | 843 | GNUNET_SCHEDULER_cancel (handle->sched, handle->reconnect_task); |
840 | GNUNET_CLIENT_disconnect (handle->client); | 844 | GNUNET_CLIENT_disconnect (handle->client); |
diff --git a/src/datastore/Makefile.am b/src/datastore/Makefile.am index e4de8fcfa..b9d8ec38f 100644 --- a/src/datastore/Makefile.am +++ b/src/datastore/Makefile.am | |||
@@ -18,6 +18,7 @@ lib_LTLIBRARIES = \ | |||
18 | libgnunetdatastore_la_SOURCES = \ | 18 | libgnunetdatastore_la_SOURCES = \ |
19 | datastore_api.c datastore.h plugin_datastore.h | 19 | datastore_api.c datastore.h plugin_datastore.h |
20 | libgnunetdatastore_la_LIBADD = \ | 20 | libgnunetdatastore_la_LIBADD = \ |
21 | $(top_builddir)/src/arm/libgnunetarm.la \ | ||
21 | $(top_builddir)/src/util/libgnunetutil.la \ | 22 | $(top_builddir)/src/util/libgnunetutil.la \ |
22 | $(GN_LIBINTL) | 23 | $(GN_LIBINTL) |
23 | libgnunetdatastore_la_LDFLAGS = \ | 24 | libgnunetdatastore_la_LDFLAGS = \ |
diff --git a/src/datastore/datastore_api.c b/src/datastore/datastore_api.c index f6d7480de..a9058fa04 100644 --- a/src/datastore/datastore_api.c +++ b/src/datastore/datastore_api.c | |||
@@ -24,6 +24,7 @@ | |||
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | */ | 25 | */ |
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_arm_service.h" | ||
27 | #include "gnunet_datastore_service.h" | 28 | #include "gnunet_datastore_service.h" |
28 | #include "datastore.h" | 29 | #include "datastore.h" |
29 | 30 | ||
@@ -75,6 +76,7 @@ struct GNUNET_DATASTORE_Handle | |||
75 | }; | 76 | }; |
76 | 77 | ||
77 | 78 | ||
79 | |||
78 | /** | 80 | /** |
79 | * Connect to the datastore service. | 81 | * Connect to the datastore service. |
80 | * | 82 | * |
@@ -95,6 +97,7 @@ struct GNUNET_DATASTORE_Handle *GNUNET_DATASTORE_connect (const struct | |||
95 | c = GNUNET_CLIENT_connect (sched, "datastore", cfg); | 97 | c = GNUNET_CLIENT_connect (sched, "datastore", cfg); |
96 | if (c == NULL) | 98 | if (c == NULL) |
97 | return NULL; /* oops */ | 99 | return NULL; /* oops */ |
100 | GNUNET_ARM_start_services (cfg, sched, "datastore", NULL); | ||
98 | h = GNUNET_malloc (sizeof(struct GNUNET_DATASTORE_Handle) + | 101 | h = GNUNET_malloc (sizeof(struct GNUNET_DATASTORE_Handle) + |
99 | GNUNET_SERVER_MAX_MESSAGE_SIZE); | 102 | GNUNET_SERVER_MAX_MESSAGE_SIZE); |
100 | h->client = c; | 103 | h->client = c; |
@@ -149,6 +152,7 @@ void GNUNET_DATASTORE_disconnect (struct GNUNET_DATASTORE_Handle *h, | |||
149 | GNUNET_CLIENT_notify_transmit_ready (h->client, | 152 | GNUNET_CLIENT_notify_transmit_ready (h->client, |
150 | sizeof(struct GNUNET_MessageHeader), | 153 | sizeof(struct GNUNET_MessageHeader), |
151 | GNUNET_TIME_UNIT_MINUTES, | 154 | GNUNET_TIME_UNIT_MINUTES, |
155 | GNUNET_YES, | ||
152 | &transmit_drop, | 156 | &transmit_drop, |
153 | h)) | 157 | h)) |
154 | return; | 158 | return; |
@@ -156,6 +160,7 @@ void GNUNET_DATASTORE_disconnect (struct GNUNET_DATASTORE_Handle *h, | |||
156 | } | 160 | } |
157 | if (h->client != NULL) | 161 | if (h->client != NULL) |
158 | GNUNET_CLIENT_disconnect (h->client); | 162 | GNUNET_CLIENT_disconnect (h->client); |
163 | GNUNET_ARM_stop_services (h->cfg, h->sched, "datastore", NULL); | ||
159 | GNUNET_free (h); | 164 | GNUNET_free (h); |
160 | } | 165 | } |
161 | 166 | ||
@@ -233,51 +238,6 @@ with_status_response_handler (void *cls, | |||
233 | 238 | ||
234 | 239 | ||
235 | /** | 240 | /** |
236 | * Transmit message to datastore service and then | ||
237 | * read a status message. | ||
238 | * | ||
239 | * @param cls closure with handle to datastore | ||
240 | * @param size number of bytes we can transmit at most | ||
241 | * @param buf where to write transmission, NULL on | ||
242 | * timeout | ||
243 | * @return number of bytes copied to buf | ||
244 | */ | ||
245 | static size_t | ||
246 | transmit_get_status (void *cls, | ||
247 | size_t size, | ||
248 | void *buf) | ||
249 | { | ||
250 | struct GNUNET_DATASTORE_Handle *h = cls; | ||
251 | GNUNET_DATASTORE_ContinuationWithStatus cont = h->response_proc; | ||
252 | uint16_t msize; | ||
253 | |||
254 | if (buf == NULL) | ||
255 | { | ||
256 | h->message_size = 0; | ||
257 | h->response_proc = NULL; | ||
258 | cont (h->response_proc_cls, | ||
259 | GNUNET_SYSERR, | ||
260 | _("Error transmitting message to datastore service.")); | ||
261 | return 0; | ||
262 | } | ||
263 | msize = h->message_size; | ||
264 | GNUNET_assert (msize <= size); | ||
265 | memcpy (buf, &h[1], msize); | ||
266 | #if DEBUG_DATASTORE | ||
267 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
268 | "Transmitted %u byte message to datastore service, now waiting for status.\n", | ||
269 | msize); | ||
270 | #endif | ||
271 | h->message_size = 0; | ||
272 | GNUNET_CLIENT_receive (h->client, | ||
273 | &with_status_response_handler, | ||
274 | h, | ||
275 | GNUNET_TIME_absolute_get_remaining (h->timeout)); | ||
276 | return msize; | ||
277 | } | ||
278 | |||
279 | |||
280 | /** | ||
281 | * Helper function that will initiate the | 241 | * Helper function that will initiate the |
282 | * transmission of a message to the datastore | 242 | * transmission of a message to the datastore |
283 | * service. The message must already be prepared | 243 | * service. The message must already be prepared |
@@ -313,11 +273,13 @@ transmit_for_status (struct GNUNET_DATASTORE_Handle *h, | |||
313 | h->response_proc_cls = cont_cls; | 273 | h->response_proc_cls = cont_cls; |
314 | h->timeout = GNUNET_TIME_relative_to_absolute (timeout); | 274 | h->timeout = GNUNET_TIME_relative_to_absolute (timeout); |
315 | h->message_size = msize; | 275 | h->message_size = msize; |
316 | if (NULL == GNUNET_CLIENT_notify_transmit_ready (h->client, | 276 | if (GNUNET_OK != |
317 | msize, | 277 | GNUNET_CLIENT_transmit_and_get_response (h->client, |
318 | timeout, | 278 | hdr, |
319 | &transmit_get_status, | 279 | timeout, |
320 | h)) | 280 | GNUNET_YES, |
281 | &with_status_response_handler, | ||
282 | h)) | ||
321 | { | 283 | { |
322 | GNUNET_break (0); | 284 | GNUNET_break (0); |
323 | h->response_proc = NULL; | 285 | h->response_proc = NULL; |
@@ -571,54 +533,6 @@ with_result_response_handler (void *cls, | |||
571 | 533 | ||
572 | 534 | ||
573 | /** | 535 | /** |
574 | * Transmit message to datastore service and then | ||
575 | * read a result message. | ||
576 | * | ||
577 | * @param cls closure with handle to datastore | ||
578 | * @param size number of bytes we can transmit at most | ||
579 | * @param buf where to write transmission, NULL on | ||
580 | * timeout | ||
581 | * @return number of bytes copied to buf | ||
582 | */ | ||
583 | static size_t | ||
584 | transmit_get_result (void *cls, | ||
585 | size_t size, | ||
586 | void *buf) | ||
587 | { | ||
588 | struct GNUNET_DATASTORE_Handle *h = cls; | ||
589 | GNUNET_DATASTORE_Iterator cont = h->response_proc; | ||
590 | uint16_t msize; | ||
591 | |||
592 | if (buf == NULL) | ||
593 | { | ||
594 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
595 | _("Error transmitting message to datastore service.\n")); | ||
596 | h->response_proc = NULL; | ||
597 | h->message_size = 0; | ||
598 | cont (h->response_proc_cls, | ||
599 | NULL, 0, NULL, 0, 0, 0, | ||
600 | GNUNET_TIME_UNIT_ZERO_ABS, 0); | ||
601 | return 0; | ||
602 | } | ||
603 | msize = h->message_size; | ||
604 | GNUNET_assert (msize <= size); | ||
605 | memcpy (buf, &h[1], msize); | ||
606 | #if DEBUG_DATASTORE | ||
607 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
608 | "Transmitted %u byte message to datastore service, now waiting for result.\n", | ||
609 | msize); | ||
610 | #endif | ||
611 | h->message_size = 0; | ||
612 | GNUNET_CLIENT_receive (h->client, | ||
613 | &with_result_response_handler, | ||
614 | h, | ||
615 | GNUNET_TIME_absolute_get_remaining (h->timeout)); | ||
616 | return msize; | ||
617 | } | ||
618 | |||
619 | |||
620 | |||
621 | /** | ||
622 | * Function called to trigger obtaining the next result | 536 | * Function called to trigger obtaining the next result |
623 | * from the datastore. | 537 | * from the datastore. |
624 | * | 538 | * |
@@ -651,12 +565,10 @@ GNUNET_DATASTORE_get_next (struct GNUNET_DATASTORE_Handle *h, | |||
651 | 565 | ||
652 | 566 | ||
653 | /** | 567 | /** |
654 | * Helper function that will initiate the | 568 | * Helper function that will initiate the transmission of a message to |
655 | * transmission of a message to the datastore | 569 | * the datastore service. The message must already be prepared and |
656 | * service. The message must already be prepared | 570 | * stored in the buffer at the end of the handle. The message must be |
657 | * and stored in the buffer at the end of the | 571 | * of a type that expects a "DataMessage" in response. |
658 | * handle. The message must be of a type that | ||
659 | * expects a "DataMessage" in response. | ||
660 | * | 572 | * |
661 | * @param h handle to the service with prepared message | 573 | * @param h handle to the service with prepared message |
662 | * @param cont function to call with result | 574 | * @param cont function to call with result |
@@ -686,11 +598,13 @@ transmit_for_result (struct GNUNET_DATASTORE_Handle *h, | |||
686 | h->response_proc_cls = cont_cls; | 598 | h->response_proc_cls = cont_cls; |
687 | h->timeout = GNUNET_TIME_relative_to_absolute (timeout); | 599 | h->timeout = GNUNET_TIME_relative_to_absolute (timeout); |
688 | h->message_size = msize; | 600 | h->message_size = msize; |
689 | if (NULL == GNUNET_CLIENT_notify_transmit_ready (h->client, | 601 | if (GNUNET_OK != |
690 | msize, | 602 | GNUNET_CLIENT_transmit_and_get_response (h->client, |
691 | timeout, | 603 | hdr, |
692 | &transmit_get_result, | 604 | timeout, |
693 | h)) | 605 | GNUNET_YES, |
606 | &with_result_response_handler, | ||
607 | h)) | ||
694 | { | 608 | { |
695 | GNUNET_break (0); | 609 | GNUNET_break (0); |
696 | h->response_proc = NULL; | 610 | h->response_proc = NULL; |
diff --git a/src/datastore/perf_datastore_api.c b/src/datastore/perf_datastore_api.c index 1bee3ee57..e454e69f0 100644 --- a/src/datastore/perf_datastore_api.c +++ b/src/datastore/perf_datastore_api.c | |||
@@ -358,8 +358,8 @@ check () | |||
358 | struct GNUNET_GETOPT_CommandLineOption options[] = { | 358 | struct GNUNET_GETOPT_CommandLineOption options[] = { |
359 | GNUNET_GETOPT_OPTION_END | 359 | GNUNET_GETOPT_OPTION_END |
360 | }; | 360 | }; |
361 | pid = GNUNET_OS_start_process ("gnunet-service-datastore", | 361 | pid = GNUNET_OS_start_process ("gnunet-service-arm", |
362 | "gnunet-service-datastore", | 362 | "gnunet-service-arm", |
363 | #if VERBOSE | 363 | #if VERBOSE |
364 | "-L", "DEBUG", | 364 | "-L", "DEBUG", |
365 | #endif | 365 | #endif |
diff --git a/src/datastore/test_datastore_api.c b/src/datastore/test_datastore_api.c index a63f0425f..6a63e8e26 100644 --- a/src/datastore/test_datastore_api.c +++ b/src/datastore/test_datastore_api.c | |||
@@ -567,8 +567,8 @@ check () | |||
567 | struct GNUNET_GETOPT_CommandLineOption options[] = { | 567 | struct GNUNET_GETOPT_CommandLineOption options[] = { |
568 | GNUNET_GETOPT_OPTION_END | 568 | GNUNET_GETOPT_OPTION_END |
569 | }; | 569 | }; |
570 | pid = GNUNET_OS_start_process ("gnunet-service-datastore", | 570 | pid = GNUNET_OS_start_process ("gnunet-service-arm", |
571 | "gnunet-service-datastore", | 571 | "gnunet-service-arm", |
572 | #if VERBOSE | 572 | #if VERBOSE |
573 | "-L", "DEBUG", | 573 | "-L", "DEBUG", |
574 | #endif | 574 | #endif |
diff --git a/src/datastore/test_datastore_api_data.conf b/src/datastore/test_datastore_api_data.conf index 815bce0b8..a09bfae0e 100644 --- a/src/datastore/test_datastore_api_data.conf +++ b/src/datastore/test_datastore_api_data.conf | |||
@@ -1,5 +1,15 @@ | |||
1 | [PATHS] | 1 | [PATHS] |
2 | SERVICEHOME = /tmp/test-gnunetd-datastore/ | 2 | SERVICEHOME = /tmp/test-gnunetd-datastore/ |
3 | DEFAULTCONFIG = test_datastore_api_data.conf | ||
4 | |||
5 | [arm] | ||
6 | DEFAULTSERVICES = resolver | ||
7 | PORT = 42466 | ||
8 | HOSTNAME = localhost | ||
9 | |||
10 | [resolver] | ||
11 | PORT = 42464 | ||
12 | HOSTNAME = localhost | ||
3 | 13 | ||
4 | [datastore] | 14 | [datastore] |
5 | PORT = 22654 | 15 | PORT = 22654 |
@@ -21,3 +31,10 @@ DATABASE = sqlite | |||
21 | # REJECT_FROM = | 31 | # REJECT_FROM = |
22 | # REJECT_FROM6 = | 32 | # REJECT_FROM6 = |
23 | # PREFIX = | 33 | # PREFIX = |
34 | |||
35 | [statistics] | ||
36 | PORT = 22667 | ||
37 | HOSTNAME = localhost | ||
38 | |||
39 | [testing] | ||
40 | WEAKRANDOM = YES | ||
diff --git a/src/datastore/test_datastore_api_management.c b/src/datastore/test_datastore_api_management.c index 22d4aff25..c9fc9c8c5 100644 --- a/src/datastore/test_datastore_api_management.c +++ b/src/datastore/test_datastore_api_management.c | |||
@@ -335,8 +335,8 @@ check () | |||
335 | struct GNUNET_GETOPT_CommandLineOption options[] = { | 335 | struct GNUNET_GETOPT_CommandLineOption options[] = { |
336 | GNUNET_GETOPT_OPTION_END | 336 | GNUNET_GETOPT_OPTION_END |
337 | }; | 337 | }; |
338 | pid = GNUNET_OS_start_process ("gnunet-service-datastore", | 338 | pid = GNUNET_OS_start_process ("gnunet-service-arm", |
339 | "gnunet-service-datastore", | 339 | "gnunet-service-arm", |
340 | #if VERBOSE | 340 | #if VERBOSE |
341 | "-L", "DEBUG", | 341 | "-L", "DEBUG", |
342 | #endif | 342 | #endif |
diff --git a/src/fs/fs.h b/src/fs/fs.h index 8270d38ba..2cac304a3 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h | |||
@@ -950,7 +950,7 @@ struct GNUNET_FS_DownloadContext | |||
950 | * Non-NULL if we are currently having a request for | 950 | * Non-NULL if we are currently having a request for |
951 | * transmission pending with the client handle. | 951 | * transmission pending with the client handle. |
952 | */ | 952 | */ |
953 | struct GNUNET_CONNECTION_TransmitHandle *th; | 953 | struct GNUNET_CLIENT_TransmitHandle *th; |
954 | 954 | ||
955 | /** | 955 | /** |
956 | * Identity of the peer having the content, or all-zeros | 956 | * Identity of the peer having the content, or all-zeros |
diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c index 22b92aa09..e92eb85c1 100644 --- a/src/fs/fs_download.c +++ b/src/fs/fs_download.c | |||
@@ -239,6 +239,7 @@ schedule_block_download (struct GNUNET_FS_DownloadContext *dc, | |||
239 | dc->th = GNUNET_CLIENT_notify_transmit_ready (dc->client, | 239 | dc->th = GNUNET_CLIENT_notify_transmit_ready (dc->client, |
240 | sizeof (struct SearchMessage), | 240 | sizeof (struct SearchMessage), |
241 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | 241 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, |
242 | GNUNET_NO, | ||
242 | &transmit_download_request, | 243 | &transmit_download_request, |
243 | dc); | 244 | dc); |
244 | 245 | ||
@@ -366,7 +367,7 @@ process_result (struct GNUNET_FS_DownloadContext *dc, | |||
366 | /* abort all pending requests */ | 367 | /* abort all pending requests */ |
367 | if (NULL != dc->th) | 368 | if (NULL != dc->th) |
368 | { | 369 | { |
369 | GNUNET_CONNECTION_notify_transmit_ready_cancel (dc->th); | 370 | GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th); |
370 | dc->th = NULL; | 371 | dc->th = NULL; |
371 | } | 372 | } |
372 | GNUNET_CLIENT_disconnect (dc->client); | 373 | GNUNET_CLIENT_disconnect (dc->client); |
@@ -432,7 +433,7 @@ process_result (struct GNUNET_FS_DownloadContext *dc, | |||
432 | /* abort all pending requests */ | 433 | /* abort all pending requests */ |
433 | if (NULL != dc->th) | 434 | if (NULL != dc->th) |
434 | { | 435 | { |
435 | GNUNET_CONNECTION_notify_transmit_ready_cancel (dc->th); | 436 | GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th); |
436 | dc->th = NULL; | 437 | dc->th = NULL; |
437 | } | 438 | } |
438 | GNUNET_CLIENT_disconnect (dc->client); | 439 | GNUNET_CLIENT_disconnect (dc->client); |
@@ -618,6 +619,7 @@ transmit_download_request (void *cls, | |||
618 | dc->th = GNUNET_CLIENT_notify_transmit_ready (dc->client, | 619 | dc->th = GNUNET_CLIENT_notify_transmit_ready (dc->client, |
619 | sizeof (struct SearchMessage), | 620 | sizeof (struct SearchMessage), |
620 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | 621 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, |
622 | GNUNET_NO, | ||
621 | &transmit_download_request, | 623 | &transmit_download_request, |
622 | dc); | 624 | dc); |
623 | return msize; | 625 | return msize; |
@@ -654,6 +656,7 @@ do_reconnect (void *cls, | |||
654 | dc->th = GNUNET_CLIENT_notify_transmit_ready (client, | 656 | dc->th = GNUNET_CLIENT_notify_transmit_ready (client, |
655 | sizeof (struct SearchMessage), | 657 | sizeof (struct SearchMessage), |
656 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | 658 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, |
659 | GNUNET_NO, | ||
657 | &transmit_download_request, | 660 | &transmit_download_request, |
658 | dc); | 661 | dc); |
659 | GNUNET_CLIENT_receive (client, | 662 | GNUNET_CLIENT_receive (client, |
@@ -704,7 +707,7 @@ try_reconnect (struct GNUNET_FS_DownloadContext *dc) | |||
704 | { | 707 | { |
705 | if (NULL != dc->th) | 708 | if (NULL != dc->th) |
706 | { | 709 | { |
707 | GNUNET_CONNECTION_notify_transmit_ready_cancel (dc->th); | 710 | GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th); |
708 | dc->th = NULL; | 711 | dc->th = NULL; |
709 | } | 712 | } |
710 | GNUNET_CONTAINER_multihashmap_iterate (dc->active, | 713 | GNUNET_CONTAINER_multihashmap_iterate (dc->active, |
@@ -892,7 +895,7 @@ GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, | |||
892 | dc->task); | 895 | dc->task); |
893 | if (NULL != dc->th) | 896 | if (NULL != dc->th) |
894 | { | 897 | { |
895 | GNUNET_CONNECTION_notify_transmit_ready_cancel (dc->th); | 898 | GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th); |
896 | dc->th = NULL; | 899 | dc->th = NULL; |
897 | } | 900 | } |
898 | if (NULL != dc->client) | 901 | if (NULL != dc->client) |
diff --git a/src/fs/fs_list_indexed.c b/src/fs/fs_list_indexed.c index 1a404a078..9ef205ca0 100644 --- a/src/fs/fs_list_indexed.c +++ b/src/fs/fs_list_indexed.c | |||
@@ -155,50 +155,6 @@ handle_index_info (void *cls, | |||
155 | 155 | ||
156 | 156 | ||
157 | /** | 157 | /** |
158 | * Transmit the request to get a list of all | ||
159 | * indexed files to the "FS" service. | ||
160 | * | ||
161 | * @param cls closure (of type "struct GetIndexedContext*") | ||
162 | * @param size number of bytes availabe in buf | ||
163 | * @param buf where to write the message, NULL on error | ||
164 | * @return number of bytes written to buf | ||
165 | */ | ||
166 | static size_t | ||
167 | transmit_get_indexed (void *cls, | ||
168 | size_t size, | ||
169 | void *buf) | ||
170 | { | ||
171 | struct GetIndexedContext *gic = cls; | ||
172 | struct GNUNET_MessageHeader *hdr; | ||
173 | |||
174 | if (NULL == buf) | ||
175 | { | ||
176 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
177 | _("Failed to transmit `%s' request to `%s' service.\n"), | ||
178 | "GET_INDEXED", | ||
179 | "fs"); | ||
180 | GNUNET_SCHEDULER_add_continuation (gic->h->sched, | ||
181 | GNUNET_NO, | ||
182 | gic->cont, | ||
183 | gic->cont_cls, | ||
184 | GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
185 | GNUNET_CLIENT_disconnect (gic->client); | ||
186 | GNUNET_free (gic); | ||
187 | return 0; | ||
188 | } | ||
189 | GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); | ||
190 | hdr = buf; | ||
191 | hdr->size = htons (sizeof (struct GNUNET_MessageHeader)); | ||
192 | hdr->type = htons (GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET); | ||
193 | GNUNET_CLIENT_receive (gic->client, | ||
194 | &handle_index_info, | ||
195 | gic, | ||
196 | GNUNET_CONSTANTS_SERVICE_TIMEOUT); | ||
197 | return sizeof (struct GNUNET_MessageHeader); | ||
198 | } | ||
199 | |||
200 | |||
201 | /** | ||
202 | * Iterate over all indexed files. | 158 | * Iterate over all indexed files. |
203 | * | 159 | * |
204 | * @param h handle to the file sharing subsystem | 160 | * @param h handle to the file sharing subsystem |
@@ -218,6 +174,7 @@ GNUNET_FS_get_indexed_files (struct GNUNET_FS_Handle *h, | |||
218 | { | 174 | { |
219 | struct GNUNET_CLIENT_Connection *client; | 175 | struct GNUNET_CLIENT_Connection *client; |
220 | struct GetIndexedContext *gic; | 176 | struct GetIndexedContext *gic; |
177 | struct GNUNET_MessageHeader msg; | ||
221 | 178 | ||
222 | client = GNUNET_CLIENT_connect (h->sched, | 179 | client = GNUNET_CLIENT_connect (h->sched, |
223 | "fs", | 180 | "fs", |
@@ -242,11 +199,15 @@ GNUNET_FS_get_indexed_files (struct GNUNET_FS_Handle *h, | |||
242 | gic->iterator_cls = iterator_cls; | 199 | gic->iterator_cls = iterator_cls; |
243 | gic->cont = cont; | 200 | gic->cont = cont; |
244 | gic->cont_cls = cont_cls; | 201 | gic->cont_cls = cont_cls; |
245 | GNUNET_CLIENT_notify_transmit_ready (client, | 202 | msg.size = htons (sizeof (struct GNUNET_MessageHeader)); |
246 | sizeof (struct GNUNET_MessageHeader), | 203 | msg.type = htons (GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET); |
247 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | 204 | GNUNET_assert (GNUNET_OK == |
248 | &transmit_get_indexed, | 205 | GNUNET_CLIENT_transmit_and_get_response (client, |
249 | gic); | 206 | &msg, |
207 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | ||
208 | GNUNET_YES, | ||
209 | &handle_index_info, | ||
210 | gic)); | ||
250 | } | 211 | } |
251 | 212 | ||
252 | /* end of fs_list_indexed.c */ | 213 | /* end of fs_list_indexed.c */ |
diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c index 3501416ad..34a13f55c 100644 --- a/src/fs/fs_publish.c +++ b/src/fs/fs_publish.c | |||
@@ -783,6 +783,7 @@ hash_for_index_cb (void *cls, | |||
783 | GNUNET_CLIENT_transmit_and_get_response (client, | 783 | GNUNET_CLIENT_transmit_and_get_response (client, |
784 | &ism->header, | 784 | &ism->header, |
785 | GNUNET_TIME_UNIT_FOREVER_REL, | 785 | GNUNET_TIME_UNIT_FOREVER_REL, |
786 | GNUNET_YES, | ||
786 | &process_index_start_response, | 787 | &process_index_start_response, |
787 | sc); | 788 | sc); |
788 | GNUNET_free (ism); | 789 | GNUNET_free (ism); |
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c index ae681577f..94b8b2082 100644 --- a/src/fs/fs_search.c +++ b/src/fs/fs_search.c | |||
@@ -694,6 +694,7 @@ do_reconnect (void *cls, | |||
694 | GNUNET_CLIENT_notify_transmit_ready (client, | 694 | GNUNET_CLIENT_notify_transmit_ready (client, |
695 | size, | 695 | size, |
696 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | 696 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, |
697 | GNUNET_NO, | ||
697 | &transmit_search_request, | 698 | &transmit_search_request, |
698 | sc); | 699 | sc); |
699 | } | 700 | } |
@@ -812,6 +813,7 @@ search_start (struct GNUNET_FS_Handle *h, | |||
812 | GNUNET_CLIENT_notify_transmit_ready (client, | 813 | GNUNET_CLIENT_notify_transmit_ready (client, |
813 | size, | 814 | size, |
814 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | 815 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, |
816 | GNUNET_NO, | ||
815 | &transmit_search_request, | 817 | &transmit_search_request, |
816 | sc); | 818 | sc); |
817 | return sc; | 819 | return sc; |
diff --git a/src/fs/fs_unindex.c b/src/fs/fs_unindex.c index 4a57c7d59..0374e1db2 100644 --- a/src/fs/fs_unindex.c +++ b/src/fs/fs_unindex.c | |||
@@ -379,6 +379,7 @@ process_hash (void *cls, | |||
379 | GNUNET_CLIENT_transmit_and_get_response (uc->client, | 379 | GNUNET_CLIENT_transmit_and_get_response (uc->client, |
380 | &req.header, | 380 | &req.header, |
381 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, | 381 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, |
382 | GNUNET_YES, | ||
382 | &process_fs_response, | 383 | &process_fs_response, |
383 | uc); | 384 | uc); |
384 | } | 385 | } |
diff --git a/src/include/gnunet_client_lib.h b/src/include/gnunet_client_lib.h index 20842de5c..c78df41c7 100644 --- a/src/include/gnunet_client_lib.h +++ b/src/include/gnunet_client_lib.h | |||
@@ -97,6 +97,12 @@ void GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *sock, | |||
97 | 97 | ||
98 | 98 | ||
99 | /** | 99 | /** |
100 | * Transmit handle for client connections. | ||
101 | */ | ||
102 | struct GNUNET_CLIENT_TransmitHandle; | ||
103 | |||
104 | |||
105 | /** | ||
100 | * Ask the client to call us once the specified number of bytes | 106 | * Ask the client to call us once the specified number of bytes |
101 | * are free in the transmission buffer. May call the notify | 107 | * are free in the transmission buffer. May call the notify |
102 | * method immediately if enough space is available. | 108 | * method immediately if enough space is available. |
@@ -105,20 +111,35 @@ void GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *sock, | |||
105 | * @param size number of bytes to send | 111 | * @param size number of bytes to send |
106 | * @param timeout after how long should we give up (and call | 112 | * @param timeout after how long should we give up (and call |
107 | * notify with buf NULL and size 0)? | 113 | * notify with buf NULL and size 0)? |
114 | * @param auto_retry if the connection to the service dies, should we | ||
115 | * automatically re-connect and retry (within the timeout period) | ||
116 | * or should we immediately fail in this case? Pass GNUNET_YES | ||
117 | * if the caller does not care about temporary connection errors, | ||
118 | * for example because the protocol is stateless | ||
108 | * @param notify function to call | 119 | * @param notify function to call |
109 | * @param notify_cls closure for notify | 120 | * @param notify_cls closure for notify |
110 | * @return NULL if someone else is already waiting to be notified | 121 | * @return NULL if someone else is already waiting to be notified |
111 | * non-NULL if the notify callback was queued (can be used to cancel | 122 | * non-NULL if the notify callback was queued (can be used to cancel |
112 | * using GNUNET_CONNECTION_notify_transmit_ready_cancel) | 123 | * using GNUNET_CONNECTION_notify_transmit_ready_cancel) |
113 | */ | 124 | */ |
114 | struct GNUNET_CONNECTION_TransmitHandle | 125 | struct GNUNET_CLIENT_TransmitHandle |
115 | *GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock, | 126 | *GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock, |
116 | size_t size, | 127 | size_t size, |
117 | struct GNUNET_TIME_Relative timeout, | 128 | struct GNUNET_TIME_Relative timeout, |
129 | int auto_retry, | ||
118 | GNUNET_CONNECTION_TransmitReadyNotify | 130 | GNUNET_CONNECTION_TransmitReadyNotify |
119 | notify, void *notify_cls); | 131 | notify, |
132 | void *notify_cls); | ||
120 | 133 | ||
121 | 134 | ||
135 | /** | ||
136 | * Cancel a request for notification. | ||
137 | * | ||
138 | * @param th handle from the original request. | ||
139 | */ | ||
140 | void | ||
141 | GNUNET_CLIENT_notify_transmit_ready_cancel (struct GNUNET_CLIENT_TransmitHandle *th); | ||
142 | |||
122 | 143 | ||
123 | /** | 144 | /** |
124 | * Convenience API that combines sending a request | 145 | * Convenience API that combines sending a request |
@@ -131,13 +152,21 @@ struct GNUNET_CONNECTION_TransmitHandle | |||
131 | * @param hdr message to transmit | 152 | * @param hdr message to transmit |
132 | * @param timeout when to give up (for both transmission | 153 | * @param timeout when to give up (for both transmission |
133 | * and for waiting for a response) | 154 | * and for waiting for a response) |
155 | * @param auto_retry if the connection to the service dies, should we | ||
156 | * automatically re-connect and retry (within the timeout period) | ||
157 | * or should we immediately fail in this case? Pass GNUNET_YES | ||
158 | * if the caller does not care about temporary connection errors, | ||
159 | * for example because the protocol is stateless | ||
134 | * @param rn function to call with the response | 160 | * @param rn function to call with the response |
135 | * @param rn_cls closure for rn | 161 | * @param rn_cls closure for rn |
162 | * @return GNUNET_OK on success, GNUNET_SYSERR if a request | ||
163 | * is already pending | ||
136 | */ | 164 | */ |
137 | void | 165 | int |
138 | GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *sock, | 166 | GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *sock, |
139 | const struct GNUNET_MessageHeader *hdr, | 167 | const struct GNUNET_MessageHeader *hdr, |
140 | struct GNUNET_TIME_Relative timeout, | 168 | struct GNUNET_TIME_Relative timeout, |
169 | int auto_retry, | ||
141 | GNUNET_CLIENT_MessageHandler rn, | 170 | GNUNET_CLIENT_MessageHandler rn, |
142 | void *rn_cls); | 171 | void *rn_cls); |
143 | 172 | ||
diff --git a/src/peerinfo/peerinfo_api.c b/src/peerinfo/peerinfo_api.c index 14efa1708..d02ec3f2d 100644 --- a/src/peerinfo/peerinfo_api.c +++ b/src/peerinfo/peerinfo_api.c | |||
@@ -106,7 +106,9 @@ GNUNET_PEERINFO_add_peer (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
106 | cc->msg = &pam->header; | 106 | cc->msg = &pam->header; |
107 | GNUNET_CLIENT_notify_transmit_ready (client, | 107 | GNUNET_CLIENT_notify_transmit_ready (client, |
108 | ntohs (pam->header.size), | 108 | ntohs (pam->header.size), |
109 | ADD_PEER_TIMEOUT, ©_and_free, cc); | 109 | ADD_PEER_TIMEOUT, |
110 | GNUNET_YES, | ||
111 | ©_and_free, cc); | ||
110 | } | 112 | } |
111 | 113 | ||
112 | 114 | ||
@@ -203,36 +205,6 @@ info_handler (void *cls, const struct GNUNET_MessageHeader *msg) | |||
203 | } | 205 | } |
204 | 206 | ||
205 | 207 | ||
206 | static size_t | ||
207 | copy_then_receive (void *cls, size_t size, void *buf) | ||
208 | { | ||
209 | struct InfoContext *ic = cls; | ||
210 | const struct GNUNET_MessageHeader *msg = | ||
211 | (const struct GNUNET_MessageHeader *) &ic[1]; | ||
212 | uint16_t msize; | ||
213 | |||
214 | if (buf == NULL) | ||
215 | { | ||
216 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
217 | _ | ||
218 | ("Failed to transmit message of type %u to `%s' service.\n"), | ||
219 | ntohs (msg->type), "peerinfo"); | ||
220 | ic->callback (ic->callback_cls, NULL, NULL, 1); | ||
221 | GNUNET_CLIENT_disconnect (ic->client); | ||
222 | GNUNET_free (ic); | ||
223 | return 0; | ||
224 | } | ||
225 | msize = ntohs (msg->size); | ||
226 | GNUNET_assert (size >= msize); | ||
227 | memcpy (buf, msg, msize); | ||
228 | GNUNET_CLIENT_receive (ic->client, | ||
229 | &info_handler, | ||
230 | ic, | ||
231 | GNUNET_TIME_absolute_get_remaining (ic->timeout)); | ||
232 | return msize; | ||
233 | } | ||
234 | |||
235 | |||
236 | /** | 208 | /** |
237 | * Call a method for each known matching host and change | 209 | * Call a method for each known matching host and change |
238 | * its trust value. The method will be invoked once for | 210 | * its trust value. The method will be invoked once for |
@@ -293,8 +265,20 @@ GNUNET_PEERINFO_for_all (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
293 | lpm->trust_change = htonl (trust_delta); | 265 | lpm->trust_change = htonl (trust_delta); |
294 | memcpy (&lpm->peer, peer, sizeof (struct GNUNET_PeerIdentity)); | 266 | memcpy (&lpm->peer, peer, sizeof (struct GNUNET_PeerIdentity)); |
295 | } | 267 | } |
296 | GNUNET_CLIENT_notify_transmit_ready (client, | 268 | if (GNUNET_OK != |
297 | hs, timeout, ©_then_receive, ihc); | 269 | GNUNET_CLIENT_transmit_and_get_response (client, |
270 | (const struct GNUNET_MessageHeader*) &ihc[1], | ||
271 | timeout, | ||
272 | GNUNET_YES, | ||
273 | &info_handler, | ||
274 | ihc)) | ||
275 | { | ||
276 | GNUNET_break (0); | ||
277 | ihc->callback (ihc->callback_cls, NULL, NULL, 1); | ||
278 | GNUNET_CLIENT_disconnect (ihc->client); | ||
279 | GNUNET_free (ihc); | ||
280 | return; | ||
281 | } | ||
298 | } | 282 | } |
299 | 283 | ||
300 | /* end of peerinfo_api.c */ | 284 | /* end of peerinfo_api.c */ |
diff --git a/src/statistics/statistics_api.c b/src/statistics/statistics_api.c index 21b8ecd8a..cc0a1b11a 100644 --- a/src/statistics/statistics_api.c +++ b/src/statistics/statistics_api.c | |||
@@ -539,7 +539,9 @@ schedule_action (struct GNUNET_STATISTICS_Handle *h) | |||
539 | if (NULL == | 539 | if (NULL == |
540 | GNUNET_CLIENT_notify_transmit_ready (h->client, | 540 | GNUNET_CLIENT_notify_transmit_ready (h->client, |
541 | h->current->msize, | 541 | h->current->msize, |
542 | timeout, &transmit_action, h)) | 542 | timeout, |
543 | GNUNET_YES, | ||
544 | &transmit_action, h)) | ||
543 | { | 545 | { |
544 | #if DEBUG_STATISTICS | 546 | #if DEBUG_STATISTICS |
545 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 547 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
diff --git a/src/transport/transport_api.c b/src/transport/transport_api.c index 0ddd3b86b..7ffff30d9 100644 --- a/src/transport/transport_api.c +++ b/src/transport/transport_api.c | |||
@@ -278,7 +278,7 @@ struct GNUNET_TRANSPORT_Handle | |||
278 | /** | 278 | /** |
279 | * Handle to our registration with the client for notification. | 279 | * Handle to our registration with the client for notification. |
280 | */ | 280 | */ |
281 | struct GNUNET_CONNECTION_TransmitHandle *network_handle; | 281 | struct GNUNET_CLIENT_TransmitHandle *network_handle; |
282 | 282 | ||
283 | /** | 283 | /** |
284 | * Linked list of transmit handles that are waiting for the | 284 | * Linked list of transmit handles that are waiting for the |
@@ -477,6 +477,7 @@ schedule_transmission (struct GNUNET_TRANSPORT_Handle *h) | |||
477 | th->notify_size, | 477 | th->notify_size, |
478 | GNUNET_TIME_absolute_get_remaining | 478 | GNUNET_TIME_absolute_get_remaining |
479 | (th->timeout), | 479 | (th->timeout), |
480 | GNUNET_NO, | ||
480 | &transport_notify_ready, | 481 | &transport_notify_ready, |
481 | h); | 482 | h); |
482 | GNUNET_assert (NULL != h->network_handle); | 483 | GNUNET_assert (NULL != h->network_handle); |
@@ -1596,7 +1597,7 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) | |||
1596 | #endif | 1597 | #endif |
1597 | if (h->network_handle != NULL) | 1598 | if (h->network_handle != NULL) |
1598 | { | 1599 | { |
1599 | GNUNET_CONNECTION_notify_transmit_ready_cancel (h->network_handle); | 1600 | GNUNET_CLIENT_notify_transmit_ready_cancel (h->network_handle); |
1600 | h->network_handle = NULL; | 1601 | h->network_handle = NULL; |
1601 | h->transmission_scheduled = GNUNET_NO; | 1602 | h->transmission_scheduled = GNUNET_NO; |
1602 | th = h->connect_ready_head; | 1603 | th = h->connect_ready_head; |
@@ -1986,7 +1987,7 @@ GNUNET_TRANSPORT_notify_transmit_ready_cancel (struct | |||
1986 | h = th->handle; | 1987 | h = th->handle; |
1987 | if ((h->connect_ready_head == NULL) && (h->network_handle != NULL)) | 1988 | if ((h->connect_ready_head == NULL) && (h->network_handle != NULL)) |
1988 | { | 1989 | { |
1989 | GNUNET_CONNECTION_notify_transmit_ready_cancel (h->network_handle); | 1990 | GNUNET_CLIENT_notify_transmit_ready_cancel (h->network_handle); |
1990 | h->network_handle = NULL; | 1991 | h->network_handle = NULL; |
1991 | h->transmission_scheduled = GNUNET_NO; | 1992 | h->transmission_scheduled = GNUNET_NO; |
1992 | } | 1993 | } |
diff --git a/src/util/client.c b/src/util/client.c index bdb258b73..75d90b074 100644 --- a/src/util/client.c +++ b/src/util/client.c | |||
@@ -36,6 +36,14 @@ | |||
36 | 36 | ||
37 | #define DEBUG_CLIENT GNUNET_NO | 37 | #define DEBUG_CLIENT GNUNET_NO |
38 | 38 | ||
39 | |||
40 | /** | ||
41 | * How often do we re-try tranmsitting requests before giving up? | ||
42 | * Note that if we succeeded transmitting a request but failed to read | ||
43 | * a response, we do NOT re-try. | ||
44 | */ | ||
45 | #define MAX_ATTEMPTS 10 | ||
46 | |||
39 | /** | 47 | /** |
40 | * Struct to refer to a GNUnet TCP connection. | 48 | * Struct to refer to a GNUnet TCP connection. |
41 | * This is more than just a socket because if the server | 49 | * This is more than just a socket because if the server |
@@ -56,6 +64,11 @@ struct GNUNET_CLIENT_Connection | |||
56 | struct GNUNET_SCHEDULER_Handle *sched; | 64 | struct GNUNET_SCHEDULER_Handle *sched; |
57 | 65 | ||
58 | /** | 66 | /** |
67 | * Our configuration. | ||
68 | */ | ||
69 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
70 | |||
71 | /** | ||
59 | * Name of the service we interact with. | 72 | * Name of the service we interact with. |
60 | */ | 73 | */ |
61 | char *service_name; | 74 | char *service_name; |
@@ -116,20 +129,11 @@ struct GNUNET_CLIENT_Connection | |||
116 | }; | 129 | }; |
117 | 130 | ||
118 | 131 | ||
119 | /** | 132 | static struct GNUNET_CONNECTION_Handle * |
120 | * Get a connection with a service. | 133 | do_connect (struct GNUNET_SCHEDULER_Handle *sched, |
121 | * | 134 | const char *service_name, |
122 | * @param sched scheduler to use | 135 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
123 | * @param service_name name of the service | ||
124 | * @param cfg configuration to use | ||
125 | * @return NULL on error (service unknown to configuration) | ||
126 | */ | ||
127 | struct GNUNET_CLIENT_Connection * | ||
128 | GNUNET_CLIENT_connect (struct GNUNET_SCHEDULER_Handle *sched, | ||
129 | const char *service_name, | ||
130 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
131 | { | 136 | { |
132 | struct GNUNET_CLIENT_Connection *ret; | ||
133 | struct GNUNET_CONNECTION_Handle *sock; | 137 | struct GNUNET_CONNECTION_Handle *sock; |
134 | char *hostname; | 138 | char *hostname; |
135 | unsigned long long port; | 139 | unsigned long long port; |
@@ -164,12 +168,34 @@ GNUNET_CLIENT_connect (struct GNUNET_SCHEDULER_Handle *sched, | |||
164 | port, | 168 | port, |
165 | GNUNET_SERVER_MAX_MESSAGE_SIZE); | 169 | GNUNET_SERVER_MAX_MESSAGE_SIZE); |
166 | GNUNET_free (hostname); | 170 | GNUNET_free (hostname); |
171 | return sock; | ||
172 | } | ||
173 | |||
174 | |||
175 | /** | ||
176 | * Get a connection with a service. | ||
177 | * | ||
178 | * @param sched scheduler to use | ||
179 | * @param service_name name of the service | ||
180 | * @param cfg configuration to use | ||
181 | * @return NULL on error (service unknown to configuration) | ||
182 | */ | ||
183 | struct GNUNET_CLIENT_Connection * | ||
184 | GNUNET_CLIENT_connect (struct GNUNET_SCHEDULER_Handle *sched, | ||
185 | const char *service_name, | ||
186 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
187 | { | ||
188 | struct GNUNET_CLIENT_Connection *ret; | ||
189 | struct GNUNET_CONNECTION_Handle *sock; | ||
190 | |||
191 | sock = do_connect (sched, service_name, cfg); | ||
167 | if (sock == NULL) | 192 | if (sock == NULL) |
168 | return NULL; | 193 | return NULL; |
169 | ret = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_Connection)); | 194 | ret = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_Connection)); |
170 | ret->sock = sock; | 195 | ret->sock = sock; |
171 | ret->sched = sched; | 196 | ret->sched = sched; |
172 | ret->service_name = GNUNET_strdup (service_name); | 197 | ret->service_name = GNUNET_strdup (service_name); |
198 | ret->cfg = cfg; | ||
173 | return ret; | 199 | return ret; |
174 | } | 200 | } |
175 | 201 | ||
@@ -521,6 +547,171 @@ GNUNET_CLIENT_service_test (struct GNUNET_SCHEDULER_Handle *sched, | |||
521 | 547 | ||
522 | 548 | ||
523 | /** | 549 | /** |
550 | * Handle for a transmission request. | ||
551 | */ | ||
552 | struct GNUNET_CLIENT_TransmitHandle | ||
553 | { | ||
554 | /** | ||
555 | * Connection state. | ||
556 | */ | ||
557 | struct GNUNET_CLIENT_Connection *sock; | ||
558 | |||
559 | /** | ||
560 | * Function to call to get the data for transmission. | ||
561 | */ | ||
562 | GNUNET_CONNECTION_TransmitReadyNotify notify; | ||
563 | |||
564 | /** | ||
565 | * Closure for notify. | ||
566 | */ | ||
567 | void *notify_cls; | ||
568 | |||
569 | /** | ||
570 | * Handle to the transmission with the underlying | ||
571 | * connection. | ||
572 | */ | ||
573 | struct GNUNET_CONNECTION_TransmitHandle *th; | ||
574 | |||
575 | /** | ||
576 | * Timeout. | ||
577 | */ | ||
578 | struct GNUNET_TIME_Absolute timeout; | ||
579 | |||
580 | /** | ||
581 | * If we are re-trying and are delaying to do so, | ||
582 | * handle to the scheduled task managing the delay. | ||
583 | */ | ||
584 | GNUNET_SCHEDULER_TaskIdentifier task; | ||
585 | |||
586 | /** | ||
587 | * Number of bytes requested. | ||
588 | */ | ||
589 | size_t size; | ||
590 | |||
591 | /** | ||
592 | * Are we allowed to re-try to connect without telling | ||
593 | * the user (of this API) about the connection troubles? | ||
594 | */ | ||
595 | int auto_retry; | ||
596 | |||
597 | /** | ||
598 | * Number of attempts left for transmitting the request. We may | ||
599 | * fail the first time (say because the service is not yet up), in | ||
600 | * which case (if auto_retry is set) we wait a bit and re-try | ||
601 | * (timeout permitting). | ||
602 | */ | ||
603 | unsigned int attempts_left; | ||
604 | |||
605 | }; | ||
606 | |||
607 | |||
608 | |||
609 | /** | ||
610 | * Connection notifies us about failure or success of | ||
611 | * a transmission request. Either pass it on to our | ||
612 | * user or, if possible, retry. | ||
613 | * | ||
614 | * @param cls our "struct GNUNET_CLIENT_TransmissionHandle" | ||
615 | * @param size number of bytes available for transmission | ||
616 | * @param buf where to write them | ||
617 | * @return number of bytes written to buf | ||
618 | */ | ||
619 | static size_t | ||
620 | client_notify (void *cls, | ||
621 | size_t size, | ||
622 | void *buf); | ||
623 | |||
624 | |||
625 | |||
626 | /** | ||
627 | * This task is run if we should re-try connection to the | ||
628 | * service after a while. | ||
629 | * | ||
630 | * @param cls our "struct GNUNET_CLIENT_TransmitHandle" of the request | ||
631 | * @param tc unused | ||
632 | */ | ||
633 | static void | ||
634 | client_delayed_retry (void *cls, | ||
635 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
636 | { | ||
637 | struct GNUNET_CLIENT_TransmitHandle *th = cls; | ||
638 | |||
639 | th->task = GNUNET_SCHEDULER_NO_TASK; | ||
640 | th->sock->sock = do_connect (th->sock->sched, | ||
641 | th->sock->service_name, | ||
642 | th->sock->cfg); | ||
643 | th->th = GNUNET_CONNECTION_notify_transmit_ready (th->sock->sock, | ||
644 | th->size, | ||
645 | GNUNET_TIME_absolute_get_remaining (th->timeout), | ||
646 | &client_notify, | ||
647 | th); | ||
648 | if (th->th == NULL) | ||
649 | { | ||
650 | GNUNET_break (0); | ||
651 | th->notify (th->notify_cls, 0, NULL); | ||
652 | GNUNET_free (th); | ||
653 | return; | ||
654 | } | ||
655 | } | ||
656 | |||
657 | |||
658 | /** | ||
659 | * Connection notifies us about failure or success of | ||
660 | * a transmission request. Either pass it on to our | ||
661 | * user or, if possible, retry. | ||
662 | * | ||
663 | * @param cls our "struct GNUNET_CLIENT_TransmissionHandle" | ||
664 | * @param size number of bytes available for transmission | ||
665 | * @param buf where to write them | ||
666 | * @return number of bytes written to buf | ||
667 | */ | ||
668 | static size_t | ||
669 | client_notify (void *cls, | ||
670 | size_t size, | ||
671 | void *buf) | ||
672 | { | ||
673 | struct GNUNET_CLIENT_TransmitHandle *th = cls; | ||
674 | size_t ret; | ||
675 | struct GNUNET_TIME_Relative delay; | ||
676 | |||
677 | if (buf == NULL) | ||
678 | { | ||
679 | delay = GNUNET_TIME_absolute_get_remaining (th->timeout); | ||
680 | delay.value /= 2; | ||
681 | if ( (GNUNET_YES != th->auto_retry) || | ||
682 | (0 == --th->attempts_left) || | ||
683 | (delay.value < 1) ) | ||
684 | { | ||
685 | GNUNET_break (0 == th->notify (th->notify_cls, | ||
686 | 0, | ||
687 | NULL)); | ||
688 | GNUNET_free (th); | ||
689 | return 0; | ||
690 | } | ||
691 | /* auto-retry */ | ||
692 | GNUNET_CONNECTION_destroy (th->sock->sock); | ||
693 | th->sock->sock = NULL; | ||
694 | th->th = NULL; | ||
695 | delay = GNUNET_TIME_relative_min (delay, GNUNET_TIME_UNIT_SECONDS); | ||
696 | th->task = GNUNET_SCHEDULER_add_delayed (th->sock->sched, | ||
697 | GNUNET_NO, | ||
698 | GNUNET_SCHEDULER_PRIORITY_KEEP, | ||
699 | GNUNET_SCHEDULER_NO_TASK, | ||
700 | delay, | ||
701 | &client_delayed_retry, | ||
702 | th); | ||
703 | return 0; | ||
704 | } | ||
705 | GNUNET_assert (size >= th->size); | ||
706 | ret = th->notify (th->notify_cls, | ||
707 | size, | ||
708 | buf); | ||
709 | GNUNET_free (th); | ||
710 | return ret; | ||
711 | } | ||
712 | |||
713 | |||
714 | /** | ||
524 | * Ask the client to call us once the specified number of bytes | 715 | * Ask the client to call us once the specified number of bytes |
525 | * are free in the transmission buffer. May call the notify | 716 | * are free in the transmission buffer. May call the notify |
526 | * method immediately if enough space is available. | 717 | * method immediately if enough space is available. |
@@ -529,21 +720,65 @@ GNUNET_CLIENT_service_test (struct GNUNET_SCHEDULER_Handle *sched, | |||
529 | * @param size number of bytes to send | 720 | * @param size number of bytes to send |
530 | * @param timeout after how long should we give up (and call | 721 | * @param timeout after how long should we give up (and call |
531 | * notify with buf NULL and size 0)? | 722 | * notify with buf NULL and size 0)? |
723 | * @param auto_retry if the connection to the service dies, should we | ||
724 | * automatically re-connect and retry (within the timeout period) | ||
725 | * or should we immediately fail in this case? Pass GNUNET_YES | ||
726 | * if the caller does not care about temporary connection errors, | ||
727 | * for example because the protocol is stateless | ||
532 | * @param notify function to call | 728 | * @param notify function to call |
533 | * @param notify_cls closure for notify | 729 | * @param notify_cls closure for notify |
534 | * @return NULL if our buffer will never hold size bytes, | 730 | * @return NULL if our buffer will never hold size bytes, |
535 | * a handle if the notify callback was queued (can be used to cancel) | 731 | * a handle if the notify callback was queued (can be used to cancel) |
536 | */ | 732 | */ |
537 | struct GNUNET_CONNECTION_TransmitHandle * | 733 | struct GNUNET_CLIENT_TransmitHandle * |
538 | GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock, | 734 | GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock, |
539 | size_t size, | 735 | size_t size, |
540 | struct GNUNET_TIME_Relative timeout, | 736 | struct GNUNET_TIME_Relative timeout, |
737 | int auto_retry, | ||
541 | GNUNET_CONNECTION_TransmitReadyNotify | 738 | GNUNET_CONNECTION_TransmitReadyNotify |
542 | notify, void *notify_cls) | 739 | notify, void *notify_cls) |
543 | { | 740 | { |
544 | return GNUNET_CONNECTION_notify_transmit_ready (sock->sock, | 741 | struct GNUNET_CLIENT_TransmitHandle *th; |
545 | size, | 742 | |
546 | timeout, notify, notify_cls); | 743 | th = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_TransmitHandle)); |
744 | th->sock = sock; | ||
745 | th->size = size; | ||
746 | th->timeout = GNUNET_TIME_relative_to_absolute (timeout); | ||
747 | th->auto_retry = auto_retry; | ||
748 | th->notify = notify; | ||
749 | th->notify_cls = notify_cls; | ||
750 | th->attempts_left = MAX_ATTEMPTS; | ||
751 | th->th = GNUNET_CONNECTION_notify_transmit_ready (sock->sock, | ||
752 | size, | ||
753 | timeout, | ||
754 | &client_notify, | ||
755 | th); | ||
756 | if (NULL == th->th) | ||
757 | { | ||
758 | GNUNET_free (th); | ||
759 | return NULL; | ||
760 | } | ||
761 | return th; | ||
762 | } | ||
763 | |||
764 | |||
765 | /** | ||
766 | * Cancel a request for notification. | ||
767 | * | ||
768 | * @param th handle from the original request. | ||
769 | */ | ||
770 | void | ||
771 | GNUNET_CLIENT_notify_transmit_ready_cancel (struct GNUNET_CLIENT_TransmitHandle *th) | ||
772 | { | ||
773 | if (th->task != GNUNET_SCHEDULER_NO_TASK) | ||
774 | GNUNET_SCHEDULER_cancel (th->sock->sched, | ||
775 | th->task); | ||
776 | else | ||
777 | { | ||
778 | GNUNET_break (NULL != th->th); | ||
779 | GNUNET_CONNECTION_notify_transmit_ready_cancel (th->th); | ||
780 | } | ||
781 | GNUNET_free (th); | ||
547 | } | 782 | } |
548 | 783 | ||
549 | 784 | ||
@@ -629,13 +864,21 @@ transmit_for_response (void *cls, | |||
629 | * @param hdr message to transmit | 864 | * @param hdr message to transmit |
630 | * @param timeout when to give up (for both transmission | 865 | * @param timeout when to give up (for both transmission |
631 | * and for waiting for a response) | 866 | * and for waiting for a response) |
867 | * @param auto_retry if the connection to the service dies, should we | ||
868 | * automatically re-connect and retry (within the timeout period) | ||
869 | * or should we immediately fail in this case? Pass GNUNET_YES | ||
870 | * if the caller does not care about temporary connection errors, | ||
871 | * for example because the protocol is stateless | ||
632 | * @param rn function to call with the response | 872 | * @param rn function to call with the response |
633 | * @param rn_cls closure for rn | 873 | * @param rn_cls closure for rn |
874 | * @return GNUNET_OK on success, GNUNET_SYSERR if a request | ||
875 | * is already pending | ||
634 | */ | 876 | */ |
635 | void | 877 | int |
636 | GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *sock, | 878 | GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *sock, |
637 | const struct GNUNET_MessageHeader *hdr, | 879 | const struct GNUNET_MessageHeader *hdr, |
638 | struct GNUNET_TIME_Relative timeout, | 880 | struct GNUNET_TIME_Relative timeout, |
881 | int auto_retry, | ||
639 | GNUNET_CLIENT_MessageHandler rn, | 882 | GNUNET_CLIENT_MessageHandler rn, |
640 | void *rn_cls) | 883 | void *rn_cls) |
641 | { | 884 | { |
@@ -650,11 +893,17 @@ GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *sock, | |||
650 | tc->timeout = GNUNET_TIME_relative_to_absolute (timeout); | 893 | tc->timeout = GNUNET_TIME_relative_to_absolute (timeout); |
651 | tc->rn = rn; | 894 | tc->rn = rn; |
652 | tc->rn_cls = rn_cls; | 895 | tc->rn_cls = rn_cls; |
653 | GNUNET_CLIENT_notify_transmit_ready (sock, | 896 | if (NULL == GNUNET_CLIENT_notify_transmit_ready (sock, |
654 | msize, | 897 | msize, |
655 | timeout, | 898 | timeout, |
656 | &transmit_for_response, | 899 | auto_retry, |
657 | tc); | 900 | &transmit_for_response, |
901 | tc)) | ||
902 | { | ||
903 | GNUNET_free (tc); | ||
904 | return GNUNET_SYSERR; | ||
905 | } | ||
906 | return GNUNET_OK; | ||
658 | } | 907 | } |
659 | 908 | ||
660 | 909 | ||
diff --git a/src/util/resolver_api.c b/src/util/resolver_api.c index cbd8392bf..5dede1c09 100644 --- a/src/util/resolver_api.c +++ b/src/util/resolver_api.c | |||
@@ -51,11 +51,6 @@ struct GetAddressContext | |||
51 | /** | 51 | /** |
52 | * FIXME. | 52 | * FIXME. |
53 | */ | 53 | */ |
54 | struct GNUNET_RESOLVER_GetMessage *msg; | ||
55 | |||
56 | /** | ||
57 | * FIXME. | ||
58 | */ | ||
59 | struct GNUNET_CLIENT_Connection *client; | 54 | struct GNUNET_CLIENT_Connection *client; |
60 | 55 | ||
61 | /** | 56 | /** |
@@ -238,43 +233,6 @@ handle_address_response (void *cls, const struct GNUNET_MessageHeader *msg) | |||
238 | 233 | ||
239 | 234 | ||
240 | /** | 235 | /** |
241 | * FIXME | ||
242 | * | ||
243 | * @param cls FIXME | ||
244 | * @param size number of bytes available in buf | ||
245 | * @param buf target buffer, NULL on error | ||
246 | * @return number of bytes written to buf | ||
247 | */ | ||
248 | static size_t | ||
249 | transmit_get_ip (void *cls, size_t size, void *buf) | ||
250 | { | ||
251 | struct GetAddressContext *actx = cls; | ||
252 | uint16_t ms; | ||
253 | |||
254 | if (buf == NULL) | ||
255 | { | ||
256 | /* timeout / error */ | ||
257 | GNUNET_free (actx->msg); | ||
258 | actx->callback (actx->cls, NULL, 0); | ||
259 | GNUNET_CLIENT_disconnect (actx->client); | ||
260 | GNUNET_free (actx); | ||
261 | return 0; | ||
262 | } | ||
263 | ms = ntohs (actx->msg->header.size); | ||
264 | GNUNET_assert (size >= ms); | ||
265 | memcpy (buf, actx->msg, ms); | ||
266 | GNUNET_free (actx->msg); | ||
267 | actx->msg = NULL; | ||
268 | GNUNET_CLIENT_receive (actx->client, | ||
269 | &handle_address_response, | ||
270 | actx, | ||
271 | GNUNET_TIME_absolute_get_remaining (actx->timeout)); | ||
272 | return ms; | ||
273 | } | ||
274 | |||
275 | |||
276 | |||
277 | /** | ||
278 | * Convert a string to one or more IP addresses. | 236 | * Convert a string to one or more IP addresses. |
279 | * | 237 | * |
280 | * @param sched scheduler to use | 238 | * @param sched scheduler to use |
@@ -404,19 +362,19 @@ GNUNET_RESOLVER_ip_get (struct GNUNET_SCHEDULER_Handle *sched, | |||
404 | actx->cls = callback_cls; | 362 | actx->cls = callback_cls; |
405 | actx->client = client; | 363 | actx->client = client; |
406 | actx->timeout = GNUNET_TIME_relative_to_absolute (timeout); | 364 | actx->timeout = GNUNET_TIME_relative_to_absolute (timeout); |
407 | actx->msg = msg; | ||
408 | 365 | ||
409 | #if DEBUG_RESOLVER | 366 | #if DEBUG_RESOLVER |
410 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 367 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
411 | _("Resolver requests DNS resolution of hostname `%s'.\n"), | 368 | _("Resolver requests DNS resolution of hostname `%s'.\n"), |
412 | hostname); | 369 | hostname); |
413 | #endif | 370 | #endif |
414 | if (NULL == | 371 | if (GNUNET_OK != |
415 | GNUNET_CLIENT_notify_transmit_ready (client, | 372 | GNUNET_CLIENT_transmit_and_get_response (client, |
416 | slen + | 373 | &msg->header, |
417 | sizeof (struct | 374 | timeout, |
418 | GNUNET_RESOLVER_GetMessage), | 375 | GNUNET_YES, |
419 | timeout, &transmit_get_ip, actx)) | 376 | &handle_address_response, |
377 | actx)) | ||
420 | { | 378 | { |
421 | GNUNET_free (msg); | 379 | GNUNET_free (msg); |
422 | GNUNET_free (actx); | 380 | GNUNET_free (actx); |
@@ -424,6 +382,7 @@ GNUNET_RESOLVER_ip_get (struct GNUNET_SCHEDULER_Handle *sched, | |||
424 | GNUNET_CLIENT_disconnect (client); | 382 | GNUNET_CLIENT_disconnect (client); |
425 | return; | 383 | return; |
426 | } | 384 | } |
385 | GNUNET_free (msg); | ||
427 | } | 386 | } |
428 | 387 | ||
429 | 388 | ||
@@ -445,11 +404,6 @@ struct GetHostnameContext | |||
445 | 404 | ||
446 | /** | 405 | /** |
447 | * FIXME. | 406 | * FIXME. |
448 | */ | ||
449 | struct GNUNET_RESOLVER_GetMessage *msg; | ||
450 | |||
451 | /** | ||
452 | * FIXME. | ||
453 | */ | 407 | */ |
454 | struct GNUNET_CLIENT_Connection *client; | 408 | struct GNUNET_CLIENT_Connection *client; |
455 | 409 | ||
@@ -516,43 +470,6 @@ handle_hostname_response (void *cls, const struct GNUNET_MessageHeader *msg) | |||
516 | 470 | ||
517 | 471 | ||
518 | /** | 472 | /** |
519 | * FIXME | ||
520 | * | ||
521 | * @param cls FIXME | ||
522 | * @param size number of bytes available in buf | ||
523 | * @param buf target buffer, NULL on error | ||
524 | * @return number of bytes written to buf | ||
525 | */ | ||
526 | static size_t | ||
527 | transmit_get_hostname (void *cls, size_t size, void *buf) | ||
528 | { | ||
529 | struct GetHostnameContext *hctx = cls; | ||
530 | uint16_t msize; | ||
531 | |||
532 | if (buf == NULL) | ||
533 | { | ||
534 | GNUNET_free (hctx->msg); | ||
535 | hctx->callback (hctx->cls, NULL); | ||
536 | GNUNET_CLIENT_disconnect (hctx->client); | ||
537 | GNUNET_free (hctx); | ||
538 | return 0; | ||
539 | } | ||
540 | msize = ntohs (hctx->msg->header.size); | ||
541 | GNUNET_assert (size >= msize); | ||
542 | memcpy (buf, hctx->msg, msize); | ||
543 | GNUNET_free (hctx->msg); | ||
544 | hctx->msg = NULL; | ||
545 | GNUNET_CLIENT_receive (hctx->client, | ||
546 | &handle_hostname_response, | ||
547 | hctx, | ||
548 | GNUNET_TIME_absolute_get_remaining (hctx->timeout)); | ||
549 | return msize; | ||
550 | } | ||
551 | |||
552 | |||
553 | |||
554 | |||
555 | /** | ||
556 | * Get an IP address as a string. | 473 | * Get an IP address as a string. |
557 | * | 474 | * |
558 | * @param sched scheduler to use | 475 | * @param sched scheduler to use |
@@ -624,19 +541,20 @@ GNUNET_RESOLVER_hostname_get (struct GNUNET_SCHEDULER_Handle *sched, | |||
624 | hctx->cls = cls; | 541 | hctx->cls = cls; |
625 | hctx->client = client; | 542 | hctx->client = client; |
626 | hctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); | 543 | hctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); |
627 | hctx->msg = msg; | 544 | if (GNUNET_OK != |
628 | if (NULL == | 545 | GNUNET_CLIENT_transmit_and_get_response (client, |
629 | GNUNET_CLIENT_notify_transmit_ready (client, | 546 | &msg->header, |
630 | sizeof (struct | 547 | timeout, |
631 | GNUNET_RESOLVER_GetMessage) | 548 | GNUNET_YES, |
632 | + salen, timeout, | 549 | &handle_hostname_response, |
633 | &transmit_get_hostname, hctx)) | 550 | hctx)) |
634 | { | 551 | { |
635 | GNUNET_free (msg); | 552 | GNUNET_free (msg); |
636 | callback (cls, NULL); | 553 | callback (cls, NULL); |
637 | GNUNET_CLIENT_disconnect (client); | 554 | GNUNET_CLIENT_disconnect (client); |
638 | GNUNET_free (hctx); | 555 | GNUNET_free (hctx); |
639 | } | 556 | } |
557 | GNUNET_free (msg); | ||
640 | } | 558 | } |
641 | 559 | ||
642 | /** | 560 | /** |
diff --git a/src/util/test_client.c b/src/util/test_client.c index cda8025ac..04efd951b 100644 --- a/src/util/test_client.c +++ b/src/util/test_client.c | |||
@@ -163,8 +163,9 @@ task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
163 | GNUNET_assert (NULL != | 163 | GNUNET_assert (NULL != |
164 | GNUNET_CLIENT_notify_transmit_ready (client, | 164 | GNUNET_CLIENT_notify_transmit_ready (client, |
165 | sizeof (struct | 165 | sizeof (struct |
166 | GNUNET_MessageHeader), | 166 | GNUNET_MessageHeader), |
167 | GNUNET_TIME_UNIT_SECONDS, | 167 | GNUNET_TIME_UNIT_SECONDS, |
168 | GNUNET_NO, | ||
168 | &make_msg, NULL)); | 169 | &make_msg, NULL)); |
169 | GNUNET_CLIENT_receive (client, &recv_bounce, cls, | 170 | GNUNET_CLIENT_receive (client, &recv_bounce, cls, |
170 | GNUNET_TIME_relative_multiply | 171 | GNUNET_TIME_relative_multiply |
diff --git a/src/util/test_server_disconnect.c b/src/util/test_server_disconnect.c index 84e9c7ccd..9aff7fc72 100644 --- a/src/util/test_server_disconnect.c +++ b/src/util/test_server_disconnect.c | |||
@@ -210,6 +210,7 @@ task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
210 | 256, | 210 | 256, |
211 | GNUNET_TIME_relative_multiply | 211 | GNUNET_TIME_relative_multiply |
212 | (GNUNET_TIME_UNIT_MILLISECONDS, 250), | 212 | (GNUNET_TIME_UNIT_MILLISECONDS, 250), |
213 | GNUNET_NO, | ||
213 | ¬ify_ready, NULL); | 214 | ¬ify_ready, NULL); |
214 | } | 215 | } |
215 | 216 | ||
diff --git a/src/util/test_server_with_client.c b/src/util/test_server_with_client.c index 4f3048f34..2558fd10c 100644 --- a/src/util/test_server_with_client.c +++ b/src/util/test_server_with_client.c | |||
@@ -184,6 +184,7 @@ task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
184 | 256, | 184 | 256, |
185 | GNUNET_TIME_relative_multiply | 185 | GNUNET_TIME_relative_multiply |
186 | (GNUNET_TIME_UNIT_MILLISECONDS, 250), | 186 | (GNUNET_TIME_UNIT_MILLISECONDS, 250), |
187 | GNUNET_NO, | ||
187 | ¬ify_ready, NULL); | 188 | ¬ify_ready, NULL); |
188 | } | 189 | } |
189 | 190 | ||
diff --git a/src/util/test_service.c b/src/util/test_service.c index f615b0cf9..f615e7eb4 100644 --- a/src/util/test_service.c +++ b/src/util/test_service.c | |||
@@ -87,6 +87,7 @@ ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
87 | GNUNET_CLIENT_notify_transmit_ready (client, | 87 | GNUNET_CLIENT_notify_transmit_ready (client, |
88 | sizeof (struct GNUNET_MessageHeader), | 88 | sizeof (struct GNUNET_MessageHeader), |
89 | GNUNET_TIME_UNIT_SECONDS, | 89 | GNUNET_TIME_UNIT_SECONDS, |
90 | GNUNET_NO, | ||
90 | &build_msg, client); | 91 | &build_msg, client); |
91 | } | 92 | } |
92 | 93 | ||
@@ -170,6 +171,7 @@ ready6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
170 | GNUNET_CLIENT_notify_transmit_ready (client, | 171 | GNUNET_CLIENT_notify_transmit_ready (client, |
171 | sizeof (struct GNUNET_MessageHeader), | 172 | sizeof (struct GNUNET_MessageHeader), |
172 | GNUNET_TIME_UNIT_SECONDS, | 173 | GNUNET_TIME_UNIT_SECONDS, |
174 | GNUNET_NO, | ||
173 | &build_msg, client); | 175 | &build_msg, client); |
174 | } | 176 | } |
175 | 177 | ||