GNUnet  0.16.x
Data Structures | Macros | Typedefs | Functions | Variables
gnunet-service-dht_clients.c File Reference

GNUnet DHT service's client management code. More...

#include "platform.h"
#include "gnunet_constants.h"
#include "gnunet_protocols.h"
#include "gnunet_statistics_service.h"
#include "gnunet-service-dht.h"
#include "gnunet-service-dht_datacache.h"
#include "gnunet-service-dht_neighbours.h"
#include "dht.h"
Include dependency graph for gnunet-service-dht_clients.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ClientQueryRecord
 Entry in the local forwarding map for a client's GET request. More...
 
struct  ClientMonitorRecord
 Struct containing parameters of monitoring requests. More...
 
struct  ClientHandle
 Struct containing information about a client, handle to connect to it, and any pending messages that need to be sent to it. More...
 
struct  FindByUniqueIdContext
 Closure for find_by_unique_id(). More...
 
struct  RemoveByUniqueIdContext
 Closure for remove_by_unique_id(). More...
 
struct  ForwardReplyContext
 Closure for forward_reply() More...
 
struct  GetActionContext
 Closure for get_action();. More...
 
struct  ResponseActionContext
 Closure for response_action(). More...
 
struct  PutActionContext
 Closure for put_action(). More...
 

Macros

#define SANITY_CHECKS   2
 Enable slow sanity checks to debug issues. More...
 
#define LOG_TRAFFIC(kind, ...)
 Should routing details be logged to stderr (for debugging)? More...
 
#define LOG(kind, ...)   GNUNET_log_from (kind, "dht-clients", __VA_ARGS__)
 
#define GDS_DHT_SERVICE_INIT(name, run)
 Define "main" method using service macro. More...
 

Typedefs

typedef void(* MonitorAction) (void *cls, struct ClientMonitorRecord *m)
 Function to call by for_matching_monitors(). More...
 

Functions

static void remove_client_query_record (struct ClientQueryRecord *record)
 Free data structures associated with the given query. More...
 
static void * client_connect_cb (void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
 Functions with this signature are called whenever a local client is connects to us. More...
 
static void client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
 Functions with this signature are called whenever a client is disconnected on the network level. More...
 
static void transmit_request (struct ClientQueryRecord *cqr)
 Route the given request via the DHT. More...
 
static void transmit_next_request_task (void *cls)
 Task that looks at the retry_heap and transmits all of the requests on the heap that are ready for transmission. More...
 
static enum GNUNET_GenericReturnValue check_dht_local_put (void *cls, const struct GNUNET_DHT_ClientPutMessage *dht_msg)
 Check DHT PUT messages from the client. More...
 
static void handle_dht_local_put (void *cls, const struct GNUNET_DHT_ClientPutMessage *dht_msg)
 Handler for PUT messages. More...
 
static void handle_local_result (void *cls, const struct GDS_DATACACHE_BlockData *bd)
 Handle a result from local datacache for a GET operation. More...
 
static enum GNUNET_GenericReturnValue check_dht_local_get (void *cls, const struct GNUNET_DHT_ClientGetMessage *get)
 Check DHT GET messages from the client. More...
 
static void handle_dht_local_get (void *cls, const struct GNUNET_DHT_ClientGetMessage *get)
 Handler for DHT GET messages from the client. More...
 
static enum GNUNET_GenericReturnValue find_by_unique_id (void *cls, const struct GNUNET_HashCode *key, void *value)
 Function called for each existing DHT record for the given query. More...
 
static enum GNUNET_GenericReturnValue check_dht_local_get_result_seen (void *cls, const struct GNUNET_DHT_ClientGetResultSeenMessage *seen)
 Check "GET result seen" messages from the client. More...
 
static void handle_dht_local_get_result_seen (void *cls, const struct GNUNET_DHT_ClientGetResultSeenMessage *seen)
 Handler for "GET result seen" messages from the client. More...
 
static enum GNUNET_GenericReturnValue remove_by_unique_id (void *cls, const struct GNUNET_HashCode *key, void *value)
 Iterator over hash map entries that frees all entries that match the given client and unique ID. More...
 
static void handle_dht_local_get_stop (void *cls, const struct GNUNET_DHT_ClientGetStopMessage *dht_stop_msg)
 Handler for any generic DHT stop messages, calls the appropriate handler depending on message type (if processed locally) More...
 
static enum GNUNET_GenericReturnValue forward_reply (void *cls, const struct GNUNET_HashCode *query_hash, void *value)
 Iterator over hash map entries that send a given reply to each of the matching clients. More...
 
bool GDS_CLIENTS_handle_reply (const struct GDS_DATACACHE_BlockData *bd, const struct GNUNET_HashCode *query_hash, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *get_path)
 Handle a reply we've received from another peer. More...
 
static void handle_dht_local_hello_get (void *cls, const struct GNUNET_MessageHeader *msg)
 Handler for HELLO GET message. More...
 
static enum GNUNET_GenericReturnValue check_dht_local_hello_offer (void *cls, const struct GNUNET_MessageHeader *hdr)
 Process a client HELLO message received from the service. More...
 
static void handle_dht_local_hello_offer (void *cls, const struct GNUNET_MessageHeader *msg)
 Handler for HELLO OFFER message. More...
 
static void handle_dht_local_monitor (void *cls, const struct GNUNET_DHT_MonitorStartStopMessage *msg)
 Handler for monitor start messages. More...
 
static void handle_dht_local_monitor_stop (void *cls, const struct GNUNET_DHT_MonitorStartStopMessage *msg)
 Handler for monitor stop messages. More...
 
static void for_matching_monitors (enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode *key, MonitorAction cb, void *cb_cls)
 Call cb on all monitors that watch for blocks of type and key key. More...
 
static void get_action (void *cls, struct ClientMonitorRecord *m)
 Function called on monitors that match a GET. More...
 
void GDS_CLIENTS_process_get (enum GNUNET_DHT_RouteOption options, enum GNUNET_BLOCK_Type type, uint32_t hop_count, uint32_t desired_replication_level, unsigned int path_length, const struct GNUNET_DHT_PathElement *path, const struct GNUNET_HashCode *key)
 Check if some client is monitoring GET messages and notify them in that case. More...
 
static void response_action (void *cls, struct ClientMonitorRecord *m)
 Function called on monitors that match a response. More...
 
void GDS_CLIENTS_process_get_resp (const struct GDS_DATACACHE_BlockData *bd, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length)
 Check if some client is monitoring GET RESP messages and notify them in that case. More...
 
static void put_action (void *cls, struct ClientMonitorRecord *m)
 Function called on monitors that match a PUT. More...
 
void GDS_CLIENTS_process_put (enum GNUNET_DHT_RouteOption options, const struct GDS_DATACACHE_BlockData *bd, uint32_t hop_count, uint32_t desired_replication_level)
 Check if some client is monitoring PUT messages and notify them in that case. More...
 
static void GDS_CLIENTS_init (void)
 Initialize client subsystem. More...
 
static void GDS_CLIENTS_stop (void)
 Shutdown client subsystem. More...
 
void __attribute__ ((destructor))
 MINIMIZE heap size (way below 128k) since this process doesn't need much. More...
 

Variables

struct GNUNET_BLOCK_ContextGDS_block_context
 Our handle to the BLOCK library. More...
 
struct GNUNET_STATISTICS_HandleGDS_stats
 Handle for the statistics service. More...
 
struct GNUNET_SERVICE_HandleGDS_service
 Handle for the service. More...
 
const struct GNUNET_CONFIGURATION_HandleGDS_cfg
 The configuration the DHT service is running with. More...
 
static struct ClientMonitorRecordmonitor_head
 List of active monitoring requests. More...
 
static struct ClientMonitorRecordmonitor_tail
 List of active monitoring requests. More...
 
static struct GNUNET_CONTAINER_MultiHashMapforward_map
 Hashmap for fast key based lookup, maps keys to struct ClientQueryRecord entries. More...
 
static struct GNUNET_CONTAINER_Heapretry_heap
 Heap with all of our client's request, sorted by retry time (earliest on top). More...
 
static struct GNUNET_SCHEDULER_Taskretry_task
 Task that re-transmits requests (using retry_heap). More...
 

Detailed Description

GNUnet DHT service's client management code.

Author
Christian Grothoff
Nathan Evans

Definition in file gnunet-service-dht_clients.c.

Macro Definition Documentation

◆ SANITY_CHECKS

#define SANITY_CHECKS   2

Enable slow sanity checks to debug issues.

0: do not check 1: check all external inputs 2: check internal computations as well

Definition at line 43 of file gnunet-service-dht_clients.c.

◆ LOG_TRAFFIC

#define LOG_TRAFFIC (   kind,
  ... 
)
Value:
GNUNET_log_from (kind, "dht-traffic", \
__VA_ARGS__)
#define GNUNET_log_from(kind, comp,...)

Should routing details be logged to stderr (for debugging)?

Definition at line 48 of file gnunet-service-dht_clients.c.

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "dht-clients", __VA_ARGS__)

Definition at line 51 of file gnunet-service-dht_clients.c.

◆ GDS_DHT_SERVICE_INIT

#define GDS_DHT_SERVICE_INIT (   name,
  run 
)

Define "main" method using service macro.

Parameters
namename of the service, like "dht" or "xdht"
runname of the initializaton method for the service

Definition at line 1604 of file gnunet-service-dht_clients.c.

Typedef Documentation

◆ MonitorAction

typedef void(* MonitorAction) (void *cls, struct ClientMonitorRecord *m)

Function to call by for_matching_monitors().

Parameters
clsclosure
ma matching monitor

Definition at line 1273 of file gnunet-service-dht_clients.c.

Function Documentation

