gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r9266 - in gnunet/src: arm core datastore fs include peerin


From: gnunet
Subject: [GNUnet-SVN] r9266 - in gnunet/src: arm core datastore fs include peerinfo statistics transport util
Date: Sat, 24 Oct 2009 15:45:44 -0600

Author: grothoff
Date: 2009-10-24 15:45:44 -0600 (Sat, 24 Oct 2009)
New Revision: 9266

Modified:
   gnunet/src/arm/arm_api.c
   gnunet/src/arm/test_gnunet_arm.sh
   gnunet/src/core/core_api.c
   gnunet/src/datastore/Makefile.am
   gnunet/src/datastore/datastore_api.c
   gnunet/src/datastore/perf_datastore_api.c
   gnunet/src/datastore/test_datastore_api.c
   gnunet/src/datastore/test_datastore_api_data.conf
   gnunet/src/datastore/test_datastore_api_management.c
   gnunet/src/fs/fs.h
   gnunet/src/fs/fs_download.c
   gnunet/src/fs/fs_list_indexed.c
   gnunet/src/fs/fs_publish.c
   gnunet/src/fs/fs_search.c
   gnunet/src/fs/fs_unindex.c
   gnunet/src/include/gnunet_client_lib.h
   gnunet/src/peerinfo/peerinfo_api.c
   gnunet/src/statistics/statistics_api.c
   gnunet/src/transport/transport_api.c
   gnunet/src/util/client.c
   gnunet/src/util/resolver_api.c
   gnunet/src/util/test_client.c
   gnunet/src/util/test_server_disconnect.c
   gnunet/src/util/test_server_with_client.c
   gnunet/src/util/test_service.c
Log:
giving client API option for auto-retry, making more often use of 
transmit_and_get_response API and removing auto-retry code where enhanced 
client API can be used for it

Modified: gnunet/src/arm/arm_api.c
===================================================================
--- gnunet/src/arm/arm_api.c    2009-10-24 19:14:23 UTC (rev 9265)
+++ gnunet/src/arm/arm_api.c    2009-10-24 21:45:44 UTC (rev 9266)
@@ -32,21 +32,8 @@
 #include "gnunet_server_lib.h"
 #include "arm.h"
 
-/**
- * How often do we re-try tranmsitting requests to ARM before
- * giving up?  Note that if we succeeded transmitting a request
- * but failed to read a response, we do NOT re-try (since that
- * might result in ARM getting a request twice).
- */
-#define MAX_ATTEMPTS 4
 
 /**
- * Minimum delay between attempts to talk to ARM.
- */
-#define MIN_RETRY_DELAY  GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_MILLISECONDS, 100)
-
-
-/**
  * How long are we willing to wait for a service operation during the 
multi-operation
  * request processing?
  */
@@ -143,28 +130,11 @@
   void *cls;
 
   /**
-   * The service that is being manipulated.  Do not free.
-   */
-  const char *service_name;
-
-  /**
    * Timeout for the operation.
    */
   struct GNUNET_TIME_Absolute timeout;
 
   /**
-   * Length of service_name plus one.
-   */
-  size_t slen;
-
-  /**
-   * Number of attempts left for transmitting the request to ARM.
-   * We may fail the first time (say because ARM is not yet up),
-   * in which case we wait a bit and re-try (timeout permitting).
-   */
-  unsigned int attempts_left;
-
-  /**
    * Type of the request expressed as a message type (start or stop).
    */
   uint16_t type;
@@ -303,121 +273,6 @@
 
 
 /**
- * We've failed to transmit the request to the ARM service.
- * Report our failure and clean up the state.
- *
- * @param sctx the state of the (now failed) request
- */
-static void
-report_transmit_failure (struct RequestContext *sctx)
-{
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-             _("Error while trying to transmit to ARM service\n"));
-  if (sctx->callback != NULL)
-    sctx->callback (sctx->cls, GNUNET_SYSERR);
-  GNUNET_free (sctx);
-}
-
-
-/**
- * Transmit a request for a service status change to the
- * ARM service.
- *
- * @param cls the "struct RequestContext" identifying the request
- * @param size how many bytes are available in buf
- * @param buf where to write the request, NULL on error
- * @return number of bytes written to buf
- */
-static size_t
-send_service_msg (void *cls, size_t size, void *buf);
-
-
-/**
- * We've failed to transmit the request to the ARM service but
- * are now going to try again.
- * 
- * @param cls state of the request
- * @param tc task context (unused)
- */
-static void
-retry_request (void *cls,
-              const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  struct RequestContext *sctx = cls;
-
-  if (NULL ==
-      GNUNET_CLIENT_notify_transmit_ready (sctx->h->client,
-                                          sctx->slen +
-                                          sizeof (struct
-                                                  GNUNET_MessageHeader),
-                                          GNUNET_TIME_absolute_get_remaining 
(sctx->timeout),
-                                          &send_service_msg, 
-                                          sctx))
-    {
-      report_transmit_failure (sctx);    
-      return;
-    }
-}
-
-
-/**
- * Transmit a request for a service status change to the
- * ARM service.
- *
- * @param cls the "struct RequestContext" identifying the request
- * @param size how many bytes are available in buf
- * @param buf where to write the request, NULL on error
- * @return number of bytes written to buf
- */
-static size_t
-send_service_msg (void *cls, size_t size, void *buf)
-{
-  struct RequestContext *sctx = cls;
-  struct GNUNET_MessageHeader *msg;
-  struct GNUNET_TIME_Relative rem;
-
-  if (buf == NULL)
-    {
-      GNUNET_CLIENT_disconnect (sctx->h->client);
-      sctx->h->client = GNUNET_CLIENT_connect (sctx->h->sched, 
-                                              "arm", 
-                                              sctx->h->cfg);
-      GNUNET_assert (sctx->h->client != NULL);
-      rem = GNUNET_TIME_absolute_get_remaining (sctx->timeout);
-      if ( (sctx->attempts_left-- > 0) &&
-          (rem.value > 0) )
-       {
-         GNUNET_SCHEDULER_add_delayed (sctx->h->sched,
-                                       GNUNET_NO,
-                                       GNUNET_SCHEDULER_PRIORITY_KEEP,
-                                       GNUNET_SCHEDULER_NO_TASK,
-                                       GNUNET_TIME_relative_min 
(MIN_RETRY_DELAY,
-                                                                 rem),
-                                       &retry_request,
-                                       sctx);
-         return 0;
-       }
-      report_transmit_failure (sctx);
-      return 0;
-    }
-#if DEBUG_ARM
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              _("Transmitting service request to ARM.\n"));
-#endif
-  GNUNET_assert (size >= sctx->slen);
-  msg = buf;
-  msg->size = htons (sizeof (struct GNUNET_MessageHeader) + sctx->slen);
-  msg->type = htons (sctx->type);
-  memcpy (&msg[1], sctx->service_name, sctx->slen);
-  GNUNET_CLIENT_receive (sctx->h->client,
-                         &handle_response,
-                         sctx,
-                         GNUNET_TIME_absolute_get_remaining (sctx->timeout));
-  return sctx->slen + sizeof (struct GNUNET_MessageHeader);
-}
-
-
-/**
  * Start or stop a service.
  *
  * @param h handle to ARM
@@ -435,6 +290,7 @@
 {
   struct RequestContext *sctx;
   size_t slen;
+  struct GNUNET_MessageHeader *msg;
 
   slen = strlen (service_name) + 1;
   if (slen + sizeof (struct GNUNET_MessageHeader) >
@@ -453,15 +309,29 @@
   sctx->h = h;
   sctx->callback = cb;
   sctx->cls = cb_cls;
-  sctx->service_name = (const char*) &sctx[1];
-  memcpy (&sctx[1],
-         service_name,
-         slen);
   sctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
-  sctx->slen = slen;
-  sctx->attempts_left = MAX_ATTEMPTS;
   sctx->type = type;
-  retry_request (sctx, NULL);
+  msg = GNUNET_malloc (sizeof (struct GNUNET_MessageHeader) + slen);
+  msg->size = htons (sizeof (struct GNUNET_MessageHeader) + slen);
+  msg->type = htons (sctx->type);
+  memcpy (&msg[1], service_name, slen);
+  if (GNUNET_OK !=
+      GNUNET_CLIENT_transmit_and_get_response (sctx->h->client,
+                                              msg,
+                                              
GNUNET_TIME_absolute_get_remaining (sctx->timeout),
+                                              GNUNET_YES,
+                                              &handle_response,
+                                              sctx))
+    {       
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                 _("Error while trying to transmit to ARM service\n"));
+      if (cb != NULL)
+       cb (cb_cls, GNUNET_SYSERR);
+      GNUNET_free (sctx);
+      GNUNET_free (msg);
+      return;
+    }
+  GNUNET_free (msg);
 }
 
 

Modified: gnunet/src/arm/test_gnunet_arm.sh
===================================================================
--- gnunet/src/arm/test_gnunet_arm.sh   2009-10-24 19:14:23 UTC (rev 9265)
+++ gnunet/src/arm/test_gnunet_arm.sh   2009-10-24 21:45:44 UTC (rev 9266)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 exe="./gnunet-arm -c test_arm_api_data.conf"
-out=`mktemp /tmp/test-gnunetd-arm-logXXXXXXXX`
+out=`mktemp /tmp/test-gnunet-arm-logXXXXXXXX`
 #DEBUG="-L DEBUG"
 
 

Modified: gnunet/src/core/core_api.c
===================================================================
--- gnunet/src/core/core_api.c  2009-10-24 19:14:23 UTC (rev 9265)
+++ gnunet/src/core/core_api.c  2009-10-24 21:45:44 UTC (rev 9266)
@@ -94,7 +94,7 @@
   /**
    * Handle for our current transmission request.
    */
