GNUnet 0.27.0
 
Loading...
Searching...
No Matches
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 {
296 GNUNET_break (NULL ==
298 db));
300 db_lib_name = NULL;
301 }
302 if (NULL != expire_task)
303 {
305 expire_task = NULL;
306 }
307 if (NULL != monitor_nc)
308 {
310 monitor_nc = NULL;
311 }
312}
313
314
315/* Forward declaration */
316static void
317expire_records_continuation (void *cls, int success);
318
319
323static void
344
345
352static void
353expire_records_continuation (void *cls, int success)
354{
355 if (success > 0)
356 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%d records expired.\n", success);
357 GNUNET_assert (NULL == expire_task);
362 NULL);
363}
364
365
371static void
373{
374 struct GNUNET_MQ_Envelope *env;
375 struct GNUNET_MessageHeader *sync;
377 "Syncing zone monitor %p\n", mc);
378
380 GNUNET_MQ_send (mc->pc->mq, env);
381 /* mark iteration done */
382 mc->in_first_iteration = GNUNET_NO;
383 mc->iteration_cnt = 0;
384}
385
386
392static void
394{
395 struct GNUNET_MQ_Envelope *env;
396 struct Monitor *mc;
397
398 // FIXME this is very inefficient, we may want to use a hash
399 // map again.
400 for (mc = monitors_head; NULL != mc; mc = mc->next)
401 {
402 if ((GNUNET_YES == mc->peer_set) &&
403 (0 != memcmp (&mc->peer, &record->peer, sizeof (record->peer))))
404 continue;
405 if ((NULL != mc->sub_system) &&
406 (0 != strcmp (mc->sub_system, record->sub_system)))
407 continue;
408 if ((NULL != mc->key) &&
409 (0 != strcmp (mc->key, record->key)))
410 continue;
411 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found watcher %p to update.\n", mc);
413 0,
414 record->sub_system,
415 &record->peer,
416 record->key,
417 record->value,
418 record->value_size,
419 record->expiry,
420 0,
422 GNUNET_MQ_send (mc->pc->mq, env);
423 }
424}
425
426
432{
436 struct Iteration *ic;
437
441 uint64_t limit;
442
443};
444
455static void
456iterate_proc (void *cls,
457 uint64_t seq,
458 const struct GNUNET_PEERSTORE_Record *record,
459 const char *emsg)
460{
461 struct IterationProcResult *proc = cls;
462 struct GNUNET_MQ_Envelope *env;
463
464 if (NULL != emsg)
465 {
467 "Error iterating over peerstore: `%s'", emsg);
468 return;
469 }
470 if (NULL == record)
471 {
472 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
473 return;
474 }
475 if (0 == proc->limit)
476 {
477 /* what is this!? should never happen */
478 GNUNET_break (0);
479 return;
480 }
481 proc->ic->seq = seq;
483 proc->ic->request_id,
484 record->sub_system,
485 &record->peer,
486 record->key,
487 record->value,
488 record->value_size,
489 record->expiry,
490 0,
492 GNUNET_MQ_send (proc->ic->pc->mq, env);
493 proc->limit--;
494}
495
496
497static void
499{
500 GNUNET_free (ic->key);
502 GNUNET_free (ic);
503}
504
505
512static void
514{
515 struct GNUNET_MQ_Envelope *env;
516 struct PeerstoreResultMessage *endmsg;
517
519 if (! ic->send_end)
520 return;
521 /* No more records */
522
524 endmsg->rid = htons (ic->request_id);
525 endmsg->result = htonl (GNUNET_OK);
526 GNUNET_MQ_send (ic->pc->mq, env);
529 return;
530}
531
532
539static void
540run_iteration_round (struct Iteration *ic, uint64_t limit)
541{
542 struct IterationProcResult proc;
545
546 memset (&proc, 0, sizeof(proc));
548 "Asked to return up to %llu records at position %llu\n",
549 (unsigned long long) limit,
550 (unsigned long long) ic->seq);
551 proc.ic = ic;
552 proc.limit = limit;
556 ic->sub_system,
557 (GNUNET_YES == ic->peer_set) ? &ic->peer :
558 NULL,
559 ic->key,
560 ic->seq,
561 proc.limit,
563 &proc));
566 if (0 == proc.limit)
568 "Returned %llu results, more results available\n",
569 (unsigned long long) limit);
570 ic->send_end = (0 != proc.limit);
572}
573
574
582static int
583check_iterate_start (void *cls, const struct
585{
586 uint16_t ss_size;
587 uint16_t key_size;
588 uint16_t size;
589
590 ss_size = ntohs (srm->sub_system_size);
591 key_size = ntohs (srm->key_size);
592 size = ntohs (srm->header.size);
593
594 if (size < key_size + ss_size + sizeof(*srm))
595 {
596 GNUNET_break (0);
597 return GNUNET_SYSERR;
598 }
599 return GNUNET_OK;
600}
601
602
609static void
611 srm)
612{
613 struct Iteration *ic = GNUNET_new (struct Iteration);
614 uint16_t ss_size;
615 char *ptr;
616
617 ss_size = ntohs (srm->sub_system_size);
618
619 ic->pc = cls;
620 ic->request_id = ntohs (srm->rid);
621 ic->offset = 0;
622 ic->peer_set = (ntohs (srm->peer_set)) ? GNUNET_YES : GNUNET_NO;
623 if (GNUNET_YES == ic->peer_set)
624 ic->peer = srm->peer;
625 ptr = (char*) &srm[1];
626 ic->sub_system = GNUNET_strdup (ptr);
627 ptr += ss_size;
628 if (0 < ntohs (srm->key_size))
629 ic->key = GNUNET_strdup (ptr);
631 "Iterate request: ss `%s', peer `%s', key `%s'\n",
632 ic->sub_system,
633 GNUNET_i2s (&ic->peer),
634 (NULL == ic->key) ? "NULL" : ic->key);
636 ic->pc->op_tail,
637 ic);
638 run_iteration_round (ic, 1);
639}
640
641
648static void
650 const struct PeerstoreIterationStopMessage *zis_msg)
651{
652 struct PeerstoreClient *pc = cls;
653 struct Iteration *ic;
654 uint32_t rid;
655
657 "Received ITERATION_STOP message\n");
658 rid = ntohs (zis_msg->rid);
659 for (ic = pc->op_head; NULL != ic; ic = ic->next)
660 if (ic->request_id == rid)
661 break;
662 if (NULL == ic)
663 {
665 "Iteration already finished.\n");
667 return;
668 }
669 GNUNET_CONTAINER_DLL_remove (pc->op_head, pc->op_tail, ic);
672}
673
674
681static void
683 const struct PeerstoreIterationNextMessage *is_msg)
684{
685 struct PeerstoreClient *pc = cls;
686 struct Iteration *ic;
687 uint32_t rid;
688 uint64_t limit;
689
691 "Received ITERATION_NEXT message\n");
692 rid = ntohs (is_msg->rid);
693 limit = GNUNET_ntohll (is_msg->limit);
694 for (ic = pc->op_head; NULL != ic; ic = ic->next)
695 if (ic->request_id == rid)
696 break;
697 if (NULL == ic)
698 {
700 "Not in iteration...\n");
701 GNUNET_break (0);
703 return;
704 }
706 "Found iteration...\n");
707 run_iteration_round (ic, limit);
708}
709
710
716static void
717monitor_iteration_next (void *cls);
718
719
730static void
732 uint64_t seq,
733 const struct GNUNET_PEERSTORE_Record *record,
734 const char *emsg)
735{
736 struct Monitor *mc = cls;
737 struct GNUNET_MQ_Envelope *env;
738
739 GNUNET_assert (0 != seq);
740 mc->seq = seq;
741
742 if (NULL != emsg)
743 {
745 "Error iterating over peerstore: `%s'", emsg);
746 return;
747 }
748 if (NULL == record)
749 {
750 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
751 return;
752 }
753 if (0 == mc->limit)
754 {
755 /* what is this!? should never happen */
756 GNUNET_break (0);
757 return;
758 }
760 0,
761 record->sub_system,
762 &record->peer,
763 record->key,
764 record->value,
765 record->value_size,
766 record->expiry,
767 0,
769 GNUNET_MQ_send (mc->pc->mq,
770 env);
772 "Sent records.\n");
773 mc->limit--;
774 mc->iteration_cnt--;
775 if ( (0 == mc->iteration_cnt) &&
776 (0 != mc->limit) )
777 {
778 /* We are done with the current iteration batch, AND the
779 client would right now accept more, so go again! */
780 GNUNET_assert (NULL == mc->task);
782 mc);
783 }
784}
785
786
792static void
794{
795 struct Monitor *mc = cls;
796 int ret;
797
798 mc->task = NULL;
799 GNUNET_assert (0 == mc->iteration_cnt);
800 if (mc->limit > 16)
801 mc->iteration_cnt = mc->limit / 2; /* leave half for monitor events */
802 else
803 mc->iteration_cnt = mc->limit; /* use it all */
805 "Running iteration\n");
807 mc->sub_system,
808 (GNUNET_YES == mc->peer_set) ? &mc->peer : NULL,
809 mc->key,
810 mc->seq,
811 mc->iteration_cnt,
813 mc);
814 if (GNUNET_SYSERR == ret)
815 {
816 if (NULL != mc->task)
817 {
819 mc->task = NULL;
820 }
823 mc);
824 GNUNET_free (mc->key);
825 GNUNET_free (mc->sub_system);
826 GNUNET_SERVICE_client_drop (mc->pc->client);
827 GNUNET_free (mc);
828 return;
829 }
830 if (GNUNET_NO == ret)
831 {
833 "Zone empty... syncing\n");
834 /* empty zone */
836 return;
837 }
838}
839
840
848static int
850 const struct PeerstoreMonitorStartMessage *srm)
851{
852 uint16_t ss_size;
853 uint16_t key_size;
854 uint16_t size;
855
856 ss_size = ntohs (srm->sub_system_size);
857 key_size = ntohs (srm->key_size);
858 size = ntohs (srm->header.size);
859 if (size < key_size + ss_size + sizeof(*srm))
860 {
861 GNUNET_break (0);
862 return GNUNET_SYSERR;
863 }
864 return GNUNET_OK;
865}
866
867
874static void
876 const struct PeerstoreMonitorStartMessage *msm)
877{
878 struct PeerstoreClient *pc = cls;
879 struct Monitor *mc;
880 uint16_t ss_size;
881 char *ptr;
882
883 if (NULL == monitor_nc)
884 {
885 GNUNET_break (0);
887 return; /* post-shutdown */
888 }
889 mc = GNUNET_new (struct Monitor);
890 ss_size = ntohs (msm->sub_system_size);
891 mc->pc = cls;
892 mc->peer_set = (ntohs (msm->peer_set)) ? GNUNET_YES : GNUNET_NO;
893 if (GNUNET_YES == mc->peer_set)
894 mc->peer = msm->peer;
895 ptr = (char*) &msm[1];
896 if (0 < ss_size)
897 mc->sub_system = GNUNET_strdup (ptr);
898 ptr += ss_size;
899 if (0 < ntohs (msm->key_size))
900 mc->key = GNUNET_strdup (ptr);
902 "Monitor request: ss `%s', peer `%s', key `%s'\n",
903 mc->sub_system,
904 GNUNET_i2s (&mc->peer),
905 (NULL == mc->key) ? "NULL" : mc->key);
906 mc->in_first_iteration = (GNUNET_YES == ntohs (msm->iterate_first));
907 mc->limit = 1;
908 mc->peer_set = (ntohs (msm->peer_set)) ? GNUNET_YES : GNUNET_NO;
911 mc);
915 mc->pc->mq);
916 if (mc->in_first_iteration)
918 mc);
919 else
921}
922
923
930static void
932 const struct PeerstoreMonitorNextMessage *nm)
933{
934 struct PeerstoreClient *pc = cls;
935 struct Monitor *mc;
936 uint64_t inc;
937
938 inc = GNUNET_ntohll (nm->limit);
940 "Received MONITOR_NEXT message with limit %llu\n",
941 (unsigned long long) inc);
942 for (mc = monitors_head; NULL != mc; mc = mc->next)
943 if (mc->pc == pc)
944 break;
945 if (NULL == mc)
946 {
947 GNUNET_break (0);
949 return;
950 }
952 if (mc->limit + inc < mc->limit)
953 {
954 GNUNET_break (0);
956 return;
957 }
958 mc->limit += inc;
959 if ((mc->in_first_iteration) && (mc->limit == inc))
960 {
961 /* We are still iterating, and the previous iteration must
962 have stopped due to the client's limit, so continue it! */
963 GNUNET_assert (NULL == mc->task);
965 }
966 GNUNET_assert (mc->iteration_cnt <= mc->limit);
967}
968
969
976static void
977store_record_continuation (void *cls, int success)
978{
979 struct StoreRecordContext *src = cls;
981 struct GNUNET_MQ_Envelope *env;
982
984 msg->rid = src->rid;
985 msg->result = htonl (success);
986 GNUNET_MQ_send (src->pc->mq, env);
987 watch_notifier (src->record);
990 GNUNET_free (src);
991}
992
993
1001static int
1002check_store (void *cls, const struct PeerstoreRecordMessage *srm)
1003{
1005
1007 if (NULL == record)
1008 {
1009 GNUNET_break (0);
1010 return GNUNET_SYSERR;
1011 }
1012 if ((NULL == record->sub_system) || (NULL == record->key))
1013 {
1014 GNUNET_break (0);
1016 return GNUNET_SYSERR;
1017 }
1019 return GNUNET_OK;
1020}
1021
1022
1029static void
1030handle_store (void *cls, const struct PeerstoreRecordMessage *srm)
1031{
1032 struct PeerstoreClient *pc = cls;
1033 struct StoreRecordContext *src = GNUNET_new (struct StoreRecordContext);
1035 GNUNET_log (
1037 "Received a store request. Sub system `%s' Peer `%s Key `%s' Options: %u.\n",
1038 src->record->sub_system,
1039 GNUNET_i2s (&src->record->peer),
1040 src->record->key,
1041 (uint32_t) ntohl (srm->options));
1042 src->rid = srm->rid;
1043 src->pc = pc;
1044 if (GNUNET_OK != db->store_record (db->cls,
1045 src->record->sub_system,
1046 &src->record->peer,
1047 src->record->key,
1048 src->record->value,
1049 src->record->value_size,
1050 src->record->expiry,
1051 ntohl (srm->options),
1053 src))
1054 {
1055 GNUNET_break (0);
1057 GNUNET_free (src);
1059 GNUNET_free (pc);
1060 return;
1061 }
1062}
1063
1064
1073static void *
1075 struct GNUNET_SERVICE_Client *client,
1076 struct GNUNET_MQ_Handle *mq)
1077{
1078 struct PeerstoreClient *pc;
1079
1081 "A client %p connected\n", client);
1082 pc = GNUNET_new (struct PeerstoreClient);
1083 pc->client = client;
1084 pc->mq = mq;
1085 return pc;
1086}
1087
1088
1095static void
1098 void *app_cls)
1099{
1100 struct PeerstoreClient *pc = app_cls;
1101 struct Iteration *iter;
1102 struct Monitor *mo;
1103
1104 (void) cls;
1106 "Client %p disconnected.\n",
1107 client);
1108 for (mo = monitors_head; NULL != mo; mo = mo->next)
1109 {
1110 if (pc != mo->pc)
1111 continue;
1114 mo);
1115 if (NULL != mo->task)
1116 {
1118 mo->task = NULL;
1119 }
1120 if (NULL != mo->sa_wait_warning)
1121 {
1123 mo->sa_wait_warning = NULL;
1124 }
1125 GNUNET_free (mo->sub_system);
1126 GNUNET_free (mo->key);
1127 GNUNET_free (mo);
1128 break;
1129 }
1130 while (NULL != (iter = pc->op_head))
1131 {
1133 pc->op_tail,
1134 iter);
1135 destroy_iteration (iter);
1136 }
1137 GNUNET_free (pc);
1138}
1139
1140
1141static void
1142store_hello_continuation (void *cls, int success)
1143{
1144 (void) cls;
1145
1146 if (GNUNET_OK != success)
1147 {
1149 "Error storing bootstrap hello!\n");
1150 GNUNET_break (0);
1151 }
1152}
1153
1154
1155static int
1156hosts_directory_scan_callback (void *cls, const char *fullname)
1157{
1158 ssize_t size_total;
1159 char buffer[GNUNET_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
1160 const struct GNUNET_MessageHeader *hello;
1161 struct GNUNET_MQ_Envelope *env;
1162 struct GNUNET_HELLO_Parser *parser;
1163 const struct GNUNET_PeerIdentity *pid;
1164 struct GNUNET_TIME_Absolute et;
1165 (void) cls;
1166
1167 if (GNUNET_YES != GNUNET_DISK_file_test (fullname))
1168 return GNUNET_OK; /* ignore non-files */
1169
1170 size_total = GNUNET_DISK_fn_read (fullname, buffer, sizeof(buffer));
1172 "Read %d bytes from `%s'\n",
1173 (int) size_total,
1174 fullname);
1175 if ((size_total < 0) ||
1176 (((size_t) size_total) < sizeof(struct GNUNET_MessageHeader)))
1177 {
1179 _ ("Failed to parse HELLO in file `%s': %s\n"),
1180 fullname,
1181 "File has invalid size");
1182 return GNUNET_OK;
1183 }
1184 parser = GNUNET_HELLO_parser_from_url (buffer);
1185 if (NULL == parser)
1186 {
1188 "Unable to parse HELLO url\n");
1189 return GNUNET_OK;
1190 }
1192 hello = GNUNET_MQ_env_get_msg (env);
1196 "store contrib hello for peer %s\n",
1197 GNUNET_i2s (pid));
1198
1199 if (GNUNET_OK != db->store_record (db->cls,
1200 "peerstore",
1201 pid,
1203 hello,
1204 size_total,
1205 et,
1208 NULL))
1209 {
1210 GNUNET_break (0);
1211 }
1212 GNUNET_free (env);
1213 GNUNET_HELLO_parser_free (parser);
1214 return GNUNET_OK;
1215}
1216
1217
1225static void
1226run (void *cls,
1227 const struct GNUNET_CONFIGURATION_Handle *c,
1229{
1230 char *database;
1231 int use_included;
1232 char *ip;
1233 char *peerdir;
1234
1235 cfg = c;
1236
1237 if (GNUNET_OK !=
1239 "peerstore",
1240 "DATABASE",
1241 &database))
1242 {
1244 "peerstore",
1245 "DATABASE");
1247 return;
1248 }
1250 "libgnunet_plugin_peerstore_%s",
1251 database);
1254 (void *) cfg);
1255 GNUNET_free (database);
1256 if (NULL == db)
1257 {
1259 _ ("Could not load database backend `%s'\n"),
1260 db_lib_name);
1262 return;
1263 }
1265 NULL);
1267 "peerstore",
1268 "USE_INCLUDED_HELLOS");
1269 if (GNUNET_SYSERR == use_included)
1270 use_included = GNUNET_NO;
1271 if (GNUNET_YES == use_included)
1272 {
1275 GNUNET_asprintf (&peerdir, "%shellos", ip);
1276 GNUNET_free (ip);
1277
1279 _ ("Importing HELLOs from `%s'\n"),
1280 peerdir);
1283 NULL);
1284 GNUNET_free (peerdir);
1285 }
1286 else
1287 {
1289 _ ("Skipping import of included HELLOs\n"));
1290 }
1293 NULL);
1294}
1295
1296
1303 &client_disconnect_cb, NULL,
1305 struct PeerstoreRecordMessage, NULL),
1306 GNUNET_MQ_hd_var_size (iterate_start,
1308 struct PeerstoreIterationStartMessage, NULL),
1309 GNUNET_MQ_hd_fixed_size (iterate_stop,
1311 struct PeerstoreIterationStopMessage, NULL),
1312 GNUNET_MQ_hd_fixed_size (iterate_next,
1315 NULL),
1316 GNUNET_MQ_hd_var_size (monitor_start,
1319 NULL),
1320 GNUNET_MQ_hd_fixed_size (monitor_next,
1323 NULL),
1325
1326
1327/* end of gnunet-service-peerstore.c */
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:38
static int ret
Final status code.
Definition gnunet-arm.c:93
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
struct GNUNET_SCHEDULER_Task * shutdown_task
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.
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 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:557
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:720
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition disk.c:881
#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_parser_free(struct GNUNET_HELLO_Parser *parser)
Release resources of a builder.
Definition hello-uri.c:380
struct GNUNET_MQ_Envelope * GNUNET_HELLO_parser_to_env(const struct GNUNET_HELLO_Parser *parser)
Generate envelope with GNUnet HELLO message (including peer ID) from a parser.
Definition hello-uri.c:939
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:633
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_url(const char *url)
Parse GNUnet HELLO url.
Definition hello-uri.c:699
#define GNUNET_log(kind,...)
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
#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.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
const struct GNUNET_MessageHeader * GNUNET_MQ_env_get_msg(const struct GNUNET_MQ_Envelope *env)
Obtain message contained in envelope.
Definition mq.c:896
#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
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
char * GNUNET_OS_installation_get_path(const struct GNUNET_OS_ProjectData *pd, 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 struct GNUNET_OS_ProjectData *pd, const char *library_name, void *arg)
Setup plugin (runs the "init" callback and returns whatever "init" returned).
Definition plugin.c:221
void * GNUNET_PLUGIN_unload(const char *library_name, void *arg)
Unload plugin (runs the "done" callback and returns whatever "done" returned).
Definition plugin.c:277
#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:572
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:1345
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1310
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1283
#define GNUNET_SERVICE_MAIN(pd, service_name, service_options, init_cb, connect_cb, disconnect_cb, cls,...)
Creates the "main" function for a GNUnet service.
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the 'monitor' flag on this client.
Definition service.c:2528
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition service.c:2463
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition service.c:2434
@ 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:438
#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:486
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:548
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:179
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
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 parsing HELLOs.
Definition hello-uri.c:233
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)
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:141
Handle to a client that is connected to a service.
Definition service.c:249
Handle to a service.
Definition service.c:116
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.