◆ remove_client_query_record()

static void remove_client_query_record ( struct ClientQueryRecord record)
static

Free data structures associated with the given query.

Parameters
recordrecord to remove

Definition at line 274 of file gnunet-service-dht_clients.c.

275 {
276  struct ClientHandle *ch = record->ch;
277 
278  GNUNET_CONTAINER_DLL_remove (ch->cqr_head,
279  ch->cqr_tail,
280  record);
283  &record->key,
284  record));
285  if (NULL != record->hnode)
287  GNUNET_array_grow (record->seen_replies,
288  record->seen_replies_count,
289  0);
291 }
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
static struct GNUNET_CONTAINER_MultiHashMap * forward_map
Hashmap for fast key based lookup, maps keys to struct ClientQueryRecord entries.
@ GNUNET_YES
Definition: gnunet_common.h:97
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#define GNUNET_free(ptr)
Wrapper around free.
Struct containing information about a client, handle to connect to it, and any pending messages that ...

References ch, forward_map, GNUNET_array_grow, GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_heap_remove_node(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_free, GNUNET_YES, and record().

Referenced by client_disconnect_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ client_connect_cb()

static void* client_connect_cb ( void *  cls,
struct GNUNET_SERVICE_Client client,
struct GNUNET_MQ_Handle mq 
)
static

Functions with this signature are called whenever a local client is connects to us.

Parameters
clsclosure (NULL for dht)
clientidentification of the client
mqmessage queue for talking to client
Returns
our struct ClientHandle for client

Definition at line 304 of file gnunet-service-dht_clients.c.

307 {
308  struct ClientHandle *ch;
309 
310  (void) cls;
311  ch = GNUNET_new (struct ClientHandle);
312  ch->client = client;
313  ch->mq = mq;
314  return ch;
315 }
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_SERVICE_Client * client
The handle to this client.
struct GNUNET_MQ_Handle * mq
Message Queue for the channel (which we are implementing).
Definition: cadet.h:143

References ch, ClientHandle::client, GNUNET_new, mq, and GNUNET_CADET_Channel::mq.

◆ client_disconnect_cb()

static void client_disconnect_cb ( void *  cls,
struct GNUNET_SERVICE_Client client,
void *  app_ctx 
)
static

Functions with this signature are called whenever a client is disconnected on the network level.

Parameters
clsclosure (NULL for dht)
clientidentification of the client
app_ctxour struct ClientHandle for client

Definition at line 327 of file gnunet-service-dht_clients.c.

330 {
331  struct ClientHandle *ch = app_ctx;
332 
333  (void) cls;
334  (void) client;
336  "Local client %p disconnects\n",
337  ch);
338  {
339  struct ClientMonitorRecord *next;
340 
342  NULL != monitor;
343  monitor = next)
344  {
345  next = monitor->next;
346  if (monitor->ch != ch)
347  continue;
349  monitor_tail,
350  monitor);
352  }
353  }
354 
355  {
356  struct ClientQueryRecord *cqr;
357 
358  while (NULL != (cqr = ch->cqr_head))
360  }
361  GNUNET_free (ch);
362 }
static int monitor
Monitor ARM activity.
Definition: gnunet-arm.c:64
static struct ClientMonitorRecord * monitor_head
List of active monitoring requests.
static struct ClientMonitorRecord * monitor_tail
List of active monitoring requests.
static void remove_client_query_record(struct ClientQueryRecord *record)
Free data structures associated with the given query.
#define GNUNET_log(kind,...)
@ GNUNET_ERROR_TYPE_DEBUG
Struct containing parameters of monitoring requests.
struct ClientMonitorRecord * next
Next element in DLL.
Entry in the local forwarding map for a client's GET request.

References ch, ClientHandle::client, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, monitor, monitor_head, monitor_tail, ClientMonitorRecord::next, and remove_client_query_record().

Here is the call graph for this function:

◆ transmit_request()

static void transmit_request ( struct ClientQueryRecord cqr)
static

Route the given request via the DHT.

This includes updating the bloom filter and retransmission times, building the P2P message and initiating the routing operation.

Parameters
cqrrequest to transmit

Definition at line 373 of file gnunet-service-dht_clients.c.

