GNUnet  0.11.x
Data Structures | Macros | 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...
 

Macros

#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...
 

Functions

static void remove_client_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 int 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 int check_dht_local_get (void *cls, const struct GNUNET_DHT_ClientGetMessage *get)
 Check DHT GET messages from the client. More...
 
static void handle_local_result (void *cls, enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, const struct GNUNET_HashCode *key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, const void *data, size_t data_size)
 Handle a result from local datacache for a GET operation. 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 int 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 int 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 int 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 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 int forward_reply (void *cls, const struct GNUNET_HashCode *key, void *value)
 Iterator over hash map entries that send a given reply to each of the matching clients. More...
 
void GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, const struct GNUNET_HashCode *key, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, enum GNUNET_BLOCK_Type type, size_t data_size, const void *data)
 Handle a reply we've received from another peer. More...
 
void GDS_CLIENTS_process_get (uint32_t options, enum GNUNET_BLOCK_Type type, uint32_t hop_count, uint32_t desired_replication_level, unsigned int path_length, const struct GNUNET_PeerIdentity *path, const struct GNUNET_HashCode *key)
 Check if some client is monitoring GET messages and notify them in that case. More...
 
void GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, const struct GNUNET_PeerIdentity *get_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int put_path_length, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const void *data, size_t size)
 Check if some client is monitoring GET RESP messages and notify them in that case. More...
 
void GDS_CLIENTS_process_put (uint32_t options, enum GNUNET_BLOCK_Type type, uint32_t hop_count, uint32_t desired_replication_level, unsigned int path_length, const struct GNUNET_PeerIdentity *path, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const void *data, size_t size)
 Check if some client is monitoring PUT messages and notify them in that case. More...
 
static void GDS_CLIENTS_init ()
 Initialize client subsystem. More...
 
static void GDS_CLIENTS_stop ()
 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

◆ 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 41 of file gnunet-service-dht_clients.c.

◆ LOG

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

Definition at line 44 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 1488 of file gnunet-service-dht_clients.c.

Function Documentation

◆ remove_client_record()

static void remove_client_record ( struct ClientQueryRecord record)
static

Free data structures associated with the given query.

Parameters
recordrecord to remove

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

266 {
267  struct ClientHandle *ch = record->ch;
268 
269  GNUNET_CONTAINER_DLL_remove (ch->cqr_head,
270  ch->cqr_tail,
271  record);
274  &record->key,
275  record));
276  if (NULL != record->hnode)
278  GNUNET_array_grow (record->seen_replies,
279  record->seen_replies_count,
280  0);
282 }
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(), forward_reply(), and remove_by_unique_id().

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 295 of file gnunet-service-dht_clients.c.

298 {
299  struct ClientHandle *ch;
300 
301  ch = GNUNET_new (struct ClientHandle);
302  ch->client = client;
303  ch->mq = mq;
304  return ch;
305 }
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 317 of file gnunet-service-dht_clients.c.

320 {
321  struct ClientHandle *ch = app_ctx;
322  struct ClientQueryRecord *cqr;
324 
326  "Local client %p disconnects\n",
327  ch);
329  while (NULL != monitor)
330  {
331  if (monitor->ch == ch)
332  {
333  struct ClientMonitorRecord *next;
334 
335  next = monitor->next;
336  GNUNET_free (monitor->key);
338  monitor_tail,
339  monitor);
341  monitor = next;
342  }
343  else
344  {
345  monitor = monitor->next;
346  }
347  }
348  while (NULL != (cqr = ch->cqr_head))
349  remove_client_record (cqr);
350  GNUNET_free (ch);
351 }
static int monitor
Monitor ARM activity.
Definition: gnunet-arm.c:64
static struct ClientMonitorRecord * monitor_head
List of active monitoring requests.
static void remove_client_record(struct ClientQueryRecord *record)
Free data structures associated with the given query.
static struct ClientMonitorRecord * monitor_tail
List of active monitoring requests.
#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, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, monitor, monitor_head, monitor_tail, ClientMonitorRecord::next, and remove_client_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.

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

361 {
362  struct GNUNET_BLOCK_Group *bg;
363  struct GNUNET_CONTAINER_BloomFilter *peer_bf;
364 
366  gettext_noop (
367  "# GET requests from clients injected"),
368  1,
369  GNUNET_NO);
371  cqr->type,
374  UINT32_MAX),
375  NULL,
376  0,
377  "seen-set-size",
378  cqr->seen_replies_count,
379  NULL);
381  cqr->seen_replies,
382  cqr->seen_replies_count);
383  peer_bf
388  "Initiating GET for %s, replication %u, already have %u replies\n",
389  GNUNET_h2s (&cqr->key),
390  cqr->replication,
391  cqr->seen_replies_count);
393  cqr->msg_options,
394  cqr->replication,
395  0 /* hop count */,
396  &cqr->key,
397  cqr->xquery,
398  cqr->xquery_size,
399  bg,
400  peer_bf);
403 
404  /* exponential back-off for retries.
405  * max GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */
408 }
#define DHT_BLOOM_SIZE
Size of the bloom filter the DHT uses to filter peers.
Definition: dht.h:34
#define gettext_noop(String)
Definition: gettext.h:69
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,...)
int GDS_NEIGHBOURS_handle_get(enum GNUNET_BLOCK_Type type, enum GNUNET_DHT_RouteOption options, uint32_t desired_replication_level, uint32_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
void GNUNET_BLOCK_group_destroy(struct GNUNET_BLOCK_Group *bg)
Destroy resources used by a block group.
Definition: block.c:206
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:290
int 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:410
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:181
#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
Replies we have already seen for this request.
uint32_t 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, gettext_noop, 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 transmit_next_request_task().

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 419 of file gnunet-service-dht_clients.c.

420 {
421  struct ClientQueryRecord *cqr;
423 
424  retry_task = NULL;
425  while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap)))
426  {
427  cqr->hnode = NULL;
429  if (delay.rel_value_us > 0)
430  {
431  cqr->hnode
433  cqr,
434  cqr->retry_time.abs_value_us);
435  retry_task
438  NULL);
439  return;
440  }
441  transmit_request (cqr);
442  cqr->hnode
444  cqr,
445  cqr->retry_time.abs_value_us);
446  }
447 }
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
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:1246
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:232
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.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.

