GNUnet  0.10.x
gnunet-service-fs_cadet_server.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2012, 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  */
20 
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"
39 
43 #define IDLE_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
44 
45 
54 
59 
63  size_t msize;
64 };
65 
66 
70 struct CadetClient {
74  struct CadetClient *next;
75 
79  struct CadetClient *prev;
80 
85 
90 
95 
100 
105 
110 
114  size_t reply_size;
115 };
116 
117 
122 
126 static struct CadetClient *sc_head;
127 
131 static struct CadetClient *sc_tail;
132 
136 static unsigned int sc_count;
137 
141 static unsigned long long sc_count_max;
142 
143 
144 
150 static void
152 {
153  struct CadetClient *sc = cls;
154  struct GNUNET_CADET_Channel *tun;
155 
156  sc->timeout_task = NULL;
157  tun = sc->channel;
158  sc->channel = NULL;
160  "Timeout for inactive cadet client %p\n",
161  sc);
163 }
164 
165 
171 static void
173 {
174  if (NULL != sc->timeout_task)
178  sc);
179 }
180 
181 
188 static void
190 {
191  struct CadetClient *sc = cls;
192  struct GNUNET_MQ_Handle *mq;
193 
194  mq = GNUNET_CADET_get_mq(sc->channel);
195  if (0 != GNUNET_MQ_get_length(mq))
196  {
198  "Write pending, waiting for it to complete\n");
199  return;
200  }
203  "Finished processing cadet request from client %p, ready to receive the next one\n",
204  sc);
206 }
207 
208 
224 static void
226  const struct GNUNET_HashCode *key,
227  size_t size,
228  const void *data,
229  enum GNUNET_BLOCK_Type type,
230  uint32_t priority,
231  uint32_t anonymity,
232  uint32_t replication,
234  uint64_t uid)
235 {
236  struct CadetClient *sc = cls;
237  size_t msize = size + sizeof(struct CadetReplyMessage);
238  struct GNUNET_MQ_Envelope *env;
239  struct CadetReplyMessage *srm;
240 
241  sc->qe = NULL;
242  if (NULL == data)
243  {
244  /* no result, this should not really happen, as for
245  non-anonymous routing only peers that HAVE the
246  answers should be queried; OTOH, this is not a
247  hard error as we might have had the answer in the
248  past and the user might have unindexed it. Hence
249  we log at level "INFO" for now. */
250  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("# queries received via CADET not answered"),
263  1,
264  GNUNET_NO);
265  continue_writing(sc);
266  return;
267  }
268  if (GNUNET_BLOCK_TYPE_FS_ONDEMAND == type)
269  {
271  "Performing on-demand encoding for query %s\n",
272  GNUNET_h2s(key));
273  if (GNUNET_OK !=
275  size,
276  data,
277  type,
278  priority,
279  anonymity,
280  replication,
281  expiration,
282  uid,
284  sc))
285  {
287  "On-demand encoding request failed\n");
288  continue_writing(sc);
289  }
290  return;
291  }
292  if (msize > GNUNET_MAX_MESSAGE_SIZE)
293  {
294  GNUNET_break(0);
295  continue_writing(sc);
296  return;
297  }
300  "Starting transmission of %u byte reply of type %d for query `%s' via cadet to %p\n",
301  (unsigned int)size,
302  (unsigned int)type,
303  GNUNET_h2s(key),
304  sc);
305  env = GNUNET_MQ_msg_extra(srm,
306  size,
308  srm->type = htonl(type);
309  srm->expiration = GNUNET_TIME_absolute_hton(expiration);
310  GNUNET_memcpy(&srm[1],
311  data,
312  size);
315  sc);
317  gettext_noop("# Blocks transferred via cadet"),
318  1,
319  GNUNET_NO);
321  env);
322 }
323 
324 
332 static void
333 handle_request(void *cls,
334  const struct CadetQueryMessage *sqm)
335 {
336  struct CadetClient *sc = cls;
337 
339  "Received query for `%s' via cadet from client %p\n",
340  GNUNET_h2s(&sqm->query),
341  sc);
343  gettext_noop("# queries received via cadet"),
344  1,
345  GNUNET_NO);
348  0 /* next_uid */,
349  false /* random */,
350  &sqm->query,
351  ntohl(sqm->type),
352  0 /* priority */,
355  sc);
356  if (NULL == sc->qe)
357  {
359  "Queueing request with datastore failed (queue full?)\n");
360  continue_writing(sc);
361  }
362 }
363 
364 
374 static void *
375 connect_cb(void *cls,
377  const struct GNUNET_PeerIdentity *initiator)
378 {
379  struct CadetClient *sc;
380 
381  GNUNET_assert(NULL != channel);
382  if (sc_count >= sc_count_max)
383  {
385  gettext_noop("# cadet client connections rejected"),
386  1,
387  GNUNET_NO);
389  return NULL;
390  }
392  gettext_noop("# cadet connections active"),
393  1,
394  GNUNET_NO);
395  sc = GNUNET_new(struct CadetClient);
396  sc->channel = channel;
398  sc_tail,
399  sc);
400  sc_count++;
403  "Accepting inbound cadet connection from `%s' as client %p\n",
404  GNUNET_i2s(initiator),
405  sc);
406  return sc;
407 }
408 
409 
418 static void
419 disconnect_cb(void *cls,
420  const struct GNUNET_CADET_Channel *channel)
421 {
422  struct CadetClient *sc = cls;
423  struct WriteQueueItem *wqi;
424 
425  if (NULL == sc)
426  return;
427  sc->channel = NULL;
429  "Terminating cadet connection with client %p\n",
430  sc);
432  gettext_noop("# cadet connections active"), -1,
433  GNUNET_NO);
434  if (NULL != sc->terminate_task)
436  if (NULL != sc->timeout_task)
438  if (NULL != sc->qe)
440  while (NULL != (wqi = sc->wqi_head))
441  {
443  sc->wqi_tail,
444  wqi);
445  GNUNET_free(wqi);
446  }
448  sc_tail,
449  sc);
450  sc_count--;
451  GNUNET_free(sc);
452 }
453 
454 
469 static void
471  const struct GNUNET_CADET_Channel *channel,
472  int window_size)
473 {
474  /* FIXME: could do flow control here... */
475 }
476 
477 
481 void
483 {
484  struct GNUNET_MQ_MessageHandler handlers[] = {
487  struct CadetQueryMessage,
488  NULL),
490  };
491  struct GNUNET_HashCode port;
492 
493  if (GNUNET_YES !=
495  "fs",
496  "MAX_CADET_CLIENTS",
497  &sc_count_max))
498  return;
500  "Initializing cadet FS server with a limit of %llu connections\n",
501  sc_count_max);
504  GNUNET_assert(NULL != cadet_handle);
507  &port);
509  &port,
510  &connect_cb,
511  NULL,
513  &disconnect_cb,
514  handlers);
515 }
516 
517 
521 void
523 {
526  NULL);
528  cadet_map = NULL;
529  if (NULL != cadet_port)
530  {
531  GNUNET_CADET_close_port(cadet_port);
532  cadet_port = NULL;
533  }
534  if (NULL != cadet_handle)
535  {
537  cadet_handle = NULL;
538  }
539  GNUNET_assert(NULL == sc_head);
540  GNUNET_assert(0 == sc_count);
541 }
542 
543 /* end of gnunet-service-fs_cadet.c */
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.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_MESSAGE_TYPE_FS_CADET_REPLY
P2P answer for content (one FS to another via a cadet).
size_t msize
Number of bytes of payload, allocated at the end of this struct.
static struct GNUNET_CADET_Handle * cadet_handle
The handle to cadet.
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:838
Query from one peer, asking the other for CHK-data.
static char * expiration
Credential TTL.
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:41
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.
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.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
Any type of block, used as a wildcard when searching.
struct GNUNET_SCHEDULER_Task * timeout_task
Task that is scheduled to terminate idle connections.
struct WriteQueueItem * next
Kept in a DLL.
struct GNUNET_SCHEDULER_Task * terminate_task
Task that is scheduled to asynchronously terminate the connection.
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct CadetClient * sc_head
Head of DLL of cadet clients.
static unsigned int replication
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
static unsigned long long sc_count_max
Maximum allowed number of cadet clients.
uint32_t type
Block type must be DBLOCK or IBLOCK.
struct GNUNET_STATISTICS_Handle * GSF_stats
Handle for reporting statistics.
#define GNUNET_NO
Definition: gnunet_common.h:78
shared data structures of gnunet-service-fs.c
Opaque handle to a channel.
Definition: cadet_api.c:79
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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.
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_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).
const struct GNUNET_CONFIGURATION_Handle * GSF_cfg
Our configuration.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Type of a block representing a block to be encoded on demand from disk.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:973
static void window_change_cb(void *cls, const struct GNUNET_CADET_Channel *channel, int window_size)
Function called whenever an MQ-channel&#39;s transmission window size changes.
#define IDLE_TIMEOUT
After how long do we termiante idle connections?
#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:52
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:1237
static void refresh_timeout_task(struct CadetClient *sc)
Reset the timeout for the cadet client (due to activity).
Entry in our priority queue.
Definition: datastore_api.c:96
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 incomming MQ-based channels.
Definition: cadet_api.c:1007
struct GNUNET_HashCode query
Query hash from CHK (hash of encrypted block).
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:772
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 unsigned int sc_count
Number of active cadet clients in the &#39;sc_*&#39;-DLL.
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...
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition: mq.c:333
unsigned int GSF_datastore_queue_size
Size of the datastore queue we assume for common requests.
non-anonymous file-transfer
static void timeout_cadet_task(void *cls)
Task run to asynchronously terminate the cadet due to timeout.
struct GNUNET_CONTAINER_MultiPeerMap * cadet_map
Map from peer identities to &#39;struct CadetHandles&#39; with cadet channels to those peers.
struct WriteQueueItem * prev
Kept in a DLL.
struct WriteQueueItem * wqi_head
Head of write queue.
enum GNUNET_MQ_PriorityPreferences priority
Flags that were set for this queue by GNUNET_MQ_set_options().
Definition: mq.c:162
A 512-bit hashcode.
Message handler for a specific message type.
struct GNUNET_DATASTORE_Handle * GSF_dsh
Our connection to the datastore.
void GSF_cadet_start_server()
Initialize subsystem for non-anonymous file-sharing.
Struct containing information about a client of the service.
struct GNUNET_HashCode key
The key used in the DHT.
static unsigned int size
Size of the "table".
Definition: peer.c:66
struct GNUNET_CADET_Channel * channel
Channel for communication.
void GSF_cadet_stop_server()
Shutdown subsystem for non-anonymous file-sharing.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
struct GNUNET_TIME_AbsoluteNBO expiration
Expiration time for the block.
static struct GNUNET_FS_SearchContext * sc
Definition: gnunet-search.c:37
indexing for the file-sharing service
size_t reply_size
Size of the last write that was initiated.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
struct WriteQueueItem * wqi_tail
Tail of write queue.
Handle to a message queue.
Definition: mq.c:84
static void disconnect_cb(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called by cadet when a client disconnects.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
void GNUNET_DATASTORE_cancel(struct GNUNET_DATASTORE_QueueEntry *qe)
Cancel a datastore operation.
The identity of the host (wraps the signing key of the peer).
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:951
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_MESSAGE_TYPE_FS_CADET_QUERY
P2P request for content (one FS to another via a cadet).
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:131
static void handle_request(void *cls, const struct CadetQueryMessage *sqm)
Functions with this signature are called whenever a complete query message is received.
Opaque handle to a port.
Definition: cadet_api.c:143
static struct GNUNET_CADET_Port * cadet_port
Listen port for incoming requests.
static struct CadetClient * sc_tail
Tail of DLL of cadet clients.
#define GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER
Transfer of blocks for non-anonymmous file-sharing.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port().
Definition: cadet_api.c:871
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
static unsigned int anonymity
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:351
uint32_t type
Block type must be DBLOCK or IBLOCK.
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.
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&#39;ve received an on-demand encoded block from the datastore.
uint32_t data
The data value.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:655
Reply to a CadetQueryMessage.
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:900
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
struct GNUNET_DATASTORE_QueueEntry * qe
Current active request to the datastore, if we have one pending.
A message in the queue to be written to the cadet.
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
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:1116
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956