*/
#define DEBUG_DHT_ROUTING GNUNET_YES
+/**
+ * FIXME: document.
+ */
#define DHT_BLOOM_SIZE 128
+/**
+ * FIXME: document.
+ */
#define DHT_BLOOM_K 6
/**
*/
#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"
#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
{
/**
uint16_t variable;
};
+
/**
* Message which indicates the DHT should cancel outstanding
* requests and discard any state.
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
*/
*/
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
*/
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
/* GNUNET_MessageHeader *enc actual DHT message, copied to end of this dealy do */
};
+
/**
* Generic P2P DHT route message
*/
*/
uint64_t unique_id GNUNET_PACKED;
- /*
+ /**
* Bloomfilter to stop circular routes
*/
char bloomfilter[DHT_BLOOM_SIZE];
*/
uint64_t unique_id GNUNET_PACKED;
- /*
+ /**
* Bloomfilter to stop circular routes
*/
char bloomfilter[DHT_BLOOM_SIZE];
/**
* The type of data to insert.
*/
- size_t type GNUNET_PACKED;
+ uint32_t type GNUNET_PACKED;
/**
* How long should this data persist?
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
char bloomfilter[DHT_BLOOM_SIZE];
};
+
/**
* Message to return data either to the client API
* or to respond to a request received from another
*/
uint32_t type;
- /**
- * The key that was searched for
- */
- //GNUNET_HashCode key;
-
/**
* When does this entry expire?
*/
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)
}
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;
}
*/
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,
/**
* 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;
*
* @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)
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,
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);
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);
}
{
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)
{
}
#endif
}
-
+ GNUNET_CONTAINER_bloomfilter_free (bf);
return results;
}
#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"
* 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.
#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.
*/
*
* @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);