GNUnet 0.28.1-dev.4-8-g14b9efcb0
 
Loading...
Searching...
No Matches
peerstore_api.c File Reference

API for peerstore. More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_protocols.h"
#include "gnunet_hello_uri_lib.h"
#include "peerstore.h"
#include "peerstore_common.h"
#include "gnunet_peerstore_service.h"
Include dependency graph for peerstore_api.c:

Go to the source code of this file.

Data Structures

struct  GNUNET_PEERSTORE_Handle
 Handle to the PEERSTORE service. More...
 
struct  GNUNET_PEERSTORE_StoreHelloContext
 Context for a add hello uri request. More...
 
struct  GNUNET_PEERSTORE_StoreContext
 Context for a store request. More...
 
struct  StoreHelloCls
 Closure for store callback when storing hello uris. More...
 
struct  GNUNET_PEERSTORE_IterateContext
 Context for a iterate request. More...
 
struct  GNUNET_PEERSTORE_NotifyContext
 Context for the info handler. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "peerstore-api", __VA_ARGS__)
 

Functions

static void reconnect (void *cls)
 Close the existing connection to PEERSTORE and reconnect.
 
static uint32_t get_op_id (struct GNUNET_PEERSTORE_Handle *h)
 Get a fresh operation id to distinguish between namestore requests.
 
static void flush_pending_operations (struct GNUNET_PEERSTORE_Handle *h, int notify)
 Terminate every operation still pending on h.
 
static void disconnect (struct GNUNET_PEERSTORE_Handle *h)
 Disconnect from the peerstore service.
 
static void disconnect_and_schedule_reconnect (struct GNUNET_PEERSTORE_Handle *h)
 Function that will schedule the job that will try to connect us again to the client.
 
static void handle_client_error (void *cls, enum GNUNET_MQ_Error error)
 Function called when we had trouble talking to the service.
 
struct GNUNET_PEERSTORE_HandleGNUNET_PEERSTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
 Connect to the PEERSTORE service.
 
void GNUNET_PEERSTORE_disconnect (struct GNUNET_PEERSTORE_Handle *h)
 Disconnect from the PEERSTORE service.
 
static void destroy_storecontext (struct GNUNET_PEERSTORE_StoreContext *sc)
 
void GNUNET_PEERSTORE_store_cancel (struct GNUNET_PEERSTORE_StoreContext *sc)
 Cancel a store request.
 
struct GNUNET_PEERSTORE_StoreContextGNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, const void *value, size_t size, struct GNUNET_TIME_Absolute expiry, enum GNUNET_PEERSTORE_StoreOption options, GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
 Store a new entry in the PEERSTORE.
 
static void handle_store_result (void *cls, const struct PeerstoreResultMessage *msg)
 When a response for store request is received.
 
static void destroy_iteratecontext (struct GNUNET_PEERSTORE_IterateContext *ic)
 
static void handle_iterate_end (void *cls, const struct PeerstoreResultMessage *msg)
 When a response for iterate request is received.
 
static int check_iterate_result (void *cls, const struct PeerstoreRecordMessage *msg)
 When a response for iterate request is received, check the message is well-formed.
 
static void handle_iterate_result (void *cls, const struct PeerstoreRecordMessage *msg)
 When a response for iterate request is received.
 
void GNUNET_PEERSTORE_iteration_next (struct GNUNET_PEERSTORE_IterateContext *ic, uint64_t limit)
 Cancel an iterate request Please do not call after the iterate request is done.
 
void GNUNET_PEERSTORE_iteration_stop (struct GNUNET_PEERSTORE_IterateContext *ic)
 Cancel an iterate request Please do not call after the iterate request is done.
 
struct GNUNET_PEERSTORE_IterateContextGNUNET_PEERSTORE_iteration_start (struct GNUNET_PEERSTORE_Handle *h, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, GNUNET_PEERSTORE_Processor callback, void *callback_cls)
 Iterate over peerstore entries.
 
static void hello_store_success (void *cls, int success)
 
