From 6aa05b3843eceb17422cf924acc35b32fd1a8659 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 30 Apr 2015 12:14:42 +0000 Subject: [PATCH] -towards tracking paths and trails via datacache in wdht --- src/dht/gnunet-service-wdht_clients.c | 70 ++++++---- src/dht/gnunet-service-wdht_datacache.c | 18 ++- src/dht/gnunet-service-wdht_datacache.h | 9 +- src/dht/gnunet-service-wdht_neighbours.c | 169 +++++++++++++++++++---- src/dht/gnunet-service-wdht_neighbours.h | 14 +- 5 files changed, 208 insertions(+), 72 deletions(-) diff --git a/src/dht/gnunet-service-wdht_clients.c b/src/dht/gnunet-service-wdht_clients.c index 896920e98..fa43fd350 100644 --- a/src/dht/gnunet-service-wdht_clients.c +++ b/src/dht/gnunet-service-wdht_clients.c @@ -165,7 +165,7 @@ struct ClientQueryRecord size_t xquery_size; /** - * Number of entries in 'seen_replies'. + * Number of entries in @e seen_replies. */ unsigned int seen_replies_count; @@ -281,7 +281,7 @@ process_pending_messages (struct ClientList *client); /** - * Callback called as a result of issuing a GNUNET_SERVER_notify_transmit_ready + * 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. @@ -375,7 +375,7 @@ add_pending_message (struct ClientList *client, /** - * Closure for 'forward_reply' + * Closure for #forward_reply() */ struct ForwardReplyContext { @@ -401,7 +401,7 @@ struct ForwardReplyContext size_t data_size; /** - * Do we need to copy 'pm' because it was already used? + * Do we need to copy @e pm because it was already used? */ int do_copy; @@ -470,14 +470,16 @@ remove_client_records (void *cls, const struct GNUNET_HashCode * key, void *valu * each of the matching clients. With some tricky recycling * of the buffer. * - * @param cls the 'struct ForwardReplyContext' + * @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) +forward_reply (void *cls, + const struct GNUNET_HashCode *key, + void *value) { struct ForwardReplyContext *frc = cls; struct ClientQueryRecord *record = value; @@ -682,6 +684,7 @@ GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, } } + /** * Check if some client is monitoring GET messages and notify * them in that case. @@ -701,7 +704,7 @@ GDS_CLIENTS_process_get (uint32_t options, uint32_t desired_replication_level, unsigned int path_length, const struct GNUNET_PeerIdentity *path, - const struct GNUNET_HashCode * key) + const struct GNUNET_HashCode *key) { struct ClientMonitorRecord *m; struct ClientList **cl; @@ -758,16 +761,16 @@ GDS_CLIENTS_process_get (uint32_t options, * 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 options options, for instance RecordRoute, DemultiplexEverywhere. + * @param type type of data in the request. + * @param hop_count hop count so far. + * @param path_length number of entries in @a 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. + * @param desired_replication_level desired replication level. + * @param exp expiration time of the data. + * @param key key under which @a data is to be stored. + * @param data pointer to the data carried. + * @param size number of bytes in @a data. */ void GDS_CLIENTS_process_put (uint32_t options, @@ -913,7 +916,8 @@ transmit_next_request_task (void *cls, * @param message the actual message received */ static void -handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client, +handle_dht_local_put (void *cls, + struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { const struct GNUNET_DHT_ClientPutMessage *put_msg; @@ -974,7 +978,8 @@ handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client, * @param message the actual message received */ static void -handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client, +handle_dht_local_get (void *cls, + struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { const struct GNUNET_DHT_ClientGetMessage *get; @@ -1041,7 +1046,7 @@ handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client, /** - * Closure for 'find_by_unique_id'. + * Closure for #find_by_unique_id(). */ struct FindByUniqueIdContext { @@ -1050,6 +1055,9 @@ struct FindByUniqueIdContext */ struct ClientQueryRecord *cqr; + /** + * Which ID are we looking for? + */ uint64_t unique_id; }; @@ -1061,8 +1069,8 @@ struct FindByUniqueIdContext * * @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) + * @param value the `struct ClientQueryRecord` + * @return #GNUNET_YES to continue iteration (result not yet found) */ static int find_by_unique_id (void *cls, @@ -1087,7 +1095,8 @@ find_by_unique_id (void *cls, * @param message the actual message received */ static void -handle_dht_local_get_result_seen (void *cls, struct GNUNET_SERVER_Client *client, +handle_dht_local_get_result_seen (void *cls, + struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { const struct GNUNET_DHT_ClientGetResultSeenMessage *seen; @@ -1138,7 +1147,7 @@ handle_dht_local_get_result_seen (void *cls, struct GNUNET_SERVER_Client *client /** - * Closure for 'remove_by_unique_id'. + * Closure for #remove_by_unique_id(). */ struct RemoveByUniqueIdContext { @@ -1164,7 +1173,9 @@ struct RemoveByUniqueIdContext * @return #GNUNET_YES (we should continue to iterate) */ static int -remove_by_unique_id (void *cls, const struct GNUNET_HashCode * key, void *value) +remove_by_unique_id (void *cls, + const struct GNUNET_HashCode *key, + void *value) { const struct RemoveByUniqueIdContext *ctx = cls; struct ClientQueryRecord *record = value; @@ -1188,7 +1199,8 @@ remove_by_unique_id (void *cls, const struct GNUNET_HashCode * key, void *value) * */ static void -handle_dht_local_get_stop (void *cls, struct GNUNET_SERVER_Client *client, +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 = @@ -1219,7 +1231,8 @@ handle_dht_local_get_stop (void *cls, struct GNUNET_SERVER_Client *client, * */ static void -handle_dht_local_monitor (void *cls, struct GNUNET_SERVER_Client *client, +handle_dht_local_monitor (void *cls, + struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { struct ClientMonitorRecord *r; @@ -1251,10 +1264,10 @@ handle_dht_local_monitor (void *cls, struct GNUNET_SERVER_Client *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_monitor_stop (void *cls, struct GNUNET_SERVER_Client *client, +handle_dht_local_monitor_stop (void *cls, + struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { struct ClientMonitorRecord *r; @@ -1343,7 +1356,6 @@ handle_client_disconnect (void *cls, } - /** * Initialize client subsystem. * diff --git a/src/dht/gnunet-service-wdht_datacache.c b/src/dht/gnunet-service-wdht_datacache.c index 577aa8699..63b946811 100644 --- a/src/dht/gnunet-service-wdht_datacache.c +++ b/src/dht/gnunet-service-wdht_datacache.c @@ -56,6 +56,8 @@ static struct GNUNET_DATACACHE_Handle *datacache; * @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 @@ -65,11 +67,14 @@ 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) { @@ -82,7 +87,12 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, GNUNET_break (0); return; } - + memcpy (path, + put_path, + put_path_length * sizeof (struct GNUNET_PeerIdentity)); + 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, @@ -90,8 +100,8 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, data, type, expiration, - put_path_length, - put_path); + get_path_length + put_path_length, + path); if (GNUNET_OK == r) GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# ITEMS stored in datacache"), 1, @@ -101,7 +111,7 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, GNUNET_h2s (key), data_size, r, - put_path_length); + put_path_length + get_path_length); } diff --git a/src/dht/gnunet-service-wdht_datacache.h b/src/dht/gnunet-service-wdht_datacache.h index 39edbbb59..f9ea8847d 100644 --- a/src/dht/gnunet-service-wdht_datacache.h +++ b/src/dht/gnunet-service-wdht_datacache.h @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors) + Copyright (C) 2009, 2010, 2011, 2015 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -38,6 +38,8 @@ * @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 @@ -47,7 +49,10 @@ 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, + unsigned int get_path_length, + const struct GNUNET_PeerIdentity *get_path, + enum GNUNET_BLOCK_Type type, + size_t data_size, const void *data); diff --git a/src/dht/gnunet-service-wdht_neighbours.c b/src/dht/gnunet-service-wdht_neighbours.c index fd6c62540..b74f7be39 100644 --- a/src/dht/gnunet-service-wdht_neighbours.c +++ b/src/dht/gnunet-service-wdht_neighbours.c @@ -152,12 +152,24 @@ struct FriendInfo */ struct GNUNET_PeerIdentity id; + /** + * + */ struct Trail *pred_head; + /** + * + */ struct Trail *pred_tail; + /** + * + */ struct Trail *succ_head; + /** + * + */ struct Trail *succ_tail; /** @@ -168,15 +180,30 @@ struct FriendInfo }; +/** + * + */ struct FingerTable; +/** + * + */ struct Finger { + /** + * + */ struct Trail *trail; + /** + * + */ struct FingerTable *ft; + /** + * + */ struct GNUNET_HashCode destination; /** @@ -349,9 +376,14 @@ struct TrailRouteMessage struct GNUNET_MessageHeader header; /** - * Zero, for alignment. + * #GNUNET_YES if the path should be recorded, #GNUNET_NO if not; in NBO. */ - uint32_t reserved GNUNET_PACKED; + uint16_t record_path GNUNET_PACKED; + + /** + * Length of the recorded trail, 0 if @e record_path is #GNUNET_NO; in NBO. + */ + uint16_t path_length GNUNET_PACKED; /** * Unique (random) identifier this peer will use to @@ -359,7 +391,13 @@ struct TrailRouteMessage */ struct GNUNET_HashCode trail_id; - /* followed by payload to send along the trail */ + /** + * Path the message has taken so far (excluding sender). + */ + /* struct GNUNET_PeerIdentity path[path_length]; */ + + /* followed by payload (another `struct GNUNET_MessageHeader`) to + send along the trail */ }; @@ -576,14 +614,24 @@ GDS_NEIGHBOURS_handle_put (const struct GNUNET_HashCode *key, enum GNUNET_DHT_RouteOption options, uint32_t desired_replication_level, struct GNUNET_TIME_Absolute expiration_time, - const void *data, size_t data_size) + const void *data, + size_t data_size) { GDS_DATACACHE_handle_put (expiration_time, key, 0, NULL, + 0, NULL, block_type, data_size, data); + GDS_CLIENTS_process_put (options, + block_type, + 0, 0, + 0, NULL, + expiration_time, + key, + data, + data_size); } @@ -1077,6 +1125,47 @@ handle_dht_p2p_trail_destroy (void *cls, } +/** + * Handler for a message we received along some trail. + * + * @param cls closure + * @param trail_id trail identifier + * @param message the message we got + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +typedef int +(*TrailHandlerCallback)(void *cls, + const struct GNUNET_HashCode *trail_id, + const struct GNUNET_MessageHandler *message); + + +/** + * Definition of a handler for a message received along some trail. + */ +struct TrailHandler +{ + /** + * NULL for end-of-list. + */ + TrailHandlerCallback callback; + + /** + * Closure for @e callback. + */ + void *cls; + + /** + * Message type this handler addresses. + */ + uint16_t message_type; + + /** + * Use 0 for variable-size. + */ + uint16_t message_size; +}; + + /** * Handle a `struct TrailRouteMessage`. * @@ -1087,8 +1176,8 @@ handle_dht_p2p_trail_destroy (void *cls, */ static int handle_dht_p2p_trail_route (void *cls, - const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_MessageHeader *message) + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MessageHeader *message) { const struct TrailRouteMessage *trm; @@ -1100,7 +1189,6 @@ handle_dht_p2p_trail_route (void *cls, * 1.a.1 if trail not finished with us, continue to forward * 1.a.2 otherwise handle body message embedded in trail */ - return GNUNET_OK; } @@ -1110,13 +1198,13 @@ handle_dht_p2p_trail_route (void *cls, * message. * * @param cls closure (NULL) - * @param peer sender identity + * @param trail_id path to the originator * @param message the finger setup message * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ static int handle_dht_p2p_successor_find (void *cls, - const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HashCode *trail_id, const struct GNUNET_MessageHeader *message) { const struct FindSuccessorMessage *fsm; @@ -1125,7 +1213,10 @@ handle_dht_p2p_successor_find (void *cls, // locate trail (for sending reply), if not exists, fail nicely. // otherwise, go to datacache and return 'top k' elements closest to 'key' // as "PUT" messages via the trail (need to extend DB API!) - +#if 0 + GDS_DATACACHE_get_successors (trail_id, + key); +#endif return GNUNET_OK; } @@ -1134,13 +1225,13 @@ handle_dht_p2p_successor_find (void *cls, * Handle a `struct PeerGetMessage`. * * @param cls closure (NULL) - * @param peer sender identity + * @param trail_id path to the originator * @param message the peer get message * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ static int handle_dht_p2p_peer_get (void *cls, - const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HashCode *trail_id, const struct GNUNET_MessageHeader *message) { const struct PeerGetMessage *pgm; @@ -1165,20 +1256,34 @@ handle_dht_p2p_peer_get (void *cls, * Handle a `struct PeerGetResultMessage`. * * @param cls closure (NULL) - * @param peer sender identity + * @param trail_id path to the originator * @param message the peer get result message * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ static int handle_dht_p2p_peer_get_result (void *cls, - const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_MessageHeader *message) + const struct GNUNET_HashCode *trail_id, + const struct GNUNET_MessageHeader *message) { const struct PeerGetResultMessage *pgrm; pgrm = (const struct PeerGetResultMessage *) message; // pretty much: parse, & pass to client (there is some call for that...) +#if 0 + GDS_CLIENTS_process_get (options, + type, + 0, 0, + path_length, path, + key); + (void) GDS_DATACACHE_handle_get (trail_id, + key, + type, + xquery, + xquery_size, + &reply_bf, + reply_bf_mutator); +#endif return GNUNET_OK; } @@ -1187,14 +1292,14 @@ handle_dht_p2p_peer_get_result (void *cls, * Handle a `struct PeerPutMessage`. * * @param cls closure (NULL) - * @param peer sender identity + * @param trail_id path to the originator * @param message the peer put message * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ static int handle_dht_p2p_peer_put (void *cls, - const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_MessageHeader *message) + const struct GNUNET_HashCode *trail_id, + const struct GNUNET_MessageHeader *message) { const struct PeerGetResultMessage *pgrm; @@ -1206,6 +1311,22 @@ handle_dht_p2p_peer_put (void *cls, * 2 use the API to add the value in the "database". Check on the xdht file, how to do it. * 3 Did i a have to return a notification or did i have to return GNUNET_[OK|SYSERR]? */ +#if 0 + GDS_DATACACHE_handle_put (expiration_time, + key, + path_length, path, + block_type, + data_size, + data); + GDS_CLIENTS_process_put (options, + block_type, + 0, 0, + path_length, path, + expiration_time, + key, + data, + data_size); +#endif return GNUNET_OK; } @@ -1230,18 +1351,6 @@ GDS_NEIGHBOURS_init (void) { &handle_dht_p2p_trail_route, GNUNET_MESSAGE_TYPE_WDHT_TRAIL_ROUTE, 0}, - { &handle_dht_p2p_successor_find, - GNUNET_MESSAGE_TYPE_WDHT_SUCCESSOR_FIND, - sizeof (struct FindSuccessorMessage) }, - { &handle_dht_p2p_peer_get, - GNUNET_MESSAGE_TYPE_WDHT_GET, - sizeof (struct PeerGetMessage) }, - { &handle_dht_p2p_peer_get_result, - GNUNET_MESSAGE_TYPE_WDHT_GET_RESULT, - 0}, - { &handle_dht_p2p_peer_put, - GNUNET_MESSAGE_TYPE_WDHT_PUT, - 0}, {NULL, 0, 0} }; diff --git a/src/dht/gnunet-service-wdht_neighbours.h b/src/dht/gnunet-service-wdht_neighbours.h index 4dba04da2..cc6be45a3 100644 --- a/src/dht/gnunet-service-wdht_neighbours.h +++ b/src/dht/gnunet-service-wdht_neighbours.h @@ -72,13 +72,13 @@ 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 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 + * @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 */ void GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *trail_id, -- 2.25.1