GNUnet debian-0.24.3-24-gfea921bd2
gnunet-service-dht_clients.c File Reference

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

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   0
 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 GNUNET_DATACACHE_Block *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 GNUNET_DATACACHE_Block *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, 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 GNUNET_DATACACHE_Block *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 (const struct GNUNET_DATACACHE_Block *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...
 
void GDS_CLIENTS_init (void)
 Initialize client subsystem. More...
 
void GDS_CLIENTS_stop (void)
 Shutdown client subsystem. More...
 
void GDS_CLIENTS_done (void)
 
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_PILS_HandleGDS_pils
 Handle for the pils 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   0

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

◆ LOG

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

Definition at line 43 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 initialization method for the service

Definition at line 1643 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 1309 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 271 of file gnunet-service-dht_clients.c.

272{
273 struct ClientHandle *ch = record->ch;
274
276 ch->cqr_tail,
277 record);
280 &record->key,
281 record));
282 if (NULL != record->hnode)
284 GNUNET_array_grow (record->seen_replies,
285 record->seen_replies_count,
286 0);
288}
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.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
enum GNUNET_GenericReturnValue 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.
@ GNUNET_YES
#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 301 of file gnunet-service-dht_clients.c.

304{
305 struct ClientHandle *ch;
306
307 (void) cls;
308 ch = GNUNET_new (struct ClientHandle);
309 ch->client = client;
310 ch->mq = mq;
311 return ch;
312}
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:142

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

327{
328 struct ClientHandle *ch = app_ctx;
329
330 (void) cls;
331 (void) client;
333 "Local client %p disconnects\n",
334 ch);
335 {
337
339 NULL != monitor;
340 monitor = next)
341 {
342 next = monitor->next;
343 if (monitor->ch != ch)
344 continue;
347 monitor);
349 }
350 }
351
352 {
353 struct ClientQueryRecord *cqr;
354
355 while (NULL != (cqr = ch->cqr_head))
357 }
358 GNUNET_free (ch);
359}
static int monitor
Monitor ARM activity.
Definition: gnunet-arm.c:63
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 370 of file gnunet-service-dht_clients.c.

371{
372 struct GNUNET_BLOCK_Group *bg;
373 struct GNUNET_CONTAINER_BloomFilter *peer_bf;
374
376 "# GET requests from clients injected",
377 1,
378 GNUNET_NO);
380 cqr->type,
381 NULL, /* raw data */
382 0, /* raw data size */
383 "seen-set-size",
385 NULL);
387 cqr->seen_replies,
388 cqr->seen_replies_count);
389 peer_bf
394 "Initiating GET for %s, replication %u, already have %u replies\n",
395 GNUNET_h2s (&cqr->key),
396 cqr->replication,
397 cqr->seen_replies_count);
399 cqr->msg_options,
400 cqr->replication,
401 0 /* hop count */,
402 &cqr->key,
403 cqr->xquery,
404 cqr->xquery_size,
405 bg,
406 peer_bf);
409
410 /* Exponential back-off for retries.
411 * max. is #GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */
414}
#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.
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:365
void GNUNET_BLOCK_group_destroy(struct GNUNET_BLOCK_Group *bg)
Destroy resources used by a block group.
Definition: block.c:194
struct GNUNET_BLOCK_Group * GNUNET_BLOCK_group_create(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, const void *raw_data, size_t raw_data_size,...)
Create a new block group.
Definition: block.c:249
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.
@ GNUNET_NO
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:316
#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_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 425 of file gnunet-service-dht_clients.c.

426{
427 struct ClientQueryRecord *cqr;
428
429 (void) cls;
430 retry_task = NULL;
431 while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap)))
432 {
433 cqr->hnode = NULL;
435 {
436 cqr->hnode
438 cqr,
443 NULL);
444 return;
445 }
446 transmit_request (cqr);
447 cqr->hnode
449 cqr,
451 }
452}
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:1254
bool GNUNET_TIME_absolute_is_past(struct GNUNET_TIME_Absolute abs)
Test if abs is truly in the past (excluding now).
Definition: time.c:671
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.

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

Referenced by handle_dht_local_get(), and transmit_next_request_task().

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

465{
466 uint32_t replication_level = ntohl (dht_msg->desired_replication_level);
467
468 (void) cls;
470 {
471 GNUNET_break_op (0);
472 return GNUNET_SYSERR;
473 }
474 return GNUNET_OK;
475}
static unsigned int replication_level
Replication level option to use for publishing.
#define GNUNET_DHT_MAXIMUM_REPLICATION_LEVEL
Maximum allowed replication level for all requests.
@ GNUNET_OK
@ GNUNET_SYSERR
#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:219

References GNUNET_DHT_ClientPutMessage::desired_replication_level, GNUNET_break_op, GNUNET_DHT_MAXIMUM_REPLICATION_LEVEL, GNUNET_OK, GNUNET_SYSERR, and replication_level.

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