static void hello_add_iter (void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
 
struct GNUNET_PEERSTORE_StoreHelloContextGNUNET_PEERSTORE_hello_add (struct GNUNET_PEERSTORE_Handle *h, const struct GNUNET_MessageHeader *msg, GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
 Add hello to peerstore.
 
void GNUNET_PEERSTORE_hello_add_cancel (struct GNUNET_PEERSTORE_StoreHelloContext *huc)
 Cancel the request to add a hello.
 

Detailed Description

API for peerstore.

Author
Omar Tarabai
Christian Grothoff
Martin Schanzenbach

Definition in file peerstore_api.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "peerstore-api", __VA_ARGS__)

Definition at line 34 of file peerstore_api.c.

Function Documentation

◆ reconnect()

static void reconnect ( void *  cls)
static

Close the existing connection to PEERSTORE and reconnect.

Parameters
clsa struct GNUNET_PEERSTORE_Handle *h
clsa struct GNUNET_PEERSTORE_Handle *

Definition at line 915 of file peerstore_api.c.

916{
917 struct GNUNET_PEERSTORE_Handle *h = cls;
918 struct GNUNET_MQ_MessageHandler mq_handlers[] = {
919 GNUNET_MQ_hd_fixed_size (iterate_end,
922 h),
923 GNUNET_MQ_hd_fixed_size (store_result,
926 h),
927 GNUNET_MQ_hd_var_size (iterate_result,
930 h),
932 };
933
934 h->reconnect_task = NULL;
935 LOG (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting...\n");
937 "peerstore",
938 mq_handlers,
940 h);
941 if (NULL == h->mq)
942 {
944 GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect, h);
945 h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay);
946 return;
947 }
949 "Resending pending requests after reconnect.\n");
950 /* Only requests that were created while we had no MQ carry a stashed
951 envelope; everything else was handed to the MQ directly and no longer
952 exists. Sending NULL dereferences it, and sending the same envelope
953 twice (a second reconnect) uses it after the MQ freed it -- so take
954 each envelope exactly once. */
955 for (struct GNUNET_PEERSTORE_IterateContext *ic = h->iterate_head; NULL != ic;
956 ic = ic->next)
957 {
958 struct GNUNET_MQ_Envelope *env = ic->env;
959
960 if (NULL == env)
961 continue;
962 ic->env = NULL;
964 }
965 for (struct GNUNET_PEERSTORE_StoreContext *sc = h->store_head; NULL != sc;
966 sc = sc->next)
967 {
968 struct GNUNET_MQ_Envelope *env = sc->env;
969
970 if (NULL == env)
971 continue;
972 sc->env = NULL;
974 }
975}
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition gnunet-arm.c:98
static struct GNUNET_FS_SearchContext * sc
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition client.c:1060
@ GNUNET_ERROR_TYPE_DEBUG
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_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
#define GNUNET_MESSAGE_TYPE_PEERSTORE_RECORD
Record result message.
#define GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_END
Iteration end message.
#define GNUNET_MESSAGE_TYPE_PEERSTORE_STORE_RESULT
Store result message.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1283
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
static void handle_client_error(void *cls, enum GNUNET_MQ_Error error)
Function called when we had trouble talking to the service.
#define LOG(kind,...)
static void reconnect(void)
Adjust exponential back-off and reconnect to the service.
struct GNUNET_MQ_Handle * mq
Our connection to the ARM service.
Definition arm_api.c:107
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration that we are using.
Definition arm_api.c:112
struct GNUNET_SCHEDULER_Task * reconnect_task
ID of the reconnect task (if any).
Definition arm_api.c:147
Message handler for a specific message type.
Handle to the PEERSTORE service.
Context for a iterate request.
Context for a store request.
Message carrying a PEERSTORE record message.
Definition peerstore.h:38
Message carrying a PEERSTORE result message.
Definition peerstore.h:96

