From 073c4a9ae448041fdc9a0683fed49d55ae61803e Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 9 Mar 2011 19:07:13 +0000 Subject: hxing --- src/fs/Makefile.am | 24 +- src/fs/gnunet-service-fs.h | 28 ++ src/fs/gnunet-service-fs_cp.c | 28 +- src/fs/gnunet-service-fs_cp.h | 13 +- src/fs/gnunet-service-fs_indexing.h | 2 - src/fs/gnunet-service-fs_lc.c | 3 +- src/fs/gnunet-service-fs_lc.h | 2 +- src/fs/gnunet-service-fs_new.c | 555 ++++++++++++++++++++++++++++++++++++ src/fs/gnunet-service-fs_pr.c | 24 +- src/fs/gnunet-service-fs_pr.h | 5 +- src/fs/gnunet-service-fs_push.c | 8 +- src/fs/gnunet-service-fs_push.h | 4 +- src/fs/gnunet-service-fs_put.c | 4 +- src/fs/gnunet-service-fs_put.h | 4 +- 14 files changed, 667 insertions(+), 37 deletions(-) create mode 100644 src/fs/gnunet-service-fs_new.c (limited to 'src') diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am index 5aa3b7f2b..49d424825 100644 --- a/src/fs/Makefile.am +++ b/src/fs/Makefile.am @@ -54,6 +54,7 @@ bin_PROGRAMS = \ gnunet-pseudonym \ gnunet-search \ gnunet-service-fs \ + gnunet-service-fs-new \ gnunet-unindex gnunet_directory_SOURCES = \ @@ -105,8 +106,29 @@ gnunet_search_LDADD = \ gnunet_search_DEPENDENCIES = \ libgnunetfs.la +gnunet_service_fs_new_SOURCES = \ + gnunet-service-fs_new.c gnunet-service-fs.h \ + gnunet-service-fs_cp.c gnunet-service-fs_cp.h \ + gnunet-service-fs_indexing.c gnunet-service-fs_indexing.h \ + gnunet-service-fs_lc.c gnunet-service-fs_lc.h \ + gnunet-service-fs_pe.c gnunet-service-fs_pe.h \ + gnunet-service-fs_pr.c gnunet-service-fs_pr.h \ + gnunet-service-fs_push.c gnunet-service-fs_push.h \ + gnunet-service-fs_put.c gnunet-service-fs_put.h +gnunet_service_fs_new_LDADD = \ + $(top_builddir)/src/fs/libgnunetfs.la \ + $(top_builddir)/src/dht/libgnunetdht.la \ + $(top_builddir)/src/block/libgnunetblock.la \ + $(top_builddir)/src/datastore/libgnunetdatastore.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/core/libgnunetcore.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(GN_LIBINTL) +gnunet_service_fs_new_DEPENDENCIES = \ + libgnunetfs.la + gnunet_service_fs_SOURCES = \ - gnunet-service-fs.c \ + gnunet-service-fs.c gnunet-service-fs.h \ gnunet-service-fs_indexing.c gnunet-service-fs_indexing.h gnunet_service_fs_LDADD = \ $(top_builddir)/src/fs/libgnunetfs.la \ diff --git a/src/fs/gnunet-service-fs.h b/src/fs/gnunet-service-fs.h index d16b1a856..db9de3cb8 100644 --- a/src/fs/gnunet-service-fs.h +++ b/src/fs/gnunet-service-fs.h @@ -33,6 +33,28 @@ #include "gnunet_block_lib.h" #include "fs.h" + +/** + * Should we introduce random latency in processing? Required for proper + * implementation of GAP, but can be disabled for performance evaluation of + * the basic routing algorithm. + * + * Note that with delays enabled, performance can be significantly lower + * (several orders of magnitude in 2-peer test runs); if you want to + * measure throughput of other components, set this to NO. Also, you + * might want to consider changing 'RETRY_PROBABILITY_INV' to 1 for + * a rather wasteful mode of operation (that might still get the highest + * throughput overall). + * + * Performance measurements (for 50 MB file, 2 peers): + * + * - Without delays: 3300 kb/s + * - With delays: 101 kb/s + */ +#define SUPPORT_DELAYS GNUNET_NO + + + /** * A connected peer. */ @@ -98,6 +120,12 @@ extern double GSF_current_priorities; */ extern unsigned int GSF_cover_query_count; +/** + * How many content messages have we received 'recently' that + * have not yet been claimed as cover traffic? + */ +extern unsigned int GSF_cover_content_count; + /** * Our block context. diff --git a/src/fs/gnunet-service-fs_cp.c b/src/fs/gnunet-service-fs_cp.c index 80ca8de9c..407c9f7fe 100644 --- a/src/fs/gnunet-service-fs_cp.c +++ b/src/fs/gnunet-service-fs_cp.c @@ -451,6 +451,19 @@ revive_migration (void *cls, } +/** + * Get a handle for a connected peer. + * + * @param peer peer's identity + */ +struct GSF_ConnectedPeer * +GSF_peer_get_ (const struct GNUNET_PeerIdentity *peer) +{ + return GNUNET_CONTAINER_multihashmap_get (cp_map, + &peer->hashPubKey); +} + + /** * Handle P2P "MIGRATION_STOP" message. * @@ -793,7 +806,7 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other, int32_t priority; int32_t ttl; enum GNUNET_BLOCK_Type type; - + GNUNET_PEER_Id spid; msize = ntohs(message->size); if (msize < sizeof (struct GetMessage)) @@ -891,6 +904,7 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other, namespace = (0 != (bm & GET_MESSAGE_BIT_SKS_NAMESPACE)) ? &opt[bits++] : NULL; target = (0 != (bm & GET_MESSAGE_BIT_TRANSMIT_TO)) ? ((const struct GNUNET_PeerIdentity*) &opt[bits++]) : NULL; options = 0; + spid = 0; if ( (GNUNET_LOAD_get_load (cp->ppd.transmission_delay) > 3 * (1 + priority)) || (GNUNET_LOAD_get_average (cp->ppd.transmission_delay) > GNUNET_CONSTANTS_MAX_CORK_DELAY.rel_value * 2 + GNUNET_LOAD_get_average (GSF_rt_entry_lifetime)) ) @@ -899,6 +913,7 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other, so at best indirect the query */ priority = 0; options |= GSF_PRO_FORWARD_ONLY; + spid = GNUNET_PEER_intern (other); } ttl = bound_ttl (ntohl (gm->ttl), priority); /* decrement ttl (always) */ @@ -972,6 +987,7 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other, 1 /* anonymity */, (uint32_t) priority, ttl, + spid, NULL, 0, /* replies_seen */ &handle_p2p_reply, cp); @@ -1290,7 +1306,9 @@ GSF_peer_disconnect_handler_ (void *cls, cp = GNUNET_CONTAINER_multihashmap_get (cp_map, &peer->hashPubKey); - GNUNET_assert (NULL != cp); + if (NULL == cp) + return; /* must have been disconnect from core with + 'peer' == my_id, ignore */ GNUNET_CONTAINER_multihashmap_remove (cp_map, &peer->hashPubKey, cp); @@ -1553,15 +1571,13 @@ cron_flush_trust (void *cls, /** * Initialize peer management subsystem. - * - * @param cfg configuration to use */ void -GSF_connected_peer_init_ (struct GNUNET_CONFIGURATION_Handle *cfg) +GSF_connected_peer_init_ () { cp_map = GNUNET_CONTAINER_multihashmap_create (128); GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_filename (cfg, + GNUNET_CONFIGURATION_get_value_filename (GSF_cfg, "fs", "TRUST", &trustDirectory)); diff --git a/src/fs/gnunet-service-fs_cp.h b/src/fs/gnunet-service-fs_cp.h index 95b2033db..7b8cf40ab 100644 --- a/src/fs/gnunet-service-fs_cp.h +++ b/src/fs/gnunet-service-fs_cp.h @@ -171,6 +171,15 @@ GSF_peer_connect_handler_ (const struct GNUNET_PeerIdentity *peer, const struct GNUNET_TRANSPORT_ATS_Information *atsi); +/** + * Get a handle for a connected peer. + * + * @param peer peer's identity + */ +struct GSF_ConnectedPeer * +GSF_peer_get_ (const struct GNUNET_PeerIdentity *peer); + + /** * Transmit a message to the given peer as soon as possible. * If the peer disconnects before the transmission can happen, @@ -377,11 +386,9 @@ GSF_iterate_connected_peers_ (GSF_ConnectedPeerIterator it, /** * Initialize peer management subsystem. - * - * @param cfg configuration to use */ void -GSF_connected_peer_init_ (struct GNUNET_CONFIGURATION_Handle *cfg); +GSF_connected_peer_init_ (void); /** diff --git a/src/fs/gnunet-service-fs_indexing.h b/src/fs/gnunet-service-fs_indexing.h index 885e141e2..e606f30b1 100644 --- a/src/fs/gnunet-service-fs_indexing.h +++ b/src/fs/gnunet-service-fs_indexing.h @@ -105,8 +105,6 @@ GNUNET_FS_handle_unindex (void *cls, const struct GNUNET_MessageHeader *message); - - /** * Initialize the indexing submodule. * diff --git a/src/fs/gnunet-service-fs_lc.c b/src/fs/gnunet-service-fs_lc.c index cb57e871f..f284ba0f8 100644 --- a/src/fs/gnunet-service-fs_lc.c +++ b/src/fs/gnunet-service-fs_lc.c @@ -349,6 +349,7 @@ GSF_local_client_start_search_handler_ (struct GNUNET_SERVER_Client *client, ntohl (sm->anonymity_level), 0 /* priority */, 0 /* ttl */, + 0 /* sender PID */, (const GNUNET_HashCode*) &sm[1], sc, &client_response_handler, cr); @@ -445,7 +446,7 @@ GSF_local_client_transmit_ (struct GSF_LocalClient *lc, */ void GSF_client_disconnect_handler_ (void *cls, - const struct GNUNET_SERVER_Client *client) + struct GNUNET_SERVER_Client *client) { struct GSF_LocalClient *pos; struct ClientRequest *cr; diff --git a/src/fs/gnunet-service-fs_lc.h b/src/fs/gnunet-service-fs_lc.h index 35d8a839a..87eb14198 100644 --- a/src/fs/gnunet-service-fs_lc.h +++ b/src/fs/gnunet-service-fs_lc.h @@ -76,7 +76,7 @@ GSF_local_client_transmit_ (struct GSF_LocalClient *lc, */ void GSF_client_disconnect_handler_ (void *cls, - const struct GNUNET_SERVER_Client *client); + struct GNUNET_SERVER_Client *client); #endif diff --git a/src/fs/gnunet-service-fs_new.c b/src/fs/gnunet-service-fs_new.c new file mode 100644 index 000000000..f0a1513c3 --- /dev/null +++ b/src/fs/gnunet-service-fs_new.c @@ -0,0 +1,555 @@ +/* + This file is part of GNUnet. + (C) 2009, 2010 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 + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file fs/gnunet-service-fs.c + * @brief gnunet anonymity protocol implementation + * @author Christian Grothoff + * + * To use: + * - GSF_plan_get_ (!) + * - GSF_plan_size_ (?) + * - GSF_plan_notify_request_done (!) + * - + * + * + */ +#include "platform.h" +#include +#include "gnunet_constants.h" +#include "gnunet_core_service.h" +#include "gnunet_dht_service.h" +#include "gnunet_datastore_service.h" +#include "gnunet_load_lib.h" +#include "gnunet_peer_lib.h" +#include "gnunet_protocols.h" +#include "gnunet_signatures.h" +#include "gnunet_statistics_service.h" +#include "gnunet_transport_service.h" +#include "gnunet_util_lib.h" +#include "gnunet-service-fs_cp.h" +#include "gnunet-service-fs_indexing.h" +#include "gnunet-service-fs_lc.h" +#include "gnunet-service-fs_pe.h" +#include "gnunet-service-fs_pr.h" +#include "gnunet-service-fs_push.h" +#include "gnunet-service-fs_put.h" +#include "fs.h" + +#define DEBUG_FS GNUNET_YES + +/** + * Size for the hash map for DHT requests from the FS + * service. Should be about the number of concurrent + * DHT requests we plan to make. + */ +#define FS_DHT_HT_SIZE 1024 + + +/** + * How quickly do we age cover traffic? At the given + * time interval, remaining cover traffic counters are + * decremented by 1/16th. + */ +#define COVER_AGE_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) + + +/* ****************************** globals ****************************** */ + +/** + * Our connection to the datastore. + */ +struct GNUNET_DATASTORE_Handle *GSF_dsh; + +/** + * Our configuration. + */ +const struct GNUNET_CONFIGURATION_Handle *GSF_cfg; + +/** + * Handle for reporting statistics. + */ +struct GNUNET_STATISTICS_Handle *GSF_stats; + +/** + * Pointer to handle to the core service (points to NULL until we've + * connected to it). + */ +struct GNUNET_CORE_Handle *GSF_core; + +/** + * Handle for DHT operations. + */ +struct GNUNET_DHT_Handle *GSF_dht; + +/** + * How long do requests typically stay in the routing table? + */ +struct GNUNET_LOAD_Value *GSF_rt_entry_lifetime; + +/** + * Typical priorities we're seeing from other peers right now. Since + * most priorities will be zero, this value is the weighted average of + * non-zero priorities seen "recently". In order to ensure that new + * values do not dramatically change the ratio, values are first + * "capped" to a reasonable range (+N of the current value) and then + * averaged into the existing value by a ratio of 1:N. Hence + * receiving the largest possible priority can still only raise our + * "current_priorities" by at most 1. + */ +double GSF_current_priorities; + +/** + * How many query messages have we received 'recently' that + * have not yet been claimed as cover traffic? + */ +unsigned int GSF_cover_query_count; + +/** + * How many content messages have we received 'recently' that + * have not yet been claimed as cover traffic? + */ +unsigned int GSF_cover_content_count; + +/** + * Our block context. + */ +struct GNUNET_BLOCK_Context *GSF_block_ctx; + + +/* ***************************** locals ******************************* */ + +/** + * Configuration for block library. + */ +static struct GNUNET_CONFIGURATION_Handle *block_cfg; + +/** + * ID of our task that we use to age the cover counters. + */ +static GNUNET_SCHEDULER_TaskIdentifier cover_age_task; + +/** + * Pointer to handle to the core service (points to NULL until we've + * connected to it). + */ +static struct GNUNET_CORE_Handle *core; + +/** + * Identity of this peer. + */ +static struct GNUNET_PeerIdentity my_id; + +/** + * Task that periodically ages our cover traffic statistics. + * + * @param cls unused closure + * @param tc task context + */ +static void +age_cover_counters (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GSF_cover_content_count = (GSF_cover_content_count * 15) / 16; + GSF_cover_query_count = (GSF_cover_query_count * 15) / 16; + cover_age_task = GNUNET_SCHEDULER_add_delayed (COVER_AGE_FREQUENCY, + &age_cover_counters, + NULL); +} + + +/** + * Handle P2P "PUT" message. + * + * @param cls closure, always NULL + * @param other the other peer involved (sender or receiver, NULL + * for loopback messages where we are both sender and receiver) + * @param message the actual message + * @param atsi performance information + * @return GNUNET_OK to keep the connection open, + * GNUNET_SYSERR to close it (signal serious error) + */ +static int +handle_p2p_put (void *cls, + const struct GNUNET_PeerIdentity *other, + const struct GNUNET_MessageHeader *message, + const struct GNUNET_TRANSPORT_ATS_Information *atsi) +{ + struct GSF_ConnectedPeer *cp; + + cp = GSF_peer_get_ (other); + if (NULL == cp) + { + GNUNET_break (0); + return GNUNET_OK; + } + return GSF_handle_p2p_content_ (cp, message); +} + + +/** + * Decide with what weight we should forward the given + * request to the given peer. + * + * @param cp target peer + * @param pr request + */ +static void +plan (struct GSF_ConnectedPeer *cp, + struct GSF_PendingRequest *pr) +{ + GNUNET_CONTAINER_HeapCostType weight; + + weight = 0; + /* FIXME: calculate weight properly... */ + GSF_plan_add_ (cp, pr, weight); +} + + +/** + * Handle P2P "GET" request. + * + * @param cls closure, always NULL + * @param other the other peer involved (sender or receiver, NULL + * for loopback messages where we are both sender and receiver) + * @param message the actual message + * @param atsi performance information + * @return GNUNET_OK to keep the connection open, + * GNUNET_SYSERR to close it (signal serious error) + */ +static int +handle_p2p_get (void *cls, + const struct GNUNET_PeerIdentity *other, + const struct GNUNET_MessageHeader *message, + const struct GNUNET_TRANSPORT_ATS_Information *atsi) +{ + struct GSF_PendingRequest *pr; + + pr = GSF_handle_p2p_query_ (other, message); + if (NULL == pr) + return GNUNET_SYSERR; + /* FIXME: local lookup! */ + /* FIXME: after local lookup, trigger forwarding/routing! */ + return GNUNET_OK; +} + + +/** + * We have a new request, consider forwarding it to the given + * peer. + * + * @param cls the 'struct GSF_PendingRequest' + * @param peer identity of the peer + * @param cp handle to the connected peer record + * @param perf peer performance data + */ +static void +consider_request_for_forwarding (void *cls, + const struct GNUNET_PeerIdentity *peer, + struct GSF_ConnectedPeer *cp, + const struct GSF_PeerPerformanceData *ppd) +{ + struct GSF_PendingRequest *pr = cls; + + plan (cp, pr); +} + + +/** + * Handle START_SEARCH-message (search request from client). + * + * @param cls closure + * @param client identification of the client + * @param message the actual message + */ +static void +handle_start_search (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + struct GSF_PendingRequest *pr; + + pr = GSF_local_client_start_search_handler_ (client, message); + if (NULL == pr) + { + /* 'GNUNET_SERVER_receive_done was already called! */ + return; + } + /* FIXME: local lookup, then (after DB done!) receive_done: */ + GNUNET_SERVER_receive_done (client, + GNUNET_OK); +#if 0 + /* FIXME: also do DHT lookup */ + struct GNUNET_DHT_GetHandle *gh; + /* store 'gh' with 'pr', cancel it on pr destruction, etc. */ + gh = GNUNET_DHT_get_start (GSF_dht, + timeout, + type, + key, + des_repl_level, + options, + bf, + bf_mutator, + xquery, + xquery_size, + &GSF_handle_dht_reply_, + pr); +#endif + GSF_iterate_connected_peers_ (&consider_request_for_forwarding, + pr); +} + + +/** + * Task run during shutdown. + * + * @param cls unused + * @param tc unused + */ +static void +shutdown_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (NULL != core) + { + GNUNET_CORE_disconnect (core); + core = NULL; + } + GSF_put_done_ (); + GSF_push_done_ (); + GSF_pending_request_done_ (); + GSF_plan_done (); + GSF_connected_peer_done_ (); + GNUNET_DATASTORE_disconnect (GSF_dsh, GNUNET_NO); + GSF_dsh = NULL; + GNUNET_DHT_disconnect (GSF_dht); + GSF_dht = NULL; + GNUNET_BLOCK_context_destroy (GSF_block_ctx); + GSF_block_ctx = NULL; + GNUNET_CONFIGURATION_destroy (block_cfg); + block_cfg = NULL; + GNUNET_STATISTICS_destroy (GSF_stats, GNUNET_NO); + if (GNUNET_SCHEDULER_NO_TASK != cover_age_task) + { + GNUNET_SCHEDULER_cancel (cover_age_task); + cover_age_task = GNUNET_SCHEDULER_NO_TASK; + } +} + + +/** + * Function called for each pending request whenever a new + * peer connects, giving us a chance to decide about submitting + * the existing request to the new peer. + * + * @param cls the 'struct GSF_ConnectedPeer' of the new peer + * @param key query for the request + * @param pr handle to the pending request + * @return GNUNET_YES to continue to iterate + */ +static int +consider_peer_for_forwarding (void *cls, + const GNUNET_HashCode *key, + struct GSF_PendingRequest *pr) +{ + struct GSF_ConnectedPeer *cp = cls; + + plan (cp, pr); + return GNUNET_YES; +} + + +/** + * Method called whenever a given peer connects. + * + * @param cls closure, not used + * @param peer peer identity this notification is about + * @param atsi performance information + */ +static void +peer_connect_handler (void *cls, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_TRANSPORT_ATS_Information *atsi) +{ + struct GSF_ConnectedPeer *cp; + + if (0 == memcmp (&my_id, peer, sizeof (struct GNUNET_PeerIdentity))) + return; + cp = GSF_peer_connect_handler_ (peer, atsi); + if (NULL == cp) + return; + GSF_iterate_pending_requests_ (&consider_peer_for_forwarding, + cp); +} + + +/** + * Function called after GNUNET_CORE_connect has succeeded + * (or failed for good). Note that the private key of the + * peer is intentionally not exposed here; if you need it, + * your process should try to read the private key file + * directly (which should work if you are authorized...). + * + * @param cls closure + * @param server handle to the server, NULL if we failed + * @param my_identity ID of this peer, NULL if we failed + * @param publicKey public key of this peer, NULL if we failed + */ +static void +peer_init_handler (void *cls, + struct GNUNET_CORE_Handle * server, + const struct GNUNET_PeerIdentity * + my_identity, + const struct + GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded * + publicKey) +{ + my_id = *my_identity; +} + + +/** + * Process fs requests. + * + * @param server the initialized server + * @param c configuration to use + */ +static int +main_init (struct GNUNET_SERVER_Handle *server, + const struct GNUNET_CONFIGURATION_Handle *c) +{ + static const struct GNUNET_CORE_MessageHandler p2p_handlers[] = + { + { &handle_p2p_get, + GNUNET_MESSAGE_TYPE_FS_GET, 0 }, + { &handle_p2p_put, + GNUNET_MESSAGE_TYPE_FS_PUT, 0 }, + { &GSF_handle_p2p_migration_stop_, + GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP, + sizeof (struct MigrationStopMessage) }, + { NULL, 0, 0 } + }; + static const struct GNUNET_SERVER_MessageHandler handlers[] = { + {&GNUNET_FS_handle_index_start, NULL, + GNUNET_MESSAGE_TYPE_FS_INDEX_START, 0}, + {&GNUNET_FS_handle_index_list_get, NULL, + GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET, sizeof(struct GNUNET_MessageHeader) }, + {&GNUNET_FS_handle_unindex, NULL, GNUNET_MESSAGE_TYPE_FS_UNINDEX, + sizeof (struct UnindexMessage) }, + {&handle_start_search, NULL, GNUNET_MESSAGE_TYPE_FS_START_SEARCH, + 0 }, + {NULL, NULL, 0, 0} + }; + + core = GNUNET_CORE_connect (GSF_cfg, + 1, /* larger? */ + NULL, + &peer_init_handler, + &peer_connect_handler, + &GSF_peer_disconnect_handler_, + &GSF_peer_status_handler_, + NULL, GNUNET_NO, + NULL, GNUNET_NO, + p2p_handlers); + if (NULL == core) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to connect to `%s' service.\n"), + "core"); + return GNUNET_SYSERR; + } + GNUNET_SERVER_disconnect_notify (server, + &GSF_client_disconnect_handler_, + NULL); + GNUNET_SERVER_add_handlers (server, handlers); + cover_age_task = GNUNET_SCHEDULER_add_delayed (COVER_AGE_FREQUENCY, + &age_cover_counters, + NULL); + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, + &shutdown_task, + NULL); + return GNUNET_OK; +} + + +/** + * Process fs requests. + * + * @param cls closure + * @param server the initialized server + * @param cfg configuration to use + */ +static void +run (void *cls, + struct GNUNET_SERVER_Handle *server, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + GSF_cfg = cfg; + GSF_dsh = GNUNET_DATASTORE_connect (cfg); + if (GSF_dsh == NULL) + { + GNUNET_SCHEDULER_shutdown (); + return; + } + GSF_stats = GNUNET_STATISTICS_create ("fs", cfg); + block_cfg = GNUNET_CONFIGURATION_create (); + GNUNET_CONFIGURATION_set_value_string (block_cfg, + "block", + "PLUGINS", + "fs"); + GSF_block_ctx = GNUNET_BLOCK_context_create (block_cfg); + GNUNET_assert (NULL != GSF_block_ctx); + GSF_dht = GNUNET_DHT_connect (cfg, + FS_DHT_HT_SIZE); + GSF_plan_init (); + GSF_pending_request_init_ (); + GSF_connected_peer_init_ (); + GSF_push_init_ (); + GSF_put_init_ (); + if ( (GNUNET_OK != GNUNET_FS_indexing_init (cfg, GSF_dsh)) || + + (GNUNET_OK != main_init (server, cfg)) ) + { + GNUNET_SCHEDULER_shutdown (); + shutdown_task (NULL, NULL); + return; + } +} + + +/** + * The main function for the fs 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) +{ + return (GNUNET_OK == + GNUNET_SERVICE_run (argc, + argv, + "fs", + GNUNET_SERVICE_OPTION_NONE, + &run, NULL)) ? 0 : 1; +} + +/* end of gnunet-service-fs.c */ diff --git a/src/fs/gnunet-service-fs_pr.c b/src/fs/gnunet-service-fs_pr.c index 3c291cfc9..45767f204 100644 --- a/src/fs/gnunet-service-fs_pr.c +++ b/src/fs/gnunet-service-fs_pr.c @@ -64,6 +64,12 @@ struct GSF_PendingRequest */ struct GNUNET_CONTAINER_HeapNode *hnode; + /** + * Identity of the peer that we should use for the 'sender' + * (recipient of the response) when forwarding (0 for none). + */ + GNUNET_PEER_Id sender_pid; + /** * Number of valid entries in the 'replies_seen' array. */ @@ -203,6 +209,7 @@ refresh_bloomfilter (struct GSF_PendingRequest *pr) * @param anonymity_level desired anonymity level * @param priority maximum outgoing cummulative request priority to use * @param ttl current time-to-live for the request + * @param sender_pid peer ID to use for the sender when forwarding, 0 for none * @param replies_seen hash codes of known local replies * @param replies_seen_count size of the 'replies_seen' array * @param rh handle to call when we get a reply @@ -221,6 +228,7 @@ GSF_pending_request_create_ (enum GSF_PendingRequestOptions options, uint32_t anonymity_level, uint32_t priority, int32_t ttl, + GNUNET_PEER_Id sender_pid, const GNUNET_HashCode *replies_seen, unsigned int replies_seen_count, GSF_PendingRequestReplyHandler rh, @@ -247,6 +255,7 @@ GSF_pending_request_create_ (enum GSF_PendingRequestOptions options, pr->public_data.options = options; pr->public_data.type = type; pr->public_data.start_time = GNUNET_TIME_absolute_get (); + pr->sender_pid = sender_pid; pr->rh = rh; pr->rh_cls = rh_cls; if (ttl >= 0) @@ -451,14 +460,14 @@ GSF_pending_request_get_message_ (struct GSF_PendingRequest *pr, ext = (GNUNET_HashCode*) &gm[1]; k = 0; if (GNUNET_YES != do_route) - GNUNET_PEER_resolve (pr->cp->pid, + GNUNET_PEER_resolve (pr->sender_pid, (struct GNUNET_PeerIdentity*) &ext[k++]); if (GNUNET_BLOCK_TYPE_FS_SBLOCK == pr->public_data.type) memcpy (&ext[k++], &pr->public_data.namespace, sizeof (GNUNET_HashCode)); if (GNUNET_YES == pr->public_data.has_target) - GNUNET_PEER_resolve (pr->public_data.target_pid, + GNUNET_PEER_resolve (pr->sender_pid, (struct GNUNET_PeerIdentity*) &ext[k++]); if (pr->bf != NULL) GNUNET_CONTAINER_bloomfilter_get_raw_data (pr->bf, @@ -487,6 +496,7 @@ clean_request (void *cls, GNUNET_free_non_null (pr->replies_seen); if (NULL != pr->bf) GNUNET_CONTAINER_bloomfilter_free (pr->bf); + GNUNET_PEER_change_rc (pr->sender_pid, -1); if (NULL != pr->hnode) GNUNET_CONTAINER_heap_remove_node (requests_by_expiration_heap, pr->hnode); @@ -519,8 +529,8 @@ GSF_pending_request_cancel_ (struct GSF_PendingRequest *pr) * @param cls closure for it */ void -GSF_iterate_pending_pr_map_ (GSF_PendingRequestIterator it, - void *cls) +GSF_iterate_pending_requests_ (GSF_PendingRequestIterator it, + void *cls) { GNUNET_CONTAINER_multihashmap_iterate (pr_map, (GNUNET_CONTAINER_HashMapIterator) it, @@ -943,14 +953,12 @@ GSF_handle_p2p_content_ (struct GSF_ConnectedPeer *cp, /** * Setup the subsystem. - * - * @param cfg configuration to use */ void -GSF_pending_request_init_ (struct GNUNET_CONFIGURATION_Handle *cfg) +GSF_pending_request_init_ () { if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (cfg, + GNUNET_CONFIGURATION_get_value_number (GSF_cfg, "fs", "MAX_PENDING_REQUESTS", &max_pending_requests)) diff --git a/src/fs/gnunet-service-fs_pr.h b/src/fs/gnunet-service-fs_pr.h index 4af4f36ee..b59cbc541 100644 --- a/src/fs/gnunet-service-fs_pr.h +++ b/src/fs/gnunet-service-fs_pr.h @@ -178,6 +178,8 @@ typedef void (*GSF_PendingRequestReplyHandler)(void *cls, * @param anonymity_level desired anonymity level * @param priority maximum outgoing cummulative request priority to use * @param ttl current time-to-live for the request + * @param sender_pid peer ID to use for the sender when forwarding, 0 for none; + * reference counter is taken over by this function * @param replies_seen hash codes of known local replies * @param replies_seen_count size of the 'replies_seen' array * @param rh handle to call when we get a reply @@ -196,6 +198,7 @@ GSF_pending_request_create_ (enum GSF_PendingRequestOptions options, uint32_t anonymity_level, uint32_t priority, int32_t ttl, + GNUNET_PEER_Id sender_pid, const GNUNET_HashCode *replies_seen, unsigned int replies_seen_count, GSF_PendingRequestReplyHandler rh, @@ -327,7 +330,7 @@ GSF_handle_dht_reply_ (void *cls, * @param cfg configuration to use */ void -GSF_pending_request_init_ (struct GNUNET_CONFIGURATION_Handle *cfg); +GSF_pending_request_init_ (void); /** diff --git a/src/fs/gnunet-service-fs_push.c b/src/fs/gnunet-service-fs_push.c index c1f520510..1a29b7837 100644 --- a/src/fs/gnunet-service-fs_push.c +++ b/src/fs/gnunet-service-fs_push.c @@ -601,22 +601,20 @@ GSF_push_stop_ (struct GSF_ConnectedPeer *peer) /** * Setup the module. - * - * @param cfg configuration to use */ void -GSF_push_init_ (struct GNUNET_CONFIGURATION_Handle *cfg) +GSF_push_init_ () { int enabled; - enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, + enabled = GNUNET_CONFIGURATION_get_value_yesno (GSF_cfg, "FS", "CONTENT_PUSHING"); if (GNUNET_YES != enabled) return; if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_time (cfg, + GNUNET_CONFIGURATION_get_value_time (GSF_cfg, "fs", "MIN_MIGRATION_DELAY", &min_migration_delay)) diff --git a/src/fs/gnunet-service-fs_push.h b/src/fs/gnunet-service-fs_push.h index 5f7a0030c..7967b04cd 100644 --- a/src/fs/gnunet-service-fs_push.h +++ b/src/fs/gnunet-service-fs_push.h @@ -31,11 +31,9 @@ /** * Setup the module. - * - * @param cfg configuration to use */ void -GSF_push_init_ (struct GNUNET_CONFIGURATION_Handle *cfg); +GSF_push_init_ (void); /** diff --git a/src/fs/gnunet-service-fs_put.c b/src/fs/gnunet-service-fs_put.c index 6afeb4faa..97a7a90b5 100644 --- a/src/fs/gnunet-service-fs_put.c +++ b/src/fs/gnunet-service-fs_put.c @@ -209,11 +209,9 @@ gather_dht_put_blocks (void *cls, /** * Setup the module. - * - * @param cfg configuration to use */ void -GSF_put_init_ (struct GNUNET_CONFIGURATION_Handle *cfg) +GSF_put_init_ () { dht_task = GNUNET_SCHEDULER_add_now (&gather_dht_put_blocks, NULL); } diff --git a/src/fs/gnunet-service-fs_put.h b/src/fs/gnunet-service-fs_put.h index ebec818b2..59b1f83e3 100644 --- a/src/fs/gnunet-service-fs_put.h +++ b/src/fs/gnunet-service-fs_put.h @@ -31,11 +31,9 @@ /** * Setup the module. - * - * @param cfg configuration to use */ void -GSF_put_init_ (struct GNUNET_CONFIGURATION_Handle *cfg); +GSF_put_init_ (void); /** -- cgit v1.2.3