GNUnet 0.28.1-dev.4-8-g14b9efcb0
 
Loading...
Searching...
No Matches
peerstore_api.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013-2016, 2019, 2026 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_protocols.h"
30#include "peerstore.h"
31#include "peerstore_common.h"
33
34#define LOG(kind, ...) GNUNET_log_from (kind, "peerstore-api", __VA_ARGS__)
35
36/******************************************************************************/
37/************************ DATA STRUCTURES ****************************/
38/******************************************************************************/
39
96
137
213
229
285
286
323
324/******************************************************************************/
325/******************* DECLARATIONS *********************/
326/******************************************************************************/
327
333static void
334reconnect (void *cls);
335
342static uint32_t
344{
345 return h->last_op_id++;
346}
347
348
363static void
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}
411
412
418static void
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}
434
435
442static void
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}
466
467
468/******************************************************************************/
469/******************* CONNECTION FUNCTIONS *********************/
470/******************************************************************************/
471
472
476static void
478{
479 struct GNUNET_PEERSTORE_Handle *h = cls;
480
482 "Received an error notification from MQ of type: %d\n",
483 error);
485}
486
487
496{
498
500 h->cfg = cfg;
501 reconnect (h);
502 if (NULL == h->mq)
503 {
504 /* #reconnect() has scheduled a retry against @a h; freeing the handle
505 without cancelling it leaves the scheduler holding a pointer into
506 freed memory. */
507 if (NULL != h->reconnect_task)
508 {
510 h->reconnect_task = NULL;
511 }
512 GNUNET_free (h);
513 return NULL;
514 }
515 return h;
516}
517
518
525void
527{
528 LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnect initiated from client.\n");
529 if (NULL != h->reconnect_task)
530 {
532 h->reconnect_task = NULL;
533 }
534 /* Silently: the caller is tearing down and the closures behind these
535 callbacks may already be gone, so this is not the moment to invoke
536 them. #disconnect() asserts both lists are empty, and until now a
537 caller that still had anything in flight -- which, with the request-id
538 truncation, was every caller that had ever stored twice -- aborted here
539 instead of shutting down. */
541 disconnect (h);
542 GNUNET_free (h);
543}
544
545
546/******************************************************************************/
547/******************* STORE FUNCTIONS *********************/
548/******************************************************************************/
549
550static void
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}
559
560
566void
568{
570 "store cancel with sc %p \n",
571 sc);
574 "store cancel with sc %p is null\n",
575 sc);
576}
577
578
597 const char *sub_system,
598 const struct GNUNET_PeerIdentity *peer,
599 const char *key,
600 const void *value,
601 size_t size,
605 void *cont_cls)
606{
607 struct GNUNET_MQ_Envelope *ev;
609
611 "Storing value (size: %llu) for subsystem `%s', peer `%s', key `%s'\n",
612 (unsigned long long) size,
615 key);
617 sc->rid = get_op_id (h);
618 sc->sub_system = GNUNET_strdup (sub_system);
619 GNUNET_assert (NULL != peer);
620 sc->peer = *peer;
621 sc->key = GNUNET_strdup (key);
622 sc->value = GNUNET_memdup (value, size);
623 sc->size = size;
624 sc->expiry = expiry;
625 sc->options = options;
626 sc->cont = cont;
627 sc->cont_cls = cont_cls;
628 sc->h = h;
629 ev =
632 peer,
633 key,
634 value,
635 size,
636 expiry,
637 options,
639
640 GNUNET_CONTAINER_DLL_insert_tail (h->store_head, h->store_tail, sc);
641 if (NULL == h->mq)
642 {
643 sc->env = ev;
644 }
645 else
646 {
647 GNUNET_MQ_send (h->mq, ev);
648 }
649 return sc;
650}
651
652
659static void
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}
692
693
694/******************************************************************************/
695/******************* ITERATE FUNCTIONS *********************/
696/******************************************************************************/
697
698static void
706
707
714static void
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}
734
735
743static int
745{
746 /* we defer validation to #handle_iterate_result */
747 return GNUNET_OK;
748}
749
750
757static void
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}
797
798
805void
807 uint64_t limit)
808{
809 struct GNUNET_MQ_Envelope *ev;
811
813 "Sending PEERSTORE_ITERATION_NEXT message\n");
815 inm->rid = htonl (ic->rid);
816 inm->limit = GNUNET_htonll (limit);
817 if (NULL == ic->h->mq)
818 {
819 ic->env = ev;
820 }
821 else
822 {
823 GNUNET_MQ_send (ic->h->mq, ev);
824 }
825}
826
827
834void
836{
837 struct GNUNET_MQ_Envelope *ev;
839
841 "Sending PEERSTORE_ITERATION_STOP message\n");
842 if (NULL != ic->h->mq)
843 {
845 ism->rid = htonl (ic->rid);
846 if (NULL != ic->h->mq)
847 GNUNET_MQ_send (ic->h->mq, ev);
848 }
850}
851
852
855 const char *sub_system,
856 const struct GNUNET_PeerIdentity *peer,
857 const char *key,
859 void *callback_cls)
860{
861 struct GNUNET_MQ_Envelope *ev;
864 size_t ss_size;
865 size_t key_size;
866 size_t msg_size;
867 void *dummy;
868
870 ic->rid = get_op_id (h);
871
872 GNUNET_assert (NULL != sub_system);
873 ss_size = strlen (sub_system) + 1;
874 if (NULL == key)
875 key_size = 0;
876 else
877 key_size = strlen (key) + 1;
878 msg_size = ss_size + key_size;
879 ev = GNUNET_MQ_msg_extra (srm, msg_size,
881 srm->key_size = htons (key_size);
882 srm->rid = htonl (ic->rid);
883 srm->sub_system_size = htons (ss_size);
884 dummy = &srm[1];
885 GNUNET_memcpy (dummy, sub_system, ss_size);
886 dummy += ss_size;
887 GNUNET_memcpy (dummy, key, key_size);
888 ic->callback = callback;
890 ic->h = h;
892 if (NULL != peer)
893 {
894 ic->peer = *peer;
895 srm->peer_set = htons (GNUNET_YES);
896 srm->peer = *peer;
897 }
898 if (NULL != key)
899 ic->key = GNUNET_strdup (key);
900 GNUNET_CONTAINER_DLL_insert_tail (h->iterate_head, h->iterate_tail, ic);
902 "Sending an iterate request for sub system `%s'\n",
903 sub_system);
904 GNUNET_MQ_send (h->mq, ev);
905 return ic;
906}
907
908
914static void
915reconnect (void *cls)
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}
976
977
978static void
979hello_store_success (void *cls, int success)
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}
997
998
999static void
1001 const char *emsg)
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}
1058
1059
1062 const struct GNUNET_MessageHeader *msg,
1064 void *cont_cls)
1065{
1066 struct GNUNET_HELLO_Parser *parser = GNUNET_HELLO_parser_from_msg (msg, NULL);
1068 const struct GNUNET_PeerIdentity *pid;
1070 struct GNUNET_TIME_Absolute hello_exp =
1072 struct GNUNET_TIME_Absolute huc_exp;
1073 uint16_t size_msg = ntohs (msg->size);
1074
1075 if (NULL == parser)
1076 return NULL;
1077 if (GNUNET_TIME_absolute_cmp (hello_exp, <, now))
1078 {
1079 GNUNET_HELLO_parser_free (parser);
1080 return NULL;
1081 }
1082
1084 huc->h = h;
1085 huc->cont = cont;
1086 huc->cont_cls = cont_cls;
1087 huc->hello = GNUNET_malloc (size_msg);
1088 GNUNET_memcpy (huc->hello, msg, size_msg);
1089 huc_exp =
1091 pid = GNUNET_HELLO_parser_get_id (parser);
1092 huc->pid = *pid;
1094 "Adding hello for peer %s with expiration %s msg size %u\n",
1095 GNUNET_i2s (&huc->pid),
1097 size_msg);
1098
1099 huc->ic = GNUNET_PEERSTORE_iteration_start (h, "peerstore", &huc->pid,
1102 huc);
1103 GNUNET_HELLO_parser_free (parser);
1104 return huc;
1105}
1106
1107
1108void
1111{
1112 if (NULL != huc->sc)
1114 if (NULL != huc->ic)
1116 GNUNET_free (huc->hello);
1117 GNUNET_free (huc);
1118}
1119
1120
1121/* end of peerstore_api.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition 002.c:5
struct GNUNET_MessageHeader * msg
Definition 005.c:2
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_CONFIGURATION_Handle * cfg
Our configuration.
Definition gnunet-arm.c:108
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
struct GNUNET_HashCode key
The key used in the DHT.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
static char * value
Value of the record to add/remove.
static struct GNUNET_FS_SearchContext * sc
Helper library for handling HELLO URIs.
API to the peerstore service.
Constants for network protocols.
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
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
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.
void GNUNET_HELLO_parser_free(struct GNUNET_HELLO_Parser *parser)
Release resources of a builder.
Definition hello-uri.c:380
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
const struct GNUNET_PeerIdentity * GNUNET_HELLO_parser_get_id(const struct GNUNET_HELLO_Parser *parser)
Get the PeerIdentity for this builder.
Definition hello-uri.c:354
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_log(kind,...)
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
#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.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
GNUNET_MQ_Error
Error codes for the queue.
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.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition mq.c:317
#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_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition mq.c:732
struct GNUNET_PEERSTORE_IterateContext * GNUNET_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.
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_store_cancel(struct GNUNET_PEERSTORE_StoreContext *sc)
Cancel a store request.
void GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h)
Disconnect from the PEERSTORE service.
void(* GNUNET_PEERSTORE_hello_notify_cb)(void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *hello, const char *err_msg)
Function called by PEERSTORE when notifying a client about a changed hello.
struct GNUNET_PEERSTORE_Handle * GNUNET_PEERSTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the PEERSTORE service.
GNUNET_PEERSTORE_StoreOption
Options for storing values in PEERSTORE.
void(* GNUNET_PEERSTORE_Processor)(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
Function called by PEERSTORE for each matching record.
void GNUNET_PEERSTORE_hello_add_cancel(struct GNUNET_PEERSTORE_StoreHelloContext *huc)
Cancel the request to add a hello.
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.
void(* GNUNET_PEERSTORE_Continuation)(void *cls, int success)
Continuation called with a status result.
void GNUNET_PEERSTORE_iteration_stop(struct GNUNET_PEERSTORE_IterateContext *ic)
Cancel an iterate request Please do not call after the iterate request is done.
#define GNUNET_PEERSTORE_HELLO_KEY
Key used for storing HELLO in the peerstore.
struct GNUNET_PEERSTORE_StoreHelloContext * GNUNET_PEERSTORE_hello_add(struct GNUNET_PEERSTORE_Handle *h, const struct GNUNET_MessageHeader *msg, GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
Add hello to peerstore.
@ GNUNET_PEERSTORE_STOREOPTION_REPLACE
Delete any previous values for the given key before storing the given value.
#define GNUNET_MESSAGE_TYPE_PEERSTORE_STORE
Store request message.
#define GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_START
Iteration request (see also 828, 829)
#define GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_NEXT
Iteration request (see also 821, 829)
#define GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_STOP
Iteration request (see also 821, 828)
#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.
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_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
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
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
#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
#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 unsigned int size
Size of the "table".
Definition peer.c:68
IPC messages.
static void flush_pending_operations(struct GNUNET_PEERSTORE_Handle *h, int notify)
Terminate every operation still pending on h.
static void handle_iterate_result(void *cls, const struct PeerstoreRecordMessage *msg)
When a response for iterate request is received.
static void handle_client_error(void *cls, enum GNUNET_MQ_Error error)
Function called when we had trouble talking to the service.
static void hello_add_iter(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
static void handle_iterate_end(void *cls, const struct PeerstoreResultMessage *msg)
When a response for iterate request is received.
static uint32_t get_op_id(struct GNUNET_PEERSTORE_Handle *h)
Get a fresh operation id to distinguish between namestore requests.
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_store_result(void *cls, const struct PeerstoreResultMessage *msg)
When a response for store request is received.
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 disconnect(struct GNUNET_PEERSTORE_Handle *h)
Disconnect from the peerstore service.
static void destroy_iteratecontext(struct GNUNET_PEERSTORE_IterateContext *ic)
static void destroy_storecontext(struct GNUNET_PEERSTORE_StoreContext *sc)
#define LOG(kind,...)
static void hello_store_success(void *cls, int success)
struct GNUNET_PEERSTORE_Record * PEERSTORE_parse_record_message(const struct PeerstoreRecordMessage *srm)
Parses a message carrying a record.
struct GNUNET_MQ_Envelope * PEERSTORE_create_record_mq_envelope(uint32_t rid, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, const void *value, size_t value_size, struct GNUNET_TIME_Absolute expiry, enum GNUNET_PEERSTORE_StoreOption options, uint16_t msg_type)
Creates a MQ envelope for a single record.
void PEERSTORE_destroy_record(struct GNUNET_PEERSTORE_Record *record)
Free any memory allocated for this record.
Helper peerstore functions.
#define _(String)
GNU gettext support macro.
Definition platform.h:179
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
Internal representation of the hash map.
enum GNUNET_FS_SearchOptions options
Options for the search.
Definition fs_api.h:1611
struct GNUNET_FS_Handle * h
Handle to the global FS context.
Definition fs_api.h:1528
Context for parsing HELLOs.
Definition hello-uri.c:233
Handle to a message queue.
Definition mq.c:87
Message handler for a specific message type.
Header for all communications.
Handle to the PEERSTORE service.
struct GNUNET_PEERSTORE_IterateContext * iterate_tail
Tail of active ITERATE requests.
struct GNUNET_MQ_Handle * mq
Message queue.
struct GNUNET_TIME_Relative reconnect_delay
Delay until we try to reconnect.
struct GNUNET_PEERSTORE_StoreContext * store_tail
Tail of active STORE requests.
struct GNUNET_PEERSTORE_StoreContext * store_head
Head of active STORE requests.
struct GNUNET_PEERSTORE_IterateContext * iterate_head
Head of active ITERATE requests.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
struct GNUNET_SCHEDULER_Task * reconnect_task
ID of the task trying to reconnect to the service.
struct GNUNET_CONTAINER_MultiHashMap * watches
Hashmap of watch requests.
Context for a iterate request.
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_PEERSTORE_IterateContext * prev
Kept in a DLL.
struct GNUNET_PEERSTORE_Handle * h
Handle to the PEERSTORE service.
struct GNUNET_MQ_Envelope * env
Temporary envelope.
struct GNUNET_PEERSTORE_IterateContext * next
Kept in a DLL.
struct GNUNET_PeerIdentity peer
Peer the store is for.
Context for the info handler.
void * callback_cls
Closure for callback.
GNUNET_PEERSTORE_hello_notify_cb callback
Function to call with information.
unsigned int canceled
Is this request canceled.
struct GNUNET_PEERSTORE_Monitor * wc
The watch for this context.
struct GNUNET_PEERSTORE_Handle * h
Peerstore handle.
Context for a store request.
char * sub_system
Which subsystem does the store?
enum GNUNET_PEERSTORE_StoreOption options
Options for the store operation.
void * value
Contains size bytes.
struct GNUNET_TIME_Absolute expiry
When does the value expire?
struct GNUNET_PEERSTORE_StoreContext * prev
Kept in a DLL.
void * cont_cls
Closure for cont.
struct GNUNET_MQ_Envelope * env
Temporary envelope.
struct GNUNET_PEERSTORE_StoreContext * next
Kept in a DLL.
size_t size
Number of bytes in value.
struct GNUNET_PEERSTORE_Handle * h
Handle to the PEERSTORE service.
GNUNET_PEERSTORE_Continuation cont
Continuation called with service response.
struct GNUNET_PeerIdentity peer
Peer the store is for.
char * key
Key for the store operation.
Context for a add hello uri request.
struct GNUNET_MessageHeader * hello
Hello uri which was request for storing.
struct GNUNET_PEERSTORE_Handle * h
Peerstore handle.
struct GNUNET_PEERSTORE_IterateContext * ic
The iteration for the merge.
GNUNET_PEERSTORE_Continuation cont
Function to call with information.
struct GNUNET_PeerIdentity pid
The peer id for the hello.
struct GNUNET_PEERSTORE_StoreContext * sc
Store operation for the merge.
void * cont_cls
Closure for callback.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition scheduler.c:141
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
Iteration next message.
Definition peerstore.h:248
uint32_t rid
Request id.
Definition peerstore.h:262
uint64_t limit
Number of records to return.
Definition peerstore.h:257
Iteration start message.
Definition peerstore.h:202
uint16_t peer_set
GNUNET_YES if peer id value set, GNUNET_NO otherwise
Definition peerstore.h:221
struct GNUNET_PeerIdentity peer
Peer Identity.
Definition peerstore.h:211
uint32_t rid
Request id.
Definition peerstore.h:216
uint16_t sub_system_size
Size of the sub_system string Allocated at position 0 after this struct.
Definition peerstore.h:227
uint16_t key_size
Size of the key string Allocated at position 1 after this struct.
Definition peerstore.h:238
uint32_t rid
Request id.
Definition peerstore.h:275
Message carrying a PEERSTORE record message.
Definition peerstore.h:38
Message carrying a PEERSTORE result message.
Definition peerstore.h:96
Closure for store callback when storing hello uris.
struct GNUNET_PEERSTORE_StoreHelloContext * huc
The corresponding hello uri add request.
struct GNUNET_PEERSTORE_StoreContext * sc
The corresponding store context.