References GNUNET_ARM_Handle::cfg, env, GNUNET_CLIENT_connect(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_END, GNUNET_MESSAGE_TYPE_PEERSTORE_RECORD, GNUNET_MESSAGE_TYPE_PEERSTORE_STORE_RESULT, GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_MQ_hd_var_size, GNUNET_MQ_send(), GNUNET_SCHEDULER_add_delayed(), GNUNET_TIME_STD_BACKOFF, h, handle_client_error(), LOG, GNUNET_ARM_Handle::mq, reconnect(), GNUNET_ARM_Handle::reconnect_task, and sc.

Here is the call graph for this function:

◆ get_op_id()

static uint32_t get_op_id ( struct GNUNET_PEERSTORE_Handle h)
static

Get a fresh operation id to distinguish between namestore requests.

Parameters
hthe namestore handle
Returns
next operation id to use

Definition at line 343 of file peerstore_api.c.

344{
345 return h->last_op_id++;
346}

References h.

Referenced by GNUNET_PEERSTORE_iteration_start(), and GNUNET_PEERSTORE_store().

Here is the caller graph for this function:

◆ flush_pending_operations()

static void flush_pending_operations ( struct GNUNET_PEERSTORE_Handle h,
int  notify 
)
static

Terminate every operation still pending on h.

The service tracks operations by request id on a per-connection basis, so once the connection is gone nothing can be resumed: an operation that is merely dropped leaves its caller waiting for a callback that can never arrive. disconnect() asserts that both lists are empty, which is what this establishes.

Parameters
hhandle whose operations to terminate
notifyGNUNET_YES to report the outcome to each waiter (we lost the connection), GNUNET_NO to release them silently (our caller is going away and its closures may be gone already)

Definition at line 364 of file peerstore_api.c.

365{
368
369 /* Splice both lists out before running a single callback: a callback may
370 legitimately start a new operation -- #hello_add_iter() does -- and that
371 one has to survive to be replayed by #reconnect() rather than be flushed
372 by the loop we are still inside. */
373 ic = h->iterate_head;
374 h->iterate_head = NULL;
375 h->iterate_tail = NULL;
376 sc = h->store_head;
377 h->store_head = NULL;
378 h->store_tail = NULL;
379
380 while (NULL != ic)
381 {
383
384 /* A NULL record is the end-of-iteration signal every caller already
385 handles by clearing its handle; that is exactly what we need here,
386 and unlike an @a emsg it is understood by all of them. */
387 if ((GNUNET_YES == notify) && (NULL != ic->callback))
388 ic->callback (ic->callback_cls, NULL, NULL);
389 if (NULL != ic->env)
392 GNUNET_free (ic->key);
393 GNUNET_free (ic);
394 ic = next;
395 }
396 while (NULL != sc)
397 {
398 struct GNUNET_PEERSTORE_StoreContext *next = sc->next;
399
400 if ((GNUNET_YES == notify) && (NULL != sc->cont))
401 sc->cont (sc->cont_cls, GNUNET_SYSERR);
402 if (NULL != sc->env)
403 GNUNET_MQ_discard (sc->env);
404 GNUNET_free (sc->sub_system);
405 GNUNET_free (sc->value);
406 GNUNET_free (sc->key);
407 GNUNET_free (sc);
408 sc = next;
409 }
410}
@ GNUNET_YES
@ GNUNET_SYSERR
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition mq.c:317
char * sub_system
Which subsystem does the store?
void * callback_cls
Closure for callback.
char * key
Key for the store operation.
GNUNET_PEERSTORE_Processor callback
Callback with each matching record.
struct GNUNET_MQ_Envelope * env
Temporary envelope.
struct GNUNET_PEERSTORE_IterateContext * next
Kept in a DLL.
struct GNUNET_PEERSTORE_StoreContext * next
Kept in a DLL.

References GNUNET_PEERSTORE_IterateContext::callback, GNUNET_PEERSTORE_IterateContext::callback_cls, GNUNET_PEERSTORE_IterateContext::env, GNUNET_free, GNUNET_MQ_discard(), GNUNET_SYSERR, GNUNET_YES, h, GNUNET_PEERSTORE_IterateContext::key, GNUNET_PEERSTORE_StoreContext::next, GNUNET_PEERSTORE_IterateContext::next, sc, and GNUNET_PEERSTORE_IterateContext::sub_system.

Referenced by disconnect_and_schedule_reconnect(), and GNUNET_PEERSTORE_disconnect().

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

◆ disconnect()

static void disconnect ( struct GNUNET_PEERSTORE_Handle h)
static

Disconnect from the peerstore service.

Parameters
hpeerstore handle to disconnect

Definition at line 419 of file peerstore_api.c.

420{
421 if (NULL != h->watches)
422 {
425 }
426 GNUNET_assert (NULL == h->iterate_head);
427 GNUNET_assert (NULL == h->store_head);
428 if (NULL != h->mq)
429 {
431 h->mq = NULL;
432 }
433}
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition mq.c:732

References GNUNET_assert, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_MQ_destroy(), h, and GNUNET_ARM_Handle::mq.

Referenced by disconnect_and_schedule_reconnect(), and GNUNET_PEERSTORE_disconnect().

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

◆ disconnect_and_schedule_reconnect()

static void disconnect_and_schedule_reconnect ( struct GNUNET_PEERSTORE_Handle h)
static

Function that will schedule the job that will try to connect us again to the client.

Parameters
hpeerstore to reconnect

Definition at line 443 of file peerstore_api.c.

444{
445 GNUNET_assert (NULL == h->reconnect_task);
446 /* Tear the MQ down first: a callback in #flush_pending_operations() may
447 start a new operation, and with no MQ that operation stashes its
448 envelope for #reconnect() to send instead of handing it to a queue we
449 are about to destroy. */
450 if (NULL != h->mq)
451 {
453 h->mq = NULL;
454 }
455 /* Without this, #disconnect() below aborts the whole process the moment
456 PEERSTORE hiccups while anything at all is in flight. */
458 disconnect (h);
460 "Scheduling task to reconnect to PEERSTORE service in %s.\n",
463 GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect, h);
464 h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay);
465}
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition strings.c:610
static void flush_pending_operations(struct GNUNET_PEERSTORE_Handle *h, int notify)
Terminate every operation still pending on h.
static void disconnect(struct GNUNET_PEERSTORE_Handle *h)
Disconnect from the peerstore service.

