gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r6348 - in GNUnet/src: applications applications/dht/module


From: gnunet
Subject: [GNUnet-SVN] r6348 - in GNUnet/src: applications applications/dht/module applications/dht/tools applications/fs/collection applications/fs/fsui applications/fs/gap applications/rpc include util/containers
Date: Sun, 17 Feb 2008 00:50:48 -0700 (MST)

Author: grothoff
Date: 2008-02-17 00:50:48 -0700 (Sun, 17 Feb 2008)
New Revision: 6348

Removed:
   GNUnet/src/include/gnunet_blockstore.h
   GNUnet/src/util/containers/vector.c
   GNUnet/src/util/containers/vectortest.c
Modified:
   GNUnet/src/applications/Makefile.am
   GNUnet/src/applications/dht/module/cs.c
   GNUnet/src/applications/dht/module/routing.c
   GNUnet/src/applications/dht/module/service.c
   GNUnet/src/applications/dht/tools/dht-query.c
   GNUnet/src/applications/dht/tools/dht_api.c
   GNUnet/src/applications/fs/collection/collection.c
   GNUnet/src/applications/fs/fsui/deserialize.c
   GNUnet/src/applications/fs/fsui/fsui.h
   GNUnet/src/applications/fs/fsui/serialize.c
   GNUnet/src/applications/fs/gap/fs_dht.c
   GNUnet/src/applications/rpc/parameters.c
   GNUnet/src/applications/rpc/parameterstest.c
   GNUnet/src/applications/rpc/rpc.c
   GNUnet/src/include/Makefile.am
   GNUnet/src/include/gnunet_dht_lib.h
   GNUnet/src/include/gnunet_dht_service.h
   GNUnet/src/include/gnunet_dstore_service.h
   GNUnet/src/include/gnunet_rpc_lib.h
   GNUnet/src/include/gnunet_rpc_service.h
   GNUnet/src/include/gnunet_util_containers.h
   GNUnet/src/util/containers/Makefile.am
Log:
RPC code clean up

Modified: GNUnet/src/applications/Makefile.am
===================================================================
--- GNUnet/src/applications/Makefile.am 2008-02-17 04:58:52 UTC (rev 6347)
+++ GNUnet/src/applications/Makefile.am 2008-02-17 07:50:48 UTC (rev 6348)
@@ -18,7 +18,6 @@
  identity \
  bootstrap_http \
  datastore \
- rpc \
  fragmentation \
  getoption \
  $(HOSTLIST_DIR) \

Modified: GNUnet/src/applications/dht/module/cs.c
===================================================================
--- GNUnet/src/applications/dht/module/cs.c     2008-02-17 04:58:52 UTC (rev 
6347)
+++ GNUnet/src/applications/dht/module/cs.c     2008-02-17 07:50:48 UTC (rev 
6348)
@@ -29,7 +29,6 @@
 #include "platform.h"
 #include "gnunet_core.h"
 #include "gnunet_protocols.h"
-#include "gnunet_rpc_service.h"
 #include "dht.h"
 #include "gnunet_dht_service.h"
 
@@ -100,18 +99,17 @@
 }
 
 static int
-get_result (const GNUNET_HashCode * key, const GNUNET_DataContainer * value,
+get_result (const GNUNET_HashCode * key, 
+           unsigned int type,
+           unsigned int size,
+           const char * value,
             void *cls)
 {
   struct DHT_CLIENT_GET_RECORD *record = cls;
   CS_dht_request_put_MESSAGE *msg;
   size_t n;
 
-  GNUNET_GE_ASSERT (NULL,
-                    ntohl (value->size) >= sizeof (GNUNET_DataContainer));
-  n =
-    sizeof (CS_dht_request_put_MESSAGE) + ntohl (value->size) -
-    sizeof (GNUNET_DataContainer);
+  n = sizeof (CS_dht_request_put_MESSAGE) + size;
   if (n > GNUNET_MAX_BUFFER_SIZE)
     {
       GNUNET_GE_BREAK (NULL, 0);
@@ -121,8 +119,7 @@
   msg->header.size = htons (n);
   msg->header.type = htons (GNUNET_CS_PROTO_DHT_REQUEST_PUT);
   msg->key = *key;
-  memcpy (&msg[1], &value[1],
-          ntohl (value->size) - sizeof (GNUNET_DataContainer));
+  memcpy (&msg[1], value, size);
 #if DEBUG_CS
   GNUNET_GE_LOG (coreAPI->ectx,
                  GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
@@ -130,8 +127,8 @@
                  __FUNCTION__,
                  __FILE__,
                  __LINE__,
-                 ntohl (value->size) - sizeof (GNUNET_DataContainer),
-                 &value[1]);
+                 size,
+                 value);
 #endif
   if (GNUNET_OK !=
       coreAPI->cs_send_to_client (record->client, &msg->header, GNUNET_YES))

Modified: GNUnet/src/applications/dht/module/routing.c
===================================================================
--- GNUnet/src/applications/dht/module/routing.c        2008-02-17 04:58:52 UTC 
(rev 6347)
+++ GNUnet/src/applications/dht/module/routing.c        2008-02-17 07:50:48 UTC 
(rev 6348)
@@ -247,7 +247,7 @@
  * Given a result, lookup in the routing table
  * where to send it next.
  */
-static void
+static int
 routeResult (const GNUNET_HashCode * key,
              unsigned int type,
              unsigned int size, const char *data, void *cls)
@@ -387,6 +387,7 @@
 #endif
   if (cls == NULL)
     GNUNET_free (result);
+  return GNUNET_OK;
 }
 
 /**

Modified: GNUnet/src/applications/dht/module/service.c
===================================================================
--- GNUnet/src/applications/dht/module/service.c        2008-02-17 04:58:52 UTC 
(rev 6347)
+++ GNUnet/src/applications/dht/module/service.c        2008-02-17 07:50:48 UTC 
(rev 6348)
@@ -48,8 +48,8 @@
   /**
    * Function to call for each result.
    */
-  GNUNET_DataProcessor callback;
-
+  GNUNET_ResultProcessor callback;
+  
   /**
    * Extra argument to callback.
    */
@@ -62,21 +62,6 @@
 
 };
 
-static void
-client_result_converter (const GNUNET_HashCode * key,
-                         unsigned int type,
-                         unsigned int size, const char *data, void *cls)
-{
-  struct GNUNET_DHT_GetHandle *get = cls;
-  GNUNET_DataContainer *dc;
-
-  dc = GNUNET_malloc (sizeof (GNUNET_DataContainer) + size);
-  dc->size = ntohl (sizeof (GNUNET_DataContainer) + size);
-  memcpy (&dc[1], data, size);
-  get->callback (key, dc, get->cls);
-  GNUNET_free (dc);
-}
-
 /**
  * Perform an asynchronous GET operation on the DHT identified by
  * 'table' using 'key' as the key.  The peer does not have to be part
@@ -96,7 +81,7 @@
 static struct GNUNET_DHT_GetHandle *
 dht_get_async_start (unsigned int type,
                      const GNUNET_HashCode * key,
-                     GNUNET_DataProcessor callback, void *cls)
+                     GNUNET_ResultProcessor callback, void *cls)
 {
   struct GNUNET_DHT_GetHandle *ret;
 
@@ -106,7 +91,7 @@
   ret->cls = cls;
   ret->type = type;
   if (GNUNET_OK !=
-      GNUNET_DHT_get_start (key, type, &client_result_converter, ret))
+      GNUNET_DHT_get_start (key, type, callback, cls))
     {
       GNUNET_free (ret);
       return NULL;
@@ -120,8 +105,7 @@
 static int
 dht_get_async_stop (struct GNUNET_DHT_GetHandle *record)
 {
-  GNUNET_DHT_get_stop (&record->key, record->type, &client_result_converter,
-                       record);
+  GNUNET_DHT_get_stop (&record->key, record->type, record->callback, 
record->cls);
   GNUNET_free (record);
   return GNUNET_OK;
 }

Modified: GNUnet/src/applications/dht/tools/dht-query.c
===================================================================
--- GNUnet/src/applications/dht/tools/dht-query.c       2008-02-17 04:58:52 UTC 
(rev 6347)
+++ GNUnet/src/applications/dht/tools/dht-query.c       2008-02-17 07:50:48 UTC 
(rev 6348)
@@ -62,14 +62,16 @@
 
 static int
 printCallback (const GNUNET_HashCode * hash,
-               const GNUNET_DataContainer * data, void *cls)
+              unsigned int type,
+              unsigned int size,
+               const char * data, void *cls)
 {
   char *key = cls;
   printf ("%s(%s): '%.*s'\n",
           "get",
           key,
-          (int) (ntohl (data->size) - sizeof (GNUNET_DataContainer)),
-          (char *) &data[1]);
+          size,
+          data);
   return GNUNET_OK;
 }
 
@@ -99,13 +101,9 @@
 do_put (struct GNUNET_ClientServerConnection *sock,
         const char *key, const char *value)
 {
-  GNUNET_DataContainer *dc;
   GNUNET_HashCode hc;
 
   GNUNET_hash (key, strlen (key), &hc);
-  dc = GNUNET_malloc (sizeof (GNUNET_DataContainer) + strlen (value));
-  dc->size = htonl (strlen (value) + sizeof (GNUNET_DataContainer));
-  memcpy (&dc[1], value, strlen (value));
 #if DEBUG_DHT_QUERY
   GNUNET_GE_LOG (ectx,
                  GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
@@ -115,7 +113,8 @@
     timeout = 30 * GNUNET_CRON_MINUTES;
   if (GNUNET_OK ==
       GNUNET_DHT_put (cfg, ectx, &hc, GNUNET_ECRS_BLOCKTYPE_DHT_STRING2STRING,
-                      dc))
+                      strlen(value),
+                     value))
     {
       printf (_("'%s(%s,%s)' succeeded\n"), "put", key, value);
     }
@@ -123,7 +122,6 @@
     {
       printf (_("'%s(%s,%s)' failed.\n"), "put", key, value);
     }
-  GNUNET_free (dc);
 }
 
 int

Modified: GNUnet/src/applications/dht/tools/dht_api.c
===================================================================
--- GNUnet/src/applications/dht/tools/dht_api.c 2008-02-17 04:58:52 UTC (rev 
6347)
+++ GNUnet/src/applications/dht/tools/dht_api.c 2008-02-17 07:50:48 UTC (rev 
6348)
@@ -46,7 +46,7 @@
   /**
    * Callback to call for each result.
    */
-  GNUNET_DataProcessor processor;
+  GNUNET_ResultProcessor processor;
 
   /**
    * Extra argument for processor.
@@ -81,7 +81,6 @@
   GetInfo *info = cls;
   GNUNET_MessageHeader *reply;
   CS_dht_request_put_MESSAGE *put;
-  GNUNET_DataContainer *cont;
   unsigned int size;
 
   while (info->aborted == GNUNET_NO)
@@ -100,15 +99,13 @@
         }
       size = ntohs (reply->size) - sizeof (CS_dht_request_put_MESSAGE);
       put = (CS_dht_request_put_MESSAGE *) reply;
-      if (info->processor != NULL)
-        {
-          cont = GNUNET_malloc (sizeof (GNUNET_DataContainer) + size);
-          cont->size = htonl (sizeof (GNUNET_DataContainer) + size);
-          memcpy (&cont[1], &put[1], size);
-          if (GNUNET_OK != info->processor (&put->key, cont, info->closure))
-            info->aborted = GNUNET_YES;
-          GNUNET_free (cont);
-        }
+      if ( (info->processor != NULL) &&
+          (GNUNET_OK != info->processor (&put->key, 
+                                         0 /* unknown! */, 
+                                         size,
+                                         (const char*) &put[1],
+                                         info->closure)) )
+       info->aborted = GNUNET_YES;        
       info->total++;
       GNUNET_free (reply);
     }
@@ -142,7 +139,7 @@
                 struct GNUNET_GE_Context *ectx,
                 unsigned int type,
                 const GNUNET_HashCode * key,
-                GNUNET_CronTime timeout, GNUNET_DataProcessor processor,
+                GNUNET_CronTime timeout, GNUNET_ResultProcessor processor,
                 void *closure)
 {
   struct GNUNET_ClientServerConnection *sock;
@@ -206,7 +203,9 @@
 GNUNET_DHT_put (struct GNUNET_GC_Configuration *cfg,
                 struct GNUNET_GE_Context *ectx,
                 const GNUNET_HashCode * key,
-                unsigned int type, const GNUNET_DataContainer * value)
+                unsigned int type, 
+               unsigned int size,
+               const char * value)
 {
   struct GNUNET_ClientServerConnection *sock;
   CS_dht_request_put_MESSAGE *req;
@@ -216,24 +215,19 @@
   GNUNET_GE_LOG (ectx,
                  GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
                  "DHT_LIB_put called with value '%.*s'\n",
-                 ntohl (value->size), &value[1]);
+                 size, value);
 #endif
   sock = GNUNET_client_connection_create (ectx, cfg);
   if (sock == NULL)
     return GNUNET_SYSERR;
-  GNUNET_GE_ASSERT (NULL,
-                    ntohl (value->size) >= sizeof (GNUNET_DataContainer));
   req =
-    GNUNET_malloc (sizeof (CS_dht_request_put_MESSAGE) + ntohl (value->size) -
-                   sizeof (GNUNET_DataContainer));
+    GNUNET_malloc (sizeof (CS_dht_request_put_MESSAGE) + size);
   req->header.size =
-    htons (sizeof (CS_dht_request_put_MESSAGE) + ntohl (value->size) -
-           sizeof (GNUNET_DataContainer));
+    htons (sizeof (CS_dht_request_put_MESSAGE) + size);
   req->header.type = htons (GNUNET_CS_PROTO_DHT_REQUEST_PUT);
   req->key = *key;
   req->type = htonl (type);
-  memcpy (&req[1], &value[1],
-          ntohl (value->size) - sizeof (GNUNET_DataContainer));
+  memcpy (&req[1], value, size);
   ret = GNUNET_client_connection_write (sock, &req->header);
   GNUNET_client_connection_destroy (sock);
   GNUNET_free (req);

Modified: GNUnet/src/applications/fs/collection/collection.c
===================================================================
--- GNUnet/src/applications/fs/collection/collection.c  2008-02-17 04:58:52 UTC 
(rev 6347)
+++ GNUnet/src/applications/fs/collection/collection.c  2008-02-17 07:50:48 UTC 
(rev 6348)
@@ -36,7 +36,6 @@
  */
 
 #include "platform.h"
-#include "gnunet_blockstore.h"
 #include "gnunet_directories.h"
 #include "gnunet_collection_lib.h"
 #include "gnunet_util.h"

Modified: GNUnet/src/applications/fs/fsui/deserialize.c
===================================================================
--- GNUnet/src/applications/fs/fsui/deserialize.c       2008-02-17 04:58:52 UTC 
(rev 6347)
+++ GNUnet/src/applications/fs/fsui/deserialize.c       2008-02-17 07:50:48 UTC 
(rev 6348)
@@ -362,12 +362,13 @@
       GNUNET_GE_BREAK (NULL, 0);
       return GNUNET_SYSERR;
     }
+  ctx->collectionDataSize = big;
   ctx->collectionData = GNUNET_malloc (big);
-  if (big - sizeof (unsigned int) !=
-      READ (fd, &ctx->collectionData[1], big - sizeof (unsigned int)))
+  if (big != READ (fd, ctx->collectionData, big))
     {
       GNUNET_free (ctx->collectionData);
       ctx->collectionData = NULL;
+      ctx->collectionDataSize = 0;
       GNUNET_GE_BREAK (NULL, 0);
       return GNUNET_SYSERR;
     }