374 {
375  struct GNUNET_BLOCK_Group *bg;
376  struct GNUNET_CONTAINER_BloomFilter *peer_bf;
377 
379  "# GET requests from clients injected",
380  1,
381  GNUNET_NO);
383  cqr->type,
386  UINT32_MAX),
387  NULL, /* raw data */
388  0, /* raw data size */
389  "seen-set-size",
390  cqr->seen_replies_count,
391  NULL);
393  cqr->seen_replies,
394  cqr->seen_replies_count);
395  peer_bf
400  "Initiating GET for %s, replication %u, already have %u replies\n",
401  GNUNET_h2s (&cqr->key),
402  cqr->replication,
403  cqr->seen_replies_count);
405  cqr->msg_options,
406  cqr->replication,
407  0 /* hop count */,
408  &cqr->key,
409  cqr->xquery,
410  cqr->xquery_size,
411  bg,
412  peer_bf);
415 
416  /* Exponential back-off for retries.
417  * max. is #GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */
420 }
#define DHT_BLOOM_SIZE
Size of the bloom filter the DHT uses to filter peers.
Definition: dht.h:34
struct GNUNET_STATISTICS_Handle * GDS_stats
Handle for the statistics service.
struct GNUNET_BLOCK_Context * GDS_block_context
Our handle to the BLOCK library.
#define LOG(kind,...)
enum GNUNET_GenericReturnValue GDS_NEIGHBOURS_handle_get(enum GNUNET_BLOCK_Type type, enum GNUNET_DHT_RouteOption options, uint16_t desired_replication_level, uint16_t hop_count, const struct GNUNET_HashCode *key, const void *xquery, size_t xquery_size, struct GNUNET_BLOCK_Group *bg, struct GNUNET_CONTAINER_BloomFilter *peer_bf)
Perform a GET operation.
@ GNUNET_NO
Definition: gnunet_common.h:94
enum GNUNET_GenericReturnValue GNUNET_BLOCK_group_set_seen(struct GNUNET_BLOCK_Group *bg, const struct GNUNET_HashCode *seen_results, unsigned int seen_results_count)
Update block group to filter out the given results.
Definition: block.c:343
void GNUNET_BLOCK_group_destroy(struct GNUNET_BLOCK_Group *bg)
Destroy resources used by a block group.
Definition: block.c:173
struct GNUNET_BLOCK_Group * GNUNET_BLOCK_group_create(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, uint32_t nonce, const void *raw_data, size_t raw_data_size,...)
Create a new block group.
Definition: block.c:228
struct GNUNET_CONTAINER_BloomFilter * GNUNET_CONTAINER_bloomfilter_init(const char *data, size_t size, unsigned int k)
Create a Bloom filter from raw bits.
void GNUNET_CONTAINER_bloomfilter_free(struct GNUNET_CONTAINER_BloomFilter *bf)
Free the space associated with a filter in memory, flush to drive if needed (do not free the space on...
#define GNUNET_CONSTANTS_BLOOMFILTER_K
K-value that must be used for the bloom filters in 'GET' queries.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
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_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:315
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
unsigned int seen_replies_count
Number of entries in seen_replies.
size_t xquery_size
Number of bytes in xquery.
struct GNUNET_TIME_Relative retry_frequency
What's the delay between re-try operations that we currently use for this request?
struct GNUNET_HashCode * seen_replies
Array of (hashes of) replies we have already seen for this request.
enum GNUNET_DHT_RouteOption msg_options
Any message options for this request.
struct GNUNET_HashCode key
The key this request was about.
enum GNUNET_BLOCK_Type type
The type for the data for the GET request.
const void * xquery
Extended query (see gnunet_block_lib.h), allocated at the end of this struct.
struct GNUNET_TIME_Absolute retry_time
What's the next time we should re-try this request?
uint32_t replication
Desired replication level.
Block group data.

References DHT_BLOOM_SIZE, GDS_block_context, GDS_NEIGHBOURS_handle_get(), GDS_stats, GNUNET_BLOCK_group_create(), GNUNET_BLOCK_group_destroy(), GNUNET_BLOCK_group_set_seen(), GNUNET_CONSTANTS_BLOOMFILTER_K, GNUNET_CONTAINER_bloomfilter_free(), GNUNET_CONTAINER_bloomfilter_init(), GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_STD_BACKOFF, ClientQueryRecord::key, LOG, ClientQueryRecord::msg_options, ClientQueryRecord::replication, ClientQueryRecord::retry_frequency, ClientQueryRecord::retry_time, ClientQueryRecord::seen_replies, ClientQueryRecord::seen_replies_count, ClientQueryRecord::type, ClientQueryRecord::xquery, and ClientQueryRecord::xquery_size.

Referenced by check_dht_local_put().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ transmit_next_request_task()

static void transmit_next_request_task ( void *  cls)
static

Task that looks at the retry_heap and transmits all of the requests on the heap that are ready for transmission.

Then re-schedules itself (unless the heap is empty).

Parameters
clsunused

Definition at line 431 of file gnunet-service-dht_clients.c.

432 {
433  struct ClientQueryRecord *cqr;
434 
435  (void) cls;
436  retry_task = NULL;
437  while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap)))
438  {
439  cqr->hnode = NULL;
441  {
442  cqr->hnode
444  cqr,
445  cqr->retry_time.abs_value_us);
446  retry_task
449  NULL);
450  return;
451  }
452  transmit_request (cqr);
453  cqr->hnode
455  cqr,
456  cqr->retry_time.abs_value_us);
457  }
458 }
static void transmit_request(struct ClientQueryRecord *cqr)
Route the given request via the DHT.
static struct GNUNET_CONTAINER_Heap * retry_heap
Heap with all of our client's request, sorted by retry time (earliest on top).
static struct GNUNET_SCHEDULER_Task * retry_task
Task that re-transmits requests (using retry_heap).
static void transmit_next_request_task(void *cls)
Task that looks at the retry_heap and transmits all of the requests on the heap that are ready for tr...
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_at(struct GNUNET_TIME_Absolute at, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run at the specified time.
Definition: scheduler.c:1231
bool GNUNET_TIME_absolute_is_past(struct GNUNET_TIME_Absolute abs)
Test if abs is truly in the past (excluding now).
Definition: time.c:668
struct GNUNET_CONTAINER_HeapNode * hnode
Pointer to this nodes heap location in the retry-heap (for fast removal)
uint64_t abs_value_us
The actual value.

Referenced by check_dht_local_get_result_seen(), and check_dht_local_put().

Here is the caller graph for this function:

◆ check_dht_local_put()

static enum GNUNET_GenericReturnValue check_dht_local_put ( void *  cls,
const struct GNUNET_DHT_ClientPutMessage dht_msg 
)
static

Check DHT PUT messages from the client.

Parameters
clsthe client we received this message from
dht_msgthe actual message received
Returns
GNUNET_OK (always)

Definition at line 431 of file gnunet-service-dht_clients.c.

471 {
472  uint32_t replication_level = ntohl (dht_msg->desired_replication_level);
473 
474  (void) cls;
476  {
477  GNUNET_break_op (0);
478  return GNUNET_SYSERR;
479  }
480  return GNUNET_OK;
481 }
static unsigned int replication_level
Replication level option to use for publishing.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
#define GNUNET_DHT_MAXIMUM_REPLICATION_LEVEL
Maximum allowed replication level for all requests.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
uint32_t desired_replication_level
Replication level for this message.
Definition: dht.h:209

References GNUNET_TIME_Absolute::abs_value_us, GNUNET_CONTAINER_heap_insert(), GNUNET_CONTAINER_heap_remove_root(), GNUNET_SCHEDULER_add_at(), GNUNET_TIME_absolute_is_past(), ClientQueryRecord::hnode, retry_heap, retry_task, ClientQueryRecord::retry_time, transmit_next_request_task(), and transmit_request().

Here is the call graph for this function:

◆ handle_dht_local_put()

static void handle_dht_local_put ( void *  cls,
const struct GNUNET_DHT_ClientPutMessage dht_msg 
)
static

Handler for PUT messages.

Parameters
clsthe client we received this message from
dht_msgthe actual message received

Definition at line 491 of file gnunet-service-dht_clients.c.

493 {
494  struct ClientHandle *ch = cls;
495  uint16_t size = ntohs (dht_msg->header.size);
497  = (enum GNUNET_DHT_RouteOption) ntohl (dht_msg->options);
498  uint32_t replication_level
499  = ntohl (dht_msg->desired_replication_level);
500  struct GDS_DATACACHE_BlockData bd = {
501  .key = dht_msg->key,
502  .expiration_time = GNUNET_TIME_absolute_ntoh (dht_msg->expiration),
503  .data = &dht_msg[1],
504  .data_size = size - sizeof (*dht_msg),
505  .type = ntohl (dht_msg->type)
506  };
507 
509  "Handling local PUT of %lu-bytes for query %s of type %u\n",
510  (unsigned long) (size - sizeof(struct GNUNET_DHT_ClientPutMessage)),
511  GNUNET_h2s (&dht_msg->key),
512  (unsigned int) bd.type);
513  if (GNUNET_OK !=
515  bd.type,
516  bd.data,
517  bd.data_size))
518  {
519  GNUNET_break (0);
520  return;
521  }
523  "# PUT requests received from clients",
524  1,
525  GNUNET_NO);
527  "CLIENT-PUT %s\n",
528  GNUNET_h2s_full (&dht_msg->key));
529  /* give to local clients */
531  &bd.key,
532  0, NULL /* get path */));
533 
534  {
535  struct GNUNET_CONTAINER_BloomFilter *peer_bf;
536 
537  peer_bf
541  /* store locally */
543  (GDS_am_closest_peer (&dht_msg->key,
544  peer_bf)))
546  /* route to other peers */
547  if (GNUNET_OK !=
549  options,
551  0 /* hop count */,
552  peer_bf))
553  {
555  "# Local PUT requests not routed",
556  1,
557  GNUNET_NO);
558  }
560  }
562  options,
563  &bd,
564  0, /* hop count */
567 }
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
void GDS_CLIENTS_process_put(enum GNUNET_DHT_RouteOption options, const struct GDS_DATACACHE_BlockData *bd, uint32_t hop_count, uint32_t desired_replication_level)
Check if some client is monitoring PUT messages and notify them in that case.
bool GDS_CLIENTS_handle_reply(const struct GDS_DATACACHE_BlockData *bd, const struct GNUNET_HashCode *query_hash, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *get_path)
Handle a reply we've received from another peer.
#define LOG_TRAFFIC(kind,...)
Should routing details be logged to stderr (for debugging)?
void GDS_DATACACHE_handle_put(const struct GDS_DATACACHE_BlockData *bd)
Handle a datum we've received from another peer.
enum GNUNET_GenericReturnValue GDS_NEIGHBOURS_handle_put(const struct GDS_DATACACHE_BlockData *bd, enum GNUNET_DHT_RouteOption options, uint16_t desired_replication_level, uint16_t hop_count, struct GNUNET_CONTAINER_BloomFilter *bf)
Perform a PUT operation.
enum GNUNET_GenericReturnValue GDS_am_closest_peer(const struct GNUNET_HashCode *key, const struct GNUNET_CONTAINER_BloomFilter *bloom)
Check whether my identity is closer than any known peers.
enum GNUNET_GenericReturnValue GNUNET_BLOCK_check_block(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, const void *block, size_t block_size)
Function called to validate a block.
Definition: block.c:299
GNUNET_DHT_RouteOption
Options for routing.
@ GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE
Each peer along the way should process the request (otherwise only peers locally closest to the key w...
const char * GNUNET_h2s_full(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2248
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:736
static unsigned int size
Size of the "table".
Definition: peer.c:67
Information about a block stored in the datacache.
const void * data
Actual block data.
size_t data_size
Number of bytes in data.
enum GNUNET_BLOCK_Type type
Type of the block.
struct GNUNET_HashCode key
Key of the block.
Message to insert data into the DHT, sent from clients to DHT service.
Definition: dht.h:190
struct GNUNET_HashCode key
The key to store the value under.
Definition: dht.h:219
uint32_t type
The type of data to insert.
Definition: dht.h:199
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition: dht.h:204
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT.
Definition: dht.h:194
struct GNUNET_TIME_AbsoluteNBO expiration
How long should this data persist?
Definition: dht.h:214
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.

References ch, GDS_DATACACHE_BlockData::data, GDS_DATACACHE_BlockData::data_size, GNUNET_DHT_ClientPutMessage::desired_replication_level, DHT_BLOOM_SIZE, GNUNET_DHT_ClientPutMessage::expiration, GDS_am_closest_peer(), GDS_block_context, GDS_CLIENTS_handle_reply(), GDS_CLIENTS_process_put(), GDS_DATACACHE_handle_put(), GDS_NEIGHBOURS_handle_put(), GDS_stats, GNUNET_BLOCK_check_block(), GNUNET_break, GNUNET_CONSTANTS_BLOOMFILTER_K, GNUNET_CONTAINER_bloomfilter_free(), GNUNET_CONTAINER_bloomfilter_init(), GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_h2s_full(), GNUNET_NO, GNUNET_OK, GNUNET_SERVICE_client_continue(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_ntoh(), GNUNET_DHT_ClientPutMessage::header, GNUNET_DHT_ClientPutMessage::key, GDS_DATACACHE_BlockData::key, LOG, LOG_TRAFFIC, options, GNUNET_DHT_ClientPutMessage::options, replication_level, GNUNET_MessageHeader::size, size, GNUNET_DHT_ClientPutMessage::type, and GDS_DATACACHE_BlockData::type.

Here is the call graph for this function:

◆ handle_local_result()

static void handle_local_result ( void *  cls,
const struct GDS_DATACACHE_BlockData bd 
)
static

Handle a result from local datacache for a GET operation.

Parameters
clsthe struct ClientHandle of the client doing the query
bddetails about the block that was found

Definition at line 577 of file gnunet-service-dht_clients.c.

579 {
581  "Datacache provided result for query key %s\n",
582  GNUNET_h2s (&bd->key));
584  &bd->key,
585  0, NULL /* get_path */));
586 }
@ GNUNET_ERROR_TYPE_INFO

Referenced by check_dht_local_get_result_seen().

Here is the caller graph for this function:

◆ check_dht_local_get()

static enum GNUNET_GenericReturnValue check_dht_local_get ( void *  cls,
const struct GNUNET_DHT_ClientGetMessage get 
)
static

Check DHT GET messages from the client.

Parameters
clsthe client we received this message from
messagethe actual message received
Returns
GNUNET_OK (always)

Definition at line 577 of file gnunet-service-dht_clients.c.

599 {
600  (void) cls;
601  (void) get;
602  /* always well-formed */
603  return GNUNET_OK;
604 }
static int get
Get DID Documement for DID Flag.
Definition: gnunet-did.c:64

References GDS_CLIENTS_handle_reply(), GNUNET_break, GNUNET_ERROR_TYPE_INFO, GNUNET_h2s(), GNUNET_log, and GDS_DATACACHE_BlockData::key.

Here is the call graph for this function:

◆ handle_dht_local_get()