References disconnect(), flush_pending_operations(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_MQ_destroy(), GNUNET_SCHEDULER_add_delayed(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_STD_BACKOFF, GNUNET_YES, h, LOG, GNUNET_ARM_Handle::mq, reconnect(), and GNUNET_ARM_Handle::reconnect_task.

Referenced by handle_client_error().

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

◆ handle_client_error()

static void handle_client_error ( void *  cls,
enum GNUNET_MQ_Error  error 
)
static

Function called when we had trouble talking to the service.

Definition at line 477 of file peerstore_api.c.

478{
479 struct GNUNET_PEERSTORE_Handle *h = cls;
480
482 "Received an error notification from MQ of type: %d\n",
483 error);
485}
@ GNUNET_ERROR_TYPE_ERROR
static void disconnect_and_schedule_reconnect(struct GNUNET_PEERSTORE_Handle *h)
Function that will schedule the job that will try to connect us again to the client.

References disconnect_and_schedule_reconnect(), GNUNET_ERROR_TYPE_ERROR, h, and LOG.

Referenced by reconnect().

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

◆ destroy_storecontext()

static void destroy_storecontext ( struct GNUNET_PEERSTORE_StoreContext sc)
static

Definition at line 551 of file peerstore_api.c.

552{
553 GNUNET_CONTAINER_DLL_remove (sc->h->store_head, sc->h->store_tail, sc);
554 GNUNET_free (sc->sub_system);
555 GNUNET_free (sc->value);
556 GNUNET_free (sc->key);
557 GNUNET_free (sc);
558}
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct GNUNET_FS_Handle * h
Handle to the global FS context.
Definition fs_api.h:1528

References GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_FS_SearchContext::h, and sc.

Referenced by GNUNET_PEERSTORE_store_cancel(), and handle_store_result().

Here is the caller graph for this function:

◆ handle_store_result()

static void handle_store_result ( void *  cls,
const struct PeerstoreResultMessage msg 
)
static

When a response for store request is received.

Parameters
clsa struct GNUNET_PEERSTORE_Handle *
msgmessage received

Definition at line 660 of file peerstore_api.c.

661{
662 struct GNUNET_PEERSTORE_Handle *h = cls;
663 struct GNUNET_PEERSTORE_StoreContext *sc = h->store_head;
664
665 LOG (GNUNET_ERROR_TYPE_DEBUG, "Got PeerstoreResultMessage\n");
666 for (sc = h->store_head; NULL != sc; sc = sc->next)
667 {
668 /* @e rid is a uint32_t, written with htonl() by
669 #PEERSTORE_create_record_mq_envelope() and echoed back verbatim by
670 #store_record_continuation(). Reading it with ntohs() truncated it
671 to 16 bits, so the comparison only ever succeeded for rid 0 -- the
672 very first operation of the process. Every store after that lost
673 its result: the continuation was never called and the context never
674 freed, so #GNUNET_PEERSTORE_store() leaked one context per call and
675 callers that wait for their continuation waited forever. */
676 if (sc->rid == ntohl (msg->rid))
677 break;
678 }
679 if (NULL == sc)
680 {
681 /* Routine, not an error: the service has no cancel message, so every
682 #GNUNET_PEERSTORE_store_cancel() leaves exactly one result behind
683 with nothing left to match it against. */
685 "Store response for an unknown or cancelled request, ignoring.\n");
686 return;
687 }
688 if (NULL != sc->cont)
689 sc->cont (sc->cont_cls, ntohl (msg->result));
691}
struct GNUNET_MessageHeader * msg
Definition 005.c:2
static void destroy_storecontext(struct GNUNET_PEERSTORE_StoreContext *sc)

