GNUnet 0.28.1-dev.4-46-g92a0edb0d
 
Loading...
Searching...
No Matches
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  PendingPut
 A local PUT that we could not route anywhere, kept so that we can try again once we have a peer to route it to. 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.
 
#define LOG_TRAFFIC(kind, ...)
 Should routing details be logged to stderr (for debugging)?
 
#define LOG(kind, ...)   GNUNET_log_from (kind, "dht-clients", __VA_ARGS__)
 
#define UNROUTED_RETRY_INTERVAL
 Upper bound on the retry interval for a GET that we were unable to route anywhere.
 
#define MAXIMUM_GET_RETRY_INTERVAL
 Upper bound on the retry interval during FAST_RETRY_WINDOW.
 
#define FAST_RETRY_WINDOW
 For how long after a GET was received from the client do we bound the retry interval by MAXIMUM_GET_RETRY_INTERVAL? Beyond this the client is no longer waiting interactively (GNS gives up much earlier), and long-running searches (fs, cadet) should be allowed to back off.
 
#define UNROUTED_PUT_TIMEOUT
 How long do we keep re-trying a local PUT that we were unable to route anywhere? Long enough to cover the usual "peer just started, transport and CORE have not brought up a link yet" case.
 
#define UNROUTED_PUT_RETRY_INTERVAL
 Upper bound on the retry interval for such a PUT.
 
#define MAX_PENDING_PUTS   1024
 How many unroutable local PUTs do we hold on to at most?
 
#define GDS_DHT_SERVICE_INIT(name, run)
 Define "main" method using service macro.
 

Typedefs

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

Functions

static void remove_client_query_record (struct ClientQueryRecord *record)
 Free data structures associated with the given query.
 
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.
 
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.
 
static void transmit_request (struct ClientQueryRecord *cqr)
 Route the given request via the DHT.
 
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.
 
static enum GNUNET_GenericReturnValue reset_retry_backoff (void *cls, const struct GNUNET_HashCode *key, void *value)
 Make a client's GET request eligible for immediate re-transmission.
 
void GDS_CLIENTS_retry_requests (void)
 Our routing table gained a peer.
 
static enum GNUNET_GenericReturnValue check_dht_local_put (void *cls, const struct GNUNET_DHT_ClientPutMessage *dht_msg)
 Check DHT PUT messages from the client.
 
static void route_pending_put (struct PendingPut *pp)
 Hand pp to the routing layer.
 
static void put_retry_task_cb (void *cls)
 
static void schedule_put_retry (void)
 Make sure the retry task is armed for the earliest pending PUT.
 
static void cb_forwarded_dht_local_put (void *cls, enum GNUNET_GenericReturnValue forwarded)
 
void GDS_CLIENTS_retry_puts (void)
 Our routing table gained a peer.
 
static void handle_dht_local_put (void *cls, const struct GNUNET_DHT_ClientPutMessage *dht_msg)
 Handler for PUT messages.
 
static void handle_local_result (void *cls, const struct GNUNET_DATACACHE_Block *bd)
 Handle a result from local datacache for a GET operation.
 
static enum GNUNET_GenericReturnValue check_dht_local_get (void *cls, const struct GNUNET_DHT_ClientGetMessage *get)
 Check DHT GET messages from the client.
 
static void handle_dht_local_get (void *cls, const struct GNUNET_DHT_ClientGetMessage *get)
 Handler for DHT GET messages from the client.
 
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.
 
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.
 
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.
 
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.
 
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)
 
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.
 
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.
 
static void handle_dht_local_hello_get (void *cls, const struct GNUNET_MessageHeader *msg)
 Handler for HELLO GET message.
 
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.
 
static void handle_dht_local_hello_offer (void *cls, const struct GNUNET_MessageHeader *msg)
 Handler for HELLO OFFER message.
 
static void handle_dht_local_monitor (void *cls, const struct GNUNET_DHT_MonitorStartStopMessage *msg)
 Handler for monitor start messages.
 
static void handle_dht_local_monitor_stop (void *cls, const struct GNUNET_DHT_MonitorStartStopMessage *msg)
 Handler for monitor stop messages.
 
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.
 
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 response_action (void *cls, struct ClientMonitorRecord *m)
 Function called on monitors that match a response.
 
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.
 
static void put_action (void *cls, struct ClientMonitorRecord *m)
 Function called on monitors that match a 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.
 
void GDS_CLIENTS_init (void)
 Initialize client subsystem.
 
void GDS_CLIENTS_stop (void)
 Shutdown client subsystem.
 
void GDS_CLIENTS_done (void)
 
void __attribute__ ((destructor))
 MINIMIZE heap size (way below 128k) since this process doesn't need much.
 

Variables

struct GNUNET_BLOCK_ContextGDS_block_context
 Our handle to the BLOCK library.
 
struct GNUNET_STATISTICS_HandleGDS_stats
 Handle for the statistics service.
 
struct GNUNET_PILS_HandleGDS_pils
 Handle for the pils service.
 
struct GNUNET_SERVICE_HandleGDS_service
 Handle for the service.
 
const struct GNUNET_CONFIGURATION_HandleGDS_cfg
 The configuration the DHT service is running with.
 
static struct ClientMonitorRecordmonitor_head
 List of active monitoring requests.
 
static struct ClientMonitorRecordmonitor_tail
 List of active monitoring requests.
 
static struct GNUNET_CONTAINER_MultiHashMapforward_map
 Hashmap for fast key based lookup, maps keys to struct ClientQueryRecord entries.
 
static struct GNUNET_CONTAINER_Heapretry_heap
 Heap with all of our client's request, sorted by retry time (earliest on top).
 
static struct GNUNET_SCHEDULER_Taskretry_task
 Task that re-transmits requests (using retry_heap).
 
static struct PendingPutpp_head
 Head of the list of PUTs waiting for a usable routing table.
 
static struct PendingPutpp_tail
 Tail of the list of PUTs waiting for a usable routing table.
 
static unsigned int pp_count
 Number of entries in the pp_head DLL.
 
static struct GNUNET_SCHEDULER_Taskput_retry_task
 Task that re-tries the PUTs in the pp_head DLL.
 

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

◆ LOG

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

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

◆ UNROUTED_RETRY_INTERVAL

#define UNROUTED_RETRY_INTERVAL
Value:
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition time.c:486

Upper bound on the retry interval for a GET that we were unable to route anywhere.

Such a GET consumed no bandwidth, so the regular exponential back-off (which runs up to 15 minutes) must not apply to it: we want to be back on the wire quickly once the routing table has a usable peer again.

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

◆ MAXIMUM_GET_RETRY_INTERVAL

#define MAXIMUM_GET_RETRY_INTERVAL
Value:

Upper bound on the retry interval during FAST_RETRY_WINDOW.