static void handle_dht_local_get ( void *  cls,
const struct GNUNET_DHT_ClientGetMessage get 
)
static

Handler for DHT GET messages from the client.

Parameters
clsthe client we received this message from
messagethe actual message received

Definition at line 614 of file gnunet-service-dht_clients.c.

616 {
617  struct ClientHandle *ch = cls;
618  struct ClientQueryRecord *cqr;
619  uint16_t size = ntohs (get->header.size);
620  const char *xquery = (const char *) &get[1];
621  size_t xquery_size = size - sizeof(struct GNUNET_DHT_ClientGetMessage);
622 
624  "Received GET request for %s from local client %p, xq: %.*s\n",
625  GNUNET_h2s (&get->key),
626  ch->client,
627  (int) xquery_size,
628  xquery);
630  "# GET requests received from clients",
631  1,
632  GNUNET_NO);
634  "CLIENT-GET %s\n",
635  GNUNET_h2s_full (&get->key));
636 
637  cqr = GNUNET_malloc (sizeof(struct ClientQueryRecord) + xquery_size);
638  cqr->key = get->key;
639  cqr->ch = ch;
640  cqr->xquery = (const void *) &cqr[1];
641  GNUNET_memcpy (&cqr[1],
642  xquery,
643  xquery_size);
645  cqr,
646  0);
649  cqr->unique_id = get->unique_id;
650  cqr->xquery_size = xquery_size;
651  cqr->replication = ntohl (get->desired_replication_level);
652  cqr->msg_options = (enum GNUNET_DHT_RouteOption) ntohl (get->options);
653  cqr->type = ntohl (get->type);
654  GNUNET_CONTAINER_DLL_insert (ch->cqr_head,
655  ch->cqr_tail,
656  cqr);
658  &cqr->key,
659  cqr,
662  cqr->type,
663  0, /* hop count */
664  cqr->replication,
665  0, /* path length */
666  NULL,
667  &get->key);
668  /* start remote requests */
669  if (NULL != retry_task)
672  NULL);
673  /* perform local lookup */
675  cqr->type,
676  cqr->xquery,
677  xquery_size,
678  NULL,
680  ch);
682 }
static void handle_local_result(void *cls, const struct GDS_DATACACHE_BlockData *bd)
Handle a result from local datacache for a GET operation.
void GDS_CLIENTS_process_get(enum GNUNET_DHT_RouteOption options, enum GNUNET_BLOCK_Type type, uint32_t hop_count, uint32_t desired_replication_level, unsigned int path_length, const struct GNUNET_DHT_PathElement *path, const struct GNUNET_HashCode *key)
Check if some client is monitoring GET messages and notify them in that case.
enum GNUNET_BLOCK_ReplyEvaluationResult GDS_DATACACHE_handle_get(const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, const void *xquery, size_t xquery_size, struct GNUNET_BLOCK_Group *bg, GDS_DATACACHE_GetCallback gc, void *gc_cls)
Handle a GET request we've received from another peer.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
#define GNUNET_malloc(size)
Wrapper around malloc.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1281
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:110
struct ClientHandle * ch
Client responsible for the request.
uint64_t unique_id
The unique identifier of this request.
DHT GET message sent from clients to service.
Definition: dht.h:72

◆ find_by_unique_id()

static enum GNUNET_GenericReturnValue find_by_unique_id ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Function called for each existing DHT record for the given query.

Checks if it matches the UID given in the closure and if so returns the entry as a result.

Parameters
clsthe search context
keyquery for the lookup (not used)
valuethe struct ClientQueryRecord
Returns
GNUNET_YES to continue iteration (result not yet found)

Definition at line 614 of file gnunet-service-dht_clients.c.

716 {
717  struct FindByUniqueIdContext *fui_ctx = cls;
718  struct ClientQueryRecord *cqr = value;
719 
720  if (cqr->unique_id != fui_ctx->unique_id)
721  return GNUNET_YES;
722  fui_ctx->cqr = cqr;
723  return GNUNET_NO;
724 }
static char * value
Value of the record to add/remove.
Closure for find_by_unique_id().
uint64_t unique_id
Unique ID to look for.
struct ClientQueryRecord * cqr
Where to store the result, if found.

Referenced by handle_dht_local_get_result_seen().

Here is the caller graph for this function:

◆ check_dht_local_get_result_seen()

static enum GNUNET_GenericReturnValue check_dht_local_get_result_seen ( void *  cls,
const struct GNUNET_DHT_ClientGetResultSeenMessage seen 
)
static

Check "GET result seen" messages from the client.

Parameters
clsthe client we received this message from
messagethe actual message received
Returns
GNUNET_OK if seen is well-formed

Definition at line 614 of file gnunet-service-dht_clients.c.

738 {
739  uint16_t size = ntohs (seen->header.size);
740  unsigned int hash_count =
741  (size - sizeof(*seen))
742  / sizeof(struct GNUNET_HashCode);
743 
744  if (size != sizeof(*seen) + hash_count * sizeof(struct GNUNET_HashCode))
745  {
746  GNUNET_break (0);
747  return GNUNET_SYSERR;
748  }
749  return GNUNET_OK;
750 }
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN.
Definition: dht.h:118
A 512-bit hashcode.

References ch, ClientQueryRecord::ch, forward_map, GDS_CLIENTS_process_get(), GDS_DATACACHE_handle_get(), GDS_stats, get, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_heap_insert(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_h2s_full(), GNUNET_malloc, GNUNET_memcpy, GNUNET_NO, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_SERVICE_client_continue(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get(), GNUNET_TIME_UNIT_SECONDS, handle_local_result(), ClientQueryRecord::hnode, ClientQueryRecord::key, LOG, LOG_TRAFFIC, ClientQueryRecord::msg_options, ClientQueryRecord::replication, ClientQueryRecord::retry_frequency, retry_heap, retry_task, ClientQueryRecord::retry_time, size, transmit_next_request_task(), ClientQueryRecord::type, ClientQueryRecord::unique_id, ClientQueryRecord::xquery, and ClientQueryRecord::xquery_size.

Here is the call graph for this function:

◆ handle_dht_local_get_result_seen()

static void handle_dht_local_get_result_seen ( void *  cls,
const struct GNUNET_DHT_ClientGetResultSeenMessage seen 
)
static

Handler for "GET result seen" messages from the client.

Parameters
clsthe client we received this message from
messagethe actual message received

Definition at line 760 of file gnunet-service-dht_clients.c.

763 {
764  struct ClientHandle *ch = cls;
765  uint16_t size = ntohs (seen->header.size);
766  unsigned int hash_count = (size - sizeof(*seen))
767  / sizeof(struct GNUNET_HashCode);
768  const struct GNUNET_HashCode *hc = (const struct GNUNET_HashCode*) &seen[1];
769  struct FindByUniqueIdContext fui_ctx = {
770  .unique_id = seen->unique_id
771  };
772  unsigned int old_count;
773  struct ClientQueryRecord *cqr;
774 
776  &seen->key,
778  &fui_ctx);
779  if (NULL == (cqr = fui_ctx.cqr))
780  {
781  GNUNET_break (0);
782  GNUNET_SERVICE_client_drop (ch->client);
783  return;
784  }
785  /* finally, update 'seen' list */
786  old_count = cqr->seen_replies_count;
788  cqr->seen_replies_count,
789  cqr->seen_replies_count + hash_count);
790  GNUNET_memcpy (&cqr->seen_replies[old_count],
791  hc,
792  sizeof(struct GNUNET_HashCode) * hash_count);
793 }
static enum GNUNET_GenericReturnValue find_by_unique_id(void *cls, const struct GNUNET_HashCode *key, void *value)
Function called for each existing DHT record for the given query.
int GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2329
struct GNUNET_HashCode key
The key we are searching for (to make it easy to find the corresponding GET inside the service).
Definition: dht.h:129
uint64_t unique_id
Unique ID identifying this request.
Definition: dht.h:134

References ch, FindByUniqueIdContext::cqr, find_by_unique_id(), forward_map, GNUNET_array_grow, GNUNET_break, GNUNET_CONTAINER_multihashmap_get_multiple(), GNUNET_memcpy, GNUNET_SERVICE_client_drop(), GNUNET_DHT_ClientGetResultSeenMessage::header, GNUNET_DHT_ClientGetResultSeenMessage::key, ClientQueryRecord::seen_replies, ClientQueryRecord::seen_replies_count, GNUNET_MessageHeader::size, size, GNUNET_DHT_ClientGetResultSeenMessage::unique_id, and FindByUniqueIdContext::unique_id.

Here is the call graph for this function:

◆ remove_by_unique_id()

static enum GNUNET_GenericReturnValue remove_by_unique_id ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Iterator over hash map entries that frees all entries that match the given client and unique ID.

Parameters
clsunique ID and client to search for in source routes
keycurrent key code
valuevalue in the hash map, a ClientQueryRecord
Returns
GNUNET_YES (we should continue to iterate)

Definition at line 760 of file gnunet-service-dht_clients.c.

826 {
827  const struct RemoveByUniqueIdContext *ctx = cls;
828  struct ClientQueryRecord *cqr = value;
829 
830  if (cqr->unique_id != ctx->unique_id)
831  return GNUNET_YES;
833  "Removing client %p's record for key %s (by unique id)\n",
834  ctx->ch->client,
835  GNUNET_h2s (key));
837  return GNUNET_YES;
838 }
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
Closure for remove_by_unique_id().

Referenced by forward_reply().

Here is the caller graph for this function:

◆ handle_dht_local_get_stop()

static void handle_dht_local_get_stop ( void *  cls,
const struct GNUNET_DHT_ClientGetStopMessage dht_stop_msg 
)
static

Handler for any generic DHT stop messages, calls the appropriate handler depending on message type (if processed locally)