Modified: GNUnet/src/applications/fs/fsui/fsui.h
===================================================================
--- GNUnet/src/applications/fs/fsui/fsui.h      2008-02-17 04:58:52 UTC (rev 
6347)
+++ GNUnet/src/applications/fs/fsui/fsui.h      2008-02-17 07:50:48 UTC (rev 
6348)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other 
contributing authors)
+     (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008 Christian Grothoff (and 
other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -29,7 +29,6 @@
 #include "gnunet_util.h"
 #include "gnunet_util_cron.h"
 #include "gnunet_ecrs_lib.h"
-#include "gnunet_blockstore.h"
 
 /**
  * Track record for a given result.
@@ -408,7 +407,9 @@
   /**
    * Collection related data.
    */
-  GNUNET_DataContainer *collectionData;
+  char * collectionData;
+  
+  unsigned int collectionDataSize;
 
   /**
    * List of active searches.

Modified: GNUnet/src/applications/fs/fsui/serialize.c
===================================================================
--- GNUnet/src/applications/fs/fsui/serialize.c 2008-02-17 04:58:52 UTC (rev 
6347)
+++ GNUnet/src/applications/fs/fsui/serialize.c 2008-02-17 07:50:48 UTC (rev 
6348)
@@ -174,13 +174,14 @@
 writeCollection (int fd, struct GNUNET_FSUI_Context *ctx)
 {
   if ((ctx->collectionData == NULL) ||
-      (ctx->collectionData->size > 16 * 1024 * 1024))
+      (ctx->collectionDataSize > 16 * 1024 * 1024))
     {
       WRITEINT (fd, 0);
       return;
     }
   /* serialize collection data */
-  WRITE (fd, ctx->collectionData, ntohl (ctx->collectionData->size));
+  WRITEINT(fd, ctx->collectionDataSize);
+  WRITE (fd, ctx->collectionData, ctx->collectionDataSize);
 }
 
 static void

Modified: GNUnet/src/applications/fs/gap/fs_dht.c
===================================================================
--- GNUnet/src/applications/fs/gap/fs_dht.c     2008-02-17 04:58:52 UTC (rev 
6347)
+++ GNUnet/src/applications/fs/gap/fs_dht.c     2008-02-17 07:50:48 UTC (rev 
6348)
@@ -130,20 +130,15 @@
  */
 static int
 response_callback (const GNUNET_HashCode * key,
-                   const GNUNET_DataContainer * value, void *cls)
+                  unsigned int type,
+                  unsigned int size,              
+                   const char * value, void *cls)
 {
   struct ActiveRequestRecords *record = cls;
-  unsigned int size;
   const DBlock *dblock;
   GNUNET_HashCode hc;
 
-  size = ntohl (value->size);
-  if (size < 4)
-    {
-      GNUNET_GE_BREAK_OP (NULL, 0);
-      return GNUNET_OK;
-    }
-  dblock = (const DBlock *) &value[1];
+  dblock = (const DBlock *) value;
   if ((GNUNET_SYSERR ==
        GNUNET_EC_file_block_check_and_get_query (size,
                                                  dblock,

Modified: GNUnet/src/applications/rpc/parameters.c
===================================================================
--- GNUnet/src/applications/rpc/parameters.c    2008-02-17 04:58:52 UTC (rev 
6347)
+++ GNUnet/src/applications/rpc/parameters.c    2008-02-17 07:50:48 UTC (rev 
6348)
@@ -1,6 +1,6 @@
 /*
       This file is part of GNUnet
-      (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+      (C) 2004, 2005, 2006, 2008 Christian Grothoff (and other contributing 
authors)
 
       GNUnet is free software; you can redistribute it and/or modify
       it under the terms of the GNU General Public License as published
@@ -30,25 +30,35 @@
 #include "platform.h"
 
 /**
- * A parameter to/from an RPC call. These (and nothing else) are stored in
- * the GNUNET_Vector of the GNUNET_RPC_CallParameters structure.
+ * A linked list of parameters to/from an RPC call. 
  */
-typedef struct
+struct Parameter 
 {
+  struct Parameter * next;
+  char * name;
+  void * data;
   unsigned int dataLength;
-  char *name;
-  void *data;
-} Parameter;
+};
 
+struct GNUNET_RPC_CallParameters 
+{
+  struct Parameter * list;
+};
+
+
 /**
  * Allocate a new, empty RPC parameter structure.
  *
  * @return An empty GNUNET_RPC_CallParameters structure
  */
-GNUNET_RPC_CallParameters *
+struct GNUNET_RPC_CallParameters *
 GNUNET_RPC_parameters_create ()
 {
-  return GNUNET_vector_create (4);
+  struct GNUNET_RPC_CallParameters * ret;
+
+  ret = GNUNET_malloc(sizeof(struct GNUNET_RPC_CallParameters));
+  ret->list = NULL;
+  return ret;
 }
 
 /**
@@ -59,18 +69,19 @@
  * @param param The RPC parameter structure to be freed
  */
 void
-GNUNET_RPC_parameters_destroy (GNUNET_RPC_CallParameters * param)
+GNUNET_RPC_parameters_destroy (struct GNUNET_RPC_CallParameters * param)
 {
   if (param == NULL)
     return;
-  while (GNUNET_vector_get_size (param) > 0)
+  while (param->list != NULL)
     {
-      Parameter *p = GNUNET_vector_delete_last (param);
+      struct Parameter *p = param->list;
+      param->list = p->next;
       GNUNET_free (p->name);
       GNUNET_free (p->data);
       GNUNET_free (p);
     }
-  GNUNET_vector_destroy (param);
+  GNUNET_free(param);
 }
 
 /**
@@ -78,43 +89,40 @@
  * GNUNET_RPC_parameters_get_serialized_size(param) bytes of memory.
  */
 void
-GNUNET_RPC_parameters_serialize (GNUNET_RPC_CallParameters * param,
+GNUNET_RPC_parameters_serialize (const struct GNUNET_RPC_CallParameters * 
param,
                                  char *target)
 {
-  int i;
-  const char *paramName;
+  const struct Parameter *pos;
   unsigned int dataLength;
-  void *paramValue;
-  size_t pos;
+  size_t off;
 
   if (param == NULL)
     return;
   if (target == NULL)
     return;
-  pos = 0;
+  off = 0;
   dataLength = 0;
-  for (i = 0; i < GNUNET_RPC_parameters_count (param); i++)
+  pos = param->list;
+  while (pos != NULL) 
     {
-      paramName = GNUNET_RPC_parameters_get_name (param, i);
-      paramValue = NULL;
-      GNUNET_RPC_parameters_get_value_by_index (param, i, &dataLength,
-                                                &paramValue);
-      memcpy (&target[pos], paramName, strlen (paramName) + 1);
-      pos += strlen (paramName) + 1;
-      *(unsigned int *) &target[pos] = htonl (dataLength);
-      pos += sizeof (unsigned int);
-      memcpy (&target[pos], paramValue, dataLength);
-      pos += dataLength;
+      memcpy (&target[off], pos->name, strlen (pos->name) + 1);
+      off += strlen (pos->name) + 1;
+      dataLength = htonl(pos->dataLength);
+      memcpy(&target[off], &dataLength, sizeof(unsigned int));
+      off += sizeof (unsigned int);
+      memcpy (&target[off], pos->data, pos->dataLength);
+      off += pos->dataLength;
+      pos = pos->next;
     }
 }
 
 /**
  * Deserialize parameters from buffer.
  */
-GNUNET_RPC_CallParameters *
-GNUNET_RPC_parameters_deserialize (char *buffer, size_t size)
+struct GNUNET_RPC_CallParameters *
+GNUNET_RPC_parameters_deserialize (const char *buffer, size_t size)
 {
-  GNUNET_RPC_CallParameters *ret;
+  struct GNUNET_RPC_CallParameters *ret;
   size_t pos;
   size_t xpos;
   unsigned int dataLength;
@@ -134,15 +142,19 @@
           GNUNET_RPC_parameters_destroy (ret);
           return NULL;
         }
-      dataLength = ntohl (*(unsigned int *) &buffer[pos]);
+      memcpy(&dataLength,
+            &buffer[pos],
+            sizeof(unsigned int));
+      dataLength = ntohl(dataLength);
       pos += sizeof (unsigned int);
       if ((pos + dataLength < pos) || (pos + dataLength > size))
         {
           GNUNET_RPC_parameters_destroy (ret);
           return NULL;
         }
-
-      GNUNET_RPC_parameters_add (ret, &buffer[xpos], dataLength,
+      GNUNET_RPC_parameters_add (ret, 
+                                &buffer[xpos], 
+                                dataLength,
                                  &buffer[pos]);
       pos += dataLength;
     }
@@ -153,36 +165,26 @@
  * How many bytes are required to serialize the param array?
  */
 size_t
-GNUNET_RPC_parameters_get_serialized_size (GNUNET_RPC_CallParameters * param)
+GNUNET_RPC_parameters_get_serialized_size (const struct 
GNUNET_RPC_CallParameters * param)
 {
-  int i;
-  const char *paramName;
-  unsigned int dataLength;
-  void *paramValue;
-  size_t pos;
+  const struct Parameter *pos;
+  size_t off;
 
   if (param == NULL)
     return 0;
-  pos = 0;
-  dataLength = 0;
-  for (i = 0; i < GNUNET_RPC_parameters_count (param); i++)
+  off = 0;
+  pos = param->list;
+  while (pos != NULL) {
     {
-      paramName = GNUNET_RPC_parameters_get_name (param, i);
-      paramValue = NULL;
-      GNUNET_RPC_parameters_get_value_by_index (param, i, &dataLength,
-                                                &paramValue);
-      if (pos + strlen (paramName) + 1 + sizeof (unsigned int) < pos)
-        return 0;
-      pos += strlen (paramName) + 1;
-      pos += sizeof (unsigned int);
-      if (pos + dataLength < pos)
-        return 0;
-      pos += dataLength;
+      off += strlen (pos->name) + 1;
+      off += sizeof (unsigned int);
+      off += pos->dataLength;
+      pos = pos->next;
     }
-  return pos;
+  }
+  return off;
 }
 
-
 /**
  * Return the number of parameters in an RPC parameter structure.
  *
@@ -190,11 +192,19 @@
  * @return The number of parameters
  */
 unsigned int
-GNUNET_RPC_parameters_count (GNUNET_RPC_CallParameters * param)
+GNUNET_RPC_parameters_count (const struct GNUNET_RPC_CallParameters * param)
 {
-  if (param == NULL)
-    return 0;
-  return GNUNET_vector_get_size (param);
+  const struct Parameter *pos;
+  unsigned int s;
+
+  s = 0;
+  pos = param->list;
+  while (pos != NULL)
+    {
+      s++;
+      pos = pos->next;
+    }
+  return s;
 }
 
 
@@ -211,89 +221,42 @@
  */
 
 void
-GNUNET_RPC_parameters_add (GNUNET_RPC_CallParameters * param,
+GNUNET_RPC_parameters_add (struct GNUNET_RPC_CallParameters * param,
                            const char *name, unsigned int dataLength,
                            const void *data)
 {
-  Parameter *new;
+  struct Parameter *p;
+  struct Parameter *pos;
 
   if (param == NULL)
     return;
-  new = GNUNET_malloc (sizeof (Parameter));
-  new->name = GNUNET_strdup (name);
-  new->dataLength = dataLength;
+  p = GNUNET_malloc (sizeof (struct Parameter));
+  p->name = GNUNET_strdup (name);
+  p->dataLength = dataLength;
   if (dataLength == 0)
     {
-      new->data = NULL;
+      p->data = NULL;
     }
   else
     {
-      new->data = GNUNET_malloc (dataLength);
-      memcpy (new->data, data, dataLength);
+      p->data = GNUNET_malloc (dataLength);
+      memcpy (p->data, data, dataLength);
     }
-  GNUNET_vector_insert_last (param, new);
-}
-
-
-/**
- * Add a new parameter to the RPC parameter structure. The parameter name and
- * value are copied to memory private to the RPC parameter collection. The
- * pointers returned by other functions point to this private memory and should
- * not be freed by the user of the abstraction.
- *
- * @param param Target RPC parameter structure
- * @param name Name of the parameter
- * @param dataLength Length of the value of the parameter
- * @param data Value of the parameter
- */
-void
-GNUNET_RPC_parameters_add_data_container (GNUNET_RPC_CallParameters * param,
-                                          const char *name,
-                                          const GNUNET_DataContainer * data)
-{
-  Parameter *new;
-
-  if (param == NULL)
-    return;
-  new = GNUNET_malloc (sizeof (Parameter));
-  new->name = GNUNET_strdup (name);
-  new->dataLength = ntohl (data->size) - sizeof (GNUNET_DataContainer);
-  if (new->dataLength == 0)
+  p->next = NULL;
+  if (param->list == NULL)
     {
-      new->data = NULL;
+      param->list = p;
     }
   else
     {
-      new->data = GNUNET_malloc (new->dataLength);
-      memcpy (new->data, &data[1], new->dataLength);
+      pos = param->list;
+      while (pos->next != NULL)
+       pos = pos->next;
+      pos->next = p;
     }
-  GNUNET_vector_insert_last (param, new);
 }
 
 /**
- * Return the name of the given parameter in the RPC parameter structure, the
- * first parameter being parameter number zero.
- *
- * @param param Target RPC parameter structure
- * @return Name of the parameter
- */
-const char *
-GNUNET_RPC_parameters_get_name (GNUNET_RPC_CallParameters * param,
-                                unsigned int i)
-{
-  Parameter *p;
-
-  if (param == NULL)
-    return NULL;
-  p = GNUNET_vector_get (param, i);
-  if (p)
-    return p->name;
-  else
-    return NULL;
-}
-
-
-/**
  * Return the value of the named parameter in the RPC parameter structure.
  *
  * @param param Target RPC parameter structure
@@ -301,16 +264,16 @@
  * @return GNUNET_SYSERR on error
  */
 int
-GNUNET_RPC_parameters_get_value_by_name (GNUNET_RPC_CallParameters * param,
+GNUNET_RPC_parameters_get_value_by_name (const struct 
GNUNET_RPC_CallParameters * param,
                                          const char *name,
                                          unsigned int *dataLength,
-                                         void **value)
+                                         void const * *value)
 {
-  Parameter *p;
+  const struct Parameter *p;
 
   if (param == NULL)
     return GNUNET_SYSERR;
-  p = GNUNET_vector_get_first (param);
+  p = param->list;
   while (p != NULL)
     {
       if (!strcmp (p->name, name))
@@ -319,61 +282,34 @@
           *dataLength = p->dataLength;
           return GNUNET_OK;
         }
-      p = GNUNET_vector_get_next (param);
+      p = p->next;
     }
-
   return GNUNET_SYSERR;
 }
 
 /**
- * Return the value of the named parameter in the RPC parameter structure.
- *
- * @param param Target RPC parameter structure
- * @param value set to the value of the named parameter
- * @return GNUNET_SYSERR on error
- */
-GNUNET_DataContainer *
-GNUNET_RPC_parameters_get_data_container_by_name (GNUNET_RPC_CallParameters *
-                                                  param, const char *name)
-{
-  Parameter *p;
-  GNUNET_DataContainer *ret;
-
-  if (param == NULL)
-    return NULL;
-  p = GNUNET_vector_get_first (param);
-  while (p != NULL)
-    {
-      if (!strcmp (p->name, name))
-        {
-          ret = GNUNET_malloc (sizeof (GNUNET_DataContainer) + p->dataLength);
-          ret->size = htonl (sizeof (GNUNET_DataContainer) + p->dataLength);
-          memcpy (&ret[1], p->data, p->dataLength);
-          return ret;
-        }
-      p = GNUNET_vector_get_next (param);
-    }
-
-  return NULL;
-}
-
-/**
  * Return the value of the given parameter in the RPC parameter structure.
  *
  * @param param Target RPC parameter structure
  * @param value set to the value of the parameter
  */
 int
-GNUNET_RPC_parameters_get_value_by_index (GNUNET_RPC_CallParameters * param,
+GNUNET_RPC_parameters_get_value_by_index (const struct 
GNUNET_RPC_CallParameters * param,
                                           unsigned int i,
                                           unsigned int *dataLength,
-                                          void **value)
+                                          void const **value)
 {
-  Parameter *p;
+  struct Parameter *p;
 
   if (param == NULL)
     return GNUNET_SYSERR;
-  p = GNUNET_vector_get (param, i);
+  p = param->list;
+  while ( (i > 0) &&
+         (p != NULL) )
+    {
+      i--;
+      p = p->next;
+    }
   if (p != NULL)
     {
       *dataLength = p->dataLength;
@@ -383,30 +319,4 @@
   return GNUNET_SYSERR;
 }
 
-/**
- * Return the value of the given parameter in the RPC parameter structure.
- *
- * @param param Target RPC parameter structure
- * @param value set to the value of the parameter
- */
-GNUNET_DataContainer *
-GNUNET_RPC_parameters_get_data_container_by_index (GNUNET_RPC_CallParameters *
-                                                   param, unsigned int i)
-{
-  Parameter *p;
-  GNUNET_DataContainer *ret;
-
-  if (param == NULL)
-    return NULL;
-  p = GNUNET_vector_get (param, i);
-  if (p != NULL)
-    {
-      ret = GNUNET_malloc (sizeof (GNUNET_DataContainer) + p->dataLength);
-      ret->size = htonl (sizeof (GNUNET_DataContainer) + p->dataLength);
-      memcpy (&ret[1], p->data, p->dataLength);
-      return ret;
-    }
-  return NULL;
-}
-
 /* end of parameters.c */

Modified: GNUnet/src/applications/rpc/parameterstest.c
===================================================================
--- GNUnet/src/applications/rpc/parameterstest.c        2008-02-17 04:58:52 UTC 
(rev 6347)
+++ GNUnet/src/applications/rpc/parameterstest.c        2008-02-17 07:50:48 UTC 
(rev 6348)
@@ -1,6 +1,6 @@
 /*
       This file is part of GNUnet
-      (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+      (C) 2004, 2005, 2006, 2008 Christian Grothoff (and other contributing 
authors)
 
       GNUnet is free software; you can redistribute it and/or modify
       it under the terms of the GNU General Public License as published
@@ -29,8 +29,9 @@
 int
 main (int argc, char *argv[])
 {
-  GNUNET_RPC_CallParameters *p;
-  void *buf;
+  struct GNUNET_RPC_CallParameters *p;
+  const void *buf;
+  void *wbuf;
   size_t size;
   unsigned int len;
 
@@ -50,17 +51,12 @@
   GNUNET_RPC_parameters_add (p, "bar", 4, "foo");
   if (GNUNET_RPC_parameters_count (p) != 2)
     return 1;
-  if (0 != strcmp (GNUNET_RPC_parameters_get_name (p, 0), "foo"))
-    return 1;
-  if (0 != strcmp (GNUNET_RPC_parameters_get_name (p, 1), "bar"))
-    return 1;
-
   size = GNUNET_RPC_parameters_get_serialized_size (p);
-  buf = GNUNET_malloc (size);
-  GNUNET_RPC_parameters_serialize (p, buf);
+  wbuf = GNUNET_malloc (size);
+  GNUNET_RPC_parameters_serialize (p, wbuf);
   GNUNET_RPC_parameters_destroy (p);
-  p = GNUNET_RPC_parameters_deserialize (buf, size);
-  GNUNET_free (buf);
+  p = GNUNET_RPC_parameters_deserialize (wbuf, size);
+  GNUNET_free (wbuf);
   if (p == NULL)
     return 1;
   buf = NULL;

Modified: GNUnet/src/applications/rpc/rpc.c
===================================================================
--- GNUnet/src/applications/rpc/rpc.c   2008-02-17 04:58:52 UTC (rev 6347)
+++ GNUnet/src/applications/rpc/rpc.c   2008-02-17 07:50:48 UTC (rev 6348)
@@ -1,5 +1,6 @@
 /*
       This file is part of GNUnet
+      (C) 2003, 2005, 2008 Christian Grothoff (and other contributing authors)
 
       GNUnet is free software; you can redistribute it and/or modify
       it under the terms of the GNU General Public License as published
@@ -18,8 +19,8 @@
 */
 
 /**
- * @file module/dht_rpc.c
- * @brief Implementation of RPC's
+ * @file rpc/module/rpc.c
+ * @brief Implementation of RPCs
  * @author Antti Salonen, Christian Grothoff
  */
 
@@ -30,566 +31,186 @@
 #include "gnunet_rpc_lib.h"
 
 /**
- * Flag that determines if the RPC test will be build as
- * an application module.
+ * Maximum number of concurrent RPCs that we support per peer.
  */
-#define PROVIDE_RPC_TEST GNUNET_YES
+#define RPC_MAX_REQUESTS_PER_PEER 16
 
 /**
- * Print messages helpful for debugging the RPC code.
+ * Maximum number of retries done for sending of responses.
  */
-#define DEBUG_RPC GNUNET_NO
+#define RPC_MAX_REPLY_ATTEMPTS 3
 
 /**
- * Print messages helpful for debugging RPC clients.
+ * Granularity for the RPC cron job.
  */
-#define DEBUG_RPC_CLIENT GNUNET_NO
+#define RPC_CRON_FREQUENCY (500 * GNUNET_CRON_MILLISECONDS)
 
 /**
- * Minimum delay between retry attempts for RPC messages.
- */
-#define MIN_RPC_FREQUENCY (50 * GNUNET_CRON_MILLISECONDS)
-
-/**
  * Initial minimum delay between retry attempts for RPC messages
  * (before we figure out how fast the connection really is).
  */
-#define INITIAL_RPC_FREQUENCY (15 * GNUNET_CRON_SECONDS)
+#define RPC_INITIAL_ROUND_TRIP_TIME (15 * GNUNET_CRON_SECONDS)
 
 /**
  * After what time do we time-out every request (if it is not
  * repeated)?
  */
-#define MAX_RPC_TIMEOUT (2 * GNUNET_CRON_MINUTES)
+#define RPC_INTERNAL_PROCESSING_TIMEOUT (2 * GNUNET_CRON_MINUTES)
 
 
-#if DEBUG_RPC_CLIENT
-#define RPC_STATUS(a,b,c) GNUNET_GE_LOG(ectx, GNUNET_GE_DEBUG | 
GNUNET_GE_REQUEST | GNUNET_GE_USER, "RPC: `%s' (%p) %s at %s\n", a, c, b, 
__FUNCTION__);
-#else
-#define RPC_STATUS(a,b,c)
-#endif
-
-
 /**
- * Access to GNUnet core API.
+ * @brief Request to execute an function call on the remote peer.  The
+ * message is of variable size to pass arguments.  Requests and reply
+ * messages use the same struct, the only difference is in the value
+ * of the header.type field.  
  */
-static GNUNET_CoreAPIForPlugins *coreAPI = NULL;
-
-/**
- * A mutex for synchronous access to all module-wide data structures. This
- * lock must be held by the thread that accesses any module-wide accessable
- * data structures.
- */
-static struct GNUNET_Mutex *rpcLock;
-
-static struct GNUNET_GE_Context *ectx;
-
-/* *************** RPC registration ****************** */
-
-/**
- * An RPC registered by the local node.
- */
 typedef struct
 {
-  char *name;
+  GNUNET_MessageHeader header;
+
   /**
-   * Callback for a synchronous RPC.  NULL for async RPCs.
+   * Timestamp (of the sender of this message).
    */
-  GNUNET_RPC_SynchronousFunction callback;
+  GNUNET_Int32Time timestamp;
+  
+  /**
+   * Sequence number (of the initiator).
+   */
+  unsigned int sequenceNumber;
+  
+  /**
+   * How important is this message?
+   */
+  unsigned int importance;
 
   /**
-   * Callback for an asynchronous RPC.  NULL for sync RPCs.
+   * Number of arguments or return values.  Must be 0
+   * if this message communicates an error.
    */
-  GNUNET_RPC_AsynchronousFunction async_callback;
-} RegisteredRPC;
+  unsigned int argumentCount;
 
-/**
- * A set of RegisteredRPC structures, one for each RPC registered by the
- * local node.
- */
-static struct GNUNET_Vector *list_of_callbacks;
+  /**
+   * For the request, this is the length of the
+   * name of the function.  For a response,
+   * this is the status.
+   */
+  unsigned int functionNameLength;
+} P2P_rpc_MESSAGE;
 
-
 /**
- * Registers an RPC callback under the given name.
- * @param name the name of the callback, must not be NULL
- * @param callback the function to call
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
- *   (typically if a callback of that name is already in use).
+ * An ACK message.  An ACK acknowledges the receiving a reply to an
+ * RPC call (three-way handshake).  Without an ACK, the receiver of an
+ * RPC request is supposed to repeatedly send the RPC reply (until it
+ * times out).
  */
-static int
-RPC_register (const char *name, GNUNET_RPC_SynchronousFunction callback)
+typedef struct
 {
-  RegisteredRPC *rrpc;
+  GNUNET_MessageHeader header;
+  /**
+   * The number of the original request for which this is the
+   * ACK.
+   */
+  unsigned int sequenceNumber;
+} RPC_ACK_Message;
 
-  GNUNET_GE_ASSERT (ectx, name != NULL);
-  GNUNET_GE_ASSERT (ectx, callback != NULL);
-  GNUNET_mutex_lock (rpcLock);
-  rrpc = GNUNET_vector_get_first (list_of_callbacks);
-  while (rrpc != NULL)
-    {
-      if (0 == strcmp (rrpc->name, name))
-        {
-          GNUNET_mutex_unlock (rpcLock);
-          GNUNET_GE_LOG (ectx,
-                         GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
-                         _("%s::%s - RPC %s:%p could not be registered:"
-                           " another callback is already using this name 
(%p)\n"),
-                         __FILE__, __FUNCTION__, name, callback,
-                         rrpc->callback);
-          return GNUNET_SYSERR;
-        }
-      rrpc = GNUNET_vector_get_next (list_of_callbacks);
-    }
-  rrpc = GNUNET_malloc (sizeof (RegisteredRPC));
-  rrpc->name = GNUNET_strdup (name);
-  rrpc->callback = callback;
-  rrpc->async_callback = NULL;
-  GNUNET_vector_insert_last (list_of_callbacks, rrpc);
-  GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "%s::%s - Registered RPC %d: %s\n",
-                 __FILE__, __FUNCTION__,
-                 GNUNET_vector_get_size (list_of_callbacks), name);
-  GNUNET_mutex_unlock (rpcLock);
-  return GNUNET_OK;
-}
-
 /**
- * Registers an async RPC callback under the given name.
- * @param name the name of the callback, must not be NULL
- * @param callback the function to call
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
- *   (typically if a callback of that name is already in use).
+ * These structures are allocated while a peer
+ * is handling an RPC request.
  */
-static int
-RPC_register_async (const char *name,
-                    GNUNET_RPC_AsynchronousFunction callback)
+struct GNUNET_RPC_CallHandle
 {
-  RegisteredRPC *rrpc;
+  struct GNUNET_RPC_CallHandle * next;
 
-  GNUNET_GE_ASSERT (ectx, name != NULL);
-  GNUNET_GE_ASSERT (ectx, callback != NULL);
-  GNUNET_mutex_lock (rpcLock);
-  rrpc = GNUNET_vector_get_first (list_of_callbacks);
-  while (rrpc != NULL)
-    {
-      if (0 == strcmp (rrpc->name, name))
-        {
-          GNUNET_mutex_unlock (rpcLock);
-          GNUNET_GE_LOG (ectx,
-                         GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
-                         _("%s::%s - RPC %s:%p could not be registered:"
-                           " another callback is already using this name 
(%p)\n"),
-                         __FILE__, __FUNCTION__, name, callback,
-                         rrpc->callback);
-          return GNUNET_SYSERR;
-        }
-      rrpc = GNUNET_vector_get_next (list_of_callbacks);
-    }
-  rrpc = GNUNET_malloc (sizeof (RegisteredRPC));
-  rrpc->name = GNUNET_strdup (name);
-  rrpc->callback = NULL;
-  rrpc->async_callback = callback;
-  GNUNET_vector_insert_last (list_of_callbacks, rrpc);
-  GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "%s::%s - Registered asynchronous RPC %d: %s\n",
-                 __FILE__, __FUNCTION__,
-                 GNUNET_vector_get_size (list_of_callbacks), name);
-  GNUNET_mutex_unlock (rpcLock);
-  return GNUNET_OK;
-}
+  struct GNUNET_RPC_CallHandle * prev;
 
+  /**
+   * The message we are transmitting.  NULL
+   * if our local RPC invocation has not
+   * yet completed.  NON-NULL if we are
+   * waiting for the ACK.
+   */
+  P2P_rpc_MESSAGE *msg;
 
-/**
- * Unregisters an RPC callback of the given name.
- * @param name the name of the callback, must not be NULL
- * @param callback the function to unregister, NULL for any function
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
- *   (typically if a callback of that name does not exist or is
- *    bound to a different function).
- */
-static int
-RPC_unregister (const char *name, GNUNET_RPC_SynchronousFunction callback)
-{
-  RegisteredRPC *rrpc;
+  /**
+   * Name of the local RPC function that we
+   * have been calling.
+   */ 
+  char * function_name;
 
-  GNUNET_GE_ASSERT (ectx, name != NULL);
-  GNUNET_mutex_lock (rpcLock);
-  rrpc = GNUNET_vector_get_first (list_of_callbacks);
-  while (rrpc != NULL)
-    {
-      if (0 == strcmp (rrpc->name, name))
-        {
-          if ((rrpc->callback != callback) && (callback != NULL))
-            {
-              GNUNET_GE_LOG (ectx,
-                             GNUNET_GE_WARNING | GNUNET_GE_BULK |
-                             GNUNET_GE_USER,
-                             _("%s::%s - RPC %s:%p could not be unregistered:"
-                               " another callback registered under that name: 
%p\n"),
-                             __FILE__, __FUNCTION__, name, callback,
-                             rrpc->callback);
-              GNUNET_mutex_unlock (rpcLock);
-              return GNUNET_SYSERR;
-            }
-          GNUNET_vector_delete (list_of_callbacks, rrpc);
-          GNUNET_free (rrpc->name);
-          GNUNET_free (rrpc);
-          GNUNET_mutex_unlock (rpcLock);
-          GNUNET_GE_LOG (ectx,
-                         GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                         "%s::%s - Unregistered RPC %s\n", __FILE__,
-                         __FUNCTION__, name);
-          return GNUNET_OK;
-        }
-      rrpc = GNUNET_vector_get_next (list_of_callbacks);
-    }
-  GNUNET_mutex_unlock (rpcLock);
-  GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
-                 _
-                 ("%s::%s - RPC %s:%p could not be unregistered: not found\n"),
-                 __FILE__, __FUNCTION__, name, callback);
-  return GNUNET_SYSERR;
-}
+  /**
+   * For which peer is this response?
+   */
+  GNUNET_PeerIdentity initiator;
 
-/**
- * Unregisters an asynchronous RPC callback of the given name.
- * @param name the name of the callback, must not be NULL
- * @param callback the function to unregister, NULL for any function
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
- *   (typically if a callback of that name does not exist or is
- *    bound to a different function).
- */
-static int
-RPC_unregister_async (const char *name,
-                      GNUNET_RPC_AsynchronousFunction callback)
-{
-  RegisteredRPC *rrpc;
-
-  GNUNET_GE_ASSERT (ectx, name != NULL);
-  GNUNET_mutex_lock (rpcLock);
-  rrpc = GNUNET_vector_get_first (list_of_callbacks);
-  while (rrpc != NULL)
-    {
-      if (0 == strcmp (rrpc->name, name))
-        {
-          if ((rrpc->async_callback != callback) && (callback != NULL))
-            {
-              GNUNET_GE_LOG (ectx,
-                             GNUNET_GE_WARNING | GNUNET_GE_BULK |
-                             GNUNET_GE_USER,
-                             _("%s::%s - RPC %s:%p could not be unregistered:"
-                               " another callback registered under that name: 
%p\n"),
-                             __FILE__, __FUNCTION__, name, callback,
-                             rrpc->callback);
-              GNUNET_mutex_unlock (rpcLock);
-              return GNUNET_SYSERR;
-            }
-          GNUNET_vector_delete (list_of_callbacks, rrpc);
-          GNUNET_free (rrpc->name);
-          GNUNET_free (rrpc);
-          GNUNET_mutex_unlock (rpcLock);
-          GNUNET_GE_LOG (ectx,
-                         GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                         "%s::%s - Unregistered asynchronous RPC %s\n",
-                         __FILE__, __FUNCTION__, name);
-          return GNUNET_OK;
-        }
-      rrpc = GNUNET_vector_get_next (list_of_callbacks);
-    }
-  GNUNET_mutex_unlock (rpcLock);
-  GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
-                 _
-                 ("%s::%s - async RPC %s:%p could not be unregistered: not 
found\n"),
-                 __FILE__, __FUNCTION__, name, callback);
-  return GNUNET_SYSERR;
-}
-
-
-/* ******** tracking per peer stats to estimate turnaround ***** */
-
-/**
- * What is the time-interval for which we keep activity stats?
- */
-#define PEER_TRACKING_TIME_INTERVAL (30 * GNUNET_CRON_SECONDS)
-
-/**
- * Of how many messages do we keep track per peer (for statistics).
- */
-#define MTRACK_COUNT 64
-
-/**
- * A per-peer structure to store TCP-like data.
- */
-typedef struct
-{
-  GNUNET_PeerIdentity identity;
-
   /**
-   * What is the expected response time for this peer? (0 for unknown)
+   * Time where this record times out (timeout value for original
+   * request, fixed timeout for reply if no further requests are
+   * received; once we send the ACK the record of the sender is
+   * discarded; we always send additional ACKs even if we don't have a
+   * matching record anymore).
    */
-  GNUNET_CronTime averageResponseTime;
+  GNUNET_CronTime expirationTime;
 
   /**
-   * In which of the last 32 time intervals did we send a message?
-   * (highest bit corresponds to last time interval; if zero,
-   * the record is to be freed).
+   * Frequency at which we currently repeat the message.  Initially
+   * set to the round-trip estimate, with exponential back-off.
    */
-  unsigned int agedActivitySend;
+  GNUNET_CronTime repetitionFrequency;
 
   /**
-   * In which of the last 32 time intervals did we receive a message?
-   * (highest bit corresponds to last time interval; if zero,
-   * the record is to be freed).
+   * Last time the message was sent.
    */
-  unsigned int agedActivityRecv;
+  GNUNET_CronTime lastAttempt;
 
   /**
-   * What were the last times when requests were send to the peer?
-   * 0 for no request send *or* last request was repeated.
+   * Number of times we have attempted to transmit.
    */
-  GNUNET_CronTime lastRequestTimes[MTRACK_COUNT];
+  unsigned int attempts;
 
   /**
-   * Message ID of the last requests.
+   * Error code for the response.
    */
-  unsigned int lastRequestId[MTRACK_COUNT];
+  unsigned int errorCode;
 
   /**
-   * Index to the smallest value in lastRequestTimes.
+   * The sequence number of this RPC.
    */
-  unsigned int oldestRTIndex;
+  unsigned int sequenceNumber;
 
-} PeerInfo;
+   /**
+    * How important is this RPC?
+    */
+  unsigned int importance;
+};
 
 /**
- * A set of Peer structures, one for each GNUnet peer (as identified by
- * GNUNET_PeerIdentity) known to the RPC module. Peers are added as either 
RPC's
- * are made to them from the local node, or an RPC call is received from them.
+ * These structures are allocated while a peer
+ * is waiting for a remote RPC to return a result.
  */
-static struct GNUNET_Vector *peerInformation;
-
-static PeerInfo *
-getPeerInfo (const GNUNET_PeerIdentity * id)
+struct GNUNET_RPC_RequestHandle
 {
-  PeerInfo *pi;
+  struct GNUNET_RPC_RequestHandle * next;
 
-  pi = (PeerInfo *) GNUNET_vector_get_first (peerInformation);
-  while (pi != NULL)
-    {
-      if (0 == memcmp (id, &pi->identity, sizeof (GNUNET_PeerIdentity)))
-        return pi;
-      pi = (PeerInfo *) GNUNET_vector_get_next (peerInformation);
-    }
-  return NULL;
-}
+  struct GNUNET_RPC_RequestHandle * prev;
 
-/**
- * What is the expected response time for this peer?
- * @return 0 for unknown
- */
-static GNUNET_CronTime
-getExpectedResponseTime (const GNUNET_PeerIdentity * peer)
-{
-  GNUNET_CronTime result;
-  PeerInfo *pi;
-
-  GNUNET_mutex_lock (rpcLock);
-  pi = getPeerInfo (peer);
-  if (pi == NULL)
-    result = 0;
-  else
-    result = pi->averageResponseTime;
-  GNUNET_mutex_unlock (rpcLock);
-  return result;
-}
-
-/**
- * Cron-job used to age the peer statistics.
- */
-static void
-agePeerStats (void *unused)
-{
-  PeerInfo *pi;
-
-  GNUNET_mutex_lock (rpcLock);
-  pi = GNUNET_vector_get_first (peerInformation);
-  while (pi != NULL)
-    {
-      pi->agedActivitySend = pi->agedActivitySend / 2;
-      pi->agedActivityRecv = pi->agedActivityRecv / 2;
-      if ((pi->agedActivitySend == 0) && (pi->agedActivityRecv == 0))
-        {
-          GNUNET_vector_delete (peerInformation, pi);
-          GNUNET_free (pi);
-        }
-
-      pi = GNUNET_vector_get_next (peerInformation);
-    }
-  GNUNET_mutex_unlock (rpcLock);
-}
-
-/**
- * Ensure replies and requests have different IDs when dealing
- * with the same peer.
- */
-#define MINGLE(a,b) (((b) == GNUNET_P2P_PROTO_RPC_RES) ? (a) : (a) ^ 
0x12345678)
-
-/**
- * Notification: we sent a message to the peer.
- * @param messageID pseudo-unique ID of the request
- */
-static void
-notifyPeerRequest (GNUNET_PeerIdentity * peer, unsigned int messageID)
-{
-  int i;
-  PeerInfo *pi;
-
-  GNUNET_mutex_lock (rpcLock);
-  pi = getPeerInfo (peer);
-  if (pi != NULL)
-    {
-      for (i = 0; i < MTRACK_COUNT; i++)
-        {
-          if (pi->lastRequestId[i] == messageID)
-            {
-              pi->lastRequestTimes[i] = 0;      /* re-send! */
-              GNUNET_mutex_unlock (rpcLock);
-              return;
-            }
-        }
-      pi->agedActivitySend |= 0x80000000;
-      pi->lastRequestTimes[pi->oldestRTIndex] = GNUNET_get_time ();
-      pi->lastRequestId[pi->oldestRTIndex] = messageID;
-      pi->oldestRTIndex = (pi->oldestRTIndex + 1) % MTRACK_COUNT;
-      GNUNET_mutex_unlock (rpcLock);
-      return;
-    }
-  pi = GNUNET_malloc (sizeof (PeerInfo));
-  memset (pi, 0, sizeof (PeerInfo));
-  pi->identity = *peer;
-  pi->agedActivitySend = 0x80000000;
-  pi->lastRequestTimes[0] = GNUNET_get_time ();
-  pi->lastRequestId[0] = messageID;
-  pi->oldestRTIndex = 1;
-  GNUNET_vector_insert_last (peerInformation, pi);
-  GNUNET_mutex_unlock (rpcLock);
-}
-
-/**
- * Notification: we received a (valid) response from the peer.
- * @param messageID the ID of the message that a reply was received
- *        for
- */
-static void
-notifyPeerReply (const GNUNET_PeerIdentity * peer, unsigned int messageID)
-{
-  int i;
-  PeerInfo *pi;
-
-  GNUNET_mutex_lock (rpcLock);
-  pi = GNUNET_vector_get_first (peerInformation);
-  while (pi != NULL)
-    {
-      if (0 == memcmp (peer, &pi->identity, sizeof (GNUNET_PeerIdentity)))
-        {
-          for (i = 0; i < MTRACK_COUNT; i++)
-            {
-              if (pi->lastRequestId[i] == messageID)
-                {
-                  if (pi->lastRequestTimes[i] != 0)
-                    {           /* resend */
-                      pi->averageResponseTime
-                        = (pi->averageResponseTime * (MTRACK_COUNT - 1) +
-                           GNUNET_get_time () -
-                           pi->lastRequestTimes[i]) / MTRACK_COUNT;
-                      pi->agedActivityRecv |= 0x80000000;
-                      pi->lastRequestTimes[i] = 0;
-                    }
-                  GNUNET_mutex_unlock (rpcLock);
-                  return;
-                }
-            }
-          break;
-        }
-      pi = GNUNET_vector_get_next (peerInformation);
-    }
-  GNUNET_mutex_unlock (rpcLock);
-}
-
-/* ***************** RPC datastructures ****************** */
-
-
-/**
- * @brief Request to execute an function call on the remote peer.  The
- * message is of variable size to pass arguments.  Requests and reply
- * messages use the same struct, the only difference is in the value
- * of the header.type field.  For the reply, the
- * functionNameLength indicates the status (0 for GNUNET_OK, otherwise an
- * error code).  argumentCount must be 0 for errors and otherwise
- * indicate the number of return values.
- */
-typedef struct
-{
-  GNUNET_MessageHeader header;
-  GNUNET_Int32Time timestamp;
-  unsigned int sequenceNumber;
-  unsigned int importance;
-  unsigned short argumentCount;
-  unsigned short functionNameLength;
-} P2P_rpc_MESSAGE;
-
-/**
- * An ACK message.  An ACK acknowledges the receiving a reply to an
- * RPC call (three-way handshake).  Without an ACK, the receiver of an
- * RPC request is supposed to repeatedly send the RPC reply (until it
- * times out).
- */
-typedef struct
-{
-  GNUNET_MessageHeader header;
   /**
-   * The number of the original request for which this is the
-   * ACK.
+   * The message we are transmitting.
    */
-  unsigned int sequenceNumber;
-} RPC_ACK_Message;
+  P2P_rpc_MESSAGE *msg;
 
-/**
- * GNUNET_RSA_Signature of a function called on completion of
- * the RPC.
- * @param context closure
- * @param sequenceNumber ID of the callback
- * @param errorCode 0 on success
- * @param result the return values, NULL on error
- */
-typedef void (*RPCFinishedCallback) (void *context,
-                                     unsigned int sequenceNumber,
-                                     unsigned short errorCode,
-                                     GNUNET_RPC_CallParameters * result);
-
-/**
- * A per-RPC structure.
- */
-typedef struct GNUNET_RPC_CallHandle
-{
   /**
-   * The sequence number of this RPC.
+   * Function to call once we get a reply. 
    */
-  unsigned int sequenceNumber;
+  GNUNET_RPC_AsynchronousCompletionCallback callback;
 
+  void * cls;
+
   /**
-   * For which peer is this message?
+   * To which peer are we sending the request?
    */
   GNUNET_PeerIdentity receiver;
 
   /**
-   * The message we are transmitting (either the request or the
-   * reply).
-   */
-  P2P_rpc_MESSAGE *msg;
-
-  /**
    * Time where this record times out (timeout value for original
    * request, fixed timeout for reply if no further requests are
    * received; once we send the ACK the record of the sender is
@@ -608,41 +229,68 @@
    * Last time the message was sent.
    */
   GNUNET_CronTime lastAttempt;
-
+  
   /**
+   * The sequence number of this RPC.
+   */
+  unsigned int sequenceNumber;
+
+   /**
    * Number of times we have attempted to transmit.
    */
   unsigned int attempts;
 
+   /**
+    * How important is this RPC?
+    */
+  unsigned int importance;
+
   /**
-   * If this was a request initiated by this node we'll have to pass
-   * the result back to the original caller.  This gives the method
-   * and some context args that needs to be invoked.
+   * Error code for the response.
    */
-  RPCFinishedCallback finishedCallback;
+  unsigned int errorCode;
+};
 
+/**
+ * List of RPC handlers registered by the local node.
+ */
+struct RegisteredRPC
+{
+  struct RegisteredRPC * next;
+
   /**
-   * Arguments to the callback.
+   * Name of the RPC.
    */
-  void *rpcCallbackArgs;
+  char *name;
 
-   /**
-    * How important is this RPC?
-    */
-  unsigned int importance;
-} CallInstance;
+  /**
+   * Callback for an asynchronous RPC. 
+   */
+  GNUNET_RPC_AsynchronousFunction async_callback;
 
+  /**
+   * Extra argument to async_callback.
+   */
+  void * cls;
+};
+
 /**
+ * A set of RegisteredRPC structures, one for each RPC registered by the
+ * local node.
+ */
+static struct RegisteredRPC *list_of_callbacks;
+
+/**
  * A set of GNUNET_RPC_CallHandle structures for active incoming rpc calls.
  * (requests without a reply).
  */