487{
488 struct ClientHandle *ch = cls;
489 uint16_t size = ntohs (dht_msg->header.size);
490 uint32_t replication_level
491 = ntohl (dht_msg->desired_replication_level);
492 struct GNUNET_DATACACHE_Block bd = {
493 .key = dht_msg->key,
494 .expiration_time = GNUNET_TIME_absolute_ntoh (dht_msg->expiration),
495 .data = &dht_msg[1],
496 .data_size = size - sizeof (*dht_msg),
497 .type = ntohl (dht_msg->type),
498 .ro = ntohl (dht_msg->options)
499 };
500
502 "Handling local PUT of %lu-bytes for query %s of type %u\n",
503 (unsigned long) (size - sizeof(struct GNUNET_DHT_ClientPutMessage)),
504 GNUNET_h2s (&dht_msg->key),
505 (unsigned int) bd.type);
506#if SANITY_CHECKS > 0
507 if (GNUNET_OK !=
509 bd.type,
510 bd.data,
511 bd.data_size))
512 {
513 GNUNET_break (0);
514 return;
515 }
516#endif
518 "# PUT requests received from clients",
519 1,
520 GNUNET_NO);
522 "CLIENT-PUT %s\n",
523 GNUNET_h2s_full (&dht_msg->key));
524 /* give to local clients */
526 &bd.key,
527 0, NULL /* get path */));
528
529 {
530 struct GNUNET_CONTAINER_BloomFilter *peer_bf;
531
532 peer_bf
536 /* store locally */
537 if ( (0 != (bd.ro & GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE)) ||
538 (GDS_am_closest_peer (&dht_msg->key,
539 peer_bf)))
541 /* route to other peers */
542 if (GNUNET_OK !=
545 0 /* hop count */,
546 peer_bf))
547 {
549 "# Local PUT requests not routed",
550 1,
551 GNUNET_NO);
552 }
554 }
556 &bd,
557 0, /* hop count */
560}
void GDS_CLIENTS_process_put(const struct GNUNET_DATACACHE_Block *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 GNUNET_DATACACHE_Block *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 GNUNET_DATACACHE_Block *bd)
Handle a datum we've received from another peer.
enum GNUNET_GenericReturnValue GDS_NEIGHBOURS_handle_put(const struct GNUNET_DATACACHE_Block *bd, 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:321
@ GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE
Each peer along the way should process the request (otherwise only peers locally closest to the key w...
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
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:2433
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:741
static unsigned int size
Size of the "table".
Definition: peer.c:68
Information about a block stored in the datacache.
enum GNUNET_BLOCK_Type type
Type of the block.
const void * data
Actual block data.
enum GNUNET_DHT_RouteOption ro
Options for routing for the block.
struct GNUNET_HashCode key
Key of the block.
size_t data_size
Number of bytes in data.
Message to insert data into the DHT, sent from clients to DHT service.
Definition: dht.h:200
struct GNUNET_HashCode key
The key to store the value under.
Definition: dht.h:229
uint32_t type
The type of data to insert.
Definition: dht.h:209
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition: dht.h:214
struct GNUNET_MessageHeader header
Type: GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT.
Definition: dht.h:204
struct GNUNET_TIME_AbsoluteNBO expiration
How long should this data persist?
Definition: dht.h:224

References ch, GNUNET_DATACACHE_Block::data, GNUNET_DATACACHE_Block::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_DATACACHE_Block::key, GNUNET_DHT_ClientPutMessage::key, LOG, LOG_TRAFFIC, GNUNET_DHT_ClientPutMessage::options, replication_level, GNUNET_DATACACHE_Block::ro, GNUNET_MessageHeader::size, size, GNUNET_DATACACHE_Block::type, and GNUNET_DHT_ClientPutMessage::type.

Here is the call graph for this function:

◆ handle_local_result()

static void handle_local_result ( void *  cls,
const struct GNUNET_DATACACHE_Block 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 570 of file gnunet-service-dht_clients.c.

572{
574 "Datacache provided result for query key %s\n",
575 GNUNET_h2s (&bd->key));
577 &bd->key,
578 0, NULL /* get_path */));
579}
@ GNUNET_ERROR_TYPE_INFO

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

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_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
getthe actual message received
Returns
GNUNET_OK (always)

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

592{
593 (void) cls;
594 (void) get;
595 /* always well-formed */
596 return GNUNET_OK;
597}
static int get
Get DID Documement for DID Flag.
Definition: gnunet-did.c:63

References get, and GNUNET_OK.

◆ 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
getthe actual message received

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