Parameters
clsclient we received this message from
messagethe actual message received

Definition at line 850 of file gnunet-service-dht_clients.c.

853 {
854  struct ClientHandle *ch = cls;
856 
858  "# GET STOP requests received from clients",
859  1,
860  GNUNET_NO);
862  "Received GET STOP request for %s from local client %p\n",
863  GNUNET_h2s (&dht_stop_msg->key),
864  ch->client);
865  ctx.ch = ch;
866  ctx.unique_id = dht_stop_msg->unique_id;
868  &dht_stop_msg->key,
870  &ctx);
872 }
static enum GNUNET_GenericReturnValue remove_by_unique_id(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over hash map entries that frees all entries that match the given client and unique ID.
uint64_t unique_id
Unique ID identifying this request.
Definition: dht.h:58
struct GNUNET_HashCode key
Key of this request.
Definition: dht.h:63

◆ forward_reply()

static enum GNUNET_GenericReturnValue forward_reply ( void *  cls,
const struct GNUNET_HashCode query_hash,
void *  value 
)
static

Iterator over hash map entries that send a given reply to each of the matching clients.

With some tricky recycling of the buffer.

Parameters
clsthe struct ForwardReplyContext
query_hashhash of the query for which this may be a reply
valuevalue in the hash map, a ClientQueryRecord
Returns
GNUNET_YES (we should continue to iterate), if the result is mal-formed, GNUNET_NO

Definition at line 850 of file gnunet-service-dht_clients.c.

913 {
914  struct ForwardReplyContext *frc = cls;
915  struct ClientQueryRecord *record = value;
916  struct GNUNET_MQ_Envelope *env;
917  struct GNUNET_DHT_ClientResultMessage *reply;
919  bool do_free;
920  struct GNUNET_HashCode ch;
921  struct GNUNET_DHT_PathElement *paths;
922 
924  "CLIENT-RESULT %s\n",
925  GNUNET_h2s_full (&frc->bd->key));
926  if ( (record->type != GNUNET_BLOCK_TYPE_ANY) &&
927  (record->type != frc->bd->type) )
928  {
930  "Record type mismatch, not passing request for key %s to local client\n",
931  GNUNET_h2s (&frc->bd->key));
933  "# Key match, type mismatches in REPLY to CLIENT",
934  1,
935  GNUNET_NO);
936  return GNUNET_YES; /* type mismatch */
937  }
938  if ( (0 == (record->msg_options & GNUNET_DHT_RO_FIND_APPROXIMATE)) &&
939  (0 != GNUNET_memcmp (&frc->bd->key,
940  query_hash)) )
941  {
943  "# Inexact key match, but exact match required",
944  1,
945  GNUNET_NO);
946  return GNUNET_YES; /* type mismatch */
947  }
948  GNUNET_CRYPTO_hash (frc->bd->data,
949  frc->bd->data_size,
950  &ch);
951  for (unsigned int i = 0; i < record->seen_replies_count; i++)
952  if (0 ==
953  GNUNET_memcmp (&record->seen_replies[i],
954  &ch))
955  {
957  "Duplicate reply, not passing request for key %s to local client\n",
958  GNUNET_h2s (&frc->bd->key));
960  "# Duplicate REPLIES to CLIENT request dropped",
961  1,
962  GNUNET_NO);
963  return GNUNET_YES; /* duplicate */
964  }
965  eval
967  record->type,
968  NULL,
969  &frc->bd->key,
970  record->xquery,
971  record->xquery_size,
972  frc->bd->data,
973  frc->bd->data_size);
975  "Evaluation result is %d for key %s for local client's query\n",
976  (int) eval,
977  GNUNET_h2s (&frc->bd->key));
978  switch (eval)
979  {
981  do_free = true;
982  break;
985  GNUNET_array_append (record->seen_replies,
986  record->seen_replies_count,
987  ch);
988  do_free = false;
989  break;
991  /* should be impossible to encounter here */
992  GNUNET_break (0);
993  return GNUNET_YES;
995  return GNUNET_YES;
996  default:
997  GNUNET_break (0);
998  return GNUNET_NO;
999  }
1001  "# RESULTS queued for clients",
1002  1,
1003  GNUNET_NO);
1004  env = GNUNET_MQ_msg_extra (reply,
1005  frc->bd->data_size
1006  + (frc->get_path_length + frc->bd->put_path_length)
1007  * sizeof(struct GNUNET_DHT_PathElement),
1009  reply->type = htonl (frc->bd->type);
1010  reply->get_path_length = htonl (frc->get_path_length);
1011  reply->put_path_length = htonl (frc->bd->put_path_length);
1012  reply->unique_id = record->unique_id;
1014  reply->key = *query_hash;
1015  paths = (struct GNUNET_DHT_PathElement *) &reply[1];
1016  GNUNET_memcpy (paths,
1017  frc->bd->put_path,
1018  sizeof(struct GNUNET_DHT_PathElement)
1019  * frc->bd->put_path_length);
1020  GNUNET_memcpy (&paths[frc->bd->put_path_length],
1021  frc->get_path,
1022  sizeof(struct GNUNET_DHT_PathElement)
1023  * frc->get_path_length);
1024  GNUNET_memcpy (&paths[frc->get_path_length + frc->bd->put_path_length],
1025  frc->bd->data,
1026  frc->bd->data_size);
1028  "Sending reply to query %s for client %p\n",
1029  GNUNET_h2s (query_hash),
1030  record->ch->client);
1031  GNUNET_MQ_send (record->ch->mq,
1032  env);
1033  if (GNUNET_YES == do_free)
1035  return GNUNET_YES;
1036 }
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
@ GNUNET_BLOCK_TYPE_ANY
Identifier for any block.
enum GNUNET_BLOCK_ReplyEvaluationResult GNUNET_BLOCK_check_reply(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, struct GNUNET_BLOCK_Group *group, const struct GNUNET_HashCode *query, const void *xquery, size_t xquery_size, const void *reply_block, size_t reply_block_size)
Function called to validate if a reply is good for a particular query.
Definition: block.c:317
GNUNET_BLOCK_ReplyEvaluationResult
Possible ways for how a block may relate to a query.
@ GNUNET_BLOCK_REPLY_OK_MORE
Valid result, and there may be more.
@ GNUNET_BLOCK_REPLY_OK_DUPLICATE
Valid result, but suppressed because it is a duplicate.
@ GNUNET_BLOCK_REPLY_OK_LAST
Last possible valid result.
@ GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED
Specified block type not supported by any plugin.
@ GNUNET_BLOCK_REPLY_IRRELEVANT
Block does not match xquery (valid result, not relevant for the request)
@ GNUNET_DHT_RO_FIND_APPROXIMATE
Approximate results are fine.
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
#define GNUNET_array_append(arr, len, element)
Append an element to an array (growing the array by one).
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_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
#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT
Service returns result to client.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:637
Closure for forward_reply()
const struct GNUNET_DHT_PathElement * get_path
GET path taken.
const struct GDS_DATACACHE_BlockData * bd
Block details.
unsigned int get_path_length
Number of entries in get_path.
const struct GNUNET_DHT_PathElement * put_path
PUT path taken by the block, array of peer identities.
struct GNUNET_TIME_Absolute expiration_time
When does the block expire?
unsigned int put_path_length
Length of the put_path array.
Reply to a GET send from the service to a client.
Definition: dht.h:144
uint32_t put_path_length
Number of peers recorded in the outgoing path from source to the storgage location of this message.
Definition: dht.h:159
uint64_t unique_id
Unique ID of the matching GET request.
Definition: dht.h:170
struct GNUNET_TIME_AbsoluteNBO expiration
When does this entry expire?
Definition: dht.h:175
struct GNUNET_HashCode key
The key that was searched for.
Definition: dht.h:180
uint32_t type
The type for the data.
Definition: dht.h:153
uint32_t get_path_length
The number of peer identities recorded from the storage location to this peer.
Definition: dht.h:165
A (signed) path tracking a block's flow through the DHT is represented by an array of path elements,...