-  struct GNUNET_CONNECTION_TransmitHandle *th;
+  struct GNUNET_CLIENT_TransmitHandle *th;
 
   /**
    * Head of doubly-linked list of pending requests.
@@ -257,6 +257,7 @@
                                                sizeof (struct InitMessage) +
                                                sizeof (uint16_t) * h->hcnt,
                                                GNUNET_TIME_UNIT_SECONDS,
+                                              GNUNET_NO,
                                                &transmit_start, h);
 }
 
@@ -346,7 +347,9 @@
   h->th = GNUNET_CLIENT_notify_transmit_ready (h->client,
                                                th->msize,
                                                
GNUNET_TIME_absolute_get_remaining
-                                               (th->timeout), &request_start,
+                                               (th->timeout), 
+                                              GNUNET_NO,
+                                              &request_start,
                                                h);
 }
 
@@ -821,6 +824,7 @@
     GNUNET_CLIENT_notify_transmit_ready (h->client,
                                          sizeof (struct InitMessage) +
                                          sizeof (uint16_t) * h->hcnt, timeout,
+                                        GNUNET_YES,
                                          &transmit_start, h);
 }
 
@@ -834,7 +838,7 @@
 GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle)
 {
   if (handle->th != NULL)
-    GNUNET_CONNECTION_notify_transmit_ready_cancel (handle->th);
+    GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th);
   if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK)
     GNUNET_SCHEDULER_cancel (handle->sched, handle->reconnect_task);
   GNUNET_CLIENT_disconnect (handle->client);

Modified: gnunet/src/datastore/Makefile.am
===================================================================
--- gnunet/src/datastore/Makefile.am    2009-10-24 19:14:23 UTC (rev 9265)
+++ gnunet/src/datastore/Makefile.am    2009-10-24 21:45:44 UTC (rev 9266)
@@ -18,6 +18,7 @@
 libgnunetdatastore_la_SOURCES = \
   datastore_api.c datastore.h plugin_datastore.h
 libgnunetdatastore_la_LIBADD = \
+  $(top_builddir)/src/arm/libgnunetarm.la \
   $(top_builddir)/src/util/libgnunetutil.la \
   $(GN_LIBINTL) 
 libgnunetdatastore_la_LDFLAGS = \

Modified: gnunet/src/datastore/datastore_api.c
===================================================================
--- gnunet/src/datastore/datastore_api.c        2009-10-24 19:14:23 UTC (rev 
9265)
+++ gnunet/src/datastore/datastore_api.c        2009-10-24 21:45:44 UTC (rev 
9266)
@@ -24,6 +24,7 @@
  * @author Christian Grothoff
  */
 #include "platform.h"
+#include "gnunet_arm_service.h"
 #include "gnunet_datastore_service.h"
 #include "datastore.h"
 
@@ -75,6 +76,7 @@
 };
 
 
+
 /**
  * Connect to the datastore service.
  *
@@ -95,6 +97,7 @@
   c = GNUNET_CLIENT_connect (sched, "datastore", cfg);
   if (c == NULL)
     return NULL; /* oops */
+  GNUNET_ARM_start_services (cfg, sched, "datastore", NULL);
   h = GNUNET_malloc (sizeof(struct GNUNET_DATASTORE_Handle) + 
                     GNUNET_SERVER_MAX_MESSAGE_SIZE);
   h->client = c;
@@ -149,6 +152,7 @@
          GNUNET_CLIENT_notify_transmit_ready (h->client,
                                               sizeof(struct 
GNUNET_MessageHeader),
                                               GNUNET_TIME_UNIT_MINUTES,
+                                              GNUNET_YES,
                                               &transmit_drop,
                                               h))
        return;
@@ -156,6 +160,7 @@
     }
   if (h->client != NULL)
     GNUNET_CLIENT_disconnect (h->client);
+  GNUNET_ARM_stop_services (h->cfg, h->sched, "datastore", NULL);
   GNUNET_free (h);
 }
 