609{
610 struct ClientHandle *ch = cls;
611 struct ClientQueryRecord *cqr;
612 uint16_t size = ntohs (get->header.size);
613 const char *xquery = (const char *) &get[1];
614 size_t xquery_size = size - sizeof(struct GNUNET_DHT_ClientGetMessage);
615
617 "Received GET request for %s from local client %p, xq: %.*s\n",
618 GNUNET_h2s (&get->key),
619 ch->client,
620 (int) xquery_size,
621 xquery);
623 "# GET requests received from clients",
624 1,
625 GNUNET_NO);
627 "CLIENT-GET %s\n",
628 GNUNET_h2s_full (&get->key));
629
630 cqr = GNUNET_malloc (sizeof(struct ClientQueryRecord) + xquery_size);
631 cqr->key = get->key;
632 cqr->ch = ch;
633 cqr->xquery = (const void *) &cqr[1];
634 GNUNET_memcpy (&cqr[1],
635 xquery,
636 xquery_size);
638 cqr,
639 0);
642 cqr->unique_id = get->unique_id;
643 cqr->xquery_size = xquery_size;
644 cqr->replication = ntohl (get->desired_replication_level);
645 cqr->msg_options = ntohl (get->options);
646 cqr->type = ntohl (get->type);
648 ch->cqr_tail,
649 cqr);
651 &cqr->key,
652 cqr,
655 cqr->type,
656 0, /* hop count */
657 cqr->replication,
658 &get->key);
659 /* start remote requests */
660 if (NULL != retry_task)
663 NULL);
664 /* perform local lookup */
666 cqr->type,
667 cqr->xquery,
668 xquery_size,
669 NULL,
671 ch);
673}
void GDS_CLIENTS_process_get(enum GNUNET_DHT_RouteOption options, enum GNUNET_BLOCK_Type type, uint32_t hop_count, uint32_t desired_replication_level, 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, const struct GNUNET_DATACACHE_Block *bd)
Handle a result from local datacache for a GET operation.
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_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
enum GNUNET_GenericReturnValue 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_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_malloc(size)
Wrapper around malloc.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:980
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:1304
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
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

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:

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

707{
708 struct FindByUniqueIdContext *fui_ctx = cls;
709 struct ClientQueryRecord *cqr = value;
710
711 if (cqr->unique_id != fui_ctx->unique_id)
712 return GNUNET_YES;
713 fui_ctx->cqr = cqr;
714 return GNUNET_NO;
715}
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.

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 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
seenthe actual message received
Returns
GNUNET_OK if seen is well-formed

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

729{
730 uint16_t size = ntohs (seen->header.size);
731 unsigned int hash_count =
732 (size - sizeof(*seen))
733 / sizeof(struct GNUNET_HashCode);
734
735 if (size != sizeof(*seen) + hash_count * sizeof(struct GNUNET_HashCode))
736 {
737 GNUNET_break (0);
738 return GNUNET_SYSERR;
739 }
740 return GNUNET_OK;
741}
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
seenthe actual message received

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

754{
755 struct ClientHandle *ch = cls;
756 uint16_t size = ntohs (seen->header.size);
757 unsigned int hash_count = (size - sizeof(*seen))
758 / sizeof(struct GNUNET_HashCode);
759 const struct GNUNET_HashCode *hc = (const struct GNUNET_HashCode*) &seen[1];
760 struct FindByUniqueIdContext fui_ctx = {
761 .unique_id = seen->unique_id
762 };
763 unsigned int old_count;
764 struct ClientQueryRecord *cqr;
765
767 &seen->key,
769 &fui_ctx);
770 if (NULL == (cqr = fui_ctx.cqr))
771 {
772 GNUNET_break (0);
774 return;
775 }
776 /* finally, update 'seen' list */
777 old_count = cqr->seen_replies_count;
780 cqr->seen_replies_count + hash_count);
781 GNUNET_memcpy (&cqr->seen_replies[old_count],
782 hc,
783 sizeof(struct GNUNET_HashCode) * hash_count);
784}
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.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MultiHashMapIteratorCallback 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:2462
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 814 of file gnunet-service-dht_clients.c.

817{
818 const struct RemoveByUniqueIdContext *ctx = cls;
819 struct ClientQueryRecord *cqr = value;
820
821 if (cqr->unique_id != ctx->unique_id)
822 return GNUNET_YES;
824 "Removing client %p's record for key %s (by unique id)\n",
825 ctx->ch->client,
826 GNUNET_h2s (key));
828 return GNUNET_YES;
829}
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_FS_Handle * ctx
Closure for remove_by_unique_id().

References ctx, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_YES, key, remove_client_query_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
dht_stop_msgthe actual message received

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

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

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.

Here is the call graph for this function:

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

