GNUnet 0.21.2
gnunet-service-peerstore.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2014, 2015, 2016 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 */
20
26#include "platform.h"
28#include "gnunet_protocols.h"
29#include "gnunet_util_lib.h"
30#include "peerstore.h"
32#include "peerstore_common.h"
34
35
39#define EXPIRED_RECORDS_CLEANUP_INTERVAL 300 /* 5mins */
40
41
45struct PeerstoreClient;
46
50struct Monitor
51{
55 struct Monitor *next;
56
60 struct Monitor *prev;
61
66
71
76
81
89 uint64_t seq;
90
95 uint64_t limit;
96
104
109
114
119
124
128 char *key;
129};
130
135{
140
145
150
158 uint64_t seq;
159
163 uint32_t request_id;
164
172 uint32_t offset;
173
180
185
190
194 char *key;
195
200};
201
206{
211
216
222
228};
229
230
232{
237
241 uint32_t rid;
242
247};
248
252static const struct GNUNET_CONFIGURATION_Handle *cfg;
253
257static char *db_lib_name;
258
263
268
272static struct Monitor *monitors_head;
273
277static struct Monitor *monitors_tail;
278
283
289static void
290shutdown_task (void *cls)
291{
293 "Shutting down peerstore, bye.\n");
294 if (NULL != db_lib_name)
295 {
298 db_lib_name = NULL;
299 }
300 if (NULL != expire_task)
301 {
303 expire_task = NULL;
304 }
305 if (NULL != monitor_nc)
306 {
308 monitor_nc = NULL;
309 }
310}
311
312
313/* Forward declaration */
314static void
315expire_records_continuation (void *cls, int success);
316
317
321static void
323{
324 int ret;
325
326 expire_task = NULL;
327 GNUNET_assert (NULL != db);
331 NULL);
332 if (GNUNET_OK != ret)
333 {
334 GNUNET_assert (NULL == expire_task);
339 NULL);
340 }
341}
342
343
350static void
351expire_records_continuation (void *cls, int success)
352{
353 if (success > 0)
354 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%d records expired.\n", success);
355 GNUNET_assert (NULL == expire_task);
360 NULL);
361}
362
363
369static void
371{
372 struct GNUNET_MQ_Envelope *env;
373 struct GNUNET_MessageHeader *sync;
375 "Syncing zone monitor %p\n", mc);
376
378 GNUNET_MQ_send (mc->pc->mq, env);
379 /* mark iteration done */
380 mc->in_first_iteration = GNUNET_NO;
381 mc->iteration_cnt = 0;
382}
383
384
390static void
392{
393 struct GNUNET_MQ_Envelope *env;
394 struct Monitor *mc;
395
396 // FIXME this is very inefficient, we may want to use a hash
397 // map again.
398 for (mc = monitors_head; NULL != mc; mc = mc->next)
399 {
400 if ((GNUNET_YES == mc->peer_set) &&
401 (0 != memcmp (&mc->peer, &record->peer, sizeof (record->peer))))
402 continue;
403 if ((NULL != mc->sub_system) &&
404 (0 != strcmp (mc->sub_system, record->sub_system)))
405 continue;
406 if ((NULL != mc->key) &&
407 (0 != strcmp (mc->key, record->key)))
408 continue;
409 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found watcher %p to update.\n", mc);
411 0,
412 record->sub_system,
413 &record->peer,
414 record->key,
415 record->value,
416 record->value_size,
417 record->expiry,
418 0,
420 GNUNET_MQ_send (mc->pc->mq, env);
421 }
422}
423
424
430{
434 struct Iteration *ic;
435
439 uint64_t limit;
440
441};
442
453static void
454iterate_proc (void *cls,
455 uint64_t seq,
456 const struct GNUNET_PEERSTORE_Record *record,
457 const char *emsg)
458{
459 struct IterationProcResult *proc = cls;
460 struct GNUNET_MQ_Envelope *env;
461
462 if (NULL != emsg)
463 {
465 "Error iterating over peerstore: `%s'", emsg);
466 return;
467 }
468 if (NULL == record)
469 {
470 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
471 return;
472 }
473 if (0 == proc->limit)
474 {
475 /* what is this!? should never happen */
476 GNUNET_break (0);
477 return;
478 }
479 proc->ic->seq = seq;
481 proc->ic->request_id,
482 record->sub_system,
483 &record->peer,
484 record->key,
485 record->value,
486 record->value_size,
487 record->expiry,
488 0,
490 GNUNET_MQ_send (proc->ic->pc->mq, env);
491 proc->limit--;
492}
493
494
495static void
497{
498 GNUNET_free (ic->key);
500 GNUNET_free (ic);
501}
502
503
510static void
512{
513 struct GNUNET_MQ_Envelope *env;
514 struct PeerstoreResultMessage *endmsg;
515
517 if (! ic->send_end)
518 return;
519 /* No more records */
520
522 endmsg->rid = htons (ic->request_id);
523 endmsg->result = htonl (GNUNET_OK);
524 GNUNET_MQ_send (ic->pc->mq, env);
527 return;
528}
529
530
537static void
538run_iteration_round (struct Iteration *ic, uint64_t limit)
539{
540 struct IterationProcResult proc;
543
544 memset (&proc, 0, sizeof(proc));
546 "Asked to return up to %llu records at position %llu\n",
547 (unsigned long long) limit,
548 (unsigned long long) ic->seq);
549 proc.ic = ic;
550 proc.limit = limit;
554 ic->sub_system,
555 (GNUNET_YES == ic->peer_set) ? &ic->peer :
556 NULL,
557 ic->key,
558 ic->seq,
559 proc.limit,
561 &proc));
564 if (0 == proc.limit)
566 "Returned %llu results, more results available\n",
567 (unsigned long long) limit);
568 ic->send_end = (0 != proc.limit);
570}
571
572
580static int
581check_iterate_start (void *cls, const struct
583{
584 uint16_t ss_size;
585 uint16_t key_size;
586 uint16_t size;
587
588 ss_size = ntohs (srm->sub_system_size);
589 key_size = ntohs (srm->key_size);
590 size = ntohs (srm->header.size);
591
592 if (size < key_size + ss_size + sizeof(*srm))
593 {
594 GNUNET_break (0);
595 return GNUNET_SYSERR;
596 }
597 return GNUNET_OK;
598}
599
600
607static void
609 srm)
610{
611 struct Iteration *ic = GNUNET_new (struct Iteration);
612 uint16_t ss_size;
613 char *ptr;
614
615 ss_size = ntohs (srm->sub_system_size);
616
617 ic->pc = cls;
618 ic->request_id = ntohs (srm->rid);
619 ic->offset = 0;
620 ic->peer_set = (ntohs (srm->peer_set)) ? GNUNET_YES : GNUNET_NO;
621 if (GNUNET_YES == ic->peer_set)
622 ic->peer = srm->peer;
623 ptr = (char*) &srm[1];
624 ic->sub_system = GNUNET_strdup (ptr);
625 ptr += ss_size;
626 if (0 < ntohs (srm->key_size))
627 ic->key = GNUNET_strdup (ptr);
629 "Iterate request: ss `%s', peer `%s', key `%s'\n",
630 ic->sub_system,
631 GNUNET_i2s (&ic->peer),
632 (NULL == ic->key) ? "NULL" : ic->key);
634 ic->pc->op_tail,
635 ic);
636 run_iteration_round (ic, 1);
637}
638
639
646static void
648 const struct PeerstoreIterationStopMessage *zis_msg)
649{
650 struct PeerstoreClient *pc = cls;
651 struct Iteration *ic;
652 uint32_t rid;
653
655 "Received ITERATION_STOP message\n");
656 rid = ntohs (zis_msg->rid);
657 for (ic = pc->op_head; NULL != ic; ic = ic->next)
658 if (ic->request_id == rid)
659 break;
660 if (NULL == ic)
661 {
662 GNUNET_break (0);
664 return;
665 }
666 GNUNET_CONTAINER_DLL_remove (pc->op_head, pc->op_tail, ic);
669}
670
671
678static void
680 const struct PeerstoreIterationNextMessage *is_msg)
681{
682 struct PeerstoreClient *pc = cls;
683 struct Iteration *ic;
684 uint32_t rid;
685 uint64_t limit;
686
688 "Received ITERATION_NEXT message\n");
689 rid = ntohs (is_msg->rid);
690 limit = GNUNET_ntohll (is_msg->limit);
691 for (ic = pc->op_head; NULL != ic; ic = ic->next)
692 if (ic->request_id == rid)
693 break;
694 if (NULL == ic)
695 {
697 "Not in iteration...\n");
698 GNUNET_break (0);
700 return;
701 }
703 "Found iteration...\n");
704 run_iteration_round (ic, limit);
705}
706
707
713static void
714monitor_iteration_next (void *cls);
715
716
727static void
729 uint64_t seq,
730 const struct GNUNET_PEERSTORE_Record *record,
731 const char *emsg)
732{
733 struct Monitor *mc = cls;
734 struct GNUNET_MQ_Envelope *env;
735
736 GNUNET_assert (0 != seq);
737 mc->seq = seq;
738
739 if (NULL != emsg)
740 {
742 "Error iterating over peerstore: `%s'", emsg);
743 return;
744 }
745 if (NULL == record)
746 {
747 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
748 return;
749 }
750 if (0 == mc->limit)
751 {
752 /* what is this!? should never happen */
753 GNUNET_break (0);
754 return;
755 }
757 0,
758 record->sub_system,
759 &record->peer,
760 record->key,
761 record->value,
762 record->value_size,
763 record->expiry,
764 0,
766 GNUNET_MQ_send (mc->pc->mq, env);
767
769 "Sent records.\n");
770 mc->limit--;
771 mc->iteration_cnt--;
772 if ((0 == mc->iteration_cnt) && (0 != mc->limit))
773 {
774 /* We are done with the current iteration batch, AND the
775 client would right now accept more, so go again! */
776 GNUNET_assert (NULL == mc->task);
778 }
779}
780
781
787static void
789{
790 struct Monitor *mc = cls;
791 int ret;
792
793 mc->task = NULL;
794 GNUNET_assert (0 == mc->iteration_cnt);
795 if (mc->limit > 16)
796 mc->iteration_cnt = mc->limit / 2; /* leave half for monitor events */
797 else
798 mc->iteration_cnt = mc->limit; /* use it all */
800 "Running iteration\n");
802 mc->sub_system,
803 (GNUNET_YES == mc->peer_set) ? &mc->peer : NULL,
804 mc->key,
805 mc->seq,
806 mc->iteration_cnt,
808 mc);
809 if (GNUNET_SYSERR == ret)
810 {
811 GNUNET_free (mc->key);
812 GNUNET_free (mc->sub_system);
813 GNUNET_SERVICE_client_drop (mc->pc->client);
814 GNUNET_free (mc);
815 return;
816 }
817 if (GNUNET_NO == ret)
818 {
820 "Zone empty... syncing\n");
821 /* empty zone */
823 return;
824 }
825}
826
827
835static int
837{
838 uint16_t ss_size;
839 uint16_t key_size;
840 uint16_t size;
841
842 ss_size = ntohs (srm->sub_system_size);
843 key_size = ntohs (srm->key_size);
844 size = ntohs (srm->header.size);
845
846 if (size < key_size + ss_size + sizeof(*srm))
847 {
848 GNUNET_break (0);
849 return GNUNET_SYSERR;
850 }
851 return GNUNET_OK;
852}
853
854
861static void
863{
864 struct Monitor *mc = GNUNET_new (struct Monitor);
865
866 uint16_t ss_size;
867 char *ptr;
868
869 ss_size = ntohs (msm->sub_system_size);
870
871 mc->pc = cls;
872 mc->peer_set = (ntohs (msm->peer_set)) ? GNUNET_YES : GNUNET_NO;
873 if (GNUNET_YES == mc->peer_set)
874 mc->peer = msm->peer;
875 ptr = (char*) &msm[1];
876 if (0 < ss_size)
877 mc->sub_system = GNUNET_strdup (ptr);
878 ptr += ss_size;
879 if (0 < ntohs (msm->key_size))
880 mc->key = GNUNET_strdup (ptr);
882 "Monitor request: ss `%s', peer `%s', key `%s'\n",
883 mc->sub_system,
884 GNUNET_i2s (&mc->peer),
885 (NULL == mc->key) ? "NULL" : mc->key);
886 mc->in_first_iteration = (GNUNET_YES == ntohs (msm->iterate_first));
887 mc->limit = 1;
888 mc->peer_set = (ntohs (msm->peer_set)) ? GNUNET_YES : GNUNET_NO;
891 mc);
895 if (mc->in_first_iteration)
897 else
899}
900
901
908static void
910{
911 struct PeerstoreClient *pc = cls;
912 struct Monitor *mc;
913 uint64_t inc;
914
915 inc = GNUNET_ntohll (nm->limit);
917 "Received MONITOR_NEXT message with limit %llu\n",
918 (unsigned long long) inc);
919 for (mc = monitors_head; NULL != mc; mc = mc->next)
920 if (mc->pc == pc)
921 break;
922 if (NULL == mc)
923 {
924 GNUNET_break (0);
926 return;
927 }
929 if (mc->limit + inc < mc->limit)
930 {
931 GNUNET_break (0);
933 return;
934 }
935 mc->limit += inc;
936 if ((mc->in_first_iteration) && (mc->limit == inc))
937 {
938 /* We are still iterating, and the previous iteration must
939 have stopped due to the client's limit, so continue it! */
940 GNUNET_assert (NULL == mc->task);
942 }
943 GNUNET_assert (mc->iteration_cnt <= mc->limit);
944}
945
946
953static void
954store_record_continuation (void *cls, int success)
955{
956 struct StoreRecordContext *src = cls;
958 struct GNUNET_MQ_Envelope *env;
959
961 msg->rid = src->rid;
962 msg->result = htonl (success);
963 GNUNET_MQ_send (src->pc->mq, env);
964 watch_notifier (src->record);
967 GNUNET_free (src);
968}
969
970
978static int
979check_store (void *cls, const struct PeerstoreRecordMessage *srm)
980{
982
984 if (NULL == record)
985 {
986 GNUNET_break (0);
987 return GNUNET_SYSERR;
988 }
989 if ((NULL == record->sub_system) || (NULL == record->key))
990 {
991 GNUNET_break (0);
993 return GNUNET_SYSERR;
994 }
996 return GNUNET_OK;
997}
998
999
1006static void
1007handle_store (void *cls, const struct PeerstoreRecordMessage *srm)
1008{
1009 struct PeerstoreClient *pc = cls;
1010 struct StoreRecordContext *src = GNUNET_new (struct StoreRecordContext);
1012 GNUNET_log (
1014 "Received a store request. Sub system `%s' Peer `%s Key `%s' Options: %u.\n",
1015 src->record->sub_system,
1016 GNUNET_i2s (&src->record->peer),
1017 src->record->key,
1018 (uint32_t) ntohl (srm->options));
1019 src->rid = srm->rid;
1020 src->pc = pc;
1021 if (GNUNET_OK != db->store_record (db->cls,
1022 src->record->sub_system,
1023 &src->record->peer,
1024 src->record->key,
1025 src->record->value,
1026 src->record->value_size,
1027 src->record->expiry,
1028 ntohl (srm->options),
1030 src))
1031 {
1032 GNUNET_break (0);
1034 GNUNET_free (src);
1036 GNUNET_free (pc);
1037 return;
1038 }
1039}
1040
1041
1050static void *
1052 struct GNUNET_SERVICE_Client *client,
1053 struct GNUNET_MQ_Handle *mq)
1054{
1055 struct PeerstoreClient *pc;
1056
1058 "A client %p connected\n", client);
1059 pc = GNUNET_new (struct PeerstoreClient);
1060 pc->client = client;
1061 pc->mq = mq;
1062 return pc;
1063}
1064
1065
1072static void
1075 void *app_cls)
1076{
1077 struct PeerstoreClient *pc = app_cls;
1078 struct Iteration *iter;
1079 struct Monitor *mo;
1080
1081 (void) cls;
1083 "Client %p disconnected.\n",
1084 client);
1085 for (mo = monitors_head; NULL != mo; mo = mo->next)
1086 {
1087 if (pc != mo->pc)
1088 continue;
1090 if (NULL != mo->task)
1091 {
1093 mo->task = NULL;
1094 }
1095 if (NULL != mo->sa_wait_warning)
1096 {
1098 mo->sa_wait_warning = NULL;
1099 }
1100 GNUNET_free (mo->sub_system);
1101 GNUNET_free (mo->key);
1102 GNUNET_free (mo);
1103 break;
1104 }
1105 while (NULL != (iter = pc->op_head))
1106 {
1107 GNUNET_CONTAINER_DLL_remove (pc->op_head, pc->op_tail, iter);
1108 destroy_iteration (iter);
1109 }
1110 GNUNET_free (pc);
1111}
1112
1113
1114static void
1115store_hello_continuation (void *cls, int success)
1116{
1117 (void) cls;
1118
1119 if (GNUNET_OK != success)
1120 {
1122 "Error storing bootstrap hello!\n");
1123 GNUNET_break (0);
1124 }
1125}
1126
1127
1128static int
1129hosts_directory_scan_callback (void *cls, const char *fullname)
1130{
1131 (void) cls;
1132 ssize_t size_total;
1133 char buffer[GNUNET_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
1134 const struct GNUNET_MessageHeader *hello;
1136 const struct GNUNET_PeerIdentity *pid;
1137
1138 if (GNUNET_YES != GNUNET_DISK_file_test (fullname))
1139 return GNUNET_OK; /* ignore non-files */
1140
1141 size_total = GNUNET_DISK_fn_read (fullname, buffer, sizeof(buffer));
1143 "Read %d bytes from `%s'\n",
1144 (int) size_total,
1145 fullname);
1146 if ((size_total < 0) ||
1147 (((size_t) size_total) < sizeof(struct GNUNET_MessageHeader)))
1148 {
1150 _ ("Failed to parse HELLO in file `%s': %s\n"),
1151 fullname,
1152 "File has invalid size");
1153 return GNUNET_OK;
1154 }
1155 hello = (const struct GNUNET_MessageHeader *) &buffer[0];
1157 if (NULL == builder)
1158 {
1160 "Unable to parse HELLO message\n");
1161 return GNUNET_OK;
1162 }
1164
1166 "store contrib hello for peer %s\n",
1167 GNUNET_i2s (pid));
1168
1169 if (GNUNET_OK != db->store_record (db->cls,
1170 "peerstore",
1171 pid,
1173 hello,
1174 size_total,
1178 NULL))
1179 {
1180 GNUNET_break (0);
1181 }
1183 return GNUNET_OK;
1184}
1185
1186
1194static void
1195run (void *cls,
1196 const struct GNUNET_CONFIGURATION_Handle *c,
1198{
1199 char *database;
1200 int use_included;
1201 char *ip;
1202 char *peerdir;
1203
1204 cfg = c;
1205
1207 "peerstore",
1208 "DATABASE",
1209 &database))
1210 {
1212 "peerstore",
1213 "DATABASE");
1215 return;
1216 }
1217 GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_peerstore_%s", database);
1218 db = GNUNET_PLUGIN_load (db_lib_name, (void *) cfg);
1219 GNUNET_free (database);
1220 if (NULL == db)
1221 {
1223 _ ("Could not load database backend `%s'\n"),
1224 db_lib_name);
1226 return;
1227 }
1229
1231 "peerstore",
1232 "USE_INCLUDED_HELLOS");
1233 if (GNUNET_SYSERR == use_included)
1234 use_included = GNUNET_NO;
1235 if (GNUNET_YES == use_included)
1236 {
1238 GNUNET_asprintf (&peerdir, "%shellos", ip);
1239 GNUNET_free (ip);
1240
1242 _ ("Importing HELLOs from `%s'\n"),
1243 peerdir);
1244
1247 NULL);
1248 GNUNET_free (peerdir);
1249 }
1250 else
1251 {
1253 _ ("Skipping import of included HELLOs\n"));
1254 }
1256
1258}
1259
1260
1266 &client_disconnect_cb, NULL,
1268 struct PeerstoreRecordMessage, NULL),
1269 GNUNET_MQ_hd_var_size (iterate_start,
1271 struct PeerstoreIterationStartMessage, NULL),
1272 GNUNET_MQ_hd_fixed_size (iterate_stop,
1274 struct PeerstoreIterationStopMessage, NULL),
1275 GNUNET_MQ_hd_fixed_size (iterate_next,
1278 NULL),
1279 GNUNET_MQ_hd_var_size (monitor_start,
1282 NULL),
1283 GNUNET_MQ_hd_fixed_size (monitor_next,
1286 NULL),
1288
1289
1290/* end of gnunet-service-peerstore.c */
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static int ret
Final status code.
Definition: gnunet-arm.c:94
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
static struct HostSet * builder
NULL if we are not currently iterating over peer information.
static struct GNUNET_FS_PublishContext * pc
Handle to FS-publishing operation.
static struct GNUNET_TESTBED_Controller * mc
Handle to the master controller.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static void watch_notifier(struct GNUNET_PEERSTORE_Record *record)
Given a new record, notifies watchers.
static void handle_iterate_next(void *cls, const struct PeerstoreIterationNextMessage *is_msg)
Handles a #GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATION_NEXT message.
static void handle_monitor_start(void *cls, const struct PeerstoreMonitorStartMessage *msm)
Handle an iterate request from client.
static void run_iteration_round(struct Iteration *ic, uint64_t limit)
Perform the next round of the zone iteration.
GNUNET_SERVICE_MAIN("peerstore", GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(store, GNUNET_MESSAGE_TYPE_PEERSTORE_STORE, struct PeerstoreRecordMessage, NULL), GNUNET_MQ_hd_var_size(iterate_start, GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_START, struct PeerstoreIterationStartMessage, NULL), GNUNET_MQ_hd_fixed_size(iterate_stop, GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_STOP, struct PeerstoreIterationStopMessage, NULL), GNUNET_MQ_hd_fixed_size(iterate_next, GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_NEXT, struct PeerstoreIterationNextMessage, NULL), GNUNET_MQ_hd_var_size(monitor_start, GNUNET_MESSAGE_TYPE_PEERSTORE_MONITOR_START, struct PeerstoreMonitorStartMessage, NULL), GNUNET_MQ_hd_fixed_size(monitor_next, GNUNET_MESSAGE_TYPE_PEERSTORE_MONITOR_NEXT, struct PeerstoreMonitorNextMessage, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
static void handle_iterate_start(void *cls, const struct PeerstoreIterationStartMessage *srm)
Handle an iterate request from client.
static void destroy_iteration(struct Iteration *ic)
static void handle_monitor_next(void *cls, const struct PeerstoreMonitorNextMessage *nm)
Handles a GNUNET_MESSAGE_TYPE_PEERSTORE_MONITOR_NEXT message.
static int hosts_directory_scan_callback(void *cls, const char *fullname)
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static struct GNUNET_NotificationContext * monitor_nc
Notification context shared by all monitors.
static struct Monitor * monitors_head
Monitor DLL.
static int check_monitor_start(void *cls, const struct PeerstoreMonitorStartMessage *srm)
Check a monitor request from client.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_cls)
A client disconnected.
static char * db_lib_name
Database plugin library name.
static void expire_records_continuation(void *cls, int success)
Continuation to expire_records called by the peerstore plugin.
static void shutdown_task(void *cls)
Task run during shutdown.
static void iterate_proc(void *cls, uint64_t seq, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
Process results for zone iteration from database.
#define EXPIRED_RECORDS_CLEANUP_INTERVAL
Interval for expired records cleanup (in seconds)
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
A client disconnected.
static int check_store(void *cls, const struct PeerstoreRecordMessage *srm)
Check a store request from client.
static void store_record_continuation(void *cls, int success)
Continuation of store_record called by the peerstore plugin.
static void monitor_sync(struct Monitor *mc)
Send 'sync' message to zone monitor, we're now in sync.
static struct GNUNET_PEERSTORE_PluginFunctions * db
Database handle.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
Peerstore service runner.
static void monitor_iterate_cb(void *cls, uint64_t seq, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
A GNUNET_NAMESTORE_RecordIterator for monitors.
static void store_hello_continuation(void *cls, int success)
static struct GNUNET_SCHEDULER_Task * expire_task
Task run to clean up expired records.
static void cleanup_expired_records(void *cls)
Deletes any expired records from storage.
static void monitor_iteration_next(void *cls)
Obtain the next datum during the monitor's initial iteration.
static int check_iterate_start(void *cls, const struct PeerstoreIterationStartMessage *srm)
Check an iterate request from client.
static void handle_iterate_stop(void *cls, const struct PeerstoreIterationStopMessage *zis_msg)
Handles a #GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATION_STOP message.
static void handle_store(void *cls, const struct PeerstoreRecordMessage *srm)
Handle a store request from client.
static struct Monitor * monitors_tail
Monitor DLL.
static void iteration_done_client_continue(struct Iteration *ic)
Function called once we are done with the iteration and allow the zone iteration client to send us mo...
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_TIME_Relative duration
Option '-d': duration of the mapping.
Definition: gnunet-vpn.c:90
Helper library for handling HELLO URIs.
Plugin API for the peerstore database backend.
API to the peerstore service.
Constants for network protocols.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
Definition: disk.c:482
ssize_t GNUNET_DISK_fn_read(const char *fn, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:664
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:814
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_HELLO_builder_free(struct GNUNET_HELLO_Builder *builder)
Release resources of a builder.
Definition: hello-uri.c:373
struct GNUNET_HELLO_Builder * GNUNET_HELLO_builder_from_msg(const struct GNUNET_MessageHeader *msg)
Parse msg into builder.
Definition: hello-uri.c:391
const struct GNUNET_PeerIdentity * GNUNET_HELLO_builder_get_id(const struct GNUNET_HELLO_Builder *builder)
Get the PeerIdentity for this builder.
Definition: hello-uri.c:366
#define GNUNET_log(kind,...)
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:54
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
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.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition: nc.c:138
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:305
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition: nc.c:122
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:78
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_notification_context_add(struct GNUNET_NotificationContext *nc, struct GNUNET_MQ_Handle *mq)
Add a subscriber to the notification context.
Definition: nc.c:161
char * GNUNET_OS_installation_get_path(enum GNUNET_OS_InstallationPathKind dirkind)
Get the path to a specific GNUnet installation directory or, with GNUNET_OS_IPK_SELF_PREFIX,...
@ GNUNET_OS_IPK_DATADIR
Return the directory where data is installed (share/gnunet/)
#define GNUNET_PEERSTORE_HELLO_KEY
Key used for storing HELLO in the peerstore.
@ GNUNET_PEERSTORE_STOREOPTION_MULTIPLE
Possibly store multiple values under given key.
void * GNUNET_PLUGIN_load(const char *library_name, void *arg)
Setup plugin (runs the "init" callback and returns whatever "init" returned).
Definition: plugin.c:198
void * GNUNET_PLUGIN_unload(const char *library_name, void *arg)
Unload plugin (runs the "done" callback and returns whatever "done" returned).
Definition: plugin.c:242
#define GNUNET_MESSAGE_TYPE_PEERSTORE_MONITOR_SYNC
Monitor sync.
#define GNUNET_MESSAGE_TYPE_PEERSTORE_STORE
Store request message.
#define GNUNET_MESSAGE_TYPE_PEERSTORE_MONITOR_NEXT
Monitor next request.
#define GNUNET_MESSAGE_TYPE_PEERSTORE_MONITOR_START
Monitor request.
#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_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:567
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1340
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:981
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:1305
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:1278
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the 'monitor' flag on this client.
Definition: service.c:2549
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2484
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2455
@ GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN
Trigger a SOFT server shutdown on signals, allowing active non-monitor clients to complete their tran...
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:436
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
struct 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:484
struct GNUNET_TIME_Relative GNUNET_TIME_relative_divide(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Divide relative time by a given factor.
Definition: time.c:550
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
static unsigned int size
Size of the "table".
Definition: peer.c:68
IPC messages.
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:178
struct GNUNET_MQ_Handle * mq
Our own message queue for the FS service; only briefly used when we start to index a file,...
Definition: fs_api.h:1221
Context for building (or parsing) HELLO URIs.
Definition: hello-uri.c:205
Handle to a message queue.
Definition: mq.c:87
Header for all communications.
The notification context is the key datastructure for a convenience API used for transmission of noti...
Definition: nc.c:77
struct returned by the initialization function of the plugin
void * cls
Closure to pass to all plugin functions.
int(* iterate_records)(void *cls, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, uint64_t serial, uint64_t limit, GNUNET_PEERSTORE_PluginProcessor iter, void *iter_cls)
Iterate over the records given an optional peer id and/or key.
int(* store_record)(void *cls, 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 record in the peerstore.
int(* expire_records)(void *cls, struct GNUNET_TIME_Absolute now, GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
Delete expired records (expiry < now)
Single PEERSTORE record.
size_t value_size
Size of value BLOB.
struct GNUNET_PeerIdentity peer
Peer Identity.
void * value
Record value BLOB.
struct GNUNET_TIME_Absolute expiry
Expiry time of entry.
char * sub_system
Responsible sub system string.
char * key
Record key string.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:136
Handle to a client that is connected to a service.
Definition: service.c:246
Handle to a service.
Definition: service.c:117
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
Context for iteration operations passed from run_iteration_round to iterate_proc as closure.
struct Iteration * ic
The zone iteration handle.
uint64_t limit
Number of results left to be returned in this iteration.
A peerstore iteration operation.
int send_end
Set to GNUNET_YES if the last iteration exhausted the limit set by the client and we should send the ...
uint64_t seq
Last sequence number in the zone iteration used to address next result of the zone iteration in the s...
char * sub_system
Responsible sub system string.
char * key
Record key string.
struct GNUNET_PeerIdentity peer
Peer Identity.
struct PeerstoreClient * pc
Namestore client which initiated this zone iteration.
struct Iteration * prev
Previous element in the DLL.
int peer_set
Peer is set?
uint32_t offset
Offset of the zone iteration used to address next result of the zone iteration in the store.
uint32_t request_id
The operation id for the zone iteration in the response for the client.
struct Iteration * next
Next element in the DLL.
A peerstore monitor.
struct PeerstoreClient * pc
Namestore client which initiated this zone monitor.
struct Monitor * next
Next element in the DLL.
uint64_t limit
Current limit of how many more messages we are allowed to queue to this monitor.
struct GNUNET_PeerIdentity peer
Peer Identity.
uint64_t seq
Last sequence number in the zone iteration used to address next result of the iteration in the store.
struct GNUNET_SCHEDULER_Task * task
Task active during initial iteration.
char * key
Record key string.
int in_first_iteration
Are we (still) in the initial iteration pass?
struct Monitor * prev
Previous element in the DLL.
char * sub_system
Responsible sub system string.
struct GNUNET_TIME_Absolute sa_waiting_start
Since when are we blocked on this monitor?
uint64_t iteration_cnt
How many more requests may we receive from the iterator before it is at the limit we gave it?...
struct GNUNET_SCHEDULER_Task * sa_wait_warning
Task to warn about slow monitors.
int peer_set
Is the peer set?
A peerstore client.
struct Iteration * op_head
Head of the DLL of Zone iteration operations in progress initiated by this client.
struct GNUNET_MQ_Handle * mq
Message queue for transmission to client.
struct GNUNET_SERVICE_Client * client
The client.
struct Iteration * op_tail
Tail of the DLL of Zone iteration operations in progress initiated by this client.
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
struct GNUNET_MessageHeader header
GNUnet message header.
Definition: peerstore.h:206
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
Iteration next message.
Definition: peerstore.h:185
uint64_t limit
Number of records to return.
Definition: peerstore.h:194
Iteration start message.
Definition: peerstore.h:140
uint16_t iterate_first
GNUNET_YES if iterate first, GNUNET_NO otherwise
Definition: peerstore.h:176
struct GNUNET_PeerIdentity peer
Peer Identity.
Definition: peerstore.h:149
uint16_t peer_set
GNUNET_YES if peer id value set, GNUNET_NO otherwise
Definition: peerstore.h:165
uint16_t key_size
Size of the key string Allocated at position 1 after this struct.
Definition: peerstore.h:160
uint16_t sub_system_size
Size of the sub_system string Allocated at position 0 after this struct.
Definition: peerstore.h:171
struct GNUNET_MessageHeader header
GNUnet message header.
Definition: peerstore.h:144
Message carrying a PEERSTORE record message.
Definition: peerstore.h:38
uint32_t rid
Request id.
Definition: peerstore.h:57
uint32_t options
Options, needed only in case of a store operation.
Definition: peerstore.h:63
Message carrying a PEERSTORE result message.
Definition: peerstore.h:96
uint32_t result
Options, needed only in case of a store operation.
Definition: peerstore.h:111
uint32_t rid
Request id.
Definition: peerstore.h:105
struct GNUNET_PEERSTORE_Record * record
The record that was stored.
uint32_t rid
The request ID.
struct PeerstoreClient * pc
The client.