References GNUNET_TIME_Absolute::abs_value_us, delay, GNUNET_CONTAINER_heap_insert(), GNUNET_CONTAINER_heap_remove_root(), GNUNET_SCHEDULER_add_at(), GNUNET_TIME_absolute_get_remaining(), ClientQueryRecord::hnode, GNUNET_TIME_Relative::rel_value_us, retry_heap, retry_task, ClientQueryRecord::retry_time, and transmit_request().

Referenced by handle_dht_local_get().

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

◆ check_dht_local_put()

static int 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 458 of file gnunet-service-dht_clients.c.

460 {
461  /* always well-formed */
462  return GNUNET_OK;
463 }
@ GNUNET_OK
Definition: gnunet_common.h:95

References GNUNET_OK.

◆ 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 473 of file gnunet-service-dht_clients.c.

475 {
476  struct ClientHandle *ch = cls;
477  struct GNUNET_CONTAINER_BloomFilter *peer_bf;
478  uint16_t size;
479 
480  size = ntohs (dht_msg->header.size);
482  gettext_noop (
483  "# PUT requests received from clients"),
484  1,
485  GNUNET_NO);
487  "CLIENT-PUT %s\n",
488  GNUNET_h2s_full (&dht_msg->key));
489  /* give to local clients */
491  "Handling local PUT of %lu-bytes for query %s\n",
492  (unsigned long) (size - sizeof(struct GNUNET_DHT_ClientPutMessage)),
493  GNUNET_h2s (&dht_msg->key));
495  &dht_msg->key,
496  0,
497  NULL,
498  0,
499  NULL,
500  ntohl (dht_msg->type),
501  size - sizeof(struct GNUNET_DHT_ClientPutMessage),
502  &dht_msg[1]);
503  /* store locally */
505  &dht_msg->key,
506  0,
507  NULL,
508  ntohl (dht_msg->type),
509  size - sizeof(struct GNUNET_DHT_ClientPutMessage),
510  &dht_msg[1]);
511  /* route to other peers */
512  peer_bf
516  GDS_NEIGHBOURS_handle_put (ntohl (dht_msg->type),
517  ntohl (dht_msg->options),
518  ntohl (dht_msg->desired_replication_level),
520  0 /* hop count */,
521  peer_bf,
522  &dht_msg->key,
523  0,
524  NULL,
525  &dht_msg[1],
526  size - sizeof(struct GNUNET_DHT_ClientPutMessage));
527  GDS_CLIENTS_process_put (ntohl (dht_msg->options),
528  ntohl (dht_msg->type),
529  0,
530  ntohl (dht_msg->desired_replication_level),
531  1,
534  &dht_msg->key,
535  &dht_msg[1],
536  size - sizeof(struct GNUNET_DHT_ClientPutMessage));
539 }
void GDS_CLIENTS_process_put(uint32_t options, enum GNUNET_BLOCK_Type type, uint32_t hop_count, uint32_t desired_replication_level, unsigned int path_length, const struct GNUNET_PeerIdentity *path, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const void *data, size_t size)
Check if some client is monitoring PUT messages and notify them in that case.
#define LOG_TRAFFIC(kind,...)
Should routing details be logged to stderr (for debugging)?
void GDS_CLIENTS_handle_reply(struct GNUNET_TIME_Absolute expiration, const struct GNUNET_HashCode *key, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, enum GNUNET_BLOCK_Type type, size_t data_size, const void *data)
Handle a reply we've received from another peer.
void GDS_DATACACHE_handle_put(struct GNUNET_TIME_Absolute expiration, const struct GNUNET_HashCode *key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, enum GNUNET_BLOCK_Type type, size_t data_size, const void *data)
Handle a datum we've received from another peer.
int GDS_NEIGHBOURS_handle_put(enum GNUNET_BLOCK_Type type, enum GNUNET_DHT_RouteOption options, uint32_t desired_replication_level, struct GNUNET_TIME_Absolute expiration_time, uint32_t hop_count, struct GNUNET_CONTAINER_BloomFilter *bf, const struct GNUNET_HashCode *key, unsigned int put_path_length, struct GNUNET_PeerIdentity *put_path, const void *data, size_t data_size)
Perform a PUT operation.
struct GNUNET_PeerIdentity * GDS_NEIGHBOURS_get_id()
Get the ID of the local node.
const char * GNUNET_h2s_full(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2244
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:542
static unsigned int size
Size of the "table".
Definition: peer.c:67
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
uint32_t desired_replication_level
Replication level for this message.
Definition: dht.h:209
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, GNUNET_DHT_ClientPutMessage::desired_replication_level, DHT_BLOOM_SIZE, GNUNET_DHT_ClientPutMessage::expiration, GDS_CLIENTS_handle_reply(), GDS_CLIENTS_process_put(), GDS_DATACACHE_handle_put(), GDS_NEIGHBOURS_get_id(), GDS_NEIGHBOURS_handle_put(), GDS_stats, gettext_noop, GNUNET_CONSTANTS_BLOOMFILTER_K, GNUNET_CONTAINER_bloomfilter_free(), GNUNET_CONTAINER_bloomfilter_init(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_h2s_full(), GNUNET_NO, GNUNET_SERVICE_client_continue(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_ntoh(), GNUNET_DHT_ClientPutMessage::header, GNUNET_DHT_ClientPutMessage::key, LOG, LOG_TRAFFIC, GNUNET_DHT_ClientPutMessage::options, GNUNET_MessageHeader::size, size, and GNUNET_DHT_ClientPutMessage::type.

Here is the call graph for this function:

◆ check_dht_local_get()

static int 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 550 of file gnunet-service-dht_clients.c.

552 {
553  /* always well-formed */
554  return GNUNET_OK;
555 }

References GNUNET_OK.

◆ handle_local_result()

static void handle_local_result ( void *  cls,
enum GNUNET_BLOCK_Type  type,
struct GNUNET_TIME_Absolute  expiration_time,
const struct GNUNET_HashCode key,
unsigned int  put_path_length,
const struct GNUNET_PeerIdentity put_path,
unsigned int  get_path_length,
const struct GNUNET_PeerIdentity get_path,
const void *  data,
size_t  data_size 
)
static

Handle a result from local datacache for a GET operation.

Parameters
clsthe struct ClientHandle of the client doing the query
typetype of the block
expiration_timewhen does the content expire
keykey for the content
put_path_lengthnumber of entries in put_path
put_pathpeers the original PUT traversed (if tracked)
get_path_lengthnumber of entries in get_path
get_pathpeers this reply has traversed so far (if tracked)
datapayload of the reply
data_sizenumber of bytes in data

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

583 {
584  // FIXME: this needs some clean up: inline the function,
585  // possibly avoid even looking up the client!
586  GDS_CLIENTS_handle_reply (expiration_time,
587  key,
588  0, NULL,
589  put_path_length, put_path,
590  type,
591  data_size, data);
592 }
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
struct GNUNET_HashCode key
The key used in the DHT.
uint32_t data
The data value.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model

References data, data_size, GDS_CLIENTS_handle_reply(), key, and type.

Referenced by handle_dht_local_get().

Here is the call graph for this function:
Here is the caller 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 602 of file gnunet-service-dht_clients.c.

604 {
605  struct ClientHandle *ch = cls;
606  struct ClientQueryRecord *cqr;
607  size_t xquery_size;
608  const char *xquery;
609  uint16_t size;
610 
611  size = ntohs (get->header.size);
612  xquery_size = size - sizeof(struct GNUNET_DHT_ClientGetMessage);
613  xquery = (const char *) &get[1];
616  ("# GET requests received from clients"), 1,
617  GNUNET_NO);
619  "Received GET request for %s from local client %p, xq: %.*s\n",
620  GNUNET_h2s (&get->key),
621  ch->client,
622  (int) xquery_size,
623  xquery);
625  "CLIENT-GET %s\n",
626  GNUNET_h2s_full (&get->key));
627 
628  cqr = GNUNET_malloc (sizeof(struct ClientQueryRecord) + xquery_size);
629  cqr->key = get->key;
630  cqr->ch = ch;
631  cqr->xquery = (void *) &cqr[1];
632  GNUNET_memcpy (&cqr[1], xquery, xquery_size);
636  cqr->unique_id = get->unique_id;
637  cqr->xquery_size = xquery_size;
638  cqr->replication = ntohl (get->desired_replication_level);
639  cqr->msg_options = ntohl (get->options);
640  cqr->type = ntohl (get->type);
641  GNUNET_CONTAINER_DLL_insert (ch->cqr_head,
642  ch->cqr_tail,
643  cqr);
645  &cqr->key,
646  cqr,
648  GDS_CLIENTS_process_get (ntohl (get->options),
649  ntohl (get->type),
650  0,
651  ntohl (get->desired_replication_level),
652  1,
654  &get->key);
655  /* start remote requests */
656  if (NULL != retry_task)
659  NULL);
660  /* perform local lookup */
662  cqr->type,
663  cqr->xquery,
664  xquery_size,
665  NULL,
667  ch);
669 }
void GDS_CLIENTS_process_get(uint32_t options, enum GNUNET_BLOCK_Type type, uint32_t hop_count, uint32_t desired_replication_level, unsigned int path_length, const struct GNUNET_PeerIdentity *path, const struct GNUNET_HashCode *key)
Check if some client is monitoring GET messages and notify them in that case.
static void handle_local_result(void *cls, enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, const struct GNUNET_HashCode *key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, const void *data, size_t data_size)
Handle a result from local datacache for a GET operation.
enum GNUNET_BLOCK_EvaluationResult 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:1296
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:86
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
uint64_t unique_id
Unique ID identifying this request, if 0 then the client will not expect a response.
Definition: dht.h:103
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition: dht.h:81
struct GNUNET_HashCode key
The key to search for.
Definition: dht.h:97
uint32_t type
The type for the data for the GET request; actually an 'enum GNUNET_BLOCK_Type'.
Definition: dht.h:92
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET.
Definition: dht.h:76
uint32_t desired_replication_level
Replication level for this message.
Definition: dht.h:86