904{
905 struct ForwardReplyContext *frc = cls;
907 const struct GNUNET_DATACACHE_Block *bd = frc->bd;
908 struct GNUNET_MQ_Envelope *env;
909 struct GNUNET_DHT_ClientResultMessage *reply;
911 bool do_free;
912 struct GNUNET_HashCode ch;
913 struct GNUNET_DHT_PathElement *paths;
914 bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
915 size_t xsize = bd->data_size;
916
918 "CLIENT-RESULT %s\n",
919 GNUNET_h2s_full (&bd->key));
920 if ( (record->type != GNUNET_BLOCK_TYPE_ANY) &&
921 (record->type != bd->type) )
922 {
924 "Record type mismatch, not passing request for key %s to local client\n",
925 GNUNET_h2s (&bd->key));
927 "# Key match, type mismatches in REPLY to CLIENT",
928 1,
929 GNUNET_NO);
930 return GNUNET_YES; /* type mismatch */
931 }
932 if ( (0 == (record->msg_options & GNUNET_DHT_RO_FIND_APPROXIMATE)) &&
933 (0 != GNUNET_memcmp (&bd->key,
934 query_hash)) )
935 {
937 "# Inexact key match, but exact match required",
938 1,
939 GNUNET_NO);
940 return GNUNET_YES; /* type mismatch */
941 }
943 bd->data_size,
944 &ch);
945 for (unsigned int i = 0; i < record->seen_replies_count; i++)
946 if (0 ==
947 GNUNET_memcmp (&record->seen_replies[i],
948 &ch))
949 {
951 "Duplicate reply, not passing request for key %s to local client\n",
952 GNUNET_h2s (&bd->key));
954 "# Duplicate REPLIES to CLIENT request dropped",
955 1,
956 GNUNET_NO);
957 return GNUNET_YES; /* duplicate */
958 }
959 eval
961 record->type,
962 NULL,
963 &bd->key,
964 record->xquery,
965 record->xquery_size,
966 bd->data,
967 bd->data_size);
969 "Evaluation result is %d for key %s for local client's query\n",
970 (int) eval,
971 GNUNET_h2s (&bd->key));
972 switch (eval)
973 {
975 do_free = true;
976 break;
979 GNUNET_array_append (record->seen_replies,
980 record->seen_replies_count,
981 ch);
982 do_free = false;
983 break;
985 /* should be impossible to encounter here */
986 GNUNET_break (0);
987 return GNUNET_YES;
989 return GNUNET_YES;
990 default:
991 GNUNET_break (0);
992 return GNUNET_NO;
993 }
995 "# RESULTS queued for clients",
996 1,
997 GNUNET_NO);
998 xsize += (frc->get_path_length + bd->put_path_length)
999 * sizeof(struct GNUNET_DHT_PathElement);
1000 if (truncated)
1001 xsize += sizeof (struct GNUNET_PeerIdentity);
1002
1003#if SUPER_REDUNDANT_CHECK
1004 GNUNET_break (0 ==
1006 bd->data_size,
1007 bd->expiration_time,
1008 truncated
1009 ? &bd->trunc_peer
1010 : NULL,
1011 bd->put_path,
1012 bd->put_path_length,
1013 frc->get_path,
1014 frc->get_path_length,
1015 &GDS_my_identity));
1016#endif
1017
1018 env = GNUNET_MQ_msg_extra (reply,
1019 xsize,
1021 reply->type = htonl (bd->type);
1022 reply->options = htonl (bd->ro);
1023 reply->get_path_length = htonl (frc->get_path_length);
1024 reply->put_path_length = htonl (bd->put_path_length);
1025 reply->unique_id = record->unique_id;
1027 reply->key = *query_hash;
1028 if (truncated)
1029 {
1030 void *tgt = &reply[1];
1031
1032 GNUNET_memcpy (tgt,
1033 &bd->trunc_peer,
1034 sizeof (struct GNUNET_PeerIdentity));
1035 paths = (struct GNUNET_DHT_PathElement *)
1036 (tgt + sizeof (struct GNUNET_PeerIdentity));
1037 }
1038 else
1039 {
1040 paths = (struct GNUNET_DHT_PathElement *) &reply[1];
1041 }
1042 GNUNET_memcpy (paths,
1043 bd->put_path,
1044 sizeof(struct GNUNET_DHT_PathElement)
1045 * bd->put_path_length);
1046 GNUNET_memcpy (&paths[bd->put_path_length],
1047 frc->get_path,
1048 sizeof(struct GNUNET_DHT_PathElement)
1049 * frc->get_path_length);
1050 GNUNET_memcpy (&paths[frc->get_path_length + bd->put_path_length],
1051 bd->data,
1052 bd->data_size);
1054 "Sending reply to query %s for client %p\n",
1055 GNUNET_h2s (query_hash),
1056 record->ch->client);
1057 GNUNET_MQ_send (record->ch->mq,
1058 env);
1059 if (GNUNET_YES == do_free)
1061 return GNUNET_YES;
1062}
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
struct GNUNET_PeerIdentity GDS_my_identity
Identity of this peer.
@ 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:339
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)
unsigned int GNUNET_DHT_verify_path(const void *data, size_t data_size, struct GNUNET_TIME_Absolute exp_time, const struct GNUNET_PeerIdentity *trunc_peer, 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:1349
@ GNUNET_DHT_RO_TRUNCATED
Flag set if the path was truncated.
@ 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_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#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:305
#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:61
#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:640
Closure for forward_reply()
const struct GNUNET_DATACACHE_Block * bd
Block details.
const struct GNUNET_DHT_PathElement * get_path
GET path taken.
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_PeerIdentity trunc_peer
If the path was truncated, this is the peer ID at which the path was truncated.
unsigned int put_path_length
Length of the put_path array.
struct GNUNET_TIME_Absolute expiration_time
When does the block expire?
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:169
uint64_t unique_id
Unique ID of the matching GET request.
Definition: dht.h:180
struct GNUNET_TIME_AbsoluteNBO expiration
When does this entry expire?
Definition: dht.h:185
struct GNUNET_HashCode key
The key that was searched for.
Definition: dht.h:190
uint32_t type
The type for the data.
Definition: dht.h:153
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition: dht.h:163
uint32_t get_path_length
The number of peer identities recorded from the storage location to this peer.
Definition: dht.h:175
A (signed) path tracking a block's flow through the DHT is represented by an array of path elements,...
The identity of the host (wraps the signing key of the peer).

References ForwardReplyContext::bd, ch, GNUNET_DATACACHE_Block::data, GNUNET_DATACACHE_Block::data_size, env, GNUNET_DHT_ClientResultMessage::expiration, GNUNET_DATACACHE_Block::expiration_time, GDS_block_context, GDS_my_identity, GDS_stats, ForwardReplyContext::get_path, GNUNET_DHT_ClientResultMessage::get_path_length, ForwardReplyContext::get_path_length, GNUNET_array_append, GNUNET_BLOCK_check_reply(), GNUNET_BLOCK_REPLY_IRRELEVANT, GNUNET_BLOCK_REPLY_OK_DUPLICATE, GNUNET_BLOCK_REPLY_OK_LAST, GNUNET_BLOCK_REPLY_OK_MORE, GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED, GNUNET_BLOCK_TYPE_ANY, GNUNET_break, GNUNET_CRYPTO_hash(), GNUNET_DHT_RO_FIND_APPROXIMATE, GNUNET_DHT_RO_TRUNCATED, GNUNET_DHT_verify_path(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_h2s_full(), GNUNET_memcmp, 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_DATACACHE_Block::key, GNUNET_DHT_ClientResultMessage::key, LOG, LOG_TRAFFIC, GNUNET_DHT_ClientResultMessage::options, GNUNET_DATACACHE_Block::put_path, GNUNET_DATACACHE_Block::put_path_length, GNUNET_DHT_ClientResultMessage::put_path_length, record(), remove_client_query_record(), GNUNET_DATACACHE_Block::ro, GNUNET_DATACACHE_Block::trunc_peer, GNUNET_DATACACHE_Block::type, GNUNET_DHT_ClientResultMessage::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()

bool GDS_CLIENTS_handle_reply ( const struct GNUNET_DATACACHE_Block 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 1066 of file gnunet-service-dht_clients.c.

1070{
1071 struct ForwardReplyContext frc;
1072 size_t msize = sizeof (struct GNUNET_DHT_ClientResultMessage)
1073 + bd->data_size
1075 * sizeof(struct GNUNET_DHT_PathElement);
1076#if SANITY_CHECKS > 1
1077 bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
1078#endif
1079
1080 if (msize >= GNUNET_MAX_MESSAGE_SIZE)
1081 {
1082 GNUNET_break (0);
1083 return false;
1084 }
1085#if SANITY_CHECKS > 1
1086 if (0 !=
1088 bd->data_size,
1089 bd->expiration_time,
1090 truncated
1091 ? &bd->trunc_peer
1092 : NULL,
1093 bd->put_path,
1094 bd->put_path_length,
1095 get_path,
1096 get_path_length,
1098 {
1099 GNUNET_break (0);
1100 return false;
1101 }
1102#endif
1103 frc.bd = bd;
1104 frc.get_path = get_path;
1105 frc.get_path_length = get_path_length;
1107 "Forwarding reply for query hash %s with GPL %u and PPL %u to client\n",
1108 GNUNET_h2s (query_hash),
1109 get_path_length,
1110 bd->put_path_length);
1111 if (0 ==
1113 query_hash,
1115 &frc))
1116 {
1118 "No matching client for reply for query %s\n",
1119 GNUNET_h2s (query_hash));
1121 "# REPLIES ignored for CLIENTS (no match)",
1122 1,
1123 GNUNET_NO);
1124 }
1125 return true;
1126}
static size_t data_size
Number of bytes in data.
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,...