With the plain 15 minute ceiling of GNUNET_TIME_STD_BACKOFF the attempts fall on 0s, 2s, 6s, 14s, 30s, ..., so a single unanswered attempt already costs an interactive lookup (GNS) tens of seconds.

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

◆ FAST_RETRY_WINDOW

#define FAST_RETRY_WINDOW
Value:
#define GNUNET_TIME_UNIT_MINUTES
One minute.

For how long after a GET was received from the client do we bound the retry interval by MAXIMUM_GET_RETRY_INTERVAL? Beyond this the client is no longer waiting interactively (GNS gives up much earlier), and long-running searches (fs, cadet) should be allowed to back off.

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

◆ UNROUTED_PUT_TIMEOUT

#define UNROUTED_PUT_TIMEOUT
Value:

How long do we keep re-trying a local PUT that we were unable to route anywhere? Long enough to cover the usual "peer just started, transport and CORE have not brought up a link yet" case.

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

◆ UNROUTED_PUT_RETRY_INTERVAL

#define UNROUTED_PUT_RETRY_INTERVAL
Value:

Upper bound on the retry interval for such a PUT.

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

◆ MAX_PENDING_PUTS

#define MAX_PENDING_PUTS   1024

How many unroutable local PUTs do we hold on to at most?

Definition at line 92 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 2064 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 1715 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 387 of file gnunet-service-dht_clients.c.

388{
389 struct ClientHandle *ch = record->ch;
390
392 ch->cqr_tail,
393 record);
396 &record->key,
397 record));
398 if (NULL != record->hnode)
400 GNUNET_array_grow (record->seen_replies,
401 record->seen_replies_count,
402 0);
404}
static struct GNUNET_CADET_Channel * ch
Channel handle.
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 417 of file gnunet-service-dht_clients.c.

420{
421 struct ClientHandle *ch;
422
423 (void) cls;
424 ch = GNUNET_new (struct ClientHandle);
425 ch->client = client;
426 ch->mq = mq;
427 return ch;
428}
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
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 440 of file gnunet-service-dht_clients.c.

443{
444 struct ClientHandle *ch = app_ctx;
445
446 (void) cls;
447 (void) client;
449 "Local client %p disconnects\n",
450 ch);
451 {
453
455 NULL != monitor;
456 monitor = next)
457 {
458 next = monitor->next;
459 if (monitor->ch != ch)
460 continue;
463 monitor);
465 }
466 }
467
468 {
469 struct ClientQueryRecord *cqr;
470
471 while (NULL != (cqr = ch->cqr_head))
473 }
474 GNUNET_free (ch);
475}
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 486 of file gnunet-service-dht_clients.c.

487{
488 struct GNUNET_BLOCK_Group *bg;
489 struct GNUNET_CONTAINER_BloomFilter *peer_bf;
490 enum GNUNET_GenericReturnValue routed;
491
493 "# GET requests from clients injected",
494 1,
495 GNUNET_NO);
497 cqr->type,
498 NULL, /* raw data */
499 0, /* raw data size */
500 "seen-set-size",
502 NULL);
504 cqr->seen_replies,
505 cqr->seen_replies_count);
506 peer_bf
511 "Initiating GET for %s, replication %u, already have %u replies\n",
512 GNUNET_h2s (&cqr->key),
513 cqr->replication,
514 cqr->seen_replies_count);
515 routed = GDS_NEIGHBOURS_handle_get (cqr->type,
516 cqr->msg_options,
517 cqr->replication,
518 0 /* hop count */,
519 &cqr->key,
520 cqr->xquery,
521 cqr->xquery_size,
522 bg,
523 peer_bf);
526
527 /* Exponential back-off for retries.
528 * max. is #GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */
532 <,
534 {
535 /* Somebody is still waiting for an answer; do not let the back-off
536 turn one lost attempt into tens of seconds of latency. */
537 cqr->retry_frequency
539 cqr->retry_frequency);
540 }
541 if (GNUNET_OK != routed)
542 {
543 /* We had no peer to route this to, so nothing was sent and nothing
544 can answer. Cap the interval so we come back as soon as the
545 routing table recovers instead of idling for up to 15 minutes. */
547 "# GET requests from clients not routed",
548 1,
549 GNUNET_NO);
550 cqr->retry_frequency
552 cqr->retry_frequency);
553 }
555}
#define DHT_BLOOM_SIZE
Size of the bloom filter the DHT uses to filter peers.
Definition dht.h:34
#define FAST_RETRY_WINDOW
For how long after a GET was received from the client do we bound the retry interval by MAXIMUM_GET_R...
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 MAXIMUM_GET_RETRY_INTERVAL
Upper bound on the retry interval during FAST_RETRY_WINDOW.
#define UNROUTED_RETRY_INTERVAL
Upper bound on the retry interval for a GET that we were unable to route anywhere.
#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_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ 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_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition time.c:344
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition time.c:438
#define GNUNET_TIME_relative_cmp(t1, op, t2)
Compare two relative times.
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?
struct GNUNET_TIME_Absolute start_time
When did the client give us this request?
uint32_t replication
Desired replication level.

References DHT_BLOOM_SIZE, FAST_RETRY_WINDOW, 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_OK, GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get_duration(), GNUNET_TIME_relative_cmp, GNUNET_TIME_relative_min(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_STD_BACKOFF, ClientQueryRecord::key, LOG, MAXIMUM_GET_RETRY_INTERVAL, ClientQueryRecord::msg_options, ClientQueryRecord::replication, ClientQueryRecord::retry_frequency, ClientQueryRecord::retry_time, ClientQueryRecord::seen_replies, ClientQueryRecord::seen_replies_count, ClientQueryRecord::start_time, ClientQueryRecord::type, UNROUTED_RETRY_INTERVAL, 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 566 of file gnunet-service-dht_clients.c.

567{
568 struct ClientQueryRecord *cqr;
569
570 (void) cls;
571 retry_task = NULL;
572 while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap)))
573 {
574 cqr->hnode = NULL;
576 {
577 cqr->hnode
579 cqr,
584 NULL);
585 return;
586 }
587 transmit_request (cqr);
588 cqr->hnode
590 cqr,
592 }
593}
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:1260
bool GNUNET_TIME_absolute_is_past(struct GNUNET_TIME_Absolute abs)
Test if abs is truly in the past (excluding now).
Definition time.c:667
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 GDS_CLIENTS_retry_requests(), 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:

◆ reset_retry_backoff()

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

Make a client's GET request eligible for immediate re-transmission.

Parameters
clsNULL
keythe query (not used)
valuethe struct ClientQueryRecord
Returns
GNUNET_YES (continue to iterate)

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