References ch, ClientQueryRecord::ch, GNUNET_DHT_ClientGetMessage::desired_replication_level, forward_map, GDS_CLIENTS_process_get(), GDS_DATACACHE_handle_get(), GDS_NEIGHBOURS_get_id(), GDS_stats, gettext_noop, 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(), GNUNET_DHT_ClientGetMessage::header, ClientQueryRecord::hnode, GNUNET_DHT_ClientGetMessage::key, ClientQueryRecord::key, LOG, LOG_TRAFFIC, ClientQueryRecord::msg_options, GNUNET_DHT_ClientGetMessage::options, ClientQueryRecord::replication, ClientQueryRecord::retry_frequency, retry_heap, retry_task, ClientQueryRecord::retry_time, GNUNET_MessageHeader::size, size, transmit_next_request_task(), GNUNET_DHT_ClientGetMessage::type, ClientQueryRecord::type, GNUNET_DHT_ClientGetMessage::unique_id, ClientQueryRecord::unique_id, ClientQueryRecord::xquery, and ClientQueryRecord::xquery_size.

Here is the call graph for this function:

◆ find_by_unique_id()

static int 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 697 of file gnunet-service-dht_clients.c.

700 {
701  struct FindByUniqueIdContext *fui_ctx = cls;
702  struct ClientQueryRecord *cqr = value;
703 
704  if (cqr->unique_id != fui_ctx->unique_id)
705  return GNUNET_YES;
706  fui_ctx->cqr = cqr;
707  return GNUNET_NO;
708 }
static char * value
Value of the record to add/remove.
Closure for find_by_unique_id().
struct ClientQueryRecord * cqr
Where to store the result, if found.

