From a82188f859826f98b209f265531d1fa63f2b6ae2 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 4 Oct 2010 08:25:28 +0000 Subject: [PATCH] passing bf and xquery from client to service --- src/dht/dht.h | 85 +++++++++++++++++++++++++------- src/dht/dht_api.c | 8 ++- src/dht/dht_api_find_peer.c | 10 ++++ src/dht/dht_api_get_put.c | 51 ++++++++++++++----- src/dht/gnunet-service-dht.c | 66 ++++++++++++++++++++----- src/fs/fs.h | 3 +- src/include/gnunet_dht_service.h | 12 +++++ 7 files changed, 192 insertions(+), 43 deletions(-) diff --git a/src/dht/dht.h b/src/dht/dht.h index 237b91f64..63e95e113 100644 --- a/src/dht/dht.h +++ b/src/dht/dht.h @@ -34,8 +34,14 @@ */ #define DEBUG_DHT_ROUTING GNUNET_YES +/** + * FIXME: document. + */ #define DHT_BLOOM_SIZE 128 +/** + * FIXME: document. + */ #define DHT_BLOOM_K 6 /** @@ -48,12 +54,24 @@ */ #define DHT_FORWARD_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5) +/** + * FIXME: document. + */ #define DEFAULT_DHT_REPUBLISH_FREQUENCY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 60) +/** + * FIXME: document. + */ #define DHT_SEND_PRIORITY 4 +/** + * FIXME: document. + */ #define DEFAULT_GET_REPLICATION 5 +/** + * FIXME: document. + */ #define DEFAULT_PUT_REPLICATION 8 #define STAT_ROUTES "# DHT ROUTE Requests Seen" @@ -79,9 +97,18 @@ #define STAT_DUPLICATE_UID "# Duplicate UID's encountered (bad if any!)" #define STAT_RECENT_SEEN "# recent requests seen again (routing loops, alternate paths)" + +/** + * FIXME: document. + */ typedef void (*GNUNET_DHT_MessageReceivedHandler) (void *cls, const struct GNUNET_MessageHeader *msg); + + +/** + * FIXME: document. + */ struct GNUNET_DHT_ControlMessage { /** @@ -100,6 +127,7 @@ struct GNUNET_DHT_ControlMessage uint16_t variable; }; + /** * Message which indicates the DHT should cancel outstanding * requests and discard any state. @@ -142,10 +170,20 @@ struct GNUNET_DHT_RouteMessage struct GNUNET_MessageHeader header; /** - * Message options + * Message options, actually an 'enum GNUNET_DHT_RouteOption' value. */ uint32_t options GNUNET_PACKED; + /** + * Replication level for this message + */ + uint32_t desired_replication_level GNUNET_PACKED; + + /** + * For alignment, always zero. + */ + uint32_t reserved GNUNET_PACKED; + /** * The key to search for */ @@ -157,16 +195,12 @@ struct GNUNET_DHT_RouteMessage */ uint64_t unique_id GNUNET_PACKED; - /** - * Replication level for this message - */ - uint32_t desired_replication_level GNUNET_PACKED; - /* GNUNET_MessageHeader *enc actual DHT message, copied to end of this dealy do */ }; + /** * Generic local route result message */ @@ -178,9 +212,9 @@ struct GNUNET_DHT_RouteResultMessage struct GNUNET_MessageHeader header; /** - * Message options + * For alignment, always zero. */ - uint32_t options GNUNET_PACKED; + uint32_t reserved GNUNET_PACKED; /** * Unique ID identifying this request (necessary for @@ -196,6 +230,7 @@ struct GNUNET_DHT_RouteResultMessage /* GNUNET_MessageHeader *enc actual DHT message, copied to end of this dealy do */ }; + /** * Generic P2P DHT route message */ @@ -231,7 +266,7 @@ struct GNUNET_DHT_P2PRouteMessage */ uint64_t unique_id GNUNET_PACKED; - /* + /** * Bloomfilter to stop circular routes */ char bloomfilter[DHT_BLOOM_SIZE]; @@ -277,7 +312,7 @@ struct GNUNET_DHT_P2PRouteResultMessage */ uint64_t unique_id GNUNET_PACKED; - /* + /** * Bloomfilter to stop circular routes */ char bloomfilter[DHT_BLOOM_SIZE]; @@ -313,7 +348,7 @@ struct GNUNET_DHT_PutMessage /** * The type of data to insert. */ - size_t type GNUNET_PACKED; + uint32_t type GNUNET_PACKED; /** * How long should this data persist? @@ -337,12 +372,32 @@ struct GNUNET_DHT_GetMessage struct GNUNET_MessageHeader header; /** - * The type for the data for the GET request + * The type for the data for the GET request; actually an 'enum + * GNUNET_BLOCK_Type'. */ uint32_t type; + /** + * Mutator used for the bloom filter (0 if no bf is used). + */ + uint32_t bf_mutator; + + /** + * Size of the eXtended query (xquery). + */ + uint16_t xquery_size; + + /** + * Size of the bloom filter. + */ + uint16_t bf_size; + + /* Followed by the xquery which has 'xquery_size' bytes */ + + /* Followed by the bloom filter (after xquery) with 'bf_size' bytes */ }; + /** * Generic DHT message, indicates that a route request * should be issued, if coming from a client. Shared @@ -361,6 +416,7 @@ struct GNUNET_DHT_FindPeerMessage char bloomfilter[DHT_BLOOM_SIZE]; }; + /** * Message to return data either to the client API * or to respond to a request received from another @@ -378,11 +434,6 @@ struct GNUNET_DHT_GetResultMessage */ uint32_t type; - /** - * The key that was searched for - */ - //GNUNET_HashCode key; - /** * When does this entry expire? */ diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c index 5abc228a3..0dd40a735 100644 --- a/src/dht/dht_api.c +++ b/src/dht/dht_api.c @@ -398,6 +398,8 @@ process_reply (void *cls, const struct GNUNET_MessageHeader *enc_msg; size_t enc_size; uint64_t uid; + const struct GNUNET_PeerIdentity *const*get_path; + const struct GNUNET_PeerIdentity *const*put_path; uid = GNUNET_ntohll (dht_msg->unique_id); if (uid != rh->uid) @@ -420,8 +422,12 @@ process_reply (void *cls, } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing reply.\n"); + get_path = NULL; // FIXME: parse path info! + put_path = NULL; // FIXME: parse path info! rh->iter (rh->iter_cls, &rh->key, + get_path, + put_path, enc_msg); return GNUNET_YES; } @@ -613,7 +619,7 @@ timeout_route_request (void *cls, */ struct GNUNET_DHT_RouteHandle * GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle, - const GNUNET_HashCode * key, + const GNUNET_HashCode *key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, const struct GNUNET_MessageHeader *enc, diff --git a/src/dht/dht_api_find_peer.c b/src/dht/dht_api_find_peer.c index fb27820ad..cd3bed5ba 100644 --- a/src/dht/dht_api_find_peer.c +++ b/src/dht/dht_api_find_peer.c @@ -62,10 +62,20 @@ struct GNUNET_DHT_FindPeerHandle /** * Iterator called on each result obtained from a generic route * operation + * + * @param cls closure + * @param key key that was used + * @param get_path NULL-terminated array of pointers + * to the peers on reverse GET path (or NULL if not recorded) + * @param put_path NULL-terminated array of pointers + * to the peers on the PUT path (or NULL if not recorded) + * @param reply response */ static void find_peer_reply_iterator (void *cls, const GNUNET_HashCode *key, + const struct GNUNET_PeerIdentity * const *get_path, + const struct GNUNET_PeerIdentity * const *put_path, const struct GNUNET_MessageHeader *reply) { struct GNUNET_DHT_FindPeerHandle *find_peer_handle = cls; diff --git a/src/dht/dht_api_get_put.c b/src/dht/dht_api_get_put.c index b1b80b01e..d0e40ca70 100644 --- a/src/dht/dht_api_get_put.c +++ b/src/dht/dht_api_get_put.c @@ -121,17 +121,21 @@ struct GNUNET_DHT_GetHandle * * @param cls the 'struct GNUNET_DHT_GetHandle' * @param key key that was used + * @param get_path NULL-terminated array of pointers + * to the peers on reverse GET path (or NULL if not recorded) + * @param put_path NULL-terminated array of pointers + * to the peers on the PUT path (or NULL if not recorded) * @param reply response */ static void get_reply_iterator (void *cls, const GNUNET_HashCode *key, + const struct GNUNET_PeerIdentity * const *get_path, + const struct GNUNET_PeerIdentity * const *put_path, const struct GNUNET_MessageHeader *reply) { struct GNUNET_DHT_GetHandle *get_handle = cls; const struct GNUNET_DHT_GetResultMessage *result; - const struct GNUNET_PeerIdentity *const*get_path; - const struct GNUNET_PeerIdentity *const*put_path; size_t payload; if (ntohs (reply->type) != GNUNET_MESSAGE_TYPE_DHT_GET_RESULT) @@ -144,9 +148,6 @@ get_reply_iterator (void *cls, sizeof (struct GNUNET_DHT_GetResultMessage)); result = (const struct GNUNET_DHT_GetResultMessage *) reply; payload = ntohs (reply->size) - sizeof(struct GNUNET_DHT_GetResultMessage); - get_path = NULL; // FIXME: parse path info! - put_path = NULL; // FIXME: parse path info! - get_handle->iter (get_handle->iter_cls, GNUNET_TIME_absolute_ntoh (result->expiration), key, @@ -191,25 +192,49 @@ GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle, void *iter_cls) { struct GNUNET_DHT_GetHandle *get_handle; - struct GNUNET_DHT_GetMessage get_msg; - - /* FIXME: transmit bf, mutator, xquery & xquery_size as well... */ + char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; + struct GNUNET_DHT_GetMessage *get_msg; + size_t bf_size; + + bf_size = GNUNET_CONTAINER_bloomfilter_get_size (bf); + if ( (sizeof (buf) <= + sizeof (struct GNUNET_DHT_GetMessage) + xquery_size + bf_size) || + (sizeof (buf) <= bf_size)) + { + GNUNET_break (0); + return NULL; + } get_handle = GNUNET_malloc (sizeof (struct GNUNET_DHT_GetHandle)); get_handle->iter = iter; get_handle->iter_cls = iter_cls; - get_msg.header.type = htons (GNUNET_MESSAGE_TYPE_DHT_GET); - get_msg.header.size = htons (sizeof (struct GNUNET_DHT_GetMessage)); - get_msg.type = htons (type); + get_msg = (struct GNUNET_DHT_GetMessage*) buf; + get_msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_GET); + get_msg->header.size = htons (sizeof (struct GNUNET_DHT_GetMessage) + + xquery_size + + bf_size); + get_msg->type = htons ((uint32_t) type); + get_msg->bf_mutator = bf_mutator; + get_msg->xquery_size = htons ((uint16_t) xquery_size); + get_msg->bf_size = htons (bf_size); + if (xquery != NULL) + memcpy (&buf[sizeof(struct GNUNET_DHT_GetMessage)], + xquery, + xquery_size); + else + GNUNET_assert (xquery_size == 0); + (void) GNUNET_CONTAINER_bloomfilter_get_raw_data (bf, + &buf[sizeof(struct GNUNET_DHT_GetMessage) + xquery_size], + bf_size); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting route for %u byte `%s' message\n", - (unsigned int) sizeof (struct GNUNET_DHT_GetMessage), + (unsigned int) (sizeof (struct GNUNET_DHT_GetMessage) + xquery_size + bf_size) , "GET"); get_handle->route_handle = GNUNET_DHT_route_start (handle, key, DEFAULT_GET_REPLICATION, options, - &get_msg.header, + &get_msg->header, timeout, &get_reply_iterator, get_handle, NULL, NULL); diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c index b97f56893..c03e0b1ac 100644 --- a/src/dht/gnunet-service-dht.c +++ b/src/dht/gnunet-service-dht.c @@ -1877,16 +1877,15 @@ send_reply_to_client (struct ClientList *client, GNUNET_break_op (0); return; } - pending_message = GNUNET_malloc (sizeof (struct PendingMessage) + tsize); pending_message->msg = (struct GNUNET_MessageHeader *)&pending_message[1]; reply = (struct GNUNET_DHT_RouteResultMessage *)&pending_message[1]; reply->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_LOCAL_ROUTE_RESULT); reply->header.size = htons (tsize); + reply->reserved = 0; reply->unique_id = GNUNET_htonll (uid); reply->key = *key; memcpy (&reply[1], message, msize); - add_pending_message (client, pending_message); } @@ -2156,31 +2155,76 @@ handle_dht_get (void *cls, { const struct GNUNET_DHT_GetMessage *get_msg; uint16_t get_type; + uint16_t bf_size; + uint16_t msize; + uint16_t xquery_size; unsigned int results; + struct GNUNET_CONTAINER_BloomFilter *bf; + const void *xquery; + const char *end; + msize = ntohs (msg->size); + if (msize < sizeof (struct GNUNET_DHT_GetMessage)) + { + GNUNET_break (0); + return 0; + } get_msg = (const struct GNUNET_DHT_GetMessage *) msg; - if (ntohs (get_msg->header.size) != sizeof (struct GNUNET_DHT_GetMessage)) + bf_size = ntohs (get_msg->bf_size); + xquery_size = ntohs (get_msg->xquery_size); + if (msize != sizeof (struct GNUNET_DHT_GetMessage) + bf_size + xquery_size) { GNUNET_break (0); return 0; } + end = (const char*) &get_msg[1]; + if (xquery_size == 0) + { + xquery = NULL; + } + else + { + xquery = (const void*) end; + end += xquery_size; + } + if (bf_size == 0) + { + bf = NULL; + } + else + { + bf = GNUNET_CONTAINER_bloomfilter_init (end, + bf_size, + GNUNET_DHT_GET_BLOOMFILTER_K); + } get_type = ntohs (get_msg->type); #if DEBUG_DHT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "`%s:%s': Received `%s' request, message type %u, key %s, uid %llu\n", my_short_id, - "DHT", "GET", get_type, GNUNET_h2s (&message_context->key), + "`%s:%s': Received `%s' request, message type %u, key %s, uid %llu\n", + my_short_id, + "DHT", "GET", + get_type, + GNUNET_h2s (&message_context->key), message_context->unique_id); #endif increment_stats(STAT_GETS); results = 0; +#if HAVE_MALICIOUS if (get_type == DHT_MALICIOUS_MESSAGE_TYPE) - return results; - + { + GNUNET_CONTAINER_bloomfilter_free (bf); + return results; + } +#endif + /* FIXME: put xquery / bf into message_context and use + them for processing! */ if (datacache != NULL) - results = - GNUNET_DATACACHE_get (datacache, &message_context->key, get_type, - &datacache_get_iterator, message_context); + results + = GNUNET_DATACACHE_get (datacache, + &message_context->key, get_type, + &datacache_get_iterator, + message_context); if (results >= 1) { @@ -2218,7 +2262,7 @@ handle_dht_get (void *cls, } #endif } - + GNUNET_CONTAINER_bloomfilter_free (bf); return results; } diff --git a/src/fs/fs.h b/src/fs/fs.h index edbde19da..0eba5615c 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h @@ -29,6 +29,7 @@ #include "gnunet_constants.h" #include "gnunet_datastore_service.h" +#include "gnunet_dht_service.h" #include "gnunet_fs_service.h" #include "gnunet_block_lib.h" #include "block_fs.h" @@ -114,7 +115,7 @@ * Number of bits we set per entry in the bloomfilter. * Do not change! */ -#define BLOOMFILTER_K 16 +#define BLOOMFILTER_K GNUNET_DHT_GET_BLOOMFILTER_K /** * Number of availability trials we perform per search result. diff --git a/src/include/gnunet_dht_service.h b/src/include/gnunet_dht_service.h index 00d9851b9..9ad4cc809 100644 --- a/src/include/gnunet_dht_service.h +++ b/src/include/gnunet_dht_service.h @@ -40,6 +40,12 @@ extern "C" #endif +/** + * K-value that must be used for the bloom filter 'GET' + * queries. + */ +#define GNUNET_DHT_GET_BLOOMFILTER_K 16 + /** * Connection to the DHT service. */ @@ -260,10 +266,16 @@ GNUNET_DHT_find_peer_stop (struct GNUNET_DHT_FindPeerHandle *find_peer_handle); * * @param cls closure * @param key key that was used + * @param get_path NULL-terminated array of pointers + * to the peers on reverse GET path (or NULL if not recorded) + * @param put_path NULL-terminated array of pointers + * to the peers on the PUT path (or NULL if not recorded) * @param reply response */ typedef void (*GNUNET_DHT_ReplyProcessor)(void *cls, const GNUNET_HashCode *key, + const struct GNUNET_PeerIdentity * const *get_path, + const struct GNUNET_PeerIdentity * const *put_path, const struct GNUNET_MessageHeader *reply); -- 2.25.1