608{
609 struct ClientQueryRecord *cqr = value;
610
611 (void) cls;
612 (void) key;
615 if (NULL != cqr->hnode)
618 return GNUNET_YES;
619}
struct GNUNET_HashCode key
The key used in the DHT.
static char * value
Value of the record to add/remove.
void GNUNET_CONTAINER_heap_update_cost(struct GNUNET_CONTAINER_HeapNode *node, GNUNET_CONTAINER_HeapCostType new_cost)
Updates the cost of any node in the tree.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111

References GNUNET_TIME_Absolute::abs_value_us, GNUNET_CONTAINER_heap_update_cost(), GNUNET_TIME_absolute_get(), GNUNET_TIME_UNIT_SECONDS, GNUNET_YES, ClientQueryRecord::hnode, key, ClientQueryRecord::retry_frequency, ClientQueryRecord::retry_time, and value.

Referenced by GDS_CLIENTS_retry_requests().

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

◆ GDS_CLIENTS_retry_requests()

void GDS_CLIENTS_retry_requests ( void  )

Our routing table gained a peer.

Reset the retry back-off of all pending client GET requests and re-transmit them now: a request that found no route earlier has been backing off for up to 15 minutes without ever reaching the network.

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

624{
626 return;
628 "Routing table changed, re-transmitting %u pending GET request(s)\n",
631 "# GET requests retried after routing table change",
633 GNUNET_NO);
636 NULL);
637 if (NULL != retry_task)
640 NULL);
641}
static enum GNUNET_GenericReturnValue reset_retry_backoff(void *cls, const struct GNUNET_HashCode *key, void *value)
Make a client's GET request eligible for immediate re-transmission.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
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:1310

References forward_map, GDS_stats, GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), LOG, reset_retry_backoff(), retry_task, and transmit_next_request_task().

Referenced by GDS_u_connect().

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

654{
655 uint32_t replication_level = ntohl (dht_msg->desired_replication_level);
656
657 (void) cls;
659 {
660 GNUNET_break_op (0);
661 return GNUNET_SYSERR;
662 }
663 return GNUNET_OK;
664}
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_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.

◆ route_pending_put()

static void route_pending_put ( struct PendingPut pp)
static

Hand pp to the routing layer.

Consumes pp: the operation callback either frees it or re-queues it.

Parameters
ppthe PUT to route

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

784{
785 struct GNUNET_CONTAINER_BloomFilter *peer_bf;
786
787 peer_bf
791 /* Takes over @a pp via the callback, which may run synchronously. */
794 0 /* hop count */,
795 peer_bf,
797 pp);
799}
static void cb_forwarded_dht_local_put(void *cls, enum GNUNET_GenericReturnValue forwarded)
void GDS_NEIGHBOURS_handle_put(const struct GNUNET_DATACACHE_Block *bd, uint16_t desired_replication_level, uint16_t hop_count, struct GNUNET_CONTAINER_BloomFilter *bf, GDS_PutOperationCallback cb, void *cb_cls)
Perform a PUT operation.
uint32_t replication_level
Replication level the client asked for.
struct GNUNET_DATACACHE_Block bd
The block to store.

References PendingPut::bd, cb_forwarded_dht_local_put(), DHT_BLOOM_SIZE, GDS_NEIGHBOURS_handle_put(), GNUNET_CONSTANTS_BLOOMFILTER_K, GNUNET_CONTAINER_bloomfilter_free(), GNUNET_CONTAINER_bloomfilter_init(), and PendingPut::replication_level.

Referenced by handle_dht_local_put(), and put_retry_task_cb().

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

◆ put_retry_task_cb()

static void put_retry_task_cb ( void *  cls)
static

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

679{
680 struct PendingPut *ready_head = NULL;
681 struct PendingPut *ready_tail = NULL;
683 struct PendingPut *nxt;
684
685 (void) cls;
686 put_retry_task = NULL;
687 /* Splice the entries that are due out of the DLL first: routing one of
688 them can re-queue it (and does, whenever it still finds no route). */
689 for (struct PendingPut *pp = pp_head; NULL != pp; pp = nxt)
690 {
691 nxt = pp->next;
692 if (! GNUNET_TIME_absolute_is_past (pp->retry_time))
693 continue;
695 pp_tail,
696 pp);
697 pp_count--;
700 pp);
701 }
702 while (NULL != (nxt = ready_head))
703 {
706 nxt);
707 route_pending_put (nxt);
708 }
709 /* Re-queueing above may have armed the task again; we know better. */
710 if (NULL != put_retry_task)
711 {
713 put_retry_task = NULL;
714 }
715 if (NULL == pp_head)
716 return;
717 for (struct PendingPut *pp = pp_head; NULL != pp; pp = pp->next)
719 pp->retry_time);
722 NULL);
723}
static struct PendingPut * pp_tail
Tail of the list of PUTs waiting for a usable routing table.
static void route_pending_put(struct PendingPut *pp)
Hand pp to the routing layer.
static struct PendingPut * pp_head
Head of the list of PUTs waiting for a usable routing table.
static void put_retry_task_cb(void *cls)
static unsigned int pp_count
Number of entries in the pp_head DLL.
static struct GNUNET_SCHEDULER_Task * put_retry_task
Task that re-tries the PUTs in the pp_head DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_min(struct GNUNET_TIME_Absolute t1, struct GNUNET_TIME_Absolute t2)
Return the minimum of two absolute time values.
Definition time.c:360
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
static struct GNUNET_SCHEDULER_Task * ready_tail[GNUNET_SCHEDULER_PRIORITY_COUNT]
Tail of list of tasks ready to run right now, grouped by importance.
Definition scheduler.c:384
static struct GNUNET_SCHEDULER_Task * ready_head[GNUNET_SCHEDULER_PRIORITY_COUNT]
Head of list of tasks ready to run right now, grouped by importance.
Definition scheduler.c:378
Time for absolute times used by GNUnet, in microseconds.
A local PUT that we could not route anywhere, kept so that we can try again once we have a peer to ro...
struct GNUNET_TIME_Absolute retry_time
When should we try again?
struct PendingPut * next
Kept in a DLL.

References GNUNET_CONTAINER_DLL_insert_tail, GNUNET_CONTAINER_DLL_remove, GNUNET_SCHEDULER_add_at(), GNUNET_SCHEDULER_cancel(), GNUNET_TIME_absolute_is_past(), GNUNET_TIME_absolute_min(), GNUNET_TIME_UNIT_FOREVER_ABS, PendingPut::next, pp_count, pp_head, pp_tail, put_retry_task, put_retry_task_cb(), ready_head, ready_tail, PendingPut::retry_time, and route_pending_put().

Referenced by put_retry_task_cb(), and schedule_put_retry().

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

◆ schedule_put_retry()

static void schedule_put_retry ( void  )
static

Make sure the retry task is armed for the earliest pending PUT.

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

References GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), put_retry_task, and put_retry_task_cb().

Referenced by cb_forwarded_dht_local_put(), and GDS_CLIENTS_retry_puts().

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

◆ cb_forwarded_dht_local_put()