References FindByUniqueIdContext::cqr, GNUNET_NO, GNUNET_YES, ClientQueryRecord::unique_id, FindByUniqueIdContext::unique_id, and value.

Referenced by handle_dht_local_get_result_seen().

Here is the caller graph for this function:

◆ check_dht_local_get_result_seen()

static int 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 719 of file gnunet-service-dht_clients.c.

722 {
723  uint16_t size;
724  unsigned int hash_count;
725 
726  size = ntohs (seen->header.size);
727  hash_count = (size - sizeof(struct GNUNET_DHT_ClientGetResultSeenMessage))
728  / sizeof(struct GNUNET_HashCode);
729  if (size != sizeof(struct GNUNET_DHT_ClientGetResultSeenMessage)
730  + hash_count * sizeof(struct GNUNET_HashCode))
731  {
732  GNUNET_break (0);
733  return GNUNET_SYSERR;
734  }
735  return GNUNET_OK;
736 }
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
DHT GET RESULTS KNOWN message sent from clients to service.
Definition: dht.h:114
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN.
Definition: dht.h:118
A 512-bit hashcode.

References GNUNET_break, GNUNET_OK, GNUNET_SYSERR, GNUNET_DHT_ClientGetResultSeenMessage::header, GNUNET_MessageHeader::size, and size.

◆ 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 746 of file gnunet-service-dht_clients.c.

749 {
750  struct ClientHandle *ch = cls;
751  uint16_t size;
752  unsigned int hash_count;
753  unsigned int old_count;
754  const struct GNUNET_HashCode *hc;
755  struct FindByUniqueIdContext fui_ctx;
756  struct ClientQueryRecord *cqr;
757 
758  size = ntohs (seen->header.size);
759  hash_count = (size - sizeof(struct GNUNET_DHT_ClientGetResultSeenMessage))
760  / sizeof(struct GNUNET_HashCode);
761  hc = (const struct GNUNET_HashCode*) &seen[1];
762  fui_ctx.unique_id = seen->unique_id;
763  fui_ctx.cqr = NULL;
765  &seen->key,
767  &fui_ctx);
768  if (NULL == (cqr = fui_ctx.cqr))
769  {
770  GNUNET_break (0);
771  GNUNET_SERVICE_client_drop (ch->client);
772  return;
773  }
774  /* finally, update 'seen' list */
775  old_count = cqr->seen_replies_count;
777  cqr->seen_replies_count,
778  cqr->seen_replies_count + hash_count);
779  GNUNET_memcpy (&cqr->seen_replies[old_count],
780  hc,
781  sizeof(struct GNUNET_HashCode) * hash_count);
782 }
static int 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:2325
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 int 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 812 of file gnunet-service-dht_clients.c.

815 {
816  const struct RemoveByUniqueIdContext *ctx = cls;
817  struct ClientQueryRecord *cqr = value;
818 
819  if (cqr->unique_id != ctx->unique_id)
820  return GNUNET_YES;
822  "Removing client %p's record for key %s (by unique id)\n",
823  ctx->ch->client,
824  GNUNET_h2s (key));
825  remove_client_record (cqr);
826  return GNUNET_YES;
827 }
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
Closure for remove_by_unique_id().

References ctx, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_YES, key, remove_client_record(), ClientQueryRecord::unique_id, and value.

Referenced by handle_dht_local_get_stop().

Here is the call graph for this function:
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 839 of file gnunet-service-dht_clients.c.

842 {
843  struct ClientHandle *ch = cls;
845 
848  ("# GET STOP requests received from clients"), 1,
849  GNUNET_NO);
851  "Received GET STOP request for %s from local client %p\n",
852  GNUNET_h2s (&dht_stop_msg->key),
853  ch->client);
854  ctx.ch = ch;
855  ctx.unique_id = dht_stop_msg->unique_id;
857  &dht_stop_msg->key,
859  &ctx);
861 }
static int 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

References ch, ctx, forward_map, GDS_stats, gettext_noop, 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.

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 872 of file gnunet-service-dht_clients.c.

874 {
875  struct ClientHandle *ch = cls;
876  struct ClientMonitorRecord *r;
877 
878  r = GNUNET_new (struct ClientMonitorRecord);
879  r->ch = ch;
880  r->type = ntohl (msg->type);
881  r->get = ntohs (msg->get);
882  r->get_resp = ntohs (msg->get_resp);
883  r->put = ntohs (msg->put);
884  if (0 == ntohs (msg->filter_key))
885  {
886  r->key = NULL;
887  }
888  else
889  {
890  r->key = GNUNET_new (struct GNUNET_HashCode);
891  GNUNET_memcpy (r->key,
892  &msg->key,
893  sizeof(struct GNUNET_HashCode));
894  }
896  monitor_tail,
897  r);
899 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
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, NULL for all.
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_memcpy, 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 909 of file gnunet-service-dht_clients.c.