@@ -233,51 +238,6 @@
 
 
 /**
- * Transmit message to datastore service and then
- * read a status message.
- *
- * @param cls closure with handle to datastore
- * @param size number of bytes we can transmit at most
- * @param buf where to write transmission, NULL on
- *        timeout
- * @return number of bytes copied to buf
- */
-static size_t
-transmit_get_status (void *cls,
-                    size_t size,
-                    void *buf)
-{
-  struct GNUNET_DATASTORE_Handle *h = cls;
-  GNUNET_DATASTORE_ContinuationWithStatus cont = h->response_proc;
-  uint16_t msize;
-
-  if (buf == NULL)
-    {
-      h->message_size = 0;
-      h->response_proc = NULL;
-      cont (h->response_proc_cls, 
-           GNUNET_SYSERR,
-           _("Error transmitting message to datastore service."));
-      return 0;
-    }
-  msize = h->message_size;
-  GNUNET_assert (msize <= size);
-  memcpy (buf, &h[1], msize);
-#if DEBUG_DATASTORE
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Transmitted %u byte message to datastore service, now waiting 
for status.\n",
-             msize);
-#endif
-  h->message_size = 0;
-  GNUNET_CLIENT_receive (h->client,
-                        &with_status_response_handler,
-                        h,
-                        GNUNET_TIME_absolute_get_remaining (h->timeout));
-  return msize;
-}
-
-
-/**
  * Helper function that will initiate the
  * transmission of a message to the datastore
  * service.  The message must already be prepared
@@ -313,11 +273,13 @@
   h->response_proc_cls = cont_cls;
   h->timeout = GNUNET_TIME_relative_to_absolute (timeout);
   h->message_size = msize;
-  if (NULL == GNUNET_CLIENT_notify_transmit_ready (h->client,
-                                                  msize,
-                                                  timeout,
-                                                  &transmit_get_status,
-                                                  h))
+  if (GNUNET_OK !=
+      GNUNET_CLIENT_transmit_and_get_response (h->client,
+                                              hdr,                             
               
+                                              timeout,
+                                              GNUNET_YES,
+                                              &with_status_response_handler,   
                                       
+                                              h))
     {
       GNUNET_break (0);
       h->response_proc = NULL;
@@ -571,54 +533,6 @@
 
 
 /**
- * Transmit message to datastore service and then
- * read a result message.
- *
- * @param cls closure with handle to datastore
- * @param size number of bytes we can transmit at most
- * @param buf where to write transmission, NULL on
- *        timeout
- * @return number of bytes copied to buf
- */
-static size_t
-transmit_get_result (void *cls,
-                    size_t size,
-                    void *buf)
-{
-  struct GNUNET_DATASTORE_Handle *h = cls;
-  GNUNET_DATASTORE_Iterator cont = h->response_proc;
-  uint16_t msize;
-
-  if (buf == NULL)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                 _("Error transmitting message to datastore service.\n"));
-      h->response_proc = NULL;
-      h->message_size = 0;
-      cont (h->response_proc_cls, 
-           NULL, 0, NULL, 0, 0, 0,
-           GNUNET_TIME_UNIT_ZERO_ABS, 0);
-      return 0;
-    }
-  msize = h->message_size;
-  GNUNET_assert (msize <= size);
-  memcpy (buf, &h[1], msize);
-#if DEBUG_DATASTORE
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Transmitted %u byte message to datastore service, now waiting 
for result.\n",
-             msize);
-#endif
-  h->message_size = 0;
-  GNUNET_CLIENT_receive (h->client,
-                        &with_result_response_handler,
-                        h,
-                        GNUNET_TIME_absolute_get_remaining (h->timeout));
-  return msize;
-}
-
-
-
-/**
  * Function called to trigger obtaining the next result
  * from the datastore.
  * 
@@ -651,12 +565,10 @@
 
 
 /**
- * Helper function that will initiate the
- * transmission of a message to the datastore
- * service.  The message must already be prepared
- * and stored in the buffer at the end of the
- * handle.  The message must be of a type that
- * expects a "DataMessage" in response.
+ * Helper function that will initiate the transmission of a message to
+ * the datastore service.  The message must already be prepared and
+ * stored in the buffer at the end of the handle.  The message must be
+ * of a type that expects a "DataMessage" in response.
  *
  * @param h handle to the service with prepared message
  * @param cont function to call with result
@@ -686,11 +598,13 @@
   h->response_proc_cls = cont_cls;
   h->timeout = GNUNET_TIME_relative_to_absolute (timeout);
   h->message_size = msize;
-  if (NULL == GNUNET_CLIENT_notify_transmit_ready (h->client,
-                                                  msize,
-                                                  timeout,
-                                                  &transmit_get_result,
-                                                  h))
+  if (GNUNET_OK !=
+      GNUNET_CLIENT_transmit_and_get_response (h->client,
+                                              hdr,
+                                              timeout,
+                                              GNUNET_YES,
+                                              &with_result_response_handler,
+                                              h))
     {
       GNUNET_break (0);
       h->response_proc = NULL;

Modified: gnunet/src/datastore/perf_datastore_api.c
===================================================================
--- gnunet/src/datastore/perf_datastore_api.c   2009-10-24 19:14:23 UTC (rev 
9265)
+++ gnunet/src/datastore/perf_datastore_api.c   2009-10-24 21:45:44 UTC (rev 
9266)
@@ -358,8 +358,8 @@
   struct GNUNET_GETOPT_CommandLineOption options[] = {
     GNUNET_GETOPT_OPTION_END
   };
-  pid = GNUNET_OS_start_process ("gnunet-service-datastore",
-                                 "gnunet-service-datastore",
+  pid = GNUNET_OS_start_process ("gnunet-service-arm",
+                                 "gnunet-service-arm",
 #if VERBOSE
                                  "-L", "DEBUG",
 #endif

Modified: gnunet/src/datastore/test_datastore_api.c
===================================================================
--- gnunet/src/datastore/test_datastore_api.c   2009-10-24 19:14:23 UTC (rev 
9265)
+++ gnunet/src/datastore/test_datastore_api.c   2009-10-24 21:45:44 UTC (rev 
9266)
@@ -567,8 +567,8 @@
   struct GNUNET_GETOPT_CommandLineOption options[] = {
     GNUNET_GETOPT_OPTION_END
   };
-  pid = GNUNET_OS_start_process ("gnunet-service-datastore",
-                                 "gnunet-service-datastore",
+  pid = GNUNET_OS_start_process ("gnunet-service-arm",
+                                 "gnunet-service-arm",
 #if VERBOSE
                                  "-L", "DEBUG",
 #endif

Modified: gnunet/src/datastore/test_datastore_api_data.conf
===================================================================
--- gnunet/src/datastore/test_datastore_api_data.conf   2009-10-24 19:14:23 UTC 
(rev 9265)
+++ gnunet/src/datastore/test_datastore_api_data.conf   2009-10-24 21:45:44 UTC 
(rev 9266)
@@ -1,6 +1,16 @@
 [PATHS]
 SERVICEHOME = /tmp/test-gnunetd-datastore/
+DEFAULTCONFIG = test_datastore_api_data.conf
 
+[arm]
+DEFAULTSERVICES = resolver 
+PORT = 42466
+HOSTNAME = localhost
+
+[resolver]
+PORT = 42464
+HOSTNAME = localhost
+
 [datastore]
 PORT = 22654
 HOSTNAME = localhost
@@ -21,3 +31,10 @@
 # REJECT_FROM =
 # REJECT_FROM6 =
 # PREFIX =
+
+[statistics]
+PORT = 22667
+HOSTNAME = localhost
+
+[testing]
+WEAKRANDOM = YES

Modified: gnunet/src/datastore/test_datastore_api_management.c
===================================================================
--- gnunet/src/datastore/test_datastore_api_management.c        2009-10-24 
19:14:23 UTC (rev 9265)
+++ gnunet/src/datastore/test_datastore_api_management.c        2009-10-24 
21:45:44 UTC (rev 9266)
@@ -335,8 +335,8 @@
   struct GNUNET_GETOPT_CommandLineOption options[] = {
     GNUNET_GETOPT_OPTION_END
   };
-  pid = GNUNET_OS_start_process ("gnunet-service-datastore",
-                                 "gnunet-service-datastore",
+  pid = GNUNET_OS_start_process ("gnunet-service-arm",
+                                 "gnunet-service-arm",
 #if VERBOSE
                                  "-L", "DEBUG",
 #endif

Modified: gnunet/src/fs/fs.h
===================================================================
--- gnunet/src/fs/fs.h  2009-10-24 19:14:23 UTC (rev 9265)
+++ gnunet/src/fs/fs.h  2009-10-24 21:45:44 UTC (rev 9266)
@@ -950,7 +950,7 @@
    * Non-NULL if we are currently having a request for
    * transmission pending with the client handle.
    */