static void cb_forwarded_dht_local_put ( void *  cls,
enum GNUNET_GenericReturnValue  forwarded 
)
static

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

742{
743 struct PendingPut *pp = cls;
744
745 if (GNUNET_OK == forwarded)
746 {
747 GNUNET_free (pp);
748 return;
749 }
750 /* Nothing was sent, so nothing can store this block and no retry
751 happens anywhere else: the DHT keeps no state about a PUT, and the
752 client's continuation has already reported success (it fires when
753 the request left the client, not when it was routed). Hold on to
754 the block and try again when we have somewhere to send it. */
756 "# Local PUT requests not routed",
757 1,
758 GNUNET_NO);
762 {
764 "# Local PUT requests dropped (never routed)",
765 1,
766 GNUNET_NO);
767 GNUNET_free (pp);
768 return;
769 }
775 pp_tail,
776 pp);
777 pp_count++;
779}
#define MAX_PENDING_PUTS
How many unroutable local PUTs do we hold on to at most?
static void schedule_put_retry(void)
Make sure the retry task is armed for the earliest pending PUT.
#define UNROUTED_PUT_RETRY_INTERVAL
Upper bound on the retry interval for such a PUT.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct GNUNET_TIME_Absolute expiration_time
When does the block expire?
struct GNUNET_TIME_Absolute give_up_time
When do we give up on this block?
struct GNUNET_TIME_Relative retry_frequency
Current delay between attempts.

References PendingPut::bd, GNUNET_DATACACHE_Block::expiration_time, GDS_stats, PendingPut::give_up_time, GNUNET_CONTAINER_DLL_insert, GNUNET_free, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_is_past(), GNUNET_TIME_relative_min(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_STD_BACKOFF, MAX_PENDING_PUTS, pp_count, pp_head, pp_tail, PendingPut::retry_frequency, PendingPut::retry_time, schedule_put_retry(), and UNROUTED_PUT_RETRY_INTERVAL.

Referenced by route_pending_put().

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

◆ GDS_CLIENTS_retry_puts()

void GDS_CLIENTS_retry_puts ( void  )

Our routing table gained a peer.

Re-try the local PUTs that we were unable to route: nothing else will, as the DHT keeps no state about a PUT and the client was told the operation succeeded.

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

804{
805 if (NULL == pp_head)
806 return;
808 "Routing table changed, re-trying %u unrouted PUT(s)\n",
809 pp_count);
811 "# PUT requests retried after routing table change",
812 pp_count,
813 GNUNET_NO);
814 for (struct PendingPut *pp = pp_head; NULL != pp; pp = pp->next)
815 {
816 pp->retry_frequency = GNUNET_TIME_UNIT_SECONDS;
817 pp->retry_time = GNUNET_TIME_absolute_get ();
818 }
820}

References GDS_stats, GNUNET_ERROR_TYPE_DEBUG, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get(), GNUNET_TIME_UNIT_SECONDS, LOG, PendingPut::next, pp_count, pp_head, and schedule_put_retry().

Referenced by GDS_u_connect().

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

◆ handle_dht_local_put()

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

Handler for PUT messages.

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

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

832{
833 struct ClientHandle *ch = cls;
834 uint16_t size = ntohs (dht_msg->header.size);
835 uint32_t replication_level
836 = ntohl (dht_msg->desired_replication_level);
837 struct GNUNET_DATACACHE_Block bd = {
838 .key = dht_msg->key,
839 .expiration_time = GNUNET_TIME_absolute_ntoh (dht_msg->expiration),
840 .data = &dht_msg[1],
841 .data_size = size - sizeof (*dht_msg),
842 .type = ntohl (dht_msg->type),
843 .ro = ntohl (dht_msg->options)
844 };
845
847 "Handling local PUT of %lu-bytes for query %s of type %u\n",
848 (unsigned long) (size - sizeof(struct GNUNET_DHT_ClientPutMessage)),
849 GNUNET_h2s (&dht_msg->key),
850 (unsigned int) bd.type);
852 {
853 /* Without our own identity we can neither decide whether to store
854 this block nor route it: GDS_am_closest_peer(),
855 GDS_DATACACHE_handle_put() and GDS_NEIGHBOURS_handle_put() all
856 require it. Should not happen -- the service stays suspended
857 until PILS answers -- but drop the request rather than abort. */
858 GNUNET_break (0);
860 "# PUT requests dropped (no identity yet)",
861 1,
862 GNUNET_NO);
864 return;
865 }
866#if SANITY_CHECKS > 0
867 if (GNUNET_OK !=
869 bd.type,
870 bd.data,
871 bd.data_size))
872 {
873 GNUNET_break (0);
875 return;
876 }
877#endif
879 "# PUT requests received from clients",
880 1,
881 GNUNET_NO);
883 "CLIENT-PUT %s\n",
884 GNUNET_h2s_full (&dht_msg->key));
885 /* give to local clients */
887 &bd.key,
888 0, NULL /* get path */));
889
890 {
891 struct GNUNET_CONTAINER_BloomFilter *peer_bf;
892 struct PendingPut *pp;
893
894 peer_bf
898 /* store locally */
900 (GDS_am_closest_peer (&dht_msg->key,
901 peer_bf)))
904 /* route to other peers; the copy survives a failure to route so that
905 we can try again, the client message does not */
906 pp = GNUNET_malloc (sizeof (*pp) + bd.data_size);
907 pp->bd = bd;
908 pp->bd.data = &pp[1];
909 GNUNET_memcpy (&pp[1],
910 bd.data,
911 bd.data_size);
914 pp->give_up_time
917 }
919 &bd,
920 0, /* hop count */
923}
#define UNROUTED_PUT_TIMEOUT
How long do we keep re-trying a local PUT that we were unable to route anywhere? Long enough to cover...
struct GNUNET_PILS_Handle * GDS_pils
Handle for the pils service.
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_am_closest_peer(const struct GNUNET_HashCode *key, const struct GNUNET_CONTAINER_BloomFilter *bloom)
Check whether my identity is closer than any known peers.
const struct GNUNET_PeerIdentity * GNUNET_PILS_get_identity(const struct GNUNET_PILS_Handle *handle)
Return the current peer identity of a given handle.
Definition pils_api.c:875
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...
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
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.
#define GNUNET_malloc(size)
Wrapper around malloc.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition service.c:2434
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition time.c:737
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 PendingPut::bd, 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_pils, GDS_stats, PendingPut::give_up_time, 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_malloc, GNUNET_memcpy, GNUNET_NO, GNUNET_OK, GNUNET_PILS_get_identity(), GNUNET_SERVICE_client_continue(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_ntoh(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_UNIT_SECONDS, GNUNET_DHT_ClientPutMessage::header, GNUNET_DATACACHE_Block::key, GNUNET_DHT_ClientPutMessage::key, LOG, LOG_TRAFFIC, GNUNET_DHT_ClientPutMessage::options, replication_level, PendingPut::replication_level, PendingPut::retry_frequency, GNUNET_DATACACHE_Block::ro, route_pending_put(), GNUNET_MessageHeader::size, size, GNUNET_DATACACHE_Block::type, GNUNET_DHT_ClientPutMessage::type, and UNROUTED_PUT_TIMEOUT.

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

935{
937 "Datacache provided result for query key %s\n",
938 GNUNET_h2s (&bd->key));
940 &bd->key,
941 0, NULL /* get_path */));
942}
@ GNUNET_ERROR_TYPE_INFO

