From 7b00dd51218edbd9182caa664cfce185edc2cc45 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 26 Sep 2016 21:24:03 +0000 Subject: [PATCH] porting xdht to new service API, major code de-duplication effort --- src/dht/Makefile.am | 11 +- src/dht/gnunet-service-dht.c | 23 +- src/dht/gnunet-service-dht.h | 3 +- src/dht/gnunet-service-dht_clients.c | 67 +- src/dht/gnunet-service-dht_datacache.c | 193 ++- src/dht/gnunet-service-dht_datacache.h | 95 +- src/dht/gnunet-service-dht_neighbours.c | 59 +- src/dht/gnunet-service-dht_neighbours.h | 6 +- src/dht/gnunet-service-dht_routing.c | 9 +- src/dht/gnunet-service-dht_routing.h | 10 +- src/dht/gnunet-service-wdht.c | 6 +- src/dht/gnunet-service-wdht_clients.c | 2 +- src/dht/gnunet-service-wdht_datacache.c | 459 ------- src/dht/gnunet-service-wdht_datacache.h | 123 -- src/dht/gnunet-service-wdht_neighbours.c | 27 +- src/dht/gnunet-service-wdht_neighbours.h | 7 +- src/dht/gnunet-service-wdht_nse.c | 116 -- src/dht/gnunet-service-wdht_nse.h | 52 - src/dht/gnunet-service-xdht.c | 75 +- src/dht/gnunet-service-xdht_clients.c | 1417 ---------------------- src/dht/gnunet-service-xdht_clients.h | 149 --- src/dht/gnunet-service-xdht_datacache.c | 401 ------ src/dht/gnunet-service-xdht_datacache.h | 90 -- src/dht/gnunet-service-xdht_neighbours.c | 313 +++-- src/dht/gnunet-service-xdht_neighbours.h | 86 -- src/dht/gnunet-service-xdht_nse.c | 116 -- src/dht/gnunet-service-xdht_nse.h | 52 - src/dht/gnunet-service-xdht_routing.c | 9 +- 28 files changed, 642 insertions(+), 3334 deletions(-) delete mode 100644 src/dht/gnunet-service-wdht_datacache.c delete mode 100644 src/dht/gnunet-service-wdht_datacache.h delete mode 100644 src/dht/gnunet-service-wdht_nse.c delete mode 100644 src/dht/gnunet-service-wdht_nse.h delete mode 100644 src/dht/gnunet-service-xdht_clients.c delete mode 100644 src/dht/gnunet-service-xdht_clients.h delete mode 100644 src/dht/gnunet-service-xdht_datacache.c delete mode 100644 src/dht/gnunet-service-xdht_datacache.h delete mode 100644 src/dht/gnunet-service-xdht_nse.c delete mode 100644 src/dht/gnunet-service-xdht_nse.h diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am index f7dc5df6d..10aeae175 100644 --- a/src/dht/Makefile.am +++ b/src/dht/Makefile.am @@ -82,10 +82,9 @@ gnunet_service_dht_LDADD = \ -lm gnunet_service_dht_xvine_SOURCES = \ - gnunet-service-xdht.c gnunet-service-xdht.h \ - gnunet-service-xdht_clients.c gnunet-service-xdht_clients.h \ - gnunet-service-xdht_datacache.c gnunet-service-xdht_datacache.h \ - gnunet-service-xdht_nse.c gnunet-service-xdht_nse.h \ + gnunet-service-xdht.c gnunet-service-dht.h \ + gnunet-service-dht_datacache.c gnunet-service-dht_datacache.h \ + gnunet-service-dht_nse.c gnunet-service-dht_nse.h \ gnunet-service-xdht_neighbours.c gnunet-service-xdht_neighbours.h \ gnunet-service-xdht_routing.c gnunet-service-xdht_routing.h @@ -105,8 +104,8 @@ gnunet_service_dht_xvine_LDADD = \ gnunet_service_dht_whanau_SOURCES = \ gnunet-service-wdht.c gnunet-service-wdht.h \ gnunet-service-wdht_clients.c gnunet-service-wdht_clients.h \ - gnunet-service-wdht_datacache.c gnunet-service-wdht_datacache.h \ - gnunet-service-wdht_nse.c gnunet-service-wdht_nse.h \ + gnunet-service-dht_datacache.c gnunet-service-dht_datacache.h \ + gnunet-service-dht_nse.c gnunet-service-dht_nse.h \ gnunet-service-wdht_neighbours.c gnunet-service-wdht_neighbours.h gnunet_service_dht_whanau_LDADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c index a2ba2e8b0..f2b922dc4 100644 --- a/src/dht/gnunet-service-dht.c +++ b/src/dht/gnunet-service-dht.c @@ -39,27 +39,6 @@ #include "gnunet-service-dht_nse.h" #include "gnunet-service-dht_routing.h" - -/** - * Handle for the statistics service. - */ -struct GNUNET_STATISTICS_Handle *GDS_stats; - -/** - * Handle for the service. - */ -struct GNUNET_SERVICE_Handle *GDS_service; - -/** - * Our handle to the BLOCK library. - */ -struct GNUNET_BLOCK_Context *GDS_block_context; - -/** - * The configuration the DHT service is running with - */ -const struct GNUNET_CONFIGURATION_Handle *GDS_cfg; - /** * Our HELLO */ @@ -180,7 +159,7 @@ run (void *cls, /* Finally, define the main method */ -GDS_DHT_SERVICE_INIT(&run); +GDS_DHT_SERVICE_INIT("dht", &run); diff --git a/src/dht/gnunet-service-dht.h b/src/dht/gnunet-service-dht.h index bc7a48b5a..493c3b961 100644 --- a/src/dht/gnunet-service-dht.h +++ b/src/dht/gnunet-service-dht.h @@ -82,7 +82,8 @@ GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, const struct GNUNET_PeerIdentity *get_path, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, - enum GNUNET_BLOCK_Type type, size_t data_size, + enum GNUNET_BLOCK_Type type, + size_t data_size, const void *data); diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c index 0e344b566..df56c010a 100644 --- a/src/dht/gnunet-service-dht_clients.c +++ b/src/dht/gnunet-service-dht_clients.c @@ -213,6 +213,25 @@ struct ClientHandle }; +/** + * Our handle to the BLOCK library. + */ +struct GNUNET_BLOCK_Context *GDS_block_context; + +/** + * Handle for the statistics service. + */ +struct GNUNET_STATISTICS_Handle *GDS_stats; + +/** + * Handle for the service. + */ +struct GNUNET_SERVICE_Handle *GDS_service; + +/** + * The configuration the DHT service is running with + */ +const struct GNUNET_CONFIGURATION_Handle *GDS_cfg; /** * List of active monitoring requests. @@ -496,7 +515,7 @@ handle_dht_local_put (void *cls, ntohl (dht_msg->options), ntohl (dht_msg->desired_replication_level), GNUNET_TIME_absolute_ntoh (dht_msg->expiration), - 0 /* hop count */ , + 0 /* hop count */, peer_bf, &dht_msg->key, 0, @@ -540,6 +559,43 @@ check_dht_local_get (void *cls, } +/** + * Handle a result from local datacache for a GET operation. + * + * @param cls the `struct ClientHandle` of the client doing the query + * @param type type of the block + * @param expiration_time when does the content expire + * @param key key for the content + * @param put_path_length number of entries in @a put_path + * @param put_path peers the original PUT traversed (if tracked) + * @param get_path_length number of entries in @a get_path + * @param get_path peers this reply has traversed so far (if tracked) + * @param data payload of the reply + * @param data_size number of bytes in @a data + */ +static void +handle_local_result (void *cls, + enum GNUNET_BLOCK_Type type, + struct GNUNET_TIME_Absolute expiration_time, + const struct GNUNET_HashCode *key, + unsigned int put_path_length, + const struct GNUNET_PeerIdentity *put_path, + unsigned int get_path_length, + const struct GNUNET_PeerIdentity *get_path, + const void *data, + size_t data_size) +{ + // FIXME: this needs some clean up: inline the function, + // possibly avoid even looking up the client! + GDS_CLIENTS_handle_reply (expiration_time, + key, + 0, NULL, + put_path_length, put_path, + type, + data_size, data); +} + + /** * Handler for DHT GET messages from the client. * @@ -611,7 +667,9 @@ handle_dht_local_get (void *cls, cqr->xquery, xquery_size, NULL, - 0); + 0, + &handle_local_result, + ch); GNUNET_SERVICE_client_continue (ch->client); } @@ -1413,11 +1471,12 @@ GDS_CLIENTS_stop () /** * Define "main" method using service macro. * + * @param name name of the service, i.e. "dht" or "xdht" * @param run name of the initializaton method for the service */ -#define GDS_DHT_SERVICE_INIT(run) \ +#define GDS_DHT_SERVICE_INIT(name,run) \ GNUNET_SERVICE_MAIN \ - ("dht", \ + (name, \ GNUNET_SERVICE_OPTION_NONE, \ run, \ &client_connect_cb, \ diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c index 12c79764d..9b4dace67 100644 --- a/src/dht/gnunet-service-dht_datacache.c +++ b/src/dht/gnunet-service-dht_datacache.c @@ -31,6 +31,11 @@ #define LOG(kind,...) GNUNET_log_from (kind, "dht-dhtcache",__VA_ARGS__) +/** + * How many "closest" results to we return for migration when + * asked (at most)? + */ +#define NUM_CLOSEST 42 /** * Handle to the datacache service (for inserting/retrieving data) @@ -127,6 +132,17 @@ struct GetRequestContext * Return value to give back. */ enum GNUNET_BLOCK_EvaluationResult eval; + + /** + * Function to call on results. + */ + GDS_DATACACHE_GetCallback gc; + + /** + * Closure for @e gc. + */ + void *gc_cls; + }; @@ -136,7 +152,7 @@ struct GetRequestContext * @param cls closure for iterator, a `struct GetRequestContext` * @param exp when does this value expire? * @param key the key this data is stored under - * @param size the size of the data identified by key + * @param data_size the size of the data identified by key * @param data the actual data * @param type the type of the @a data * @param put_path_length number of peers in @a put_path @@ -147,7 +163,7 @@ struct GetRequestContext static int datacache_get_iterator (void *cls, const struct GNUNET_HashCode *key, - size_t size, + size_t data_size, const char *data, enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute exp, @@ -157,8 +173,8 @@ datacache_get_iterator (void *cls, struct GetRequestContext *ctx = cls; enum GNUNET_BLOCK_EvaluationResult eval; - eval = - GNUNET_BLOCK_evaluate (GDS_block_context, + eval + = GNUNET_BLOCK_evaluate (GDS_block_context, type, GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO, key, @@ -167,7 +183,7 @@ datacache_get_iterator (void *cls, ctx->xquery, ctx->xquery_size, data, - size); + data_size); LOG (GNUNET_ERROR_TYPE_DEBUG, "Found reply for query %s in datacache, evaluation result is %d\n", GNUNET_h2s (key), @@ -182,18 +198,13 @@ datacache_get_iterator (void *cls, gettext_noop ("# Good RESULTS found in datacache"), 1, GNUNET_NO); - GDS_CLIENTS_handle_reply (exp, key, - 0, NULL, - put_path_length, put_path, - type, - size, data); - /* forward to other peers */ - GDS_ROUTING_process (type, - exp, - key, - put_path_length, put_path, - 0, NULL, - data, size); + ctx->gc (ctx->gc_cls, + type, + exp, + key, + put_path_length, put_path, + 0, NULL, + data, data_size); break; case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: GNUNET_STATISTICS_update (GDS_stats, @@ -242,6 +253,8 @@ datacache_get_iterator (void *cls, * @param xquery_size number of bytes in @a xquery * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL * @param reply_bf_mutator mutation value for @a reply_bf + * @param gc function to call on the results + * @param gc_cls closure for @a gc * @return evaluation result for the local replies */ enum GNUNET_BLOCK_EvaluationResult @@ -250,7 +263,9 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, const void *xquery, size_t xquery_size, struct GNUNET_CONTAINER_BloomFilter **reply_bf, - uint32_t reply_bf_mutator) + uint32_t reply_bf_mutator, + GDS_DATACACHE_GetCallback gc, + void *gc_cls) { struct GetRequestContext ctx; unsigned int r; @@ -267,6 +282,8 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, ctx.xquery_size = xquery_size; ctx.reply_bf = reply_bf; ctx.reply_bf_mutator = reply_bf_mutator; + ctx.gc = gc; + ctx.gc_cls = gc_cls; r = GNUNET_DATACACHE_get (datacache, key, type, @@ -281,6 +298,146 @@ GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, } +/** + * Function called with a random element from the datacache. + * Stores the key in the closure. + * + * @param cls a `struct GNUNET_HashCode *`, where to store the @a key + * @param key key for the content + * @param data_size number of bytes in @a data + * @param data content stored + * @param type type of the content + * @param exp when will the content expire? + * @param path_info_len number of entries in @a path_info + * @param path_info a path through the network + * @return #GNUNET_OK to continue iterating, #GNUNET_SYSERR to abort + */ +static int +datacache_random_iterator (void *cls, + const struct GNUNET_HashCode *key, + size_t data_size, + const char *data, + enum GNUNET_BLOCK_Type type, + struct GNUNET_TIME_Absolute exp, + unsigned int path_info_len, + const struct GNUNET_PeerIdentity *path_info) +{ + struct GNUNET_HashCode *dest = cls; + + *dest = *key; + return GNUNET_OK; /* should actually not matter which we return */ +} + + +/** + * Obtain a random key from the datacache. + * Used by Whanau for load-balancing. + * + * @param[out] key where to store the key of a random element, + * randomized by PRNG if datacache is empty + * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty + */ +int +GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key) +{ + if (0 == + GNUNET_DATACACHE_get_random (datacache, + &datacache_random_iterator, + key)) + { + /* randomize key in this case */ + GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, + key); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +/** + * Closure for #datacache_get_successors_iterator(). + */ +struct SuccContext +{ + /** + * Function to call on the result + */ + GDS_DATACACHE_SuccessorCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; +}; + + +/** + * Iterator for local get request results, + * + * @param cls closure with the `struct GNUNET_HashCode *` with the trail ID + * @param key the key this data is stored under + * @param size the size of the data identified by key + * @param data the actual data + * @param type the type of the data + * @param exp when does this value expire? + * @param put_path_length number of peers in @a put_path + * @param put_path path the reply took on put + * @return #GNUNET_OK to continue iteration, anything else + * to stop iteration. + */ +static int +datacache_get_successors_iterator (void *cls, + const struct GNUNET_HashCode *key, + size_t size, + const char *data, + enum GNUNET_BLOCK_Type type, + struct GNUNET_TIME_Absolute exp, + unsigned int put_path_length, + const struct GNUNET_PeerIdentity *put_path) +{ + const struct SuccContext *sc = cls; + + /* NOTE: The datacache currently does not store the RO from + the original 'put', so we don't know the 'correct' option + at this point anymore. Thus, we conservatively assume + that recording is desired (for now). */ + sc->cb (sc->cb_cls, + GNUNET_DHT_RO_RECORD_ROUTE, + key, + type, + put_path_length, put_path, + exp, + data, + size); + return GNUNET_OK; +} + + +/** + * Handle a request for data close to a key that we have received from + * another peer. + * + * @param key the location at which the peer is looking for data that is close + * @param cb function to call with the result + * @param cb_cls closure for @a cb + */ +void +GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *key, + GDS_DATACACHE_SuccessorCallback cb, + void *cb_cls) +{ + struct SuccContext sc; + + sc.cb = cb; + sc.cb_cls = cb_cls; + (void) GNUNET_DATACACHE_get_closest (datacache, + key, + NUM_CLOSEST, + &datacache_get_successors_iterator, + &sc); +} + + /** * Initialize datacache subsystem. */ diff --git a/src/dht/gnunet-service-dht_datacache.h b/src/dht/gnunet-service-dht_datacache.h index 66bfc3bbf..5069883c7 100644 --- a/src/dht/gnunet-service-dht_datacache.h +++ b/src/dht/gnunet-service-dht_datacache.h @@ -29,6 +29,7 @@ #include "gnunet_util_lib.h" #include "gnunet_block_lib.h" +#include "gnunet_dht_service.h" /** * Handle a datum we've received from another peer. Cache if @@ -44,13 +45,41 @@ */ void GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, - const struct GNUNET_HashCode * key, + const struct GNUNET_HashCode *key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, - enum GNUNET_BLOCK_Type type, size_t data_size, + enum GNUNET_BLOCK_Type type, + size_t data_size, const void *data); +/** + * Handle a result for a GET operation. + * + * @param cls closure + * @param type type of the block + * @param expiration_time when does the content expire + * @param key key for the content + * @param put_path_length number of entries in @a put_path + * @param put_path peers the original PUT traversed (if tracked) + * @param get_path_length number of entries in @a get_path + * @param get_path peers this reply has traversed so far (if tracked) + * @param data payload of the reply + * @param data_size number of bytes in @a data + */ +typedef void +(*GDS_DATACACHE_GetCallback)(void *cls, + enum GNUNET_BLOCK_Type type, + struct GNUNET_TIME_Absolute expiration_time, + const struct GNUNET_HashCode *key, + unsigned int put_path_length, + const struct GNUNET_PeerIdentity *put_path, + unsigned int get_path_length, + const struct GNUNET_PeerIdentity *get_path, + const void *data, + size_t data_size); + + /** * Handle a GET request we've received from another peer. * @@ -60,14 +89,70 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, * @param xquery_size number of bytes in xquery * @param reply_bf where the reply bf is (to be) stored, possibly updated!, can be NULL * @param reply_bf_mutator mutation value for reply_bf + * @param gc function to call on the results + * @param gc_cls closure for @a gc * @return evaluation result for the local replies */ enum GNUNET_BLOCK_EvaluationResult -GDS_DATACACHE_handle_get (const struct GNUNET_HashCode * key, - enum GNUNET_BLOCK_Type type, const void *xquery, +GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, + enum GNUNET_BLOCK_Type type, + const void *xquery, size_t xquery_size, struct GNUNET_CONTAINER_BloomFilter **reply_bf, - uint32_t reply_bf_mutator); + uint32_t reply_bf_mutator, + GDS_DATACACHE_GetCallback gc, + void *gc_cls); + + +/** + * Obtain a random key from the datacache. + * Used by Whanau for load-balancing. + * + * @param[out] key where to store the key of a random element, + * randomized by PRNG if datacache is empty + * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty + */ +int +GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key); + + +/** + * Send the get result to requesting client. + * + * @param cls closure + * @param options routing options (from GET request) + * @param key key of the requested data. + * @param type block type + * @param put_path_length number of peers in @a put_path + * @param put_path path taken to put the data at its stored location. + * @param expiration when will this result expire? + * @param data payload to store + * @param data_size size of the @a data + */ +typedef void +(*GDS_DATACACHE_SuccessorCallback)(void *cls, + enum GNUNET_DHT_RouteOption options, + const struct GNUNET_HashCode *key, + enum GNUNET_BLOCK_Type type, + unsigned int put_path_length, + const struct GNUNET_PeerIdentity *put_path, + struct GNUNET_TIME_Absolute expiration, + const void *data, + size_t data_size); + + +/** + * Handle a request for data close to a key that we have received from + * another peer. + * + * @param key the location at which the peer is looking for data that is close + * @param cb function to call with the result + * @param cb_cls closure for @a cb + */ +void +GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *key, + GDS_DATACACHE_SuccessorCallback cb, + void *cb_cls); /** diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c index 39fb43495..574ed9ad0 100644 --- a/src/dht/gnunet-service-dht_neighbours.c +++ b/src/dht/gnunet-service-dht_neighbours.c @@ -1255,8 +1255,8 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, gettext_noop ("# PUT requests routed"), 1, GNUNET_NO); - target_count = - get_target_peers (key, + target_count + = get_target_peers (key, bf, hop_count, desired_replication_level, @@ -1768,9 +1768,13 @@ handle_dht_p2p_put (void *cls, /* store locally */ if ((0 != (options & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) || (am_closest_peer (&put->key, bf))) - GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh - (put->expiration_time), &put->key, putlen, pp, - ntohl (put->type), payload_size, payload); + GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put->expiration_time), + &put->key, + putlen, + pp, + ntohl (put->type), + payload_size, + payload); /* route to other peers */ forwarded = GDS_NEIGHBOURS_handle_put (ntohl (put->type), options, @@ -1912,6 +1916,44 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender, } +/** + * Handle a result from local datacache for a GET operation. + * + * @param cls the `struct ClientHandle` of the client doing the query + * @param type type of the block + * @param expiration_time when does the content expire + * @param key key for the content + * @param put_path_length number of entries in @a put_path + * @param put_path peers the original PUT traversed (if tracked) + * @param get_path_length number of entries in @a get_path + * @param get_path peers this reply has traversed so far (if tracked) + * @param data payload of the reply + * @param data_size number of bytes in @a data + */ +static void +handle_local_result (void *cls, + enum GNUNET_BLOCK_Type type, + struct GNUNET_TIME_Absolute expiration_time, + const struct GNUNET_HashCode *key, + unsigned int put_path_length, + const struct GNUNET_PeerIdentity *put_path, + unsigned int get_path_length, + const struct GNUNET_PeerIdentity *get_path, + const void *data, + size_t data_size) +{ + // FIXME: we can probably do better here by + // passing the peer that did the query in the closure... + GDS_ROUTING_process (NULL, + type, + expiration_time, + key, + put_path_length, put_path, + 0, NULL, + data, data_size); +} + + /** * Check validity of p2p get request. * @@ -2067,7 +2109,9 @@ handle_dht_p2p_get (void *cls, xquery, xquery_size, &reply_bf, - get->bf_mutator); + get->bf_mutator, + &handle_local_result, + NULL); } } else @@ -2276,7 +2320,8 @@ handle_dht_p2p_result (void *cls, data); } /* forward to other peers */ - GDS_ROUTING_process (type, + GDS_ROUTING_process (NULL, + type, GNUNET_TIME_absolute_ntoh (prm->expiration_time), &prm->key, put_path_length, diff --git a/src/dht/gnunet-service-dht_neighbours.h b/src/dht/gnunet-service-dht_neighbours.h index 856f1faae..d89e5c54f 100644 --- a/src/dht/gnunet-service-dht_neighbours.h +++ b/src/dht/gnunet-service-dht_neighbours.h @@ -58,7 +58,7 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, uint32_t hop_count, struct GNUNET_CONTAINER_BloomFilter *bf, - const struct GNUNET_HashCode * key, + const struct GNUNET_HashCode *key, unsigned int put_path_length, struct GNUNET_PeerIdentity *put_path, const void *data, size_t data_size); @@ -125,7 +125,7 @@ GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target, /** * Initialize neighbours subsystem. * - * @return GNUNET_OK on success, GNUNET_SYSERR on error + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ int GDS_NEIGHBOURS_init (void); @@ -144,7 +144,7 @@ GDS_NEIGHBOURS_done (void); * @return identity of the local node */ struct GNUNET_PeerIdentity * -GDS_NEIGHBOURS_get_id (); +GDS_NEIGHBOURS_get_id (void); #endif diff --git a/src/dht/gnunet-service-dht_routing.c b/src/dht/gnunet-service-dht_routing.c index d078c865d..48bece35e 100644 --- a/src/dht/gnunet-service-dht_routing.c +++ b/src/dht/gnunet-service-dht_routing.c @@ -277,13 +277,16 @@ process (void *cls, const struct GNUNET_HashCode * key, void *value) * @param data_size number of bytes in data */ void -GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, +GDS_ROUTING_process (void *cls, + enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, - const struct GNUNET_HashCode * key, unsigned int put_path_length, + const struct GNUNET_HashCode *key, + unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, - const void *data, size_t data_size) + const void *data, + size_t data_size) { struct ProcessContext pc; diff --git a/src/dht/gnunet-service-dht_routing.h b/src/dht/gnunet-service-dht_routing.h index 1b163c25b..7c57361dc 100644 --- a/src/dht/gnunet-service-dht_routing.h +++ b/src/dht/gnunet-service-dht_routing.h @@ -38,6 +38,7 @@ * GDS_NEIGHBOURS_handle_reply for all peers that sent us a matching * request recently. * + * @param cls closure * @param type type of the block * @param expiration_time when does the content expire * @param key key for the content @@ -49,13 +50,16 @@ * @param data_size number of bytes in @a data */ void -GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, +GDS_ROUTING_process (void *cls, + enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, - const struct GNUNET_HashCode * key, unsigned int put_path_length, + const struct GNUNET_HashCode *key, + unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, - const void *data, size_t data_size); + const void *data, + size_t data_size); /** diff --git a/src/dht/gnunet-service-wdht.c b/src/dht/gnunet-service-wdht.c index b58bb729d..8be25ad5e 100644 --- a/src/dht/gnunet-service-wdht.c +++ b/src/dht/gnunet-service-wdht.c @@ -19,7 +19,7 @@ */ /** - * @file dht/gnunet-service-xdht.c + * @file dht/gnunet-service-wdht.c * @brief GNUnet DHT service * @author Christian Grothoff * @author Nathan Evans @@ -34,9 +34,9 @@ #include "gnunet_statistics_service.h" #include "gnunet-service-wdht.h" #include "gnunet-service-wdht_clients.h" -#include "gnunet-service-wdht_datacache.h" +#include "gnunet-service-dht_datacache.h" #include "gnunet-service-wdht_neighbours.h" -#include "gnunet-service-wdht_nse.h" +#include "gnunet-service-dht_nse.h" diff --git a/src/dht/gnunet-service-wdht_clients.c b/src/dht/gnunet-service-wdht_clients.c index 2abeea661..7ad0d2904 100644 --- a/src/dht/gnunet-service-wdht_clients.c +++ b/src/dht/gnunet-service-wdht_clients.c @@ -31,7 +31,7 @@ #include "gnunet_statistics_service.h" #include "gnunet-service-wdht.h" #include "gnunet-service-wdht_clients.h" -#include "gnunet-service-wdht_datacache.h" +#include "gnunet-service-dht_datacache.h" #include "gnunet-service-wdht_neighbours.h" #include "dht.h" diff --git a/src/dht/gnunet-service-wdht_datacache.c b/src/dht/gnunet-service-wdht_datacache.c deleted file mode 100644 index 40d54bf5a..000000000 --- a/src/dht/gnunet-service-wdht_datacache.c +++ /dev/null @@ -1,459 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2009, 2010, 2011, 2015 GNUnet e.V. - - 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 3, 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -/** - * @file dht/gnunet-service-wdht_datacache.c - * @brief GNUnet DHT service's datacache integration - * @author Christian Grothoff - * @author Nathan Evans - */ -#include "platform.h" -#include "gnunet_datacache_lib.h" -#include "gnunet-service-wdht_clients.h" -#include "gnunet-service-wdht_datacache.h" -#include "gnunet-service-wdht_neighbours.h" -#include "gnunet-service-dht.h" - -#define LOG(kind,...) GNUNET_log_from (kind, "dht-dtcache",__VA_ARGS__) - -#define DEBUG(...) \ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) - -/** - * How many "closest" results to we return for migration when - * asked (at most)? - */ -#define NUM_CLOSEST 42 - -/** - * Handle to the datacache service (for inserting/retrieving data) - */ -static struct GNUNET_DATACACHE_Handle *datacache; - - -/** - * Handle a datum we've received from another peer. Cache if - * possible. - * - * @param expiration when will the reply expire - * @param key the query this reply is for - * @param put_path_length number of peers in @a put_path - * @param put_path path the reply took on put - * @param get_path_length number of peers in @a get_path - * @param get_path path the reply took on get - * @param type type of the reply - * @param data_size number of bytes in @a data - * @param data application payload data - */ -void -GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, - const struct GNUNET_HashCode *key, - unsigned int put_path_length, - const struct GNUNET_PeerIdentity *put_path, - unsigned int get_path_length, - const struct GNUNET_PeerIdentity *get_path, - enum GNUNET_BLOCK_Type type, - size_t data_size, - const void *data) -{ - int r; - struct GNUNET_PeerIdentity path[get_path_length + put_path_length]; - - if (NULL == datacache) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("PUT request received, but have no datacache!\n")); - return; - } - if (data_size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) - { - GNUNET_break (0); - return; - } - GNUNET_memcpy (path, - put_path, - put_path_length * sizeof (struct GNUNET_PeerIdentity)); - GNUNET_memcpy (&path[put_path_length], - get_path, - get_path_length * sizeof (struct GNUNET_PeerIdentity)); - /* Put size is actual data size plus struct overhead plus path length (if any) */ - r = GNUNET_DATACACHE_put (datacache, - key, - data_size, - data, - type, - expiration, - get_path_length + put_path_length, - path); - if (GNUNET_OK == r) - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop ("# ITEMS stored in datacache"), 1, - GNUNET_NO); - LOG (GNUNET_ERROR_TYPE_DEBUG, - "DATACACHE PUT for key %s [%u] completed (%d) after %u hops\n", - GNUNET_h2s (key), - data_size, - r, - put_path_length + get_path_length); -} - - -/** - * Context containing information about a GET request. - */ -struct GetRequestContext -{ - /** - * extended query (see gnunet_block_lib.h). - */ - const void *xquery; - - /** - * Bloomfilter to filter out duplicate replies (updated) - */ - struct GNUNET_CONTAINER_BloomFilter **reply_bf; - - /** - * The key this request was about - */ - struct GNUNET_HashCode key; - - /** - * The trail this request was for - */ - const struct GNUNET_HashCode *trail_id; - - /** - * Number of bytes in @e xquery. - */ - size_t xquery_size; - - /** - * Mutator value for the @e reply_bf, see gnunet_block_lib.h - */ - uint32_t reply_bf_mutator; - - /** - * Return value to give back. - */ - enum GNUNET_BLOCK_EvaluationResult eval; - - /** - * Routing options of the GET. - */ - enum GNUNET_DHT_RouteOption options; - -}; - - -/** - * Iterator for local get request results, - * - * @param cls closure for iterator, a `struct GetRequestContext` - * @param key the key this data is stored under - * @param size the size of the data identified by key - * @param data the actual data - * @param type the type of the data - * @param exp when does this value expire? - * @param put_path_length number of peers in @a put_path - * @param put_path path the reply took on put - * @return #GNUNET_OK to continue iteration, anything else - * to stop iteration. - */ -static int -datacache_get_iterator (void *cls, - const struct GNUNET_HashCode *key, - size_t size, - const char *data, - enum GNUNET_BLOCK_Type type, - struct GNUNET_TIME_Absolute exp, - unsigned int put_path_length, - const struct GNUNET_PeerIdentity *put_path) -{ - struct GetRequestContext *ctx = cls; - enum GNUNET_BLOCK_EvaluationResult eval; - - eval = - GNUNET_BLOCK_evaluate (GDS_block_context, - type, - GNUNET_BLOCK_EO_NONE, - key, - ctx->reply_bf, - ctx->reply_bf_mutator, - ctx->xquery, - ctx->xquery_size, - data, - size); - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Found reply for query %s in datacache, evaluation result is %d\n", - GNUNET_h2s (key), (int) eval); - ctx->eval = eval; - - switch (eval) - { - case GNUNET_BLOCK_EVALUATION_OK_MORE: - case GNUNET_BLOCK_EVALUATION_OK_LAST: - /* forward to local clients */ - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# Good RESULTS found in datacache"), 1, - GNUNET_NO); - GDS_NEIGHBOURS_send_get_result (ctx->trail_id, - ctx->options, - key, - type, - put_path_length, - put_path, - exp, - data, - size); - break; - case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# Duplicate RESULTS found in datacache"), 1, - GNUNET_NO); - break; - case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# Invalid RESULTS found in datacache"), 1, - GNUNET_NO); - break; - case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# Irrelevant RESULTS found in datacache"), 1, - GNUNET_NO); - break; - case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: - GNUNET_break (0); - break; - case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: - GNUNET_break_op (0); - return GNUNET_SYSERR; - case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# Unsupported RESULTS found in datacache"), 1, - GNUNET_NO); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Unsupported block type (%u) in local response!\n"), type); - break; - } - - return (eval == GNUNET_BLOCK_EVALUATION_OK_LAST) ? GNUNET_NO : GNUNET_OK; -} - - -/** - * Handle a GET request we've received from another peer. - * - * @param trail_id trail identifying where to send the result to, NULL for us - * @param options routing options (to be passed along) - * @param key the query - * @param type requested data type - * @param xquery extended query - * @param xquery_size number of bytes in @a xquery - * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL - * @param reply_bf_mutator mutation value for @a reply_bf - * @return evaluation result for the local replies - */ -enum GNUNET_BLOCK_EvaluationResult -GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *trail_id, - enum GNUNET_DHT_RouteOption options, - const struct GNUNET_HashCode *key, - enum GNUNET_BLOCK_Type type, - const void *xquery, - size_t xquery_size, - struct GNUNET_CONTAINER_BloomFilter **reply_bf, - uint32_t reply_bf_mutator) -{ - struct GetRequestContext ctx; - unsigned int r; - - if (NULL == datacache) - return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop ("# GET requests given to datacache"), - 1, GNUNET_NO); - ctx.eval = GNUNET_BLOCK_EVALUATION_REQUEST_VALID; - ctx.trail_id = trail_id; - ctx.options = options; - ctx.key = *key; - ctx.xquery = xquery; - ctx.xquery_size = xquery_size; - ctx.reply_bf = reply_bf; - ctx.reply_bf_mutator = reply_bf_mutator; - r = GNUNET_DATACACHE_get (datacache, - key, - type, - &datacache_get_iterator, - &ctx); - DEBUG ("DATACACHE_GET for key %s completed (%d). %u results found.\n", - GNUNET_h2s (key), - ctx.eval, - r); - return ctx.eval; -} - - -/** - * Function called with a random element from the datacache. - * Stores the key in the closure. - * - * @param cls a `struct GNUNET_HashCode *`, where to store the @a key - * @param key key for the content - * @param data_size number of bytes in @a data - * @param data content stored - * @param type type of the content - * @param exp when will the content expire? - * @param path_info_len number of entries in @a path_info - * @param path_info a path through the network - * @return #GNUNET_OK to continue iterating, #GNUNET_SYSERR to abort - */ -static int -datacache_random_iterator (void *cls, - const struct GNUNET_HashCode *key, - size_t data_size, - const char *data, - enum GNUNET_BLOCK_Type type, - struct GNUNET_TIME_Absolute exp, - unsigned int path_info_len, - const struct GNUNET_PeerIdentity *path_info) -{ - struct GNUNET_HashCode *dest = cls; - - *dest = *key; - return GNUNET_OK; /* should actually not matter which we return */ -} - - -/** - * Obtain a random key from the datacache. - * Used by Whanau for load-balancing. - * - * @param[out] key where to store the key of a random element, - * randomized by PRNG if datacache is empty - * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty - */ -int -GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key) -{ - if (0 == - GNUNET_DATACACHE_get_random (datacache, - &datacache_random_iterator, - key)) - { - /* randomize key in this case */ - GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, - key); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -/** - * Iterator for local get request results, - * - * @param cls closure with the `struct GNUNET_HashCode *` with the trail ID - * @param key the key this data is stored under - * @param size the size of the data identified by key - * @param data the actual data - * @param type the type of the data - * @param exp when does this value expire? - * @param put_path_length number of peers in @a put_path - * @param put_path path the reply took on put - * @return #GNUNET_OK to continue iteration, anything else - * to stop iteration. - */ -static int -datacache_get_successors_iterator (void *cls, - const struct GNUNET_HashCode *key, - size_t size, - const char *data, - enum GNUNET_BLOCK_Type type, - struct GNUNET_TIME_Absolute exp, - unsigned int put_path_length, - const struct GNUNET_PeerIdentity *put_path) -{ - const struct GNUNET_HashCode *trail_id = cls; - - /* NOTE: The datacache currently does not store the RO from - the original 'put', so we don't know the 'correct' option - at this point anymore. Thus, we conservatively assume - that recording is desired (for now). */ - GDS_NEIGHBOURS_send_get_result (trail_id, - GNUNET_DHT_RO_RECORD_ROUTE, - key, - type, - put_path_length, put_path, - exp, - data, - size); - return GNUNET_OK; -} - - -/** - * Handle a request for data close to a key that we have received from - * another peer. - * - * @param trail_id trail where the reply needs to be send to - * @param key the location at which the peer is looking for data that is close - */ -void -GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *trail_id, - const struct GNUNET_HashCode *key) -{ - (void) GNUNET_DATACACHE_get_closest (datacache, - key, - NUM_CLOSEST, - &datacache_get_successors_iterator, - (void *) trail_id); -} - - -/** - * Initialize datacache subsystem. - */ -void -GDS_DATACACHE_init () -{ - datacache = GNUNET_DATACACHE_create (GDS_cfg, "dhtcache"); -} - - -/** - * Shutdown datacache subsystem. - */ -void -GDS_DATACACHE_done () -{ - if (NULL != datacache) - { - GNUNET_DATACACHE_destroy (datacache); - datacache = NULL; - } -} - - -/* end of gnunet-service-wdht_datacache.c */ diff --git a/src/dht/gnunet-service-wdht_datacache.h b/src/dht/gnunet-service-wdht_datacache.h deleted file mode 100644 index ba9b55a0c..000000000 --- a/src/dht/gnunet-service-wdht_datacache.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2009, 2010, 2011, 2015 GNUnet e.V. - - 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 3, 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -/** - * @file dht/gnunet-service-dht_datacache.h - * @brief GNUnet DHT service's datacache integration - * @author Christian Grothoff - * @author Nathan Evans - */ -#ifndef GNUNET_SERVICE_DHT_DATACACHE_H -#define GNUNET_SERVICE_DHT_DATACACHE_H - -#include "gnunet_util_lib.h" -#include "gnunet_block_lib.h" -#include "gnunet_dht_service.h" - -/** - * Handle a datum we've received from another peer. Cache if - * possible. - * - * @param expiration when will the reply expire - * @param key the query this reply is for - * @param put_path_length number of peers in @a put_path - * @param put_path path the reply took on put - * @param get_path_length number of peers in @a get_path - * @param get_path path the reply took on get - * @param type type of the reply - * @param data_size number of bytes in @a data - * @param data application payload data - */ -void -GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, - const struct GNUNET_HashCode *key, - unsigned int put_path_length, - const struct GNUNET_PeerIdentity *put_path, - unsigned int get_path_length, - const struct GNUNET_PeerIdentity *get_path, - enum GNUNET_BLOCK_Type type, - size_t data_size, - const void *data); - - -/** - * Handle a GET request we've received from another peer. - * - * @param trail_id trail where the reply needs to be send to - * @param options routing options (to be passed along) - * @param key the query - * @param type requested data type - * @param xquery extended query - * @param xquery_size number of bytes in @a xquery - * @param reply_bf where the reply bf is (to be) stored, possibly updated!, can be NULL - * @param reply_bf_mutator mutation value for @a reply_bf - * @return evaluation result for the local replies - * - * FIXME: also pass options, so we know to record paths or not... - */ -enum GNUNET_BLOCK_EvaluationResult -GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *trail_id, - enum GNUNET_DHT_RouteOption options, - const struct GNUNET_HashCode *key, - enum GNUNET_BLOCK_Type type, - const void *xquery, - size_t xquery_size, - struct GNUNET_CONTAINER_BloomFilter **reply_bf, - uint32_t reply_bf_mutator); - - -/** - * Obtain a random key from the datacache. - * Used by Whanau for load-balancing. - * - * @param[out] key where to store the key of a random element, - * randomized by PRNG if datacache is empty - * @return #GNUNET_OK on success, #GNUNET_SYSERR if the datacache is empty - */ -int -GDS_DATACACHE_get_random_key (struct GNUNET_HashCode *key); - - -/** - * Handle a request for data close to a key that we have received from - * another peer. - * - * @param trail_id trail where the reply needs to be send to - * @param key the location at which the peer is looking for data that is close - */ -void -GDS_DATACACHE_get_successors (const struct GNUNET_HashCode *trail_id, - const struct GNUNET_HashCode *key); - - -/** - * Initialize datacache subsystem. - */ -void -GDS_DATACACHE_init (void); - - -/** - * Shutdown datacache subsystem. - */ -void -GDS_DATACACHE_done (void); - -#endif diff --git a/src/dht/gnunet-service-wdht_neighbours.c b/src/dht/gnunet-service-wdht_neighbours.c index a6ebdb033..2a88ffa09 100644 --- a/src/dht/gnunet-service-wdht_neighbours.c +++ b/src/dht/gnunet-service-wdht_neighbours.c @@ -41,9 +41,9 @@ #include "gnunet_statistics_service.h" #include "gnunet-service-wdht.h" #include "gnunet-service-wdht_clients.h" -#include "gnunet-service-wdht_datacache.h" +#include "gnunet-service-dht_datacache.h" #include "gnunet-service-wdht_neighbours.h" -#include "gnunet-service-wdht_nse.h" +#include "gnunet-service-dht_nse.h" #include "dht.h" #define DEBUG(...) \ @@ -605,7 +605,6 @@ GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key, GDS_DATACACHE_handle_put (expiration_time, key, 0, NULL, - 0, NULL, block_type, data_size, data); @@ -777,7 +776,7 @@ forward_message_on_trail (struct FriendInfo *next_target, /** * Send the get result to requesting client. * - * @param trail_id trail identifying where to send the result to, NULL for us + * @param cls trail identifying where to send the result to, NULL for us * @param options routing options (from GET request) * @param key Key of the requested data. * @param type Block type @@ -788,7 +787,7 @@ forward_message_on_trail (struct FriendInfo *next_target, * @param data_size Size of the @a data */ void -GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *trail_id, +GDS_NEIGHBOURS_send_get_result (void *cls, enum GNUNET_DHT_RouteOption options, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, @@ -798,6 +797,7 @@ GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *trail_id, const void *data, size_t data_size) { + const struct GNUNET_HashCode *trail_id = cls; struct GNUNET_MessageHeader *payload; struct Trail *trail; @@ -1221,13 +1221,13 @@ handle_dht_p2p_random_walk (void *cls, /** * Handle a `struct RandomWalkResponseMessage`. * - * @param cls closure + * @param cls closure * @param rwrm the setup response message */ static void handle_dht_p2p_random_walk_response (void *cls, const struct RandomWalkResponseMessage *rwrm) -{ +{ struct Trail *trail; struct FriendInfo *pred; struct FingerTable *ft; @@ -1298,7 +1298,7 @@ handle_dht_p2p_random_walk_response (void *cls, static void handle_dht_p2p_trail_destroy (void *cls, const struct TrailDestroyMessage *tdm) -{ +{ struct FriendInfo *sender = cls; struct Trail *trail; @@ -1340,8 +1340,9 @@ handle_dht_p2p_successor_find (void *cls, of successor finding... */ GNUNET_break_op (0 == trail_path_length); fsm = (const struct FindSuccessorMessage *) message; - GDS_DATACACHE_get_successors (trail_id, - &fsm->key); + GDS_DATACACHE_get_successors (&fsm->key, + &GDS_NEIGHBOURS_send_get_result, + (void *) trail_id); return GNUNET_OK; } @@ -1522,7 +1523,7 @@ struct TrailHandler /** * Check that a `struct TrailRouteMessage` is well-formed. * - * @param cls closure + * @param cls closure * @param trm the finger destroy message * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ @@ -1534,7 +1535,7 @@ check_dht_p2p_trail_route (void *cls, uint16_t path_length; const struct GNUNET_MessageHeader *payload; size_t msize; - + msize = ntohs (trm->header.size); path_length = ntohs (trm->path_length); if (msize < sizeof (struct TrailRouteMessage) + @@ -1561,7 +1562,7 @@ check_dht_p2p_trail_route (void *cls, /** * Handle a `struct TrailRouteMessage`. * - * @param cls closure + * @param cls closure * @param trm the finger destroy message */ static void diff --git a/src/dht/gnunet-service-wdht_neighbours.h b/src/dht/gnunet-service-wdht_neighbours.h index f080258bb..8461d16e8 100644 --- a/src/dht/gnunet-service-wdht_neighbours.h +++ b/src/dht/gnunet-service-wdht_neighbours.h @@ -71,7 +71,7 @@ GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key, /** * Send the get result to requesting client. * - * @param trail_id trail identifying where to send the result to, NULL for us + * @param cls a `const struct GNUNET_HashCode *` trail identifying where to send the result to, NULL for us * @param options routing options (from GET request) * @param key key of the requested data. * @param type block type @@ -82,14 +82,15 @@ GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key, * @param data_size size of the @a data */ void -GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *trail_id, +GDS_NEIGHBOURS_send_get_result (void *cls, enum GNUNET_DHT_RouteOption options, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, struct GNUNET_TIME_Absolute expiration, - const void *data, size_t data_size); + const void *data, + size_t data_size); /** diff --git a/src/dht/gnunet-service-wdht_nse.c b/src/dht/gnunet-service-wdht_nse.c deleted file mode 100644 index 400c8242e..000000000 --- a/src/dht/gnunet-service-wdht_nse.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2009, 2010, 2011 GNUnet e.V. - - 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 3, 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -/** - * @file dht/gnunet-service-xdht_nse.c - * @brief GNUnet DHT integration with NSE - * @author Christian Grothoff - */ -#include "platform.h" -#include "gnunet_nse_service.h" -#include "gnunet-service-wdht.h" -#include "gnunet-service-wdht_nse.h" - -/** - * log of the current network size estimate, used as the point where - * we switch between random and deterministic routing. Default - * value of 4.0 is used if NSE module is not available (i.e. not - * configured). - */ -static double log_of_network_size_estimate = 4.0; - -/** - * Network size estimation handle. - */ -static struct GNUNET_NSE_Handle *nse; - - -/** - * Callback that is called when network size estimate is updated. - * - * @param cls closure - * @param timestamp time when the estimate was received from the server (or created by the server) - * @param logestimate the log(Base 2) value of the current network size estimate - * @param std_dev standard deviation for the estimate - * - */ -static void -update_network_size_estimate (void *cls, struct GNUNET_TIME_Absolute timestamp, - double logestimate, double std_dev) -{ - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop ("# Network size estimates received"), - 1, GNUNET_NO); - /* do not allow estimates < 0.5 */ - log_of_network_size_estimate = GNUNET_MAX (0.5, logestimate); -} - - -/** - * Return the log of the current network size estimate. - * - * @return log of NSE - */ -double -GDS_NSE_get () -{ - return log_of_network_size_estimate; -} - - -/** - * Initialize NSE subsystem. - */ -void -GDS_NSE_init () -{ - unsigned long long hops; - - if ( (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (GDS_cfg, - "dht", - "FORCE_NSE")) && - (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_number (GDS_cfg, - "dht", - "FORCE_NSE", - &hops)) ) - { - log_of_network_size_estimate = (double) hops; - return; - } - nse = GNUNET_NSE_connect (GDS_cfg, &update_network_size_estimate, NULL); -} - - -/** - * Shutdown NSE subsystem. - */ -void -GDS_NSE_done () -{ - if (NULL != nse) - { - GNUNET_NSE_disconnect (nse); - nse = NULL; - } -} - -/* end of gnunet-service-dht_nse.c */ diff --git a/src/dht/gnunet-service-wdht_nse.h b/src/dht/gnunet-service-wdht_nse.h deleted file mode 100644 index 358c0c4bd..000000000 --- a/src/dht/gnunet-service-wdht_nse.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2011 GNUnet e.V. - - 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 3, 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -/** - * @file dht/gnunet-service-xdht_nse.h - * @brief GNUnet DHT integration with NSE - * @author Christian Grothoff - */ -#ifndef GNUNET_SERVICE_XDHT_NSE_H -#define GNUNET_SERVICE_XDHT_NSE_H - - -/** - * Return the log of the current network size estimate. - * - * @return log of NSE - */ -double -GDS_NSE_get (void); - - -/** - * Initialize NSE subsystem. - */ -void -GDS_NSE_init (void); - - -/** - * Shutdown NSE subsystem. - */ -void -GDS_NSE_done (void); - -#endif diff --git a/src/dht/gnunet-service-xdht.c b/src/dht/gnunet-service-xdht.c index e7b2c50c4..382a3b7c3 100644 --- a/src/dht/gnunet-service-xdht.c +++ b/src/dht/gnunet-service-xdht.c @@ -30,36 +30,23 @@ #include "gnunet_hello_lib.h" #include "gnunet_dht_service.h" #include "gnunet_statistics_service.h" -#include "gnunet-service-xdht.h" -#include "gnunet-service-xdht_clients.h" -#include "gnunet-service-xdht_datacache.h" -#include "gnunet-service-xdht_neighbours.h" -#include "gnunet-service-xdht_nse.h" +#include "gnunet-service-dht.h" +#include "gnunet-service-dht_datacache.h" +#include "gnunet-service-dht_neighbours.h" +#include "gnunet-service-dht_nse.h" #include "gnunet-service-xdht_routing.h" - -/** - * Handle for the statistics service. - */ -struct GNUNET_STATISTICS_Handle *GDS_stats; - -/** - * Our handle to the BLOCK library. - */ -struct GNUNET_BLOCK_Context *GDS_block_context; - -/** - * The configuration the DHT service is running with - */ -const struct GNUNET_CONFIGURATION_Handle *GDS_cfg; - /** * Should we store our topology predecessor and successor IDs into statistics? */ extern unsigned int track_topology; +/* Code shared between different DHT implementations */ +#include "gnunet-service-dht_clients.c" + + /** * Task run during shutdown. * @@ -72,16 +59,17 @@ shutdown_task (void *cls) GDS_DATACACHE_done (); GDS_ROUTING_done (); GDS_NSE_done (); - if (GDS_block_context != NULL) + if (NULL != GDS_block_context) { GNUNET_BLOCK_context_destroy (GDS_block_context); GDS_block_context = NULL; } - if (GDS_stats != NULL) + if (NULL != GDS_stats) { GNUNET_STATISTICS_destroy (GDS_stats, GNUNET_YES); GDS_stats = NULL; } + GDS_CLIENTS_stop (); } @@ -89,24 +77,29 @@ shutdown_task (void *cls) * Process dht requests. * * @param cls closure - * @param server the initialized server * @param c configuration to use + * @param service the initialized service */ static void -run (void *cls, struct GNUNET_SERVER_Handle *server, - const struct GNUNET_CONFIGURATION_Handle *c) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *c, + struct GNUNET_SERVICE_Handle *service) { unsigned long long _track_topology; GDS_cfg = c; + GDS_service = service; GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg); - GDS_stats = GNUNET_STATISTICS_create ("dht", GDS_cfg); + GDS_stats = GNUNET_STATISTICS_create ("dht", + GDS_cfg); GDS_ROUTING_init (); GDS_NSE_init (); GDS_DATACACHE_init (); - GDS_CLIENTS_init (server); + GDS_CLIENTS_init (); if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_number (c, "xdht", "track_toplogy", + GNUNET_CONFIGURATION_get_value_number (c, + "xdht", + "track_toplogy", &_track_topology)) { track_topology = (unsigned int) _track_topology; @@ -121,26 +114,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, } -/** - * The main function for the dht 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) -{ - int ret; - - ret = - (GNUNET_OK == - GNUNET_SERVICE_run (argc, argv, - "xdht", - GNUNET_SERVICE_OPTION_NONE, &run, - NULL)) ? 0 : 1; - GDS_CLIENTS_done (); - return ret; -} +/* Finally, define the main method */ +GDS_DHT_SERVICE_INIT("xdht", &run); + /* end of gnunet-service-xdht.c */ diff --git a/src/dht/gnunet-service-xdht_clients.c b/src/dht/gnunet-service-xdht_clients.c deleted file mode 100644 index 3185243b7..000000000 --- a/src/dht/gnunet-service-xdht_clients.c +++ /dev/null @@ -1,1417 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2009, 2010, 2011, 2016 GNUnet e.V. - - 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 3, 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -/** - * @file dht/gnunet-service-dht_clients.c - * @brief GNUnet DHT service's client management code - * @author Christian Grothoff - * @author Nathan Evans - */ - -#include "platform.h" -#include "gnunet_constants.h" -#include "gnunet_protocols.h" -#include "gnunet_statistics_service.h" -#include "gnunet-service-xdht.h" -#include "gnunet-service-xdht_clients.h" -#include "gnunet-service-xdht_datacache.h" -#include "gnunet-service-xdht_neighbours.h" -#include "dht.h" - - -/** - * Should routing details be logged to stderr (for debugging)? - */ -#define LOG_TRAFFIC(kind,...) GNUNET_log_from (kind, "dht-traffic",__VA_ARGS__) - -#define LOG(kind,...) GNUNET_log_from (kind, "dht-clients",__VA_ARGS__) - -#define DEBUG(...) \ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) - -/** - * Linked list of messages to send to clients. - */ -struct PendingMessage -{ - /** - * Pointer to next item in the list - */ - struct PendingMessage *next; - - /** - * Pointer to previous item in the list - */ - struct PendingMessage *prev; - - /** - * Actual message to be sent, allocated at the end of the struct: - * // msg = (cast) &pm[1]; - * // GNUNET_memcpy (&pm[1], data, len); - */ - const struct GNUNET_MessageHeader *msg; - -}; - - -/** - * Struct containing information about a client, - * handle to connect to it, and any pending messages - * that need to be sent to it. - */ -struct ClientList -{ - /** - * Linked list of active clients - */ - struct ClientList *next; - - /** - * Linked list of active clients - */ - struct ClientList *prev; - - /** - * The handle to this client - */ - struct GNUNET_SERVER_Client *client_handle; - - /** - * Handle to the current transmission request, NULL - * if none pending. - */ - struct GNUNET_SERVER_TransmitHandle *transmit_handle; - - /** - * Linked list of pending messages for this client - */ - struct PendingMessage *pending_head; - - /** - * Tail of linked list of pending messages for this client - */ - struct PendingMessage *pending_tail; - -}; - - -/** - * Entry in the local forwarding map for a client's GET request. - */ -struct ClientQueryRecord -{ - - /** - * The key this request was about - */ - struct GNUNET_HashCode key; - - /** - * Client responsible for the request. - */ - struct ClientList *client; - - /** - * Extended query (see gnunet_block_lib.h), allocated at the end of this struct. - */ - const void *xquery; - - /** - * Replies we have already seen for this request. - */ - struct GNUNET_HashCode *seen_replies; - - /** - * Pointer to this nodes heap location in the retry-heap (for fast removal) - */ - struct GNUNET_CONTAINER_HeapNode *hnode; - - /** - * What's the delay between re-try operations that we currently use for this - * request? - */ - struct GNUNET_TIME_Relative retry_frequency; - - /** - * What's the next time we should re-try this request? - */ - struct GNUNET_TIME_Absolute retry_time; - - /** - * The unique identifier of this request - */ - uint64_t unique_id; - - /** - * Number of bytes in xquery. - */ - size_t xquery_size; - - /** - * Number of entries in 'seen_replies'. - */ - unsigned int seen_replies_count; - - /** - * Desired replication level - */ - uint32_t replication; - - /** - * Any message options for this request - */ - uint32_t msg_options; - - /** - * The type for the data for the GET request. - */ - enum GNUNET_BLOCK_Type type; - -}; - - -/** - * Struct containing paremeters of monitoring requests. - */ -struct ClientMonitorRecord -{ - - /** - * Next element in DLL. - */ - struct ClientMonitorRecord *next; - - /** - * Previous element in DLL. - */ - struct ClientMonitorRecord *prev; - - /** - * Type of blocks that are of interest - */ - enum GNUNET_BLOCK_Type type; - - /** - * Key of data of interest, NULL for all. - */ - struct GNUNET_HashCode *key; - - /** - * Flag whether to notify about GET messages. - */ - int16_t get; - - /** - * Flag whether to notify about GET_REPONSE messages. - */ - int16_t get_resp; - - /** - * Flag whether to notify about PUT messages. - */ - uint16_t put; - - /** - * Client to notify of these requests. - */ - struct ClientList *client; -}; - - -/** - * List of active clients. - */ -static struct ClientList *client_head; - -/** - * List of active clients. - */ -static struct ClientList *client_tail; - -/** - * List of active monitoring requests. - */ -static struct ClientMonitorRecord *monitor_head; - -/** - * List of active monitoring requests. - */ -static struct ClientMonitorRecord *monitor_tail; - -/** - * Hashmap for fast key based lookup, maps keys to `struct ClientQueryRecord` entries. - */ -static struct GNUNET_CONTAINER_MultiHashMap *forward_map; - -/** - * Heap with all of our client's request, sorted by retry time (earliest on top). - */ -static struct GNUNET_CONTAINER_Heap *retry_heap; - -/** - * Task that re-transmits requests (using retry_heap). - */ -static struct GNUNET_SCHEDULER_Task * retry_task; - - -/** - * Task run to check for messages that need to be sent to a client. - * - * @param client a ClientList, containing the client and any messages to be sent to it - */ -static void -process_pending_messages (struct ClientList *client); - - -/** - * Callback called as a result of issuing a GNUNET_SERVER_notify_transmit_ready - * request. A ClientList is passed as closure, take the head of the list - * and copy it into buf, which has the result of sending the message to the - * client. - * - * @param cls closure to this call - * @param size maximum number of bytes available to send - * @param buf where to copy the actual message to - * - * @return the number of bytes actually copied, 0 indicates failure - */ -static size_t -send_reply_to_client (void *cls, size_t size, void *buf) -{ - struct ClientList *client = cls; - char *cbuf = buf; - struct PendingMessage *reply; - size_t off; - size_t msize; - - client->transmit_handle = NULL; - if (buf == NULL) - { - /* client disconnected */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Client %p disconnected, pending messages will be discarded\n", - client->client_handle); - return 0; - } - off = 0; - while ((NULL != (reply = client->pending_head)) && - (size >= off + (msize = ntohs (reply->msg->size)))) - { - GNUNET_CONTAINER_DLL_remove (client->pending_head, client->pending_tail, - reply); - GNUNET_memcpy (&cbuf[off], reply->msg, msize); - GNUNET_free (reply); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Transmitting %u bytes to client %p\n", - (unsigned int) msize, - client->client_handle); - off += msize; - } - process_pending_messages (client); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Transmitted %u/%u bytes to client %p\n", - (unsigned int) off, - (unsigned int) size, - client->client_handle); - return off; -} - - -/** - * Task run to check for messages that need to be sent to a client. - * - * @param client a ClientList, containing the client and any messages to be sent to it - */ -static void -process_pending_messages (struct ClientList *client) -{ - if ((client->pending_head == NULL) || (client->transmit_handle != NULL)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Not asking for transmission to %p now: %s\n", - client->client_handle, - client->pending_head == - NULL ? "no more messages" : "request already pending"); - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Asking for transmission of %u bytes to client %p\n", - ntohs (client->pending_head->msg->size), client->client_handle); - client->transmit_handle = - GNUNET_SERVER_notify_transmit_ready (client->client_handle, - ntohs (client->pending_head-> - msg->size), - GNUNET_TIME_UNIT_FOREVER_REL, - &send_reply_to_client, client); -} - - -/** - * Add a PendingMessage to the clients list of messages to be sent - * - * @param client the active client to send the message to - * @param pending_message the actual message to send - */ -static void -add_pending_message (struct ClientList *client, - struct PendingMessage *pending_message) -{ - GNUNET_CONTAINER_DLL_insert_tail (client->pending_head, client->pending_tail, - pending_message); - process_pending_messages (client); -} - - -/** - * Closure for 'forward_reply' - */ -struct ForwardReplyContext -{ - - /** - * Actual message to send to matching clients. - */ - struct PendingMessage *pm; - - /** - * Embedded payload. - */ - const void *data; - - /** - * Type of the data. - */ - enum GNUNET_BLOCK_Type type; - - /** - * Number of bytes in data. - */ - size_t data_size; - - /** - * Do we need to copy 'pm' because it was already used? - */ - int do_copy; - -}; - - -/** - * Find a client if it exists, add it otherwise. - * - * @param client the server handle to the client - * - * @return the client if found, a new client otherwise - */ -static struct ClientList * -find_active_client (struct GNUNET_SERVER_Client *client) -{ - struct ClientList *pos = client_head; - struct ClientList *ret; - - while (pos != NULL) - { - if (pos->client_handle == client) - return pos; - pos = pos->next; - } - ret = GNUNET_new (struct ClientList); - ret->client_handle = client; - GNUNET_CONTAINER_DLL_insert (client_head, client_tail, ret); - return ret; -} - - -/** - * Iterator over hash map entries that frees all entries - * associated with the given client. - * - * @param cls client to search for in source routes - * @param key current key code (ignored) - * @param value value in the hash map, a ClientQueryRecord - * @return #GNUNET_YES (we should continue to iterate) - */ -static int -remove_client_records (void *cls, const struct GNUNET_HashCode * key, void *value) -{ - struct ClientList *client = cls; - struct ClientQueryRecord *record = value; - - if (record->client != client) - return GNUNET_YES; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Removing client %p's record for key %s\n", client, - GNUNET_h2s (key)); - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_remove (forward_map, key, - record)); - if (NULL != record->hnode) - GNUNET_CONTAINER_heap_remove_node (record->hnode); - GNUNET_array_grow (record->seen_replies, record->seen_replies_count, 0); - GNUNET_free (record); - return GNUNET_YES; -} - - -/** - * Iterator over hash map entries that send a given reply to - * each of the matching clients. With some tricky recycling - * of the buffer. - * - * @param cls the 'struct ForwardReplyContext' - * @param key current key - * @param value value in the hash map, a ClientQueryRecord - * @return GNUNET_YES (we should continue to iterate), - * if the result is mal-formed, GNUNET_NO - */ -static int -forward_reply (void *cls, const struct GNUNET_HashCode * key, void *value) -{ - struct ForwardReplyContext *frc = cls; - struct ClientQueryRecord *record = value; - struct PendingMessage *pm; - struct GNUNET_DHT_ClientResultMessage *reply; - enum GNUNET_BLOCK_EvaluationResult eval; - int do_free; - struct GNUNET_HashCode ch; - unsigned int i; - - LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, - "XVINE CLIENT-RESULT %s\n", - GNUNET_h2s_full (key)); -#if 0 - if ((record->type != GNUNET_BLOCK_TYPE_ANY) && (record->type != frc->type)) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Record type missmatch, not passing request for key %s to local client\n", - GNUNET_h2s (key)); - - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# Key match, type mismatches in REPLY to CLIENT"), - 1, GNUNET_NO); - return GNUNET_YES; /* type mismatch */ - } -#endif - GNUNET_CRYPTO_hash (frc->data, frc->data_size, &ch); - for (i = 0; i < record->seen_replies_count; i++) - if (0 == memcmp (&record->seen_replies[i], &ch, sizeof (struct GNUNET_HashCode))) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Duplicate reply, not passing request for key %s to local client\n", - GNUNET_h2s (key)); - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# Duplicate REPLIES to CLIENT request dropped"), - 1, GNUNET_NO); - return GNUNET_YES; /* duplicate */ - } - eval = - GNUNET_BLOCK_evaluate (GDS_block_context, - record->type, - GNUNET_BLOCK_EO_NONE, - key, NULL, 0, - record->xquery, - record->xquery_size, - frc->data, - frc->data_size); - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Evaluation result is %d for key %s for local client's query\n", - (int) eval, GNUNET_h2s (key)); - switch (eval) - { - case GNUNET_BLOCK_EVALUATION_OK_LAST: - do_free = GNUNET_YES; - break; - case GNUNET_BLOCK_EVALUATION_OK_MORE: - GNUNET_array_append (record->seen_replies, record->seen_replies_count, ch); - do_free = GNUNET_NO; - break; - case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: - /* should be impossible to encounter here */ - GNUNET_break (0); - return GNUNET_YES; - case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: - GNUNET_break_op (0); - return GNUNET_NO; - case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: - GNUNET_break (0); - return GNUNET_NO; - case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: - GNUNET_break (0); - return GNUNET_NO; - case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: - return GNUNET_YES; - case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Unsupported block type (%u) in request!\n"), record->type); - return GNUNET_NO; - default: - GNUNET_break (0); - return GNUNET_NO; - } - if (GNUNET_NO == frc->do_copy) - { - /* first time, we can use the original data */ - pm = frc->pm; - frc->do_copy = GNUNET_YES; - } - else - { - /* two clients waiting for same reply, must copy for queueing */ - pm = GNUNET_malloc (sizeof (struct PendingMessage) + - ntohs (frc->pm->msg->size)); - GNUNET_memcpy (pm, frc->pm, - sizeof (struct PendingMessage) + ntohs (frc->pm->msg->size)); - pm->next = pm->prev = NULL; - pm->msg = (struct GNUNET_MessageHeader *) &pm[1]; - } - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop ("# RESULTS queued for clients"), 1, - GNUNET_NO); - reply = (struct GNUNET_DHT_ClientResultMessage *) &pm[1]; - reply->unique_id = record->unique_id; - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Queueing reply to query %s for client %p\n", - GNUNET_h2s (key), - record->client->client_handle); - add_pending_message (record->client, pm); - if (GNUNET_YES == do_free) - remove_client_records (record->client, key, record); - return GNUNET_YES; -} - - -/** - * Handle a reply we've received from another peer. If the reply - * matches any of our pending queries, forward it to the respective - * client(s). - * - * @param expiration when will the reply expire - * @param key the query this reply is for - * @param get_path_length number of peers in @a get_path - * @param get_path path the reply took on get - * @param put_path_length number of peers in @a put_path - * @param put_path path the reply took on put - * @param type type of the reply - * @param data_size number of bytes in @a data - * @param data application payload data - */ -void -GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, - const struct GNUNET_HashCode *key, - unsigned int get_path_length, - const struct GNUNET_PeerIdentity *get_path, - unsigned int put_path_length, - const struct GNUNET_PeerIdentity *put_path, - enum GNUNET_BLOCK_Type type, size_t data_size, - const void *data) -{ - struct ForwardReplyContext frc; - struct PendingMessage *pm; - struct GNUNET_DHT_ClientResultMessage *reply; - struct GNUNET_PeerIdentity *paths; - size_t msize; - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "reply for key %s\n", - GNUNET_h2s (key)); - - if (NULL == GNUNET_CONTAINER_multihashmap_get (forward_map, key)) - { - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# REPLIES ignored for CLIENTS (no match)"), 1, - GNUNET_NO); - return; /* no matching request, fast exit! */ - } - msize = - sizeof (struct GNUNET_DHT_ClientResultMessage) + data_size + - (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity); - if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Could not pass reply to client, message too big!\n")); - return; - } - DEBUG ("reply FOR DATA_SIZE = %u\n", - (unsigned int) msize); - pm = GNUNET_malloc (msize + sizeof (struct PendingMessage)); - reply = (struct GNUNET_DHT_ClientResultMessage *) &pm[1]; - pm->msg = &reply->header; - reply->header.size = htons ((uint16_t) msize); - reply->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT); - reply->type = htonl (type); - reply->get_path_length = htonl (get_path_length); - reply->put_path_length = htonl (put_path_length); - reply->unique_id = 0; /* filled in later */ - reply->expiration = GNUNET_TIME_absolute_hton (expiration); - reply->key = *key; - paths = (struct GNUNET_PeerIdentity *) &reply[1]; - GNUNET_memcpy (paths, - put_path, - sizeof (struct GNUNET_PeerIdentity) * put_path_length); - GNUNET_memcpy (&paths[put_path_length], - get_path, - sizeof (struct GNUNET_PeerIdentity) * get_path_length); - GNUNET_memcpy (&paths[get_path_length + put_path_length], - data, - data_size); - frc.do_copy = GNUNET_NO; - frc.pm = pm; - frc.data = data; - frc.data_size = data_size; - frc.type = type; - GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, - key, - &forward_reply, - &frc); - if (GNUNET_NO == frc.do_copy) - { - /* did not match any of the requests, free! */ - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# REPLIES ignored for CLIENTS (no match)"), 1, - GNUNET_NO); - GNUNET_free (pm); - } -} - -/** - * Check if some client is monitoring GET messages and notify - * them in that case. - * - * @param options Options, for instance RecordRoute, DemultiplexEverywhere. - * @param type The type of data in the request. - * @param hop_count Hop count so far. - * @param path_length number of entries in path (or 0 if not recorded). - * @param path peers on the GET path (or NULL if not recorded). - * @param desired_replication_level Desired replication level. - * @param key Key of the requested data. - */ -void -GDS_CLIENTS_process_get (uint32_t options, - enum GNUNET_BLOCK_Type type, - uint32_t hop_count, - uint32_t desired_replication_level, - unsigned int path_length, - const struct GNUNET_PeerIdentity *path, - const struct GNUNET_HashCode * key) -{ - struct ClientMonitorRecord *m; - struct ClientList **cl; - unsigned int cl_size; - - cl = NULL; - cl_size = 0; - for (m = monitor_head; NULL != m; m = m->next) - { - if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) && - (NULL == m->key || - memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0)) - { - struct PendingMessage *pm; - struct GNUNET_DHT_MonitorGetMessage *mmsg; - struct GNUNET_PeerIdentity *msg_path; - size_t msize; - unsigned int i; - - /* Don't send duplicates */ - for (i = 0; i < cl_size; i++) - if (cl[i] == m->client) - break; - if (i < cl_size) - continue; - GNUNET_array_append (cl, cl_size, m->client); - - msize = path_length * sizeof (struct GNUNET_PeerIdentity); - msize += sizeof (struct GNUNET_DHT_MonitorGetMessage); - msize += sizeof (struct PendingMessage); - pm = GNUNET_malloc (msize); - mmsg = (struct GNUNET_DHT_MonitorGetMessage *) &pm[1]; - pm->msg = &mmsg->header; - mmsg->header.size = htons (msize - sizeof (struct PendingMessage)); - mmsg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET); - mmsg->options = htonl(options); - mmsg->type = htonl(type); - mmsg->hop_count = htonl(hop_count); - mmsg->desired_replication_level = htonl(desired_replication_level); - mmsg->get_path_length = htonl(path_length); - GNUNET_memcpy (&mmsg->key, key, sizeof (struct GNUNET_HashCode)); - msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1]; - if (path_length > 0) - GNUNET_memcpy (msg_path, path, - path_length * sizeof (struct GNUNET_PeerIdentity)); - add_pending_message (m->client, pm); - } - } - GNUNET_free_non_null (cl); -} - - -/** - * Check if some client is monitoring PUT messages and notify - * them in that case. - * - * @param options Options, for instance RecordRoute, DemultiplexEverywhere. - * @param type The type of data in the request. - * @param hop_count Hop count so far. - * @param path_length number of entries in path (or 0 if not recorded). - * @param path peers on the PUT path (or NULL if not recorded). - * @param desired_replication_level Desired replication level. - * @param exp Expiration time of the data. - * @param key Key under which data is to be stored. - * @param data Pointer to the data carried. - * @param size Number of bytes in data. - */ -void -GDS_CLIENTS_process_put (uint32_t options, - enum GNUNET_BLOCK_Type type, - uint32_t hop_count, - uint32_t desired_replication_level, - unsigned int path_length, - const struct GNUNET_PeerIdentity *path, - struct GNUNET_TIME_Absolute exp, - const struct GNUNET_HashCode * key, - const void *data, - size_t size) -{ - struct ClientMonitorRecord *m; - struct ClientList **cl; - unsigned int cl_size; - - cl = NULL; - cl_size = 0; - for (m = monitor_head; NULL != m; m = m->next) - { - if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) && - (NULL == m->key || - memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0)) - { - struct PendingMessage *pm; - struct GNUNET_DHT_MonitorPutMessage *mmsg; - struct GNUNET_PeerIdentity *msg_path; - size_t msize; - unsigned int i; - - /* Don't send duplicates */ - for (i = 0; i < cl_size; i++) - if (cl[i] == m->client) - break; - if (i < cl_size) - continue; - GNUNET_array_append (cl, cl_size, m->client); - - msize = size; - msize += path_length * sizeof (struct GNUNET_PeerIdentity); - msize += sizeof (struct GNUNET_DHT_MonitorPutMessage); - msize += sizeof (struct PendingMessage); - pm = GNUNET_malloc (msize); - mmsg = (struct GNUNET_DHT_MonitorPutMessage *) &pm[1]; - pm->msg = (struct GNUNET_MessageHeader *) mmsg; - mmsg->header.size = htons (msize - sizeof (struct PendingMessage)); - mmsg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT); - mmsg->options = htonl(options); - mmsg->type = htonl(type); - mmsg->hop_count = htonl(hop_count); - mmsg->desired_replication_level = htonl(desired_replication_level); - mmsg->put_path_length = htonl(path_length); - msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1]; - if (path_length > 0) - { - GNUNET_memcpy (msg_path, path, - path_length * sizeof (struct GNUNET_PeerIdentity)); - } - mmsg->expiration_time = GNUNET_TIME_absolute_hton(exp); - GNUNET_memcpy (&mmsg->key, key, sizeof (struct GNUNET_HashCode)); - if (size > 0) - GNUNET_memcpy (&msg_path[path_length], data, size); - add_pending_message (m->client, pm); - } - } - GNUNET_free_non_null (cl); -} - - -/** - * Route the given request via the DHT. - */ -static void -transmit_request (struct ClientQueryRecord *cqr) -{ - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# GET requests from clients injected"), 1, - GNUNET_NO); - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Initiating GET for %s, replication %u, already have %u replies\n", - GNUNET_h2s (&cqr->key), - cqr->replication, - cqr->seen_replies_count); - - GDS_NEIGHBOURS_handle_get (&cqr->key, cqr->type, cqr->msg_options, - cqr->replication); - - /* exponential back-off for retries. - * max GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */ - cqr->retry_frequency = GNUNET_TIME_STD_BACKOFF (cqr->retry_frequency); - cqr->retry_time = GNUNET_TIME_relative_to_absolute (cqr->retry_frequency); -} - - -/** - * Task that looks at the 'retry_heap' and transmits all of the requests - * on the heap that are ready for transmission. Then re-schedules - * itself (unless the heap is empty). - * - * @param cls unused - */ -static void -transmit_next_request_task (void *cls) -{ - struct ClientQueryRecord *cqr; - struct GNUNET_TIME_Relative delay; - - retry_task = NULL; - while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap))) - { - cqr->hnode = NULL; - delay = GNUNET_TIME_absolute_get_remaining (cqr->retry_time); - if (delay.rel_value_us > 0) - { - cqr->hnode = - GNUNET_CONTAINER_heap_insert (retry_heap, cqr, - cqr->retry_time.abs_value_us); - retry_task = - GNUNET_SCHEDULER_add_delayed (delay, &transmit_next_request_task, - NULL); - return; - } - transmit_request (cqr); - cqr->hnode = - GNUNET_CONTAINER_heap_insert (retry_heap, cqr, - cqr->retry_time.abs_value_us); - } -} - - -/** - * Handler for PUT messages. - * - * @param cls closure for the service - * @param client the client we received this message from - * @param message the actual message received - */ -static void -handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) -{ - const struct GNUNET_DHT_ClientPutMessage *put_msg; - struct PendingMessage *pm; - struct GNUNET_DHT_ClientPutConfirmationMessage *conf; - uint16_t size; - - size = ntohs (message->size); - if (size < sizeof (struct GNUNET_DHT_ClientPutMessage)) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# PUT requests received from clients"), 1, - GNUNET_NO); - put_msg = (const struct GNUNET_DHT_ClientPutMessage *) message; - LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, "X-VINE DHT CLIENT-PUT %s\n", - GNUNET_h2s_full (&put_msg->key)); - /* give to local clients */ - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Handling local PUT of %u-bytes for query %s\n", - size - sizeof (struct GNUNET_DHT_ClientPutMessage), - GNUNET_h2s (&put_msg->key)); - DEBUG("PUT doing put i = %s\n",GNUNET_h2s(&(put_msg->key))); - GDS_CLIENTS_handle_reply (GNUNET_TIME_absolute_ntoh (put_msg->expiration), - &put_msg->key, 0, NULL, 0, NULL, - ntohl (put_msg->type), - size - sizeof (struct GNUNET_DHT_ClientPutMessage), - &put_msg[1]); - - GDS_NEIGHBOURS_handle_put (&put_msg->key, - ntohl (put_msg->type), ntohl (put_msg->options), - ntohl (put_msg->desired_replication_level), - GNUNET_TIME_absolute_ntoh (put_msg->expiration), - &put_msg[1], - size - sizeof (struct GNUNET_DHT_ClientPutMessage)); - pm = GNUNET_malloc (sizeof (struct PendingMessage) + - sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage)); - conf = (struct GNUNET_DHT_ClientPutConfirmationMessage *) &pm[1]; - conf->header.size = htons (sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage)); - conf->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT_OK); - conf->reserved = htonl (0); - conf->unique_id = put_msg->unique_id; - pm->msg = &conf->header; - add_pending_message (find_active_client (client), pm); - GNUNET_SERVER_receive_done (client, GNUNET_OK); -} - - -/** - * Handler for DHT GET messages from the client. - * - * @param cls closure for the service - * @param client the client we received this message from - * @param message the actual message received - */ -static void -handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) -{ - const struct GNUNET_DHT_ClientGetMessage *get; - struct ClientQueryRecord *cqr; - size_t xquery_size; - const char *xquery; - uint16_t size; - - size = ntohs (message->size); - if (size < sizeof (struct GNUNET_DHT_ClientGetMessage)) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } - xquery_size = size - sizeof (struct GNUNET_DHT_ClientGetMessage); - get = (const struct GNUNET_DHT_ClientGetMessage *) message; - xquery = (const char *) &get[1]; - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# GET requests received from clients"), 1, - GNUNET_NO); - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Received GET request for %s from local client %p, xq: %.*s\n", - GNUNET_h2s (&get->key), client, xquery_size, xquery); - - LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, "X-VINE CLIENT-GET %s\n", - GNUNET_h2s_full (&get->key)); - - - cqr = GNUNET_malloc (sizeof (struct ClientQueryRecord) + xquery_size); - cqr->key = get->key; - cqr->client = find_active_client (client); - cqr->xquery = (void *) &cqr[1]; - GNUNET_memcpy (&cqr[1], xquery, xquery_size); - cqr->hnode = GNUNET_CONTAINER_heap_insert (retry_heap, cqr, 0); - cqr->retry_frequency = GNUNET_TIME_UNIT_SECONDS; - cqr->retry_time = GNUNET_TIME_absolute_get (); - cqr->unique_id = get->unique_id; - cqr->xquery_size = xquery_size; - cqr->replication = ntohl (get->desired_replication_level); - cqr->msg_options = ntohl (get->options); - cqr->type = ntohl (get->type); - - // FIXME use cqr->key, set multihashmap create to GNUNET_YES - GNUNET_CONTAINER_multihashmap_put (forward_map, &get->key, cqr, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); - - struct GNUNET_PeerIdentity my_identity; - my_identity = GDS_NEIGHBOURS_get_my_id(); - GDS_CLIENTS_process_get (ntohl (get->options), - ntohl (get->type), - 0, - ntohl (get->desired_replication_level), - 1, - &my_identity, - &get->key); - /* start remote requests */ - if (NULL != retry_task) - GNUNET_SCHEDULER_cancel (retry_task); - retry_task = GNUNET_SCHEDULER_add_now (&transmit_next_request_task, NULL); - GNUNET_SERVER_receive_done (client, GNUNET_OK); -} - - -/** - * Closure for 'find_by_unique_id'. - */ -struct FindByUniqueIdContext -{ - /** - * Where to store the result, if found. - */ - struct ClientQueryRecord *cqr; - - uint64_t unique_id; -}; - - -/** - * Function called for each existing DHT record for the given - * query. Checks if it matches the UID given in the closure - * and if so returns the entry as a result. - * - * @param cls the search context - * @param key query for the lookup (not used) - * @param value the 'struct ClientQueryRecord' - * @return GNUNET_YES to continue iteration (result not yet found) - */ -static int -find_by_unique_id (void *cls, - const struct GNUNET_HashCode *key, - void *value) -{ - struct FindByUniqueIdContext *fui_ctx = cls; - struct ClientQueryRecord *cqr = value; - - if (cqr->unique_id != fui_ctx->unique_id) - return GNUNET_YES; - fui_ctx->cqr = cqr; - return GNUNET_NO; -} - - -/** - * Handler for "GET result seen" messages from the client. - * - * @param cls closure for the service - * @param client the client we received this message from - * @param message the actual message received - */ -static void -handle_dht_local_get_result_seen (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) -{ - const struct GNUNET_DHT_ClientGetResultSeenMessage *seen; - uint16_t size; - unsigned int hash_count; - unsigned int old_count; - const struct GNUNET_HashCode *hc; - struct FindByUniqueIdContext fui_ctx; - struct ClientQueryRecord *cqr; - - size = ntohs (message->size); - if (size < sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage)) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } - seen = (const struct GNUNET_DHT_ClientGetResultSeenMessage *) message; - hash_count = (size - sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage)) / sizeof (struct GNUNET_HashCode); - if (size != sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage) + hash_count * sizeof (struct GNUNET_HashCode)) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } - hc = (const struct GNUNET_HashCode*) &seen[1]; - fui_ctx.unique_id = seen->unique_id; - fui_ctx.cqr = NULL; - GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, - &seen->key, - &find_by_unique_id, - &fui_ctx); - if (NULL == (cqr = fui_ctx.cqr)) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } - /* finally, update 'seen' list */ - old_count = cqr->seen_replies_count; - GNUNET_array_grow (cqr->seen_replies, - cqr->seen_replies_count, - cqr->seen_replies_count + hash_count); - GNUNET_memcpy (&cqr->seen_replies[old_count], - hc, - sizeof (struct GNUNET_HashCode) * hash_count); -} - - -/** - * Closure for 'remove_by_unique_id'. - */ -struct RemoveByUniqueIdContext -{ - /** - * Client that issued the removal request. - */ - struct ClientList *client; - - /** - * Unique ID of the request. - */ - uint64_t unique_id; -}; - - -/** - * Iterator over hash map entries that frees all entries - * that match the given client and unique ID. - * - * @param cls unique ID and client to search for in source routes - * @param key current key code - * @param value value in the hash map, a ClientQueryRecord - * @return GNUNET_YES (we should continue to iterate) - */ -static int -remove_by_unique_id (void *cls, const struct GNUNET_HashCode * key, void *value) -{ - const struct RemoveByUniqueIdContext *ctx = cls; - struct ClientQueryRecord *record = value; - - if (record->unique_id != ctx->unique_id) - return GNUNET_YES; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Removing client %p's record for key %s (by unique id)\n", - ctx->client->client_handle, GNUNET_h2s (key)); - return remove_client_records (ctx->client, key, record); -} - - -/** - * Handler for any generic DHT stop messages, calls the appropriate handler - * depending on message type (if processed locally) - * - * @param cls closure for the service - * @param client the client we received this message from - * @param message the actual message received - * - */ -static void -handle_dht_local_get_stop (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) -{ - const struct GNUNET_DHT_ClientGetStopMessage *dht_stop_msg = - (const struct GNUNET_DHT_ClientGetStopMessage *) message; - struct RemoveByUniqueIdContext ctx; - - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# GET STOP requests received from clients"), 1, - GNUNET_NO); - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Received GET STOP request for %s from local client %p\n", - GNUNET_h2s (&dht_stop_msg->key), - client); - ctx.client = find_active_client (client); - ctx.unique_id = dht_stop_msg->unique_id; - GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, &dht_stop_msg->key, - &remove_by_unique_id, &ctx); - GNUNET_SERVER_receive_done (client, GNUNET_OK); -} - - -/** - * Handler for monitor start messages - * - * @param cls closure for the service - * @param client the client we received this message from - * @param message the actual message received - * - */ -static void -handle_dht_local_monitor (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) -{ - struct ClientMonitorRecord *r; - const struct GNUNET_DHT_MonitorStartStopMessage *msg; - - msg = (struct GNUNET_DHT_MonitorStartStopMessage *) message; - r = GNUNET_new (struct ClientMonitorRecord); - - r->client = find_active_client(client); - r->type = ntohl(msg->type); - r->get = ntohs(msg->get); - r->get_resp = ntohs(msg->get_resp); - r->put = ntohs(msg->put); - if (0 == ntohs(msg->filter_key)) - r->key = NULL; - else - { - r->key = GNUNET_new (struct GNUNET_HashCode); - GNUNET_memcpy (r->key, &msg->key, sizeof (struct GNUNET_HashCode)); - } - GNUNET_CONTAINER_DLL_insert (monitor_head, monitor_tail, r); - GNUNET_SERVER_receive_done (client, GNUNET_OK); -} - - -/** - * Handler for monitor stop messages - * - * @param cls closure for the service - * @param client the client we received this message from - * @param message the actual message received - * - */ -static void -handle_dht_local_monitor_stop (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) -{ - struct ClientMonitorRecord *r; - const struct GNUNET_DHT_MonitorStartStopMessage *msg; - int keys_match; - - msg = (struct GNUNET_DHT_MonitorStartStopMessage *) message; - r = monitor_head; - - while (NULL != r) - { - if (NULL == r->key) - keys_match = (0 == ntohs(msg->filter_key)); - else - { - keys_match = (0 != ntohs(msg->filter_key) - && !memcmp(r->key, &msg->key, sizeof(struct GNUNET_HashCode))); - } - if (find_active_client(client) == r->client - && ntohl(msg->type) == r->type - && r->get == msg->get - && r->get_resp == msg->get_resp - && r->put == msg->put - && keys_match - ) - { - GNUNET_CONTAINER_DLL_remove (monitor_head, monitor_tail, r); - GNUNET_free_non_null (r->key); - GNUNET_free (r); - GNUNET_SERVER_receive_done (client, GNUNET_OK); - return; /* Delete only ONE entry */ - } - r = r->next; - } - - GNUNET_SERVER_receive_done (client, GNUNET_OK); -} - - -/** - * Functions with this signature are called whenever a client - * is disconnected on the network level. - * - * @param cls closure (NULL for dht) - * @param client identification of the client; NULL - * for the last call when the server is destroyed - */ -static void -handle_client_disconnect (void *cls, - struct GNUNET_SERVER_Client *client) -{ - struct ClientList *pos; - struct PendingMessage *reply; - struct ClientMonitorRecord *monitor; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Local client %p disconnects\n", - client); - pos = find_active_client (client); - GNUNET_CONTAINER_DLL_remove (client_head, client_tail, pos); - if (pos->transmit_handle != NULL) - GNUNET_SERVER_notify_transmit_ready_cancel (pos->transmit_handle); - while (NULL != (reply = pos->pending_head)) - { - GNUNET_CONTAINER_DLL_remove (pos->pending_head, pos->pending_tail, reply); - GNUNET_free (reply); - } - monitor = monitor_head; - while (NULL != monitor) - { - if (monitor->client == pos) - { - struct ClientMonitorRecord *next; - - GNUNET_free_non_null (monitor->key); - next = monitor->next; - GNUNET_CONTAINER_DLL_remove (monitor_head, monitor_tail, monitor); - GNUNET_free (monitor); - monitor = next; - } - else - monitor = monitor->next; - } - GNUNET_CONTAINER_multihashmap_iterate (forward_map, &remove_client_records, - pos); - GNUNET_free (pos); -} - - - -/** - * Initialize client subsystem. - * - * @param server the initialized server - */ -void -GDS_CLIENTS_init (struct GNUNET_SERVER_Handle *server) -{ - static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = { - {&handle_dht_local_put, NULL, - GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT, 0}, - {&handle_dht_local_get, NULL, - GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET, 0}, - {&handle_dht_local_get_stop, NULL, - GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_STOP, - sizeof (struct GNUNET_DHT_ClientGetStopMessage)}, - {&handle_dht_local_monitor, NULL, - GNUNET_MESSAGE_TYPE_DHT_MONITOR_START, - sizeof (struct GNUNET_DHT_MonitorStartStopMessage)}, - {&handle_dht_local_monitor_stop, NULL, - GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP, - sizeof (struct GNUNET_DHT_MonitorStartStopMessage)}, - {&handle_dht_local_get_result_seen, NULL, - GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN, 0}, - {NULL, NULL, 0, 0} - }; - forward_map = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_NO); - retry_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); - GNUNET_SERVER_add_handlers (server, plugin_handlers); - GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL); -} - - -/** - * Shutdown client subsystem. - */ -void -GDS_CLIENTS_done () -{ - GNUNET_assert (client_head == NULL); - GNUNET_assert (client_tail == NULL); - if (NULL != retry_task) - { - GNUNET_SCHEDULER_cancel (retry_task); - retry_task = NULL; - } - if (NULL != retry_heap) - { - GNUNET_assert (0 == GNUNET_CONTAINER_heap_get_size (retry_heap)); - GNUNET_CONTAINER_heap_destroy (retry_heap); - retry_heap = NULL; - } - if (NULL != forward_map) - { - GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (forward_map)); - GNUNET_CONTAINER_multihashmap_destroy (forward_map); - forward_map = NULL; - } -} - -/* end of gnunet-service-dht_clients.c */ diff --git a/src/dht/gnunet-service-xdht_clients.h b/src/dht/gnunet-service-xdht_clients.h deleted file mode 100644 index f51564136..000000000 --- a/src/dht/gnunet-service-xdht_clients.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2009, 2010, 2011 GNUnet e.V. - - 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 3, 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -/** - * @file dht/gnunet-service-xdht_clients.h - * @brief GNUnet DHT service's client management code - * @author Christian Grothoff - * @author Nathan Evans - */ -#ifndef GNUNET_SERVICE_DHT_CLIENT_H -#define GNUNET_SERVICE_DHT_CLIENT_H - -#include "gnunet_util_lib.h" -#include "gnunet_block_lib.h" - -/** - * Handle a reply we've received from another peer. If the reply - * matches any of our pending queries, forward it to the respective - * client(s). - * - * @param expiration when will the reply expire - * @param key the query this reply is for - * @param get_path_length number of peers in @a get_path - * @param get_path path the reply took on get - * @param put_path_length number of peers in @a put_path - * @param put_path path the reply took on put - * @param type type of the reply - * @param data_size number of bytes in @a data - * @param data application payload data - */ -void -GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, - const struct GNUNET_HashCode *key, - unsigned int get_path_length, - const struct GNUNET_PeerIdentity *get_path, - unsigned int put_path_length, - const struct GNUNET_PeerIdentity *put_path, - enum GNUNET_BLOCK_Type type, size_t data_size, - const void *data); - - -/** - * Check if some client is monitoring GET messages and notify - * them in that case. - * - * @param options Options, for instance RecordRoute, DemultiplexEverywhere. - * @param type The type of data in the request. - * @param hop_count Hop count so far. - * @param path_length number of entries in path (or 0 if not recorded). - * @param path peers on the GET path (or NULL if not recorded). - * @param desired_replication_level Desired replication level. - * @param key Key of the requested data. - */ -void -GDS_CLIENTS_process_get (uint32_t options, - enum GNUNET_BLOCK_Type type, - uint32_t hop_count, - uint32_t desired_replication_level, - unsigned int path_length, - const struct GNUNET_PeerIdentity *path, - const struct GNUNET_HashCode *key); - - -/** - * Check if some client is monitoring GET RESP messages and notify - * them in that case. - * - * @param type The type of data in the result. - * @param get_path Peers on GET path (or NULL if not recorded). - * @param get_path_length number of entries in @a get_path. - * @param put_path peers on the PUT path (or NULL if not recorded). - * @param put_path_length number of entries in @a get_path. - * @param exp Expiration time of the data. - * @param key Key of the @a data. - * @param data Pointer to the result data. - * @param size Number of bytes in @a data. - */ -void -GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, - const struct GNUNET_PeerIdentity *get_path, - unsigned int get_path_length, - const struct GNUNET_PeerIdentity *put_path, - unsigned int put_path_length, - struct GNUNET_TIME_Absolute exp, - const struct GNUNET_HashCode * key, - const void *data, - size_t size); - - -/** - * Check if some client is monitoring PUT messages and notify - * them in that case. - * - * @param options Options, for instance RecordRoute, DemultiplexEverywhere. - * @param type The type of data in the request. - * @param hop_count Hop count so far. - * @param path_length number of entries in path (or 0 if not recorded). - * @param path peers on the PUT path (or NULL if not recorded). - * @param desired_replication_level Desired replication level. - * @param exp Expiration time of the data. - * @param key Key under which data is to be stored. - * @param data Pointer to the data carried. - * @param size Number of bytes in data. - */ -void -GDS_CLIENTS_process_put (uint32_t options, - enum GNUNET_BLOCK_Type type, - uint32_t hop_count, - uint32_t desired_replication_level, - unsigned int path_length, - const struct GNUNET_PeerIdentity *path, - struct GNUNET_TIME_Absolute exp, - const struct GNUNET_HashCode * key, - const void *data, - size_t size); - -/** - * Initialize client subsystem. - * - * @param server the initialized server - */ -void -GDS_CLIENTS_init (struct GNUNET_SERVER_Handle *server); - - -/** - * Shutdown client subsystem. - */ -void -GDS_CLIENTS_done (void); - -#endif diff --git a/src/dht/gnunet-service-xdht_datacache.c b/src/dht/gnunet-service-xdht_datacache.c deleted file mode 100644 index 10ae0068e..000000000 --- a/src/dht/gnunet-service-xdht_datacache.c +++ /dev/null @@ -1,401 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2009, 2010, 2011, 2015 GNUnet e.V. - - 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 3, 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -/** - * @file dht/gnunet-service-xdht_datacache.c - * @brief GNUnet DHT service's datacache integration - * @author Christian Grothoff - * @author Nathan Evans - */ -#include "platform.h" -#include "gnunet_datacache_lib.h" -#include "gnunet-service-xdht_clients.h" -#include "gnunet-service-xdht_datacache.h" -#include "gnunet-service-xdht_routing.h" -#include "gnunet-service-xdht_neighbours.h" -#include "gnunet-service-dht.h" - -#define LOG(kind,...) GNUNET_log_from (kind, "dht-dtcache",__VA_ARGS__) - -#define DEBUG(...) \ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) - -/** - * Handle to the datacache service (for inserting/retrieving data) - */ -static struct GNUNET_DATACACHE_Handle *datacache; - - -/** - * Handle a datum we've received from another peer. Cache if - * possible. - * - * @param expiration when will the reply expire - * @param key the query this reply is for - * @param put_path_length number of peers in @a put_path - * @param put_path path the reply took on put - * @param type type of the reply - * @param data_size number of bytes in @a data - * @param data application payload data - */ -void -GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, - const struct GNUNET_HashCode *key, - unsigned int put_path_length, - const struct GNUNET_PeerIdentity *put_path, - enum GNUNET_BLOCK_Type type, - size_t data_size, - const void *data) -{ - int r; - - if (NULL == datacache) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "PUT request received, but have no datacache!\n"); - return; - } - if (data_size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) - { - GNUNET_break (0); - return; - } - - /* Put size is actual data size plus struct overhead plus path length (if any) */ - r = GNUNET_DATACACHE_put (datacache, - key, - data_size, - data, - type, - expiration, - put_path_length, - put_path); - if (GNUNET_OK == r) - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop ("# ITEMS stored in datacache"), 1, - GNUNET_NO); - LOG (GNUNET_ERROR_TYPE_DEBUG, - "DATACACHE PUT for key %s [%u] completed (%d) after %u hops\n", - GNUNET_h2s (key), - data_size, - r, - put_path_length); -} - - -/** - * List of peers in the get path. - */ -struct GetPath -{ - /** - * Pointer to next item in the list - */ - struct GetPath *next; - - /** - * Pointer to previous item in the list - */ - struct GetPath *prev; - - /** - * An element in the get path. - */ - struct GNUNET_PeerIdentity peer; -}; - - -/** - * Context containing information about a GET request. - */ -struct GetRequestContext -{ - /** - * extended query (see gnunet_block_lib.h). - */ - const void *xquery; - - /** - * Bloomfilter to filter out duplicate replies (updated) - */ - struct GNUNET_CONTAINER_BloomFilter **reply_bf; - - /** - * The key this request was about - */ - struct GNUNET_HashCode key; - - /** - * Number of bytes in xquery. - */ - size_t xquery_size; - - /** - * Mutator value for the @e reply_bf, see gnunet_block_lib.h - */ - uint32_t reply_bf_mutator; - - /** - * Total number of peers in get path. - */ - unsigned int get_path_length; - - /** - * Return value to give back. - */ - enum GNUNET_BLOCK_EvaluationResult eval; - - /** - * Peeer which has the data for the key. - */ - struct GNUNET_PeerIdentity source_peer; - - /** - * Next hop to forward the get result to. - */ - struct GNUNET_PeerIdentity next_hop; - - /** - * Head of get path. - */ - struct GetPath *head; - - /** - * Tail of get path. - */ - struct GetPath *tail; - - /* get_path */ -}; - - -/** - * Iterator for local get request results, - * - * @param cls closure for iterator, a `struct GetRequestContext` - * @param key the key this @a data is stored under - * @param size the size of the data identified by key - * @param data the actual data - * @param type the type of the @a data - * @param exp when does this value expire? - * @param put_path_length number of peers in @a put_path - * @param put_path path the reply took on put - * @return #GNUNET_OK to continue iteration, anything else - * to stop iteration. - */ -static int -datacache_get_iterator (void *cls, - const struct GNUNET_HashCode *key, - size_t size, - const char *data, - enum GNUNET_BLOCK_Type type, - struct GNUNET_TIME_Absolute exp, - unsigned int put_path_length, - const struct GNUNET_PeerIdentity *put_path) -{ - struct GetRequestContext *ctx = cls; - enum GNUNET_BLOCK_EvaluationResult eval; - - eval = - GNUNET_BLOCK_evaluate (GDS_block_context, - type, - GNUNET_BLOCK_EO_NONE, - key, - ctx->reply_bf, - ctx->reply_bf_mutator, - ctx->xquery, - ctx->xquery_size, - data, - size); - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Found reply for query %s in datacache, evaluation result is %d\n", - GNUNET_h2s (key), (int) eval); - ctx->eval = eval; - - switch (eval) - { - case GNUNET_BLOCK_EVALUATION_OK_MORE: - case GNUNET_BLOCK_EVALUATION_OK_LAST: - /* forward to local clients */ - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# Good RESULTS found in datacache"), 1, - GNUNET_NO); - struct GNUNET_PeerIdentity *get_path; - get_path = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity) * - ctx->get_path_length); - struct GetPath *iterator; - iterator = ctx->head; - int i = 0; - while (i < ctx->get_path_length) - { - get_path[i] = iterator->peer; - i++; - iterator = iterator->next; - } - GDS_NEIGHBOURS_send_get_result (key,type, - &ctx->next_hop, - &ctx->source_peer, - put_path_length, - put_path, - ctx->get_path_length, - get_path, - exp, - data, - size); - GNUNET_free_non_null (get_path); - break; - case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# Duplicate RESULTS found in datacache"), 1, - GNUNET_NO); - break; - case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# Invalid RESULTS found in datacache"), 1, - GNUNET_NO); - break; - case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# Irrelevant RESULTS found in datacache"), 1, - GNUNET_NO); - break; - case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: - GNUNET_break (0); - break; - case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: - GNUNET_break_op (0); - return GNUNET_SYSERR; - case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop - ("# Unsupported RESULTS found in datacache"), 1, - GNUNET_NO); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Unsupported block type (%u) in local response!\n"), - type); - break; - } - - return (eval == GNUNET_BLOCK_EVALUATION_OK_LAST) ? GNUNET_NO : GNUNET_OK; -} - - -/** - * Handle a GET request we've received from another peer. - * - * @param key the query - * @param type requested data type - * @param xquery extended query - * @param xquery_size number of bytes in @a xquery - * @param reply_bf where the reply bf is (to be) stored, possibly updated, can be NULL - * @param reply_bf_mutator mutation value for @a reply_bf - * @return evaluation result for the local replies - * @get_path_length Total number of peers in get path - * @get_path Peers in get path. - */ -enum GNUNET_BLOCK_EvaluationResult -GDS_DATACACHE_handle_get (const struct GNUNET_HashCode *key, - enum GNUNET_BLOCK_Type type, - const void *xquery, - size_t xquery_size, - struct GNUNET_CONTAINER_BloomFilter **reply_bf, - uint32_t reply_bf_mutator, - uint32_t get_path_length, - struct GNUNET_PeerIdentity *get_path, - struct GNUNET_PeerIdentity *next_hop, - struct GNUNET_PeerIdentity *source_peer) -{ - struct GetRequestContext ctx; - unsigned int r; - - if (datacache == NULL) - return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop ("# GET requests given to datacache"), - 1, GNUNET_NO); - ctx.eval = GNUNET_BLOCK_EVALUATION_REQUEST_VALID; - ctx.key = *key; - ctx.xquery = xquery; - ctx.xquery_size = xquery_size; - ctx.reply_bf = reply_bf; - ctx.reply_bf_mutator = reply_bf_mutator; - ctx.get_path_length = get_path_length; - - if (NULL != next_hop) - ctx.next_hop = *next_hop; - unsigned int i = 0; - - ctx.head = NULL; - ctx.tail = NULL; - if (NULL != get_path) - { - while (i < get_path_length) - { - struct GetPath *element; - element = GNUNET_new (struct GetPath); - element->next = NULL; - element->prev = NULL; - element->peer = get_path[i]; - GNUNET_CONTAINER_DLL_insert_tail (ctx.head, ctx.tail, element); - i++; - } - } - - r = GNUNET_DATACACHE_get (datacache, - key, - type, - &datacache_get_iterator, - &ctx); - DEBUG ("DATACACHE_GET for key %s completed (%d). %u results found.\n", - GNUNET_h2s (key), - ctx.eval, - r); - return ctx.eval; -} - - -/** - * Initialize datacache subsystem. - */ -void -GDS_DATACACHE_init () -{ - datacache = GNUNET_DATACACHE_create (GDS_cfg, "dhtcache"); -} - - -/** - * Shutdown datacache subsystem. - */ -void -GDS_DATACACHE_done () -{ - if (NULL != datacache) - { - GNUNET_DATACACHE_destroy (datacache); - datacache = NULL; - } -} - - -/* end of gnunet-service-xdht_datacache.c */ diff --git a/src/dht/gnunet-service-xdht_datacache.h b/src/dht/gnunet-service-xdht_datacache.h deleted file mode 100644 index f160d03bc..000000000 --- a/src/dht/gnunet-service-xdht_datacache.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2009, 2010, 2011 GNUnet e.V. - - 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 3, 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -/** - * @file dht/gnunet-service-dht_datacache.h - * @brief GNUnet DHT service's datacache integration - * @author Christian Grothoff - * @author Nathan Evans - */ -#ifndef GNUNET_SERVICE_DHT_DATACACHE_H -#define GNUNET_SERVICE_DHT_DATACACHE_H - -#include "gnunet_util_lib.h" -#include "gnunet_block_lib.h" - -/** - * Handle a datum we've received from another peer. Cache if - * possible. - * - * @param expiration when will the reply expire - * @param key the query this reply is for - * @param put_path_length number of peers in 'put_path' - * @param put_path path the reply took on put - * @param type type of the reply - * @param data_size number of bytes in 'data' - * @param data application payload data - */ -void -GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, - const struct GNUNET_HashCode * key, - unsigned int put_path_length, - const struct GNUNET_PeerIdentity *put_path, - enum GNUNET_BLOCK_Type type, size_t data_size, - const void *data); - - -/** - * Handle a GET request we've received from another peer. - * - * @param key the query - * @param type requested data type - * @param xquery extended query - * @param xquery_size number of bytes in xquery - * @param reply_bf where the reply bf is (to be) stored, possibly updated!, can be NULL - * @param reply_bf_mutator mutation value for reply_bf - * @return evaluation result for the local replies - */ -enum GNUNET_BLOCK_EvaluationResult -GDS_DATACACHE_handle_get (const struct GNUNET_HashCode * key, - enum GNUNET_BLOCK_Type type, const void *xquery, - size_t xquery_size, - struct GNUNET_CONTAINER_BloomFilter **reply_bf, - uint32_t reply_bf_mutator, - uint32_t get_path_length, - struct GNUNET_PeerIdentity *get_path, - struct GNUNET_PeerIdentity *next_hop, - struct GNUNET_PeerIdentity *source_peer); - - -/** - * Initialize datacache subsystem. - */ -void -GDS_DATACACHE_init (void); - - -/** - * Shutdown datacache subsystem. - */ -void -GDS_DATACACHE_done (void); - -#endif diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c index 7ab462a58..e3462f618 100644 --- a/src/dht/gnunet-service-xdht_neighbours.c +++ b/src/dht/gnunet-service-xdht_neighbours.c @@ -37,10 +37,9 @@ #include "gnunet_transport_service.h" #include "gnunet_dht_service.h" #include "gnunet_statistics_service.h" -#include "gnunet-service-xdht.h" -#include "gnunet-service-xdht_clients.h" -#include "gnunet-service-xdht_datacache.h" -#include "gnunet-service-xdht_neighbours.h" +#include "gnunet-service-dht.h" +#include "gnunet-service-dht_datacache.h" +#include "gnunet-service-dht_neighbours.h" #include "gnunet-service-xdht_routing.h" #include "dht.h" @@ -1017,7 +1016,7 @@ GDS_NEIGHBOURS_send_trail_setup_result (const struct GNUNET_PeerIdentity *queryi tsrm->finger_identity = *finger; tsrm->is_predecessor = htonl (is_predecessor); tsrm->trail_id = *trail_id; - tsrm->ultimate_destination_finger_value + tsrm->ultimate_destination_finger_value = GNUNET_htonll (ultimate_destination_finger_value); GNUNET_memcpy (&tsrm[1], trail_peer_list, @@ -1114,7 +1113,7 @@ GDS_NEIGHBOURS_send_trail_rejection (const struct GNUNET_PeerIdentity *source_pe trm->congestion_time = congestion_timeout; trm->is_predecessor = htonl (is_predecessor); trm->trail_id = *trail_id; - trm->ultimate_destination_finger_value + trm->ultimate_destination_finger_value = GNUNET_htonll (ultimate_destination_finger_value); GNUNET_memcpy (&trm[1], trail_peer_list, @@ -1957,7 +1956,7 @@ GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key, GNUNET_break (0); return; } - + GNUNET_assert (NULL != (target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, @@ -1989,20 +1988,29 @@ GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key, /** * Handle the put request from the client. * - * @param key Key for the content * @param block_type Type of the block * @param options Routing options * @param desired_replication_level Desired replication count * @param expiration_time When does the content expire + * @param hop_count how many hops has this message traversed so far + * @param bf Bloom filter of peers this PUT has already traversed + * @param key Key for the content + * @param put_path_length number of entries in put_path + * @param put_path peers this request has traversed so far (if tracked) * @param data Content to store * @param data_size Size of content @a data in bytes + * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not */ -void -GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key, - enum GNUNET_BLOCK_Type block_type, +int +GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type block_type, enum GNUNET_DHT_RouteOption options, uint32_t desired_replication_level, struct GNUNET_TIME_Absolute expiration_time, + uint32_t hop_count, + struct GNUNET_CONTAINER_BloomFilter *bf, + const struct GNUNET_HashCode *key, + unsigned int put_path_length, + struct GNUNET_PeerIdentity *put_path, const void *data, size_t data_size) { @@ -2045,7 +2053,7 @@ GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key, key, data, data_size); - return; + return GNUNET_NO; } /* In case we are sending the request to a finger, then send across all of its trail.*/ @@ -2062,6 +2070,7 @@ GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key, expiration_time, data, data_size); + return GNUNET_OK; } @@ -2099,7 +2108,7 @@ GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key, struct GNUNET_MQ_Envelope *env; struct FriendInfo *target_friend; size_t msize; - + msize = get_path_length * sizeof (struct GNUNET_PeerIdentity); if (msize + sizeof (struct PeerGetMessage) >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) @@ -2128,71 +2137,11 @@ GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key, } -/** - * Handle the get request from the client file. If I am destination do - * datacache put and return. Else find the target friend and forward message - * to it. - * - * @param key Key for the content - * @param block_type Type of the block - * @param options Routing options - * @param desired_replication_level Desired replication count - */ -void -GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key, - enum GNUNET_BLOCK_Type block_type, - enum GNUNET_DHT_RouteOption options, - uint32_t desired_replication_level) -{ - struct Closest_Peer successor; - struct GNUNET_PeerIdentity best_known_dest; - struct GNUNET_HashCode intermediate_trail_id; - uint64_t key_value; - - GNUNET_memcpy (&key_value, - key, - sizeof (uint64_t)); - key_value = GNUNET_ntohll (key_value); - successor = find_local_best_known_next_hop (key_value, - GDS_FINGER_TYPE_NON_PREDECESSOR); - best_known_dest = successor.best_known_destination; - intermediate_trail_id = successor.trail_id; - - /* I am the destination. I have the data. */ - if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, - &best_known_dest)) - { - GDS_DATACACHE_handle_get (key, - block_type, - NULL, - 0, - NULL, - 0, - 1, - &my_identity, - NULL, - &my_identity); - return; - } - - GDS_NEIGHBOURS_send_get (key, - block_type, - options, - desired_replication_level, - &best_known_dest, - &intermediate_trail_id, - &successor.next_hop, - 0, - 1, - &my_identity); -} - - /** * Send the get result to requesting client. * * @param key Key of the requested data. - * @param type Block type + * @param block_type Block type * @param target_peer Next peer to forward the message to. * @param source_peer Peer which has the data for the key. * @param put_path_length Number of peers in @a put_path @@ -2205,7 +2154,7 @@ GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key, */ void GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key, - enum GNUNET_BLOCK_Type type, + enum GNUNET_BLOCK_Type block_type, const struct GNUNET_PeerIdentity *target_peer, const struct GNUNET_PeerIdentity *source_peer, unsigned int put_path_length, @@ -2256,15 +2205,15 @@ GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key, if (0 == current_path_index) { DEBUG ("GET_RESULT TO CLIENT KEY = %s, Peer = %s", - GNUNET_h2s(key), - GNUNET_i2s(&my_identity)); + GNUNET_h2s (key), + GNUNET_i2s (&my_identity)); GDS_CLIENTS_handle_reply (expiration, key, get_path_length, get_path, put_path_length, put_path, - type, + block_type, data_size, data); return; @@ -2297,6 +2246,120 @@ GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key, } +/** + * Handle a result for a GET operation. + * + * @param cls closure + * @param type type of the block + * @param expiration_time when does the content expire + * @param key key for the content + * @param put_path_length number of entries in @a put_path + * @param put_path peers the original PUT traversed (if tracked) + * @param get_path_length number of entries in @a get_path + * @param get_path peers this reply has traversed so far (if tracked) + * @param data payload of the reply + * @param data_size number of bytes in @a data + */ +static void +get_cb (void *cls, + enum GNUNET_BLOCK_Type type, + struct GNUNET_TIME_Absolute expiration_time, + const struct GNUNET_HashCode *key, + unsigned int put_path_length, + const struct GNUNET_PeerIdentity *put_path, + unsigned int get_path_length, + const struct GNUNET_PeerIdentity *get_path, + const void *data, + size_t data_size) +{ + struct GNUNET_PeerIdentity *target_peer = cls; + // FIXME: inline? + GDS_NEIGHBOURS_send_get_result (key, + type, + target_peer, + &my_identity, + put_path_length, + put_path, + 1, + &my_identity, + expiration_time, + data, + data_size); +} + + +/** + * Perform a GET operation. Forwards the given request to other + * peers. Does not lookup the key locally. May do nothing if this is + * the only peer in the network (or if we are the closest peer in the + * network). + * + * @param block_type type of the block + * @param options routing options + * @param desired_replication_level desired replication count + * @param hop_count how many hops did this request traverse so far? + * @param key key for the content + * @param xquery extended query + * @param xquery_size number of bytes in @a xquery + * @param reply_bf bloomfilter to filter duplicates + * @param reply_bf_mutator mutator for @a reply_bf + * @param peer_bf filter for peers not to select (again, updated) + * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not + */ +int +GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type block_type, + enum GNUNET_DHT_RouteOption options, + uint32_t desired_replication_level, + uint32_t hop_count, + const struct GNUNET_HashCode *key, + const void *xquery, size_t xquery_size, + const struct GNUNET_CONTAINER_BloomFilter *reply_bf, + uint32_t reply_bf_mutator, + struct GNUNET_CONTAINER_BloomFilter *peer_bf) +{ + struct Closest_Peer successor; + struct GNUNET_PeerIdentity best_known_dest; + struct GNUNET_HashCode intermediate_trail_id; + uint64_t key_value; + + GNUNET_memcpy (&key_value, + key, + sizeof (uint64_t)); + key_value = GNUNET_ntohll (key_value); + successor = find_local_best_known_next_hop (key_value, + GDS_FINGER_TYPE_NON_PREDECESSOR); + best_known_dest = successor.best_known_destination; + intermediate_trail_id = successor.trail_id; + + /* I am the destination. I have the data. */ + if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, + &best_known_dest)) + { + GDS_DATACACHE_handle_get (key, + block_type, + NULL, + 0, + NULL, + 0, + &get_cb, + NULL); + return GNUNET_NO; + } + + GDS_NEIGHBOURS_send_get (key, + block_type, + options, + desired_replication_level, + &best_known_dest, + &intermediate_trail_id, + &successor.next_hop, + 0, + 1, + &my_identity); + return GNUNET_OK; +} + + /** * Randomly choose one of your friends (which is not congested and have not crossed * trail threshold) from the friend_peermap @@ -3121,7 +3184,7 @@ update_current_search_finger_index (unsigned int finger_table_index) { if (NULL == send_verify_successor_task) { - send_verify_successor_task + send_verify_successor_task = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, NULL); } @@ -3389,7 +3452,7 @@ finger_table_add (const struct GNUNET_PeerIdentity *finger_identity, else select_and_replace_trail (existing_finger, finger_trail, - finger_trail_length, + finger_trail_length, finger_trail_id); } update_current_search_finger_index (finger_table_index); @@ -3425,7 +3488,7 @@ check_dht_p2p_put (void *cls, return GNUNET_OK; } - + /** * Core handler for P2P put messages. * @@ -3435,7 +3498,7 @@ check_dht_p2p_put (void *cls, static void handle_dht_p2p_put (void *cls, const struct PeerPutMessage *put) -{ +{ struct GNUNET_PeerIdentity *put_path; struct GNUNET_PeerIdentity current_best_known_dest; struct GNUNET_PeerIdentity best_known_dest; @@ -3623,7 +3686,7 @@ handle_dht_p2p_put (void *cls, * @return #GNUNET_OK if @a get is well-formed */ static int -check_dht_p2p_get (void *cls, +check_dht_p2p_get (void *cls, const struct PeerGetMessage *get) { uint32_t get_length; @@ -3653,7 +3716,7 @@ check_dht_p2p_get (void *cls, * @param get the message */ static void -handle_dht_p2p_get (void *cls, +handle_dht_p2p_get (void *cls, const struct PeerGetMessage *get) { const struct GNUNET_PeerIdentity *get_path; @@ -3744,10 +3807,8 @@ handle_dht_p2p_get (void *cls, 0, NULL, 0, - 1, - &my_identity, - NULL, - &my_identity); + &get_cb, + NULL); } else { @@ -3757,10 +3818,8 @@ handle_dht_p2p_get (void *cls, 0, NULL, 0, - get_length, - gp, - &gp[get_length - 2], - &my_identity); + &get_cb, + &gp[get_length - 2]); } } else @@ -3822,7 +3881,7 @@ check_dht_p2p_get_result (void *cls, static void handle_dht_p2p_get_result (void *cls, const struct PeerGetResultMessage *get_result) -{ +{ const struct GNUNET_PeerIdentity *get_path; const struct GNUNET_PeerIdentity *put_path; const void *payload; @@ -3965,7 +4024,7 @@ get_local_best_known_next_hop (uint64_t final_dest_finger_val, * @return #GNUNET_OK if @a trail_setup is well-formed */ static int -check_dht_p2p_trail_setup (void *cls, +check_dht_p2p_trail_setup (void *cls, const struct PeerTrailSetupMessage *trail_setup) { size_t msize; @@ -3988,7 +4047,7 @@ check_dht_p2p_trail_setup (void *cls, * @param trail_setup the message */ static void -handle_dht_p2p_trail_setup (void *cls, +handle_dht_p2p_trail_setup (void *cls, const struct PeerTrailSetupMessage *trail_setup) { struct FriendInfo *friend = cls; @@ -4014,7 +4073,7 @@ handle_dht_p2p_trail_setup (void *cls, trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_setup[1]; current_dest = trail_setup->best_known_destination; trail_id = trail_setup->trail_id; - final_dest_finger_val + final_dest_finger_val = GNUNET_ntohll (trail_setup->final_destination_finger_value); source = trail_setup->source_peer; is_predecessor = ntohl (trail_setup->is_predecessor); @@ -4024,7 +4083,7 @@ handle_dht_p2p_trail_setup (void *cls, if ( (trail_length > 0) && (0 != memcmp (&trail_peer_list[trail_length-1], friend->id, - sizeof (struct GNUNET_PeerIdentity))) ) + sizeof (struct GNUNET_PeerIdentity))) ) { GNUNET_break_op (0); return; @@ -4052,7 +4111,7 @@ handle_dht_p2p_trail_setup (void *cls, /* Is my routing table full? */ if (GNUNET_YES == GDS_ROUTING_threshold_reached ()) { - target_friend + target_friend = (trail_length > 0) ? GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail_peer_list[trail_length - 1]) @@ -4077,7 +4136,7 @@ handle_dht_p2p_trail_setup (void *cls, } /* Get the next hop to forward the trail setup request. */ - struct Closest_Peer next_peer + struct Closest_Peer next_peer = get_local_best_known_next_hop (final_dest_finger_val, &intermediate_trail_id, is_predecessor, @@ -4100,7 +4159,7 @@ handle_dht_p2p_trail_setup (void *cls, return; } - target_friend + target_friend = (trail_length > 0) ? GNUNET_CONTAINER_multipeermap_get (friend_peermap, &trail_peer_list[trail_length-1]) @@ -4139,7 +4198,7 @@ handle_dht_p2p_trail_setup (void *cls, { /* Add yourself to list of peers. */ struct GNUNET_PeerIdentity peer_list[trail_length + 1]; - + GNUNET_memcpy (peer_list, trail_peer_list, trail_length * sizeof (struct GNUNET_PeerIdentity)); @@ -4175,7 +4234,7 @@ handle_dht_p2p_trail_setup (void *cls, * @return #GNUNET_OK if @a trail_result is well-formed */ static int -check_dht_p2p_trail_setup_result (void *cls, +check_dht_p2p_trail_setup_result (void *cls, const struct PeerTrailSetupResultMessage *trail_result) { size_t msize; @@ -4189,7 +4248,7 @@ check_dht_p2p_trail_setup_result (void *cls, } return GNUNET_OK; } - + /** * Core handle for p2p trail setup result messages. @@ -4198,7 +4257,7 @@ check_dht_p2p_trail_setup_result (void *cls, * @param trail_result the message */ static void -handle_dht_p2p_trail_setup_result (void *cls, +handle_dht_p2p_trail_setup_result (void *cls, const struct PeerTrailSetupResultMessage *trail_result) { struct FriendInfo *friend = cls; @@ -4228,7 +4287,7 @@ handle_dht_p2p_trail_setup_result (void *cls, finger_identity = trail_result->finger_identity; trail_id = trail_result->trail_id; trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_result[1]; - ultimate_destination_finger_value + ultimate_destination_finger_value = GNUNET_ntohll (trail_result->ultimate_destination_finger_value); /* Am I the one who initiated the query? */ @@ -4314,7 +4373,7 @@ handle_dht_p2p_trail_setup_result (void *cls, GDS_NEIGHBOURS_send_trail_setup_result (&querying_peer, &finger_identity, target_friend, - trail_length, + trail_length, trail_peer_list, is_predecessor, ultimate_destination_finger_value, @@ -4569,7 +4628,7 @@ get_trail_src_to_curr_pred (struct GNUNET_PeerIdentity source_peer, *trail_src_to_curr_pred_length = trail_me_to_curr_pred_length - i; trail_src_to_curr_pred = GNUNET_new_array (*trail_src_to_curr_pred_length, struct GNUNET_PeerIdentity); - + for (j = 0; j < *trail_src_to_curr_pred_length; i++,j++) trail_src_to_curr_pred[j] = trail_me_to_curr_pred[i]; @@ -4821,7 +4880,7 @@ handle_dht_p2p_verify_successor (void *cls, if (0 != (GNUNET_CRYPTO_cmp_peer_identity (¤t_predecessor.finger_identity, &source_peer))) { - trail_src_to_curr_pred + trail_src_to_curr_pred = get_trail_src_to_curr_pred (source_peer, trail, trail_length, @@ -4832,7 +4891,7 @@ handle_dht_p2p_verify_successor (void *cls, trail_src_to_curr_pred_len = trail_length; trail_src_to_curr_pred = GNUNET_new_array (trail_src_to_curr_pred_len, struct GNUNET_PeerIdentity); - + for (unsigned int i = 0; i < trail_src_to_curr_pred_len; i++) { trail_src_to_curr_pred[i] = trail[i]; @@ -5175,7 +5234,7 @@ check_dht_p2p_verify_successor_result (void *cls, static void handle_dht_p2p_verify_successor_result (void *cls, const struct PeerVerifySuccessorResultMessage *vsrm) -{ +{ enum GDS_ROUTING_trail_direction trail_direction; struct GNUNET_PeerIdentity querying_peer; struct GNUNET_HashCode trail_id; @@ -5211,7 +5270,7 @@ handle_dht_p2p_verify_successor_result (void *cls, if (NULL != send_verify_successor_retry_task) { struct VerifySuccessorContext *ctx; - + ctx = GNUNET_SCHEDULER_cancel (send_verify_successor_retry_task); GNUNET_free (ctx); send_verify_successor_retry_task = NULL; @@ -5277,7 +5336,7 @@ check_dht_p2p_notify_new_successor (void *cls, return GNUNET_OK; } - + /** * Core handle for p2p notify new successor messages. * @@ -5387,7 +5446,7 @@ handle_dht_p2p_notify_succ_confirmation (void *cls, struct GNUNET_HashCode trail_id; struct FriendInfo *target_friend; const struct GNUNET_PeerIdentity *next_hop; - + GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# Bytes received from other peers"), ntohs (notify_confirmation->header.size), @@ -5431,7 +5490,7 @@ handle_dht_p2p_notify_succ_confirmation (void *cls, DHT_SEND_VERIFY_SUCCESSOR_INTERVAL.rel_value_us + GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, DHT_SEND_VERIFY_SUCCESSOR_INTERVAL.rel_value_us); - send_verify_successor_task + send_verify_successor_task = GNUNET_SCHEDULER_add_delayed(verify_successor_next_send_time, &send_verify_successor_message, NULL); @@ -5476,7 +5535,7 @@ check_dht_p2p_trail_setup_rejection (void *cls, } return GNUNET_OK; } - + /** * Core handler for P2P trail rejection message @@ -5487,7 +5546,7 @@ check_dht_p2p_trail_setup_rejection (void *cls, static void handle_dht_p2p_trail_setup_rejection (void *cls, const struct PeerTrailRejectionMessage *trail_rejection) -{ +{ struct FriendInfo *friend = cls; unsigned int trail_length; const struct GNUNET_PeerIdentity *trail_peer_list; @@ -5514,7 +5573,7 @@ handle_dht_p2p_trail_setup_rejection (void *cls, congestion_timeout = trail_rejection->congestion_time; source = trail_rejection->source_peer; trail_id = trail_rejection->trail_id; - ultimate_destination_finger_value + ultimate_destination_finger_value = GNUNET_ntohll (trail_rejection->ultimate_destination_finger_value); /* First set the congestion time of the friend that sent you this message. */ target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, @@ -5525,7 +5584,7 @@ handle_dht_p2p_trail_setup_rejection (void *cls, GNUNET_break(0); return; } - target_friend->congestion_timestamp + target_friend->congestion_timestamp = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), congestion_timeout); @@ -5549,7 +5608,7 @@ handle_dht_p2p_trail_setup_rejection (void *cls, else next_peer = trail[new_trail_length-1]; - target_friend + target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, &next_peer); if (NULL == target_friend) @@ -5640,7 +5699,7 @@ handle_dht_p2p_trail_setup_rejection (void *cls, * @param trail_teardown the message */ static void -handle_dht_p2p_trail_teardown (void *cls, +handle_dht_p2p_trail_teardown (void *cls, const struct PeerTrailTearDownMessage *trail_teardown) { enum GDS_ROUTING_trail_direction trail_direction; @@ -5707,7 +5766,7 @@ handle_dht_p2p_trail_teardown (void *cls, * @return #GNUNET_OK if @a add_trail is well-formed */ static int -check_dht_p2p_add_trail (void *cls, +check_dht_p2p_add_trail (void *cls, const struct PeerAddTrailMessage *add_trail) { size_t msize; @@ -5730,9 +5789,9 @@ check_dht_p2p_add_trail (void *cls, * @param add_trail the message */ static void -handle_dht_p2p_add_trail (void *cls, +handle_dht_p2p_add_trail (void *cls, const struct PeerAddTrailMessage *add_trail) -{ +{ struct FriendInfo *friend = cls; const struct GNUNET_PeerIdentity *trail; struct GNUNET_HashCode trail_id; @@ -6183,7 +6242,7 @@ GDS_NEIGHBOURS_done (void) if (NULL != send_notify_new_successor_retry_task) { struct SendNotifyContext *notify_ctx; - + notify_ctx = GNUNET_SCHEDULER_cancel (send_notify_new_successor_retry_task); GNUNET_free (notify_ctx->successor_trail); GNUNET_free (notify_ctx); @@ -6197,10 +6256,10 @@ GDS_NEIGHBOURS_done (void) * * @return my identity */ -struct GNUNET_PeerIdentity -GDS_NEIGHBOURS_get_my_id (void) +struct GNUNET_PeerIdentity * +GDS_NEIGHBOURS_get_id (void) { - return my_identity; + return &my_identity; } /* end of gnunet-service-xdht_neighbours.c */ diff --git a/src/dht/gnunet-service-xdht_neighbours.h b/src/dht/gnunet-service-xdht_neighbours.h index 1df45031d..2fb118448 100644 --- a/src/dht/gnunet-service-xdht_neighbours.h +++ b/src/dht/gnunet-service-xdht_neighbours.h @@ -32,67 +32,6 @@ #include "gnunet_dht_service.h" -/** - * Handle the put request from the client. - * @param key Key for the content - * @param block_type Type of the block - * @param options Routing options - * @param desired_replication_level Desired replication count - * @param expiration_time When does the content expire - * @param data Content to store - * @param data_size Size of content @a data in bytes - */ -void -GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key, - enum GNUNET_BLOCK_Type block_type, - enum GNUNET_DHT_RouteOption options, - uint32_t desired_replication_level, - struct GNUNET_TIME_Absolute expiration_time, - const void *data, size_t data_size); - -/** - * Handle the get request from the client file. If I am destination do - * datacache put and return. Else find the target friend and forward message - * to it. - * @param key Key for the content - * @param block_type Type of the block - * @param options Routing options - * @param desired_replication_level Desired replication count - */ -void -GDS_NEIGHBOURS_handle_get (const struct GNUNET_HashCode *key, - enum GNUNET_BLOCK_Type block_type, - enum GNUNET_DHT_RouteOption options, - uint32_t desired_replication_level); - -/** - * Send the get result to requesting client. - * @param key Key of the requested data. - * @param type Block type - * @param target_peer Next peer to forward the message to. - * @param source_peer Peer which has the data for the key. - * @param put_path_length Number of peers in @a put_path - * @param put_path Path taken to put the data at its stored location. - * @param get_path_length Number of peers in @a get_path - * @param get_path Path taken to reach to the location of the key. - * @param expiration When will this result expire? - * @param data Payload to store - * @param data_size Size of the @a data - */ -void -GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key, - enum GNUNET_BLOCK_Type type, - const struct GNUNET_PeerIdentity *target_peer, - const struct GNUNET_PeerIdentity *source_peer, - unsigned int put_path_length, - const struct GNUNET_PeerIdentity *put_path, - unsigned int get_path_length, - const struct GNUNET_PeerIdentity *get_path, - struct GNUNET_TIME_Absolute expiration, - const void *data, - size_t data_size); - - /** * Construct a trail teardown message and forward it to target friend. * @param trail_id Unique identifier of the trail. @@ -105,29 +44,4 @@ GDS_NEIGHBOURS_send_trail_teardown (const struct GNUNET_HashCode *trail_id, const struct GNUNET_PeerIdentity *peer); -/** - * Initialize neighbours subsystem. - * - * @return #GNUNET_OK on success, - * #GNUNET_SYSERR on error - */ -int -GDS_NEIGHBOURS_init (void); - - -/** - * Shutdown neighbours subsystem. - */ -void -GDS_NEIGHBOURS_done (void); - - -/** - * Get my identity - * - * @return my identity - */ -struct GNUNET_PeerIdentity -GDS_NEIGHBOURS_get_my_id (void); - #endif diff --git a/src/dht/gnunet-service-xdht_nse.c b/src/dht/gnunet-service-xdht_nse.c deleted file mode 100644 index b7d60013a..000000000 --- a/src/dht/gnunet-service-xdht_nse.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2009, 2010, 2011 GNUnet e.V. - - 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 3, 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -/** - * @file dht/gnunet-service-xdht_nse.c - * @brief GNUnet DHT integration with NSE - * @author Christian Grothoff - */ -#include "platform.h" -#include "gnunet_nse_service.h" -#include "gnunet-service-xdht.h" -#include "gnunet-service-xdht_nse.h" - -/** - * log of the current network size estimate, used as the point where - * we switch between random and deterministic routing. Default - * value of 4.0 is used if NSE module is not available (i.e. not - * configured). - */ -static double log_of_network_size_estimate = 4.0; - -/** - * Network size estimation handle. - */ -static struct GNUNET_NSE_Handle *nse; - - -/** - * Callback that is called when network size estimate is updated. - * - * @param cls closure - * @param timestamp time when the estimate was received from the server (or created by the server) - * @param logestimate the log(Base 2) value of the current network size estimate - * @param std_dev standard deviation for the estimate - * - */ -static void -update_network_size_estimate (void *cls, struct GNUNET_TIME_Absolute timestamp, - double logestimate, double std_dev) -{ - GNUNET_STATISTICS_update (GDS_stats, - gettext_noop ("# Network size estimates received"), - 1, GNUNET_NO); - /* do not allow estimates < 0.5 */ - log_of_network_size_estimate = GNUNET_MAX (0.5, logestimate); -} - - -/** - * Return the log of the current network size estimate. - * - * @return log of NSE - */ -double -GDS_NSE_get () -{ - return log_of_network_size_estimate; -} - - -/** - * Initialize NSE subsystem. - */ -void -GDS_NSE_init () -{ - unsigned long long hops; - - if ( (GNUNET_YES == - GNUNET_CONFIGURATION_have_value (GDS_cfg, - "dht", - "FORCE_NSE")) && - (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_number (GDS_cfg, - "dht", - "FORCE_NSE", - &hops)) ) - { - log_of_network_size_estimate = (double) hops; - return; - } - nse = GNUNET_NSE_connect (GDS_cfg, &update_network_size_estimate, NULL); -} - - -/** - * Shutdown NSE subsystem. - */ -void -GDS_NSE_done () -{ - if (NULL != nse) - { - GNUNET_NSE_disconnect (nse); - nse = NULL; - } -} - -/* end of gnunet-service-dht_nse.c */ diff --git a/src/dht/gnunet-service-xdht_nse.h b/src/dht/gnunet-service-xdht_nse.h deleted file mode 100644 index 358c0c4bd..000000000 --- a/src/dht/gnunet-service-xdht_nse.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2011 GNUnet e.V. - - 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 3, 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -/** - * @file dht/gnunet-service-xdht_nse.h - * @brief GNUnet DHT integration with NSE - * @author Christian Grothoff - */ -#ifndef GNUNET_SERVICE_XDHT_NSE_H -#define GNUNET_SERVICE_XDHT_NSE_H - - -/** - * Return the log of the current network size estimate. - * - * @return log of NSE - */ -double -GDS_NSE_get (void); - - -/** - * Initialize NSE subsystem. - */ -void -GDS_NSE_init (void); - - -/** - * Shutdown NSE subsystem. - */ -void -GDS_NSE_done (void); - -#endif diff --git a/src/dht/gnunet-service-xdht_routing.c b/src/dht/gnunet-service-xdht_routing.c index 12b85eb7f..ec7361579 100644 --- a/src/dht/gnunet-service-xdht_routing.c +++ b/src/dht/gnunet-service-xdht_routing.c @@ -24,9 +24,10 @@ * @author Supriti Singh */ #include "platform.h" +#include "gnunet-service-dht_neighbours.h" #include "gnunet-service-xdht_neighbours.h" #include "gnunet-service-xdht_routing.h" -#include "gnunet-service-xdht.h" +#include "gnunet-service-dht.h" /** @@ -207,7 +208,7 @@ remove_matching_trails (void *cls, if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_trail->next_hop, disconnected_peer)) { - my_identity = GDS_NEIGHBOURS_get_my_id (); + my_identity = *GDS_NEIGHBOURS_get_id (); if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &remove_trail->prev_hop)) { @@ -222,7 +223,7 @@ remove_matching_trails (void *cls, if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_trail->prev_hop, disconnected_peer)) { - my_identity = GDS_NEIGHBOURS_get_my_id (); + my_identity = *GDS_NEIGHBOURS_get_id (); if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &remove_trail->next_hop)) @@ -255,7 +256,7 @@ GDS_ROUTING_test_print (void) struct GNUNET_HashCode key_ret; int i; - struct GNUNET_PeerIdentity my_identity = GDS_NEIGHBOURS_get_my_id(); + struct GNUNET_PeerIdentity my_identity = *GDS_NEIGHBOURS_get_id(); print_peer = my_identity; FPRINTF (stderr,_("\nSUPU ***PRINTING ROUTING TABLE ***** of =%s"),GNUNET_i2s(&print_peer)); iter =GNUNET_CONTAINER_multihashmap_iterator_create (routing_table); -- 2.25.1