References destroy_storecontext(), GNUNET_ERROR_TYPE_DEBUG, h, LOG, msg, and sc.

Here is the call graph for this function:

◆ destroy_iteratecontext()

static void destroy_iteratecontext ( struct GNUNET_PEERSTORE_IterateContext ic)
static

Definition at line 699 of file peerstore_api.c.

700{
703 GNUNET_free (ic->key);
704 GNUNET_free (ic);
705}
struct GNUNET_PEERSTORE_IterateContext * iterate_tail
Tail of active ITERATE requests.
struct GNUNET_PEERSTORE_IterateContext * iterate_head
Head of active ITERATE requests.
struct GNUNET_PEERSTORE_Handle * h
Handle to the PEERSTORE service.

References GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_PEERSTORE_IterateContext::h, GNUNET_PEERSTORE_Handle::iterate_head, GNUNET_PEERSTORE_Handle::iterate_tail, GNUNET_PEERSTORE_IterateContext::key, and GNUNET_PEERSTORE_IterateContext::sub_system.

Referenced by GNUNET_PEERSTORE_iteration_stop(), and handle_iterate_end().

Here is the caller graph for this function:

◆ handle_iterate_end()

static void handle_iterate_end ( void *  cls,
const struct PeerstoreResultMessage msg 
)
static

When a response for iterate request is received.

Parameters
clsa struct GNUNET_PEERSTORE_Handle *
msgmessage received

Definition at line 715 of file peerstore_api.c.

716{
717 struct GNUNET_PEERSTORE_Handle *h = cls;
718 struct GNUNET_PEERSTORE_IterateContext *ic = h->iterate_head;
719
720 for (ic = h->iterate_head; NULL != ic; ic = ic->next)
721 if (ic->rid == ntohl (msg->rid))
722 break;
723 if (NULL == ic)
724 {
726 _ ("Unexpected iteration response.\n"));
727 return;
728 }
729 if (NULL != ic->callback)
730 ic->callback (ic->callback_cls, NULL, NULL);
731 LOG (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up iteration with rid %u\n", ic->rid);
733}
@ GNUNET_ERROR_TYPE_WARNING
static void destroy_iteratecontext(struct GNUNET_PEERSTORE_IterateContext *ic)
#define _(String)
GNU gettext support macro.
Definition platform.h:179