References ForwardReplyContext::bd, GNUNET_DATACACHE_Block::data, data_size, GNUNET_DATACACHE_Block::data_size, GNUNET_DATACACHE_Block::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_RO_TRUNCATED, GNUNET_DHT_verify_path(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_MAX_MESSAGE_SIZE, GNUNET_NO, GNUNET_STATISTICS_update(), LOG, GNUNET_DATACACHE_Block::put_path, GNUNET_DATACACHE_Block::put_path_length, GNUNET_DHT_ClientResultMessage::put_path_length, GNUNET_DATACACHE_Block::ro, and GNUNET_DATACACHE_Block::trunc_peer.

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:

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

1143{
1144 struct ClientHandle *ch = cls;
1145 struct GNUNET_HELLO_Parser *p;
1146 char *url;
1147 size_t slen;
1148 struct GNUNET_MessageHeader *hdr;
1149 struct GNUNET_MQ_Envelope *env;
1150
1152 GNUNET_assert (NULL != p);
1154 slen = strlen (url) + 1;
1156 "Handling request from local client for my HELLO\n");
1157 env = GNUNET_MQ_msg_extra (hdr,
1158 slen,
1160 memcpy (&hdr[1],
1161 url,
1162 slen);
1163 GNUNET_free (url);
1166 env);
1168}
struct GNUNET_MessageHeader * GDS_my_hello
Our HELLO.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38
void GNUNET_HELLO_parser_free(struct GNUNET_HELLO_Parser *parser)
Release resources of a builder.
Definition: hello-uri.c:379
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_msg(const struct GNUNET_MessageHeader *msg)
Parse msg.
Definition: hello-uri.c:415
char * GNUNET_HELLO_parser_to_url(const struct GNUNET_HELLO_Parser *parser)
Generate GNUnet HELLO URI from a parser.
Definition: hello-uri.c:803
#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_URL
HELLO URL send between client and service (in either direction).
Context for parsing HELLOs.
Definition: hello-uri.c:232
Header for all communications.

