GNUnet 0.21.1
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
27#include "gnunet_protocols.h"
28#include "platform.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 "Synching 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
500static void
502{
503 struct GNUNET_MQ_Envelope *env;
504 struct PeerstoreResultMessage *endmsg;
505
507 if (! ic->send_end)
508 return;
509 /* No more records */
510
512 endmsg->rid = htons (ic->request_id);
513 endmsg->result = htonl (GNUNET_OK);
514 GNUNET_MQ_send (ic->pc->mq, env);
515 GNUNET_free (ic->key);
518 GNUNET_free (ic);
519 return;
520}
521
522
523
530static void
531run_iteration_round (struct Iteration *ic, uint64_t limit)
532{
533 struct IterationProcResult proc;
536
537 memset (&proc, 0, sizeof(proc));
539 "Asked to return up to %llu records at position %llu\n",
540 (unsigned long long) limit,
541 (unsigned long long) ic->seq);
542 proc.ic = ic;
543 proc.limit = limit;
547 ic->sub_system,
548 (GNUNET_YES == ic->peer_set) ? &ic->peer :
549 NULL,
550 ic->key,
551 ic->seq,
552 proc.limit,
554 &proc));
557 if (0 == proc.limit)
559 "Returned %llu results, more results available\n",
560 (unsigned long long) limit);
561 ic->send_end = (0 != proc.limit);
563}
564
565
573static int
574check_iterate_start (void *cls, const struct
576{
577 uint16_t ss_size;
578 uint16_t key_size;
579 uint16_t size;
580
581 ss_size = ntohs (srm->sub_system_size);
582 key_size = ntohs (srm->key_size);
583 size = ntohs (srm->header.size);
584
585 if (size < key_size + ss_size + sizeof(*srm))
586 {
587 GNUNET_break (0);
588 return GNUNET_SYSERR;
589 }
590 return GNUNET_OK;
591}
592
593
600static void
602 srm)
603{
604 struct Iteration *ic = GNUNET_new (struct Iteration);
605 uint16_t ss_size;
606 char *ptr;
607
608 ss_size = ntohs (srm->sub_system_size);
609
610 ic->pc = cls;
611 ic->request_id = ntohs (srm->rid);
612 ic->offset = 0;
613 ic->peer_set = (ntohs (srm->peer_set)) ? GNUNET_YES : GNUNET_NO;
614 if (GNUNET_YES == ic->peer_set)
615 ic->peer = srm->peer;
616 ptr = (char*) &srm[1];
617 ic->sub_system = GNUNET_strdup (ptr);
618 ptr += ss_size;
619 if (0 < ntohs (srm->key_size))
620 ic->key = GNUNET_strdup (ptr);
622 "Iterate request: ss `%s', peer `%s', key `%s'\n",
623 ic->sub_system,
624 GNUNET_i2s (&ic->peer),
625 (NULL == ic->key) ? "NULL" : ic->key);
627 ic->pc->op_tail,
628 ic);
629 run_iteration_round (ic, 1);
630}
631
632
639static void
641 const struct PeerstoreIterationStopMessage *zis_msg)
642{
643 struct PeerstoreClient *pc = cls;
644 struct Iteration *ic;
645 uint32_t rid;
646
648 "Received ITERATION_STOP message\n");
649 rid = ntohs (zis_msg->rid);
650 for (ic = pc->op_head; NULL != ic; ic = ic->next)
651 if (ic->request_id == rid)
652 break;
653 if (NULL == ic)
654 {
655 GNUNET_break (0);
657 return;
658 }
659 GNUNET_CONTAINER_DLL_remove (pc->op_head, pc->op_tail, ic);
660 GNUNET_free (ic);
662}
663
664
671static void
673 const struct PeerstoreIterationNextMessage *is_msg)
674{
675 struct PeerstoreClient *pc = cls;
676 struct Iteration *ic;
677 uint32_t rid;
678 uint64_t limit;
679
681 "Received ITERATION_NEXT message\n");
682 rid = ntohs (is_msg->rid);
683 limit = GNUNET_ntohll (is_msg->limit);
684 for (ic = pc->op_head; NULL != ic; ic = ic->next)
685 if (ic->request_id == rid)
686 break;
687 if (NULL == ic)
688 {
690 "Not in iteration...\n");
691 GNUNET_break (0);
693 return;
694 }
696 "Found iteration...\n");
697 run_iteration_round (ic, limit);
698}
699
700
706static void
707monitor_iteration_next (void *cls);
708
709
720static void
722 uint64_t seq,
723 const struct GNUNET_PEERSTORE_Record *record,
724 const char *emsg)
725{
726 struct Monitor *mc = cls;
727 struct GNUNET_MQ_Envelope *env;
728
729 GNUNET_assert (0 != seq);
730 mc->seq = seq;
731
732 if (NULL != emsg)
733 {
735 "Error iterating over peerstore: `%s'", emsg);
736 return;
737 }
738 if (NULL == record)
739 {
740 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
741 return;
742 }
743 if (0 == mc->limit)
744 {
745 /* what is this!? should never happen */
746 GNUNET_break (0);
747 return;
748 }
750 0,
751 record->sub_system,
752 &record->peer,
753 record->key,
754 record->value,
755 record->value_size,
756 record->expiry,
757 0,
759 GNUNET_MQ_send (mc->pc->mq, env);
760
762 "Sent records.\n");
763 mc->limit--;
764 mc->iteration_cnt--;
765 if ((0 == mc->iteration_cnt) && (0 != mc->limit))
766 {
767 /* We are done with the current iteration batch, AND the
768 client would right now accept more, so go again! */
769 GNUNET_assert (NULL == mc->task);
771 }
772}
773
774
780static void
782{
783 struct Monitor *mc = cls;
784 int ret;
785
786 mc->task = NULL;
787 GNUNET_assert (0 == mc->iteration_cnt);
788 if (mc->limit > 16)
789 mc->iteration_cnt = mc->limit / 2; /* leave half for monitor events */
790 else
791 mc->iteration_cnt = mc->limit; /* use it all */
793 "Running iteration\n");
795 mc->sub_system,
796 (GNUNET_YES == mc->peer_set) ? &mc->peer : NULL,
797 mc->key,
798 mc->seq,
799 mc->iteration_cnt,
801 mc);
802 if (GNUNET_SYSERR == ret)
803 {
804 GNUNET_free (mc->key);
805 GNUNET_free (mc->sub_system);
806 GNUNET_free (mc);
807 GNUNET_SERVICE_client_drop (mc->pc->client);
808 return;
809 }
810 if (GNUNET_NO == ret)
811 {
813 "Zone empty... syncing\n");
814 /* empty zone */
816 return;
817 }
818}
819
820
828static int
830{
831 uint16_t ss_size;
832 uint16_t key_size;
833 uint16_t size;
834
835 ss_size = ntohs (srm->sub_system_size);
836 key_size = ntohs (srm->key_size);
837 size = ntohs (srm->header.size);
838
839 if (size < key_size + ss_size + sizeof(*srm))
840 {
841 GNUNET_break (0);
842 return GNUNET_SYSERR;
843 }
844 return GNUNET_OK;
845}
846
847
854static void
856{
857 struct Monitor *mc = GNUNET_new (struct Monitor);
858
859 uint16_t ss_size;
860 char *ptr;
861
862 ss_size = ntohs (msm->sub_system_size);
863
864 mc->pc = cls;
865 mc->peer_set = (ntohs (msm->peer_set)) ? GNUNET_YES : GNUNET_NO;
866 if (GNUNET_YES == mc->peer_set)
867 mc->peer = msm->peer;
868 ptr = (char*) &msm[1];
869 if (0 < ss_size)
870 mc->sub_system = GNUNET_strdup (ptr);
871 ptr += ss_size;
872 if (0 < ntohs (msm->key_size))
873 mc->key = GNUNET_strdup (ptr);
875 "Monitor request: ss `%s', peer `%s', key `%s'\n",
876 mc->sub_system,
877 GNUNET_i2s (&mc->peer),
878 (NULL == mc->key) ? "NULL" : mc->key);
879 mc->in_first_iteration = (GNUNET_YES == ntohs (msm->iterate_first));
880 mc->limit = 1;
881 mc->peer_set = (ntohs (msm->peer_set)) ? GNUNET_YES : GNUNET_NO;
884 mc);
888 if (mc->in_first_iteration)
890 else
892}
893
894
901static void
903{
904 struct PeerstoreClient *pc = cls;
905 struct Monitor *mc;
906 uint64_t inc;
907
908 inc = GNUNET_ntohll (nm->limit);
910 "Received MONITOR_NEXT message with limit %llu\n",
911 (unsigned long long) inc);
912 for (mc = monitors_head; NULL != mc; mc = mc->next)
913 if (mc->pc == pc)
914 break;
915 if (NULL == mc)
916 {
917 GNUNET_break (0);
919 return;
920 }
922 if (mc->limit + inc < mc->limit)
923 {
924 GNUNET_break (0);
926 return;
927 }
928 mc->limit += inc;
929 if ((mc->in_first_iteration) && (mc->limit == inc))
930 {
931 /* We are still iterating, and the previous iteration must
932 have stopped due to the client's limit, so continue it! */
933 GNUNET_assert (NULL == mc->task);
935 }
936 GNUNET_assert (mc->iteration_cnt <= mc->limit);
937}
938
939
946static void
947store_record_continuation (void *cls, int success)
948{
949 struct StoreRecordContext *src = cls;
951 struct GNUNET_MQ_Envelope *env;
952
954 msg->rid = src->rid;
955 msg->result = htonl (success);
956 GNUNET_MQ_send (src->pc->mq, env);
957 watch_notifier (src->record);
960 GNUNET_free (src);
961}
962
963
971static int
972check_store (void *cls, const struct PeerstoreRecordMessage *srm)
973{
975
977 if (NULL == record)
978 {
979 GNUNET_break (0);
980 return GNUNET_SYSERR;
981 }
982 if ((NULL == record->sub_system) || (NULL == record->key))
983 {
984 GNUNET_break (0);
986 return GNUNET_SYSERR;
987 }
989 return GNUNET_OK;
990}
991
992
999static void
1000handle_store (void *cls, const struct PeerstoreRecordMessage *srm)
1001{
1002 struct PeerstoreClient *pc = cls;
1003 struct StoreRecordContext *src = GNUNET_new (struct StoreRecordContext);
1005 GNUNET_log (
1007 "Received a store request. Sub system `%s' Peer `%s Key `%s' Options: %u.\n",
1008 src->record->sub_system,
1009 GNUNET_i2s (&src->record->peer),
1010 src->record->key,
1011 (uint32_t) ntohl (srm->options));
1012 src->rid = srm->rid;
1013 src->pc = pc;
1014 if (GNUNET_OK != db->store_record (db->cls,
1015 src->record->sub_system,
1016 &src->record->peer,
1017 src->record->key,
1018 src->record->value,
1019 src->record->value_size,
1020 src->record->expiry,
1021 ntohl (srm->options),
1023 src))
1024 {
1025 GNUNET_break (0);
1027 GNUNET_free (src);
1029 GNUNET_free (pc);
1030 return;
1031 }
1032}
1033
1034
1043static void *
1045 struct GNUNET_SERVICE_Client *client,
1046 struct GNUNET_MQ_Handle *mq)
1047{
1048 struct PeerstoreClient *pc;
1049
1051 "A client %p connected\n", client);
1052 pc = GNUNET_new (struct PeerstoreClient);
1053 pc->client = client;
1054 pc->mq = mq;
1055 return pc;
1056}
1057
1058
1065static void
1068 void *app_cls)
1069{
1070 struct PeerstoreClient *pc = app_cls;
1071 struct Iteration *iter;
1072 struct Monitor *mo;
1073
1074 (void) cls;
1076 "Client %p disconnected.\n",
1077 client);
1078 for (mo = monitors_head; NULL != mo; mo = mo->next)
1079 {
1080 if (pc != mo->pc)
1081 continue;
1083 if (NULL != mo->task)
1084 {
1086 mo->task = NULL;
1087 }
1088 if (NULL != mo->sa_wait_warning)
1089 {
1091 mo->sa_wait_warning = NULL;
1092 }
1093 GNUNET_free (mo);
1094 break;
1095 }
1096 while (NULL != (iter = pc->op_head))
1097 {
1098 GNUNET_CONTAINER_DLL_remove (pc->op_head, pc->op_tail, iter);
1099 GNUNET_free (iter);
1100 }
1101 GNUNET_free (pc);
1102}
1103
1104
1105static void
1106store_hello_continuation (void *cls, int success)
1107{
1108 (void) cls;
1109
1110 if (GNUNET_OK != success)
1111 {
1113 "Error storing bootstrap hello!\n");
1114 GNUNET_break (0);
1115 }
1116}
1117
1118
1119static int
1120hosts_directory_scan_callback (void *cls, const char *fullname)
1121{
1122 (void) cls;
1123 ssize_t size_total;
1124 char buffer[GNUNET_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
1125 const struct GNUNET_MessageHeader *hello;
1127 const struct GNUNET_PeerIdentity *pid;
1128
1129 if (GNUNET_YES != GNUNET_DISK_file_test (fullname))
1130 return GNUNET_OK; /* ignore non-files */
1131
1132 size_total = GNUNET_DISK_fn_read (fullname, buffer, sizeof(buffer));
1134 "Read %d bytes from `%s'\n",
1135 (int) size_total,
1136 fullname);
1137 if ((size_total < 0) ||
1138 (((size_t) size_total) < sizeof(struct GNUNET_MessageHeader)))
1139 {
1141 _ ("Failed to parse HELLO in file `%s': %s\n"),
1142 fullname,
1143 "File has invalid size");
1144 return GNUNET_OK;
1145 }
1146 hello = (const struct GNUNET_MessageHeader *) &buffer[0];
1148 if (NULL == builder)
1149 {
1151 "Unable to parse HELLO message\n");
1152 return GNUNET_OK;
1153 }
1155
1157 "store contrib hello for peer %s\n",
1158 GNUNET_i2s (pid));
1159
1160 if (GNUNET_OK != db->store_record (db->cls,
1161 "peerstore",
1162 pid,
1164 hello,
1165 size_total,
1169 NULL))
1170 {
1171 GNUNET_break (0);
1172 }
1174 return GNUNET_OK;
1175}
1176
1177
1185static void
1186run (void *cls,
1187 const struct GNUNET_CONFIGURATION_Handle *c,
1189{
1190 char *database;
1191 int use_included;
1192 char *ip;
1193 char *peerdir;
1194
1195 cfg = c;
1196
1198 "peerstore",
1199 "DATABASE",
1200 &database))
1201 {
1203 "peerstore",
1204 "DATABASE");
1206 return;
1207 }
1208 GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_peerstore_%s", database);
1209 db = GNUNET_PLUGIN_load (db_lib_name, (void *) cfg);
1210 GNUNET_free (database);
1211 if (NULL == db)
1212 {
1214 _ ("Could not load database backend `%s'\n"),
1215 db_lib_name);
1217 return;
1218 }
1220
1222 "peerstore",
1223 "USE_INCLUDED_HELLOS");
1224 if (GNUNET_SYSERR == use_included)
1225 use_included = GNUNET_NO;
1226 if (GNUNET_YES == use_included)
1227 {
1229 GNUNET_asprintf (&peerdir, "%shellos", ip);
1230 GNUNET_free (ip);
1231
1233 _ ("Importing HELLOs from `%s'\n"),
1234 peerdir);
1235
1238 NULL);
1239 GNUNET_free (peerdir);
1240 }
1241 else
1242 {
1244 _ ("Skipping import of included HELLOs\n"));
1245 }
1247
1249}
1250
1251
1257 &client_disconnect_cb, NULL,
1259 struct PeerstoreRecordMessage, NULL),
1260 GNUNET_MQ_hd_var_size (iterate_start,
1262 struct PeerstoreIterationStartMessage, NULL),
1263 GNUNET_MQ_hd_fixed_size (iterate_stop,
1265 struct PeerstoreIterationStopMessage, NULL),
1266 GNUNET_MQ_hd_fixed_size (iterate_next,
1269 NULL),
1270 GNUNET_MQ_hd_var_size (monitor_start,
1273 NULL),
1274 GNUNET_MQ_hd_fixed_size (monitor_next,
1277 NULL),
1279
1280
1281/* 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 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.
@ 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:304
#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:562
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:1334
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
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:1299
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:1272
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the 'monitor' flag on this client.
Definition: service.c:2572
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2489
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2408
@ 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.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
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:252
Handle to a service.
Definition: service.c:118
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 intiated 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 intiated 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.