From: Nathan S. Evans Date: Sun, 4 Apr 2010 11:34:11 +0000 (+0000) Subject: add find peer to api, went a bit continuation crazy but i think it's better this... X-Git-Tag: initial-import-from-subversion-38251~22302 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=f5ee95ef07151a06778fa02a6d74689dcbb0bdf5;p=oweals%2Fgnunet.git add find peer to api, went a bit continuation crazy but i think it's better this way... --- diff --git a/src/dht/dht.h b/src/dht/dht.h index 0cfd9b3bf..68591a97e 100644 --- a/src/dht/dht.h +++ b/src/dht/dht.h @@ -27,7 +27,7 @@ #ifndef DHT_H_ #define DHT_H_ -#define DEBUG_DHT GNUNET_YES +#define DEBUG_DHT GNUNET_NO typedef void (*GNUNET_DHT_MessageReceivedHandler) (void *cls, struct GNUNET_MessageHeader *msg); @@ -166,7 +166,7 @@ struct GNUNET_DHT_GetResultMessage }; /** - * Message to request data from the DHT + * Message to issue find peer request to the DHT */ struct GNUNET_DHT_FindPeerMessage { @@ -175,6 +175,13 @@ struct GNUNET_DHT_FindPeerMessage */ struct GNUNET_MessageHeader header; + /** + * Size of inject message (may be zero) + */ + size_t msg_len; + + /* Followed by message to inject at found peers */ + }; /** @@ -188,14 +195,15 @@ struct GNUNET_DHT_FindPeerResultMessage struct GNUNET_MessageHeader header; /** - * The peer that was searched for + * The peer that was found */ struct GNUNET_PeerIdentity peer; /** - * The size of the HELLO for the returned peer, + * The size of the return message from the peer + * (defaults to HELLO for the peer), * appended to the end of this message, 0 if - * no hello. + * no message. */ size_t data_size; diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c index 9fb77d5d4..f935d69d3 100644 --- a/src/dht/dht_api.c +++ b/src/dht/dht_api.c @@ -24,13 +24,8 @@ * @author Christian Grothoff * @author Nathan Evans * - * TODO: Only allow a single message until confirmed as received by - * the service. For put messages call continuation as soon as - * receipt acknowledged (then remove), for GET or other messages - * only call continuation when data received. - * Add unique identifier to message types requesting data to be - * returned. */ + #include "platform.h" #include "gnunet_bandwidth_lib.h" #include "gnunet_client_lib.h" @@ -44,7 +39,7 @@ #include "gnunet_dht_service.h" #include "dht.h" -#define DEBUG_DHT_API GNUNET_YES +#define DEBUG_DHT_API GNUNET_NO #define DEFAULT_DHT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) @@ -86,8 +81,6 @@ struct PendingMessage struct GNUNET_DHT_GetContext { - - /** * Iterator to call on data receipt */ @@ -100,6 +93,20 @@ struct GNUNET_DHT_GetContext }; +struct GNUNET_DHT_FindPeerContext +{ + /** + * Iterator to call on data receipt + */ + GNUNET_DHT_FindPeerProcessor proc; + + /** + * Closure for the iterator callback + */ + void *proc_cls; + +}; + /** * Handle to control a unique operation (one that is * expected to return results) @@ -162,6 +169,38 @@ struct GNUNET_DHT_NonUniqueHandle void *cont_cls; }; +/** + * Handle to control a get operation. + */ +struct GNUNET_DHT_GetHandle +{ + /** + * Handle to the actual route operation for the get + */ + struct GNUNET_DHT_RouteHandle *route_handle; + + /** + * The context of the get request + */ + struct GNUNET_DHT_GetContext get_context; +}; + +/** + * Handle to control a find peer operation. + */ +struct GNUNET_DHT_FindPeerHandle +{ + /** + * Handle to the actual route operation for the request + */ + struct GNUNET_DHT_RouteHandle *route_handle; + + /** + * The context of the get request + */ + struct GNUNET_DHT_FindPeerContext find_peer_context; +}; + /** * Connection to the DHT service. @@ -565,6 +604,17 @@ void get_reply_iterator (void *cls, } + +/** + * Iterator called on each result obtained from a generic route + * operation + */ +void find_peer_reply_iterator (void *cls, + const struct GNUNET_MessageHeader *reply) +{ + +} + /** * Perform an asynchronous FIND_PEER operation on the DHT. * @@ -674,8 +724,7 @@ GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle, } void -GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *fph); - +GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle, GNUNET_SCHEDULER_Task cont, void *cont_cls); /** * Perform an asynchronous GET operation on the DHT identified. @@ -691,7 +740,7 @@ GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *fph); * * @return handle to stop the async get */ -struct GNUNET_DHT_RouteHandle * +struct GNUNET_DHT_GetHandle * GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle, struct GNUNET_TIME_Relative timeout, uint32_t type, @@ -701,15 +750,15 @@ GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle, GNUNET_SCHEDULER_Task cont, void *cont_cls) { - struct GNUNET_DHT_GetContext *get_context; + struct GNUNET_DHT_GetHandle *get_handle; struct GNUNET_DHT_GetMessage *get_msg; if (handle->current != NULL) /* Can't send right now, we have a pending message... */ return NULL; - get_context = GNUNET_malloc(sizeof(struct GNUNET_DHT_GetContext)); - get_context->iter = iter; - get_context->iter_cls = iter_cls; + get_handle = GNUNET_malloc(sizeof(struct GNUNET_DHT_GetHandle)); + get_handle->get_context.iter = iter; + get_handle->get_context.iter_cls = iter_cls; #if DEBUG_DHT_API GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -721,13 +770,13 @@ GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle, get_msg->header.size = htons(sizeof(struct GNUNET_DHT_GetMessage)); get_msg->type = htonl(type); - return GNUNET_DHT_route_start(handle, key, 0, 0, &get_msg->header, timeout, &get_reply_iterator, get_context, cont, cont_cls); - + get_handle->route_handle = GNUNET_DHT_route_start(handle, key, 0, 0, &get_msg->header, timeout, &get_reply_iterator, get_handle, cont, cont_cls); + return get_handle; } void -GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle) +GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle, GNUNET_SCHEDULER_Task cont, void *cont_cls) { struct PendingMessage *pending; struct GNUNET_DHT_StopMessage *message; @@ -750,8 +799,8 @@ GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle) pending = GNUNET_malloc(sizeof(struct PendingMessage)); pending->msg = (struct GNUNET_MessageHeader *)message; pending->timeout = DEFAULT_DHT_TIMEOUT; - pending->cont = NULL; - pending->cont_cls = NULL; + pending->cont = cont; + pending->cont_cls = cont_cls; pending->is_unique = GNUNET_NO; pending->unique_id = route_handle->uid; @@ -781,33 +830,95 @@ GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle) * @param get_handle handle to the GET operation to stop */ void -GNUNET_DHT_get_stop (struct GNUNET_DHT_RouteHandle *get_handle) +GNUNET_DHT_get_stop (struct GNUNET_DHT_GetHandle *get_handle, GNUNET_SCHEDULER_Task cont, void *cont_cls) { -#if OLDREMOVE - struct GNUNET_DHT_GetMessage *get_msg; - struct GNUNET_DHT_Handle *handle; - GNUNET_HashCode *uid_key; +#if DEBUG_DHT_API + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "`%s': Removing pending get request with key %s, uid %llu\n", "DHT API", GNUNET_h2s(&get_handle->route_handle->key), get_handle->route_handle->uid); #endif + GNUNET_DHT_route_stop(get_handle->route_handle, cont, cont_cls); + GNUNET_free(get_handle); - GNUNET_DHT_route_stop(get_handle); +} -#if OLDREMOVE - uid_key = hash_from_uid(get_handle->uid); - GNUNET_assert(GNUNET_CONTAINER_multihashmap_remove(handle->outstanding_requests, uid_key, get_handle) == GNUNET_YES); - 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)); +/** + * Perform an asynchronous FIND PEER operation on the DHT. + * + * @param handle handle to the DHT service + * @param timeout timeout for this request to be sent to the + * service + * @param options routing options for this message + * @param message a message to inject at found peers (may be null) + * @param key the key to look up + * @param iter function to call on each result + * @param iter_cls closure for iter + * @param cont continuation to call once message sent + * @param cont_cls closure for continuation + * + * @return handle to stop the async get, NULL on error + */ +struct GNUNET_DHT_FindPeerHandle * +GNUNET_DHT_find_peer_start (struct GNUNET_DHT_Handle *handle, + struct GNUNET_TIME_Relative timeout, + enum GNUNET_DHT_RouteOption options, + struct GNUNET_MessageHeader *message, + const GNUNET_HashCode * key, + GNUNET_DHT_FindPeerProcessor proc, + void *proc_cls, + GNUNET_SCHEDULER_Task cont, + void *cont_cls) +{ + struct GNUNET_DHT_FindPeerHandle *find_peer_handle; + struct GNUNET_DHT_FindPeerMessage *find_peer_msg; + size_t msize; + + if (handle->current != NULL) /* Can't send right now, we have a pending message... */ + return NULL; + if (message != NULL) + msize = ntohs(message->size); + else + msize = 0; - } + find_peer_handle = GNUNET_malloc(sizeof(struct GNUNET_DHT_FindPeerHandle)); + find_peer_handle->find_peer_context.proc = proc; + find_peer_handle->find_peer_context.proc_cls = proc_cls; + +#if DEBUG_DHT_API + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "`%s': Inserting pending `%s' request with key %s\n", "DHT API", "FIND PEER", GNUNET_h2s(key)); #endif + + find_peer_msg = GNUNET_malloc(sizeof(struct GNUNET_DHT_FindPeerMessage) + msize); + find_peer_msg->header.type = htons(GNUNET_MESSAGE_TYPE_DHT_FIND_PEER); + find_peer_msg->header.size = htons(sizeof(struct GNUNET_DHT_FindPeerMessage)); + find_peer_msg->msg_len = msize; + + if (message != NULL) + { + memcpy(&find_peer_msg[1], message, msize); + } + + find_peer_handle->route_handle = GNUNET_DHT_route_start(handle, key, 0, options, &find_peer_msg->header, timeout, &find_peer_reply_iterator, find_peer_handle, cont, cont_cls); + return find_peer_handle; +} + +/** + * Stop async find peer. Frees associated resources. + * + * @param find_peer_handle GET operation to stop. + */ +void +GNUNET_DHT_find_peer_stop (struct GNUNET_DHT_FindPeerHandle *find_peer_handle, GNUNET_SCHEDULER_Task cont, void *cont_cls) +{ #if DEBUG_DHT_API GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "`%s': Removing pending get request with key %s, uid %llu\n", "DHT API", GNUNET_h2s(&get_handle->key), get_handle->uid); + "`%s': Removing pending `%s' request with key %s, uid %llu\n", "DHT API", "FIND PEER", GNUNET_h2s(&find_peer_handle->route_handle->key), find_peer_handle->route_handle->uid); #endif + GNUNET_DHT_route_stop(find_peer_handle->route_handle, cont, cont_cls); + GNUNET_free(find_peer_handle); + } diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c index b8a45e5d1..c6ddb0ab9 100644 --- a/src/dht/gnunet-service-dht.c +++ b/src/dht/gnunet-service-dht.c @@ -144,7 +144,9 @@ static struct GNUNET_CORE_MessageHandler core_handlers[] = { */ static void handle_dht_get (void *cls, struct GNUNET_DHT_GetMessage *get_msg, GNUNET_HashCode *key) { +#if DEBUG_DHT GNUNET_HashCode get_key; +#endif size_t get_type; GNUNET_assert(ntohs(get_msg->header.size) >= sizeof(struct GNUNET_DHT_GetMessage)); @@ -164,14 +166,13 @@ static void handle_dht_get (void *cls, struct GNUNET_DHT_GetMessage *get_msg, GN */ static void handle_dht_find_peer (void *cls, struct GNUNET_DHT_FindPeerMessage *find_msg, GNUNET_HashCode *key) { - - GNUNET_assert(ntohs(find_msg->header.size) == sizeof(struct GNUNET_DHT_FindPeerMessage)); - #if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "`%s': Received `%s' request from client, key %s\n", "DHT", "FIND PEER", GNUNET_h2s(key)); + "`%s': Received `%s' request from client, key %s (msg size %d, we expected %d)\n", "DHT", "FIND PEER", GNUNET_h2s(key), ntohs(find_msg->header.size), sizeof(struct GNUNET_DHT_FindPeerMessage)); #endif + GNUNET_assert(ntohs(find_msg->header.size) >= sizeof(struct GNUNET_DHT_FindPeerMessage)); + /* FIXME: Implement find peer functionality here */ } @@ -298,10 +299,8 @@ handle_dht_start_message(void *cls, struct GNUNET_SERVER_Client * client, handle_dht_find_peer(cls, (struct GNUNET_DHT_FindPeerMessage *)enc_msg, &dht_msg->key); break; default: -#if DEBUG_DHT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "`%s': Message type (%d) not handled\n", "DHT", enc_type); -#endif } GNUNET_SERVER_receive_done(client, GNUNET_OK); diff --git a/src/dht/test_dht_api.c b/src/dht/test_dht_api.c index dd940a6e4..9dc429148 100644 --- a/src/dht/test_dht_api.c +++ b/src/dht/test_dht_api.c @@ -51,8 +51,8 @@ struct PeerContext struct GNUNET_CONFIGURATION_Handle *cfg; struct GNUNET_DHT_Handle *dht_handle; struct GNUNET_PeerIdentity id; - struct GNUNET_DHT_RouteHandle *get_handle; - struct GNUNET_DHT_RouteHandle *find_peer_handle; + struct GNUNET_DHT_GetHandle *get_handle; + struct GNUNET_DHT_FindPeerHandle *find_peer_handle; #if START_ARM pid_t arm_pid; @@ -123,6 +123,50 @@ end_badly () return; } +/** + * Signature of the main function of a task. + * + * @param cls closure + * @param tc context information (why was this task triggered now) + */ +void test_find_peer_stop (void *cls, + const struct GNUNET_SCHEDULER_TaskContext * tc) +{ + struct PeerContext *peer = cls; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_find_peer_stop!\n"); + if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT) + GNUNET_SCHEDULER_add_now(sched, &end_badly, NULL); + + GNUNET_assert (peer->dht_handle != NULL); + + GNUNET_DHT_find_peer_stop(peer->find_peer_handle, &end, &p1); + + //GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &end, &p1); + +} + +/** + * Signature of the main function of a task. + * + * @param cls closure + * @param tc context information (why was this task triggered now) + */ +void test_find_peer (void *cls, + const struct GNUNET_SCHEDULER_TaskContext * tc) +{ + struct PeerContext *peer = cls; + GNUNET_HashCode hash; + memset(&hash, 42, sizeof(GNUNET_HashCode)); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_find_peer!\n"); + GNUNET_assert (peer->dht_handle != NULL); + + peer->find_peer_handle = GNUNET_DHT_find_peer_start(peer->dht_handle, TIMEOUT, 0, NULL, &hash, NULL, NULL, &test_find_peer_stop, &p1); + + if (peer->find_peer_handle == NULL) + GNUNET_SCHEDULER_add_now(sched, &end_badly, &p1); +} /** * Signature of the main function of a task. @@ -143,11 +187,8 @@ void test_put (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_put!\n"); GNUNET_assert (peer->dht_handle != NULL); - GNUNET_DHT_put(peer->dht_handle, &hash, 0, data_size, data, GNUNET_TIME_relative_to_absolute(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 360)) ,GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 360), &end, NULL); + GNUNET_DHT_put(peer->dht_handle, &hash, 0, data_size, data, GNUNET_TIME_relative_to_absolute(TIMEOUT), TIMEOUT, &test_find_peer, &p1); - //GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &test_put, &p1); - - //GNUNET_SCHEDULER_add_now(sched, &end, NULL); } /** @@ -160,8 +201,6 @@ void test_get_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) { struct PeerContext *peer = cls; - GNUNET_HashCode hash; - memset(&hash, 42, sizeof(GNUNET_HashCode)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_get_stop!\n"); if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT) @@ -169,10 +208,9 @@ void test_get_stop (void *cls, GNUNET_assert (peer->dht_handle != NULL); - GNUNET_DHT_get_stop(peer->get_handle); + GNUNET_DHT_get_stop(peer->get_handle, &test_put, &p1); //GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &test_put, &p1); - GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &test_put, &p1); } @@ -193,12 +231,10 @@ void test_get (void *cls, peer->dht_handle = GNUNET_DHT_connect (sched, peer->cfg, 100); GNUNET_assert (peer->dht_handle != NULL); - peer->get_handle = GNUNET_DHT_get_start(peer->dht_handle, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 100), 42, &hash, NULL, NULL, &test_get_stop, &p1); + peer->get_handle = GNUNET_DHT_get_start(peer->dht_handle, TIMEOUT, 42, &hash, NULL, NULL, &test_get_stop, &p1); if (peer->get_handle == NULL) GNUNET_SCHEDULER_add_now(sched, &end_badly, &p1); - - //GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &test_get_stop, &p1); } static void diff --git a/src/dht/test_dht_api_peer1.conf b/src/dht/test_dht_api_peer1.conf index 45a0adde2..b9d9ab417 100644 --- a/src/dht/test_dht_api_peer1.conf +++ b/src/dht/test_dht_api_peer1.conf @@ -31,7 +31,7 @@ ALLOW_SHUTDOWN = YES ACCEPT_FROM6 = ::1; ACCEPT_FROM = 127.0.0.1; BINARY = gnunet-service-dht -#BINARY = /home/mrwiggles/documents/research/gnunet/gnunet-ng/src/dht/.libs/gnunet-service-dht +#BINARY = /root/documents/research/gnunet/gnunet-ng/src/dht/.libs/gnunet-service-dht #PREFIX = xterm -T dvservice -e gdb --args OPTIONS="" CONFIG = $DEFAULTCONFIG @@ -39,6 +39,10 @@ HOME = $SERVICEHOME HOSTNAME = localhost PORT = 2100 +[dhtcache] +QUOTA = 1000000 +DATABASE = sqlite + [hostlist] HTTP-PROXY = SERVERS = http://gnunet.org:8080/