References ch, ctx, forward_map, GDS_stats, GNUNET_CONTAINER_multihashmap_get_multiple(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_NO, GNUNET_SERVICE_client_continue(), GNUNET_STATISTICS_update(), GNUNET_DHT_ClientGetStopMessage::key, LOG, remove_by_unique_id(), and GNUNET_DHT_ClientGetStopMessage::unique_id.

Referenced by GDS_CLIENTS_handle_reply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GDS_CLIENTS_handle_reply()

bool GDS_CLIENTS_handle_reply ( const struct GDS_DATACACHE_BlockData bd,
const struct GNUNET_HashCode query_hash,
unsigned int  get_path_length,
const struct GNUNET_DHT_PathElement get_path 
)

Handle a reply we've received from another peer.

If the reply matches any of our pending queries, forward it to the respective client(s).

Parameters
bdblock details
query_hashhash of the original query, might not match key in bd
get_path_lengthnumber of entries in get_path
get_pathpath the reply has taken
Returns
true on success, false on failures

Definition at line 1040 of file gnunet-service-dht_clients.c.

1044 {
1045  struct ForwardReplyContext frc;
1046  size_t msize = sizeof (struct GNUNET_DHT_ClientResultMessage)
1047  + bd->data_size
1049  * sizeof(struct GNUNET_DHT_PathElement);
1050 
1051  if (msize >= GNUNET_MAX_MESSAGE_SIZE)
1052  {
1053  GNUNET_break (0);
1054  return false;
1055  }
1056 #if SANITY_CHECKS > 1
1057  if (0 !=
1059  bd->data_size,
1060  bd->expiration_time,
1061  bd->put_path,
1062  bd->put_path_length,
1063  get_path,
1064  get_path_length,
1065  &GDS_my_identity))
1066  {
1067  GNUNET_break (0);
1068  return false;
1069  }
1070 #endif
1071  frc.bd = bd;
1072  frc.get_path = get_path;
1073  frc.get_path_length = get_path_length;
1075  "Forwarding reply for query hash %s with GPL %u and PPL %u to client\n",
1076  GNUNET_h2s (query_hash),
1077  get_path_length,
1078  bd->put_path_length);
1079  if (0 ==
1081  query_hash,
1082  &forward_reply,
1083  &frc))
1084  {
1086  "No matching client for reply for query %s\n",
1087  GNUNET_h2s (query_hash));
1089  "# REPLIES ignored for CLIENTS (no match)",
1090  1,
1091  GNUNET_NO);
1092  }
1093  return true;
1094 }
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
struct GNUNET_PeerIdentity GDS_my_identity
Identity of this peer.
static enum GNUNET_GenericReturnValue forward_reply(void *cls, const struct GNUNET_HashCode *query_hash, void *value)
Iterator over hash map entries that send a given reply to each of the matching clients.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
unsigned int GNUNET_DHT_verify_path(const void *data, size_t data_size, struct GNUNET_TIME_Absolute exp_time, const struct GNUNET_DHT_PathElement *put_path, unsigned int put_path_len, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_len, const struct GNUNET_PeerIdentity *me)
Verify signatures on a path consisting of put_path and get_path in reverse order (starting at the las...
Definition: dht_api.c:1303

References ForwardReplyContext::bd, GDS_DATACACHE_BlockData::data, data_size, GDS_DATACACHE_BlockData::data_size, GDS_DATACACHE_BlockData::expiration_time, forward_map, forward_reply(), GDS_my_identity, GDS_stats, ForwardReplyContext::get_path, GNUNET_DHT_ClientResultMessage::get_path_length, ForwardReplyContext::get_path_length, GNUNET_break, GNUNET_CONTAINER_multihashmap_get_multiple(), GNUNET_DHT_verify_path(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_MAX_MESSAGE_SIZE, GNUNET_NO, GNUNET_STATISTICS_update(), LOG, GDS_DATACACHE_BlockData::put_path, GNUNET_DHT_ClientResultMessage::put_path_length, and GDS_DATACACHE_BlockData::put_path_length.

Referenced by check_dht_local_get(), check_dht_p2p_result(), handle_dht_local_put(), and handle_dht_p2p_put().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_dht_local_hello_get()

static void handle_dht_local_hello_get ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

Handler for HELLO GET message.

Reply to client with a URL of our HELLO.

Parameters
clsthe client we received this message from
msgthe actual message received

Definition at line 1108 of file gnunet-service-dht_clients.c.

1110 {
1111  struct ClientHandle *ch = cls;
1114  size_t slen = strlen (url) + 1;
1115  struct GNUNET_MessageHeader *hdr;
1116  struct GNUNET_MQ_Envelope *env;
1117 
1119  "Handling request from local client for my HELLO\n");
1120  env = GNUNET_MQ_msg_extra (hdr,
1121  slen,
1123  memcpy (&hdr[1],
1124  url,
1125  slen);
1126  GNUNET_free (url);
1127  GNUNET_MQ_send (ch->mq,
1128  env);
1130 }
struct GNUNET_CRYPTO_EddsaPrivateKey GDS_my_private_key
Our private key.
struct GNUNET_HELLO_Builder * GDS_my_hello
Our HELLO.
char * GNUNET_HELLO_builder_to_url(const struct GNUNET_HELLO_Builder *builder, const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
Generate GNUnet HELLO URI from a builder.
Definition: hello-uri.c:627
#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_URL
HELLO URL send between client and service (in either direction).
Header for all communications.

◆ check_dht_local_hello_offer()

static enum GNUNET_GenericReturnValue check_dht_local_hello_offer ( void *  cls,
const struct GNUNET_MessageHeader hdr 
)
static

Process a client HELLO message received from the service.

Parameters
clsthe client we received this message from
hdrHELLO URL message from the service.
Returns
GNUNET_OK if hdr is well-formed

Definition at line 1108 of file gnunet-service-dht_clients.c.

1143 {
1144  uint16_t len = ntohs (hdr->size);
1145  const char *buf = (const char *) &hdr[1];
1146 
1147  (void) cls;
1148  if ('\0' != buf[len - sizeof (*hdr) - 1])
1149  {
1150  GNUNET_break (0);
1151  return GNUNET_SYSERR;
1152  }
1153  return GNUNET_OK;
1154 }
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static char buf[2048]

References ch, env, GDS_my_hello, GDS_my_private_key, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_HELLO_builder_to_url(), GNUNET_log, GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_URL, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_SERVICE_client_continue(), and GNUNET_CADET_Channel::mq.

Here is the call graph for this function:

◆ handle_dht_local_hello_offer()

static void handle_dht_local_hello_offer ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

Handler for HELLO OFFER message.

Try to use the HELLO to connect to another peer.

Parameters
clsthe client we received this message from
msgthe actual message received

Definition at line 1165 of file gnunet-service-dht_clients.c.

1167 {
1168  struct ClientHandle *ch = cls;
1169  const char *url = (const char *) &msg[1];
1170  struct GNUNET_HELLO_Builder *b;
1171  struct GNUNET_PeerIdentity pid;
1172 
1174  "Local client provided HELLO URL %s\n",
1175  url);
1177  if (NULL == b)
1178  {
1179  GNUNET_break (0);
1180  GNUNET_SERVICE_client_drop (ch->client);
1181  return;
1182  }
1185  &pid,
1186  &GDS_try_connect,
1187  &pid);
1189 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
void GDS_try_connect(void *cls, const char *uri)
Callback function used to extract URIs from a builder.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
void GNUNET_HELLO_builder_free(struct GNUNET_HELLO_Builder *builder)
Release resources of a builder.
Definition: hello-uri.c:312
void GNUNET_HELLO_builder_iterate(const struct GNUNET_HELLO_Builder *builder, struct GNUNET_PeerIdentity *pid, GNUNET_HELLO_UriCallback uc, void *uc_cls)
Iterate over URIs in a builder.
Definition: hello-uri.c:815
struct GNUNET_HELLO_Builder * GNUNET_HELLO_builder_from_url(const char *url)
Parse GNUnet HELLO url into builder.
Definition: hello-uri.c:409
Context for building (or parsing) HELLO URIs.
Definition: hello-uri.c:184
The identity of the host (wraps the signing key of the peer).

References ch, GDS_try_connect(), GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_HELLO_builder_free(), GNUNET_HELLO_builder_from_url(), GNUNET_HELLO_builder_iterate(), GNUNET_log, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), msg, and pid.

Here is the call graph for this function:

◆ handle_dht_local_monitor()

static void handle_dht_local_monitor ( void *  cls,
const struct GNUNET_DHT_MonitorStartStopMessage msg 
)
static

Handler for monitor start messages.

Parameters
clsthe client we received this message from
msgthe actual message received

Definition at line 1203 of file gnunet-service-dht_clients.c.

1205 {
1206  struct ClientHandle *ch = cls;
1207  struct ClientMonitorRecord *r;
1208 
1209  r = GNUNET_new (struct ClientMonitorRecord);
1210  r->ch = ch;
1211  r->type = ntohl (msg->type);
1212  r->get = ntohs (msg->get);
1213  r->get_resp = ntohs (msg->get_resp);
1214  r->put = ntohs (msg->put);
1215  if (0 != ntohs (msg->filter_key))
1216  r->key = msg->key;
1218  monitor_tail,
1219  r);
1221 }
uint16_t put
Flag whether to notify about PUT messages.
struct ClientHandle * ch
Client to notify of these requests.
enum GNUNET_BLOCK_Type type
Type of blocks that are of interest.
int16_t get
Flag whether to notify about GET messages.
struct GNUNET_HashCode key
Key of data of interest.
int16_t get_resp
Flag whether to notify about GET_REPONSE messages.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.

References ch, ClientMonitorRecord::ch, ClientMonitorRecord::get, ClientMonitorRecord::get_resp, GNUNET_CONTAINER_DLL_insert, GNUNET_new, GNUNET_SERVICE_client_continue(), ClientMonitorRecord::key, monitor_head, monitor_tail, msg, ClientMonitorRecord::put, ClientMonitorRecord::type, and GNUNET_MessageHeader::type.

Here is the call graph for this function:

◆ handle_dht_local_monitor_stop()

static void handle_dht_local_monitor_stop ( void *  cls,
const struct GNUNET_DHT_MonitorStartStopMessage msg 
)
static

Handler for monitor stop messages.

Parameters
clsthe client we received this message from
msgthe actual message received

Definition at line 1231 of file gnunet-service-dht_clients.c.

1234 {
1235  struct ClientHandle *ch = cls;
1236 
1238  for (struct ClientMonitorRecord *r = monitor_head;
1239  NULL != r;
1240  r = r->next)
1241  {
1242  bool keys_match;
1243 
1244  keys_match =
1245  (GNUNET_is_zero (&r->key))
1246  ? (0 == ntohs (msg->filter_key))
1247  : ( (0 != ntohs (msg->filter_key)) &&
1248  (! GNUNET_memcmp (&r->key,
1249  &msg->key)) );
1250  if ( (ch == r->ch) &&
1251  (ntohl (msg->type) == r->type) &&
1252  (r->get == msg->get) &&
1253  (r->get_resp == msg->get_resp) &&
1254  (r->put == msg->put) &&
1255  keys_match)
1256  {
1258  monitor_tail,
1259  r);
1260  GNUNET_free (r);
1261  return; /* Delete only ONE entry */
1262  }
1263  }
1264 }
#define GNUNET_is_zero(a)
Check that memory in a is all zeros.