-  struct GNUNET_CONNECTION_TransmitHandle *th;
+  struct GNUNET_CLIENT_TransmitHandle *th;
 
   /**
    * Identity of the peer having the content, or all-zeros

Modified: gnunet/src/fs/fs_download.c
===================================================================
--- gnunet/src/fs/fs_download.c 2009-10-24 19:14:23 UTC (rev 9265)
+++ gnunet/src/fs/fs_download.c 2009-10-24 21:45:44 UTC (rev 9266)
@@ -239,6 +239,7 @@
     dc->th = GNUNET_CLIENT_notify_transmit_ready (dc->client,
                                                  sizeof (struct SearchMessage),
                                                  
GNUNET_CONSTANTS_SERVICE_TIMEOUT,
+                                                 GNUNET_NO,
                                                  &transmit_download_request,
                                                  dc); 
 
@@ -366,7 +367,7 @@
       /* abort all pending requests */
       if (NULL != dc->th)
        {
-         GNUNET_CONNECTION_notify_transmit_ready_cancel (dc->th);
+         GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th);
          dc->th = NULL;
        }
       GNUNET_CLIENT_disconnect (dc->client);
@@ -432,7 +433,7 @@
          /* abort all pending requests */
          if (NULL != dc->th)
            {
-             GNUNET_CONNECTION_notify_transmit_ready_cancel (dc->th);
+             GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th);
              dc->th = NULL;
            }
          GNUNET_CLIENT_disconnect (dc->client);
@@ -618,6 +619,7 @@
     dc->th = GNUNET_CLIENT_notify_transmit_ready (dc->client,
                                                  sizeof (struct SearchMessage),
                                                  
GNUNET_CONSTANTS_SERVICE_TIMEOUT,
+                                                 GNUNET_NO,
                                                  &transmit_download_request,
                                                  dc); 
   return msize;
@@ -654,6 +656,7 @@
   dc->th = GNUNET_CLIENT_notify_transmit_ready (client,
                                                sizeof (struct SearchMessage),
                                                
GNUNET_CONSTANTS_SERVICE_TIMEOUT,
+                                               GNUNET_NO,
                                                &transmit_download_request,
                                                dc);  
   GNUNET_CLIENT_receive (client,
@@ -704,7 +707,7 @@
     {
       if (NULL != dc->th)
        {
-         GNUNET_CONNECTION_notify_transmit_ready_cancel (dc->th);
+         GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th);
          dc->th = NULL;
        }
       GNUNET_CONTAINER_multihashmap_iterate (dc->active,
@@ -892,7 +895,7 @@
                             dc->task);
   if (NULL != dc->th)
     {
-      GNUNET_CONNECTION_notify_transmit_ready_cancel (dc->th);
+      GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th);
       dc->th = NULL;
     }
   if (NULL != dc->client)

Modified: gnunet/src/fs/fs_list_indexed.c
===================================================================
--- gnunet/src/fs/fs_list_indexed.c     2009-10-24 19:14:23 UTC (rev 9265)
+++ gnunet/src/fs/fs_list_indexed.c     2009-10-24 21:45:44 UTC (rev 9266)
@@ -155,50 +155,6 @@
 
 
 /**
- * Transmit the request to get a list of all 
- * indexed files to the "FS" service.
- *
- * @param cls closure (of type "struct GetIndexedContext*")
- * @param size number of bytes availabe in buf
- * @param buf where to write the message, NULL on error
- * @return number of bytes written to buf
- */
-static size_t
-transmit_get_indexed (void *cls,
-                     size_t size,
-                     void *buf)
-{
-  struct GetIndexedContext *gic = cls;
-  struct GNUNET_MessageHeader *hdr;
-
-  if (NULL == buf)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                 _("Failed to transmit `%s' request to `%s' service.\n"),
-                 "GET_INDEXED",
-                 "fs");
-      GNUNET_SCHEDULER_add_continuation (gic->h->sched,
-                                        GNUNET_NO,
-                                        gic->cont,
-                                        gic->cont_cls,
-                                        GNUNET_SCHEDULER_REASON_TIMEOUT);
-      GNUNET_CLIENT_disconnect (gic->client);
-      GNUNET_free (gic);
-      return 0;
-    }
-  GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
-  hdr = buf;
-  hdr->size = htons (sizeof (struct GNUNET_MessageHeader));
-  hdr->type = htons (GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET);
-  GNUNET_CLIENT_receive (gic->client,
-                        &handle_index_info,
-                        gic,
-                        GNUNET_CONSTANTS_SERVICE_TIMEOUT);
-  return sizeof (struct GNUNET_MessageHeader);
-}
-
-
-/**
  * Iterate over all indexed files.
  *
  * @param h handle to the file sharing subsystem
@@ -218,6 +174,7 @@
 {
   struct GNUNET_CLIENT_Connection *client;
   struct GetIndexedContext *gic;
+  struct GNUNET_MessageHeader msg;
 
   client = GNUNET_CLIENT_connect (h->sched,
                                  "fs",
@@ -242,11 +199,15 @@
   gic->iterator_cls = iterator_cls;
   gic->cont = cont;
   gic->cont_cls = cont_cls;
-  GNUNET_CLIENT_notify_transmit_ready (client,
-                                      sizeof (struct GNUNET_MessageHeader),
-                                      GNUNET_CONSTANTS_SERVICE_TIMEOUT,
-                                      &transmit_get_indexed,
-                                      gic);
+  msg.size = htons (sizeof (struct GNUNET_MessageHeader));
+  msg.type = htons (GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET);
+  GNUNET_assert (GNUNET_OK ==
+                GNUNET_CLIENT_transmit_and_get_response (client,
+                                                         &msg,
+                                                         
GNUNET_CONSTANTS_SERVICE_TIMEOUT,
+                                                         GNUNET_YES,
+                                                         &handle_index_info,
+                                                         gic));
 }
 
 /* end of fs_list_indexed.c */

Modified: gnunet/src/fs/fs_publish.c
===================================================================
--- gnunet/src/fs/fs_publish.c  2009-10-24 19:14:23 UTC (rev 9265)
+++ gnunet/src/fs/fs_publish.c  2009-10-24 21:45:44 UTC (rev 9266)
@@ -783,6 +783,7 @@
   GNUNET_CLIENT_transmit_and_get_response (client,
                                           &ism->header,
                                           GNUNET_TIME_UNIT_FOREVER_REL,
+                                          GNUNET_YES,
                                           &process_index_start_response,
                                           sc);
   GNUNET_free (ism);

Modified: gnunet/src/fs/fs_search.c
===================================================================
--- gnunet/src/fs/fs_search.c   2009-10-24 19:14:23 UTC (rev 9265)
+++ gnunet/src/fs/fs_search.c   2009-10-24 21:45:44 UTC (rev 9266)
@@ -694,6 +694,7 @@
   GNUNET_CLIENT_notify_transmit_ready (client,
                                       size,
                                        GNUNET_CONSTANTS_SERVICE_TIMEOUT,
+                                      GNUNET_NO,
                                       &transmit_search_request,
                                       sc);  
 }