References PendingPut::bd, 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 953 of file gnunet-service-dht_clients.c.

955{
956 (void) cls;
957 (void) get;
958 /* always well-formed */
959 return GNUNET_OK;
960}
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 970 of file gnunet-service-dht_clients.c.

972{
973 struct ClientHandle *ch = cls;
974 struct ClientQueryRecord *cqr;
975 uint16_t size = ntohs (get->header.size);
976 const char *xquery = (const char *) &get[1];
977 size_t xquery_size = size - sizeof(struct GNUNET_DHT_ClientGetMessage);
978
980 "Received GET request for %s from local client %p, xq: %.*s\n",
981 GNUNET_h2s (&get->key),
982 ch->client,
983 (int) xquery_size,
984 xquery);
986 "# GET requests received from clients",
987 1,
988 GNUNET_NO);
990 "CLIENT-GET %s\n",
991 GNUNET_h2s_full (&get->key));
993 {
994 /* GDS_NEIGHBOURS_handle_get() requires our identity. Should not
995 happen -- the service stays suspended until PILS answers -- but
996 drop the request rather than abort. */
997 GNUNET_break (0);
999 "# GET requests dropped (no identity yet)",
1000 1,
1001 GNUNET_NO);
1003 return;
1004 }
1005
1006 cqr = GNUNET_malloc (sizeof(struct ClientQueryRecord) + xquery_size);
1007 cqr->key = get->key;
1008 cqr->ch = ch;
1009 cqr->xquery = (const void *) &cqr[1];
1010 GNUNET_memcpy (&cqr[1],
1011 xquery,
1012 xquery_size);
1014 cqr,
1015 0);
1018 cqr->start_time = cqr->retry_time;
1019 cqr->unique_id = get->unique_id;
1020 cqr->xquery_size = xquery_size;
1021 cqr->replication = ntohl (get->desired_replication_level);
1022 cqr->msg_options = ntohl (get->options);
1023 cqr->type = ntohl (get->type);
1025 ch->cqr_tail,
1026 cqr);
1028 &cqr->key,
1029 cqr,
1032 cqr->type,
1033 0, /* hop count */
1034 cqr->replication,
1035 &get->key);
1036 /* start remote requests */
1037 if (NULL != retry_task)
1040 NULL);
1041 /* perform local lookup */
1043 cqr->type,
1044 cqr->xquery,
1045 xquery_size,
1046 NULL,
1048 ch);
1050}
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.
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.
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_pils, GDS_stats, get, GNUNET_break, 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_PILS_get_identity(), 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, ClientQueryRecord::start_time, 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 1081 of file gnunet-service-dht_clients.c.

1084{
1085 struct FindByUniqueIdContext *fui_ctx = cls;
1086 struct ClientQueryRecord *cqr = value;
1087
1088 if (cqr->unique_id != fui_ctx->unique_id)
1089 return GNUNET_YES;
1090 fui_ctx->cqr = cqr;
1091 return GNUNET_NO;
1092}
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 1103 of file gnunet-service-dht_clients.c.

1106{
1107 uint16_t size = ntohs (seen->header.size);
1108 unsigned int hash_count =
1109 (size - sizeof(*seen))
1110 / sizeof(struct GNUNET_HashCode);
1111
1112 if (size != sizeof(*seen) + hash_count * sizeof(struct GNUNET_HashCode))
1113 {
1114 GNUNET_break (0);
1115 return GNUNET_SYSERR;
1116 }
1117 return GNUNET_OK;
1118}
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 1128 of file gnunet-service-dht_clients.c.

1131{
1132 struct ClientHandle *ch = cls;
1133 uint16_t size = ntohs (seen->header.size);
1134 unsigned int hash_count = (size - sizeof(*seen))
1135 / sizeof(struct GNUNET_HashCode);
1136 const struct GNUNET_HashCode *hc = (const struct GNUNET_HashCode*) &seen[1];
1137 struct FindByUniqueIdContext fui_ctx = {
1138 .unique_id = seen->unique_id
1139 };
1140 unsigned int old_count;
1141 struct ClientQueryRecord *cqr;
1142
1144 &seen->key,
1146 &fui_ctx);
1147 if (NULL == (cqr = fui_ctx.cqr))
1148 {
1149 GNUNET_break (0);
1151 return;
1152 }
1153 /* finally, update 'seen' list */
1154 old_count = cqr->seen_replies_count;
1156 cqr->seen_replies_count,
1157 cqr->seen_replies_count + hash_count);
1158 GNUNET_memcpy (&cqr->seen_replies[old_count],
1159 hc,
1160 sizeof(struct GNUNET_HashCode) * hash_count);
1162}
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:2463
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_continue(), 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 1192 of file gnunet-service-dht_clients.c.

1195{
1196 const struct RemoveByUniqueIdContext *ctx = cls;
1197 struct ClientQueryRecord *cqr = value;
1198
1199 if (cqr->unique_id != ctx->unique_id)
1200 return GNUNET_YES;
1202 "Removing client %p's record for key %s (by unique id)\n",
1203 ctx->ch->client,
1204 GNUNET_h2s (key));
1206 return GNUNET_YES;
1207}
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 1219 of file gnunet-service-dht_clients.c.

1222{
1223 struct ClientHandle *ch = cls;
1225
1227 "# GET STOP requests received from clients",
1228 1,
1229 GNUNET_NO);
1231 "Received GET STOP request for %s from local client %p\n",
1232 GNUNET_h2s (&dht_stop_msg->key),
1233 ch->client);
1234 ctx.ch = ch;
1235 ctx.unique_id = dht_stop_msg->unique_id;
1237 &dht_stop_msg->key,
1239 &ctx);
1241}
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 1279 of file gnunet-service-dht_clients.c.