References ch, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_is_zero, GNUNET_memcmp, GNUNET_SERVICE_client_continue(), monitor_head, monitor_tail, msg, ClientMonitorRecord::next, and GNUNET_MessageHeader::type.

Here is the call graph for this function:

◆ for_matching_monitors()

static void for_matching_monitors ( enum GNUNET_BLOCK_Type  type,
const struct GNUNET_HashCode key,
MonitorAction  cb,
void *  cb_cls 
)
static

Call cb on all monitors that watch for blocks of type and key key.

Parameters
typethe type to match
keythe key to match
cbfunction to call
cb_clsclosure for cb

Definition at line 1288 of file gnunet-service-dht_clients.c.

1292 {
1293  struct ClientHandle **cl = NULL;
1294  unsigned int cl_size = 0;
1295 
1296  for (struct ClientMonitorRecord *m = monitor_head;
1297  NULL != m;
1298  m = m->next)
1299  {
1300  if ( ( (GNUNET_BLOCK_TYPE_ANY == m->type) ||
1301  (m->type == type) ) &&
1302  ( (GNUNET_is_zero (&m->key)) ||
1303  (0 ==
1304  GNUNET_memcmp (key,
1305  &m->key)) ) )
1306  {
1307  unsigned int i;
1308 
1309  /* Don't send duplicates */
1310  for (i = 0; i < cl_size; i++)
1311  if (cl[i] == m->ch)
1312  break;
1313  if (i < cl_size)
1314  continue;
1315  GNUNET_array_append (cl,
1316  cl_size,
1317  m->ch);
1318  cb (cb_cls,
1319  m);
1320  }
1321  }
1322  GNUNET_free (cl);
1323 }
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model

References GNUNET_array_append, GNUNET_BLOCK_TYPE_ANY, GNUNET_free, GNUNET_is_zero, GNUNET_memcmp, key, m, monitor_head, and type.

Referenced by GDS_CLIENTS_process_get(), GDS_CLIENTS_process_get_resp(), and GDS_CLIENTS_process_put().

Here is the caller graph for this function:

◆ get_action()

static void get_action ( void *  cls,
struct ClientMonitorRecord m 
)
static

Function called on monitors that match a GET.

Sends the GET notification to the monitor.

Parameters
clsa struct GetActionContext
ma matching monitor

Definition at line 1349 of file gnunet-service-dht_clients.c.

1351 {
1352  struct GetActionContext *gac = cls;
1353  struct GNUNET_MQ_Envelope *env;
1354  struct GNUNET_DHT_MonitorGetMessage *mmsg;
1355  struct GNUNET_DHT_PathElement *msg_path;
1356  size_t msize;
1357 
1358  msize = gac->get_path_length * sizeof(struct GNUNET_DHT_PathElement);
1359  env = GNUNET_MQ_msg_extra (mmsg,
1360  msize,
1362  mmsg->options = htonl (gac->options);
1363  mmsg->type = htonl (gac->type);
1364  mmsg->hop_count = htonl (gac->hop_count);
1366  mmsg->get_path_length = htonl (gac->get_path_length);
1367  mmsg->key = *gac->key;
1368  msg_path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
1369  GNUNET_memcpy (msg_path,
1370  gac->get_path,
1371  gac->get_path_length * sizeof(struct GNUNET_DHT_PathElement));
1372  GNUNET_MQ_send (m->ch->mq,
1373  env);
1374 }
#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET
Receive information about transiting GETs.
struct GNUNET_MQ_Handle * mq
Our control connection to the ARM service.
Message to monitor get requests going through peer, DHT service -> clients.
Definition: dht.h:324
uint32_t hop_count
Hop count.
Definition: dht.h:343
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition: dht.h:333
uint32_t desired_replication_level
Replication level for this message.
Definition: dht.h:348
struct GNUNET_HashCode key
The key to store the value under.
Definition: dht.h:359
uint32_t type
The type of data in the request.
Definition: dht.h:338
uint32_t get_path_length
Number of peers recorded in the outgoing path from source to the storage location of this message.
Definition: dht.h:354
Closure for get_action();.
const struct GNUNET_HashCode * key
enum GNUNET_DHT_RouteOption options
const struct GNUNET_DHT_PathElement * get_path
enum GNUNET_BLOCK_Type type

References GNUNET_DHT_MonitorGetMessage::desired_replication_level, GetActionContext::desired_replication_level, env, GetActionContext::get_path, GNUNET_DHT_MonitorGetMessage::get_path_length, GetActionContext::get_path_length, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_DHT_MonitorGetMessage::hop_count, GetActionContext::hop_count, GNUNET_DHT_MonitorGetMessage::key, GetActionContext::key, m, GNUNET_ARM_MonitorHandle::mq, GNUNET_DHT_MonitorGetMessage::options, GetActionContext::options, GNUNET_DHT_MonitorGetMessage::type, and GetActionContext::type.

Referenced by GDS_CLIENTS_process_get().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GDS_CLIENTS_process_get()

void GDS_CLIENTS_process_get ( enum GNUNET_DHT_RouteOption  options,
enum GNUNET_BLOCK_Type  type,
uint32_t  hop_count,
uint32_t  desired_replication_level,
unsigned int  path_length,
const struct GNUNET_DHT_PathElement path,
const struct GNUNET_HashCode key 
)

Check if some client is monitoring GET messages and notify them in that case.

If tracked, path should include the local peer.

Parameters
optionsOptions, for instance RecordRoute, DemultiplexEverywhere.
typeThe type of data in the request.
hop_countHop count so far.
path_lengthnumber of entries in path (or 0 if not recorded).
pathpeers on the GET path (or NULL if not recorded).
desired_replication_levelDesired replication level.
keyKey of the requested data.

Definition at line 1390 of file gnunet-service-dht_clients.c.

1397 {
1398  struct GetActionContext gac = {
1399  .options = options,
1400  .type = type,
1401  .hop_count = hop_count,
1402  .desired_replication_level = desired_replication_level,
1403  .get_path_length = path_length,
1404  .get_path = path,
1405  .key = key
1406  };
1407 
1409  key,
1410  &get_action,
1411  &gac);
1412 }
static void for_matching_monitors(enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode *key, MonitorAction cb, void *cb_cls)
Call cb on all monitors that watch for blocks of type and key key.
static void get_action(void *cls, struct ClientMonitorRecord *m)
Function called on monitors that match a GET.

References GetActionContext::desired_replication_level, for_matching_monitors(), get_action(), GetActionContext::hop_count, key, options, GetActionContext::options, and type.

Referenced by check_dht_local_get_result_seen(), and handle_dht_p2p_get().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ response_action()

static void response_action ( void *  cls,
struct ClientMonitorRecord m 
)
static

Function called on monitors that match a response.

Sends the response notification to the monitor.

Parameters
clsa struct ResponseActionContext
ma matching monitor

Definition at line 1434 of file gnunet-service-dht_clients.c.

1436 {
1437  const struct ResponseActionContext *resp_ctx = cls;
1438  const struct GDS_DATACACHE_BlockData *bd = resp_ctx->bd;
1439 
1440  struct GNUNET_MQ_Envelope *env;
1441  struct GNUNET_DHT_MonitorGetRespMessage *mmsg;
1442  struct GNUNET_DHT_PathElement *path;
1443  size_t msize;
1444 
1445  msize = bd->data_size;
1446  msize += (resp_ctx->get_path_length + bd->put_path_length)
1447  * sizeof(struct GNUNET_DHT_PathElement);
1448  env = GNUNET_MQ_msg_extra (mmsg,
1449  msize,
1451  mmsg->type = htonl (bd->type);
1452  mmsg->put_path_length = htonl (bd->put_path_length);
1453  mmsg->get_path_length = htonl (resp_ctx->get_path_length);
1455  mmsg->key = bd->key;
1456  path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
1457  GNUNET_memcpy (path,
1458  bd->put_path,
1459  bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement));
1460  GNUNET_memcpy (path,
1461  resp_ctx->get_path,
1462  resp_ctx->get_path_length
1463  * sizeof(struct GNUNET_DHT_PathElement));
1464  GNUNET_memcpy (&path[resp_ctx->get_path_length],
1465  bd->data,
1466  bd->data_size);
1467  GNUNET_MQ_send (m->ch->mq,
1468  env);
1469 }
#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP
Receive information about transiting GET responses.
Message to monitor get results going through peer, DHT service -> clients.
Definition: dht.h:368
struct GNUNET_HashCode key
The key of the corresponding GET request.
Definition: dht.h:397
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the content expire?
Definition: dht.h:392
uint32_t type
Content type.
Definition: dht.h:377
uint32_t get_path_length
Length of the GET path that follows (if tracked).
Definition: dht.h:387
uint32_t put_path_length
Length of the PUT path that follows (if tracked).
Definition: dht.h:382
Closure for response_action().
const struct GDS_DATACACHE_BlockData * bd
const struct GNUNET_DHT_PathElement * get_path

References ResponseActionContext::bd, GDS_DATACACHE_BlockData::data, GDS_DATACACHE_BlockData::data_size, env, GNUNET_DHT_MonitorGetRespMessage::expiration_time, GDS_DATACACHE_BlockData::expiration_time, ResponseActionContext::get_path, GNUNET_DHT_MonitorGetRespMessage::get_path_length, ResponseActionContext::get_path_length, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_TIME_absolute_hton(), GNUNET_DHT_MonitorGetRespMessage::key, GDS_DATACACHE_BlockData::key, m, GNUNET_ARM_MonitorHandle::mq, GDS_DATACACHE_BlockData::put_path, GNUNET_DHT_MonitorGetRespMessage::put_path_length, GDS_DATACACHE_BlockData::put_path_length, GNUNET_DHT_MonitorGetRespMessage::type, and GDS_DATACACHE_BlockData::type.