References _, GNUNET_PEERSTORE_IterateContext::callback, GNUNET_PEERSTORE_IterateContext::callback_cls, destroy_iteratecontext(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, h, LOG, msg, GNUNET_PEERSTORE_IterateContext::next, and GNUNET_PEERSTORE_IterateContext::rid.

Here is the call graph for this function:

◆ check_iterate_result()

static int check_iterate_result ( void *  cls,
const struct PeerstoreRecordMessage msg 
)
static

When a response for iterate request is received, check the message is well-formed.

Parameters
clsa struct GNUNET_PEERSTORE_Handle *
msgmessage received

Definition at line 744 of file peerstore_api.c.

745{
746 /* we defer validation to #handle_iterate_result */
747 return GNUNET_OK;
748}
@ GNUNET_OK

References GNUNET_OK.

◆ handle_iterate_result()

static void handle_iterate_result ( void *  cls,
const struct PeerstoreRecordMessage msg 
)
static

When a response for iterate request is received.

Parameters
clsa struct GNUNET_PEERSTORE_Handle *
msgmessage received

Definition at line 758 of file peerstore_api.c.

759{
760 struct GNUNET_PEERSTORE_Handle *h = cls;
763
764 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RecordMessage\n");
765 for (ic = h->iterate_head; NULL != ic; ic = ic->next)
766 if (ic->rid == ntohl (msg->rid))
767 break;
768 if (NULL == ic)
769 {
771 _ (
772 "Unexpected iteration response, no iterating client found, discarding message.\n"));
773 return;
774 }
776 if (NULL == record)
777 {
778 /* A NULL record is how #handle_iterate_end() signals that the iteration
779 is over and @a ic is gone, and that is how every caller reads it: they
780 clear their handle and return. Passing NULL here without ending the
781 iteration therefore left them holding a pointer they believe is dead
782 while @a ic was still live, and the ITERATE_END that followed invoked
783 the callback a second time -- which trips, for instance,
784 #backtalker_monotime_cb()'s `GNUNET_assert (NULL != b->cmc)' in
785 transport. Make the signal mean one thing. */
786 if (NULL != ic->callback)
787 ic->callback (ic->callback_cls,
788 NULL,
789 _ ("Received a malformed response from service."));
791 return;
792 }
793 if (NULL != ic->callback)
794 ic->callback (ic->callback_cls, record, NULL);
796}
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
void GNUNET_PEERSTORE_iteration_stop(struct GNUNET_PEERSTORE_IterateContext *ic)
Cancel an iterate request Please do not call after the iterate request is done.
struct GNUNET_PEERSTORE_Record * PEERSTORE_parse_record_message(const struct PeerstoreRecordMessage *srm)
Parses a message carrying a record.
void PEERSTORE_destroy_record(struct GNUNET_PEERSTORE_Record *record)
Free any memory allocated for this record.

References _, GNUNET_PEERSTORE_IterateContext::callback, GNUNET_PEERSTORE_IterateContext::callback_cls, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_PEERSTORE_iteration_stop(), h, LOG, msg, GNUNET_PEERSTORE_IterateContext::next, PEERSTORE_destroy_record(), PEERSTORE_parse_record_message(), record(), and GNUNET_PEERSTORE_IterateContext::rid.

Here is the call graph for this function:

◆ hello_store_success()

static void hello_store_success ( void *  cls,
int  success 
)
static

Definition at line 979 of file peerstore_api.c.

980{
981 struct GNUNET_PEERSTORE_StoreHelloContext *huc = cls;
982
983 huc->sc = NULL;
984 if (GNUNET_OK != success)
985 {
987 "Storing hello uri failed\n");
988 huc->cont (huc->cont_cls, success);
989 GNUNET_free (huc->hello);
990 GNUNET_free (huc);
991 return;
992 }
993 huc->cont (huc->cont_cls, GNUNET_OK);
994 GNUNET_free (huc->hello);
995 GNUNET_free (huc);
996}
Context for a add hello uri request.
struct GNUNET_MessageHeader * hello
Hello uri which was request for storing.
GNUNET_PEERSTORE_Continuation cont
Function to call with information.
struct GNUNET_PEERSTORE_StoreContext * sc
Store operation for the merge.
void * cont_cls
Closure for callback.

References GNUNET_PEERSTORE_StoreHelloContext::cont, GNUNET_PEERSTORE_StoreHelloContext::cont_cls, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_OK, GNUNET_PEERSTORE_StoreHelloContext::hello, LOG, and GNUNET_PEERSTORE_StoreHelloContext::sc.

Referenced by hello_add_iter().

Here is the caller graph for this function:

◆ hello_add_iter()

static void hello_add_iter ( void *  cls,
const struct GNUNET_PEERSTORE_Record record,
const char *  emsg 
)
static

If we ever get here, we are newer than the existing record or the only/first record.

Definition at line 1000 of file peerstore_api.c.