1282{
1283 struct ForwardReplyContext *frc = cls;
1284 struct ClientQueryRecord *record = value;
1285 const struct GNUNET_DATACACHE_Block *bd = frc->bd;
1286 struct GNUNET_MQ_Envelope *env;
1287 struct GNUNET_DHT_ClientResultMessage *reply;
1289 bool do_free;
1290 struct GNUNET_HashCode ch;
1291 struct GNUNET_DHT_PathElement *paths;
1292 bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
1293 size_t xsize = bd->data_size;
1294
1296 "CLIENT-RESULT %s\n",
1297 GNUNET_h2s_full (&bd->key));
1298 if ( (record->type != GNUNET_BLOCK_TYPE_ANY) &&
1299 (record->type != bd->type) )
1300 {
1302 "Record type mismatch, not passing request for key %s to local client\n",
1303 GNUNET_h2s (&bd->key));
1305 "# Key match, type mismatches in REPLY to CLIENT",
1306 1,
1307 GNUNET_NO);
1308 return GNUNET_YES; /* type mismatch */
1309 }
1310 if ( (0 == (record->msg_options & GNUNET_DHT_RO_FIND_APPROXIMATE)) &&
1311 (0 != GNUNET_memcmp (&bd->key,
1312 query_hash)) )
1313 {
1315 "# Inexact key match, but exact match required",
1316 1,
1317 GNUNET_NO);
1318 return GNUNET_YES; /* type mismatch */
1319 }
1321 bd->data_size,
1322 &ch);
1323 for (unsigned int i = 0; i < record->seen_replies_count; i++)
1324 if (0 ==
1325 GNUNET_memcmp (&record->seen_replies[i],
1326 &ch))
1327 {
1329 "Duplicate reply, not passing request for key %s to local client\n",
1330 GNUNET_h2s (&bd->key));
1332 "# Duplicate REPLIES to CLIENT request dropped",
1333 1,
1334 GNUNET_NO);
1335 return GNUNET_YES; /* duplicate */
1336 }
1337 eval
1339 record->type,
1340 NULL,
1341 &bd->key,
1342 record->xquery,
1343 record->xquery_size,
1344 bd->data,
1345 bd->data_size);
1347 "Evaluation result is %d for key %s for local client's query\n",
1348 (int) eval,
1349 GNUNET_h2s (&bd->key));
1350 switch (eval)
1351 {
1353 do_free = true;
1354 break;
1357 GNUNET_array_append (record->seen_replies,
1358 record->seen_replies_count,
1359 ch);
1360 do_free = false;
1361 break;
1363 /* should be impossible to encounter here */
1364 GNUNET_break (0);
1365 return GNUNET_YES;
1367 return GNUNET_YES;
1368 default:
1369 GNUNET_break (0);
1370 return GNUNET_NO;
1371 }
1373 "# RESULTS queued for clients",
1374 1,
1375 GNUNET_NO);
1376 xsize += (frc->get_path_length + bd->put_path_length)
1377 * sizeof(struct GNUNET_DHT_PathElement);
1378 if (truncated)
1379 xsize += sizeof (struct GNUNET_PeerIdentity);
1380
1381#if SUPER_REDUNDANT_CHECK
1382 {
1383 const struct GNUNET_PeerIdentity *my_identity;
1385 GNUNET_assert (NULL != my_identity);
1386 GNUNET_break (0 ==
1388 bd->data_size,
1389 bd->expiration_time,
1390 truncated
1391 ? &bd->trunc_peer
1392 : NULL,
1393 bd->put_path,
1394 bd->put_path_length,
1395 frc->get_path,
1396 frc->get_path_length,
1397 my_identity));
1398 }
1399#endif
1400
1401 env = GNUNET_MQ_msg_extra (reply,
1402 xsize,
1404 reply->type = htonl (bd->type);
1405 reply->options = htonl (bd->ro);
1406 reply->get_path_length = htonl (frc->get_path_length);
1407 reply->put_path_length = htonl (bd->put_path_length);
1408 reply->unique_id = record->unique_id;
1410 reply->key = *query_hash;
1411 if (truncated)
1412 {
1413 void *tgt = &reply[1];
1414
1415 GNUNET_memcpy (tgt,
1416 &bd->trunc_peer,
1417 sizeof (struct GNUNET_PeerIdentity));
1418 paths = (struct GNUNET_DHT_PathElement *)
1419 (tgt + sizeof (struct GNUNET_PeerIdentity));
1420 }
1421 else
1422 {
1423 paths = (struct GNUNET_DHT_PathElement *) &reply[1];
1424 }
1425 GNUNET_memcpy (paths,
1426 bd->put_path,
1427 sizeof(struct GNUNET_DHT_PathElement)
1428 * bd->put_path_length);
1429 GNUNET_memcpy (&paths[bd->put_path_length],
1430 frc->get_path,
1431 sizeof(struct GNUNET_DHT_PathElement)
1432 * frc->get_path_length);
1433 GNUNET_memcpy (&paths[frc->get_path_length + bd->put_path_length],
1434 bd->data,
1435 bd->data_size);
1437 "Sending reply to query %s for client %p\n",
1438 GNUNET_h2s (query_hash),
1439 record->ch->client);
1440 GNUNET_MQ_send (record->ch->mq,
1441 env);
1442 if (GNUNET_YES == do_free)
1444 return GNUNET_YES;
1445}
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
static struct GNUNET_PeerIdentity 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:1354
@ 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:40
#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:337
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
#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:636
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.
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_pils, GDS_stats, ForwardReplyContext::get_path, GNUNET_DHT_ClientResultMessage::get_path_length, ForwardReplyContext::get_path_length, GNUNET_array_append, GNUNET_assert, 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_PILS_get_identity(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_hton(), GNUNET_YES, GNUNET_DATACACHE_Block::key, GNUNET_DHT_ClientResultMessage::key, LOG, LOG_TRAFFIC, my_identity, 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 1449 of file gnunet-service-dht_clients.c.

1453{
1454 struct ForwardReplyContext frc;
1455 size_t msize = sizeof (struct GNUNET_DHT_ClientResultMessage)
1456 + bd->data_size
1458 * sizeof(struct GNUNET_DHT_PathElement);
1459#if SANITY_CHECKS > 1
1460 bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
1461#endif
1462
1463 if (msize >= GNUNET_MAX_MESSAGE_SIZE)
1464 {
1465 GNUNET_break (0);
1466 return false;
1467 }
1468#if SANITY_CHECKS > 1
1469 {
1470 const struct GNUNET_PeerIdentity *my_identity;
1472 GNUNET_assert (NULL != my_identity);
1473 if (0 !=
1475 bd->data_size,
1476 bd->expiration_time,
1477 truncated
1478 ? &bd->trunc_peer
1479 : NULL,
1480 bd->put_path,
1481 bd->put_path_length,
1482 get_path,
1483 get_path_length,
1484 my_identity))
1485 {
1486 GNUNET_break (0);
1487 return false;
1488 }
1489 }
1490#endif
1491 frc.bd = bd;
1492 frc.get_path = get_path;
1493 frc.get_path_length = get_path_length;
1495 "Forwarding reply for query hash %s with GPL %u and PPL %u to client\n",
1496 GNUNET_h2s (query_hash),
1497 get_path_length,
1498 bd->put_path_length);
1499 if (0 ==
1501 query_hash,
1503 &frc))
1504 {
1506 "No matching client for reply for query %s\n",
1507 GNUNET_h2s (query_hash));
1509 "# REPLIES ignored for CLIENTS (no match)",
1510 1,
1511 GNUNET_NO);
1512 }
1513 return true;
1514}
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_pils, GDS_stats, ForwardReplyContext::get_path, GNUNET_DHT_ClientResultMessage::get_path_length, ForwardReplyContext::get_path_length, GNUNET_assert, 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_PILS_get_identity(), GNUNET_STATISTICS_update(), LOG, my_identity, 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 1529 of file gnunet-service-dht_clients.c.