Referenced by GDS_CLIENTS_process_get_resp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GDS_CLIENTS_process_get_resp()

void GDS_CLIENTS_process_get_resp ( const struct GDS_DATACACHE_BlockData bd,
const struct GNUNET_DHT_PathElement get_path,
unsigned int  get_path_length 
)

Check if some client is monitoring GET RESP messages and notify them in that case.

Parameters
bdblock details
get_pathPeers on GET path (or NULL if not recorded).
get_path_lengthnumber of entries in get_path.

Definition at line 1473 of file gnunet-service-dht_clients.c.

1476 {
1477  struct ResponseActionContext rac = {
1478  .bd = bd,
1479  .get_path = get_path,
1480  .get_path_length = get_path_length
1481  };
1482 
1484  &bd->key,
1485  &response_action,
1486  &rac);
1487 }
static void response_action(void *cls, struct ClientMonitorRecord *m)
Function called on monitors that match a response.

References ResponseActionContext::bd, for_matching_monitors(), ResponseActionContext::get_path, ResponseActionContext::get_path_length, GDS_DATACACHE_BlockData::key, response_action(), and GDS_DATACACHE_BlockData::type.

Referenced by check_dht_p2p_result().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ put_action()

static void put_action ( void *  cls,
struct ClientMonitorRecord m 
)
static

Function called on monitors that match a PUT.

Sends the PUT notification to the monitor.

Parameters
clsa struct PutActionContext
ma matching monitor

Definition at line 1510 of file gnunet-service-dht_clients.c.

1512 {
1513  const struct PutActionContext *put_ctx = cls;
1514  const struct GDS_DATACACHE_BlockData *bd = put_ctx->bd;
1515  struct GNUNET_MQ_Envelope *env;
1516  struct GNUNET_DHT_MonitorPutMessage *mmsg;
1517  struct GNUNET_DHT_PathElement *msg_path;
1518  size_t msize;
1519 
1520  msize = bd->data_size
1521  + bd->put_path_length
1522  * sizeof(struct GNUNET_DHT_PathElement);
1523  env = GNUNET_MQ_msg_extra (mmsg,
1524  msize,
1526  mmsg->options = htonl (put_ctx->options);
1527  mmsg->type = htonl (bd->type);
1528  mmsg->hop_count = htonl (put_ctx->hop_count);
1529  mmsg->desired_replication_level = htonl (put_ctx->desired_replication_level);
1530  mmsg->put_path_length = htonl (bd->put_path_length);
1531  mmsg->key = bd->key;
1533  msg_path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
1534  GNUNET_memcpy (msg_path,
1535  bd->put_path,
1536  bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement));
1537  GNUNET_memcpy (&msg_path[bd->put_path_length],
1538  bd->data,
1539  bd->data_size);
1540  GNUNET_MQ_send (m->ch->mq,
1541  env);
1542 }
#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT
Receive information about transiting PUTs.
Message to monitor put requests going through peer, DHT service -> clients.
Definition: dht.h:229
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition: dht.h:238
struct GNUNET_TIME_AbsoluteNBO expiration_time
How long should this data persist?
Definition: dht.h:264
uint32_t desired_replication_level
Replication level for this message.
Definition: dht.h:253
struct GNUNET_HashCode key
The key to store the value under.
Definition: dht.h:269
uint32_t hop_count
Hop count so far.
Definition: dht.h:248
uint32_t type
The type of data in the request.
Definition: dht.h:243
uint32_t put_path_length
Number of peers recorded in the outgoing path from source to the storage location of this message.
Definition: dht.h:259
Closure for put_action().
enum GNUNET_DHT_RouteOption options
const struct GDS_DATACACHE_BlockData * bd

References PutActionContext::bd, GDS_DATACACHE_BlockData::data, GDS_DATACACHE_BlockData::data_size, GNUNET_DHT_MonitorPutMessage::desired_replication_level, PutActionContext::desired_replication_level, env, GNUNET_DHT_MonitorPutMessage::expiration_time, GDS_DATACACHE_BlockData::expiration_time, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_TIME_absolute_hton(), GNUNET_DHT_MonitorPutMessage::hop_count, PutActionContext::hop_count, GNUNET_DHT_MonitorPutMessage::key, GDS_DATACACHE_BlockData::key, m, GNUNET_ARM_MonitorHandle::mq, GNUNET_DHT_MonitorPutMessage::options, PutActionContext::options, GDS_DATACACHE_BlockData::put_path, GNUNET_DHT_MonitorPutMessage::put_path_length, GDS_DATACACHE_BlockData::put_path_length, GNUNET_DHT_MonitorPutMessage::type, and GDS_DATACACHE_BlockData::type.

Referenced by GDS_CLIENTS_process_put().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GDS_CLIENTS_process_put()

void GDS_CLIENTS_process_put ( enum GNUNET_DHT_RouteOption  options,
const struct GDS_DATACACHE_BlockData bd,
uint32_t  hop_count,
uint32_t  desired_replication_level 
)

Check if some client is monitoring PUT messages and notify them in that case.

The path should include our own peer ID (if recorded).

Parameters
optionsrouting options to apply
bddetails about the block
hop_countHop count so far.
desired_replication_levelDesired replication level.

Definition at line 1546 of file gnunet-service-dht_clients.c.

1550 {
1551  struct PutActionContext put_ctx = {
1552  .bd = bd,
1553  .hop_count = hop_count,
1554  .desired_replication_level = desired_replication_level,
1555  .options = options
1556  };
1557 
1559  &bd->key,
1560  &put_action,
1561  &put_ctx);
1562 }
static void put_action(void *cls, struct ClientMonitorRecord *m)
Function called on monitors that match a PUT.

References PutActionContext::bd, PutActionContext::desired_replication_level, for_matching_monitors(), PutActionContext::hop_count, GDS_DATACACHE_BlockData::key, options, put_action(), and GDS_DATACACHE_BlockData::type.

Referenced by handle_dht_local_put(), and handle_dht_p2p_put().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GDS_CLIENTS_init()

static void GDS_CLIENTS_init ( void  )
static

Initialize client subsystem.

Parameters
serverthe initialized server

Definition at line 1574 of file gnunet-service-dht_clients.c.

1575 {
1576  forward_map
1578  GNUNET_YES);
1579  retry_heap
1581 }
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.

References forward_map, GNUNET_CONTAINER_heap_create(), GNUNET_CONTAINER_HEAP_ORDER_MIN, GNUNET_CONTAINER_multihashmap_create(), GNUNET_YES, and retry_heap.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GDS_CLIENTS_stop()

static void GDS_CLIENTS_stop ( void  )
static

Shutdown client subsystem.

Definition at line 1588 of file gnunet-service-dht_clients.c.

1589 {
1590  if (NULL != retry_task)
1591  {
1593  retry_task = NULL;
1594  }
1595 }

References GNUNET_SCHEDULER_cancel(), and retry_task.

Referenced by shutdown_task().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ __attribute__()

void __attribute__ ( (destructor)  )

MINIMIZE heap size (way below 128k) since this process doesn't need much.

Definition at line 1650 of file gnunet-service-dht_clients.c.

1652 {
1653  if (NULL != retry_heap)
1654  {
1657  retry_heap = NULL;
1658  }
1659  if (NULL != forward_map)
1660  {
1663  forward_map = NULL;
1664  }
1665 }
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
unsigned int GNUNET_CONTAINER_heap_get_size(const struct GNUNET_CONTAINER_Heap *heap)
Get the current size of the heap.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.

Variable Documentation

◆ GDS_block_context

struct GNUNET_BLOCK_Context* GDS_block_context

◆ GDS_stats

struct GNUNET_STATISTICS_Handle* GDS_stats

◆ GDS_service

struct GNUNET_SERVICE_Handle* GDS_service

Handle for the service.

Definition at line 235 of file gnunet-service-dht_clients.c.

Referenced by run().

◆ GDS_cfg

const struct GNUNET_CONFIGURATION_Handle* GDS_cfg

The configuration the DHT service is running with.

Configuration we use.

Definition at line 240 of file gnunet-service-dht_clients.c.

Referenced by GDS_DATACACHE_init(), load_underlay(), and run().

◆ monitor_head

struct ClientMonitorRecord* monitor_head
static

List of active monitoring requests.

Definition at line 245 of file gnunet-service-dht_clients.c.

Referenced by client_disconnect_cb(), for_matching_monitors(), handle_dht_local_monitor(), and handle_dht_local_monitor_stop().

◆ monitor_tail

struct ClientMonitorRecord* monitor_tail
static

List of active monitoring requests.

Definition at line 250 of file gnunet-service-dht_clients.c.

Referenced by client_disconnect_cb(), handle_dht_local_monitor(), and handle_dht_local_monitor_stop().

◆ forward_map

struct GNUNET_CONTAINER_MultiHashMap* forward_map
static

◆ retry_heap

struct GNUNET_CONTAINER_Heap* retry_heap
static

Heap with all of our client's request, sorted by retry time (earliest on top).

Definition at line 260 of file gnunet-service-dht_clients.c.

Referenced by check_dht_local_get_result_seen(), check_dht_local_put(), and GDS_CLIENTS_init().

◆ retry_task

struct GNUNET_SCHEDULER_Task* retry_task
static

Task that re-transmits requests (using retry_heap).

Definition at line 265 of file gnunet-service-dht_clients.c.

Referenced by check_dht_local_get_result_seen(), check_dht_local_put(), and GDS_CLIENTS_stop().