-static struct GNUNET_Vector *incomingCalls;
+static struct GNUNET_RPC_CallHandle *incomingCalls;
 
 /**
- * A set of GNUNET_RPC_CallHandle structures for active outgoing rpc calls.
- * (reply messages without an ACK).
+ * Linked list active outgoing rpc calls.
+ * (waiting for function and reply messages without an ACK).
  */
-static struct GNUNET_Vector *outgoingCalls;
+static struct GNUNET_RPC_RequestHandle *outgoingCalls;
 
 /**
  * A counter whose value is used for identifying the RPC's originating
@@ -650,133 +298,120 @@
  * RPC and thus its value also tells the number of RPC's originated from the
  * local node (modulo integer overflow).
  */
-static unsigned int rpcIdentifier = 0;
+static unsigned int rpcIdentifier;
 
 /**
- * Cron-job that processes the RPC queues.  Created for
- * each GNUNET_RPC_CallHandle.  Not renewed if the call times out,
- * deleted if the appropriate response is received.
+ * Access to GNUnet core API.
  */
-static void
-retryRPCJob (void *ctx)
+static GNUNET_CoreAPIForPlugins *coreAPI;
+
+/**
+ * A mutex for synchronous access to all module-wide data structures. This
+ * lock must be held by the thread that accesses any module-wide accessable
+ * data structures.
+ */
+static struct GNUNET_Mutex *lock;
+
+/**
+ * Registers an async RPC callback under the given name.
+ * @param name the name of the callback, must not be NULL
+ * @param callback the function to call
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ *   (typically if a callback of that name is already in use).
+ */
+static int
+RPC_register (const char *name,
+             GNUNET_RPC_AsynchronousFunction callback,
+             void * cls)
 {
-  CallInstance *call = ctx;
-  GNUNET_CronTime now;
+  struct RegisteredRPC *rrpc;
 
-  now = GNUNET_get_time ();
-  GNUNET_GE_ASSERT (ectx,
-                    (GNUNET_get_time () + 1 * GNUNET_CRON_MINUTES >
-                     call->expirationTime)
-                    || (call->expirationTime - GNUNET_get_time () <
-                        1 * GNUNET_CRON_HOURS));
-  GNUNET_mutex_lock (rpcLock);
-  if (now > call->expirationTime)
+  GNUNET_GE_ASSERT (coreAPI->ectx, name != NULL);
+  GNUNET_GE_ASSERT (coreAPI->ectx, callback != NULL);
+  GNUNET_mutex_lock (lock);
+  rrpc = list_of_callbacks;
+  while (rrpc != NULL)
     {
-#if DEBUG_RPC
-      GNUNET_GE_LOG (ectx,
-                     GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                     "Completed RPC %p (timeout).\n", call);
-#endif
-      if (call->finishedCallback != NULL)
+      if (0 == strcmp (rrpc->name, name))
         {
-          call->finishedCallback (call->rpcCallbackArgs,
-                                  call->sequenceNumber,
-                                  GNUNET_RPC_ERROR_TIMEOUT, NULL);
-          GNUNET_vector_delete (outgoingCalls, call);
+          GNUNET_mutex_unlock (lock);
+          GNUNET_GE_LOG (coreAPI->ectx,
+                         GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
+                         _("%s::%s - RPC %s:%p could not be registered:"
+                           " another callback is already using this name 
(%p)\n"),
+                         __FILE__, __FUNCTION__, name, callback,
+                         rrpc->async_callback);
+          return GNUNET_SYSERR;
         }
-      else
-        {
-          GNUNET_vector_delete (incomingCalls, call);
-        }
-      GNUNET_free (call->msg);
-      GNUNET_free (call);
+      rrpc = rrpc->next;
     }
-  else
-    {
-      if ((coreAPI != NULL)
-          && (call->expirationTime - now > 50 * GNUNET_CRON_MILLISECONDS))
-        {
-          unsigned int maxdelay;
-
-          if (call->repetitionFrequency == 0)
-            {
-              call->repetitionFrequency
-                = getExpectedResponseTime (&call->receiver) * 2;
-              if (call->repetitionFrequency == 0)
-                call->repetitionFrequency = INITIAL_RPC_FREQUENCY;
-              if (call->repetitionFrequency < MIN_RPC_FREQUENCY)
-                call->repetitionFrequency = MIN_RPC_FREQUENCY;
-            }
-          else
-            call->repetitionFrequency = 2 * call->repetitionFrequency;
-          maxdelay = (now - call->expirationTime) / 2;
-          if (maxdelay > call->repetitionFrequency / 2)
-            maxdelay = call->repetitionFrequency / 2;
-          notifyPeerRequest (&call->receiver,
-                             MINGLE (call->sequenceNumber,
-                                     ntohs (call->msg->header.type)));
-#if DEBUG_RPC
-          if (ntohs (call->msg->header.type) == GNUNET_P2P_PROTO_RPC_REQ)
-            {
-              GNUNET_GE_LOG (ectx,
-                             GNUNET_GE_DEBUG | GNUNET_GE_REQUEST |
-                             GNUNET_GE_USER,
-                             "Sending RPC request %p: '%.*s' (expires in 
%llums, last attempt %llums ago; attempt %u).\n",
-                             call, ntohs (call->msg->functionNameLength),
-                             &call->msg[1], call->expirationTime - now,
-                             now - call->lastAttempt, call->attempts);
-            }
-          else
-            {
-              GNUNET_GE_LOG (ectx,
-                             GNUNET_GE_DEBUG | GNUNET_GE_REQUEST |
-                             GNUNET_GE_USER,
-                             "Sending RPC reply %p (expires in %llums, last 
attempt %llums ago, attempt %u).\n",
-                             call, call->expirationTime - now,
-                             now - call->lastAttempt, call->attempts);
-            }
-#endif
-          call->lastAttempt = now;
-          call->attempts++;
-          coreAPI->unicast (&call->receiver,
-                            &call->msg->header,
-                            ntohl (call->msg->importance), maxdelay);
-        }
-      GNUNET_GE_ASSERT (ectx,
-                        (GNUNET_get_time () + 1 * GNUNET_CRON_MINUTES >
-                         call->expirationTime)
-                        || (call->expirationTime - GNUNET_get_time () <
-                            1 * GNUNET_CRON_HOURS));
-      GNUNET_cron_add_job (coreAPI->cron, &retryRPCJob,
-                           call->repetitionFrequency, 0, call);
-    }
-  GNUNET_mutex_unlock (rpcLock);
+  rrpc = GNUNET_malloc(sizeof(struct RegisteredRPC));
+  rrpc->name = GNUNET_strdup (name);
+  rrpc->async_callback = callback;
+  rrpc->cls = cls;
+  rrpc->next = list_of_callbacks;
+  list_of_callbacks = rrpc;
+  GNUNET_mutex_unlock (lock);
+  return GNUNET_OK;
 }
 
 /**
- * Send an ACK message.
+ * Unregisters an asynchronous RPC callback of the given name.
+ * @param name the name of the callback, must not be NULL
+ * @param callback the function to unregister, NULL for any function
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ *   (typically if a callback of that name does not exist or is
+ *    bound to a different function).
  */