1531{
1532 struct ClientHandle *ch = cls;
1533 const struct GNUNET_PeerIdentity *my_identity;
1534 struct GNUNET_HELLO_Parser *p;
1535 struct GNUNET_MessageHeader *hdr;
1536 struct GNUNET_MQ_Envelope *env;
1537
1539
1540 if (NULL != GDS_my_hello)
1542 else
1543 p = NULL;
1544
1546 "Handling request from local client for my HELLO\n");
1547
1548 if (NULL != p)
1549 {
1550 char *url;
1551 size_t slen;
1552
1554 slen = strlen (url) + 1;
1555
1556 env = GNUNET_MQ_msg_extra (hdr,
1557 slen,
1559 memcpy (&hdr[1],
1560 url,
1561 slen);
1562 GNUNET_free (url);
1564 }
1565 else
1566 {
1568 ;
1569 }
1570
1572 env);
1574}
struct GNUNET_MessageHeader * GDS_my_hello
Our HELLO.
static struct GNUNET_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:380
char * GNUNET_HELLO_parser_to_url(const struct GNUNET_HELLO_Parser *parser)
Generate GNUnet HELLO URI from a parser.
Definition hello-uri.c:880
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_msg(const struct GNUNET_MessageHeader *msg, const struct GNUNET_PeerIdentity *pid)
Parse msg.
Definition hello-uri.c:416
#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:233
Header for all communications.

References ch, env, GDS_my_hello, GDS_pils, 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_PILS_get_identity(), GNUNET_SERVICE_client_continue(), GNUNET_CADET_Channel::mq, my_identity, 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 1585 of file gnunet-service-dht_clients.c.

1587{
1588 uint16_t len = ntohs (hdr->size);
1589 const char *buf = (const char *) &hdr[1];
1590
1591 (void) cls;
1592 if ('\0' != buf[len - sizeof (*hdr) - 1])
1593 {
1594 GNUNET_break (0);
1595 return GNUNET_SYSERR;
1596 }
1597 return GNUNET_OK;
1598}

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

1611{
1612 struct ClientHandle *ch = cls;
1613 const char *url = (const char *) &msg[1];
1614 struct GNUNET_HELLO_Parser *b;
1615
1617 "Local client provided HELLO URL %s\n",
1618 url);
1620 if (NULL == b)
1621 {
1622 GNUNET_break (0);
1624 return;
1625 }
1629 NULL);
1631}
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:1052
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_url(const char *url)
Parse GNUnet HELLO url.
Definition hello-uri.c:740

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

1647{
1648 struct ClientHandle *ch = cls;
1649 struct ClientMonitorRecord *r;
1650
1651 r = GNUNET_new (struct ClientMonitorRecord);
1652 r->ch = ch;
1653 r->type = ntohl (msg->type);
1654 r->get = ntohs (msg->get);
1655 r->get_resp = ntohs (msg->get_resp);
1656 r->put = ntohs (msg->put);
1657 if (0 != ntohs (msg->filter_key))
1658 r->key = msg->key;
1661 r);
1663}
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 1673 of file gnunet-service-dht_clients.c.

1676{
1677 struct ClientHandle *ch = cls;
1678
1680 for (struct ClientMonitorRecord *r = monitor_head;
1681 NULL != r;
1682 r = r->next)
1683 {
1684 bool keys_match;
1685
1686 keys_match =
1687 (GNUNET_is_zero (&r->key))
1688 ? (0 == ntohs (msg->filter_key))
1689 : ( (0 != ntohs (msg->filter_key)) &&
1690 (! GNUNET_memcmp (&r->key,
1691 &msg->key)) );
1692 if ( (ch == r->ch) &&
1693 (ntohl (msg->type) == r->type) &&
1694 (r->get == msg->get) &&
1695 (r->get_resp == msg->get_resp) &&
1696 (r->put == msg->put) &&
1697 keys_match)
1698 {
1701 r);
1702 GNUNET_free (r);
1703 return; /* Delete only ONE entry */
1704 }
1705 }
1706}
#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 1730 of file gnunet-service-dht_clients.c.

1734{
1735 struct ClientHandle **cl = NULL;
1736 unsigned int cl_size = 0;
1737
1738 for (struct ClientMonitorRecord *m = monitor_head;
1739 NULL != m;
1740 m = m->next)
1741 {
1742 bool found = false;
1743
1744 if ( (GNUNET_BLOCK_TYPE_ANY != m->type) &&
1745 (m->type != type) )
1746 continue;
1747 if ( (! GNUNET_is_zero (&m->key)) &&
1748 (0 ==
1750 &m->key)) )
1751 continue;
1752 /* Don't send duplicates */
1753 for (unsigned i = 0; i < cl_size; i++)
1754 if (cl[i] == m->ch)
1755 {
1756 found = true;
1757 break;
1758 }
1759 if (found)
1760 continue;
1762 cl_size,
1763 m->ch);
1764 cb (cb_cls,
1765 m);
1766 }
1767 GNUNET_free (cl);
1768}
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 1793 of file gnunet-service-dht_clients.c.

1795{
1796 struct GetActionContext *gac = cls;
1797 struct GNUNET_MQ_Envelope *env;
1798 struct GNUNET_DHT_MonitorGetMessage *mmsg;
1799
1800 env = GNUNET_MQ_msg (mmsg,
1802 mmsg->options = htonl (gac->options);
1803 mmsg->type = htonl (gac->type);
1804 mmsg->hop_count = htonl (gac->hop_count);
1806 mmsg->key = *gac->key;
1807 GNUNET_MQ_send (m->ch->mq,
1808 env);
1809}
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
#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 1813 of file gnunet-service-dht_clients.c.

1818{
1819 struct GetActionContext gac = {
1820 .options = options,
1821 .type = type,
1822 .hop_count = hop_count,
1823 .desired_replication_level = desired_replication_level,
1824 .key = key
1825 };
1826
1828 key,
1829 &get_action,
1830 &gac);
1831}
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 cb_handle_dht_p2p_get_local_result(), and handle_dht_local_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 1853 of file gnunet-service-dht_clients.c.