@@ -812,6 +813,7 @@
   GNUNET_CLIENT_notify_transmit_ready (client,
                                       size,
                                        GNUNET_CONSTANTS_SERVICE_TIMEOUT,
+                                      GNUNET_NO,
                                       &transmit_search_request,
                                       sc);  
   return sc;

Modified: gnunet/src/fs/fs_unindex.c
===================================================================
--- gnunet/src/fs/fs_unindex.c  2009-10-24 19:14:23 UTC (rev 9265)
+++ gnunet/src/fs/fs_unindex.c  2009-10-24 21:45:44 UTC (rev 9266)
@@ -379,6 +379,7 @@
   GNUNET_CLIENT_transmit_and_get_response (uc->client,
                                           &req.header,
                                           GNUNET_CONSTANTS_SERVICE_TIMEOUT,
+                                          GNUNET_YES,
                                           &process_fs_response,
                                           uc);
 }

Modified: gnunet/src/include/gnunet_client_lib.h
===================================================================
--- gnunet/src/include/gnunet_client_lib.h      2009-10-24 19:14:23 UTC (rev 
9265)
+++ gnunet/src/include/gnunet_client_lib.h      2009-10-24 21:45:44 UTC (rev 
9266)
@@ -97,6 +97,12 @@
 
 
 /**
+ * Transmit handle for client connections.
+ */
+struct GNUNET_CLIENT_TransmitHandle;
+
+
+/**
  * Ask the client to call us once the specified number of bytes
  * are free in the transmission buffer.  May call the notify
  * method immediately if enough space is available.
@@ -105,21 +111,36 @@
  * @param size number of bytes to send
  * @param timeout after how long should we give up (and call
  *        notify with buf NULL and size 0)?
+ * @param auto_retry if the connection to the service dies, should we
+ *        automatically re-connect and retry (within the timeout period)
+ *        or should we immediately fail in this case?  Pass GNUNET_YES
+ *        if the caller does not care about temporary connection errors,
+ *        for example because the protocol is stateless
  * @param notify function to call
  * @param notify_cls closure for notify
  * @return NULL if someone else is already waiting to be notified
  *         non-NULL if the notify callback was queued (can be used to cancel
  *         using GNUNET_CONNECTION_notify_transmit_ready_cancel)
  */
-struct GNUNET_CONNECTION_TransmitHandle
+struct GNUNET_CLIENT_TransmitHandle
   *GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock,
                                         size_t size,
                                         struct GNUNET_TIME_Relative timeout,
+                                       int auto_retry,
                                         GNUNET_CONNECTION_TransmitReadyNotify
-                                        notify, void *notify_cls);
+                                        notify,
+                                       void *notify_cls);
 
 
+/**
+ * Cancel a request for notification.
+ * 
+ * @param th handle from the original request.
+ */
+void
+GNUNET_CLIENT_notify_transmit_ready_cancel (struct 
GNUNET_CLIENT_TransmitHandle *th);
 
+
 /**
  * Convenience API that combines sending a request
  * to the service and waiting for a response.
@@ -131,13 +152,21 @@
  * @param hdr message to transmit
  * @param timeout when to give up (for both transmission
  *         and for waiting for a response)
+ * @param auto_retry if the connection to the service dies, should we
+ *        automatically re-connect and retry (within the timeout period)
+ *        or should we immediately fail in this case?  Pass GNUNET_YES
+ *        if the caller does not care about temporary connection errors,
+ *        for example because the protocol is stateless
  * @param rn function to call with the response
  * @param rn_cls closure for rn 
+ * @return GNUNET_OK on success, GNUNET_SYSERR if a request
+ *         is already pending
  */
-void
+int
 GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *sock,
                                         const struct GNUNET_MessageHeader *hdr,
                                         struct GNUNET_TIME_Relative timeout,
+                                        int auto_retry,
                                         GNUNET_CLIENT_MessageHandler rn,
                                         void *rn_cls);
 

Modified: gnunet/src/peerinfo/peerinfo_api.c
===================================================================
--- gnunet/src/peerinfo/peerinfo_api.c  2009-10-24 19:14:23 UTC (rev 9265)
+++ gnunet/src/peerinfo/peerinfo_api.c  2009-10-24 21:45:44 UTC (rev 9266)
@@ -106,7 +106,9 @@
   cc->msg = &pam->header;
   GNUNET_CLIENT_notify_transmit_ready (client,
                                        ntohs (pam->header.size),
-                                       ADD_PEER_TIMEOUT, &copy_and_free, cc);
+                                       ADD_PEER_TIMEOUT, 
+                                      GNUNET_YES,
+                                      &copy_and_free, cc);
 }
 
 
@@ -203,36 +205,6 @@
 }
 
 
-static size_t
-copy_then_receive (void *cls, size_t size, void *buf)
-{
-  struct InfoContext *ic = cls;
-  const struct GNUNET_MessageHeader *msg =
-    (const struct GNUNET_MessageHeader *) &ic[1];
-  uint16_t msize;
-
-  if (buf == NULL)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                  _
-                  ("Failed to transmit message of type %u to `%s' service.\n"),
-                  ntohs (msg->type), "peerinfo");
-      ic->callback (ic->callback_cls, NULL, NULL, 1);
-      GNUNET_CLIENT_disconnect (ic->client);
-      GNUNET_free (ic);
-      return 0;
-    }
-  msize = ntohs (msg->size);
-  GNUNET_assert (size >= msize);
-  memcpy (buf, msg, msize);
-  GNUNET_CLIENT_receive (ic->client,
-                         &info_handler,
-                         ic,
-                         GNUNET_TIME_absolute_get_remaining (ic->timeout));
-  return msize;
-}
-
-
 /**
  * Call a method for each known matching host and change
  * its trust value.  The method will be invoked once for
@@ -293,8 +265,20 @@
       lpm->trust_change = htonl (trust_delta);
       memcpy (&lpm->peer, peer, sizeof (struct GNUNET_PeerIdentity));
     }
-  GNUNET_CLIENT_notify_transmit_ready (client,
-                                       hs, timeout, &copy_then_receive, ihc);
+  if (GNUNET_OK != 
+      GNUNET_CLIENT_transmit_and_get_response (client,
+                                              (const struct 
GNUNET_MessageHeader*) &ihc[1],
+                                              timeout,
+                                              GNUNET_YES,
+                                              &info_handler,
+                                              ihc))
+    {
+      GNUNET_break (0);
+      ihc->callback (ihc->callback_cls, NULL, NULL, 1);
+      GNUNET_CLIENT_disconnect (ihc->client);
+      GNUNET_free (ihc);
+      return;
+    }
 }
 
 /* end of peerinfo_api.c */

