--- /dev/null
+INCLUDES = -I$(top_srcdir)/src/include
+
+if MINGW
+ WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols -lole32 -lshell32 -luuid -liconv -lstdc++ -lcomdlg32 -lgdi32
+endif
+
+if USE_COVERAGE
+ AM_CFLAGS = --coverage -O0
+ XLIB = -lgcov
+endif
+
+lib_LTLIBRARIES = libgnunetdht.la
+
+libgnunetdht_la_SOURCES = \
+ dht_api.c dht.h
+libgnunetdht_la_LIBADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(XLIB)
+libgnunetdht_la_LDFLAGS = \
+ $(GN_LIB_LDFLAGS) $(WINFLAGS) \
+ -version-info 0:0:0
+
+
+bin_PROGRAMS = \
+ gnunet-service-dht
+
+gnunet_service_dht_SOURCES = \
+ gnunet-service-dht.c
+gnunet_service_dht_LDADD = \
+ $(top_builddir)/src/statistics/libgnunetstatistics.la \
+ $(top_builddir)/src/core/libgnunetcore.la \
+ $(top_builddir)/src/datastore/libgnunetdatastore.la \
+ $(top_builddir)/src/util/libgnunetutil.la
+
+
+check_PROGRAMS = \
+ test_dht_api
+
+TESTS = $(check_PROGRAMS) # $(check_SCRIPTS)
+
+test_dht_api_SOURCES = \
+ test_dht_api.c
+test_dht_api_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/dht/libgnunetdht.la
+
+EXTRA_DIST = \
+ test_dht_api_data.conf
+
+#check_SCRIPTS = \
+# test_gnunet_peerinfo.sh
--- /dev/null
+/*
+ This file is part of GNUnet.
+ (C) 2001, 2002, 2003, 2004, 2009 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.
+*/
+
+/**
+ * @author Christian Grothoff
+ * @author Nathan Evans
+ * @file dht/dht.h
+ */
+
+#ifndef DHT_H_
+#define DHT_H_
+
+#define DEBUG_DHT GNUNET_YES
+
+typedef void (*GNUNET_DHT_MessageReceivedHandler) (void *cls,
+ struct GNUNET_MessageHeader *msg);
+
+/**
+ * Message to insert data into the DHT
+ */
+struct GNUNET_DHT_PutMessage
+{
+ /**
+ * Type: GNUNET_MESSAGE_TYPE_DHT_PUT
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * The type of data to insert.
+ */
+ size_t type;
+
+ /**
+ * The key to insert data under.
+ */
+ GNUNET_HashCode key;
+
+ /**
+ * The size of the data, appended to the end of this message.
+ */
+ size_t data_size;
+
+ /**
+ * How long should this data persist?
+ */
+ struct GNUNET_TIME_Relative timeout;
+
+};
+
+
+/**
+ * Message to request data from the DHT
+ */
+struct GNUNET_DHT_GetMessage
+{
+ /**
+ * Type: GNUNET_MESSAGE_TYPE_DHT_GET
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * The type for the data for the GET request
+ */
+ size_t type;
+
+ /**
+ * The key to search for
+ */
+ GNUNET_HashCode key;
+
+};
+
+/**
+ * Message to return data from the DHT
+ */
+struct GNUNET_DHT_GetResultMessage
+{
+ /**
+ * Type: GNUNET_MESSAGE_TYPE_DHT_GET_RESULT
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * The type for the data for the GET request
+ */
+ size_t type;
+
+ /**
+ * The key to search for
+ */
+ GNUNET_HashCode key;
+
+ /**
+ * The size of the data, appended to the end of this message.
+ */
+ size_t data_size;
+
+};
+
+/**
+ * Response to PUT request from the DHT
+ */
+struct GNUNET_DHT_PutResultMessage
+{
+ /**
+ * Type: GNUNET_MESSAGE_TYPE_DHT_PUT_RESULT
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * The type for the data for the GET request
+ */
+ size_t type;
+
+ /**
+ * The key to search for
+ */
+ GNUNET_HashCode key;
+
+ /**
+ * Was the put successful? GNUNET_YES or GNUNET_NO
+ */
+ size_t result;
+
+};
+
+
+
+#endif /* DHT_H_ */
--- /dev/null
+/*
+ This file is part of GNUnet.
+ (C) 2009, 2010 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 dht/dht_api.c
+ * @brief library to access the DHT service
+ * @author Christian Grothoff
+ * @author Nathan Evans
+ */
+#include "platform.h"
+#include "gnunet_bandwidth_lib.h"
+#include "gnunet_client_lib.h"
+#include "gnunet_constants.h"
+#include "gnunet_container_lib.h"
+#include "gnunet_arm_service.h"
+#include "gnunet_hello_lib.h"
+#include "gnunet_protocols.h"
+#include "gnunet_server_lib.h"
+#include "gnunet_time_lib.h"
+#include "gnunet_dht_service.h"
+#include "dht.h"
+
+#define DEBUG_DHT_API GNUNET_YES
+
+struct PendingMessages
+{
+ /**
+ * Linked list of pending messages
+ */
+ struct PendingMessages *next;
+
+ /**
+ * Message that is pending
+ */
+ struct GNUNET_MessageHeader *msg;
+
+ /**
+ * Timeout for this message
+ */
+ struct GNUNET_TIME_Relative timeout;
+
+};
+
+/**
+ * Connection to the DHT service.
+ */
+struct GNUNET_DHT_Handle
+{
+ /**
+ * Our scheduler.
+ */
+ struct GNUNET_SCHEDULER_Handle *sched;
+
+ /**
+ * Configuration to use.
+ */
+ const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+ /**
+ * Socket (if available).
+ */
+ struct GNUNET_CLIENT_Connection *client;
+
+ /**
+ * Currently pending transmission request.
+ */
+ struct GNUNET_CLIENT_TransmitHandle *th;
+
+ /**
+ * List of the currently pending messages for the DHT service.
+ */
+ struct PendingMessages *pending_list;
+
+ /**
+ * Message we are currently sending.
+ */
+ struct PendingMessages *current;
+
+ /**
+ * Hash map containing the current outstanding get requests
+ */
+ struct GNUNET_CONTAINER_MultiHashMap *outstanding_get_requests;
+
+ /**
+ * Hash map containing the current outstanding put requests, awaiting
+ * a response
+ */
+ struct GNUNET_CONTAINER_MultiHashMap *outstanding_put_requests;
+
+ /**
+ * Kill off the connection and any pending messages.
+ */
+ int do_destroy;
+
+};
+
+static struct GNUNET_TIME_Relative default_request_timeout;
+
+/* Forward declaration */
+static void process_pending_message(struct GNUNET_DHT_Handle *handle);
+
+/**
+ * Handler for messages received from the DHT service
+ * a demultiplexer which handles numerous message types
+ *
+ */
+void service_message_handler (void *cls,
+ const struct GNUNET_MessageHeader *msg)
+{
+
+ /* TODO: find out message type, handle callbacks for different types of messages.
+ * Should be a put acknowledgment, get data or find node result. */
+}
+
+
+/**
+ * Initialize the connection with the DHT service.
+ *
+ * @param cfg configuration to use
+ * @param sched scheduler to use
+ * @return NULL on error
+ */
+struct GNUNET_DHT_Handle *
+GNUNET_DHT_connect (struct GNUNET_SCHEDULER_Handle *sched,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ struct GNUNET_DHT_Handle *handle;
+
+ handle = GNUNET_malloc(sizeof(struct GNUNET_DHT_Handle));
+
+ default_request_timeout = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5);
+ handle->cfg = cfg;
+ handle->sched = sched;
+ handle->pending_list = NULL;
+ handle->current = NULL;
+ handle->do_destroy = GNUNET_NO;
+ handle->th = NULL;
+
+ handle->client = GNUNET_CLIENT_connect(sched, "dht", cfg);
+ handle->outstanding_get_requests = GNUNET_CONTAINER_multihashmap_create(100); /* FIXME: better number */
+ handle->outstanding_put_requests = GNUNET_CONTAINER_multihashmap_create(100); /* FIXME: better number */
+ if (handle->client == NULL)
+ return NULL;
+#if DEBUG_DHT_API
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "`%s': Connection to service in progress\n", "DHT API");
+#endif
+ GNUNET_CLIENT_receive (handle->client,
+ &service_message_handler,
+ handle, GNUNET_TIME_UNIT_FOREVER_REL);
+
+ return handle;
+}
+
+
+/**
+ * Shutdown connection with the DHT service.
+ *
+ * @param h connection to shut down
+ */
+void
+GNUNET_DHT_disconnect (struct GNUNET_DHT_Handle *handle)
+{
+ struct PendingMessages *pos;
+#if DEBUG_DHT_API
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "`%s': Called GNUNET_DHT_disconnect\n", "DHT API");
+#endif
+ GNUNET_assert(handle != NULL);
+
+ if (handle->th != NULL) /* We have a live transmit request in the Aether */
+ {
+ GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th);
+ handle->th = NULL;
+ }
+ if (handle->current != NULL) /* We are trying to send something now, clean it up */
+ GNUNET_free(handle->current);
+
+ while (NULL != (pos = handle->pending_list)) /* Remove all pending sends from the list */
+ {
+ handle->pending_list = pos->next;
+ GNUNET_free(pos);
+ }
+ if (handle->client != NULL) /* Finally, disconnect from the service */
+ {
+ GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO);
+ handle->client = NULL;
+ }
+
+ GNUNET_free (handle);
+}
+
+
+/**
+ * Handle to control a GET operation.
+ */
+struct GNUNET_DHT_GetHandle
+{
+
+ /**
+ * Key that this get request is for
+ */
+ GNUNET_HashCode key;
+
+ /**
+ * Type of data get request was for
+ */
+ uint32_t type;
+
+ /**
+ * Iterator to call on data receipt
+ */
+ GNUNET_DHT_Iterator iter;
+
+ /**
+ * Closure for the iterator callback
+ */
+ void *iter_cls;
+};
+
+/**
+ * Handle for a PUT request, holds callback
+ */
+struct GNUNET_DHT_PutHandle
+{
+ /**
+ * Key that this get request is for
+ */
+ GNUNET_HashCode key;
+
+ /**
+ * Type of data get request was for
+ */
+ uint32_t type;
+
+ /**
+ * Continuation to call on put send
+ */
+ GNUNET_SCHEDULER_Task cont;
+
+ /**
+ * Send continuation cls
+ */
+ void *cont_cls;
+};
+
+/**
+ * Send complete (or failed), schedule next (or don't)
+ */
+static void
+finish (struct GNUNET_DHT_Handle *handle, int code)
+{
+ /* TODO: if code is not GNUNET_OK, do something! */
+ struct PendingMessages *pos = handle->current;
+ struct GNUNET_DHT_GetMessage *get;
+ struct GNUNET_DHT_PutMessage *put;
+
+ GNUNET_assert(pos != NULL);
+
+ switch (ntohs(pos->msg->type))
+ {
+ case GNUNET_MESSAGE_TYPE_DHT_GET:
+ get = (struct GNUNET_DHT_GetMessage *)pos->msg;
+ GNUNET_free(get);
+ break;
+ case GNUNET_MESSAGE_TYPE_DHT_PUT:
+ put = (struct GNUNET_DHT_PutMessage *)pos->msg;
+ GNUNET_free(put);
+ break;
+ default:
+ GNUNET_break(0);
+ }
+
+ handle->current = NULL;
+
+ if (code != GNUNET_SYSERR)
+ process_pending_message (handle);
+
+ GNUNET_free(pos);
+}
+
+/**
+ * Transmit the next pending message, called by notify_transmit_ready
+ */
+static size_t
+transmit_pending (void *cls, size_t size, void *buf)
+{
+ struct GNUNET_DHT_Handle *handle = cls;
+ size_t ret;
+ size_t tsize;
+
+ if (buf == NULL)
+ {
+#if DEBUG_DHT_API
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "`%s': In transmit_pending buf is NULL\n", "DHT API");
+#endif
+ /* FIXME: free associated resources or summat */
+ finish(handle, GNUNET_SYSERR);
+ return 0;
+ }
+
+ handle->th = NULL;
+ ret = 0;
+
+ if (handle->current != NULL)
+ {
+ tsize = ntohs(handle->current->msg->size);
+ if (size >= tsize)
+ {
+#if DEBUG_DHT_API
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "`%s': Sending message size %d\n", "DHT API", tsize);
+#endif
+ memcpy(buf, handle->current->msg, tsize);
+ }
+ else
+ {
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+
+/**
+ * Try to (re)connect to the dht service.
+ *
+ * @return GNUNET_YES on success, GNUNET_NO on failure.
+ */
+static int
+try_connect (struct GNUNET_DHT_Handle *ret)
+{
+ if (ret->client != NULL)
+ return GNUNET_OK;
+ ret->client = GNUNET_CLIENT_connect (ret->sched, "dht", ret->cfg);
+ if (ret->client != NULL)
+ return GNUNET_YES;
+#if DEBUG_STATISTICS
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ _("Failed to connect to the dht service!\n"));
+#endif
+ return GNUNET_NO;
+}
+
+
+/**
+ * Try to send messages from list of messages to send
+ */
+static void process_pending_message(struct GNUNET_DHT_Handle *handle)
+{
+
+ if (handle->current != NULL)
+ return; /* action already pending */
+ if (GNUNET_YES != try_connect (handle))
+ {
+ finish (handle, GNUNET_SYSERR);
+ return;
+ }
+
+ /* TODO: set do_destroy somewhere's, see what needs to happen in that case! */
+ if (handle->do_destroy)
+ {
+ //GNUNET_DHT_disconnect (handle); /* FIXME: replace with proper disconnect stuffs */
+ }
+
+ /* schedule next action */
+ handle->current = handle->pending_list;
+ if (NULL == handle->current)
+ {
+ return;
+ }
+ handle->pending_list = handle->pending_list->next;
+ handle->current->next = NULL;
+
+ if (NULL ==
+ (handle->th = GNUNET_CLIENT_notify_transmit_ready (handle->client,
+ ntohs(handle->current->msg->size),
+ handle->current->timeout,
+ GNUNET_YES,
+ &transmit_pending, handle)))
+ {
+#if DEBUG_DHT_API
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Failed to transmit request to dht service.\n");
+#endif
+ finish (handle, GNUNET_SYSERR);
+ }
+#if DEBUG_DHT_API
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "`%s': Scheduled sending message of size %d to service\n", "DHT API", ntohs(handle->current->msg->size));
+#endif
+}
+
+/**
+ * Add a pending message to the linked list of messages which need to be sent
+ *
+ * @param handle handle to the specified DHT api
+ * @param msg the message to add to the list
+ */
+static void add_pending(struct GNUNET_DHT_Handle *handle, struct GNUNET_MessageHeader *msg)
+{
+ struct PendingMessages *new_message;
+ struct PendingMessages *pos;
+ struct PendingMessages *last;
+
+ new_message = GNUNET_malloc(sizeof(struct PendingMessages));
+ new_message->msg = msg;
+ new_message->timeout = default_request_timeout;
+
+ if (handle->pending_list != NULL)
+ {
+ pos = handle->pending_list;
+ while(pos != NULL)
+ {
+ last = pos;
+ pos = pos->next;
+ }
+ new_message->next = last->next; /* Should always be null */
+ last->next = new_message;
+ }
+ else
+ {
+ new_message->next = handle->pending_list; /* Will always be null */
+ handle->pending_list = new_message;
+ }
+
+ process_pending_message(handle);
+}
+
+/**
+ * Perform an asynchronous GET operation on the DHT identified.
+ *
+ * @param h handle to the DHT service
+ * @param type expected type of the response object
+ * @param key the key to look up
+ * @param iter function to call on each result
+ * @param iter_cls closure for iter
+ * @return handle to stop the async get
+ */
+struct GNUNET_DHT_GetHandle *
+GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle,
+ uint32_t type,
+ const GNUNET_HashCode * key,
+ GNUNET_DHT_Iterator iter,
+ void *iter_cls)
+{
+ struct GNUNET_DHT_GetMessage *get_msg;
+ struct GNUNET_DHT_GetHandle *get_handle;
+
+ get_handle = GNUNET_CONTAINER_multihashmap_get(handle->outstanding_get_requests, key);
+
+ if (get_handle != NULL)
+ {
+ /*
+ * A get has been previously sent, return existing handle.
+ * FIXME: should we re-transmit the request to the DHT service?
+ */
+ return get_handle;
+ }
+
+ get_handle = GNUNET_malloc(sizeof(struct GNUNET_DHT_GetHandle));
+ get_handle->type = type;
+ memcpy(&get_handle->key, key, sizeof(GNUNET_HashCode));
+ get_handle->iter = iter;
+ get_handle->iter_cls = iter_cls;
+
+ GNUNET_CONTAINER_multihashmap_put(handle->outstanding_get_requests, key, get_handle, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+
+ get_msg = GNUNET_malloc(sizeof(struct GNUNET_DHT_GetMessage));
+ get_msg->header.type = htons(GNUNET_MESSAGE_TYPE_DHT_GET);
+ get_msg->header.size = htons(sizeof(struct GNUNET_DHT_GetMessage));
+ get_msg->type = htonl(type);
+ memcpy(&get_msg->key, key, sizeof(GNUNET_HashCode));
+
+ add_pending(handle, &get_msg->header);
+
+ return get_handle;
+}
+
+
+/**
+ * Stop async DHT-get. Frees associated resources.
+ *
+ * @param record GET operation to stop.
+ */
+void
+GNUNET_DHT_get_stop (struct GNUNET_DHT_Handle *handle, struct GNUNET_DHT_GetHandle *get_handle)
+{
+ struct GNUNET_DHT_GetMessage *get_msg;
+
+ if (handle->do_destroy == GNUNET_NO)
+ {
+ get_msg = GNUNET_malloc(sizeof(struct GNUNET_DHT_GetMessage));
+ get_msg->header.type = htons(GNUNET_MESSAGE_TYPE_DHT_GET_STOP);
+ get_msg->header.size = htons(sizeof(struct GNUNET_DHT_GetMessage));
+ get_msg->type = htonl(get_handle->type);
+ memcpy(&get_msg->key, &get_handle->key, sizeof(GNUNET_HashCode));
+
+ add_pending(handle, &get_msg->header);
+ }
+
+ GNUNET_assert(GNUNET_CONTAINER_multihashmap_remove(handle->outstanding_get_requests, &get_handle->key, get_handle) == GNUNET_YES);
+ GNUNET_free(get_handle);
+}
+
+
+/**
+ * Perform a PUT operation storing data in the DHT.
+ *
+ * @param h handle to DHT service
+ * @param key the key to store under
+ * @param type type of the value
+ * @param size number of bytes in data; must be less than 64k
+ * @param data the data to store
+ * @param exp desired expiration time for the value
+ * @param cont continuation to call when done;
+ * reason will be TIMEOUT on error,
+ * reason will be PREREQ_DONE on success
+ * @param cont_cls closure for cont
+ *
+ * @return GNUNET_YES if put message is queued for transmission
+ */
+int GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle,
+ const GNUNET_HashCode * key,
+ uint32_t type,
+ uint32_t size,
+ const char *data,
+ struct GNUNET_TIME_Relative exp,
+ GNUNET_SCHEDULER_Task cont,
+ void *cont_cls)
+{
+ struct GNUNET_DHT_PutMessage *put_msg;
+ struct GNUNET_DHT_PutHandle *put_handle;
+ size_t msize;
+
+ put_handle = GNUNET_CONTAINER_multihashmap_get(handle->outstanding_put_requests, key);
+
+ if (put_handle != NULL)
+ {
+ /*
+ * A put has been previously queued, but not yet sent.
+ * FIXME: change the continuation function and callback or something?
+ */
+ return GNUNET_NO;
+ }
+
+ put_handle = GNUNET_malloc(sizeof(struct GNUNET_DHT_PutHandle));
+ put_handle->type = type;
+ memcpy(&put_handle->key, key, sizeof(GNUNET_HashCode));
+
+ GNUNET_CONTAINER_multihashmap_put(handle->outstanding_put_requests, key, put_handle, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+
+ msize = sizeof(struct GNUNET_DHT_PutMessage) + size;
+ put_msg = GNUNET_malloc(msize);
+ put_msg->header.type = htons(GNUNET_MESSAGE_TYPE_DHT_PUT);
+ put_msg->header.size = htons(msize);
+ put_msg->type = htonl(type);
+ memcpy(&put_msg->key, key, sizeof(GNUNET_HashCode));
+ memcpy(&put_msg[1], data, size);
+
+ add_pending(handle, &put_msg->header);
+
+ return GNUNET_YES;
+}
--- /dev/null
+/*
+ This file is part of GNUnet.
+ (C) 2009, 2010 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 dht/gnunet_dht_service.c
+ * @brief main DHT service shell, building block for DHT implementations
+ * @author Christian Grothoff
+ * @author Nathan Evans
+ */
+
+#include "platform.h"
+#include "gnunet_client_lib.h"
+#include "gnunet_getopt_lib.h"
+#include "gnunet_os_lib.h"
+#include "gnunet_protocols.h"
+#include "gnunet_service_lib.h"
+#include "gnunet_core_service.h"
+#include "gnunet_signal_lib.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_datastore_service.h"
+#include "dht.h"
+
+/**
+ * Handle to the datastore service (for inserting/retrieving data)
+ */
+static struct GNUNET_DATASTORE_Handle *datastore;
+
+/**
+ * The main scheduler to use for the DHT service
+ */
+static struct GNUNET_SCHEDULER_Handle *sched;
+
+/**
+ * The configuration the DHT service is running with
+ */
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+/**
+ * Timeout for transmissions to clients
+ */
+static struct GNUNET_TIME_Relative client_transmit_timeout;
+
+/**
+ * Handle to the core service
+ */
+static struct GNUNET_CORE_Handle *coreAPI;
+
+/**
+ * The identity of our peer.
+ */
+static struct GNUNET_PeerIdentity my_identity;
+
+/**
+ * Task to run when we shut down, cleaning up all our trash
+ */
+static GNUNET_SCHEDULER_TaskIdentifier cleanup_task;
+
+struct ClientList
+{
+ /**
+ * This is a linked list
+ */
+ struct ClientList *next;
+
+ /**
+ * The client in question
+ */
+ struct GNUNET_SERVER_Client *client;
+};
+
+/**
+ * Server handler for initiating local dht get requests
+ */
+static void handle_dht_get (void *cls, struct GNUNET_SERVER_Client * client,
+ const struct GNUNET_MessageHeader *message);
+
+/**
+ * Server handler for stopping local dht get requests
+ */
+static void handle_dht_get_stop (void *cls, struct GNUNET_SERVER_Client * client,
+ const struct GNUNET_MessageHeader *message);
+
+/**
+ * Server handler for initiating local dht find peer requests
+ */
+static void handle_dht_find_peer (void *cls, struct GNUNET_SERVER_Client *
+ client, const struct GNUNET_MessageHeader *
+ message);
+
+/**
+ * Server handler for stopping local dht find peer requests
+ */
+static void handle_dht_find_peer_stop (void *cls, struct GNUNET_SERVER_Client *
+ client, const struct GNUNET_MessageHeader *
+ message);
+
+/**
+ * Server handler for initiating local dht put requests
+ */
+static void handle_dht_put (void *cls, struct GNUNET_SERVER_Client * client,
+ const struct GNUNET_MessageHeader *message);
+
+
+static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = {
+ {&handle_dht_get, NULL, GNUNET_MESSAGE_TYPE_DHT_GET, 0},
+ {&handle_dht_get_stop, NULL, GNUNET_MESSAGE_TYPE_DHT_GET_STOP, 0},
+ {&handle_dht_put, NULL, GNUNET_MESSAGE_TYPE_DHT_PUT, 0},
+ {&handle_dht_find_peer, NULL, GNUNET_MESSAGE_TYPE_DHT_FIND_PEER, 0},
+ {&handle_dht_find_peer_stop, NULL, GNUNET_MESSAGE_TYPE_DHT_FIND_PEER_STOP, 0},
+ {NULL, NULL, 0, 0}
+};
+
+
+/**
+ * Core handler for p2p dht get requests.
+ */
+static int handle_dht_p2p_get (void *cls,
+ const struct GNUNET_PeerIdentity * peer,
+ const struct GNUNET_MessageHeader * message,
+ struct GNUNET_TIME_Relative latency,
+ uint32_t distance);
+
+/**
+ * Core handler for p2p dht put requests.
+ */
+static int handle_dht_p2p_put (void *cls,
+ const struct GNUNET_PeerIdentity * peer,
+ const struct GNUNET_MessageHeader * message,
+ struct GNUNET_TIME_Relative latency,
+ uint32_t distance);
+
+/**
+ * Core handler for p2p dht find peer requests.
+ */
+static int handle_dht_p2p_find_peer (void *cls,
+ const struct GNUNET_PeerIdentity * peer,
+ const struct GNUNET_MessageHeader * message,
+ struct GNUNET_TIME_Relative latency,
+ uint32_t distance);
+
+static struct GNUNET_CORE_MessageHandler core_handlers[] = {
+ {&handle_dht_p2p_get, GNUNET_MESSAGE_TYPE_DHT_GET, 0},
+ {&handle_dht_p2p_put, GNUNET_MESSAGE_TYPE_DHT_PUT, 0},
+ {&handle_dht_p2p_find_peer, GNUNET_MESSAGE_TYPE_DHT_PUT, 0},
+ {NULL, 0, 0}
+};
+
+
+/**
+ * Server handler for initiating local dht get requests
+ */
+static void handle_dht_get (void *cls, struct GNUNET_SERVER_Client * client,
+ const struct GNUNET_MessageHeader *message)
+{
+#if DEBUG_DHT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "`%s': Received `%s' request from client\n", "DHT", "GET");
+#endif
+
+}
+
+/**
+ * Server handler for stopping local dht get requests
+ */
+static void handle_dht_get_stop (void *cls, struct GNUNET_SERVER_Client * client,
+ const struct GNUNET_MessageHeader *message)
+{
+#if DEBUG_DHT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "`%s': Received `%s' request from client\n", "DHT", "GET STOP");
+#endif
+
+}
+
+/**
+ * Server handler for initiating local dht find peer requests
+ */
+static void handle_dht_find_peer (void *cls, struct GNUNET_SERVER_Client *
+ client, const struct GNUNET_MessageHeader *
+ message)
+{
+#if DEBUG_DHT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "`%s': Received `%s' request from client\n", "DHT", "FIND PEER");
+#endif
+
+}
+
+/**
+ * Server handler for stopping local dht find peer requests
+ */
+static void handle_dht_find_peer_stop (void *cls, struct GNUNET_SERVER_Client *
+ client, const struct GNUNET_MessageHeader *
+ message)
+{
+#if DEBUG_DHT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "`%s': Received `%s' request from client\n", "DHT", "FIND PEER STOP");
+#endif
+
+}
+
+/**
+ * Server handler for initiating local dht put requests
+ */
+static void handle_dht_put (void *cls, struct GNUNET_SERVER_Client * client,
+ const struct GNUNET_MessageHeader *message)
+{
+#if DEBUG_DHT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "`%s': Received `%s' request from client\n", "DHT", "PUT");
+#endif
+
+}
+
+/**
+ * Core handler for p2p dht get requests.
+ */
+static int handle_dht_p2p_get (void *cls,
+ const struct GNUNET_PeerIdentity * peer,
+ const struct GNUNET_MessageHeader * message,
+ struct GNUNET_TIME_Relative latency,
+ uint32_t distance)
+{
+#if DEBUG_DHT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "`%s': Received `%s' request from another peer\n", "DHT", "GET");
+#endif
+
+ return GNUNET_YES;
+}
+
+/**
+ * Core handler for p2p dht put requests.
+ */
+static int handle_dht_p2p_put (void *cls,
+ const struct GNUNET_PeerIdentity * peer,
+ const struct GNUNET_MessageHeader * message,
+ struct GNUNET_TIME_Relative latency,
+ uint32_t distance)
+{
+#if DEBUG_DHT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "`%s': Received `%s' request from another peer\n", "DHT", "PUT");
+#endif
+
+ return GNUNET_YES;
+}
+
+/**
+ * Core handler for p2p dht find peer requests.
+ */
+static int handle_dht_p2p_find_peer (void *cls,
+ const struct GNUNET_PeerIdentity * peer,
+ const struct GNUNET_MessageHeader * message,
+ struct GNUNET_TIME_Relative latency,
+ uint32_t distance)
+{
+#if DEBUG_DHT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "`%s': Received `%s' request from another peer\n", "DHT", "FIND PEER");
+#endif
+
+ return GNUNET_YES;
+}
+
+/**
+ * Task run during shutdown.
+ *
+ * @param cls unused
+ * @param tc unused
+ */
+static void
+shutdown_task (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ GNUNET_CORE_disconnect (coreAPI);
+}
+
+/**
+ * To be called on core init/fail.
+ */
+void core_init (void *cls,
+ struct GNUNET_CORE_Handle * server,
+ const struct GNUNET_PeerIdentity *identity,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded * publicKey)
+{
+
+ if (server == NULL)
+ {
+ GNUNET_SCHEDULER_cancel(sched, cleanup_task);
+ GNUNET_SCHEDULER_add_now(sched, &shutdown_task, NULL);
+ return;
+ }
+#if DEBUG_DHT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "%s: Core connection initialized, I am peer: %s\n", "dht", GNUNET_i2s(identity));
+#endif
+ memcpy(&my_identity, identity, sizeof(struct GNUNET_PeerIdentity));
+ coreAPI = server;
+}
+
+/**
+ * Process dht requests.
+ *
+ * @param cls closure
+ * @param scheduler scheduler to use
+ * @param server the initialized server
+ * @param c configuration to use
+ */
+static void
+run (void *cls,
+ struct GNUNET_SCHEDULER_Handle *scheduler,
+ struct GNUNET_SERVER_Handle *server,
+ const struct GNUNET_CONFIGURATION_Handle *c)
+{
+ sched = scheduler;
+ cfg = c;
+
+ datastore = GNUNET_DATASTORE_connect(c, scheduler);
+
+ client_transmit_timeout = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5);
+ GNUNET_SERVER_add_handlers (server, plugin_handlers);
+
+ coreAPI =
+ GNUNET_CORE_connect (sched,
+ cfg,
+ client_transmit_timeout,
+ NULL, /* FIXME: anything we want to pass around? */
+ &core_init,
+ NULL, /* Don't care about pre-connects */
+ NULL, /* Don't care about connects */
+ NULL, /* Don't care about disconnects */
+ NULL,
+ GNUNET_NO,
+ NULL,
+ GNUNET_NO,
+ core_handlers);
+
+ if (coreAPI == NULL)
+ return;
+ /* load (server); Huh? */
+
+ /* Scheduled the task to clean up when shutdown is called */
+ cleanup_task = GNUNET_SCHEDULER_add_delayed (sched,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &shutdown_task,
+ NULL);
+}
+
+
+/**
+ * The main function for the dv service.
+ *
+ * @param argc number of arguments from the command line
+ * @param argv command line arguments
+ * @return 0 ok, 1 on error
+ */
+int
+main (int argc, char *const *argv)
+{
+ return (GNUNET_OK ==
+ GNUNET_SERVICE_run (argc,
+ argv,
+ "dht",
+ GNUNET_SERVICE_OPTION_NONE,
+ &run, NULL)) ? 0 : 1;
+}
--- /dev/null
+/*
+ This file is part of GNUnet.
+ (C) 2009 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 dht/test_dht_api.c
+ * @brief base test case for dht api
+ *
+ * This test case tests DHT api to DUMMY DHT service communication.
+ *
+ */
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_hello_lib.h"
+#include "gnunet_getopt_lib.h"
+#include "gnunet_os_lib.h"
+#include "gnunet_program_lib.h"
+#include "gnunet_scheduler_lib.h"
+#include "gnunet_dht_service.h"
+
+#define VERBOSE GNUNET_YES
+
+#define VERBOSE_ARM GNUNET_YES
+
+#define START_ARM GNUNET_YES
+
+/**
+ * How long until we give up on transmitting the message?
+ */
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 50)
+
+#define MTYPE 12345
+
+struct PeerContext
+{
+ struct GNUNET_CONFIGURATION_Handle *cfg;
+ struct GNUNET_DHT_Handle *dht_handle;
+ struct GNUNET_PeerIdentity id;
+#if START_ARM
+ pid_t arm_pid;
+#endif
+};
+
+static struct PeerContext p1;
+
+static struct GNUNET_SCHEDULER_Handle *sched;
+
+static int ok;
+
+GNUNET_SCHEDULER_TaskIdentifier die_task;
+
+#if VERBOSE
+#define OKPP do { ok++; fprintf (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0)
+#else
+#define OKPP do { ok++; } while (0)
+#endif
+
+
+static void
+end ()
+{
+ /* do work here */
+ GNUNET_SCHEDULER_cancel (sched, die_task);
+
+ GNUNET_DHT_disconnect (p1.dht_handle);
+
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "DHT disconnected, returning success!\n");
+ ok = 0;
+}
+
+static void
+stop_arm (struct PeerContext *p)
+{
+#if START_ARM
+ if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+ GNUNET_OS_process_wait (p->arm_pid);
+#endif
+ GNUNET_CONFIGURATION_destroy (p->cfg);
+}
+
+
+static void
+end_badly ()
+{
+ /* do work here */
+#if VERBOSE
+ fprintf(stderr, "Ending on an unhappy note.\n");
+#endif
+
+ GNUNET_DHT_disconnect (p1.dht_handle);
+
+ ok = 1;
+ return;
+}
+
+/**
+ * Signature of the main function of a task.
+ *
+ * @param cls closure
+ * @param tc context information (why was this task triggered now)
+ */
+void test_get (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext * tc)
+{
+ struct PeerContext *peer = cls;
+ GNUNET_HashCode hash;
+ memset(&hash, 42, sizeof(GNUNET_HashCode));
+
+ peer->dht_handle = GNUNET_DHT_connect (sched, peer->cfg);
+ GNUNET_assert (peer->dht_handle != NULL);
+
+ GNUNET_DHT_get_start(peer->dht_handle, 42, &hash, NULL, NULL);
+
+ GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 10), &end, &p1);
+}
+
+static void
+setup_peer (struct PeerContext *p, const char *cfgname)
+{
+ p->cfg = GNUNET_CONFIGURATION_create ();
+#if START_ARM
+ p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+ "gnunet-service-arm",
+#if VERBOSE_ARM
+ "-L", "DEBUG",
+#endif
+ "-c", cfgname, NULL);
+#endif
+ GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
+
+}
+
+static void
+run (void *cls,
+ struct GNUNET_SCHEDULER_Handle *s,
+ char *const *args,
+ const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ GNUNET_assert (ok == 1);
+ OKPP;
+ sched = s;
+
+ die_task = GNUNET_SCHEDULER_add_delayed (sched,
+ GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 1), &end_badly, NULL);
+
+ setup_peer (&p1, "test_dht_api_peer1.conf");
+
+ GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 2), &test_get, &p1);
+}
+
+static int
+check ()
+{
+
+ char *const argv[] = { "test-dht-api",
+ "-c",
+ "test_dht_api_data.conf",
+#if VERBOSE
+ "-L", "DEBUG",
+#endif
+ NULL
+ };
+
+ struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ ok = 1;
+ GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
+ argv, "test-dht-api", "nohelp",
+ options, &run, &ok);
+ stop_arm (&p1);
+ return ok;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int ret;
+#ifdef MINGW
+ return GNUNET_SYSERR;
+#endif
+
+ GNUNET_log_setup ("test-dht-api",
+#if VERBOSE
+ "DEBUG",
+#else
+ "WARNING",
+#endif
+ NULL);
+ ret = check ();
+
+ //GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-dht-peer-1");
+
+ return ret;
+}
+
+/* end of test_dht_api.c */
--- /dev/null
+[PATHS]
+SERVICEHOME = /tmp/test-dht-api/
+DEFAULTCONFIG = test_dht_api_data.conf
+
+[fs]
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-fs
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 2094
+INDEXDB = $SERVICEHOME/idxinfo.lst
+
+[datastore-sqlite]
+FILENAME = $SERVICEHOME/datastore/sqlite.db
+
+[datastore]
+DATABASE = sqlite
+BLOOMFILTER = $SERVICEHOME/fs/bloomfilter
+QUOTA = 100000000
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-datastore
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 2093
+
+[hostlist]
+HTTP-PROXY =
+SERVERS = http://gnunet.org:8080/
+OPTIONS = -b
+BINARY = gnunet-daemon-hostlist
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+HTTPPORT = 8080
+
+[topology]
+BINARY = gnunet-daemon-topology
+CONFIG = $DEFAULTCONFIG
+FRIENDS = $SERVICEHOME/friends
+TARGET-CONNECTION-COUNT = 16
+AUTOCONNECT = YES
+FRIENDS-ONLY = NO
+MINIMUM-FRIENDS = 0
+
+[core]
+TOTAL_QUOTA_OUT = 3932160
+TOTAL_QUOTA_IN = 3932160
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-core
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 2092
+
+[dht]
+DEBUG = YES
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-dht
+#BINARY = /root/documents/research/gnunet/gnunet-ng/src/dv/.libs/gnunet-service-dv
+#PREFIX = xterm -T dvservice -e gdb --args
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 12370
+
+[transport]
+plugins = tcp
+DEBUG = NO
+PREFIX =
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+NEIGHBOUR_LIMIT = 50
+BINARY = gnunet-service-transport
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 2091
+
+[peerinfo]
+TRUST = $SERVICEHOME/data/credit/
+HOSTS = $SERVICEHOME/data/hosts/
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-peerinfo
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 2090
+
+[resolver]
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-resolver
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 2089
+
+[statistics]
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-statistics
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 2088
+
+[arm]
+DEFAULTSERVICES = resolver transport core
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-arm
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 2087
+
+[transport-tcp]
+ALLOW_SHUTDOWN = NO
+TIMEOUT = 300000
+PORT = 2094
+
+[TESTING]
+WEAKRANDOM = NO
+
+[gnunetd]
+HOSTKEY = $SERVICEHOME/.hostkey
+
--- /dev/null
+[fs]
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-fs
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 2094
+INDEXDB = $SERVICEHOME/idxinfo.lst
+
+[datastore-sqlite]
+FILENAME = $SERVICEHOME/datastore/sqlite.db
+
+[datastore]
+DATABASE = sqlite
+BLOOMFILTER = $SERVICEHOME/fs/bloomfilter
+QUOTA = 100000000
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-datastore
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 2093
+
+[dht]
+DEBUG = YES
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-dht
+#BINARY = /root/documents/research/gnunet/gnunet-ng/src/dht/.libs/gnunet-service-dht
+#PREFIX = xterm -T dvservice -e gdb --args
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 2100
+
+[hostlist]
+HTTP-PROXY =
+SERVERS = http://gnunet.org:8080/
+OPTIONS = -b
+BINARY = gnunet-daemon-hostlist
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+HTTPPORT = 8080
+
+[topology]
+BINARY = gnunet-daemon-topology
+CONFIG = $DEFAULTCONFIG
+FRIENDS = $SERVICEHOME/friends
+TARGET-CONNECTION-COUNT = 16
+AUTOCONNECT = YES
+FRIENDS-ONLY = NO
+MINIMUM-FRIENDS = 0
+
+[transport]
+PLUGINS = tcp
+DEBUG = NO
+#PREFIX = xterm -T transport2 -e gdb --command=cmd --args
+#PREFIX = valgrind --leak-check=full
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+NEIGHBOUR_LIMIT = 50
+BINARY = gnunet-service-transport
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 12365
+
+[peerinfo]
+TRUST = $SERVICEHOME/data/credit/
+HOSTS = $SERVICEHOME/data/hosts/
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-peerinfo
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 12369
+
+[resolver]
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-resolver
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 12364
+
+[statistics]
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-statistics
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 12367
+
+[core]
+TOTAL_QUOTA_OUT = 3932160
+TOTAL_QUOTA_IN = 3932160
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-core
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 12092
+
+[arm]
+DEFAULTSERVICES = core dht
+ALLOW_SHUTDOWN = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-arm
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 12366
+
+[transport-tcp]
+ALLOW_SHUTDOWN = NO
+TIMEOUT = 300000
+PORT = 12368
+
+[TESTING]
+WEAKRANDOM = YES
+
+[gnunetd]
+HOSTKEY = $SERVICEHOME/.hostkey
+
+[PATHS]
+DEFAULTCONFIG = test_dht_api_peer1.conf
+SERVICEHOME = /tmp/test-gnunetd-dht-peer-1/
+