References ch, env, GDS_my_hello, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_HELLO_parser_free(), GNUNET_HELLO_parser_from_msg(), GNUNET_HELLO_parser_to_url(), GNUNET_log, GNUNET_MESSAGE_TYPE_DHT_CLIENT_HELLO_URL, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_SERVICE_client_continue(), GNUNET_CADET_Channel::mq, and p.

Here is the call graph for this function:

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

1181{
1182 uint16_t len = ntohs (hdr->size);
1183 const char *buf = (const char *) &hdr[1];
1184
1185 (void) cls;
1186 if ('\0' != buf[len - sizeof (*hdr) - 1])
1187 {
1188 GNUNET_break (0);
1189 return GNUNET_SYSERR;
1190 }
1191 return GNUNET_OK;
1192}

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

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

1205{
1206 struct ClientHandle *ch = cls;
1207 const char *url = (const char *) &msg[1];
1208 struct GNUNET_HELLO_Parser *b;
1209
1211 "Local client provided HELLO URL %s\n",
1212 url);
1214 if (NULL == b)
1215 {
1216 GNUNET_break (0);
1218 return;
1219 }
1223 NULL);
1225}
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
void GDS_try_connect(void *cls, const struct GNUNET_PeerIdentity *pid, const char *uri)
Callback function used to extract URIs from a builder.
const struct GNUNET_PeerIdentity * GNUNET_HELLO_parser_iterate(const struct GNUNET_HELLO_Parser *parser, GNUNET_HELLO_UriCallback uc, void *uc_cls)
Iterate over URIs in a parser.
Definition: hello-uri.c:975
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_url(const char *url)
Parse GNUnet HELLO url.
Definition: hello-uri.c:663

References ch, GDS_try_connect(), GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_HELLO_parser_free(), GNUNET_HELLO_parser_from_url(), GNUNET_HELLO_parser_iterate(), GNUNET_log, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), and msg.

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

1241{
1242 struct ClientHandle *ch = cls;
1243 struct ClientMonitorRecord *r;
1244
1245 r = GNUNET_new (struct ClientMonitorRecord);
1246 r->ch = ch;
1247 r->type = ntohl (msg->type);
1248 r->get = ntohs (msg->get);
1249 r->get_resp = ntohs (msg->get_resp);
1250 r->put = ntohs (msg->put);
1251 if (0 != ntohs (msg->filter_key))
1252 r->key = msg->key;
1255 r);
1257}
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
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.

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, GNUNET_MessageHeader::type, and ClientMonitorRecord::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 1267 of file gnunet-service-dht_clients.c.

1270{
1271 struct ClientHandle *ch = cls;
1272
1274 for (struct ClientMonitorRecord *r = monitor_head;
1275 NULL != r;
1276 r = r->next)
1277 {
1278 bool keys_match;
1279
1280 keys_match =
1281 (GNUNET_is_zero (&r->key))
1282 ? (0 == ntohs (msg->filter_key))
1283 : ( (0 != ntohs (msg->filter_key)) &&
1284 (! GNUNET_memcmp (&r->key,
1285 &msg->key)) );
1286 if ( (ch == r->ch) &&
1287 (ntohl (msg->type) == r->type) &&
1288 (r->get == msg->get) &&
1289 (r->get_resp == msg->get_resp) &&
1290 (r->put == msg->put) &&
1291 keys_match)
1292 {
1295 r);
1296 GNUNET_free (r);
1297 return; /* Delete only ONE entry */
1298 }
1299 }
1300}
#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 1324 of file gnunet-service-dht_clients.c.

1328{
1329 struct ClientHandle **cl = NULL;
1330 unsigned int cl_size = 0;
1331
1332 for (struct ClientMonitorRecord *m = monitor_head;
1333 NULL != m;
1334 m = m->next)
1335 {
1336 bool found = false;
1337
1338 if ( (GNUNET_BLOCK_TYPE_ANY != m->type) &&
1339 (m->type != type) )
1340 continue;
1341 if ( (! GNUNET_is_zero (&m->key)) &&
1342 (0 ==
1344 &m->key)) )
1345 continue;
1346 /* Don't send duplicates */
1347 for (unsigned i = 0; i < cl_size; i++)
1348 if (cl[i] == m->ch)
1349 {
1350 found = true;
1351 break;
1352 }
1353 if (found)
1354 continue;
1356 cl_size,
1357 m->ch);
1358 cb (cb_cls,
1359 m);
1360 }
1361 GNUNET_free (cl);
1362}
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:103
static uint32_t type
Type string converted to DNS type value.

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