1002{
1003 struct GNUNET_PEERSTORE_StoreHelloContext *huc = cls;
1004 struct GNUNET_TIME_Absolute hello_exp =
1006 struct GNUNET_TIME_Absolute hello_record_exp;
1007
1008 if ((NULL == record) && (NULL == emsg))
1009 {
1013 /* The iteration ended with this call and @e ic is about to be freed by
1014 #handle_iterate_end(); keeping the pointer would leave
1015 #GNUNET_PEERSTORE_hello_add_cancel() stopping a dead iteration. */
1016 huc->ic = NULL;
1017 huc->sc = GNUNET_PEERSTORE_store (huc->h,
1018 "peerstore",
1019 &huc->pid,
1021 huc->hello,
1022 ntohs (huc->hello->size),
1023 hello_exp,
1026 huc);
1027 return;
1028 }
1029 if (NULL != emsg)
1030 {
1031 /* @a emsg only ever accompanies a NULL record, which ends the iteration
1032 and destroys @e ic. Asking for another record here used a context
1033 that no longer exists, and left @a huc -- and our caller's
1034 continuation -- hanging forever. */
1035 LOG (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
1036 huc->ic = NULL;
1037 huc->cont (huc->cont_cls, GNUNET_SYSERR);
1038 GNUNET_free (huc->hello);
1039 GNUNET_free (huc);
1040 return;
1041 }
1042 hello_record_exp = GNUNET_HELLO_get_expiration_time_from_msg (record->value);
1043 if (GNUNET_TIME_absolute_cmp (hello_record_exp, >, hello_exp))
1044 {
1046 "Not storing hello for %s since we seem to have a newer version on record expiring `%s' and after `%s'.\n",
1047 GNUNET_i2s (&huc->pid),
1048 GNUNET_STRINGS_absolute_time_to_string (hello_record_exp),
1050 huc->cont (huc->cont_cls, GNUNET_OK);
1052 GNUNET_free (huc->hello);
1053 GNUNET_free (huc);
1054 return;
1055 }
1057}
struct GNUNET_TIME_Absolute GNUNET_HELLO_get_expiration_time_from_msg(const struct GNUNET_MessageHeader *msg)
Get the expiration time for this HELLO.
Definition hello-uri.c:642
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
void GNUNET_PEERSTORE_iteration_next(struct GNUNET_PEERSTORE_IterateContext *ic, uint64_t limit)
Cancel an iterate request Please do not call after the iterate request is done.
struct GNUNET_PEERSTORE_StoreContext * GNUNET_PEERSTORE_store(struct GNUNET_PEERSTORE_Handle *h, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, const void *value, size_t size, struct GNUNET_TIME_Absolute expiry, enum GNUNET_PEERSTORE_StoreOption options, GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
Store a new entry in the PEERSTORE.
#define GNUNET_PEERSTORE_HELLO_KEY
Key used for storing HELLO in the peerstore.
@ GNUNET_PEERSTORE_STOREOPTION_REPLACE
Delete any previous values for the given key before storing the given value.
#define GNUNET_TIME_absolute_cmp(t1, op, t2)
Compare two absolute times.
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition strings.c:671
static void hello_store_success(void *cls, int success)
struct GNUNET_PEERSTORE_Handle * h
Peerstore handle.
struct GNUNET_PEERSTORE_IterateContext * ic
The iteration for the merge.
struct GNUNET_PeerIdentity pid
The peer id for the hello.
Time for absolute times used by GNUnet, in microseconds.

References GNUNET_PEERSTORE_StoreHelloContext::cont, GNUNET_PEERSTORE_StoreHelloContext::cont_cls, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_HELLO_get_expiration_time_from_msg(), GNUNET_i2s(), GNUNET_OK, GNUNET_PEERSTORE_HELLO_KEY, GNUNET_PEERSTORE_iteration_next(), GNUNET_PEERSTORE_iteration_stop(), GNUNET_PEERSTORE_store(), GNUNET_PEERSTORE_STOREOPTION_REPLACE, GNUNET_STRINGS_absolute_time_to_string(), GNUNET_SYSERR, GNUNET_TIME_absolute_cmp, GNUNET_PEERSTORE_StoreHelloContext::h, GNUNET_PEERSTORE_StoreHelloContext::hello, hello_store_success(), GNUNET_PEERSTORE_StoreHelloContext::ic, LOG, GNUNET_PEERSTORE_StoreHelloContext::pid, record(), GNUNET_PEERSTORE_StoreHelloContext::sc, and GNUNET_MessageHeader::size.

Referenced by GNUNET_PEERSTORE_hello_add().

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