Modified: gnunet/src/statistics/statistics_api.c
===================================================================
--- gnunet/src/statistics/statistics_api.c      2009-10-24 19:14:23 UTC (rev 
9265)
+++ gnunet/src/statistics/statistics_api.c      2009-10-24 21:45:44 UTC (rev 
9266)
@@ -539,7 +539,9 @@
   if (NULL ==
       GNUNET_CLIENT_notify_transmit_ready (h->client,
                                            h->current->msize,
-                                           timeout, &transmit_action, h))
+                                           timeout,
+                                          GNUNET_YES,
+                                          &transmit_action, h))
     {
 #if DEBUG_STATISTICS
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,

Modified: gnunet/src/transport/transport_api.c
===================================================================
--- gnunet/src/transport/transport_api.c        2009-10-24 19:14:23 UTC (rev 
9265)
+++ gnunet/src/transport/transport_api.c        2009-10-24 21:45:44 UTC (rev 
9266)
@@ -278,7 +278,7 @@
   /**
    * Handle to our registration with the client for notification.
    */
-  struct GNUNET_CONNECTION_TransmitHandle *network_handle;
+  struct GNUNET_CLIENT_TransmitHandle *network_handle;
 
   /**
    * Linked list of transmit handles that are waiting for the
@@ -477,6 +477,7 @@
                                                            th->notify_size,
                                                            
GNUNET_TIME_absolute_get_remaining
                                                            (th->timeout),
+                                                          GNUNET_NO,
                                                            
&transport_notify_ready,
                                                            h);
   GNUNET_assert (NULL != h->network_handle);
@@ -1596,7 +1597,7 @@
 #endif
           if (h->network_handle != NULL)
             {
-              GNUNET_CONNECTION_notify_transmit_ready_cancel 
(h->network_handle);
+              GNUNET_CLIENT_notify_transmit_ready_cancel (h->network_handle);
               h->network_handle = NULL;
               h->transmission_scheduled = GNUNET_NO;
              th = h->connect_ready_head;
@@ -1986,7 +1987,7 @@
   h = th->handle;
   if ((h->connect_ready_head == NULL) && (h->network_handle != NULL))
     {
-      GNUNET_CONNECTION_notify_transmit_ready_cancel (h->network_handle);
+      GNUNET_CLIENT_notify_transmit_ready_cancel (h->network_handle);
       h->network_handle = NULL;
       h->transmission_scheduled = GNUNET_NO;
     }

Modified: gnunet/src/util/client.c
===================================================================
--- gnunet/src/util/client.c    2009-10-24 19:14:23 UTC (rev 9265)
+++ gnunet/src/util/client.c    2009-10-24 21:45:44 UTC (rev 9266)
@@ -36,7 +36,15 @@
 
 #define DEBUG_CLIENT GNUNET_NO
 
+
 /**
+ * How often do we re-try tranmsitting requests before giving up?
+ * Note that if we succeeded transmitting a request but failed to read
+ * a response, we do NOT re-try.
+ */
+#define MAX_ATTEMPTS 10
+
+/**
  * Struct to refer to a GNUnet TCP connection.
  * This is more than just a socket because if the server
  * drops the connection, the client automatically tries
@@ -56,6 +64,11 @@
   struct GNUNET_SCHEDULER_Handle *sched;
 
   /**
+   * Our configuration.
+   */
+  const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+  /**
    * Name of the service we interact with.
    */
   char *service_name;
@@ -116,20 +129,11 @@
 };
 
 
-/**
- * Get a connection with a service.
- *
- * @param sched scheduler to use
- * @param service_name name of the service
- * @param cfg configuration to use
- * @return NULL on error (service unknown to configuration)
- */
-struct GNUNET_CLIENT_Connection *
-GNUNET_CLIENT_connect (struct GNUNET_SCHEDULER_Handle *sched,
-                       const char *service_name,
-                       const struct GNUNET_CONFIGURATION_Handle *cfg)
+static struct GNUNET_CONNECTION_Handle *
+do_connect (struct GNUNET_SCHEDULER_Handle *sched,
+           const char *service_name,
+           const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
-  struct GNUNET_CLIENT_Connection *ret;
   struct GNUNET_CONNECTION_Handle *sock;
   char *hostname;
   unsigned long long port;
@@ -164,12 +168,34 @@
                                                port,
                                                GNUNET_SERVER_MAX_MESSAGE_SIZE);
   GNUNET_free (hostname);
+  return sock;
+}
+
+
+/**
+ * Get a connection with a service.
+ *
+ * @param sched scheduler to use
+ * @param service_name name of the service
+ * @param cfg configuration to use
+ * @return NULL on error (service unknown to configuration)
+ */
+struct GNUNET_CLIENT_Connection *
+GNUNET_CLIENT_connect (struct GNUNET_SCHEDULER_Handle *sched,
+                       const char *service_name,
+                       const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+  struct GNUNET_CLIENT_Connection *ret;
+  struct GNUNET_CONNECTION_Handle *sock;
+
+  sock = do_connect (sched, service_name, cfg);
   if (sock == NULL)
     return NULL;
   ret = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_Connection));
   ret->sock = sock;
   ret->sched = sched;
   ret->service_name = GNUNET_strdup (service_name);
+  ret->cfg = cfg;
   return ret;
 }
 