912 {
913  struct ClientHandle *ch = cls;
914  struct ClientMonitorRecord *r;
915  int keys_match;
916 
918  for (r = monitor_head; NULL != r; r = r->next)
919  {
920  if (NULL == r->key)
921  {
922  keys_match = (0 == ntohs (msg->filter_key));
923  }
924  else
925  {
926  keys_match = ((0 != ntohs (msg->filter_key)) &&
927  (! memcmp (r->key,
928  &msg->key,
929  sizeof(struct GNUNET_HashCode))));
930  }
931  if ((ch == r->ch) &&
932  (ntohl (msg->type) == r->type) &&
933  (r->get == msg->get) &&
934  (r->get_resp == msg->get_resp) &&
935  (r->put == msg->put) &&
936  keys_match)
937  {
939  monitor_tail,
940  r);
941  GNUNET_free (r->key);
942  GNUNET_free (r);
943  return; /* Delete only ONE entry */
944  }
945  }
946 }

References ch, ClientMonitorRecord::ch, ClientMonitorRecord::get, ClientMonitorRecord::get_resp, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_SERVICE_client_continue(), ClientMonitorRecord::key, monitor_head, monitor_tail, msg, ClientMonitorRecord::next, ClientMonitorRecord::put, ClientMonitorRecord::type, and GNUNET_MessageHeader::type.

Here is the call graph for this function:

◆ forward_reply()

