GNUnet  0.17.6
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2012, 2013, 2017 GNUnet e.V.
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.
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
13  Affero General Public License for more details.
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <>.
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
30 #include "platform.h"
31 #include "gnunet_constants.h"
32 #include "gnunet_util_lib.h"
33 #include "gnunet_cadet_service.h"
34 #include "gnunet_protocols.h"
35 #include "gnunet_applications.h"
36 #include "gnunet-service-fs.h"
50 {
64  size_t msize;
65 };
71 struct CadetClient
72 {
76  struct CadetClient *next;
81  struct CadetClient *prev;
116  size_t reply_size;
117 };
128 static struct CadetClient *sc_head;
133 static struct CadetClient *sc_tail;
138 static unsigned int sc_count;
143 static unsigned long long sc_count_max;
151 static void
153 {
154  struct CadetClient *sc = cls;
155  struct GNUNET_CADET_Channel *tun;
157  sc->timeout_task = NULL;
158  tun = sc->channel;
159  sc->channel = NULL;
161  "Timeout for inactive cadet client %p\n",
162  sc);
164 }
172 static void
174 {
175  if (NULL != sc->timeout_task)
176  GNUNET_SCHEDULER_cancel (sc->timeout_task);
179  sc);
180 }
189 static void
190 continue_writing (void *cls)
191 {
192  struct CadetClient *sc = cls;
193  struct GNUNET_MQ_Handle *mq;
195  mq = GNUNET_CADET_get_mq (sc->channel);
196  if (0 != GNUNET_MQ_get_length (mq))
197  {
199  "Write pending, waiting for it to complete\n");
200  return;
201  }
204  "Finished processing cadet request from client %p, ready to receive the next one\n",
205  sc);
206  GNUNET_CADET_receive_done (sc->channel);
207 }
225 static void
227  const struct GNUNET_HashCode *key,
228  size_t size,
229  const void *data,
230  enum GNUNET_BLOCK_Type type,
231  uint32_t priority,
232  uint32_t anonymity,
233  uint32_t replication,
235  uint64_t uid)
236 {
237  struct CadetClient *sc = cls;
238  size_t msize = size + sizeof(struct CadetReplyMessage);
239  struct GNUNET_MQ_Envelope *env;
240  struct CadetReplyMessage *srm;
242  sc->qe = NULL;
243  if (NULL == data)
244  {
245  /* no result, this should not really happen, as for
246  non-anonymous routing only peers that HAVE the
247  answers should be queried; OTOH, this is not a
248  hard error as we might have had the answer in the
249  past and the user might have unindexed it. Hence
250  we log at level "INFO" for now. */if (NULL == key)
251  {
253  "Have no answer and the query was NULL\n");
254  }
255  else
256  {
258  "Have no answer for query `%s'\n",
259  GNUNET_h2s (key));
260  }
262  gettext_noop (
263  "# queries received via CADET not answered"),
264  1,
265  GNUNET_NO);
267  return;
268  }
270  {
272  "Performing on-demand encoding for query %s\n",
273  GNUNET_h2s (key));
274  if (GNUNET_OK !=
276  size,
277  data,
278  type,
279  priority,
280  anonymity,
281  replication,
282  expiration,
283  uid,
285  sc))
286  {
288  "On-demand encoding request failed\n");
290  }
291  return;
292  }
293  if (msize > GNUNET_MAX_MESSAGE_SIZE)
294  {
295  GNUNET_break (0);
297  return;
298  }
301  "Starting transmission of %u byte reply of type %d for query `%s' via cadet to %p\n",
302  (unsigned int) size,
303  (unsigned int) type,
304  GNUNET_h2s (key),
305  sc);
306  env = GNUNET_MQ_msg_extra (srm,
307  size,
309  srm->type = htonl (type);
311  GNUNET_memcpy (&srm[1],
312  data,
313  size);
316  sc);
318  gettext_noop ("# Blocks transferred via cadet"),
319  1,
320  GNUNET_NO);
322  env);
323 }
333 static void
334 handle_request (void *cls,
335  const struct CadetQueryMessage *sqm)
336 {
337  struct CadetClient *sc = cls;
340  "Received query for `%s' via cadet from client %p\n",
341  GNUNET_h2s (&sqm->query),
342  sc);
344  gettext_noop ("# queries received via cadet"),
345  1,
346  GNUNET_NO);
349  0 /* next_uid */,
350  false /* random */,
351  &sqm->query,
352  ntohl (sqm->type),
353  0 /* priority */,
356  sc);
357  if (NULL == sc->qe)
358  {
360  "Queueing request with datastore failed (queue full?)\n");
362  }
363 }
375 static void *
376 connect_cb (void *cls,
378  const struct GNUNET_PeerIdentity *initiator)
379 {
380  struct CadetClient *sc;
382  GNUNET_assert (NULL != channel);
383  if (sc_count >= sc_count_max)
384  {
386  gettext_noop (
387  "# cadet client connections rejected"),
388  1,
389  GNUNET_NO);
391  return NULL;
392  }
394  gettext_noop ("# cadet connections active"),
395  1,
396  GNUNET_NO);
397  sc = GNUNET_new (struct CadetClient);
398  sc->channel = channel;
400  sc_tail,
401  sc);
402  sc_count++;
405  "Accepting inbound cadet connection from `%s' as client %p\n",
406  GNUNET_i2s (initiator),
407  sc);
408  return sc;
409 }
420 static void
421 disconnect_cb (void *cls,
422  const struct GNUNET_CADET_Channel *channel)
423 {
424  struct CadetClient *sc = cls;
425  struct WriteQueueItem *wqi;
427  if (NULL == sc)
428  return;
429  sc->channel = NULL;
431  "Terminating cadet connection with client %p\n",
432  sc);
434  gettext_noop ("# cadet connections active"), -1,
435  GNUNET_NO);
436  if (NULL != sc->terminate_task)
437  GNUNET_SCHEDULER_cancel (sc->terminate_task);
438  if (NULL != sc->timeout_task)
439  GNUNET_SCHEDULER_cancel (sc->timeout_task);
440  if (NULL != sc->qe)
442  while (NULL != (wqi = sc->wqi_head))
443  {
444  GNUNET_CONTAINER_DLL_remove (sc->wqi_head,
445  sc->wqi_tail,
446  wqi);
447  GNUNET_free (wqi);
448  }
450  sc_tail,
451  sc);
452  sc_count--;
453  GNUNET_free (sc);
454 }
471 static void
472 window_change_cb (void *cls,
473  const struct GNUNET_CADET_Channel *channel,
474  int window_size)
475 {
476  /* FIXME: could do flow control here... */
477 }
483 void
485 {
489  struct CadetQueryMessage,
490  NULL),
492  };
493  struct GNUNET_HashCode port;
495  if (GNUNET_YES !=
497  "fs",
499  &sc_count_max))
500  return;
502  "Initializing cadet FS server with a limit of %llu connections\n",
503  sc_count_max);
506  GNUNET_assert (NULL != cadet_handle);
509  &port);
511  &port,
512  &connect_cb,
513  NULL,
515  &disconnect_cb,
516  handlers);
517 }
523 void
525 {
528  NULL);
530  cadet_map = NULL;
531  if (NULL != cadet_port)
532  {
534  cadet_port = NULL;
535  }
536  if (NULL != cadet_handle)
537  {
539  cadet_handle = NULL;
540  }
541  GNUNET_assert (NULL == sc_head);
542  GNUNET_assert (0 == sc_count);
543 }
546 /* end of gnunet-service-fs_cadet.c */
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define gettext_noop(String)
Definition: gettext.h:69
static char * expiration
Credential TTL.
Definition: gnunet-abd.c:96
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
static unsigned int replication
static struct GNUNET_CADET_Handle * cadet_handle
The handle to cadet.
struct GNUNET_HashCode key
The key used in the DHT.
static unsigned int anonymity
uint32_t data
The data value.
static struct GNUNET_FS_SearchContext * sc
Definition: gnunet-search.c:84
struct GNUNET_STATISTICS_Handle * GSF_stats
Handle for reporting statistics.
const struct GNUNET_CONFIGURATION_Handle * GSF_cfg
Our configuration.
struct GNUNET_DATASTORE_Handle * GSF_dsh
Our connection to the datastore.
unsigned int GSF_datastore_queue_size
Size of the datastore queue we assume for common requests.
shared data structures of gnunet-service-fs.c
non-anonymous file-transfer
struct GNUNET_CONTAINER_MultiPeerMap * cadet_map
Map from peer identities to 'struct CadetHandles' with cadet channels to those peers.
int GSF_cadet_release_clients(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Function called on each active cadets to shut them down.
static void disconnect_cb(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called by cadet when a client disconnects.
static void * connect_cb(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Functions of this type are called upon new cadet connection from other peers.
static void window_change_cb(void *cls, const struct GNUNET_CADET_Channel *channel, int window_size)
Function called whenever an MQ-channel's transmission window size changes.
static unsigned int sc_count
Number of active cadet clients in the 'sc_*'-DLL.
static void refresh_timeout_task(struct CadetClient *sc)
Reset the timeout for the cadet client (due to activity).
static void handle_datastore_reply(void *cls, const struct GNUNET_HashCode *key, size_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, uint64_t uid)
Process a datum that was stored in the datastore.
static struct CadetClient * sc_tail
Tail of DLL of cadet clients.
void GSF_cadet_start_server()
Initialize subsystem for non-anonymous file-sharing.
static unsigned long long sc_count_max
Maximum allowed number of cadet clients.
void GSF_cadet_stop_server()
Shutdown subsystem for non-anonymous file-sharing.
static void handle_request(void *cls, const struct CadetQueryMessage *sqm)
Functions with this signature are called whenever a complete query message is received.
static void timeout_cadet_task(void *cls)
Task run to asynchronously terminate the cadet due to timeout.
After how long do we termiante idle connections?
static void continue_writing(void *cls)
Check if we are done with the write queue, and if so tell CADET that we are ready to read more.
static struct GNUNET_CADET_Port * cadet_port
Listen port for incoming requests.
static struct CadetClient * sc_head
Head of DLL of cadet clients.
int GNUNET_FS_handle_on_demand_block(const struct GNUNET_HashCode *key, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, uint64_t uid, GNUNET_DATASTORE_DatumProcessor cont, void *cont_cls)
We've received an on-demand encoded block from the datastore.
indexing for the file-sharing service
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:41
CADET service; establish channels to distant peers.
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
Type of a block representing a block to be encoded on demand from disk.
Identifier for any block.
Constants for network protocols.
Largest supported message (to be precise, one byte more than the largest possible message,...
Transfer of blocks for non-anonymmous file-sharing.
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:873
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:831
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:775
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port.
Definition: cadet_api.c:802
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected peer.
Definition: cadet_api.c:1067
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:895
struct GNUNET_CADET_Port * GNUNET_CADET_open_port(struct GNUNET_CADET_Handle *h, const struct GNUNET_HashCode *port, GNUNET_CADET_ConnectEventHandler connects, void *connects_cls, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Open a port to receive incoming MQ-based channels.
Definition: cadet_api.c:955
enum GNUNET_GenericReturnValue 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.
struct GNUNET_DATASTORE_QueueEntry * GNUNET_DATASTORE_get_key(struct GNUNET_DATASTORE_Handle *h, uint64_t next_uid, bool random, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, unsigned int queue_priority, unsigned int max_queue_size, GNUNET_DATASTORE_DatumProcessor proc, void *proc_cls)
Get a result for a particular key from the datastore.
void GNUNET_DATASTORE_cancel(struct GNUNET_DATASTORE_QueueEntry *qe)
Cancel a datastore operation.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
Definition: gnunet_common.h:99
Definition: gnunet_common.h:98
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition: mq.c:291
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:302
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:56
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore.
Definition: mq.c:640
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
P2P request for content (one FS to another via a cadet).
P2P answer for content (one FS to another via a cadet).
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
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:1254
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:637
static unsigned int size
Size of the "table".
Definition: peer.c:67
Struct containing information about a client of the service.
struct GNUNET_SCHEDULER_Task * terminate_task
Task that is scheduled to asynchronously terminate the connection.
struct GNUNET_DATASTORE_QueueEntry * qe
Current active request to the datastore, if we have one pending.
size_t reply_size
Size of the last write that was initiated.
struct WriteQueueItem * wqi_tail
Tail of write queue.
struct CadetClient * prev
Linked list prev.
struct GNUNET_CADET_Channel * channel
Channel for communication.
struct WriteQueueItem * wqi_head
Head of write queue.
struct GNUNET_SCHEDULER_Task * timeout_task
Task that is scheduled to terminate idle connections.
struct CadetClient * next
Linked list next.
Query from one peer, asking the other for CHK-data.
struct GNUNET_HashCode query
Query hash from CHK (hash of encrypted block).
uint32_t type
Block type must be DBLOCK or IBLOCK.
Reply to a CadetQueryMessage.
struct GNUNET_TIME_AbsoluteNBO expiration
Expiration time for the block.
uint32_t type
Block type must be DBLOCK or IBLOCK.
Opaque handle to a channel.
Definition: cadet.h:117
Opaque handle to a port.
Definition: cadet_api.c:80
Entry in our priority queue.
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:86
enum GNUNET_MQ_PriorityPreferences priority
Flags that were set for this queue by GNUNET_MQ_set_options().
Definition: mq.c:164
Message handler for a specific message type.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:135
Time for absolute times used by GNUnet, in microseconds.
A message in the queue to be written to the cadet.
struct WriteQueueItem * next
Kept in a DLL.
size_t msize
Number of bytes of payload, allocated at the end of this struct.
struct WriteQueueItem * prev
Kept in a DLL.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model