@@ -521,6 +547,171 @@
 
 
 /**
+ * Handle for a transmission request.
+ */
+struct GNUNET_CLIENT_TransmitHandle 
+{
+  /**
+   * Connection state.
+   */
+  struct GNUNET_CLIENT_Connection *sock;
+
+  /**
+   * Function to call to get the data for transmission.
+   */
+  GNUNET_CONNECTION_TransmitReadyNotify notify;
+
+  /**
+   * Closure for notify.
+   */
+  void *notify_cls;
+
+  /**
+   * Handle to the transmission with the underlying
+   * connection.
+   */
+  struct GNUNET_CONNECTION_TransmitHandle *th;
+
+  /**
+   * Timeout.
+   */
+  struct GNUNET_TIME_Absolute timeout;
+
+  /**
+   * If we are re-trying and are delaying to do so,
+   * handle to the scheduled task managing the delay.
+   */
+  GNUNET_SCHEDULER_TaskIdentifier task;
+
+  /**
+   * Number of bytes requested.
+   */
+  size_t size;
+
+  /**
+   * Are we allowed to re-try to connect without telling
+   * the user (of this API) about the connection troubles?
+   */
+  int auto_retry;
+
+  /**
+   * Number of attempts left for transmitting the request.  We may
+   * fail the first time (say because the service is not yet up), in
+   * which case (if auto_retry is set) we wait a bit and re-try
+   * (timeout permitting).
+   */
+  unsigned int attempts_left;
+
+};
+
+
+
+/**
+ * Connection notifies us about failure or success of
+ * a transmission request.  Either pass it on to our
+ * user or, if possible, retry.
+ *
+ * @param cls our "struct GNUNET_CLIENT_TransmissionHandle"
+ * @param size number of bytes available for transmission
+ * @param buf where to write them
+ * @return number of bytes written to buf
+ */
+static size_t
+client_notify (void *cls,
+              size_t size,
+              void *buf);
+
+
+
+/**
+ * This task is run if we should re-try connection to the
+ * service after a while.
+ *
+ * @param cls our "struct GNUNET_CLIENT_TransmitHandle" of the request
+ * @param tc unused
+ */
+static void
+client_delayed_retry (void *cls,
+                     const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct GNUNET_CLIENT_TransmitHandle *th = cls;
+
+  th->task = GNUNET_SCHEDULER_NO_TASK;
+  th->sock->sock = do_connect (th->sock->sched, 
+                              th->sock->service_name,
+                              th->sock->cfg);
+  th->th = GNUNET_CONNECTION_notify_transmit_ready (th->sock->sock,
+                                                   th->size,
+                                                   
GNUNET_TIME_absolute_get_remaining (th->timeout), 
+                                                   &client_notify, 
+                                                   th);
+  if (th->th == NULL)
+    {
+      GNUNET_break (0);
+      th->notify (th->notify_cls, 0, NULL);
+      GNUNET_free (th);
+      return;            
+    }
+}
+
+
+/**
+ * Connection notifies us about failure or success of
+ * a transmission request.  Either pass it on to our
+ * user or, if possible, retry.
+ *
+ * @param cls our "struct GNUNET_CLIENT_TransmissionHandle"
+ * @param size number of bytes available for transmission
+ * @param buf where to write them
+ * @return number of bytes written to buf
+ */
+static size_t
+client_notify (void *cls,
+              size_t size,
+              void *buf)
+{
+  struct GNUNET_CLIENT_TransmitHandle *th = cls;
+  size_t ret;
+  struct GNUNET_TIME_Relative delay;
+  
+  if (buf == NULL)
+    {
+      delay = GNUNET_TIME_absolute_get_remaining (th->timeout);
+      delay.value /= 2;
+      if ( (GNUNET_YES != th->auto_retry) ||
+          (0 == --th->attempts_left) ||
+          (delay.value < 1) )
+       {
+         GNUNET_break (0 == th->notify (th->notify_cls,
+                                        0,
+                                        NULL));
+         GNUNET_free (th);
+         return 0;
+       }
+      /* auto-retry */
+      GNUNET_CONNECTION_destroy (th->sock->sock);
+      th->sock->sock = NULL;
+      th->th = NULL;
+      delay = GNUNET_TIME_relative_min (delay, GNUNET_TIME_UNIT_SECONDS);
+      th->task = GNUNET_SCHEDULER_add_delayed (th->sock->sched,
+                                              GNUNET_NO,
+                                              GNUNET_SCHEDULER_PRIORITY_KEEP,
+                                              GNUNET_SCHEDULER_NO_TASK,
+                                              delay,
+                                              &client_delayed_retry,
+                                              th);
+      return 0;
+    }
+  GNUNET_assert (size >= th->size);
+  ret = th->notify (th->notify_cls,
+                   size,
+                   buf);
+  GNUNET_free (th);
+  return ret;
+}
+
+
+/**
  * Ask the client to call us once the specified number of bytes
  * are free in the transmission buffer.  May call the notify
  * method immediately if enough space is available.
@@ -529,25 +720,69 @@
  * @param size number of bytes to send
  * @param timeout after how long should we give up (and call
  *        notify with buf NULL and size 0)?
+ * @param auto_retry if the connection to the service dies, should we
+ *        automatically re-connect and retry (within the timeout period)
+ *        or should we immediately fail in this case?  Pass GNUNET_YES
+ *        if the caller does not care about temporary connection errors,
+ *        for example because the protocol is stateless
  * @param notify function to call
  * @param notify_cls closure for notify
  * @return NULL if our buffer will never hold size bytes,
  *         a handle if the notify callback was queued (can be used to cancel)
  */
-struct GNUNET_CONNECTION_TransmitHandle *
+struct GNUNET_CLIENT_TransmitHandle *
 GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock,
                                      size_t size,
                                      struct GNUNET_TIME_Relative timeout,
+                                    int auto_retry,
                                      GNUNET_CONNECTION_TransmitReadyNotify
                                      notify, void *notify_cls)
 {
-  return GNUNET_CONNECTION_notify_transmit_ready (sock->sock,
-                                               size,
-                                               timeout, notify, notify_cls);
+  struct GNUNET_CLIENT_TransmitHandle *th;
+
+  th = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_TransmitHandle));
+  th->sock = sock;
+  th->size = size;
+  th->timeout = GNUNET_TIME_relative_to_absolute (timeout);
+  th->auto_retry = auto_retry;
+  th->notify = notify;
+  th->notify_cls = notify_cls;
+  th->attempts_left = MAX_ATTEMPTS;
+  th->th = GNUNET_CONNECTION_notify_transmit_ready (sock->sock,
+                                                   size,
+                                                   timeout, 
+                                                   &client_notify, 
+                                                   th);
+  if (NULL == th->th)
+    {
+      GNUNET_free (th);
+      return NULL;
+    }
+  return th;
 }
 
 
 /**
+ * Cancel a request for notification.
+ * 
+ * @param th handle from the original request.
+ */
+void
+GNUNET_CLIENT_notify_transmit_ready_cancel (struct 
GNUNET_CLIENT_TransmitHandle *th)
+{
+  if (th->task != GNUNET_SCHEDULER_NO_TASK)
+    GNUNET_SCHEDULER_cancel (th->sock->sched,
+                            th->task);
+  else
+    {
+      GNUNET_break (NULL != th->th);
+      GNUNET_CONNECTION_notify_transmit_ready_cancel (th->th);
+    }
+  GNUNET_free (th);
+}
+
+
+/**
  * Context for processing 
  * "GNUNET_CLIENT_transmit_and_get_response" requests.
  */
@@ -629,13 +864,21 @@
  * @param hdr message to transmit
  * @param timeout when to give up (for both transmission
  *         and for waiting for a response)
+ * @param auto_retry if the connection to the service dies, should we
+ *        automatically re-connect and retry (within the timeout period)
+ *        or should we immediately fail in this case?  Pass GNUNET_YES
+ *        if the caller does not care about temporary connection errors,
+ *        for example because the protocol is stateless
  * @param rn function to call with the response
  * @param rn_cls closure for rn 
+ * @return GNUNET_OK on success, GNUNET_SYSERR if a request
+ *         is already pending
  */
-void
+int
 GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *sock,
                                         const struct GNUNET_MessageHeader *hdr,
                                         struct GNUNET_TIME_Relative timeout,
+                                        int auto_retry,
                                         GNUNET_CLIENT_MessageHandler rn,
                                         void *rn_cls)
 {
@@ -650,11 +893,17 @@
   tc->timeout = GNUNET_TIME_relative_to_absolute (timeout);
   tc->rn = rn;
   tc->rn_cls = rn_cls;
-  GNUNET_CLIENT_notify_transmit_ready (sock,
-                                      msize,
-                                      timeout,
-                                      &transmit_for_response,
-                                      tc);
+  if (NULL == GNUNET_CLIENT_notify_transmit_ready (sock,
+                                                  msize,
+                                                  timeout,
+                                                  auto_retry,
+                                                  &transmit_for_response,
+                                                  tc))
+    {
+      GNUNET_free (tc);
+      return GNUNET_SYSERR;
+    }
+  return GNUNET_OK;
 }
 
 

Modified: gnunet/src/util/resolver_api.c
===================================================================
--- gnunet/src/util/resolver_api.c      2009-10-24 19:14:23 UTC (rev 9265)
+++ gnunet/src/util/resolver_api.c      2009-10-24 21:45:44 UTC (rev 9266)
@@ -51,11 +51,6 @@
   /**
    * FIXME.
    */