static int forward_reply ( void *  cls,
const struct GNUNET_HashCode key,
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'
keycurrent key
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 1008 of file gnunet-service-dht_clients.c.

1011 {
1012  struct ForwardReplyContext *frc = cls;
1013  struct ClientQueryRecord *record = value;
1014  struct GNUNET_MQ_Envelope *env;
1015  struct GNUNET_DHT_ClientResultMessage *reply;
1017  int do_free;
1018  struct GNUNET_HashCode ch;
1019  struct GNUNET_PeerIdentity *paths;
1020 
1022  "CLIENT-RESULT %s\n",
1023  GNUNET_h2s_full (key));
1024  if ((record->type != GNUNET_BLOCK_TYPE_ANY) &&
1025  (record->type != frc->type))
1026  {
1028  "Record type mismatch, not passing request for key %s to local client\n",
1029  GNUNET_h2s (key));
1031  gettext_noop
1032  (
1033  "# Key match, type mismatches in REPLY to CLIENT"),
1034  1, GNUNET_NO);
1035  return GNUNET_YES; /* type mismatch */
1036  }
1037  GNUNET_CRYPTO_hash (frc->data, frc->data_size, &ch);
1038  for (unsigned int i = 0; i < record->seen_replies_count; i++)
1039  if (0 == memcmp (&record->seen_replies[i],
1040  &ch,
1041  sizeof(struct GNUNET_HashCode)))
1042  {
1044  "Duplicate reply, not passing request for key %s to local client\n",
1045  GNUNET_h2s (key));
1047  gettext_noop
1048  (
1049  "# Duplicate REPLIES to CLIENT request dropped"),
1050  1, GNUNET_NO);
1051  return GNUNET_YES; /* duplicate */
1052  }
1053  eval
1055  record->type,
1056  NULL,
1058  key,
1059  record->xquery,
1060  record->xquery_size,
1061  frc->data,
1062  frc->data_size);
1064  "Evaluation result is %d for key %s for local client's query\n",
1065  (int) eval,
1066  GNUNET_h2s (key));
1067  switch (eval)
1068  {
1070  do_free = GNUNET_YES;
1071  break;
1072 
1074  GNUNET_array_append (record->seen_replies,
1075  record->seen_replies_count,
1076  ch);
1077  do_free = GNUNET_NO;
1078  break;
1079 
1081  /* should be impossible to encounter here */
1082  GNUNET_break (0);
1083  return GNUNET_YES;
1084 
1086  GNUNET_break_op (0);
1087  return GNUNET_NO;
1088 
1090  GNUNET_break (0);
1091  return GNUNET_NO;
1092 
1094  GNUNET_break (0);
1095  return GNUNET_NO;
1096 
1098  return GNUNET_YES;
1099 
1102  _ ("Unsupported block type (%u) in request!\n"), record->type);
1103  return GNUNET_NO;
1104 
1105  default:
1106  GNUNET_break (0);
1107  return GNUNET_NO;
1108  }
1110  gettext_noop ("# RESULTS queued for clients"),
1111  1,
1112  GNUNET_NO);
1113  env = GNUNET_MQ_msg_extra (reply,
1114  frc->data_size
1115  + (frc->get_path_length + frc->put_path_length)
1116  * sizeof(struct GNUNET_PeerIdentity),
1118  reply->type = htonl (frc->type);
1119  reply->get_path_length = htonl (frc->get_path_length);
1120  reply->put_path_length = htonl (frc->put_path_length);
1121  reply->unique_id = record->unique_id;
1123  reply->key = *key;
1124  paths = (struct GNUNET_PeerIdentity *) &reply[1];
1125  GNUNET_memcpy (paths,
1126  frc->put_path,
1127  sizeof(struct GNUNET_PeerIdentity) * frc->put_path_length);
1128  GNUNET_memcpy (&paths[frc->put_path_length],
1129  frc->get_path,
1130  sizeof(struct GNUNET_PeerIdentity) * frc->get_path_length);
1131  GNUNET_memcpy (&paths[frc->get_path_length + frc->put_path_length],
1132  frc->data,
1133  frc->data_size);
1135  "Sending reply to query %s for client %p\n",
1136  GNUNET_h2s (key),
1137  record->ch->client);
1138  GNUNET_MQ_send (record->ch->mq,
1139  env);
1140  if (GNUNET_YES == do_free)
1142  return GNUNET_YES;
1143 }
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
enum GNUNET_BLOCK_EvaluationResult GNUNET_BLOCK_evaluate(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, struct GNUNET_BLOCK_Group *group, enum GNUNET_BLOCK_EvaluationOptions eo, 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 a reply or a request.
Definition: block.c:339
GNUNET_BLOCK_EvaluationResult
Possible ways for how a block may relate to a query.
@ GNUNET_BLOCK_EVALUATION_RESULT_INVALID
Block does not match query (invalid result)
@ GNUNET_BLOCK_EVALUATION_REQUEST_INVALID
Query format does not match block type (invalid query).
@ GNUNET_BLOCK_EVALUATION_OK_LAST
Last possible valid result.
@ GNUNET_BLOCK_EVALUATION_OK_MORE
Valid result, and there may be more.
@ GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT
Block does not match xquery (valid result, not relevant for the request)
@ GNUNET_BLOCK_EVALUATION_OK_DUPLICATE
Valid result, but suppressed because it is a duplicate.
@ GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED
Specified block type not supported by this plugin.
@ GNUNET_BLOCK_EVALUATION_REQUEST_VALID
Query is valid, no reply given.
@ GNUNET_BLOCK_EO_NONE
Default behavior.
@ GNUNET_BLOCK_TYPE_ANY
Any type of block, used as a wildcard when searching.
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_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
@ GNUNET_ERROR_TYPE_WARNING
#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:355
#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:464
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
Closure for forward_reply()
const void * data
Embedded payload.
enum GNUNET_BLOCK_Type type
Type of the data.
struct GNUNET_TIME_Absolute expiration
Expiration time of the reply.
size_t data_size
Number of bytes in data.
const struct GNUNET_PeerIdentity * put_path
PUT path taken.
const struct GNUNET_PeerIdentity * get_path
GET path taken.
unsigned int put_path_length
Number of entries in put_path.
unsigned int get_path_length
Number of entries in get_path.
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
The identity of the host (wraps the signing key of the peer).

References _, ch, ForwardReplyContext::data, ForwardReplyContext::data_size, env, GNUNET_DHT_ClientResultMessage::expiration, ForwardReplyContext::expiration, GDS_block_context, GDS_stats, ForwardReplyContext::get_path, GNUNET_DHT_ClientResultMessage::get_path_length, ForwardReplyContext::get_path_length, gettext_noop, GNUNET_array_append, GNUNET_BLOCK_EO_NONE, GNUNET_BLOCK_evaluate(), GNUNET_BLOCK_EVALUATION_OK_DUPLICATE, GNUNET_BLOCK_EVALUATION_OK_LAST, GNUNET_BLOCK_EVALUATION_OK_MORE, GNUNET_BLOCK_EVALUATION_REQUEST_INVALID, GNUNET_BLOCK_EVALUATION_REQUEST_VALID, GNUNET_BLOCK_EVALUATION_RESULT_INVALID, GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT, GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED, GNUNET_BLOCK_TYPE_ANY, GNUNET_break, GNUNET_break_op, GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_h2s(), GNUNET_h2s_full(), GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_hton(), GNUNET_YES, GNUNET_DHT_ClientResultMessage::key, key, LOG, LOG_TRAFFIC, ForwardReplyContext::put_path, GNUNET_DHT_ClientResultMessage::put_path_length, ForwardReplyContext::put_path_length, record(), remove_client_record(), GNUNET_DHT_ClientResultMessage::type, ForwardReplyContext::type, GNUNET_DHT_ClientResultMessage::unique_id, and value.

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()

void GDS_CLIENTS_handle_reply ( struct GNUNET_TIME_Absolute  expiration,
const struct GNUNET_HashCode key,
unsigned int  get_path_length,
const struct GNUNET_PeerIdentity get_path,
unsigned int  put_path_length,
const struct GNUNET_PeerIdentity put_path,
enum GNUNET_BLOCK_Type  type,
size_t  data_size,
const void *  data 
)

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
expirationwhen will the reply expire
keythe query this reply is for
get_path_lengthnumber of peers in get_path
get_pathpath the reply took on get
put_path_lengthnumber of peers in put_path
put_pathpath the reply took on put
typetype of the reply
data_sizenumber of bytes in data
dataapplication payload data

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

1171 {
1172  struct ForwardReplyContext frc;
1173  size_t msize;
1174 
1175  msize = sizeof(struct GNUNET_DHT_ClientResultMessage) + data_size
1176  + (get_path_length + put_path_length) * sizeof(struct
1178  if (msize >= GNUNET_MAX_MESSAGE_SIZE)
1179  {
1180  GNUNET_break (0);
1181  return;
1182  }
1184  key))
1185  {
1187  "No matching client for reply for key %s\n",
1188  GNUNET_h2s (key));
1190  gettext_noop (
1191  "# REPLIES ignored for CLIENTS (no match)"),
1192  1,
1193  GNUNET_NO);
1194  return; /* no matching request, fast exit! */
1195  }
1196  frc.expiration = expiration;
1197  frc.get_path = get_path;
1198  frc.put_path = put_path;
1199  frc.data = data;
1200  frc.data_size = data_size;
1201  frc.get_path_length = get_path_length;
1202  frc.put_path_length = put_path_length;
1203  frc.type = type;
1205  "Forwarding reply for key %s to client\n",
1206  GNUNET_h2s (key));
1208  key,
1209  &forward_reply,
1210  &frc);
1211 }
static char * expiration
Credential TTL.
Definition: gnunet-abd.c:96
static int forward_reply(void *cls, const struct GNUNET_HashCode *key, 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,...
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.

References ForwardReplyContext::data, data, data_size, ForwardReplyContext::data_size, expiration, ForwardReplyContext::expiration, forward_map, forward_reply(), GDS_stats, ForwardReplyContext::get_path, GNUNET_DHT_ClientResultMessage::get_path_length, ForwardReplyContext::get_path_length, gettext_noop, GNUNET_break, GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_get_multiple(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_MAX_MESSAGE_SIZE, GNUNET_NO, GNUNET_STATISTICS_update(), key, LOG, ForwardReplyContext::put_path, GNUNET_DHT_ClientResultMessage::put_path_length, ForwardReplyContext::put_path_length, ForwardReplyContext::type, and type.

Referenced by handle_dht_local_put(), handle_dht_p2p_put(), handle_local_result(), and process_reply_with_path().

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 ( uint32_t  options,
enum GNUNET_BLOCK_Type  type,
uint32_t  hop_count,
uint32_t  desired_replication_level,
unsigned int  path_length,
const struct GNUNET_PeerIdentity path,
const struct GNUNET_HashCode key 
)

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

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 1227 of file gnunet-service-dht_clients.c.

1234 {
1235  struct ClientMonitorRecord *m;
1236  struct ClientHandle **cl;
1237  unsigned int cl_size;
1238 
1239  cl = NULL;
1240  cl_size = 0;
1241  for (m = monitor_head; NULL != m; m = m->next)
1242  {
1243  if (((GNUNET_BLOCK_TYPE_ANY == m->type) ||
1244  (m->type == type)) &&
1245  ((NULL == m->key) ||
1246  (0 == memcmp (key,
1247  m->key,
1248  sizeof(struct GNUNET_HashCode)))))
1249  {
1250  struct GNUNET_MQ_Envelope *env;
1251  struct GNUNET_DHT_MonitorGetMessage *mmsg;
1252  struct GNUNET_PeerIdentity *msg_path;
1253  size_t msize;
1254  unsigned int i;
1255 
1256  /* Don't send duplicates */
1257  for (i = 0; i < cl_size; i++)
1258  if (cl[i] == m->ch)
1259  break;
1260  if (i < cl_size)
1261  continue;
1262  GNUNET_array_append (cl,
1263  cl_size,
1264  m->ch);
1265 
1266  msize = path_length * sizeof(struct GNUNET_PeerIdentity);
1267  env = GNUNET_MQ_msg_extra (mmsg,
1268  msize,
1270  mmsg->options = htonl (options);
1271  mmsg->type = htonl (type);
1272  mmsg->hop_count = htonl (hop_count);
1273  mmsg->desired_replication_level = htonl (desired_replication_level);
1274  mmsg->get_path_length = htonl (path_length);
1275  mmsg->key = *key;
1276  msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1];
1277  GNUNET_memcpy (msg_path,
1278  path,
1279  path_length * sizeof(struct GNUNET_PeerIdentity));
1280  GNUNET_MQ_send (m->ch->mq,
1281  env);
1282  }
1283  }
1284  GNUNET_free (cl);
1285 }
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
#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

References GNUNET_DHT_MonitorGetMessage::desired_replication_level, env, GNUNET_DHT_MonitorGetMessage::get_path_length, GNUNET_array_append, GNUNET_BLOCK_TYPE_ANY, GNUNET_free, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_DHT_MonitorGetMessage::hop_count, GNUNET_DHT_MonitorGetMessage::key, key, m, monitor_head, GNUNET_ARM_MonitorHandle::mq, options, GNUNET_DHT_MonitorGetMessage::options, GNUNET_DHT_MonitorGetMessage::type, and type.

Referenced by handle_dht_local_get(), and handle_dht_p2p_get().

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 ( enum GNUNET_BLOCK_Type  type,
const struct GNUNET_PeerIdentity get_path,
unsigned int  get_path_length,
const struct GNUNET_PeerIdentity put_path,
unsigned int  put_path_length,
struct GNUNET_TIME_Absolute  exp,
const struct GNUNET_HashCode key,
const void *  data,
size_t  size 
)

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

Parameters
typeThe type of data in the result.
get_pathPeers on GET path (or NULL if not recorded).
get_path_lengthnumber of entries in get_path.
put_pathpeers on the PUT path (or NULL if not recorded).
put_path_lengthnumber of entries in get_path.
expExpiration time of the data.
keyKey of the data.
dataPointer to the result data.
sizeNumber of bytes in data.

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

1312 {
1313  struct ClientMonitorRecord *m;
1314  struct ClientHandle **cl;
1315  unsigned int cl_size;
1316 
1317  cl = NULL;
1318  cl_size = 0;
1319  for (m = monitor_head; NULL != m; m = m->next)
1320  {
1321  if (((GNUNET_BLOCK_TYPE_ANY == m->type) || (m->type == type) ) &&
1322  ((NULL == m->key) ||
1323  (memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0) ))
1324  {
1325  struct GNUNET_MQ_Envelope *env;
1326  struct GNUNET_DHT_MonitorGetRespMessage *mmsg;
1327  struct GNUNET_PeerIdentity *path;
1328  size_t msize;
1329  unsigned int i;
1330 
1331  /* Don't send duplicates */
1332  for (i = 0; i < cl_size; i++)
1333  if (cl[i] == m->ch)
1334  break;
1335  if (i < cl_size)
1336  continue;
1337  GNUNET_array_append (cl,
1338  cl_size,
1339  m->ch);
1340 
1341  msize = size;
1342  msize += (get_path_length + put_path_length)
1343  * sizeof(struct GNUNET_PeerIdentity);
1344  env = GNUNET_MQ_msg_extra (mmsg,
1345  msize,
1347  mmsg->type = htonl (type);
1348  mmsg->put_path_length = htonl (put_path_length);
1349  mmsg->get_path_length = htonl (get_path_length);
1351  mmsg->key = *key;
1352  path = (struct GNUNET_PeerIdentity *) &mmsg[1];
1353  GNUNET_memcpy (path,
1354  put_path,
1355  put_path_length * sizeof(struct GNUNET_PeerIdentity));
1356  GNUNET_memcpy (path,
1357  get_path,
1358  get_path_length * sizeof(struct GNUNET_PeerIdentity));
1359  GNUNET_memcpy (&path[get_path_length],
1360  data,
1361  size);
1362  GNUNET_MQ_send (m->ch->mq,
1363  env);
1364  }
1365  }
1366  GNUNET_free (cl);
1367 }
#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

References data, env, GNUNET_DHT_MonitorGetRespMessage::expiration_time, GNUNET_DHT_MonitorGetRespMessage::get_path_length, GNUNET_array_append, GNUNET_BLOCK_TYPE_ANY, GNUNET_free, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_TIME_absolute_hton(), GNUNET_DHT_MonitorGetRespMessage::key, key, m, monitor_head, GNUNET_ARM_MonitorHandle::mq, GNUNET_DHT_MonitorGetRespMessage::put_path_length, size, GNUNET_DHT_MonitorGetRespMessage::type, and type.

Referenced by process_reply_with_path().

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 ( uint32_t  options,
enum GNUNET_BLOCK_Type  type,
uint32_t  hop_count,
uint32_t  desired_replication_level,
unsigned int  path_length,
const struct GNUNET_PeerIdentity path,
struct GNUNET_TIME_Absolute  exp,
const struct GNUNET_HashCode key,
const void *  data,
size_t  size 
)

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

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 PUT path (or NULL if not recorded).
desired_replication_levelDesired replication level.
expExpiration time of the data.
keyKey under which data is to be stored.
dataPointer to the data carried.
sizeNumber of bytes in data.

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

1396 {
1397  struct ClientMonitorRecord *m;
1398  struct ClientHandle **cl;
1399  unsigned int cl_size;
1400 
1401  cl = NULL;
1402  cl_size = 0;
1403  for (m = monitor_head; NULL != m; m = m->next)
1404  {
1405  if (((GNUNET_BLOCK_TYPE_ANY == m->type) || (m->type == type) ) &&
1406  ((NULL == m->key) ||
1407  (memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0) ))
1408  {
1409  struct GNUNET_MQ_Envelope *env;
1410  struct GNUNET_DHT_MonitorPutMessage *mmsg;
1411  struct GNUNET_PeerIdentity *msg_path;
1412  size_t msize;
1413  unsigned int i;
1414 
1415  /* Don't send duplicates */
1416  for (i = 0; i < cl_size; i++)
1417  if (cl[i] == m->ch)
1418  break;
1419  if (i < cl_size)
1420  continue;
1421  GNUNET_array_append (cl,
1422  cl_size,
1423  m->ch);
1424 
1425  msize = size;
1426  msize += path_length * sizeof(struct GNUNET_PeerIdentity);
1427  env = GNUNET_MQ_msg_extra (mmsg,
1428  msize,
1430  mmsg->options = htonl (options);
1431  mmsg->type = htonl (type);
1432  mmsg->hop_count = htonl (hop_count);
1433  mmsg->desired_replication_level = htonl (desired_replication_level);
1434  mmsg->put_path_length = htonl (path_length);
1435  mmsg->key = *key;
1437  msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1];
1438  GNUNET_memcpy (msg_path,
1439  path,
1440  path_length * sizeof(struct GNUNET_PeerIdentity));
1441  GNUNET_memcpy (&msg_path[path_length],
1442  data,
1443  size);
1444  GNUNET_MQ_send (m->ch->mq,
1445  env);
1446  }
1447  }
1448  GNUNET_free (cl);
1449 }
#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

References data, GNUNET_DHT_MonitorPutMessage::desired_replication_level, env, GNUNET_DHT_MonitorPutMessage::expiration_time, GNUNET_array_append, GNUNET_BLOCK_TYPE_ANY, GNUNET_free, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_TIME_absolute_hton(), GNUNET_DHT_MonitorPutMessage::hop_count, GNUNET_DHT_MonitorPutMessage::key, key, m, monitor_head, GNUNET_ARM_MonitorHandle::mq, options, GNUNET_DHT_MonitorPutMessage::options, GNUNET_DHT_MonitorPutMessage::put_path_length, size, GNUNET_DHT_MonitorPutMessage::type, and 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 ( )
static

Initialize client subsystem.

Parameters
serverthe initialized server

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

1459 {
1460  forward_map
1462  GNUNET_YES);
1463  retry_heap
1465 }
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 ( )
static

Shutdown client subsystem.

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

1473 {
1474  if (NULL != retry_task)
1475  {
1477  retry_task = NULL;
1478  }
1479 }

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 1526 of file gnunet-service-dht_clients.c.

1528 {
1529  if (NULL != retry_heap)
1530  {
1533  retry_heap = NULL;
1534  }
1535  if (NULL != forward_map)
1536  {
1539  forward_map = NULL;
1540  }
1541 }
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 226 of file gnunet-service-dht_clients.c.

Referenced by core_init(), and run().

◆ GDS_cfg

const struct GNUNET_CONFIGURATION_Handle* GDS_cfg

The configuration the DHT service is running with.

Configuration we use.

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

Referenced by GDS_DATACACHE_init(), GDS_HELLO_init(), GDS_NEIGHBOURS_init(), GDS_NSE_init(), run(), and try_connect().

◆ monitor_head

struct ClientMonitorRecord* monitor_head
static

◆ monitor_tail

struct ClientMonitorRecord* monitor_tail
static

List of active monitoring requests.

Definition at line 241 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 251 of file gnunet-service-dht_clients.c.

Referenced by GDS_CLIENTS_init(), handle_dht_local_get(), and transmit_next_request_task().

◆ retry_task

struct GNUNET_SCHEDULER_Task* retry_task
static

Task that re-transmits requests (using retry_heap).

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

Referenced by GDS_CLIENTS_stop(), handle_dht_local_get(), and transmit_next_request_task().