GNUnet  0.11.x
gnunet-service-cadet_dht.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2013, 2017 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
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  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_dht_service.h"
31 #include "gnunet-service-cadet.h"
36 
43 #define STARTUP_DELAY GNUNET_TIME_relative_multiply ( \
44  GNUNET_TIME_UNIT_MILLISECONDS, 500)
45 
51 #define CHANGE_DELAY GNUNET_TIME_relative_multiply ( \
52  GNUNET_TIME_UNIT_MILLISECONDS, 100)
53 
54 
55 #define LOG(level, ...) GNUNET_log_from (level, "cadet-dht", __VA_ARGS__)
56 
57 
62 {
67 };
68 
69 
74 
79 
83 static unsigned long long dht_replication_level;
84 
89 
94 
95 
112 static void
114  const struct GNUNET_HashCode *key,
115  const struct GNUNET_PeerIdentity *get_path,
116  unsigned int get_path_length,
117  const struct GNUNET_PeerIdentity *put_path,
118  unsigned int put_path_length,
119  enum GNUNET_BLOCK_Type type,
120  size_t size,
121  const void *data)
122 {
123  const struct GNUNET_HELLO_Message *hello = data;
124  struct CadetPeer *peer;
125 
126  GCPP_try_path_from_dht (get_path,
127  get_path_length,
128  put_path,
129  put_path_length);
130  if ((size >= sizeof(struct GNUNET_HELLO_Message)) &&
131  (ntohs (hello->header.size) == size) &&
132  (size == GNUNET_HELLO_size (hello)))
133  {
134  peer = GCP_get (&put_path[0],
135  GNUNET_YES);
137  "Got HELLO for %s\n",
138  GCP_2s (peer));
139  GCP_set_hello (peer,
140  hello);
141  }
142 }
143 
144 
150 static void
151 announce_id (void *cls)
152 {
153  struct GNUNET_HashCode phash;
154  const struct GNUNET_HELLO_Message *hello;
155  size_t size;
156  struct GNUNET_TIME_Absolute expiration;
157  struct GNUNET_TIME_Relative next_put;
158 
159  hello = GCH_get_mine ();
160  size = (NULL != hello) ? GNUNET_HELLO_size (hello) : 0;
161  if (0 == size)
162  {
166  }
167  else
168  {
169  expiration = GNUNET_HELLO_get_last_expiration (hello);
171  }
172 
173  /* Call again in id_announce_time, unless HELLO expires first,
174  * but wait at least 1s. */
175  next_put
176  = GNUNET_TIME_absolute_get_remaining (expiration);
177  next_put
178  = GNUNET_TIME_relative_min (next_put,
180  next_put
181  = GNUNET_TIME_relative_max (next_put,
183  announce_id_task
184  = GNUNET_SCHEDULER_add_delayed (next_put,
185  &announce_id,
186  cls);
188  "# DHT announce",
189  1,
190  GNUNET_NO);
191  memset (&phash,
192  0,
193  sizeof(phash));
194  GNUNET_memcpy (&phash,
195  &my_full_id,
196  sizeof(my_full_id));
198  "Announcing my HELLO (%u bytes) in the DHT\n",
199  size);
200  GNUNET_DHT_put (dht_handle, /* DHT handle */
201  &phash, /* Key to use */
202  dht_replication_level, /* Replication level */
204  | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, /* DHT options */
205  GNUNET_BLOCK_TYPE_DHT_HELLO, /* Block type */
206  size, /* Size of the data */
207  (const char *) hello, /* Data itself */
208  expiration, /* Data expiration */
209  NULL, /* Continuation */
210  NULL); /* Continuation closure */
211 }
212 
213 
218 void
220 {
221  if (NULL == announce_id_task)
222  return; /* too early */
223  GNUNET_SCHEDULER_cancel (announce_id_task);
224  announce_id_task
226  &announce_id,
227  NULL);
228 }
229 
230 
236 void
238 {
239  if (GNUNET_OK !=
241  "CADET",
242  "DHT_REPLICATION_LEVEL",
244  {
246  "CADET",
247  "DHT_REPLICATION_LEVEL",
248  "USING DEFAULT");
250  }
251 
252  if (GNUNET_OK !=
254  "CADET",
255  "ID_ANNOUNCE_TIME",
257  {
259  "CADET",
260  "ID_ANNOUNCE_TIME",
261  "MISSING");
263  return;
264  }
265 
266  dht_handle = GNUNET_DHT_connect (c,
267  64);
268  GNUNET_break (NULL != dht_handle);
270  announce_id_task = GNUNET_SCHEDULER_add_delayed (STARTUP_DELAY,
271  &announce_id,
272  NULL);
273 }
274 
275 
279 void
281 {
282  if (NULL != dht_handle)
283  {
284  GNUNET_DHT_disconnect (dht_handle);
285  dht_handle = NULL;
286  }
287  if (NULL != announce_id_task)
288  {
289  GNUNET_SCHEDULER_cancel (announce_id_task);
290  announce_id_task = NULL;
291  }
292 }
293 
294 
301 struct GCD_search_handle *
303 {
304  struct GNUNET_HashCode phash;
305  struct GCD_search_handle *h;
306 
308  "# DHT search",
309  1,
310  GNUNET_NO);
311  memset (&phash,
312  0,
313  sizeof(phash));
314  GNUNET_memcpy (&phash,
315  peer_id,
316  sizeof(*peer_id));
317 
318  h = GNUNET_new (struct GCD_search_handle);
319  h->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */
320  GNUNET_BLOCK_TYPE_DHT_HELLO, /* type */
321  &phash, /* key to search */
322  dht_replication_level, /* replication level */
325  NULL, /* xquery */
326  0, /* xquery bits */
328  h);
330  "Starting DHT GET for peer %s (%p)\n",
331  GNUNET_i2s (peer_id),
332  h);
333  return h;
334 }
335 
336 
342 void
344 {
346  "Stopping DHT GET %p\n",
347  h);
349  GNUNET_free (h);
350 }
351 
352 
353 /* end of gnunet-service-cadet_dht.c */
static struct GNUNET_SCHEDULER_Task * announce_id_task
Task to periodically announce itself in the network.
We should keep track of the route that the message took in the P2P network.
Peer description.
A HELLO message is used to exchange information about transports with other peers.
int GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
int GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
Handle for DHT searches.
void GCD_search_stop(struct GCD_search_handle *h)
Stop DHT search started with GCD_search().
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
static struct GNUNET_TIME_Relative id_announce_time
How often to PUT own ID in the DHT.
void GCP_set_hello(struct CadetPeer *cp, const struct GNUNET_HELLO_Message *hello)
We got a HELLO for a peer, remember it, and possibly trigger adequate actions (like trying to connect...
#define LOG(level,...)
struct GNUNET_TIME_Relative GNUNET_TIME_relative_max(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the maximum of two relative time values.
Definition: time.c:287
struct GNUNET_PeerIdentity my_full_id
Local peer own ID.
void GCD_shutdown(void)
Shut down the DHT subsystem.
#define GNUNET_TIME_UNIT_SECONDS
One second.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static struct GNUNET_DHT_Handle * dht_handle
Handle to use DHT.
static char * peer_id
Option –peer.
Definition: gnunet-cadet.c:42
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition: time.c:395
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GCPP_try_path_from_dht(const struct GNUNET_PeerIdentity *get_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int put_path_length)
Create a peer path based on the result of a DHT lookup.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
Connection to the DHT service.
Definition: dht_api.c:201
const char * GCP_2s(const struct CadetPeer *cp)
Get the static string for a peer ID.
void GCD_hello_update()
Function called by the HELLO subsystem whenever OUR hello changes.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1253
Information we track per peer.
struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
const struct GNUNET_HELLO_Message * GCH_get_mine(void)
Get own hello message.
cadet service; dealing with hello messages
static void announce_id(void *cls)
Periodically announce self id in the DHT.
Type of a block that contains a HELLO for a peer (for DHT and CADET find-peer operations).
A 512-bit hashcode.
void GNUNET_DHT_get_stop(struct GNUNET_DHT_GetHandle *get_handle)
Stop async DHT-get.
Definition: dht_api.c:1155
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
static void dht_get_id_handler(void *cls, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const struct GNUNET_PeerIdentity *get_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int put_path_length, enum GNUNET_BLOCK_Type type, size_t size, const void *data)
Function to process paths received for a new peer addition.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition: time.c:272
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
struct GNUNET_HashCode key
The key used in the DHT.
struct GNUNET_DHT_PutHandle * GNUNET_DHT_put(struct GNUNET_DHT_Handle *handle, const struct GNUNET_HashCode *key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, enum GNUNET_BLOCK_Type type, size_t size, const void *data, struct GNUNET_TIME_Absolute exp, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
Perform a PUT operation storing data in the DHT.
Definition: dht_api.c:966
static unsigned int size
Size of the "table".
Definition: peer.c:67
struct GNUNET_DHT_Handle * GNUNET_DHT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int ht_len)
Initialize the connection with the DHT service.
Definition: dht_api.c:890
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:918
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
Handle to a GET request.
Definition: dht_api.c:79
struct GNUNET_DHT_GetHandle * dhtget
DHT_GET handle.
void GCD_init(const struct GNUNET_CONFIGURATION_Handle *c)
Initialize the DHT subsystem.
static struct GNUNET_TIME_Relative announce_delay
Delay for the next ID announce.
The identity of the host (wraps the signing key of the peer).
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_HELLO.
configuration data
Definition: configuration.c:85
struct CadetPeer * GCP_get(const struct GNUNET_PeerIdentity *peer_id, int create)
Retrieve the CadetPeer stucture associated with the peer.
struct GNUNET_DHT_GetHandle * GNUNET_DHT_get_start(struct GNUNET_DHT_Handle *handle, enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode *key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, const void *xquery, size_t xquery_size, GNUNET_DHT_GetIterator iter, void *iter_cls)
Perform an asynchronous GET operation on the DHT identified.
Definition: dht_api.c:1067
struct GCD_search_handle * GCD_search(const struct GNUNET_PeerIdentity *peer_id)
Search DHT for paths to peeR_id.
static unsigned long long dht_replication_level
DHT replication level, see DHT API: GNUNET_DHT_get_start(), GNUNET_DHT_put().
Entry in list of pending tasks.
Definition: scheduler.c:134
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:652
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
#define CHANGE_DELAY
How long do we wait after we get an updated HELLO before publishing? Allows for the HELLO to be updat...
cadet service; dealing with DHT requests and results
#define STARTUP_DELAY
How long do we wait before first announcing our presence to the DHT.
uint32_t data
The data value.
struct GNUNET_TIME_Absolute GNUNET_HELLO_get_last_expiration(const struct GNUNET_HELLO_Message *msg)
When does the last address in the given HELLO expire?
Definition: hello.c:892
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
Each peer along the way should look at &#39;enc&#39; (otherwise only the k-peers closest to the key should lo...
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
Information we track per peer.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966