-  struct GNUNET_RESOLVER_GetMessage *msg;
-
-  /**
-   * FIXME.
-   */
   struct GNUNET_CLIENT_Connection *client;
 
   /**
@@ -238,43 +233,6 @@
 
 
 /**
- * FIXME
- *
- * @param cls FIXME
- * @param size number of bytes available in buf
- * @param buf target buffer, NULL on error
- * @return number of bytes written to buf
- */
-static size_t
-transmit_get_ip (void *cls, size_t size, void *buf)
-{
-  struct GetAddressContext *actx = cls;
-  uint16_t ms;
-
-  if (buf == NULL)
-    {
-      /* timeout / error */
-      GNUNET_free (actx->msg);
-      actx->callback (actx->cls, NULL, 0);
-      GNUNET_CLIENT_disconnect (actx->client);
-      GNUNET_free (actx);
-      return 0;
-    }
-  ms = ntohs (actx->msg->header.size);
-  GNUNET_assert (size >= ms);
-  memcpy (buf, actx->msg, ms);
-  GNUNET_free (actx->msg);
-  actx->msg = NULL;
-  GNUNET_CLIENT_receive (actx->client,
-                         &handle_address_response,
-                         actx,
-                         GNUNET_TIME_absolute_get_remaining (actx->timeout));
-  return ms;
-}
-
-
-
-/**
  * Convert a string to one or more IP addresses.
  *
  * @param sched scheduler to use
@@ -404,19 +362,19 @@
   actx->cls = callback_cls;
   actx->client = client;
   actx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
-  actx->msg = msg;
 
 #if DEBUG_RESOLVER
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               _("Resolver requests DNS resolution of hostname `%s'.\n"),
               hostname);
 #endif
-  if (NULL ==
-      GNUNET_CLIENT_notify_transmit_ready (client,
-                                           slen +
-                                           sizeof (struct
-                                                   GNUNET_RESOLVER_GetMessage),
-                                           timeout, &transmit_get_ip, actx))
+  if (GNUNET_OK !=
+      GNUNET_CLIENT_transmit_and_get_response (client,
+                                              &msg->header,
+                                              timeout,
+                                              GNUNET_YES,
+                                              &handle_address_response,
+                                              actx))
     {
       GNUNET_free (msg);
       GNUNET_free (actx);
@@ -424,6 +382,7 @@
       GNUNET_CLIENT_disconnect (client);
       return;
     }
+  GNUNET_free (msg);      
 }
 
 
@@ -445,11 +404,6 @@
   
   /**
    * FIXME.
-   */ 
-  struct GNUNET_RESOLVER_GetMessage *msg;
-  
-  /**
-   * FIXME.
    */  
   struct GNUNET_CLIENT_Connection *client;
   
@@ -516,43 +470,6 @@
 
 
 /**
- * FIXME
- *
- * @param cls FIXME
- * @param size number of bytes available in buf
- * @param buf target buffer, NULL on error
- * @return number of bytes written to buf
- */
-static size_t
-transmit_get_hostname (void *cls, size_t size, void *buf)
-{
-  struct GetHostnameContext *hctx = cls;
-  uint16_t msize;
-
-  if (buf == NULL)
-    {
-      GNUNET_free (hctx->msg);
-      hctx->callback (hctx->cls, NULL);
-      GNUNET_CLIENT_disconnect (hctx->client);
-      GNUNET_free (hctx);
-      return 0;
-    }
-  msize = ntohs (hctx->msg->header.size);
-  GNUNET_assert (size >= msize);
-  memcpy (buf, hctx->msg, msize);
-  GNUNET_free (hctx->msg);
-  hctx->msg = NULL;
-  GNUNET_CLIENT_receive (hctx->client,
-                         &handle_hostname_response,
-                         hctx,
-                         GNUNET_TIME_absolute_get_remaining (hctx->timeout));
-  return msize;
-}
-
-
-
-
-/**
  * Get an IP address as a string.
  *
  * @param sched scheduler to use
@@ -624,19 +541,20 @@
   hctx->cls = cls;
   hctx->client = client;
   hctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
-  hctx->msg = msg;
-  if (NULL ==
-      GNUNET_CLIENT_notify_transmit_ready (client,
-                                           sizeof (struct
-                                                   GNUNET_RESOLVER_GetMessage)
-                                           + salen, timeout,
-                                           &transmit_get_hostname, hctx))
+  if (GNUNET_OK !=
+      GNUNET_CLIENT_transmit_and_get_response (client,
+                                              &msg->header,
+                                              timeout,
+                                              GNUNET_YES,
+                                              &handle_hostname_response,
+                                              hctx))
     {
       GNUNET_free (msg);
       callback (cls, NULL);
       GNUNET_CLIENT_disconnect (client);
       GNUNET_free (hctx);
     }
+  GNUNET_free (msg);
 }
 
 /**

Modified: gnunet/src/util/test_client.c
===================================================================
--- gnunet/src/util/test_client.c       2009-10-24 19:14:23 UTC (rev 9265)
+++ gnunet/src/util/test_client.c       2009-10-24 21:45:44 UTC (rev 9266)
@@ -163,8 +163,9 @@
   GNUNET_assert (NULL !=
                  GNUNET_CLIENT_notify_transmit_ready (client,
                                                       sizeof (struct
-                                                              
GNUNET_MessageHeader),
+                                                              
GNUNET_MessageHeader),                                                 
                                                       GNUNET_TIME_UNIT_SECONDS,
+                                                     GNUNET_NO,
                                                       &make_msg, NULL));
   GNUNET_CLIENT_receive (client, &recv_bounce, cls,
                          GNUNET_TIME_relative_multiply

Modified: gnunet/src/util/test_server_disconnect.c
===================================================================
--- gnunet/src/util/test_server_disconnect.c    2009-10-24 19:14:23 UTC (rev 
9265)
+++ gnunet/src/util/test_server_disconnect.c    2009-10-24 21:45:44 UTC (rev 
9266)
@@ -210,6 +210,7 @@
                                        256,
                                        GNUNET_TIME_relative_multiply
                                        (GNUNET_TIME_UNIT_MILLISECONDS, 250),
+                                      GNUNET_NO,
                                        &notify_ready, NULL);
 }
 

Modified: gnunet/src/util/test_server_with_client.c
===================================================================
--- gnunet/src/util/test_server_with_client.c   2009-10-24 19:14:23 UTC (rev 
9265)
+++ gnunet/src/util/test_server_with_client.c   2009-10-24 21:45:44 UTC (rev 
9266)
@@ -184,6 +184,7 @@
                                        256,
                                        GNUNET_TIME_relative_multiply
                                        (GNUNET_TIME_UNIT_MILLISECONDS, 250),
+                                      GNUNET_NO,
                                        &notify_ready, NULL);
 }
 

Modified: gnunet/src/util/test_service.c
===================================================================
--- gnunet/src/util/test_service.c      2009-10-24 19:14:23 UTC (rev 9265)
+++ gnunet/src/util/test_service.c      2009-10-24 21:45:44 UTC (rev 9266)
@@ -87,6 +87,7 @@
   GNUNET_CLIENT_notify_transmit_ready (client,
                                        sizeof (struct GNUNET_MessageHeader),
                                        GNUNET_TIME_UNIT_SECONDS,
+                                      GNUNET_NO,
                                        &build_msg, client);
 }
 
@@ -170,6 +171,7 @@
   GNUNET_CLIENT_notify_transmit_ready (client,
                                        sizeof (struct GNUNET_MessageHeader),
                                        GNUNET_TIME_UNIT_SECONDS,
+                                      GNUNET_NO,
                                        &build_msg, client);
 }
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]