1389{
1390 struct GetActionContext *gac = cls;
1391 struct GNUNET_MQ_Envelope *env;
1392 struct GNUNET_DHT_MonitorGetMessage *mmsg;
1393
1394 env = GNUNET_MQ_msg (mmsg,
1396 mmsg->options = htonl (gac->options);
1397 mmsg->type = htonl (gac->type);
1398 mmsg->hop_count = htonl (gac->hop_count);
1400 mmsg->key = *gac->key;
1401 GNUNET_MQ_send (m->ch->mq,
1402 env);
1403}
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:76
#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:334
uint32_t hop_count
Hop count.
Definition: dht.h:353
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition: dht.h:343
uint32_t desired_replication_level
Replication level for this message.
Definition: dht.h:358
struct GNUNET_HashCode key
The key to store the value under.
Definition: dht.h:368
uint32_t type
The type of data in the request.
Definition: dht.h:348
Closure for get_action();.
const struct GNUNET_HashCode * key
enum GNUNET_DHT_RouteOption options
enum GNUNET_BLOCK_Type type

References GNUNET_DHT_MonitorGetMessage::desired_replication_level, GetActionContext::desired_replication_level, env, GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET, GNUNET_MQ_msg, 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,
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.
desired_replication_levelDesired replication level.
keyKey of the requested data.

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

1412{
1413 struct GetActionContext gac = {
1414 .options = options,
1415 .type = type,
1416 .hop_count = hop_count,
1417 .desired_replication_level = desired_replication_level,
1418 .key = key
1419 };
1420
1422 key,
1423 &get_action,
1424 &gac);
1425}
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
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 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:

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

1449{
1450 const struct ResponseActionContext *resp_ctx = cls;
1451 const struct GNUNET_DATACACHE_Block *bd = resp_ctx->bd;
1452 bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
1453 struct GNUNET_MQ_Envelope *env;
1455 struct GNUNET_DHT_PathElement *path;
1456 size_t msize;
1457
1458 msize = bd->data_size;
1459 msize += (resp_ctx->get_path_length + bd->put_path_length)
1460 * sizeof(struct GNUNET_DHT_PathElement);
1461 if (truncated)
1462 msize += sizeof (struct GNUNET_PeerIdentity);
1463 env = GNUNET_MQ_msg_extra (mmsg,
1464 msize,
1466 mmsg->type = htonl (bd->type);
1467 mmsg->put_path_length = htonl (bd->put_path_length);
1468 mmsg->get_path_length = htonl (resp_ctx->get_path_length);
1470 mmsg->key = bd->key;
1471 if (truncated)
1472 {
1473 void *tgt = &mmsg[1];
1474
1475 GNUNET_memcpy (tgt,
1476 &bd->trunc_peer,
1477 sizeof (struct GNUNET_PeerIdentity));
1478 path = (struct GNUNET_DHT_PathElement *)
1479 (tgt + sizeof (struct GNUNET_PeerIdentity));
1480 }
1481 else
1482 {
1483 path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
1484 }
1485 GNUNET_memcpy (path,
1486 bd->put_path,
1487 bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement));
1488 GNUNET_memcpy (path,
1489 resp_ctx->get_path,
1490 resp_ctx->get_path_length
1491 * sizeof(struct GNUNET_DHT_PathElement));
1492 GNUNET_memcpy (&path[resp_ctx->get_path_length],
1493 bd->data,
1494 bd->data_size);
1495 GNUNET_MQ_send (m->ch->mq,
1496 env);
1497}
#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:377
struct GNUNET_HashCode key
The key of the corresponding GET request.
Definition: dht.h:416
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the content expire?
Definition: dht.h:411
uint32_t type
Content type.
Definition: dht.h:386
uint32_t get_path_length
Length of the GET path that follows (if tracked).
Definition: dht.h:406
uint32_t put_path_length
Length of the PUT path that follows (if tracked).
Definition: dht.h:401
Closure for response_action().
const struct GNUNET_DHT_PathElement * get_path
const struct GNUNET_DATACACHE_Block * bd

References ResponseActionContext::bd, GNUNET_DATACACHE_Block::data, GNUNET_DATACACHE_Block::data_size, env, GNUNET_DATACACHE_Block::expiration_time, GNUNET_DHT_MonitorGetRespMessage::expiration_time, ResponseActionContext::get_path, GNUNET_DHT_MonitorGetRespMessage::get_path_length, ResponseActionContext::get_path_length, GNUNET_DHT_RO_TRUNCATED, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_TIME_absolute_hton(), GNUNET_DATACACHE_Block::key, GNUNET_DHT_MonitorGetRespMessage::key, m, GNUNET_ARM_MonitorHandle::mq, GNUNET_DATACACHE_Block::put_path, GNUNET_DATACACHE_Block::put_path_length, GNUNET_DHT_MonitorGetRespMessage::put_path_length, GNUNET_DATACACHE_Block::ro, GNUNET_DATACACHE_Block::trunc_peer, GNUNET_DATACACHE_Block::type, and GNUNET_DHT_MonitorGetRespMessage::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 GNUNET_DATACACHE_Block 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 1501 of file gnunet-service-dht_clients.c.

1504{
1505 struct ResponseActionContext rac = {
1506 .bd = bd,
1507 .get_path = get_path,
1508 .get_path_length = get_path_length
1509 };
1510
1512 &bd->key,
1514 &rac);
1515}
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, GNUNET_DATACACHE_Block::key, response_action(), and GNUNET_DATACACHE_Block::type.

Referenced by process_reply_with_path().

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

