2 This file is part of GNUnet.
3 Copyright (C) 2013, 2017 GNUnet e.V.
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
21 * @file cadet/gnunet-service-cadet-new_dht.c
22 * @brief Information we track per peer.
23 * @author Bartlomiej Polot
24 * @author Christian Grothoff
28 #include "gnunet_util_lib.h"
29 #include "gnunet_dht_service.h"
30 #include "gnunet_statistics_service.h"
31 #include "gnunet-service-cadet-new.h"
32 #include "gnunet-service-cadet-new_dht.h"
33 #include "gnunet-service-cadet-new_hello.h"
34 #include "gnunet-service-cadet-new_peer.h"
35 #include "gnunet-service-cadet-new_paths.h"
37 #define LOG(level, ...) GNUNET_log_from (level,"cadet-dht",__VA_ARGS__)
41 * Handle for DHT searches.
43 struct GCD_search_handle
48 struct GNUNET_DHT_GetHandle *dhtget;
56 static struct GNUNET_DHT_Handle *dht_handle;
59 * How often to PUT own ID in the DHT.
61 static struct GNUNET_TIME_Relative id_announce_time;
64 * DHT replication level, see DHT API: #GNUNET_DHT_get_start(), #GNUNET_DHT_put().
66 static unsigned long long dht_replication_level;
69 * Task to periodically announce itself in the network.
71 static struct GNUNET_SCHEDULER_Task *announce_id_task;
74 * Delay for the next ID announce.
76 static struct GNUNET_TIME_Relative announce_delay;
80 * Function to process paths received for a new peer addition. The recorded
81 * paths form the initial tunnel, which can be optimized later.
82 * Called on each result obtained for the DHT search.
85 * @param exp when will this value expire
86 * @param key key of the result
87 * @param get_path path of the get request
88 * @param get_path_length lenght of @a get_path
89 * @param put_path path of the put request
90 * @param put_path_length length of the @a put_path
91 * @param type type of the result
92 * @param size number of bytes in data
93 * @param data pointer to the result data
96 dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
97 const struct GNUNET_HashCode *key,
98 const struct GNUNET_PeerIdentity *get_path,
99 unsigned int get_path_length,
100 const struct GNUNET_PeerIdentity *put_path,
101 unsigned int put_path_length,
102 enum GNUNET_BLOCK_Type type,
106 const struct GNUNET_HELLO_Message *hello = data;
107 struct CadetPeer *peer;
109 GCPP_try_path_from_dht (get_path,
113 if ( (size >= sizeof (struct GNUNET_HELLO_Message)) &&
114 (ntohs (hello->header.size) == size) &&
115 (size == GNUNET_HELLO_size (hello)) )
117 peer = GCP_get (&put_path[0],
119 LOG (GNUNET_ERROR_TYPE_DEBUG,
120 "Got HELLO for %s\n",
129 * Periodically announce self id in the DHT
134 announce_id (void *cls)
136 struct GNUNET_HashCode phash;
137 const struct GNUNET_HELLO_Message *hello;
139 struct GNUNET_TIME_Absolute expiration;
140 struct GNUNET_TIME_Relative next_put;
142 hello = GCH_get_mine ();
143 size = (NULL != hello) ? GNUNET_HELLO_size (hello) : 0;
146 expiration = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
148 announce_delay = GNUNET_TIME_STD_BACKOFF (announce_delay);
152 expiration = GNUNET_HELLO_get_last_expiration (hello);
153 announce_delay = GNUNET_TIME_UNIT_SECONDS;
156 /* Call again in id_announce_time, unless HELLO expires first,
157 * but wait at least 1s. */
159 = GNUNET_TIME_absolute_get_remaining (expiration);
161 = GNUNET_TIME_relative_min (next_put,
164 = GNUNET_TIME_relative_max (next_put,
165 GNUNET_TIME_UNIT_SECONDS);
167 = GNUNET_SCHEDULER_add_delayed (next_put,
170 GNUNET_STATISTICS_update (stats,
177 GNUNET_memcpy (&phash,
179 sizeof (my_full_id));
180 LOG (GNUNET_ERROR_TYPE_DEBUG,
181 "Announcing my HELLO (%u bytes) in the DHT\n",
183 GNUNET_DHT_put (dht_handle, /* DHT handle */
184 &phash, /* Key to use */
185 dht_replication_level, /* Replication level */
186 GNUNET_DHT_RO_RECORD_ROUTE
187 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, /* DHT options */
188 GNUNET_BLOCK_TYPE_DHT_HELLO, /* Block type */
189 size, /* Size of the data */
190 (const char *) hello, /* Data itself */
191 expiration, /* Data expiration */
192 NULL, /* Continuation */
193 NULL); /* Continuation closure */
198 * Initialize the DHT subsystem.
200 * @param c Configuration.
203 GCD_init (const struct GNUNET_CONFIGURATION_Handle *c)
205 LOG (GNUNET_ERROR_TYPE_DEBUG,
208 GNUNET_CONFIGURATION_get_value_number (c,
210 "DHT_REPLICATION_LEVEL",
211 &dht_replication_level))
213 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
215 "DHT_REPLICATION_LEVEL",
217 dht_replication_level = 3;
221 GNUNET_CONFIGURATION_get_value_time (c,
226 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
230 GNUNET_SCHEDULER_shutdown ();
234 dht_handle = GNUNET_DHT_connect (c,
236 GNUNET_break (NULL != dht_handle);
237 announce_delay = GNUNET_TIME_UNIT_SECONDS;
238 announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id,
244 * Shut down the DHT subsystem.
249 if (NULL != dht_handle)
251 GNUNET_DHT_disconnect (dht_handle);
254 if (NULL != announce_id_task)
256 GNUNET_SCHEDULER_cancel (announce_id_task);
257 announce_id_task = NULL;
263 * Search DHT for paths to @a peeR_id
265 * @param peer_id peer to search for
266 * @return handle to abort search
268 struct GCD_search_handle *
269 GCD_search (const struct GNUNET_PeerIdentity *peer_id)
271 struct GNUNET_HashCode phash;
272 struct GCD_search_handle *h;
274 GNUNET_STATISTICS_update (stats,
281 GNUNET_memcpy (&phash,
285 h = GNUNET_new (struct GCD_search_handle);
286 h->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */
287 GNUNET_BLOCK_TYPE_DHT_HELLO, /* type */
288 &phash, /* key to search */
289 dht_replication_level, /* replication level */
290 GNUNET_DHT_RO_RECORD_ROUTE |
291 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
296 LOG (GNUNET_ERROR_TYPE_DEBUG,
297 "Starting DHT GET for peer %s (%p)\n",
298 GNUNET_i2s (peer_id),
305 * Stop DHT search started with #GCD_search().
307 * @param h handle to search to stop
310 GCD_search_stop (struct GCD_search_handle *h)
312 LOG (GNUNET_ERROR_TYPE_DEBUG,
313 "Stopping DHT GET %p\n",
315 GNUNET_DHT_get_stop (h->dhtget);
319 /* end of gnunet-service-cadet_dht.c */