-static void
-sendAck (const GNUNET_PeerIdentity * receiver,
-         unsigned int sequenceNumber,
-         unsigned int importance, unsigned int maxDelay)
+static int
+RPC_unregister (const char *name,
+               GNUNET_RPC_AsynchronousFunction callback,
+               void * cls)
 {
-  RPC_ACK_Message msg;
+  struct RegisteredRPC *pos;
+  struct RegisteredRPC *prev;
 
-  msg.header.size = htons (sizeof (RPC_ACK_Message));
-  msg.header.type = htons (GNUNET_P2P_PROTO_RPC_ACK);
-  msg.sequenceNumber = htonl (sequenceNumber);
-  coreAPI->unicast (receiver, &msg.header, importance, maxDelay);
+  GNUNET_GE_ASSERT (NULL, NULL == incomingCalls);
+  GNUNET_GE_ASSERT (coreAPI->ectx, name != NULL);
+  GNUNET_mutex_lock (lock);
+  prev = NULL;
+  pos = list_of_callbacks;
+  while (pos != NULL)
+    {
+      if ( (0 == strcmp (pos->name, name)) &&
+          (pos->async_callback == callback) &&
+          (pos->cls == cls) )
+       {
+         if (prev == NULL)
+           list_of_callbacks = pos->next;
+         else
+           prev->next = pos->next;
+         GNUNET_free(pos->name);
+         GNUNET_free(pos);
+        }
+      prev = pos;
+      pos = pos->next;
+    }
+  GNUNET_mutex_unlock (lock);
+  GNUNET_GE_LOG (coreAPI->ectx, GNUNET_GE_WARNING | GNUNET_GE_BULK | 
GNUNET_GE_USER,
+                 _
+                 ("%s::%s - async RPC %s:%p could not be unregistered: not 
found\n"),
+                 __FILE__, __FUNCTION__, name, callback);
+  return GNUNET_SYSERR;
 }
 
+/**
+ * Get the name of the RPC function.
+ */
 static char *
-getFunctionName (P2P_rpc_MESSAGE * req)
+RPC_get_function_name (const P2P_rpc_MESSAGE * req)
 {
   char *ret;
-  unsigned short slen;
+  unsigned int slen;
 
-  slen = ntohs (req->functionNameLength);
-  if (ntohs (req->header.size) < sizeof (P2P_rpc_MESSAGE) + slen)
+  slen = ntohl (req->functionNameLength);
+  if ( (ntohs (req->header.size) < sizeof (P2P_rpc_MESSAGE) + slen) ||
+       (sizeof(P2P_rpc_MESSAGE) + slen < sizeof(P2P_rpc_MESSAGE) ) )
     return NULL;                /* invalid! */
   ret = GNUNET_malloc (slen + 1);
   memcpy (ret, &req[1], slen);
@@ -784,17 +419,22 @@
   return ret;
 }
 
-static GNUNET_RPC_CallParameters *
-deserializeArguments (P2P_rpc_MESSAGE * req)
+/**
+ * Get the arguments (or return value) from 
+ * the request.
+ */
+static struct GNUNET_RPC_CallParameters *
+RPC_deserialize_arguments (const P2P_rpc_MESSAGE * req)
 {
-  unsigned short slen;
-  GNUNET_RPC_CallParameters *ret;
+  unsigned int slen;
+  struct GNUNET_RPC_CallParameters *ret;
 
   if (ntohs (req->header.type) == GNUNET_P2P_PROTO_RPC_REQ)
-    slen = ntohs (req->functionNameLength);
+    slen = ntohl (req->functionNameLength);
   else
     slen = 0;
-  if (ntohs (req->header.size) < sizeof (P2P_rpc_MESSAGE) + slen)
+  if ( (ntohs (req->header.size) < sizeof (P2P_rpc_MESSAGE) + slen) ||
+       (sizeof(P2P_rpc_MESSAGE) + slen < sizeof(P2P_rpc_MESSAGE) ) )
     return NULL;                /* invalid! */
   ret =
     GNUNET_RPC_parameters_deserialize (&((char *) &req[1])[slen],
@@ -809,8 +449,25 @@
 }
 
 /**
+ * Send an ACK message.
+ */
+static void
+RPC_send_ack (const GNUNET_PeerIdentity * receiver,
+             unsigned int sequenceNumber,
+             unsigned int importance, unsigned int maxDelay)
+{
+  RPC_ACK_Message msg;
+
+  msg.header.size = htons (sizeof (RPC_ACK_Message));
+  msg.header.type = htons (GNUNET_P2P_PROTO_RPC_ACK);
+  msg.sequenceNumber = htonl (sequenceNumber);
+  coreAPI->unicast (receiver, &msg.header, importance, maxDelay);
+}
+
+/**
  * Build an RPC message serializing the name and values
  * properly.
+ *
  * @param errorCode the status code for the message, if non-NULL
  *   values will be NULL
  * @param name the name of the target method, NULL for a reply.
@@ -819,88 +476,77 @@
  * @return the RPC message to transmit, caller must free
  */
 static P2P_rpc_MESSAGE *
-buildMessage (unsigned short errorCode,
-              const char *name,
-              unsigned int sequenceNumber,
-              unsigned int importance, GNUNET_RPC_CallParameters * values)
+RPC_build_message (unsigned short errorCode,
+                  const char *name,
+                  unsigned int sequenceNumber,
+                  unsigned int importance, 
+                  const struct GNUNET_RPC_CallParameters * values)
 {
   P2P_rpc_MESSAGE *ret;
   size_t size = sizeof (P2P_rpc_MESSAGE);
   int slen;
 
   if (name != NULL)
-    {
-      slen = strlen (name);
-      size += slen;
-    }
+    slen = strlen (name);    
   else
-    slen = 0;
+    slen = 0;    
+  size += slen;
   if (values != NULL)
     size += GNUNET_RPC_parameters_get_serialized_size (values);
   if (size >= GNUNET_MAX_BUFFER_SIZE)
     return NULL;                /* message to big! */
   ret = GNUNET_malloc (size);
   ret->header.size = htons (size);
+  ret->header.type = htons ((name == NULL) ? GNUNET_P2P_PROTO_RPC_RES : 
GNUNET_P2P_PROTO_RPC_REQ);
   ret->timestamp = htonl (GNUNET_get_time_int32 (NULL));
   ret->sequenceNumber = htonl (sequenceNumber);
   ret->importance = htonl (importance);
   if (name == NULL)
-    ret->functionNameLength = htons (errorCode);
+    ret->functionNameLength = htonl (errorCode);
   else
-    ret->functionNameLength = htons (slen);
-  ret->argumentCount = htons (GNUNET_RPC_parameters_count (values));
+    ret->functionNameLength = htonl (slen);
+  ret->argumentCount = htonl (GNUNET_RPC_parameters_count (values));
   if (name != NULL)
-    {
-      memcpy (&ret[1], name, slen);
-    }
+    memcpy (&ret[1], name, slen);    
   GNUNET_RPC_parameters_serialize (values, &((char *) &ret[1])[slen]);
-
-  if (name == NULL)
-    ret->header.type = htons (GNUNET_P2P_PROTO_RPC_RES);
-  else
-    ret->header.type = htons (GNUNET_P2P_PROTO_RPC_REQ);
-
   return ret;
 }
 
 
+
 /* ***************** RPC P2P message handlers **************** */
 
-
 /**
- * GNUNET_RSA_Signature of the callback function for the ASYNC_RPC to
- * be called upon completion of the ASYNC function.  Initiates
- * sending back the reply.  Also called in the synchronous RPC
- * case o complete the reply (since it's the same code).
+ * Function called to communicate the return value of
+ * an RPC to the peer that initiated it.
  */
 static void
-async_rpc_complete_callback (GNUNET_RPC_CallParameters * results,
-                             int errorCode, CallInstance * calls)
+RPC_complete (const struct GNUNET_RPC_CallParameters * results,
+             int errorCode, 
+             struct GNUNET_RPC_CallHandle * call)
 {
-  GNUNET_mutex_lock (rpcLock);
-  /* build reply message */
-  calls->msg = buildMessage (errorCode,
-                             NULL,
-                             calls->sequenceNumber,
-                             calls->importance, results);
-  if (calls->msg == NULL)
-    calls->msg = buildMessage (GNUNET_RPC_ERROR_RETURN_VALUE_TOO_LARGE,
-                               NULL,
-                               calls->sequenceNumber,
-                               calls->importance, results);
-  GNUNET_vector_insert_last (incomingCalls, calls);
-
-  GNUNET_GE_ASSERT (ectx,
-                    (GNUNET_get_time () + 1 * GNUNET_CRON_MINUTES >
-                     calls->expirationTime)
-                    || (calls->expirationTime - GNUNET_get_time () <
-                        1 * GNUNET_CRON_HOURS));
-  /* for right now: schedule cron job to send reply! */
-  GNUNET_cron_add_job (coreAPI->cron, &retryRPCJob, 0, 0, calls);
-  GNUNET_mutex_unlock (rpcLock);
+  GNUNET_mutex_lock (lock);
+  GNUNET_GE_ASSERT(NULL, call->msg == NULL);
+  call->msg = RPC_build_message (errorCode,
+                                NULL,
+                                call->sequenceNumber,
+                                call->importance, results);
+  if (call->msg == NULL)
+    call->msg = RPC_build_message (GNUNET_RPC_ERROR_RETURN_VALUE_TOO_LARGE,
+                                  NULL,
+                                  call->sequenceNumber,
+                                  call->importance, results);
+  call->lastAttempt = GNUNET_get_time();
+  call->repetitionFrequency = RPC_INITIAL_ROUND_TRIP_TIME;
+  call->attempts = 1;
+  call->errorCode = errorCode;
+  coreAPI->unicast(&call->initiator,
+                  &call->msg->header,
+                  call->importance,
+                  RPC_INITIAL_ROUND_TRIP_TIME / 2);
+  GNUNET_mutex_unlock (lock);
 }
 
-
 /**
  * Handle request for remote function call.  Checks if message
  * has been seen before, if not performs the call and sends
@@ -910,233 +556,169 @@
 handleRPCMessageReq (const GNUNET_PeerIdentity * sender,
                      const GNUNET_MessageHeader * message)
 {
-  P2P_rpc_MESSAGE *req;
-  CallInstance *calls;
+  const P2P_rpc_MESSAGE * req;
+  struct GNUNET_RPC_CallHandle * pos;
+  struct GNUNET_RPC_CallParameters *argumentValues;
+  const struct RegisteredRPC *rpc;
   unsigned int sq;
-  unsigned short errorCode;
+  unsigned int total;
   char *functionName;
-  GNUNET_RPC_CallParameters *argumentValues;
-  GNUNET_RPC_CallParameters *returnValues;
-  RegisteredRPC *rpc;
-  unsigned int minSQ;
 
-  if ((ntohs (message->type) != GNUNET_P2P_PROTO_RPC_REQ) ||
-      (ntohs (message->size) < sizeof (P2P_rpc_MESSAGE)))
+  if (ntohs (message->size) < sizeof (P2P_rpc_MESSAGE))
     {
-      GNUNET_GE_LOG (ectx,
-                     GNUNET_GE_WARNING | GNUNET_GE_REQUEST | GNUNET_GE_ADMIN,
-                     _("Invalid message of type %u received.  Dropping.\n"),
-                     ntohs (message->type));
+      GNUNET_GE_BREAK_OP(NULL, 0);
       return GNUNET_SYSERR;
     }
-  req = (P2P_rpc_MESSAGE *) message;
-  sq = ntohl (req->sequenceNumber);
-#if DEBUG_RPC
-  GNUNET_GE_LOG (ectx,
-                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "Received RPC request with id %u.\n", sq);
-#endif
-  GNUNET_mutex_lock (rpcLock);
-
-  /* check if message is already in incomingCalls,
-     if so, update expiration, otherwise deserialize,
-     perform call, add reply and create cron job */
-
-  calls = GNUNET_vector_get_first (incomingCalls);
-  if (calls == NULL)
-    minSQ = 0;
-  else
-    minSQ = 0xFFFFFFFF;
-  while (calls != NULL)
+  req = (const P2P_rpc_MESSAGE *) message;
+  functionName = RPC_get_function_name (req);
+  if (functionName == NULL)
     {
-      if (calls->sequenceNumber < minSQ)
-        minSQ = calls->sequenceNumber;
-      if ((calls->sequenceNumber == sq) &&
-          (0 ==
-           memcmp (&calls->receiver, sender, sizeof (GNUNET_PeerIdentity))))
-        break;
-      calls = GNUNET_vector_get_next (incomingCalls);
+      GNUNET_GE_BREAK_OP(NULL, 0);
+      return GNUNET_SYSERR;
     }
-  if (calls != NULL)
+  argumentValues = RPC_deserialize_arguments (req);
+  if (argumentValues == NULL)
     {
-      PeerInfo *pi = getPeerInfo (sender);
-
-      if (pi != NULL)
-        {
-          if (pi->averageResponseTime < MAX_RPC_TIMEOUT / 2)
-            pi->averageResponseTime *= 2;
-        }
-      RPC_STATUS ("", "received duplicate request", calls);
-      calls->expirationTime = GNUNET_get_time () + MAX_RPC_TIMEOUT;
-      GNUNET_GE_LOG (ectx,
-                     GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                     "Dropping RPC request %u, duplicate.\n", sq);
-      GNUNET_mutex_unlock (rpcLock);
-      return GNUNET_OK;         /* seen before */
+      GNUNET_free (functionName);
+      GNUNET_GE_BREAK_OP(NULL, 0);
+      return GNUNET_SYSERR;     /* message malformed */
     }
-  if (minSQ > sq)
+  sq = ntohl (req->sequenceNumber);
+
+  /* check if message is already in incomingCalls! */
+  GNUNET_mutex_lock (lock);
+  pos = incomingCalls;
+  total = 0;
+  while ( (pos != NULL) &&
+         ( (pos->sequenceNumber != sq) ||
+           (0 != memcmp(&pos->initiator,
+                        sender,
+                        sizeof(GNUNET_PeerIdentity)))) )
     {
-      GNUNET_GE_LOG (ectx,
-                     GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                     "Dropping RPC request %u, sequence number too old 
(current minimum is %u).\n",
-                     sq, minSQ);
-      GNUNET_mutex_unlock (rpcLock);
-      return GNUNET_OK;         /* seen before */
+      if (0 == memcmp(&pos->initiator,
+                     sender,
+                     sizeof(GNUNET_PeerIdentity)))
+       total++;
+      pos = pos->next;
     }
-
-  /* deserialize */
-  functionName = getFunctionName (req);
-  argumentValues = deserializeArguments (req);
-  if ((functionName == NULL) || (argumentValues == NULL))
+  if ( (pos != NULL) ||
+       (total > RPC_MAX_REQUESTS_PER_PEER) )
     {
-      GNUNET_free_non_null (functionName);
-      if (argumentValues != NULL)
-        GNUNET_RPC_parameters_destroy (argumentValues);
-      GNUNET_mutex_unlock (rpcLock);
-      GNUNET_GE_LOG (ectx,
-                     GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
-                     _("Dropping RPC request %u: message malformed.\n"));
-      return GNUNET_SYSERR;     /* message malformed */
+      /* already pending or too many pending */
+      GNUNET_free (functionName);
+      GNUNET_RPC_parameters_destroy(argumentValues);
+      GNUNET_mutex_unlock (lock);
+      return GNUNET_SYSERR;
     }
 
   /* find matching RPC function */
-  rpc = (RegisteredRPC *) GNUNET_vector_get_first (list_of_callbacks);
+  rpc = list_of_callbacks;
   while (rpc != NULL)
     {
       if (0 == strcmp (functionName, rpc->name))
         break;
-      rpc = (RegisteredRPC *) GNUNET_vector_get_next (list_of_callbacks);
+      rpc = rpc->next;
     }
-  calls = GNUNET_malloc (sizeof (CallInstance));
-  RPC_STATUS (functionName, "received request", calls);
-  GNUNET_free (functionName);
-  calls->sequenceNumber = sq;
-  calls->receiver = *sender;
-  calls->expirationTime = GNUNET_get_time () + MAX_RPC_TIMEOUT;
-  calls->lastAttempt = 0;
-  calls->attempts = 0;
-  calls->finishedCallback = NULL;
-  calls->rpcCallbackArgs = NULL;
-  calls->importance = ntohl (req->importance);
-
-  /* if possible, perform RPC call */
+  /* create call handle */
+  pos = GNUNET_malloc (sizeof (struct GNUNET_RPC_CallHandle));
+  memset(pos, 0, sizeof (struct GNUNET_RPC_CallHandle));
+  pos->function_name = functionName;
+  pos->sequenceNumber = sq;
+  pos->initiator = *sender;
+  pos->expirationTime = GNUNET_get_time () + RPC_INTERNAL_PROCESSING_TIMEOUT;
+  pos->importance = ntohl (req->importance);
+  pos->next = incomingCalls;
+  if (incomingCalls != NULL)
+    incomingCalls->prev = pos;
+  incomingCalls = pos;
   if (rpc == NULL)
-    {
-      GNUNET_RPC_parameters_destroy (argumentValues);
-      returnValues = NULL;
-      errorCode = GNUNET_RPC_ERROR_UNKNOWN_FUNCTION;
-    }
+    RPC_complete(NULL,
+                GNUNET_RPC_ERROR_UNKNOWN_FUNCTION,
+                pos);
   else
-    {
-      if (rpc->callback == NULL)
-        {
-          /* asynchronous RPC */
-          rpc->async_callback (sender,
-                               argumentValues,
-                               &async_rpc_complete_callback, calls);
-          GNUNET_mutex_unlock (rpcLock);
-          return GNUNET_OK;
-        }
-      returnValues = GNUNET_RPC_parameters_create ();
-      rpc->callback (sender, argumentValues, returnValues);
-      GNUNET_RPC_parameters_destroy (argumentValues);
-      errorCode = GNUNET_RPC_ERROR_OK;
-    }
-  GNUNET_mutex_unlock (rpcLock);
-  async_rpc_complete_callback (returnValues, errorCode, calls);
+    rpc->async_callback (rpc->cls,
+                        sender,
+                        argumentValues,
+                        pos);
+  GNUNET_RPC_parameters_destroy (argumentValues);
+  GNUNET_mutex_unlock (lock);
   return GNUNET_OK;
 }
 
 /**
  * Handle reply for request for remote function call.  Checks
- * if we are waiting for a reply, if so triggers the reply.
+ * if we are waiting for a reply, if so triggers the callback.
  * Also always sends an ACK.
  */
 static int
 handleRPCMessageRes (const GNUNET_PeerIdentity * sender,
                      const GNUNET_MessageHeader * message)
 {
-  P2P_rpc_MESSAGE *res;
-  CallInstance *call;
+  const P2P_rpc_MESSAGE *res;
+  struct GNUNET_RPC_RequestHandle * pos;
+  struct GNUNET_RPC_CallParameters *reply;
+  unsigned int error;
 
-  if ((ntohs (message->type) != GNUNET_P2P_PROTO_RPC_RES) ||
-      (ntohs (message->size) < sizeof (P2P_rpc_MESSAGE)))
+  if (ntohs (message->size) < sizeof (P2P_rpc_MESSAGE))
     {
-      GNUNET_GE_LOG (ectx,
-                     GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
-                     _("Invalid message of type %u received.  Dropping.\n"),
-                     ntohs (message->type));
+      GNUNET_GE_BREAK_OP(NULL, 0);
       return GNUNET_SYSERR;
     }
-  res = (P2P_rpc_MESSAGE *) message;
-#if DEBUG_RPC
-  GNUNET_GE_LOG (ectx,
-                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "Received RPC reply with id %u.\n",
-                 ntohl (res->sequenceNumber));
-#endif
-
-  GNUNET_cron_suspend_jobs (coreAPI->cron, GNUNET_NO);
-  GNUNET_mutex_lock (rpcLock);
-
+  res = (const P2P_rpc_MESSAGE *) message;
+  RPC_send_ack(sender,
+              ntohl(res->sequenceNumber),
+              ntohl(res->importance),
+              0);
   /* Locate the GNUNET_RPC_CallHandle structure. */
-  call = GNUNET_vector_get_first (outgoingCalls);
-  while (call != NULL)
+  GNUNET_mutex_lock (lock);
+  pos = outgoingCalls;
+  while (pos != NULL)
     {
-      if ((0 == memcmp (&call->receiver,
+      if ((0 == memcmp (&pos->receiver,
                         sender,
                         sizeof (GNUNET_PeerIdentity))) &&
-          (call->sequenceNumber == ntohl (res->sequenceNumber)))
+          (pos->sequenceNumber == ntohl (res->sequenceNumber)))
         break;
-      call = GNUNET_vector_get_next (outgoingCalls);
+      pos = pos->next;
     }
-  if (NULL != call)
+  if (pos == NULL)
     {
-      GNUNET_RPC_CallParameters *reply;
-      unsigned short error;
+      /* duplicate reply */
+      GNUNET_mutex_unlock (lock);
+      return GNUNET_OK;
+    }
+  /* remove pos from linked list */
+  GNUNET_mutex_unlock (lock);
 
-      RPC_STATUS ("", "received reply", call);
+  /* call callback */
+  reply = NULL;
+  error = ntohl (res->functionNameLength);
+  if (error == GNUNET_RPC_ERROR_OK)
+    reply = GNUNET_RPC_parameters_deserialize ((char *) &res[1],
+                                              ntohs (message->size) -
+                                              sizeof
+                                              (P2P_rpc_MESSAGE));
+  if (ntohl (res->argumentCount) !=
+      GNUNET_RPC_parameters_count (reply))
+    {
+      GNUNET_RPC_parameters_destroy (reply);
       reply = NULL;
-      error = ntohs (res->functionNameLength);
-
-      if (error == GNUNET_RPC_ERROR_OK)
-        {
-          reply = GNUNET_RPC_parameters_deserialize ((char *) &res[1],
-                                                     ntohs (message->size) -
-                                                     sizeof
-                                                     (P2P_rpc_MESSAGE));
-          if (ntohs (res->argumentCount) !=
-              GNUNET_RPC_parameters_count (reply))
-            {
-              GNUNET_RPC_parameters_destroy (reply);
-              reply = NULL;
-              error = GNUNET_RPC_ERROR_REPLY_MALFORMED;
-            }
-        }
-      if (call->finishedCallback != NULL)
-        {
-          call->finishedCallback (call->rpcCallbackArgs,
-                                  call->sequenceNumber, error, reply);
-          call->finishedCallback = NULL;
-        }
-      GNUNET_vector_delete (outgoingCalls, call);
-      notifyPeerReply (sender,
-                       MINGLE (call->sequenceNumber,
-                               GNUNET_P2P_PROTO_RPC_REQ));
-      GNUNET_cron_del_job (coreAPI->cron, &retryRPCJob, 0, call);
-      GNUNET_free (call->msg);
-      GNUNET_free (call);
-      if (reply != NULL)
-        GNUNET_RPC_parameters_destroy (reply);
+      error = GNUNET_RPC_ERROR_REPLY_MALFORMED;
     }
-  sendAck (sender, ntohl (res->sequenceNumber), 0,      /* not important, ACK 
should be tiny enough to go through anyway */
-           0 /* right away */ );
-  GNUNET_mutex_unlock (rpcLock);
-  GNUNET_cron_resume_jobs (coreAPI->cron, GNUNET_NO);
+  if (pos->callback != NULL)
+    {
+      pos->callback(sender,
+                   reply,
+                   error,
+                   pos->cls);
+      pos->callback = NULL;
+      pos->errorCode = error;
+    }
+  if (reply != NULL)
+    GNUNET_RPC_parameters_destroy (reply);    
   return GNUNET_OK;
 }
 
-
 /**
  * Handle a peer-to-peer message of type GNUNET_P2P_PROTO_RPC_ACK.
  */
@@ -1144,180 +726,49 @@
 handleRPCMessageAck (const GNUNET_PeerIdentity * sender,
                      const GNUNET_MessageHeader * message)
 {
-  RPC_ACK_Message *ack;
-  CallInstance *call;
+  const RPC_ACK_Message *ack;
+  struct GNUNET_RPC_CallHandle *pos;
 
-  if ((ntohs (message->type) != GNUNET_P2P_PROTO_RPC_ACK) ||
-      (ntohs (message->size) != sizeof (RPC_ACK_Message)))
+  if (ntohs (message->size) != sizeof (RPC_ACK_Message))
     {
-      GNUNET_GE_LOG (ectx,
-                     GNUNET_GE_WARNING | GNUNET_GE_REQUEST | GNUNET_GE_ADMIN,
-                     _("Invalid message of type %u received.  Dropping.\n"),
-                     ntohs (message->type));
+      GNUNET_GE_BREAK_OP(NULL, 0);
       return GNUNET_SYSERR;
     }
+  ack = (const RPC_ACK_Message *) message;
+  GNUNET_mutex_lock (lock);
 
-  ack = (RPC_ACK_Message *) message;
-#if DEBUG_RPC
-  GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "Received RPC ACK with id %u.\n",
-                 ntohl (ack->sequenceNumber));
-#endif
-  GNUNET_cron_suspend_jobs (coreAPI->cron, GNUNET_NO);
-  GNUNET_mutex_lock (rpcLock);
-
   /* Locate the GNUNET_RPC_CallHandle structure. */
-  call = (CallInstance *) GNUNET_vector_get_first (incomingCalls);
-  while (call != NULL)
+  pos = incomingCalls;
+  while (pos != NULL)
     {
-      if ((0 == memcmp (&call->receiver,
+      if ((0 == memcmp (&pos->initiator,
                         sender,
                         sizeof (GNUNET_PeerIdentity))) &&
-          (call->sequenceNumber == ntohl (ack->sequenceNumber)))
+          (pos->sequenceNumber == ntohl (ack->sequenceNumber)))
         break;
-      call = (CallInstance *) GNUNET_vector_get_next (incomingCalls);
+      pos = pos->next;
     }
-
-  /* check if we're waiting for an ACK, if so remove job */
-  if (NULL != call)
+  if (pos == NULL)
     {
-      RPC_STATUS ("", "acknowledged reply", call);
-      notifyPeerReply (sender,
-                       MINGLE (ntohl (ack->sequenceNumber),
-                               GNUNET_P2P_PROTO_RPC_RES));
-      GNUNET_cron_del_job (coreAPI->cron, &retryRPCJob, 0, call);
-      GNUNET_vector_delete (incomingCalls, call);
-      GNUNET_free (call->msg);
-      GNUNET_free (call);
+      /* duplicate ACK, ignore */
+      GNUNET_mutex_unlock (lock);
+      return GNUNET_OK;
     }
+  /* remove from list */
+  if (pos->prev == NULL)
+    incomingCalls = pos->next;
   else
-    {
-      PeerInfo *pi = getPeerInfo (sender);
-      if (pi != NULL)
-        {
-          if (pi->averageResponseTime < MAX_RPC_TIMEOUT / 2)
-            pi->averageResponseTime *= 2;
-        }
-#if DEBUG_RPC
-      GNUNET_GE_LOG (ectx,
-                     GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                     "ACK is a duplicate (or invalid).\n");
-#endif
-    }
-
-  GNUNET_mutex_unlock (rpcLock);
-  GNUNET_cron_resume_jobs (coreAPI->cron, GNUNET_NO);
+    pos->prev->next = pos->next;
+  if (pos->next != NULL)
+    pos->next->prev = pos->prev;
+  GNUNET_free (pos->msg);
+  GNUNET_free (pos->function_name);
+  GNUNET_free (pos);
+  GNUNET_mutex_unlock (lock);
   return GNUNET_OK;
 }
 
-/* ********************* RPC service functions ******************** */
-
-typedef struct
-{
-  struct GNUNET_Semaphore *sem;
-  GNUNET_RPC_CallParameters *result;
-  unsigned short ec;
-} RPC_EXEC_CLS;
-
 /**
- * Callback function invoked whenever the RPC is complete
- * (timeout, error or success).
- */
-static void
-RPC_execute_callback (RPC_EXEC_CLS * context,
-                      unsigned int sq, unsigned short ec,
-                      GNUNET_RPC_CallParameters * res)
-{
-  int i;
-  unsigned int dl;
-  void *data;
-
-  for (i = GNUNET_RPC_parameters_count (res) - 1; i >= 0; i--)
-    {
-      data = NULL;
-      GNUNET_RPC_parameters_get_value_by_index (res, i, &dl, &data);
-      GNUNET_RPC_parameters_add (context->result,
-                                 GNUNET_RPC_parameters_get_name (res, i), dl,
-                                 data);
-    }
-  context->ec = ec;
-  GNUNET_semaphore_up (context->sem);
-}
-
-/**
- * Executes a blocking RPC on a node, which may be the local node. The
- * function performs the following steps:
- *
- * - Constructs a request packet from the request parameters
- * - Waits on a signaling semaphore until the result is ready or timeout
- * - passes the results back to the caller
- *
- * @return the error code of the operation (0 for success).
- */
-static int
-RPC_execute (const GNUNET_PeerIdentity * receiver,
-             const char *name,
-             GNUNET_RPC_CallParameters * requestParam,
-             GNUNET_RPC_CallParameters * returnParam, unsigned int importance,
-             GNUNET_CronTime timeout)
-{
-  RPC_EXEC_CLS cls;
-  CallInstance *call;
-
-  GNUNET_mutex_lock (rpcLock);
-  cls.sem = GNUNET_semaphore_create (0);
-  cls.result = returnParam;
-  call = GNUNET_malloc (sizeof (CallInstance));
-  RPC_STATUS (name, "started synchronously", call);
-  call->lastAttempt = 0;
-  call->attempts = 0;
-  call->repetitionFrequency = getExpectedResponseTime (receiver);
-  call->expirationTime = GNUNET_get_time () + timeout;
-  call->receiver = *receiver;
-  call->sequenceNumber = rpcIdentifier++;
-  call->msg = buildMessage (GNUNET_RPC_ERROR_OK,
-                            name,
-                            call->sequenceNumber, importance, requestParam);
-  call->finishedCallback = (RPCFinishedCallback) & RPC_execute_callback;
-  call->rpcCallbackArgs = &cls;
-  GNUNET_vector_insert_last (outgoingCalls, call);
-  GNUNET_GE_ASSERT (ectx,
-                    (GNUNET_get_time () + 1 * GNUNET_CRON_MINUTES >
-                     call->expirationTime)
-                    || (call->expirationTime - GNUNET_get_time () <
-                        1 * GNUNET_CRON_HOURS));
-  GNUNET_cron_add_job (coreAPI->cron, &retryRPCJob, 0, 0, call);
-  GNUNET_mutex_unlock (rpcLock);
-  GNUNET_semaphore_down (cls.sem, GNUNET_YES);
-  GNUNET_semaphore_destroy (cls.sem);
-  RPC_STATUS (name, "completed synchronously", call);
-  return cls.ec;
-}
-
-typedef struct GNUNET_RPC_RequestHandle
-{
-  GNUNET_PeerIdentity peer;
-  CallInstance *call;
-  GNUNET_RPC_AsynchronousCompletionCallback callback;
-  void *closure;
-  unsigned short errorCode;
-} RPC_Record;
-
-static void
-RPC_async_callback (RPC_Record * rec,
-                    unsigned int sequenceNumber,
-                    unsigned short errorCode,
-                    GNUNET_RPC_CallParameters * result)
-{
-  if ((errorCode == GNUNET_RPC_ERROR_OK) && (rec->callback != NULL))
-    {
-      rec->callback (&rec->peer, result, rec->closure);
-      rec->callback = NULL;     /* never call callback twice */
-    }
-  rec->errorCode = errorCode;
-}
-
-/**
  * Start an asynchronous RPC.
  *
  * @param timeout when should we stop trying the RPC
@@ -1327,52 +778,42 @@
  * @return value required to stop the RPC (and the RPC must
  *  be explicitly stopped to free resources!)
  */
-static RPC_Record *
+static struct GNUNET_RPC_RequestHandle *
 RPC_start (const GNUNET_PeerIdentity * receiver,
            const char *name,
-           GNUNET_RPC_CallParameters * request_param,
+           const struct GNUNET_RPC_CallParameters * request_param,
            unsigned int importance,
            GNUNET_CronTime timeout,
            GNUNET_RPC_AsynchronousCompletionCallback callback, void *closure)
 {
-  RPC_Record *ret;
+  struct GNUNET_RPC_RequestHandle *ret;
 
   if (timeout > 1 * GNUNET_CRON_HOURS)
-    {
-      GNUNET_GE_LOG (ectx,
-                     GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
-                     _("`%s' called with timeout above 1 hour (bug?)\n"),
-                     __FUNCTION__);
-      timeout = 1 * GNUNET_CRON_HOURS;
-    }
-  ret = GNUNET_malloc (sizeof (RPC_Record));
-  RPC_STATUS (name, "started asynchronously", ret);
-  ret->peer = *receiver;
+    timeout = 1 * GNUNET_CRON_HOURS;   
+  ret = GNUNET_malloc (sizeof (struct GNUNET_RPC_RequestHandle));
+  memset(ret, 0, sizeof (struct GNUNET_RPC_RequestHandle));
+  ret->receiver = *receiver;
   ret->callback = callback;
-  ret->closure = closure;
-  ret->errorCode = GNUNET_RPC_ERROR_TIMEOUT;
-  GNUNET_mutex_lock (rpcLock);
-  ret->call = GNUNET_malloc (sizeof (CallInstance));
-  ret->call->lastAttempt = 0;
-  ret->call->attempts = 0;
-  ret->call->repetitionFrequency = getExpectedResponseTime (receiver);
-  ret->call->expirationTime = GNUNET_get_time () + timeout;
-  ret->call->receiver = *receiver;
-  ret->call->sequenceNumber = rpcIdentifier++;
-  ret->call->msg = buildMessage (GNUNET_RPC_ERROR_OK,
-                                 name,
-                                 ret->call->sequenceNumber,
-                                 importance, request_param);
-  ret->call->finishedCallback = (RPCFinishedCallback) & RPC_async_callback;
-  ret->call->rpcCallbackArgs = ret;
-  GNUNET_vector_insert_last (outgoingCalls, ret->call);
-  GNUNET_GE_ASSERT (ectx,
-                    (GNUNET_get_time () + 1 * GNUNET_CRON_MINUTES >
-                     ret->call->expirationTime)
-                    || (ret->call->expirationTime - GNUNET_get_time () <
-                        1 * GNUNET_CRON_HOURS));
-  GNUNET_cron_add_job (coreAPI->cron, &retryRPCJob, 0, 0, ret->call);
-  GNUNET_mutex_unlock (rpcLock);
+  ret->cls = closure;
+  ret->expirationTime = GNUNET_get_time () + timeout;
+  ret->lastAttempt = 0;
+  ret->attempts = 0;
+  ret->sequenceNumber = rpcIdentifier++;
+  ret->msg = RPC_build_message (GNUNET_RPC_ERROR_OK,
+                               name,
+                               ret->sequenceNumber,
+                               importance, request_param);  
+  ret->repetitionFrequency = RPC_INITIAL_ROUND_TRIP_TIME;
+  GNUNET_mutex_lock (lock);
+  ret->next = outgoingCalls;
+  outgoingCalls = ret;
+  if (ret->next != NULL)
+    ret->next->prev = ret;
+  GNUNET_mutex_unlock (lock);
+  coreAPI->unicast(receiver,
+                  &ret->msg->header,
+                  importance,
+                  RPC_INITIAL_ROUND_TRIP_TIME / 2);
   return ret;
 }
 
@@ -1384,27 +825,109 @@
  *  another RPC_ERROR code if it was aborted
  */
 static int
-RPC_stop (RPC_Record * record)
+RPC_stop (struct GNUNET_RPC_RequestHandle * record)
 {
   int ret;
 
-  RPC_STATUS ("", "stopped", record);
-  GNUNET_cron_suspend_jobs (coreAPI->cron, GNUNET_YES);
-  GNUNET_cron_del_job (coreAPI->cron, &retryRPCJob, 0, record->call);
-  GNUNET_cron_resume_jobs (coreAPI->cron, GNUNET_YES);
-  GNUNET_mutex_lock (rpcLock);
-  if (NULL != GNUNET_vector_delete (outgoingCalls, record->call))
-    {
-      GNUNET_free (record->call->msg);
-      GNUNET_free (record->call);
-    }
-  GNUNET_mutex_unlock (rpcLock);
-  ret = record->errorCode;
+  GNUNET_mutex_lock (lock);
+  if (record->prev == NULL)
+    outgoingCalls = record->next;
+  else
+    record->prev->next = record->next;
+  if (record->next != NULL)
+    record->next->prev = record->prev;
+  GNUNET_free (record->msg);
+  GNUNET_mutex_unlock (lock);
+  ret = (record->callback == NULL) ? record->errorCode : 
GNUNET_RPC_ERROR_ABORTED;
   GNUNET_free (record);
-
   return ret;
 }
 
+
+/**
+ * Cron-job that processes the RPC queues.  This job is responsible
+ * for retransmission of requests and un-ACKed responses.  It is also
+ * there to trigger timeouts.
+ */
+static void
+RPC_retry_job (void * unused)
+{
+  GNUNET_CronTime now;
+  struct GNUNET_RPC_CallHandle * ipos;
+  struct GNUNET_RPC_RequestHandle * opos;
+
+  GNUNET_mutex_lock (lock);
+  now = GNUNET_get_time ();
+  ipos = incomingCalls;
+  while (ipos != NULL)
+    {
+      if ( (ipos->expirationTime < now) ||
+          (ipos->attempts >= RPC_MAX_REPLY_ATTEMPTS) )
+       {
+         GNUNET_free_non_null(ipos->msg);
+         GNUNET_free(ipos->function_name);
+         if (ipos->prev == NULL)
+           incomingCalls = ipos->next;
+         else
+           ipos->prev->next = ipos->next;
+         if (ipos->next != NULL)
+           ipos->next = ipos->prev;
+         GNUNET_free(ipos);
+         ipos = incomingCalls;
+         continue;
+       }
+      if ( (ipos->msg != NULL) &&
+          (ipos->lastAttempt + ipos->repetitionFrequency < now) )
+       {
+         ipos->lastAttempt = now;
+         ipos->attempts++;
+         ipos->repetitionFrequency *= 2;
+         coreAPI->unicast(&ipos->initiator,
+                          &ipos->msg->header,
+                          ipos->repetitionFrequency / 2,
+                          ipos->importance);
+       }
+      ipos = ipos->next;
+    }
+  opos = outgoingCalls;
+  while (opos != NULL)
+    {
+      if (opos->expirationTime < now)
+       {
+         if (opos->callback != NULL)
+           {
+             opos->callback(&opos->receiver,
+                            NULL,
+                            GNUNET_RPC_ERROR_TIMEOUT,
+                            opos->cls);
+             opos->callback = NULL;
+           }
+         GNUNET_free_non_null(opos->msg);
+         if (opos->prev == NULL)
+           outgoingCalls = opos->next;
+         else
+           opos->prev->next = opos->next;
+         if (opos->next != NULL)
+           opos->next = opos->prev;
+         GNUNET_free(opos);
+         opos = outgoingCalls;
+         continue;
+       }
+      if (opos->lastAttempt + opos->repetitionFrequency < now) 
+       {
+         opos->lastAttempt = now;
+         opos->attempts++;
+         opos->repetitionFrequency *= 2;
+         coreAPI->unicast(&opos->receiver,
+                          &opos->msg->header,
+                          opos->repetitionFrequency / 2,
+                          opos->importance);
+       }
+      opos = opos->next;
+    }
+  GNUNET_mutex_unlock (lock);
+}
+
 /* ******************* Exported functions ******************* */
 
 /**
@@ -1413,63 +936,18 @@
 void
 release_module_rpc ()
 {
-  CallInstance *call;
-
-  GNUNET_cron_del_job (coreAPI->cron,
-                       &agePeerStats, PEER_TRACKING_TIME_INTERVAL, NULL);
   coreAPI->unregisterHandler (GNUNET_P2P_PROTO_RPC_REQ, &handleRPCMessageReq);
   coreAPI->unregisterHandler (GNUNET_P2P_PROTO_RPC_RES, &handleRPCMessageRes);
   coreAPI->unregisterHandler (GNUNET_P2P_PROTO_RPC_ACK, &handleRPCMessageAck);
-  if (NULL != peerInformation)
-    {
-      while (GNUNET_vector_get_size (peerInformation) > 0)
-        GNUNET_free (GNUNET_vector_delete_last (peerInformation));
-      GNUNET_vector_destroy (peerInformation);
-      peerInformation = NULL;
-    }
-  if (NULL != incomingCalls)
-    {
-      while (GNUNET_vector_get_size (incomingCalls) > 0)
-        {
-          call = (CallInstance *) GNUNET_vector_delete_last (incomingCalls);
-          GNUNET_cron_del_job (coreAPI->cron, &retryRPCJob, 0, call);
-          GNUNET_free (call->msg);
-          GNUNET_free (call);
-        }
-      GNUNET_vector_destroy (incomingCalls);
-      incomingCalls = NULL;
-    }
-  if (NULL != outgoingCalls)
-    {
-      while (GNUNET_vector_get_size (outgoingCalls) > 0)
-        {
-          call = (CallInstance *) GNUNET_vector_delete_last (outgoingCalls);
-          GNUNET_cron_del_job (coreAPI->cron, &retryRPCJob, 0, call);
-          GNUNET_free (call->msg);
-          GNUNET_free (call);
-        }
-      GNUNET_vector_destroy (outgoingCalls);
-      outgoingCalls = NULL;
-    }
-  if (NULL != list_of_callbacks)
-    {
-      while (GNUNET_vector_get_size (list_of_callbacks) > 0)
-        {
-          RegisteredRPC *rpc;
-          rpc =
-            (RegisteredRPC *) GNUNET_vector_delete_last (list_of_callbacks);
-          GNUNET_GE_LOG (ectx,
-                         GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
-                         _("RPC not unregistered: %s:%p\n"), rpc->name,
-                         rpc->callback);
-          GNUNET_free (rpc->name);
-          GNUNET_free (rpc);
-        }
-      GNUNET_vector_destroy (list_of_callbacks);
-      list_of_callbacks = NULL;
-    }
+  GNUNET_GE_ASSERT(NULL, NULL == incomingCalls);
+  GNUNET_GE_ASSERT(NULL, NULL == outgoingCalls);
+  GNUNET_GE_ASSERT(NULL, NULL == list_of_callbacks);
+  GNUNET_cron_del_job(coreAPI->cron,
+                     &RPC_retry_job,
+                     RPC_CRON_FREQUENCY,
+                     NULL);
   coreAPI = NULL;
-  rpcLock = NULL;
+  lock = NULL;
 }
 
 /**
@@ -1481,14 +959,9 @@
   static GNUNET_RPC_ServiceAPI rpcAPI;
   int rvalue;
 
-  ectx = capi->ectx;
-  rpcLock = capi->connection_get_lock ();
+  lock = capi->connection_get_lock ();
   coreAPI = capi;
-  peerInformation = GNUNET_vector_create (16);
-  incomingCalls = GNUNET_vector_create (16);
-  outgoingCalls = GNUNET_vector_create (16);
-  list_of_callbacks = GNUNET_vector_create (16);
-  GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
+  GNUNET_GE_LOG (coreAPI->ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | 
GNUNET_GE_USER,
                  _("`%s' registering handlers %d %d %d\n"),
                  "rpc", GNUNET_P2P_PROTO_RPC_REQ, GNUNET_P2P_PROTO_RPC_RES,
                  GNUNET_P2P_PROTO_RPC_ACK);
@@ -1505,170 +978,22 @@
   if (rvalue == GNUNET_SYSERR)
     {
       release_module_rpc ();
-      GNUNET_GE_LOG (ectx,
+      GNUNET_GE_LOG (coreAPI->ectx,
                      GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
                      _("Failed to initialize `%s' service.\n"), "rpc");
       return NULL;
     }
-  else
-    {
-      rpcAPI.RPC_execute = &RPC_execute;
-      rpcAPI.RPC_register = &RPC_register;
-      rpcAPI.RPC_unregister = &RPC_unregister;
-      rpcAPI.RPC_register_async = &RPC_register_async;
-      rpcAPI.RPC_unregister_async = &RPC_unregister_async;
-      rpcAPI.RPC_start = &RPC_start;
-      rpcAPI.RPC_stop = &RPC_stop;
-      GNUNET_cron_add_job (coreAPI->cron,
-                           &agePeerStats,
-                           PEER_TRACKING_TIME_INTERVAL,
-                           PEER_TRACKING_TIME_INTERVAL, NULL);
-      return &rpcAPI;
-    }
+  GNUNET_cron_add_job(coreAPI->cron,
+                     &RPC_retry_job,
+                     RPC_CRON_FREQUENCY,
+                     RPC_CRON_FREQUENCY,
+                     NULL);
+  rpcAPI.RPC_register = &RPC_register;
+  rpcAPI.RPC_unregister = &RPC_unregister;
+  rpcAPI.RPC_complete = &RPC_complete;
+  rpcAPI.RPC_start = &RPC_start;
+  rpcAPI.RPC_stop = &RPC_stop;
+  return &rpcAPI;    
 }
 
-#if PROVIDE_RPC_TEST
-
-static void
-testCallback (const GNUNET_PeerIdentity * sender,
-              GNUNET_RPC_CallParameters * arguments,
-              GNUNET_RPC_CallParameters * results)
-{
-  unsigned int dl;
-  char *data;
-
-  GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "RPC callback invoked!\n");
-  if ((GNUNET_OK ==
-       GNUNET_RPC_parameters_get_value_by_name (arguments, "command", &dl,
-                                                (void **) &data))
-      && (strncmp ("Hello", data, dl) == 0))
-    {
-      GNUNET_GE_LOG (ectx,
-                     GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                     "RPC callback received Hello command!\n");
-      GNUNET_RPC_parameters_add (results, "response",
-                                 strlen ("Hello RPC World") + 1,
-                                 "Hello RPC World");
-    }
-}
-
-static void
-async_RPC_Complete_callback (GNUNET_RPC_CallParameters * results,
-                             struct GNUNET_Semaphore *GNUNET_RSA_sign)
-{
-  unsigned int dl;
-  char *reply;
-
-  GNUNET_semaphore_down (GNUNET_RSA_sign, GNUNET_YES);
-  if ((GNUNET_OK != GNUNET_RPC_parameters_get_value_by_name (results,
-                                                             "response",
-                                                             &dl,
-                                                             (void **)
-                                                             &reply))
-      || (strncmp ("Hello RPC World", reply, dl) != 0))
-    {
-      GNUNET_GE_LOG (ectx,
-                     GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
-                     _("RPC async reply invalid.\n"));
-    }
-  else
-    GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                   "RPC async reply received.\n");
-}
-
-int
-initialize_module_rpc (GNUNET_CoreAPIForPlugins * capi)
-{
-  GNUNET_RPC_ServiceAPI *rpcAPI;
-  int ret;
-  GNUNET_RPC_CallParameters *args;
-  GNUNET_RPC_CallParameters *rets;
-  unsigned int dl;
-  char *reply;
-  int code;
-  struct GNUNET_RPC_RequestHandle *record;
-  struct GNUNET_Semaphore *GNUNET_RSA_sign;
-
-  GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "RPC testcase starting\n");
-  rpcAPI = capi->request_service ("rpc");
-  if (rpcAPI == NULL)
-    {
-      GNUNET_GE_BREAK (ectx, 0);
-      return GNUNET_SYSERR;
-    }
-  ret = GNUNET_OK;
-
-  if (GNUNET_OK != rpcAPI->RPC_register ("testFunction", &testCallback))
-    {
-      GNUNET_GE_BREAK (ectx, 0);
-      ret = GNUNET_SYSERR;
-    }
-
-  args = GNUNET_RPC_parameters_create ();
-  GNUNET_RPC_parameters_add (args, "command", strlen ("Hello") + 1, "Hello");
-  GNUNET_RSA_sign = GNUNET_semaphore_create (0);
-  record = rpcAPI->RPC_start (coreAPI->myIdentity,
-                              "testFunction",
-                              args,
-                              0,
-                              5 * GNUNET_CRON_SECONDS,
-                              (GNUNET_RPC_AsynchronousCompletionCallback) &
-                              async_RPC_Complete_callback, GNUNET_RSA_sign);
-  GNUNET_semaphore_up (GNUNET_RSA_sign);        /* allow callback now - forces 
async! */
-  rets = GNUNET_RPC_parameters_create ();
-  code = rpcAPI->RPC_execute (coreAPI->myIdentity,
-                              "testFunction", args, rets, 0,
-                              5 * GNUNET_CRON_SECONDS);
-  if (code != GNUNET_RPC_ERROR_OK)
-    {
-      GNUNET_GE_BREAK (ectx, 0);
-      ret = GNUNET_SYSERR;
-    }
-  GNUNET_RPC_parameters_destroy (args);
-  if ((GNUNET_OK != GNUNET_RPC_parameters_get_value_by_name (rets,
-                                                             "response",
-                                                             &dl,
-                                                             (void **)
-                                                             &reply))
-      || (strncmp ("Hello RPC World", reply, dl) != 0))
-    {
-      GNUNET_GE_BREAK (ectx, 0);
-      ret = GNUNET_SYSERR;
-    }
-  GNUNET_RPC_parameters_destroy (rets);
-  GNUNET_thread_sleep (1 * GNUNET_CRON_SECONDS);
-  if (GNUNET_RPC_ERROR_OK != rpcAPI->RPC_stop (record))
-    GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,
-                   _("async RPC reply not received.\n"));
-
-  if (GNUNET_OK != rpcAPI->RPC_unregister ("testFunction", &testCallback))
-    {
-      GNUNET_GE_BREAK (ectx, 0);
-      ret = GNUNET_SYSERR;
-    }
-  if (GNUNET_OK != capi->release_service (rpcAPI))
-    {
-      GNUNET_GE_BREAK (ectx, 0);
-      ret = GNUNET_SYSERR;
-    }
-  GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
-                 "RPC testcase completed with status %s\n",
-                 ret == GNUNET_OK ? "SUCCESS" : "FAILURE");
-  return ret;
-}
-
-/**
- * Does nothing (but must be present for clean unload of the
- * testcase!).
- */
-int
-done_module_rpc ()
-{
-  return GNUNET_OK;
-}
-
-#endif
-
 /* end of rpc.c */

Modified: GNUnet/src/include/Makefile.am
===================================================================
--- GNUnet/src/include/Makefile.am      2008-02-17 04:58:52 UTC (rev 6347)
+++ GNUnet/src/include/Makefile.am      2008-02-17 07:50:48 UTC (rev 6348)
@@ -13,7 +13,6 @@
 gnunetincludedir = $(includedir)/GNUnet
 
 gnunetinclude_HEADERS = \
-  gnunet_blockstore.h \
   gnunet_bootstrap_service.h \
   gnunet_collection_lib.h \
   gnunet_core.h \

Deleted: GNUnet/src/include/gnunet_blockstore.h
===================================================================
--- GNUnet/src/include/gnunet_blockstore.h      2008-02-17 04:58:52 UTC (rev 
6347)
+++ GNUnet/src/include/gnunet_blockstore.h      2008-02-17 07:50:48 UTC (rev 
6348)
@@ -1,155 +0,0 @@
-/*
-      This file is part of GNUnet
-      (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
-
-      GNUnet is free software; you can redistribute it and/or modify
-      it under the terms of the GNU General Public License as published
-      by the Free Software Foundation; either version 2, or (at your
-      option) any later version.
-
-      GNUnet is distributed in the hope that it will be useful, but
-      WITHOUT ANY WARRANTY; without even the implied warranty of
-      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-      General Public License for more details.
-
-      You should have received a copy of the GNU General Public License
-      along with GNUnet; see the file COPYING.  If not, write to the
-      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-      Boston, MA 02111-1307, USA.
- */
-
-/**
- * @file include/gnunet_blockstore.h
- * @brief common API for DHT and GAP service to obtain local data (from FS)
- * @author Christian Grothoff
- */
-
-#ifndef GNUNET_BLOCKSTORE_H
-#define GNUNET_BLOCKSTORE_H
-
-#include "gnunet_util.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0                           /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
-/**
- * Data stored in the blockstore.
- */
-typedef struct
-{
-  /**
-   * Size of the data container (in NBO).  This field
-   * is followed by size-sizeof(unsigned int) bytes
-   * of data.
-   */
-  unsigned int size;
-} GNUNET_DataContainer;
-
-/**
- * Callback function type for items in the GAP datastore.
- *
- * @param key the current key
- * @param value the current value
- * @param cls argument passed for context (closure)
- * @return GNUNET_OK to continue with iteration, GNUNET_SYSERR to abort
- */
-typedef int (*GNUNET_DataProcessor) (const GNUNET_HashCode * key,
-                                     const GNUNET_DataContainer * value,
-                                     void *cls);
-
-/**
- * GAP and DHT clients must implement this interface to tell
- * the routing code how to get to local data.
- *
- * The use of key in this API maybe confusing.  The specific content
- * of keys is not specified, the routing code only transmits the
- * number of keys and the type.  Only the first key is used for
- * routing, the other parts are just passed along and untouched by the
- * routing code.  The type is typically used to tell what they refer
- * to.  The assumption is that they (including the type) can be
- * reproduced from the GNUNET_DataContainer and thus the Iterator
- * methods do not communicate those values.
- *
- * The put method is (ab)used to check an item that is merely routed
- * for its integrity.
- */
-typedef struct
-{
-
-  /**
-   * First argument to be passed to all functions in this struct.
-   */
-  void *closure;
-
-  /**
-   * Do a quick test if we MAY have the content.
-   */
-  int (*fast_get) (const GNUNET_HashCode * key);
-
-  /**
-   * Lookup an item in the datastore.
-   *
-   * @param type kind of item to look up
-   * @param prio how important is this lookup
-   * @param keyCount number of keys given
-   * @param keys to look up
-   * @param resultCallback function to call for each result that was found
-   * @param resCallbackClosure extra argument to resultCallback
-   * @return number of results, GNUNET_SYSERR on error
-   */
-  int (*get) (void *closure,
-              unsigned int type,
-              unsigned int prio,
-              unsigned int keyCount,
-              const GNUNET_HashCode * keys,
-              GNUNET_DataProcessor resultCallback, void *resCallbackClosure);
-
-  /**
-   * Store an item in the datastore.
-   *
-   * @param key the key of the item, NULL if not known
-   *        (client should try to figure it out)
-   * @param value the value to store
-   * @return GNUNET_OK if the value could be stored,
-   *         GNUNET_NO if the value verifies but is not stored,
-   *         GNUNET_SYSERR if the value is malformed
-   */
-  int (*put) (void *closure,
-              const GNUNET_HashCode * key,
-              const GNUNET_DataContainer * value, unsigned int prio);
-
-  /**
-   * Remove an item from the datastore.
-   *
-   * @param key the key of the item
-   * @param value the value to remove, NULL for all values of the key
-   * @return GNUNET_OK if the value could be removed, GNUNET_SYSERR if not 
(i.e. not present)
-   */
-  int (*del) (void *closure,
-              const GNUNET_HashCode * key,
-              const GNUNET_DataContainer * value);
-
-  /**
-   * Iterate over all keys in the local datastore
-   *
-   * @param processor function to call on each item
-   * @param cls argument to processor
-   * @return number of results, GNUNET_SYSERR on error
-   */
-  int (*iterate) (void *closure, GNUNET_DataProcessor processor, void *cls);
-
-} GNUNET_Blockstore;
-
-#if 0                           /* keep Emacsens' auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif

Modified: GNUnet/src/include/gnunet_dht_lib.h
===================================================================
--- GNUnet/src/include/gnunet_dht_lib.h 2008-02-17 04:58:52 UTC (rev 6347)
+++ GNUnet/src/include/gnunet_dht_lib.h 2008-02-17 07:50:48 UTC (rev 6348)
@@ -1,6 +1,6 @@
 /*
       This file is part of GNUnet
-      (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+      (C) 2004, 2005, 2006, 2008 Christian Grothoff (and other contributing 
authors)
 
       GNUnet is free software; you can redistribute it and/or modify
       it under the terms of the GNU General Public License as published
@@ -27,7 +27,6 @@
 #ifndef GNUNET_DHT_LIB_H
 #define GNUNET_DHT_LIB_H
 
-#include "gnunet_blockstore.h"
 #include "gnunet_dht_service.h"
 
 #ifdef __cplusplus
@@ -55,7 +54,7 @@
                     unsigned int type,
                     const GNUNET_HashCode * key,
                     GNUNET_CronTime timeout,
-                    GNUNET_DataProcessor resultCallback,
+                    GNUNET_ResultProcessor resultCallback,
                     void *resCallbackClosure);
 
 /**
@@ -68,7 +67,9 @@
 int GNUNET_DHT_put (struct GNUNET_GC_Configuration *cfg,
                     struct GNUNET_GE_Context *ectx,
                     const GNUNET_HashCode * key,
-                    unsigned int type, const GNUNET_DataContainer * value);
+                    unsigned int type, 
+                   unsigned int size,
+                   const char * value);
 
 #if 0                           /* keep Emacsens' auto-indent happy */
 {

Modified: GNUnet/src/include/gnunet_dht_service.h
===================================================================
--- GNUnet/src/include/gnunet_dht_service.h     2008-02-17 04:58:52 UTC (rev 
6347)
+++ GNUnet/src/include/gnunet_dht_service.h     2008-02-17 07:50:48 UTC (rev 
6348)
@@ -1,6 +1,6 @@
 /*
       This file is part of GNUnet
-      (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+      (C) 2004, 2005, 2006, 2008 Christian Grothoff (and other contributing 
authors)
 
       GNUnet is free software; you can redistribute it and/or modify
       it under the terms of the GNU General Public License as published
@@ -32,7 +32,7 @@
 #define GNUNET_DHT_SERVICE_H
 
 #include "gnunet_core.h"
-#include "gnunet_blockstore.h"
+#include "gnunet_dstore_service.h"
 
 #ifdef __cplusplus
 extern "C"
@@ -61,7 +61,7 @@
    */
   struct GNUNET_DHT_GetHandle *(*get_start) (unsigned int type,
                                              const GNUNET_HashCode * key,
-                                             GNUNET_DataProcessor callback,
+                                             GNUNET_ResultProcessor callback,
                                              void *cls);
 
   /**

Modified: GNUnet/src/include/gnunet_dstore_service.h
===================================================================
--- GNUnet/src/include/gnunet_dstore_service.h  2008-02-17 04:58:52 UTC (rev 
6347)
+++ GNUnet/src/include/gnunet_dstore_service.h  2008-02-17 07:50:48 UTC (rev 
6348)
@@ -42,10 +42,10 @@
 #endif
 #endif
 
-typedef void (*GNUNET_ResultProcessor) (const GNUNET_HashCode * key,
-                                        unsigned int type,
-                                        unsigned int size,
-                                        const char *data, void *cls);
+typedef int (*GNUNET_ResultProcessor) (const GNUNET_HashCode * key,
+                                      unsigned int type,
+                                      unsigned int size,
+                                      const char *data, void *cls);
 
 /**
  * @brief Definition of the SQ-Store API.

Modified: GNUnet/src/include/gnunet_rpc_lib.h
===================================================================
--- GNUnet/src/include/gnunet_rpc_lib.h 2008-02-17 04:58:52 UTC (rev 6347)
+++ GNUnet/src/include/gnunet_rpc_lib.h 2008-02-17 07:50:48 UTC (rev 6348)
@@ -1,6 +1,6 @@
 /*
       This file is part of GNUnet
-      (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+      (C) 2004, 2005, 2006, 2008 Christian Grothoff (and other contributing 
authors)
 
       GNUnet is free software; you can redistribute it and/or modify
       it under the terms of the GNU General Public License as published
@@ -29,7 +29,6 @@
 
 #include "gnunet_core.h"
 #include "gnunet_util.h"
-#include "gnunet_blockstore.h"
 
 #ifdef __cplusplus
 extern "C"
@@ -42,89 +41,55 @@
 /**
  * Type of RPC arguments.
  */
-#define GNUNET_RPC_CallParameters struct GNUNET_Vector
+struct GNUNET_RPC_CallParameters;
 
 /**
  * RPC argument handling helper functions.
  */
-GNUNET_RPC_CallParameters *GNUNET_RPC_parameters_create (void);
+struct GNUNET_RPC_CallParameters *GNUNET_RPC_parameters_create (void);
 
-void GNUNET_RPC_parameters_destroy (GNUNET_RPC_CallParameters * param);
+void GNUNET_RPC_parameters_destroy (struct GNUNET_RPC_CallParameters * param);
 
-unsigned int GNUNET_RPC_parameters_count (GNUNET_RPC_CallParameters * param);
+unsigned int GNUNET_RPC_parameters_count (const struct 
GNUNET_RPC_CallParameters * param);
 
-void GNUNET_RPC_parameters_add (GNUNET_RPC_CallParameters * param,
+void GNUNET_RPC_parameters_add (struct GNUNET_RPC_CallParameters * param,
                                 const char *name,
                                 unsigned int dataLength, const void *data);
 
-void GNUNET_RPC_parameters_add_data_container (GNUNET_RPC_CallParameters *
-                                               param, const char *name,
-                                               const GNUNET_DataContainer *
-                                               data);
-
-const char *GNUNET_RPC_parameters_get_name (GNUNET_RPC_CallParameters * param,
-                                            unsigned int i);
-
-unsigned int GNUNET_RPC_get_index_by_name (GNUNET_RPC_CallParameters * param,
-                                           const char *name);
-
 /**
  * @return GNUNET_OK on success, GNUNET_SYSERR on error
  */
-int GNUNET_RPC_parameters_get_value_by_name (GNUNET_RPC_CallParameters *
+int GNUNET_RPC_parameters_get_value_by_name (const struct 
GNUNET_RPC_CallParameters *
                                              param, const char *name,
                                              unsigned int *dataLength,
-                                             void **data);
+                                             void const ** data);
 
 /**
  * @return GNUNET_OK on success, GNUNET_SYSERR on error
  */
-int GNUNET_RPC_parameters_get_value_by_index (GNUNET_RPC_CallParameters *
+int GNUNET_RPC_parameters_get_value_by_index (const struct 
GNUNET_RPC_CallParameters *
                                               param, unsigned int i,
                                               unsigned int *dataLength,
-                                              void **data);
+                                              void const ** data);
 
 /**
- * Return the value of the given parameter in the RPC parameter structure.
+ * Serialize the param array.
  *
- * @param param Target RPC parameter structure
- * @param value set to the value of the parameter
+ * @param target must point to at least 
GNUNET_RPC_parameters_get_serialized_size(param) bytes of memory.
  */
-GNUNET_DataContainer
-  * GNUNET_RPC_parameters_get_data_container_by_index
-  (GNUNET_RPC_CallParameters * param, unsigned int i);
-
-/**
- * Return the value of the named parameter in the RPC parameter
- * structure.
- *
- * @param param Target RPC parameter structure
- * @param value set to the value of the named parameter
- * @return GNUNET_SYSERR on error
- */
-GNUNET_DataContainer
-  *
-GNUNET_RPC_parameters_get_data_container_by_name (GNUNET_RPC_CallParameters *
-                                                  param, const char *name);
-
-/**
- * Serialize the param array.  target must point to at least
- * GNUNET_RPC_parameters_get_serialized_size(param) bytes of memory.
- */
-void GNUNET_RPC_parameters_serialize (GNUNET_RPC_CallParameters * param,
+void GNUNET_RPC_parameters_serialize (const struct GNUNET_RPC_CallParameters * 
param,
                                       char *target);
 
 /**
  * Deserialize parameters from buffer.
  */
-GNUNET_RPC_CallParameters *GNUNET_RPC_parameters_deserialize (char *buffer,
-                                                              size_t size);
+struct GNUNET_RPC_CallParameters *GNUNET_RPC_parameters_deserialize (const 
char *buffer,
+                                                                    size_t 
size);
 
 /**
  * How many bytes are required to serialize the param array?
  */
-size_t GNUNET_RPC_parameters_get_serialized_size (GNUNET_RPC_CallParameters *
-                                                  param);
+size_t GNUNET_RPC_parameters_get_serialized_size (const struct 
GNUNET_RPC_CallParameters * param);
 
 
 #if 0                           /* keep Emacsens' auto-indent happy */

Modified: GNUnet/src/include/gnunet_rpc_service.h
===================================================================
--- GNUnet/src/include/gnunet_rpc_service.h     2008-02-17 04:58:52 UTC (rev 
6347)
+++ GNUnet/src/include/gnunet_rpc_service.h     2008-02-17 07:50:48 UTC (rev 
6348)
@@ -1,6 +1,6 @@
 /*
       This file is part of GNUnet
-      (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+      (C) 2004, 2005, 2006, 2008 Christian Grothoff (and other contributing 
authors)
 
       GNUnet is free software; you can redistribute it and/or modify
       it under the terms of the GNU General Public License as published
@@ -28,8 +28,6 @@
 #define GNUNET_RPC_SERVICE_H
 
 #include "gnunet_core.h"
-#include "gnunet_util_containers.h"
-#include "gnunet_blockstore.h"
 #include "gnunet_rpc_lib.h"
 
 #ifdef __cplusplus
@@ -73,14 +71,9 @@
 #define GNUNET_RPC_ERROR_REPLY_MALFORMED 5
 
 /**
- * Prototype for synchronous RPC functions.
+ * RPC_stop was called before a response was received
  */
-typedef void (*GNUNET_RPC_SynchronousFunction) (const GNUNET_PeerIdentity *
-                                                caller,
-                                                GNUNET_RPC_CallParameters *
-                                                arguments,
-                                                GNUNET_RPC_CallParameters *
-                                                results);
+#define GNUNET_RPC_ERROR_ABORTED 6
 
 /**
  * Opaque RPC internal per-RPC data.
@@ -88,35 +81,34 @@
 struct GNUNET_RPC_CallHandle;
 
 /**
- * GNUNET_RSA_Signature of the callback function for the ASYNC_RPC to
- * be called upon completion of the ASYNC function.
- */
-typedef void (*GNUNET_RPC_CompleteCallback) (GNUNET_RPC_CallParameters *
-                                             results, int errorCode,
-                                             struct GNUNET_RPC_CallHandle *
-                                             context);
-
-/**
  * Prototype for asynchronous RPC functions.
+ *
+ * @param caller who called the function?
+ * @param arguments arguments to the call
+ * @param context argument to pass to rpc->RPC_complete when the function is 
done
  */
-typedef void (*GNUNET_RPC_AsynchronousFunction) (const GNUNET_PeerIdentity *
+typedef void (*GNUNET_RPC_AsynchronousFunction) (void * cls,
+                                                const GNUNET_PeerIdentity *
                                                  caller,
-                                                 GNUNET_RPC_CallParameters *
+                                                const struct 
GNUNET_RPC_CallParameters *
                                                  arguments,
-                                                 GNUNET_RPC_CompleteCallback
-                                                 callback,
                                                  struct GNUNET_RPC_CallHandle
                                                  * context);
 
 
 /**
  * Function to call once an asynchronous RPC completes.
+ * A function of this type is called if we receive return
+ * values from an RPC.
+ * @param responder who responded
+ * @param results return values
+ * @param closure client-specific context
  */
-typedef void (*GNUNET_RPC_AsynchronousCompletionCallback) (const
-                                                           GNUNET_PeerIdentity
+typedef void (*GNUNET_RPC_AsynchronousCompletionCallback) (const 
GNUNET_PeerIdentity
                                                            * responder,
-                                                           
GNUNET_RPC_CallParameters
+                                                          const struct 
GNUNET_RPC_CallParameters
                                                            * results,
+                                                          unsigned int 
errorCode,
                                                            void *closure);
 
 struct GNUNET_RPC_RequestHandle;
@@ -128,37 +120,19 @@
 {
 
   /**
-   * Perform a synchronous RPC.
-   */
-  int (*RPC_execute) (const GNUNET_PeerIdentity * receiver,
-                      const char *name,
-                      GNUNET_RPC_CallParameters * request_param,
-                      GNUNET_RPC_CallParameters * return_param,
-                      unsigned int importance, GNUNET_CronTime timeout);
-
-  /**
-   * Register a synchronous RPC function.
-   */
-  int (*RPC_register) (const char *name, GNUNET_RPC_SynchronousFunction func);
-
-  /**
-   * Unregister a synchronous RPC function.
-   */
-  int (*RPC_unregister) (const char *name,
-                         GNUNET_RPC_SynchronousFunction func);
-
-  /**
    * Register an asynchronous RPC function.
    */
-  int (*RPC_register_async) (const char *name,
-                             GNUNET_RPC_AsynchronousFunction func);
+  int (*RPC_register) (const char *name,
+                      GNUNET_RPC_AsynchronousFunction func,
+                      void * cls);
 
 
   /**
    * Unregister an asynchronous RPC function.
    */
-  int (*RPC_unregister_async) (const char *name,
-                               GNUNET_RPC_AsynchronousFunction func);
+  int (*RPC_unregister) (const char *name,
+                        GNUNET_RPC_AsynchronousFunction func,
+                        void * cls);
 
   /**
    * Start an asynchronous RPC.
@@ -172,7 +146,7 @@
    */
   struct GNUNET_RPC_RequestHandle *(*RPC_start) (const GNUNET_PeerIdentity *
                                                  receiver, const char *name,
-                                                 GNUNET_RPC_CallParameters *
+                                                 const struct 
GNUNET_RPC_CallParameters *
                                                  request_param,
                                                  unsigned int importance,
                                                  GNUNET_CronTime timeout,
@@ -180,13 +154,28 @@
                                                  callback, void *closure);
 
   /**
-   * Stop an asynchronous RPC.
+   * Stop an asynchronous RPC.  After calling this function,
+   * the AsynchronousCompletionCallback of the corresponding
+   * RPC_start request will no longer be called.  RPC_stop
+   * must be called either to abort the RPC early or to
+   * clean up the RPC's state after successful completion.
+   * There must be one and only one call to RPC_stop for
+   * each call to RPC_start.
    *
    * @param record the return value from RPC_start
    * @return GNUNET_RPC_ERROR_OK if the RPC was successful
    */
   int (*RPC_stop) (struct GNUNET_RPC_RequestHandle * record);
 
+  /**
+   * Tell RPC the result of an RPC call.  This function must
+   * be called once and only once for each AsynchronousFunction
+   * that is called from the RPC module.
+   */
+  void (*RPC_complete) (const struct GNUNET_RPC_CallParameters *
+                      results, int errorCode,
+                      struct GNUNET_RPC_CallHandle *
+                      context);
 
 } GNUNET_RPC_ServiceAPI;
 

Modified: GNUnet/src/include/gnunet_util_containers.h
===================================================================
--- GNUnet/src/include/gnunet_util_containers.h 2008-02-17 04:58:52 UTC (rev 
6347)
+++ GNUnet/src/include/gnunet_util_containers.h 2008-02-17 07:50:48 UTC (rev 
6348)
@@ -59,11 +59,6 @@
 typedef int (*GNUNET_HashCodeIterator) (GNUNET_HashCode * next, void *arg);
 
 /**
- * @brief a GNUNET_Vector (ordered variable size set of elements), opaque
- */
-struct GNUNET_Vector;
-
-/**
  * Load a bloom-filter from a file.
  * @param filename the name of the file (or the prefix)
  * @param size the size of the bloom-filter (number of
@@ -173,129 +168,6 @@
                                 void *iterator_arg,
                                 unsigned int size, unsigned int k);
 
-/**
- * A debug function that dumps the vector to stderr.
- */
-void GNUNET_vector_dump (struct GNUNET_Vector *v);
-
-/**
- * @param vss Size of the VectorSegment data area. The "correct" value for this
- * is a bit of a gamble, as it depends on both the operations you
- * perform on the vectors and how much data is stored in them. In
- * general, the more data you store the bigger the segments should be,
- * or otherwise the increased length of the linked list will become a
- * bottleneck for operations that are performed on arbitrary indexes.
- */
-struct GNUNET_Vector *GNUNET_vector_create (unsigned int vss);
-
-/**
- * Free vector structure including its data segments, but _not_ including the
- * stored void pointers. It is the user's responsibility to empty the vector
- * when necessary to avoid memory leakage.
- */
-void GNUNET_vector_destroy (struct GNUNET_Vector *v);
-
-size_t GNUNET_vector_get_size (struct GNUNET_Vector *v);
-
-/**
- * Insert a new element in the vector at given index.
- * @return GNUNET_OK on success, GNUNET_SYSERR if the index is out of bounds.
- */
-int GNUNET_vector_insert_at (struct GNUNET_Vector *v, void *object,
-                             unsigned int index);
-
-/**
- * Insert a new element at the end of the vector.
- */
-void GNUNET_vector_insert_last (struct GNUNET_Vector *v, void *object);
-
-/**
- * Return the element at given index in the vector or NULL if the index is out
- * of bounds. The iterator is set to point to the returned element.
- */
-void *GNUNET_vector_get (struct GNUNET_Vector *v, unsigned int index);
-
-/**
- * Return the first element in the vector, whose index is 0, or NULL if the
- * vector is empty. The iterator of the vector is set to point to the first
- * element.
- */
-void *GNUNET_vector_get_first (struct GNUNET_Vector *v);
-
-/**
- * Return the last element in the vector or NULL if the vector is empty. The
- * iterator of the vector is set to point to the last element.
- */
-void *GNUNET_vector_get_last (struct GNUNET_Vector *v);
-
-/**
- * Return the next element in the vector, as called after vector_get_at() or
- * vector_get_first(). The return value is NULL if there are no more elements
- * in the vector or if the iterator has not been set.
- */
-void *GNUNET_vector_get_next (struct GNUNET_Vector *v);
-
-/**
- * Return the previous element in the vector, as called after vector_get_at()
- * or vector_get_last(). The return value is NULL if there are no more
- * elements in the vector or if the iterator has not been set.
- */
-void *GNUNET_vector_get_prev (struct GNUNET_Vector *v);
-
-/**
- * Delete and return the element at given index. NULL is returned if index is
- * out of bounds.
- */
-void *GNUNET_vector_delete_at (struct GNUNET_Vector *v, unsigned int index);
-
-/**
- * Delete and return the last element in the vector, or NULL if the vector
- * is empty.
- */
-void *GNUNET_vector_delete_last (struct GNUNET_Vector *v);
-
-/**
- * Delete and return given object from the vector, or return NULL if the object
- * is not found.
- */
-void *GNUNET_vector_delete (struct GNUNET_Vector *v, void *object);
-
-/**
- * Set the given index in the vector. The old value of the index is
- * returned, or NULL if the index is out of bounds.
- */
-void *GNUNET_vector_update_at (struct GNUNET_Vector *v, void *object,
-                               unsigned int index);
-
-/**
- * Set the index occupied by the given object to point to the new object.
- * The old object is returned, or NULL if it's not found.
- */
-void *GNUNET_vector_update (struct GNUNET_Vector *v, void *object,
-                            void *old_object);
-
-/**
- * Swaps the contents of index1 and index2. Return value is GNUNET_OK
- * on success, GNUNET_SYSERR if either index is out of bounds.
- */
-int GNUNET_vector_swap_elements (struct GNUNET_Vector *v, unsigned int index1,
-                                 unsigned int index2);
-
-/**
- * Return the index of given element or -1 if the element is not found.
- */
-unsigned int GNUNET_vector_index_of (struct GNUNET_Vector *v, void *object);
-
-/**
- * Return the data stored in the vector as a single dynamically
- * allocated array of (void *), which must be GNUNET_freeed by the caller.
- * Use the functions get_{at,first,last,next,previous} instead, unless
- * you really need to access everything in the vector as fast as
- * possible.
- */
-void **GNUNET_vector_to_array (struct GNUNET_Vector *v);
-
-
 #if 0                           /* keep Emacsens' auto-indent happy */
 {
 #endif

Modified: GNUnet/src/util/containers/Makefile.am
===================================================================
--- GNUnet/src/util/containers/Makefile.am      2008-02-17 04:58:52 UTC (rev 
6347)
+++ GNUnet/src/util/containers/Makefile.am      2008-02-17 07:50:48 UTC (rev 
6348)
@@ -5,12 +5,10 @@
 noinst_LTLIBRARIES = libcontainers.la
 
 libcontainers_la_SOURCES = \
- bloomfilter.c \
- vector.c 
+ bloomfilter.c 
 
 check_PROGRAMS = \
- bloomtest \
- vectortest 
+ bloomtest 
 
 TESTS = $(check_PROGRAMS)
 
@@ -18,9 +16,3 @@
  bloomtest.c
 bloomtest_LDADD = \
  $(top_builddir)/src/util/libgnunetutil.la 
-
-vectortest_SOURCES = \
- vectortest.c
-vectortest_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la 
-

Deleted: GNUnet/src/util/containers/vector.c
===================================================================
--- GNUnet/src/util/containers/vector.c 2008-02-17 04:58:52 UTC (rev 6347)
+++ GNUnet/src/util/containers/vector.c 2008-02-17 07:50:48 UTC (rev 6348)
@@ -1,689 +0,0 @@
-/*
-      This file is part of GNUnet
-
-      GNUnet is free software; you can redistribute it and/or modify
-      it under the terms of the GNU General Public License as published
-      by the Free Software Foundation; either version 2, or (at your
-      option) any later version.
-
-      GNUnet is distributed in the hope that it will be useful, but
-      WITHOUT ANY WARRANTY; without even the implied warranty of
-      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-      General Public License for more details.
-
-      You should have received a copy of the GNU General Public License
-      along with GNUnet; see the file COPYING.  If not, write to the
-      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-      Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file util/containers/vector.c
- * @brief Implementation of a dynamic array
- * @author Antti Salonen, Christian Grothoff
- * @version vector.c,v 1.3 2004/05/02 20:22:52 aksalone Exp
- *
- * An implementation of a dynamic array of objects. Like an array, the
- * vector's elements are indexed, but it is also possible to
- * dynamically resize the vector by inserting and removing elements at
- * any location.  The vector is implemented as a double-linked list of
- * arrays, each with a static maximum length. When one array fills up,
- * it's splitted into two half-full arrays, and so forth. With
- * functions {insert,get,remove}_last the vector can also be used as a
- * fairly efficient stack.  The functions
- * get_{at,first,last,next,previous} allow traversing the vector in an
- * efficient manner, each function call taking more or less constant
- * time. Vector_get_next and Vector_get_first may only be called after
- * a call to one of vector_get_{first,last,at}, which set the vector's
- * iterator. All functions that modify the vector's contents unset the
- * iterator.
- */
-
-#include "platform.h"
-#include "gnunet_util.h"
-#include "gnunet_util_containers.h"
-
-typedef struct GNUNET_Vector
-{
-  unsigned int VECTOR_SEGMENT_SIZE;
-  struct vector_segment_t *segmentsHead;
-  struct vector_segment_t *segmentsTail;
-  struct vector_segment_t *iteratorSegment;
-  unsigned int iteratorIndex;
-  size_t size;
-} Vector;
-
-
-typedef struct vector_segment_t
-{
-  void **data;                  /* always of size VECTOR_SEGMENT_SIZE */
-  struct vector_segment_t *next;
-  struct vector_segment_t *previous;
-  size_t size;
-} VectorSegment;
-
-/**
- * A debug function that traverses the linked list and prints the
- * sizes of the segments. This currently isn't used.
- */
-void
-GNUNET_vector_dump (Vector * v)
-{
-  VectorSegment *vs;
-  int n;
-  unsigned int sum = 0;
-
-  for (vs = v->segmentsHead; vs; vs = vs->next)
-    {
-      fprintf (stderr,
-               "Segment-size: %3llu / %llu [%llu...%llu]: ",
-               (unsigned long long) vs->size,
-               (unsigned long long) v->VECTOR_SEGMENT_SIZE,
-               (unsigned long long) sum,
-               (unsigned long long) (sum + vs->size - 1));
-      for (n = 0; n < vs->size; n++)
-        {
-          fprintf (stderr, "%p, ", vs->data[n]);
-        }
-      fprintf (stderr, "\n");
-      sum += vs->size;
-    }
-  fprintf (stderr, "Vector size: %u\n", sum);
-}
-
-/**
- * Remove and return the element at given index in the segment's array. The
- * trailing pointers in the array, if any, are moved backwards to fill the gap.
- */
-static void *
-vectorSegmentRemoveAtIndex (VectorSegment * vs, int index)
-{
-  void *rvalue = vs->data[index];
-
-  while (index < vs->size)
-    {
-      vs->data[index] = vs->data[index + 1];
-      index++;
-    }
-  return rvalue;
-}
-
-
-/**
- * Split the full segment vs into two half-full segments.
- */
-static void
-vectorSegmentSplit (Vector * v, VectorSegment * vs)
-{
-  VectorSegment *oldNext;
-  int moveCount;
-
-  oldNext = vs->next;
-  vs->next = GNUNET_malloc (sizeof (VectorSegment));
-  vs->next->data = GNUNET_malloc (v->VECTOR_SEGMENT_SIZE * sizeof (void *));
-  vs->next->previous = vs;
-  vs->next->next = oldNext;
-  if (NULL != oldNext)
-    oldNext->previous = vs->next;
-  else
-    v->segmentsTail = vs->next;
-  moveCount = vs->size / 2;
-  memcpy (vs->next->data,
-          vs->data + (vs->size - moveCount), moveCount * sizeof (void *));
-  vs->next->size = moveCount;
-  vs->size -= moveCount;
-}
-
-/**
- * Joins the given segment with the following segment. The first segment _must_
- * be empty enough to store the data of both segments.
- */
-static void
-vectorSegmentJoin (Vector * v, VectorSegment * vs)
-{
-  VectorSegment *oldNext = vs->next->next;
-
-  memcpy (vs->data + vs->size,
-          vs->next->data, vs->next->size * sizeof (void *));
-  vs->size += vs->next->size;
-  GNUNET_free (vs->next->data);
-  GNUNET_free (vs->next);
-  vs->next = oldNext;
-  if (oldNext != NULL)
-    vs->next->previous = vs;
-  else
-    v->segmentsTail = vs;
-}
-
-/**
- * Free an empty segment, _unless_ it is the only segment.
- */
-static void
-vectorSegmentRemove (Vector * v, VectorSegment * vs)
-{
-  if ((vs->previous == NULL) && (vs->next == NULL))
-    return;
-  if (vs->previous != NULL)
-    vs->previous->next = vs->next;
-  else
-    v->segmentsHead = vs->next;
-  if (vs->next != NULL)
-    vs->next->previous = vs->previous;
-  else
-    v->segmentsTail = vs->previous;
-  GNUNET_free (vs->data);
-  GNUNET_free (vs);
-}
-
-
-/**
- * Search for given index in the vector v. When the index is found, its
- * segment and relative index are written to parameters vs and segment_index.
- * If possible, an unused index at the end of a segment is returned, as this
- * is also a requirement for adding data in an empty vector.
- */
-static int
-vectorFindNewIndex (Vector * v, unsigned int index, VectorSegment ** vs)
-{
-  VectorSegment *segment;
-  int segmentStartIndex;
-
-  if (index > v->size)
-    {
-      *vs = NULL;
-      return -1;
-    }
-  if (index <= v->size / 2)
-    {                           /* empty vector included */
-      segment = v->segmentsHead;
-      segmentStartIndex = 0;
-      while (index > segmentStartIndex + segment->size)
-        {
-          segmentStartIndex += segment->size;
-          segment = segment->next;
-        }
-    }
-  else
-    {                           /* reverse */
-      segment = v->segmentsTail;
-      segmentStartIndex = v->size - segment->size;
-      while (index <= segmentStartIndex)
-        {
-          segment = segment->previous;
-          segmentStartIndex -= segment->size;
-        }
-    }
-  *vs = segment;
-  return index - segmentStartIndex;
-}
-
-
-/**
- * Find the segment and segmentIndex of the element
- * with the given index.
- */
-static int
-vectorFindIndex (Vector * v, unsigned int index, VectorSegment ** vs)
-{
-  VectorSegment *segment;
-  int segmentStartIndex;
-
-  if (index >= v->size)
-    {
-      *vs = NULL;
-      return -1;
-    }
-  if (index < v->size / 2)
-    {
-      segment = v->segmentsHead;
-      segmentStartIndex = 0;
-      while (index >= segmentStartIndex + segment->size)
-        {
-          segmentStartIndex += segment->size;
-          segment = segment->next;
-        }
-    }
-  else
-    {
-      segment = v->segmentsTail;
-      segmentStartIndex = v->size - segment->size;
-      while (index < segmentStartIndex)
-        {
-          segment = segment->previous;
-          segmentStartIndex -= segment->size;
-        }
-    }
-  *vs = segment;
-  return index - segmentStartIndex;
-}
-
-
-/*
- * Traverse the vector looking for a given object. When found, set the pointer
- * pointed to by vs to point to the object's segment and the integer pointed
- * to by segmentIndex to the object's index in the segment. If the object is
- * not found, *vs is set to NULL.
- */
-static void
-vectorFindObject (Vector * v,
-                  void *object, VectorSegment ** vs, int *segmentIndex)
-{
-  VectorSegment *segment;
-  int i;
-
-  segment = v->segmentsHead;
-  while (NULL != segment)
-    {
-      for (i = 0; i < segment->size; i++)
-        {
-          if (segment->data[i] == object)
-            {
-              *vs = segment;
-              *segmentIndex = i;
-              return;
-            }
-        }
-      segment = segment->next;
-    }
-  *vs = NULL;
-}
-
-
-/**
- * Allocate a new vector structure with a single empty data segment.
- */
-Vector *
-GNUNET_vector_create (unsigned int vss)
-{
-  Vector *rvalue;
-
-  if (vss < 2)
-    return NULL;                /* invalid! */
-  rvalue = GNUNET_malloc (sizeof (Vector));
-  rvalue->VECTOR_SEGMENT_SIZE = vss;
-  rvalue->size = 0;
-  rvalue->segmentsHead = GNUNET_malloc (sizeof (VectorSegment));
-  rvalue->segmentsHead->data = GNUNET_malloc (sizeof (void *) * vss);
-  rvalue->segmentsTail = rvalue->segmentsHead;
-  rvalue->segmentsHead->next = NULL;
-  rvalue->segmentsHead->previous = NULL;
-  rvalue->segmentsHead->size = 0;
-  rvalue->iteratorSegment = NULL;
-  rvalue->iteratorIndex = 0;
-  return rvalue;
-}
-
-/**
- * Free vector structure including its data segments, but _not_ including the
- * stored void pointers. It is the user's responsibility to empty the vector
- * when necessary to avoid memory leakage.
- */
-void
-GNUNET_vector_destroy (Vector * v)
-{
-  VectorSegment *vs;
-  VectorSegment *vsNext;
-
-  vs = v->segmentsHead;
-  while (vs != NULL)
-    {
-      vsNext = vs->next;
-      GNUNET_free (vs->data);
-      GNUNET_free (vs);
-      vs = vsNext;
-    }
-  GNUNET_free (v);
-}
-
-/**
- * Return the size of the vector.
- */
-size_t
-GNUNET_vector_get_size (Vector * v)
-{
-  return v->size;
-}
-
-/**
- * Insert a new element in the vector at given index. The return value is
- * GNUNET_OK on success, GNUNET_SYSERR if the index is out of bounds.
- */
-int
-GNUNET_vector_insert_at (Vector * v, void *object, unsigned int index)
-{
-  VectorSegment *segment;
-  int segmentIndex;
-  int i;
-
-  if (index > v->size)
-    return GNUNET_SYSERR;
-  v->iteratorSegment = NULL;
-  segmentIndex = vectorFindNewIndex (v, index, &segment);
-  if (segmentIndex == -1)
-    return GNUNET_SYSERR;
-  for (i = segment->size; i > segmentIndex; i--)
-    segment->data[i] = segment->data[i - 1];
-  segment->data[segmentIndex] = object;
-  v->size++;
-  segment->size++;
-  if (segment->size == v->VECTOR_SEGMENT_SIZE)
-    vectorSegmentSplit (v, segment);
-  return GNUNET_OK;
-}
-
-/**
- * Insert a new element at the end of the vector.
- */
-void
-GNUNET_vector_insert_last (Vector * v, void *object)
-{
-  v->iteratorSegment = NULL;
-  v->segmentsTail->data[v->segmentsTail->size++] = object;
-  if (v->segmentsTail->size == v->VECTOR_SEGMENT_SIZE)
-    vectorSegmentSplit (v, v->segmentsTail);
-  v->size++;
-}
-
-/**
- * Return the element at given index in the vector or NULL if the index is out
- * of bounds. The iterator is set to point to the returned element.
- */
-void *
-GNUNET_vector_get (Vector * v, unsigned int index)
-{
-  int ret;
-  if (index >= v->size)
-    return NULL;
-  ret = vectorFindIndex (v, index, &v->iteratorSegment);
-  if (ret == -1)
-    return NULL;
-  v->iteratorIndex = ret;
-  return v->iteratorSegment->data[ret];
-}
-
-/**
- * Return the first element in the vector, whose index is 0, or NULL if the
- * vector is empty. The iterator of the vector is set to point to the first
- * element.
- */
-void *
-GNUNET_vector_get_first (Vector * v)
-{
-  if (v->size == 0)
-    return NULL;
-  v->iteratorSegment = v->segmentsHead;
-  v->iteratorIndex = 0;
-  return v->iteratorSegment->data[0];
-}
-
-/**
- * Return the last element in the vector or NULL if the vector is
- * empty. The iterator of the vector is set to the last element.
- */
-void *
-GNUNET_vector_get_last (Vector * v)
-{
-  if (v->size == 0)
-    return NULL;
-  v->iteratorSegment = v->segmentsTail;
-  v->iteratorIndex = v->segmentsTail->size - 1;
-  return v->segmentsTail->data[v->iteratorIndex];
-}
-
-/**
- * Return the next element in the vector, as called after vector_get_at() or
- * vector_get_first(). The return value is NULL if there are no more elements
- * in the vector or if the iterator has not been set.
- */
-void *
-GNUNET_vector_get_next (Vector * v)
-{
-  if (v->iteratorSegment == NULL)
-    return NULL;
-  if (++v->iteratorIndex >= v->iteratorSegment->size)
-    {
-      if (v->iteratorSegment == v->segmentsTail)
-        {
-          v->iteratorSegment = NULL;
-          return NULL;
-        }
-      else
-        {
-          v->iteratorSegment = v->iteratorSegment->next;
-          v->iteratorIndex = 0;
-        }
-    }
-  return v->iteratorSegment->data[v->iteratorIndex];
-}
-
-/**
- * Return the previous element in the vector, as called after vector_get_at()
- * or vector_get_last(). The return value is NULL if there are no more
- * elements in the vector or if the iterator has not been set.
- */
-void *
-GNUNET_vector_get_prev (Vector * v)
-{
-  if (v->iteratorSegment == NULL)
-    return NULL;
-  if (--v->iteratorIndex == -1)
-    {
-      if (v->iteratorSegment == v->segmentsHead)
-        {
-          v->iteratorSegment = 0;
-          return NULL;
-        }
-      else
-        {
-          v->iteratorSegment = v->iteratorSegment->previous;
-          v->iteratorIndex = v->iteratorSegment->size - 1;
-        }
-    }
-  return v->iteratorSegment->data[v->iteratorIndex];
-}
-
-/**
- * Delete and return the element at given index. NULL is returned if index is
- * out of bounds.
- */
-void *
-GNUNET_vector_delete_at (Vector * v, unsigned int index)
-{
-  VectorSegment *segment;
-  int segmentIndex;
-  void *rvalue;
-
-  if (index >= v->size)
-    return NULL;
-  v->iteratorSegment = NULL;
-  segmentIndex = vectorFindIndex (v, index, &segment);
-  if (segmentIndex == -1)
-    return NULL;
-  rvalue = vectorSegmentRemoveAtIndex (segment, segmentIndex);
-  /* If the segment ends empty remove it, otherwise
-     try to join it with its neighbors. */
-  if (--segment->size == 0)
-    vectorSegmentRemove (v, segment);
-  else if (segment->next &&
-           segment->size + segment->next->size < v->VECTOR_SEGMENT_SIZE)
-    vectorSegmentJoin (v, segment);
-  else if (segment->previous &&
-           segment->size + segment->previous->size < v->VECTOR_SEGMENT_SIZE)
-    vectorSegmentJoin (v, segment->previous);
-  v->size--;
-  return rvalue;
-}
-
-/**
- * Delete and return the last element in the vector, or NULL if the vector
- * is empty.
- */
-void *
-GNUNET_vector_delete_last (Vector * v)
-{
-  void *rvalue;
-
-  if (v->size == 0)
-    return NULL;
-  v->iteratorSegment = NULL;
-  rvalue = v->segmentsTail->data[v->segmentsTail->size - 1];
-  /* If the segment ends empty remove it, otherwise join it if necessary. */
-  if (--v->segmentsTail->size == 0)
-    vectorSegmentRemove (v, v->segmentsTail);
-  else if ((v->segmentsTail->previous != NULL) &&
-           (v->segmentsTail->size + v->segmentsTail->previous->size
-            < v->VECTOR_SEGMENT_SIZE))
-    vectorSegmentJoin (v, v->segmentsTail->previous);
-  v->size--;
-  return rvalue;
-}
-
-/**
- * Delete and return given object from the vector, or return NULL if the object
- * is not found.
- */
-void *
-GNUNET_vector_delete (Vector * v, void *object)
-{
-  VectorSegment *segment;
-  int segmentIndex;
-  void *rvalue;
-
-  v->iteratorSegment = NULL;
-  vectorFindObject (v, object, &segment, &segmentIndex);
-  if (segment == NULL)
-    return NULL;
-  rvalue = vectorSegmentRemoveAtIndex (segment, segmentIndex);
-  /* If the segment ends empty remove it, otherwise join it if necessary. */
-  if (--segment->size == 0)
-    vectorSegmentRemove (v, segment);
-  else if ((segment->next != NULL) &&
-           (segment->size + segment->next->size < v->VECTOR_SEGMENT_SIZE))
-    vectorSegmentJoin (v, segment);
-  else if ((segment->previous != NULL) &&
-           (segment->size + segment->previous->size < v->VECTOR_SEGMENT_SIZE))
-    vectorSegmentJoin (v, segment->previous);
-  v->size--;
-  return rvalue;
-}
-
-/**
- * Set the given index in the vector. The old value of the index is
- * returned, or NULL if the index is out of bounds.
- */
-void *
-GNUNET_vector_update_at (Vector * v, void *object, unsigned int index)
-{
-  VectorSegment *segment;
-  int segmentIndex;
-  void *rvalue;
-
-  if (index >= v->size)
-    return NULL;
-  v->iteratorSegment = NULL;
-  segmentIndex = vectorFindIndex (v, index, &segment);
-  if (segmentIndex == -1)
-    return NULL;
-  rvalue = segment->data[segmentIndex];
-  segment->data[segmentIndex] = object;
-  return rvalue;
-}
-
-
-/**
- * Set the index occupied by the given object to point to the new object.
- * The old object is returned, or NULL if it's not found.
- */
-void *
-GNUNET_vector_update (Vector * v, void *object, void *oldObject)
-{
-  VectorSegment *segment;
-  int segmentIndex;
-  void *rvalue;
-
-  v->iteratorSegment = NULL;
-  vectorFindObject (v, oldObject, &segment, &segmentIndex);
-  if (segment == NULL)
-    return NULL;
-  rvalue = segment->data[segmentIndex];
-  segment->data[segmentIndex] = object;
-  return rvalue;
-}
-
-
-/**
- * Swaps the contents of index1 and index2. Return value is GNUNET_OK
- * on success, GNUNET_SYSERR if either index is out of bounds.
- */
-int
-GNUNET_vector_swap_elements (Vector * v, unsigned int index1,
-                             unsigned int index2)
-{
-  VectorSegment *segment1;
-  VectorSegment *segment2;
-  int segmentIndex1;
-  int segmentIndex2;
-  void *temp;
-
-  if ((index1 >= v->size) || (index2 >= v->size))
-    return GNUNET_SYSERR;
-  v->iteratorSegment = NULL;
-  segmentIndex1 = vectorFindIndex (v, index1, &segment1);
-  segmentIndex2 = vectorFindIndex (v, index2, &segment2);
-  if ((segmentIndex1 == -1) || (segmentIndex2 == -1))
-    return GNUNET_SYSERR;
-  temp = segment1->data[segmentIndex1];
-  segment1->data[segmentIndex1] = segment2->data[segmentIndex2];
-  segment2->data[segmentIndex2] = temp;
-  return GNUNET_OK;
-}
-
-/**
- * Return the index of given element or -1 if the element is not found.
- */
-unsigned int
-GNUNET_vector_index_of (Vector * v, void *object)
-{
-  VectorSegment *segment;
-  unsigned int i;
-  unsigned int segmentStartIndex;
-
-  segmentStartIndex = 0;
-  segment = v->segmentsHead;
-  while (NULL != segment)
-    {
-      for (i = 0; i < segment->size; i++)
-        if (segment->data[i] == object)
-          return segmentStartIndex + i;
-      segmentStartIndex += segment->size;
-      segment = segment->next;
-    }
-  return (unsigned int) -1;
-}
-
-
-/*
- * Return the data stored in the vector as a single dynamically allocated
- * array of (void *), which must be free(3)d by the user. Use the functions
- * get_{at,first,last,next,previous} instead, unless you really need to access
- * everything in the vector as fast as possible.
- */
-void **
-GNUNET_vector_to_array (Vector * v)
-{
-  void **rvalue;
-  VectorSegment *vs;
-  size_t i = 0;
-
-  rvalue = GNUNET_malloc_large (v->size * sizeof (void *));
-  for (vs = v->segmentsHead; vs; vs = vs->next)
-    {
-      memcpy (rvalue + i, vs->data, vs->size * sizeof (void *));
-      i += vs->size;
-    }
-  return rvalue;
-}
-
-
-
-/* end of vector.c */

Deleted: GNUnet/src/util/containers/vectortest.c
===================================================================
--- GNUnet/src/util/containers/vectortest.c     2008-02-17 04:58:52 UTC (rev 
6347)
+++ GNUnet/src/util/containers/vectortest.c     2008-02-17 07:50:48 UTC (rev 
6348)
@@ -1,277 +0,0 @@
-/*
-      This file is part of GNUnet
-      (C) 2005, 2006 Christian Grothoff (and other contributing authors)
-
-      GNUnet is free software; you can redistribute it and/or modify
-      it under the terms of the GNU General Public License as published
-      by the Free Software Foundation; either version 2, or (at your
-      option) any later version.
-
-      GNUnet is distributed in the hope that it will be useful, but
-      WITHOUT ANY WARRANTY; without even the implied warranty of
-      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-      General Public License for more details.
-
-      You should have received a copy of the GNU General Public License
-      along with GNUnet; see the file COPYING.  If not, write to the
-      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-      Boston, MA 02111-1307, USA.
-*/
-
-/**
- * This is a testcase for the vector, waiting to be extended.
- */
-
-#include "gnunet_util.h"
-#include "gnunet_util_containers.h"
-#include "platform.h"
-
-#define DUMP(v) fprintf(stderr, "At %d: \n", __LINE__); GNUNET_vector_dump(v); 
GNUNET_vector_destroy(v);
-
-static int
-test (int size)
-{
-  struct GNUNET_Vector *v;
-
-  v = GNUNET_vector_create (size);
-  if (0 != GNUNET_vector_get_size (v))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (GNUNET_OK != GNUNET_vector_insert_at (v, "first", 0))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (GNUNET_OK == GNUNET_vector_insert_at (v, "not", 2))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (GNUNET_OK != GNUNET_vector_insert_at (v, "zero", 0))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (GNUNET_OK != GNUNET_vector_insert_at (v, "second", 2))
-    {
-      DUMP (v);
-      return 1;
-    }
-  GNUNET_vector_insert_last (v, "third");
-  if (4 != GNUNET_vector_get_size (v))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (0 != strcmp (GNUNET_vector_get (v, 1), "first"))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (0 != strcmp (GNUNET_vector_get (v, 3), "third"))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (0 != strcmp (GNUNET_vector_get (v, 0), "zero"))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (0 != strcmp (GNUNET_vector_get_first (v), "zero"))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (0 != strcmp (GNUNET_vector_get_last (v), "third"))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (0 != strcmp (GNUNET_vector_delete_at (v, 1), "first"))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (0 != strcmp (GNUNET_vector_get (v, 1), "second"))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (NULL != GNUNET_vector_delete_at (v, 3))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (3 != GNUNET_vector_get_size (v))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (0 != strcmp (GNUNET_vector_delete_at (v, 1), "second"))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (0 != strcmp (GNUNET_vector_delete (v, "third"), "third"))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (NULL != GNUNET_vector_delete (v, "third"))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (0 != strcmp (GNUNET_vector_delete_last (v), "zero"))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (0 != GNUNET_vector_get_size (v))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (NULL != GNUNET_vector_delete_last (v))
-    {
-      DUMP (v);
-      return 1;
-    }
-  if (0 != GNUNET_vector_get_size (v))
-    {
-      DUMP (v);
-      return 1;
-    }
-  GNUNET_vector_destroy (v);
-  return 0;
-}
-
-static int
-test2 (int size)
-{
-  long i;
-  struct GNUNET_Vector *v;
-
-  v = GNUNET_vector_create (size);
-
-  for (i = 0; i < 500; i++)
-    if (GNUNET_OK != GNUNET_vector_insert_at (v, (void *) i, 0))
-      {
-        DUMP (v);
-        return 1;
-      }
-  if (500 != GNUNET_vector_get_size (v))
-    {
-      DUMP (v);
-      return 1;
-    }
-  for (i = 0; i < 500; i++)
-    if (499 - i != (long) GNUNET_vector_get (v, i))
-      {
-        DUMP (v);
-        return 1;
-      }
-  if (499 != (long) GNUNET_vector_get_first (v))
-    {
-      DUMP (v);
-      return 1;
-    }
-  for (i = 498; i >= 0; i--)
-    if (i != (long) GNUNET_vector_get_next (v))
-      {
-        DUMP (v);
-        return 1;
-      }
-
-  if (499 != (long) GNUNET_vector_get_first (v))
-    {
-      DUMP (v);
-      return 1;
-    }
-  for (i = 498; i >= 250; i--)
-    if (i != (long) GNUNET_vector_get_next (v))
-      {
-        DUMP (v);
-        return 1;
-      }
-  for (i = 251; i < 499; i++)
-    if (i != (long) GNUNET_vector_get_prev (v))
-      {
-        DUMP (v);
-        return 1;
-      }
-
-  GNUNET_vector_destroy (v);
-  return 0;
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  if (NULL != GNUNET_vector_create (0))
-    {
-      printf ("At %d\n", __LINE__);
-      return 1;
-    }
-  if (NULL != GNUNET_vector_create (1))
-    {
-      printf ("At %d\n", __LINE__);
-      return 1;
-    }
-  if (test (2) != 0)
-    {
-      printf ("At %d\n", __LINE__);
-      return 1;
-    }
-  if (test (3) != 0)
-    {
-      printf ("At %d\n", __LINE__);
-      return 1;
-    }
-  if (test (4) != 0)
-    {
-      printf ("At %d\n", __LINE__);
-      return 1;
-    }
-  if (test (128) != 0)
-    {
-      printf ("At %d\n", __LINE__);
-      return 1;
-    }
-  if (test (65536) != 0)
-    {
-      printf ("At %d\n", __LINE__);
-      return 1;
-    }
-  if (test (2 * 65536) != 0)
-    {
-      printf ("At %d\n", __LINE__);
-      return 1;
-    }
-
-  if (test2 (2) != 0)
-    {
-      printf ("At %d\n", __LINE__);
-      return 1;
-    }
-  if (test2 (3) != 0)
-    {
-      printf ("At %d\n", __LINE__);
-      return 1;
-    }
-  if (test2 (4) != 0)
-    {
-      printf ("At %d\n", __LINE__);
-      return 1;
-    }
-  if (test2 (128) != 0)
-    {
-      printf ("At %d\n", __LINE__);
-      return 1;
-    }
-  return 0;
-}





reply via email to

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