1539{
1540 const struct PutActionContext *put_ctx = cls;
1541 const struct GNUNET_DATACACHE_Block *bd = put_ctx->bd;
1542 bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
1543 struct GNUNET_MQ_Envelope *env;
1544 struct GNUNET_DHT_MonitorPutMessage *mmsg;
1545 struct GNUNET_DHT_PathElement *msg_path;
1546 size_t msize;
1547
1548 msize = bd->data_size
1549 + bd->put_path_length
1550 * sizeof(struct GNUNET_DHT_PathElement);
1551 if (truncated)
1552 msize += sizeof (struct GNUNET_PeerIdentity);
1553 env = GNUNET_MQ_msg_extra (mmsg,
1554 msize,
1556 mmsg->options = htonl (bd->ro);
1557 mmsg->type = htonl (bd->type);
1558 mmsg->hop_count = htonl (put_ctx->hop_count);
1560 mmsg->put_path_length = htonl (bd->put_path_length);
1561 mmsg->key = bd->key;
1563 if (truncated)
1564 {
1565 void *tgt = &mmsg[1];
1566
1567 GNUNET_memcpy (tgt,
1568 &bd->trunc_peer,
1569 sizeof (struct GNUNET_PeerIdentity));
1570 msg_path = (struct GNUNET_DHT_PathElement *)
1571 (tgt + sizeof (struct GNUNET_PeerIdentity));
1572 }
1573 else
1574 {
1575 msg_path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
1576 }
1577 GNUNET_memcpy (msg_path,
1578 bd->put_path,
1579 bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement));
1580 GNUNET_memcpy (&msg_path[bd->put_path_length],
1581 bd->data,
1582 bd->data_size);
1583 GNUNET_MQ_send (m->ch->mq,
1584 env);
1585}
#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:239
uint32_t options
Message options, actually an 'enum GNUNET_DHT_RouteOption' value.
Definition: dht.h:248
struct GNUNET_TIME_AbsoluteNBO expiration_time
How long should this data persist?
Definition: dht.h:274
uint32_t desired_replication_level
Replication level for this message.
Definition: dht.h:263
struct GNUNET_HashCode key
The key to store the value under.
Definition: dht.h:279
uint32_t hop_count
Hop count so far.
Definition: dht.h:258
uint32_t type
The type of data in the request.
Definition: dht.h:253
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:269
Closure for put_action().
const struct GNUNET_DATACACHE_Block * bd

References PutActionContext::bd, GNUNET_DATACACHE_Block::data, GNUNET_DATACACHE_Block::data_size, GNUNET_DHT_MonitorPutMessage::desired_replication_level, PutActionContext::desired_replication_level, env, GNUNET_DATACACHE_Block::expiration_time, GNUNET_DHT_MonitorPutMessage::expiration_time, GNUNET_DHT_RO_TRUNCATED, 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_DATACACHE_Block::key, GNUNET_DHT_MonitorPutMessage::key, m, GNUNET_ARM_MonitorHandle::mq, GNUNET_DHT_MonitorPutMessage::options, GNUNET_DATACACHE_Block::put_path, GNUNET_DATACACHE_Block::put_path_length, GNUNET_DHT_MonitorPutMessage::put_path_length, GNUNET_DATACACHE_Block::ro, GNUNET_DATACACHE_Block::trunc_peer, GNUNET_DATACACHE_Block::type, and GNUNET_DHT_MonitorPutMessage::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 ( const struct GNUNET_DATACACHE_Block 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
bddetails about the block
hop_countHop count so far.
desired_replication_levelDesired replication level.

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

1592{
1593 struct PutActionContext put_ctx = {
1594 .bd = bd,
1595 .hop_count = hop_count,
1596 .desired_replication_level = desired_replication_level
1597 };
1598
1600 &bd->key,
1601 &put_action,
1602 &put_ctx);
1603}
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, GNUNET_DATACACHE_Block::key, put_action(), and GNUNET_DATACACHE_Block::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()

void GDS_CLIENTS_init ( void  )

Initialize client subsystem.

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

1614{
1617 GNUNET_YES);
1620}
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()

void GDS_CLIENTS_stop ( void  )

Shutdown client subsystem.

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

1628{
1629 if (NULL != retry_task)
1630 {
1632 retry_task = NULL;
1633 }
1634}

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:

◆ GDS_CLIENTS_done()

void GDS_CLIENTS_done ( void  )

◆ __attribute__()

void __attribute__ ( (destructor)  )

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

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

1693{
1694 if (NULL != retry_heap)
1695 {
1698 retry_heap = NULL;
1699 }
1700 if (NULL != forward_map)
1701 {
1704 forward_map = NULL;
1705 }
1706}
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.

References forward_map, GNUNET_assert, GNUNET_CONTAINER_heap_destroy(), GNUNET_CONTAINER_heap_get_size(), GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_size(), and retry_heap.

Here is the call graph for this function:

Variable Documentation

◆ GDS_block_context

◆ GDS_stats

◆ GDS_pils

struct GNUNET_PILS_Handle* GDS_pils

Handle for the pils service.

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

Referenced by run(), and shutdown_task().

◆ GDS_service

struct GNUNET_SERVICE_Handle* GDS_service

Handle for the service.

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

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

◆ monitor_head

struct ClientMonitorRecord* monitor_head
static

List of active monitoring requests.

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

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

◆ forward_map

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

Referenced by __attribute__(), 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 262 of file gnunet-service-dht_clients.c.

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