1855{
1856 const struct ResponseActionContext *resp_ctx = cls;
1857 const struct GNUNET_DATACACHE_Block *bd = resp_ctx->bd;
1858 bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
1859 struct GNUNET_MQ_Envelope *env;
1861 struct GNUNET_DHT_PathElement *path;
1862 size_t msize;
1863
1864 msize = bd->data_size;
1865 msize += (resp_ctx->get_path_length + bd->put_path_length)
1866 * sizeof(struct GNUNET_DHT_PathElement);
1867 if (truncated)
1868 msize += sizeof (struct GNUNET_PeerIdentity);
1869 env = GNUNET_MQ_msg_extra (mmsg,
1870 msize,
1872 mmsg->type = htonl (bd->type);
1873 mmsg->put_path_length = htonl (bd->put_path_length);
1874 mmsg->get_path_length = htonl (resp_ctx->get_path_length);
1876 mmsg->key = bd->key;
1877 if (truncated)
1878 {
1879 void *tgt = &mmsg[1];
1880
1881 GNUNET_memcpy (tgt,
1882 &bd->trunc_peer,
1883 sizeof (struct GNUNET_PeerIdentity));
1884 path = (struct GNUNET_DHT_PathElement *)
1885 (tgt + sizeof (struct GNUNET_PeerIdentity));
1886 }
1887 else
1888 {
1889 path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
1890 }
1891 GNUNET_memcpy (path,
1892 bd->put_path,
1893 bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement));
1894 GNUNET_memcpy (path,
1895 resp_ctx->get_path,
1896 resp_ctx->get_path_length
1897 * sizeof(struct GNUNET_DHT_PathElement));
1898 GNUNET_memcpy (&path[resp_ctx->get_path_length],
1899 bd->data,
1900 bd->data_size);
1901 GNUNET_MQ_send (m->ch->mq,
1902 env);
1903}
#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 1907 of file gnunet-service-dht_clients.c.

1910{
1911 struct ResponseActionContext rac = {
1912 .bd = bd,
1913 .get_path = get_path,
1914 .get_path_length = get_path_length
1915 };
1916
1918 &bd->key,
1920 &rac);
1921}
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 1943 of file gnunet-service-dht_clients.c.

1945{
1946 const struct PutActionContext *put_ctx = cls;
1947 const struct GNUNET_DATACACHE_Block *bd = put_ctx->bd;
1948 bool truncated = (0 != (bd->ro & GNUNET_DHT_RO_TRUNCATED));
1949 struct GNUNET_MQ_Envelope *env;
1950 struct GNUNET_DHT_MonitorPutMessage *mmsg;
1951 struct GNUNET_DHT_PathElement *msg_path;
1952 size_t msize;
1953
1954 msize = bd->data_size
1955 + bd->put_path_length
1956 * sizeof(struct GNUNET_DHT_PathElement);
1957 if (truncated)
1958 msize += sizeof (struct GNUNET_PeerIdentity);
1959 env = GNUNET_MQ_msg_extra (mmsg,
1960 msize,
1962 mmsg->options = htonl (bd->ro);
1963 mmsg->type = htonl (bd->type);
1964 mmsg->hop_count = htonl (put_ctx->hop_count);
1966 mmsg->put_path_length = htonl (bd->put_path_length);
1967 mmsg->key = bd->key;
1969 if (truncated)
1970 {
1971 void *tgt = &mmsg[1];
1972
1973 GNUNET_memcpy (tgt,
1974 &bd->trunc_peer,
1975 sizeof (struct GNUNET_PeerIdentity));
1976 msg_path = (struct GNUNET_DHT_PathElement *)
1977 (tgt + sizeof (struct GNUNET_PeerIdentity));
1978 }
1979 else
1980 {
1981 msg_path = (struct GNUNET_DHT_PathElement *) &mmsg[1];
1982 }
1983 GNUNET_memcpy (msg_path,
1984 bd->put_path,
1985 bd->put_path_length * sizeof(struct GNUNET_DHT_PathElement));
1986 GNUNET_memcpy (&msg_path[bd->put_path_length],
1987 bd->data,
1988 bd->data_size);
1989 GNUNET_MQ_send (m->ch->mq,
1990 env);
1991}
#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 1995 of file gnunet-service-dht_clients.c.

1998{
1999 struct PutActionContext put_ctx = {
2000 .bd = bd,
2001 .hop_count = hop_count,
2002 .desired_replication_level = desired_replication_level
2003 };
2004
2006 &bd->key,
2007 &put_action,
2008 &put_ctx);
2009}
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 cb_forwarded_dht_p2p_put(), and handle_dht_local_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 2019 of file gnunet-service-dht_clients.c.

2020{
2023 GNUNET_YES);
2026}
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 2033 of file gnunet-service-dht_clients.c.

2034{
2035 struct PendingPut *pp;
2036
2037 if (NULL != retry_task)
2038 {
2040 retry_task = NULL;
2041 }
2042 if (NULL != put_retry_task)
2043 {
2045 put_retry_task = NULL;
2046 }
2047 while (NULL != (pp = pp_head))
2048 {
2050 pp_tail,
2051 pp);
2052 pp_count--;
2053 GNUNET_free (pp);
2054 }
2055}

References GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_SCHEDULER_cancel(), pp_count, pp_head, pp_tail, put_retry_task, 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 2112 of file gnunet-service-dht_clients.c.

2114{
2115 if (NULL != retry_heap)
2116 {
2119 retry_heap = NULL;
2120 }
2121 if (NULL != forward_map)
2122 {
2125 forward_map = NULL;
2126 }
2127}
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

◆ GDS_service

struct GNUNET_SERVICE_Handle* GDS_service

Handle for the service.

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

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

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

◆ monitor_head

struct ClientMonitorRecord* monitor_head
static

List of active monitoring requests.

Definition at line 295 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 300 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 310 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 315 of file gnunet-service-dht_clients.c.

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

◆ pp_head

struct PendingPut* pp_head
static

Head of the list of PUTs waiting for a usable routing table.

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

Referenced by cb_forwarded_dht_local_put(), GDS_CLIENTS_retry_puts(), GDS_CLIENTS_stop(), and put_retry_task_cb().

◆ pp_tail

struct PendingPut* pp_tail
static

Tail of the list of PUTs waiting for a usable routing table.

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

Referenced by cb_forwarded_dht_local_put(), GDS_CLIENTS_stop(), and put_retry_task_cb().

◆ pp_count

unsigned int pp_count
static

Number of entries in the pp_head DLL.

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

Referenced by cb_forwarded_dht_local_put(), GDS_CLIENTS_retry_puts(), GDS_CLIENTS_stop(), and put_retry_task_cb().

◆ put_retry_task

struct GNUNET_SCHEDULER_Task* put_retry_task
static

Task that re-tries the PUTs in the pp_head DLL.

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

Referenced by GDS_CLIENTS_stop(), put_retry_task_cb(), and schedule_put_retry().