GNUnet 0.22.1
gnunet-service-namestore.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012, 2013, 2014, 2018 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_error_codes.h"
29#include "gnunet_protocols.h"
30#include "gnunet_util_lib.h"
33#include "namestore.h"
34
35#define LOG_STRERROR_FILE(kind, syscall, filename) \
36 GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
37
41#define MONITOR_STALL_WARN_DELAY GNUNET_TIME_UNIT_MINUTES
42
46#define NC_SIZE 16
47
51struct NamestoreClient;
52
53
58{
63
68
73
78
83
88
96 uint64_t seq;
97
101 uint32_t request_id;
102
110 uint32_t offset;
111
118};
119
124{
129
134
139
144
150
156};
157
158
163{
168
173
178
183
188
193
198
203
211 uint64_t seq;
212
217 uint64_t limit;
218
226
231
236
244};
245
246
252{
257
262
267
271 uint32_t rid;
272
276 uint16_t rd_set_pos;
277
281 uint16_t rd_set_count;
282
287
292 const struct RecordSet *rs;
293
298
299};
300
301
306{
311
316
321};
322
327
331static const struct GNUNET_CRYPTO_PrivateKey zero;
332
337
342
346static char *db_lib_name;
347
352
353
358
363
367static struct StoreActivity *sa_head;
368
372static struct StoreActivity *sa_tail;
373
378
383
389static void
390cleanup_task (void *cls)
391{
392 (void) cls;
393 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n");
394 if (NULL != monitor_nc)
395 {
397 monitor_nc = NULL;
398 }
399 if (NULL != statistics)
400 {
402 statistics = NULL;
403 }
406 db_lib_name = NULL;
407}
408
409
415static void
417{
419 GNUNET_free (sa);
420}
421
422
435static void
436lookup_nick_it (void *cls,
437 uint64_t seq,
438 const char *editor_hint,
439 const struct GNUNET_CRYPTO_PrivateKey *private_key,
440 const char *label,
441 unsigned int rd_count,
442 const struct GNUNET_GNSRECORD_Data *rd)
443{
444 struct GNUNET_GNSRECORD_Data **res = cls;
445
446 (void) private_key;
447 GNUNET_assert (0 != seq);
448 if (0 != strcmp (label, GNUNET_GNS_EMPTY_LABEL_AT))
449 {
450 GNUNET_break (0);
451 return;
452 }
453 for (unsigned int c = 0; c < rd_count; c++)
454 {
456 {
457 (*res) =
458 GNUNET_malloc (rd[c].data_size + sizeof(struct GNUNET_GNSRECORD_Data));
459 (*res)->data = &(*res)[1];
460 GNUNET_memcpy ((void *) (*res)->data, rd[c].data, rd[c].data_size);
461 (*res)->data_size = rd[c].data_size;
462 (*res)->expiration_time = rd[c].expiration_time;
463 (*res)->flags = rd[c].flags;
464 (*res)->record_type = GNUNET_GNSRECORD_TYPE_NICK;
465 return;
466 }
467 }
468 (*res) = NULL;
469}
470
471
478static void
480 const struct GNUNET_GNSRECORD_Data *nick)
481{
482 struct NickCache *oldest;
483
484 oldest = NULL;
485 for (unsigned int i = 0; i < NC_SIZE; i++)
486 {
487 struct NickCache *pos = &nick_cache[i];
488
489 if ((NULL == oldest) ||
491 oldest = pos;
492 if (0 == GNUNET_memcmp (zone, &pos->zone))
493 {
494 oldest = pos;
495 break;
496 }
497 }
498 GNUNET_free (oldest->rd);
499 oldest->zone = *zone;
500 if (NULL != nick)
501 {
502 oldest->rd = GNUNET_malloc (sizeof(*nick) + nick->data_size);
503 *oldest->rd = *nick;
504 oldest->rd->data = &oldest->rd[1];
505 memcpy (&oldest->rd[1], nick->data, nick->data_size);
506 }
507 else
508 {
509 oldest->rd = NULL;
510 }
512}
513
514
522static struct GNUNET_GNSRECORD_Data *
524{
526 struct GNUNET_GNSRECORD_Data *nick;
527 int res;
528
529 /* check cache first */
530 for (unsigned int i = 0; i < NC_SIZE; i++)
531 {
532 struct NickCache *pos = &nick_cache[i];
533 if ((NULL != pos->rd) && (0 == GNUNET_memcmp (zone, &pos->zone)))
534 {
535 if (NULL == pos->rd)
536 return NULL;
537 nick = GNUNET_malloc (sizeof(*nick) + pos->rd->data_size);
538 *nick = *pos->rd;
539 nick->data = &nick[1];
540 memcpy (&nick[1], pos->rd->data, pos->rd->data_size);
542 return nick;
543 }
544 }
545
546 nick = NULL;
548 zone,
551 &nick);
552 if ((GNUNET_OK != res) || (NULL == nick))
553 {
554#if ! defined(GNUNET_CULL_LOGGING)
555 static int do_log = GNUNET_LOG_CALL_STATUS;
556
557 if (0 == do_log)
559 "namestore",
560 __FILE__,
561 __FUNCTION__,
562 __LINE__);
563 if (1 == do_log)
564 {
567 "No nick name set for zone `%s'\n",
569 }
570#endif
571 /* update cache */
572 cache_nick (zone, NULL);
573 return NULL;
574 }
575
576 /* update cache */
577 cache_nick (zone, nick);
578 return nick;
579}
580
581
597static void
599 unsigned int rd2_length,
600 const struct GNUNET_GNSRECORD_Data *rd2,
601 unsigned int *rdc_res,
602 struct GNUNET_GNSRECORD_Data **rd_res)
603{
604 uint64_t latest_expiration;
605 size_t req;
606 char *data;
607 size_t data_offset;
608 struct GNUNET_GNSRECORD_Data *target;
609
610 (*rdc_res) = 1 + rd2_length;
611 if (0 == 1 + rd2_length)
612 {
613 GNUNET_break (0);
614 (*rd_res) = NULL;
615 return;
616 }
617 req = sizeof(struct GNUNET_GNSRECORD_Data) + nick_rd->data_size;
618 for (unsigned int i = 0; i < rd2_length; i++)
619 {
620 const struct GNUNET_GNSRECORD_Data *orig = &rd2[i];
621
622 if (req + sizeof(struct GNUNET_GNSRECORD_Data) + orig->data_size < req)
623 {
624 GNUNET_break (0);
625 (*rd_res) = NULL;
626 return;
627 }
628 req += sizeof(struct GNUNET_GNSRECORD_Data) + orig->data_size;
629 }
630 target = GNUNET_malloc (req);
631 (*rd_res) = target;
632 data = (char *) &target[1 + rd2_length];
633 data_offset = 0;
634 latest_expiration = 0;
635 for (unsigned int i = 0; i < rd2_length; i++)
636 {
637 const struct GNUNET_GNSRECORD_Data *orig = &rd2[i];
638
640 {
641 if ((GNUNET_TIME_absolute_get ().abs_value_us + orig->expiration_time) >
642 latest_expiration)
643 latest_expiration = orig->expiration_time;
644 }
645 else if (orig->expiration_time > latest_expiration)
646 latest_expiration = orig->expiration_time;
647 target[i] = *orig;
648 target[i].data = (void *) &data[data_offset];
649 GNUNET_memcpy (&data[data_offset], orig->data, orig->data_size);
650 data_offset += orig->data_size;
651 }
652 /* append nick */
653 target[rd2_length] = *nick_rd;
654 /* Mark as supplemental */
655 target[rd2_length].flags = nick_rd->flags | GNUNET_GNSRECORD_RF_SUPPLEMENTAL;
656 target[rd2_length].expiration_time = latest_expiration;
657 target[rd2_length].data = (void *) &data[data_offset];
658 GNUNET_memcpy (&data[data_offset], nick_rd->data, nick_rd->data_size);
659 data_offset += nick_rd->data_size;
660 GNUNET_assert (req == (sizeof(struct GNUNET_GNSRECORD_Data)) * (*rdc_res)
661 + data_offset);
662}
663
664
677static int
679 uint32_t request_id,
680 const struct
681 GNUNET_CRYPTO_PrivateKey *zone_key,
682 const char *name,
683 unsigned int rd_count,
684 const struct GNUNET_GNSRECORD_Data *rd,
686{
687 struct GNUNET_MQ_Envelope *env;
688 struct RecordResultMessage *zir_msg;
689 struct GNUNET_GNSRECORD_Data *nick;
691 struct GNUNET_GNSRECORD_Data rd_nf[rd_count];
692 struct GNUNET_TIME_Absolute block_exp;
693 unsigned int res_count;
694 unsigned int rd_nf_count;
695 size_t name_len;
696 size_t key_len;
697 ssize_t rd_ser_len;
698 char *name_tmp;
699 char *rd_ser;
700 char *emsg;
701
702 block_exp = GNUNET_TIME_UNIT_ZERO_ABS;
703 nick = get_nick_record (zone_key);
705
707 rd,
708 rd_count,
709 rd_nf,
710 &rd_nf_count,
711 &block_exp,
712 filter,
713 &emsg))
714 {
715 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
716 GNUNET_free (emsg);
717 GNUNET_assert (0);
718 }
719
724 if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT)))
725 {
726 nick->flags =
728 merge_with_nick_records (nick, rd_nf_count, rd_nf, &res_count, &res);
729 }
730 else
731 {
732 res_count = rd_nf_count;
733 res = (struct GNUNET_GNSRECORD_Data *) rd_nf;
734 }
735 if (NULL != nick)
736 GNUNET_free (nick);
737
738 if (0 == res_count)
739 {
740 if (rd_nf != res)
742 return 0;
743 }
745
746
747 name_len = strlen (name) + 1;
748 rd_ser_len = GNUNET_GNSRECORD_records_get_size (res_count, res);
749 if (rd_ser_len < 0)
750 {
751 if (rd_nf != res)
753 GNUNET_break (0);
755 return 0;
756 }
757 if (((size_t) rd_ser_len) >= UINT16_MAX - name_len - sizeof(*zir_msg))
758 {
759 if (rd_nf != res)
761 GNUNET_break (0);
763 return 0;
764 }
765 key_len = GNUNET_CRYPTO_private_key_get_length (zone_key);
766 env = GNUNET_MQ_msg_extra (zir_msg,
767 name_len + rd_ser_len + key_len,
769 zir_msg->gns_header.r_id = htonl (request_id);
770 zir_msg->name_len = htons (name_len);
771 zir_msg->rd_count = htons (res_count);
772 zir_msg->rd_len = htons ((uint16_t) rd_ser_len);
773 zir_msg->key_len = htons (key_len);
775 &zir_msg[1],
776 key_len);
777 zir_msg->expire = GNUNET_TIME_absolute_hton (block_exp);
778 name_tmp = (char *) &zir_msg[1] + key_len;
779 GNUNET_memcpy (name_tmp, name, name_len);
780 rd_ser = &name_tmp[name_len];
782 rd_ser_len ==
783 GNUNET_GNSRECORD_records_serialize (res_count, res, rd_ser_len, rd_ser));
785 "Sending RECORD_RESULT message with %u records\n",
786 res_count);
788 "Record sets sent to clients",
789 1,
790 GNUNET_NO);
791 GNUNET_MQ_send (nc->mq, env);
792 if (rd_nf != res)
794 return res_count;
795}
796
797
805static void
807 enum GNUNET_ErrorCode ec,
808 uint32_t rid)
809{
810 struct GNUNET_MQ_Envelope *env;
811 struct NamestoreResponseMessage *rcr_msg;
812
813 GNUNET_assert (NULL != nc);
815 "Sending GENERIC_RESPONSE message\n");
817 "Store requests completed",
818 1,
819 GNUNET_NO);
820 env = GNUNET_MQ_msg (rcr_msg,
822 rcr_msg->gns_header.r_id = htonl (rid);
823 rcr_msg->ec = htonl (ec);
824 GNUNET_MQ_send (nc->mq, env);
825}
826
827
834static void
836{
837 struct GNUNET_MQ_Envelope *env;
838 struct GNUNET_NAMESTORE_Header *em;
839
841 if (! zi->send_end)
842 return;
843 /* send empty response to indicate end of list */
845 em->r_id = htonl (zi->request_id);
846 GNUNET_MQ_send (zi->nc->mq, env);
847
849 GNUNET_free (zi);
850}
851
852
858static void
860{
861 struct ZoneMonitor *zm = cls;
862
864 "No response from monitor since %s\n",
865 GNUNET_STRINGS_absolute_time_to_string (zm->sa_waiting_start));
868 zm);
869}
870
871
877static int
879 int call_continue)
880{
881 const struct RecordSet *rd_set = sa->rs;
882 unsigned int rd_count;
883 size_t name_len;
884 size_t rd_ser_len;
885 const char *name;
886 const char *rd_ser;
887 const char *buf;
888
889 buf = (const char *) &sa[1];
890 for (int i = sa->rd_set_pos; i < sa->rd_set_count; i++)
891 {
892 rd_set = (struct RecordSet *) buf;
893 name_len = ntohs (rd_set->name_len);
894 rd_count = ntohs (rd_set->rd_count);
895 rd_ser_len = ntohs (rd_set->rd_len);
896 name = (const char *) &rd_set[1];
897 buf += sizeof (struct RecordSet) + name_len + rd_ser_len;
898 rd_ser = &name[name_len];
899 {
901
902 /* We did this before, must succeed again */
904 GNUNET_OK ==
906 rd));
907
909 "Checking monitors watching for `%s'\n",
910 name);
911 for (struct ZoneMonitor *zm = sa->zm_pos; NULL != zm; zm = sa->zm_pos)
912 {
913 if ((0 != GNUNET_memcmp (&sa->private_key, &zm->zone)) &&
914 (0 != GNUNET_memcmp (&zm->zone, &zero)))
915 {
916 sa->zm_pos = zm->next; /* not interesting to this monitor */
917 continue;
918 }
919 if (zm->limit == zm->iteration_cnt)
920 {
921 zm->sa_waiting = GNUNET_YES;
922 zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
923 if (NULL != zm->sa_wait_warning)
924 GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
925 zm->sa_wait_warning =
928 zm);
930 "Monitor is blocking client for `%s'\n",
931 name);
932 return GNUNET_NO; /* blocked on zone monitor */
933 }
935 "Notifying monitor about changes under label `%s'\n",
936 name);
938 0,
939 &sa->private_key,
940 name,
941 rd_count,
942 rd,
943 zm->filter))
944 zm->limit--;
945 sa->zm_pos = zm->next;
946 }
947 sa->rd_set_pos++;
948 }
949 }
950 if (GNUNET_YES == call_continue)
954 return GNUNET_OK;
955}
956
957
966static void
968 struct GNUNET_SERVICE_Client *client,
969 void *app_ctx)
970{
971 struct NamestoreClient *nc = app_ctx;
972 struct ZoneIteration *no;
973 struct StoreActivity *sa = sa_head;
974 struct StoreActivity *sn;
975
976 (void) cls;
977 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
978 for (struct ZoneMonitor *zm = monitor_head; NULL != zm; zm = zm->next)
979 {
980 if (nc != zm->nc)
981 continue;
983 if (NULL != zm->task)
984 {
986 zm->task = NULL;
987 }
988 if (NULL != zm->sa_wait_warning)
989 {
990 GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
991 zm->sa_wait_warning = NULL;
992 }
993 for (sa = sa_head; NULL != sa; sa = sn)
994 {
995 sn = sa->next;
996 if (zm == sa->zm_pos)
997 {
998 sa->zm_pos = zm->next;
999 /* this may free sa */
1001 }
1002 }
1003 GNUNET_free (zm);
1004 break;
1005 }
1006 sa = sa_head;
1007 while (NULL != sa)
1008 {
1009 if (nc != sa->nc)
1010 {
1011 sa = sa->next;
1012 continue;
1013 }
1014 sn = sa->next;
1016 sa = sn;
1017 }
1018 while (NULL != (no = nc->op_head))
1019 {
1020 GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no);
1021 GNUNET_free (no);
1022 }
1023 GNUNET_break (NULL == GNUNET_PLUGIN_unload (nc->db_lib_name,
1024 nc->GSN_database));
1025 GNUNET_free (nc->db_lib_name);
1026 GNUNET_free (nc);
1027}
1028
1029
1038static void *
1040 struct GNUNET_SERVICE_Client *client,
1041 struct GNUNET_MQ_Handle *mq)
1042{
1043 struct NamestoreClient *nc;
1044 char *database;
1045
1046 (void) cls;
1047 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1048 nc = GNUNET_new (struct NamestoreClient);
1049 nc->client = client;
1050 nc->mq = mq;
1051 /* Loading database plugin */
1053 "namestore",
1054 "database",
1055 &database))
1056 {
1057 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
1058 GNUNET_free (nc);
1059 return NULL;
1060 }
1062 nc->GSN_database = GNUNET_PLUGIN_load (db_lib_name, (void *) GSN_cfg);
1063 GNUNET_free (database);
1064 if (NULL == nc->GSN_database)
1065 {
1067 "Could not load database backend `%s'\n",
1068 db_lib_name);
1069 GNUNET_free (nc);
1070 return NULL;
1071 }
1072 nc->db_lib_name = GNUNET_strdup (db_lib_name);
1074 return nc;
1075}
1076
1077
1082{
1086 const char *label;
1087
1092
1096 char *res_rd;
1097
1102
1107
1112
1116 unsigned int res_rd_count;
1117
1121 ssize_t rd_ser_len;
1122};
1123
1124
1137static void
1138lookup_it (void *cls,
1139 uint64_t seq,
1140 const char *editor_hint,
1141 const struct GNUNET_CRYPTO_PrivateKey *private_key,
1142 const char *label,
1143 unsigned int rd_count_nf,
1144 const struct GNUNET_GNSRECORD_Data *rd_nf)
1145{
1146 struct RecordLookupContext *rlc = cls;
1147 struct GNUNET_GNSRECORD_Data rd[rd_count_nf];
1148 struct GNUNET_TIME_Absolute block_exp;
1149 unsigned int rd_count = 0;
1150 char *emsg;
1151
1152 (void) private_key;
1153 GNUNET_assert (0 != seq);
1154 if (0 != strcmp (label, rlc->label))
1155 return;
1156 rlc->found = GNUNET_YES;
1157 if (NULL == rlc->editor_hint)
1158 rlc->editor_hint = GNUNET_strdup (editor_hint);
1160 rd_nf,
1161 rd_count_nf,
1162 rd,
1163 &rd_count,
1164 &block_exp,
1165 rlc->filter,
1166 &emsg))
1167 {
1168 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
1169 GNUNET_free (emsg);
1170 GNUNET_assert (0);
1171 }
1172
1173 if (0 == rd_count)
1174 {
1175 rlc->rd_ser_len = 0;
1176 rlc->res_rd_count = 0;
1177 rlc->res_rd = NULL;
1178 return;
1179 }
1180 if ((NULL != rlc->nick) && (0 != strcmp (label, GNUNET_GNS_EMPTY_LABEL_AT)))
1181 {
1182 /* Merge */
1183 struct GNUNET_GNSRECORD_Data *rd_res;
1184 unsigned int rdc_res;
1185
1186 rd_res = NULL;
1187 rdc_res = 0;
1190 merge_with_nick_records (rlc->nick, rd_count, rd, &rdc_res, &rd_res);
1191 rlc->rd_ser_len = GNUNET_GNSRECORD_records_get_size (rdc_res, rd_res);
1192 if (rlc->rd_ser_len < 0)
1193 {
1194 GNUNET_break (0);
1195 GNUNET_free (rd_res);
1196 rlc->found = GNUNET_NO;
1197 rlc->rd_ser_len = 0;
1198 return;
1199 }
1200 rlc->res_rd_count = rdc_res;
1201 rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1203 rd_res,
1204 rlc->rd_ser_len,
1205 rlc->res_rd))
1206 {
1207 GNUNET_break (0);
1208 GNUNET_free (rlc->res_rd);
1209 rlc->res_rd = NULL;
1210 rlc->res_rd_count = 0;
1211 rlc->rd_ser_len = 0;
1212 GNUNET_free (rd_res);
1213 rlc->found = GNUNET_NO;
1214 return;
1215 }
1216 GNUNET_free (rd_res);
1217 GNUNET_free (rlc->nick);
1218 rlc->nick = NULL;
1219 }
1220 else
1221 {
1223 if (rlc->rd_ser_len < 0)
1224 {
1225 GNUNET_break (0);
1226 rlc->found = GNUNET_NO;
1227 rlc->rd_ser_len = 0;
1228 return;
1229 }
1230 rlc->res_rd_count = rd_count;
1231 rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1233 rd,
1234 rlc->rd_ser_len,
1235 rlc->res_rd))
1236 {
1237 GNUNET_break (0);
1238 GNUNET_free (rlc->res_rd);
1239 rlc->res_rd = NULL;
1240 rlc->res_rd_count = 0;
1241 rlc->rd_ser_len = 0;
1242 rlc->found = GNUNET_NO;
1243 return;
1244 }
1245 }
1246}
1247
1248
1256static int
1257check_edit_record_set (void *cls, const struct EditRecordSetMessage *er_msg)
1258{
1259 uint16_t name_len;
1260 uint16_t editor_hint_len;
1261 size_t src_size;
1262 size_t key_len;
1263
1264 (void) cls;
1265 name_len = ntohs (er_msg->label_len);
1266 editor_hint_len = ntohs (er_msg->editor_hint_len);
1267 key_len = ntohs (er_msg->key_len);
1268 src_size = ntohs (er_msg->gns_header.header.size);
1269 if (name_len + editor_hint_len + key_len != src_size - sizeof(struct
1271 {
1272 GNUNET_break (0);
1273 return GNUNET_SYSERR;
1274 }
1275 return GNUNET_OK;
1276}
1277
1278
1285static void
1286handle_edit_record_set (void *cls, const struct EditRecordSetMessage *er_msg)
1287{
1288 struct GNUNET_CRYPTO_PrivateKey zone;
1289 struct NamestoreClient *nc = cls;
1290 struct GNUNET_MQ_Envelope *env;
1291 struct EditRecordSetResponseMessage *rer_msg;
1292 struct RecordLookupContext rlc;
1293 const char *name_tmp;
1294 const char *editor_hint;
1295 char *conv_name;
1296 uint16_t name_len;
1297 uint16_t old_editor_hint_len;
1298 int res;
1299 size_t key_len;
1300 size_t kb_read;
1301
1302 key_len = ntohs (er_msg->key_len);
1303 name_len = ntohs (er_msg->label_len);
1304 if ((GNUNET_SYSERR ==
1306 key_len,
1307 &zone,
1308 &kb_read)) ||
1309 (kb_read != key_len))
1310 {
1312 "Error reading private key\n");
1314 return;
1315 }
1316 name_tmp = (const char *) &er_msg[1] + key_len;
1317 editor_hint = (const char *) name_tmp + name_len;
1320 "Received NAMESTORE_RECORD_SET_EDIT message for name `%s'\n",
1321 name_tmp);
1322
1323 conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
1324 if (NULL == conv_name)
1325 {
1327 "Error converting name `%s'\n",
1328 name_tmp);
1330 return;
1331 }
1332 name_len = strlen (conv_name) + 1;
1333 rlc.editor_hint = NULL;
1334 rlc.label = conv_name;
1336 "Looking up without filter\n");
1338 rlc.found = GNUNET_NO;
1339 rlc.res_rd_count = 0;
1340 rlc.res_rd = NULL;
1341 rlc.rd_ser_len = 0;
1342 rlc.nick = get_nick_record (&zone);
1343 res = nc->GSN_database->edit_records (nc->GSN_database->cls,
1345 &zone,
1346 conv_name,
1347 &lookup_it,
1348 &rlc);
1349
1350 old_editor_hint_len = 0;
1351 if (NULL != rlc.editor_hint)
1352 old_editor_hint_len = strlen (rlc.editor_hint) + 1;
1353 env =
1354 GNUNET_MQ_msg_extra (rer_msg,
1355 rlc.rd_ser_len + old_editor_hint_len,
1357 ;
1358 rer_msg->editor_hint_len = htons (old_editor_hint_len);
1359 rer_msg->gns_header.r_id = er_msg->gns_header.r_id;
1360 rer_msg->rd_count = htons (rlc.res_rd_count);
1361 rer_msg->rd_len = htons (rlc.rd_ser_len);
1362 if (GNUNET_YES == rlc.found)
1363 rer_msg->ec = htons (GNUNET_EC_NONE);
1364 else if (GNUNET_SYSERR == res)
1365 rer_msg->ec = htons (GNUNET_EC_NAMESTORE_UNKNOWN);
1366 else
1367 rer_msg->ec = htons (GNUNET_EC_NAMESTORE_NO_RESULTS);
1368 GNUNET_memcpy (&rer_msg[1], rlc.editor_hint, old_editor_hint_len);
1369 GNUNET_memcpy ((char*) &rer_msg[1] + old_editor_hint_len, rlc.res_rd,
1370 rlc.rd_ser_len);
1371 GNUNET_MQ_send (nc->mq, env);
1373 GNUNET_free (rlc.res_rd);
1374 GNUNET_free (conv_name);
1375}
1376
1377
1385static int
1386check_edit_record_set_cancel (void *cls, const struct
1388{
1389 uint16_t name_len;
1390 uint16_t editor_hint_len;
1391 uint16_t editor_hint_repl_len;
1392 size_t src_size;
1393 size_t key_len;
1394
1395 (void) cls;
1396 name_len = ntohs (er_msg->label_len);
1397 editor_hint_len = ntohs (er_msg->editor_hint_len);
1398 editor_hint_repl_len = ntohs (er_msg->editor_hint_len);
1399 key_len = ntohs (er_msg->key_len);
1400 src_size = ntohs (er_msg->gns_header.header.size);
1401 if (name_len + editor_hint_len + editor_hint_repl_len + key_len != src_size
1402 - sizeof(struct
1404 {
1405 GNUNET_break (0);
1406 return GNUNET_SYSERR;
1407 }
1408 return GNUNET_OK;
1409}
1410
1411
1418static void
1419handle_edit_record_set_cancel (void *cls, const struct
1421{
1422 struct GNUNET_CRYPTO_PrivateKey zone;
1423 struct NamestoreClient *nc = cls;
1424 struct GNUNET_MQ_Envelope *env;
1425 struct NamestoreResponseMessage *rer_msg;
1426 const char *name_tmp;
1427 const char *editor_hint;
1428 const char *editor_hint_repl;
1429 char *conv_name;
1430 uint16_t name_len;
1431 uint16_t editor_hint_len;
1432 int res;
1433 size_t key_len;
1434 size_t kb_read;
1435
1436 key_len = ntohs (er_msg->key_len);
1437 name_len = ntohs (er_msg->label_len);
1438 editor_hint_len = ntohs (er_msg->editor_hint_len);
1439 if ((GNUNET_SYSERR ==
1441 key_len,
1442 &zone,
1443 &kb_read)) ||
1444 (kb_read != key_len))
1445 {
1447 "Error reading private key\n");
1449 return;
1450 }
1451 name_tmp = (const char *) &er_msg[1] + key_len;
1452 editor_hint = (const char *) name_tmp + name_len;
1453 editor_hint_repl = (const char *) name_tmp + name_len + editor_hint_len;
1456 "Received NAMESTORE_RECORD_SET_EDIT message for name `%s'\n",
1457 name_tmp);
1458
1459 conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
1460 if (NULL == conv_name)
1461 {
1463 "Error converting name `%s'\n",
1464 name_tmp);
1466 return;
1467 }
1468 name_len = strlen (conv_name) + 1;
1470 "Clearing editor hint\n");
1471 res = nc->GSN_database->clear_editor_hint (nc->GSN_database->cls,
1472 editor_hint,
1473 editor_hint_repl,
1474 &zone,
1475 conv_name);
1477 "Clearing editor hint %s\n", (GNUNET_SYSERR == res) ? "failed." :
1478 "successful.");
1479
1480 env =
1481 GNUNET_MQ_msg (rer_msg,
1483 rer_msg->gns_header.r_id = er_msg->gns_header.r_id;
1484 rer_msg->ec = htons ((GNUNET_OK == res) ? GNUNET_EC_NONE :
1486 GNUNET_MQ_send (nc->mq, env);
1487 GNUNET_free (conv_name);
1488}
1489
1490
1498static int
1499check_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
1500{
1501 uint32_t name_len;
1502 size_t src_size;
1503 size_t key_len;
1504
1505 (void) cls;
1506 name_len = ntohs (ll_msg->label_len);
1507 key_len = ntohs (ll_msg->key_len);
1508 src_size = ntohs (ll_msg->gns_header.header.size);
1509 if (name_len + key_len != src_size - sizeof(struct LabelLookupMessage))
1510 {
1511 GNUNET_break (0);
1512 return GNUNET_SYSERR;
1513 }
1514 return GNUNET_OK;
1515}
1516
1517
1524static void
1525handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
1526{
1527 struct GNUNET_CRYPTO_PrivateKey zone;
1528 struct NamestoreClient *nc = cls;
1529 struct GNUNET_MQ_Envelope *env;
1530 struct LabelLookupResponseMessage *llr_msg;
1531 struct RecordLookupContext rlc;
1532 const char *name_tmp;
1533 char *res_name;
1534 char *conv_name;
1535 uint32_t name_len;
1536 int res;
1537 size_t key_len;
1538 size_t kb_read;
1539
1540 key_len = ntohs (ll_msg->key_len);
1541 if ((GNUNET_SYSERR ==
1543 key_len,
1544 &zone,
1545 &kb_read)) ||
1546 (kb_read != key_len))
1547 {
1549 "Error reading private key\n");
1551 return;
1552 }
1553 name_tmp = (const char *) &ll_msg[1] + key_len;
1556 "Received NAMESTORE_RECORD_LOOKUP message for name `%s'\n",
1557 name_tmp);
1558
1559 conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
1560 if (NULL == conv_name)
1561 {
1563 "Error converting name `%s'\n",
1564 name_tmp);
1566 return;
1567 }
1568 name_len = strlen (conv_name) + 1;
1569 rlc.editor_hint = NULL;
1570 rlc.label = conv_name;
1572 "Looking up with filter %u\n", ntohs (ll_msg->filter));
1573 rlc.filter = ntohs (ll_msg->filter);
1574 rlc.found = GNUNET_NO;
1575 rlc.res_rd_count = 0;
1576 rlc.res_rd = NULL;
1577 rlc.rd_ser_len = 0;
1578 rlc.nick = get_nick_record (&zone);
1579 res = nc->GSN_database->lookup_records (nc->GSN_database->cls,
1580 &zone,
1581 conv_name,
1582 &lookup_it,
1583 &rlc);
1584 env =
1585 GNUNET_MQ_msg_extra (llr_msg,
1586 key_len + name_len + rlc.rd_ser_len,
1588 llr_msg->gns_header.r_id = ll_msg->gns_header.r_id;
1589 GNUNET_memcpy (&llr_msg[1], &ll_msg[1], key_len);
1590 llr_msg->key_len = ll_msg->key_len;
1591 llr_msg->name_len = htons (name_len);
1592 llr_msg->rd_count = htons (rlc.res_rd_count);
1593 llr_msg->rd_len = htons (rlc.rd_ser_len);
1594 llr_msg->reserved = htons (0);
1595 res_name = ((char *) &llr_msg[1]) + key_len;
1596 if (GNUNET_YES == rlc.found)
1597 llr_msg->found = htons (GNUNET_YES);
1598 else if (GNUNET_SYSERR == res)
1599 llr_msg->found = htons (GNUNET_SYSERR);
1600 else
1601 llr_msg->found = htons (GNUNET_NO);
1602 GNUNET_memcpy (res_name, conv_name, name_len);
1603 GNUNET_memcpy (&res_name[name_len], rlc.res_rd, rlc.rd_ser_len);
1604 GNUNET_MQ_send (nc->mq, env);
1606 GNUNET_free (rlc.res_rd);
1607 GNUNET_free (conv_name);
1608}
1609
1610
1618static int
1619check_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1620{
1621 size_t msg_size;
1622 size_t min_size_exp;
1623 size_t rd_set_count;
1624 size_t key_len;
1625
1626 (void) cls;
1627 msg_size = ntohs (rp_msg->gns_header.header.size);
1628 rd_set_count = ntohs (rp_msg->rd_set_count);
1629 key_len = ntohs (rp_msg->key_len);
1630
1631 min_size_exp = sizeof(*rp_msg) + key_len + sizeof (struct RecordSet)
1632 * rd_set_count;
1633 if (msg_size < min_size_exp)
1634 {
1635 GNUNET_break (0);
1636 return GNUNET_SYSERR;
1637 }
1638 return GNUNET_OK;
1639}
1640
1641
1643{
1644
1649
1655
1656};
1657
1658
1669static void
1671 uint64_t seq,
1672 const char *editor_hint,
1673 const struct
1674 GNUNET_CRYPTO_PrivateKey *private_key,
1675 const char *label,
1676 unsigned int rd_count,
1677 const struct GNUNET_GNSRECORD_Data *rd)
1678{
1679 struct LookupExistingRecordsContext *lctx = cls;
1680 struct GNUNET_GNSRECORD_Data rd_pub[rd_count];
1681 unsigned int rd_pub_count;
1682 char *emsg;
1683
1684 if ((1 == rd_count) &&
1686 {
1687 /* This record set contains only a tombstone! */
1688 lctx->only_tombstone = GNUNET_YES;
1689 }
1690 if (GNUNET_OK !=
1692 rd,
1693 rd_count,
1694 rd_pub,
1695 &rd_pub_count,
1696 &lctx->exp,
1698 &emsg))
1699 {
1701 "%s\n", emsg);
1702 GNUNET_free (emsg);
1703 }
1704}
1705
1706
1707static enum GNUNET_ErrorCode
1709 const struct GNUNET_CRYPTO_PrivateKey *private_key,
1710 const struct RecordSet *rd_set,
1711 ssize_t *len)
1712{
1713 size_t name_len;
1714 size_t rd_ser_len;
1715 const char *name_tmp;
1716 const char *rd_ser;
1717 char *emsg;
1718 char *conv_name;
1719 unsigned int rd_count;
1720 int res;
1721 enum GNUNET_ErrorCode ec;
1722 struct GNUNET_TIME_Absolute new_block_exp;
1723 struct LookupExistingRecordsContext lctx;
1724 *len = sizeof (struct RecordSet);
1725
1726 ec = GNUNET_EC_NONE;
1729 new_block_exp = GNUNET_TIME_UNIT_ZERO_ABS;
1730 name_len = ntohs (rd_set->name_len);
1731 *len += name_len;
1732 rd_count = ntohs (rd_set->rd_count);
1733 rd_ser_len = ntohs (rd_set->rd_len);
1734 *len += rd_ser_len;
1735 name_tmp = (const char *) &rd_set[1];
1736 rd_ser = &name_tmp[name_len];
1737 {
1739
1740 /* Extracting and converting private key */
1741 conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
1742 if (NULL == conv_name)
1743 {
1745 "Error normalizing name `%s'\n",
1746 name_tmp);
1748 }
1749
1750 /* Check name for validity */
1751 if (GNUNET_OK != GNUNET_GNSRECORD_label_check (conv_name, &emsg))
1752 {
1754 "Label invalid: `%s'\n",
1755 emsg);
1756 GNUNET_free (emsg);
1757 GNUNET_free (conv_name);
1759 }
1760
1761 if (GNUNET_OK !=
1763 rd))
1764 {
1765 GNUNET_free (conv_name);
1767 }
1768
1770 "Well-formed store requests received",
1771 1,
1772 GNUNET_NO);
1774 "Creating %u records for name `%s'\n",
1775 (unsigned int) rd_count,
1776 conv_name);
1777 if ((0 == rd_count) &&
1778 (GNUNET_NO == nc->GSN_database->lookup_records (nc->GSN_database->cls,
1779 private_key,
1780 conv_name,
1782 &lctx)))
1783 {
1784 /* This name does not exist, so cannot be removed */
1786 "Name `%s' does not exist, no deletion required\n",
1787 conv_name);
1788 res = GNUNET_NO;
1790 }
1791 else
1792 {
1793 /* remove "NICK" records, unless this is for the
1794 #GNUNET_GNS_EMPTY_LABEL_AT label
1795 We may need one additional record later for tombstone.
1796 FIXME: Since we must normalize the record set (check for
1797 consistency etc) we have to iterate the set twice.
1798 May be inefficient.
1799 We cannot really move the nick caching into GNSRECORD.
1800 */
1801 struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL (rd_count)];
1802 struct GNUNET_GNSRECORD_Data rd_nf[GNUNET_NZL (rd_count) + 1];
1803 unsigned int rd_clean_off;
1804 unsigned int rd_nf_count;
1805 int have_nick;
1806
1807 rd_clean_off = 0;
1808 have_nick = GNUNET_NO;
1809 for (unsigned int i = 0; i < rd_count; i++)
1810 {
1811 rd_clean[rd_clean_off] = rd[i];
1812
1813 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) ||
1815 rd_clean_off++;
1816
1817 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1819 {
1820 cache_nick (private_key, &rd[i]);
1821 have_nick = GNUNET_YES;
1822 }
1823 }
1824 if (GNUNET_OK !=
1826 rd_clean,
1827 rd_clean_off,
1828 rd_nf,
1829 &rd_nf_count,
1830 &new_block_exp,
1832 &emsg))
1833 {
1834 GNUNET_free (conv_name);
1836 "Error normalizing record set: `%s'\n",
1837 emsg);
1838 GNUNET_free (emsg);
1840 }
1842 "%u/%u records before tombstone\n", rd_nf_count,
1843 rd_clean_off);
1844 /*
1845 * If existing_block_exp is 0, then there was no record set
1846 * and no tombstone.
1847 * Otherwise, if the existing block expiration is after the
1848 * new block expiration would be, we need to add a tombstone
1849 * or update it.
1850 */
1851 if (GNUNET_TIME_absolute_cmp (new_block_exp, <=, lctx.exp))
1852 {
1853 rd_nf[rd_nf_count].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE;
1854 rd_nf[rd_nf_count].expiration_time =
1855 lctx.exp.abs_value_us;
1856 rd_nf[rd_nf_count].data = NULL;
1857 rd_nf[rd_nf_count].data_size = 0;
1858 rd_nf[rd_nf_count].flags = GNUNET_GNSRECORD_RF_PRIVATE
1860 rd_nf_count++;
1861 }
1862 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1863 (GNUNET_NO == have_nick))
1864 {
1865 cache_nick (private_key, NULL);
1866 }
1867 res = nc->GSN_database->store_records (nc->GSN_database->cls,
1868 private_key,
1869 conv_name,
1870 rd_nf_count,
1871 rd_nf);
1872 /* If after a store there is only a TOMBSTONE left, and
1873 * there was >1 record under this label found (the tombstone; indicated
1874 * through res != GNUNET_NO) then we should return "NOT FOUND" == GNUNET_NO
1875 */
1876 if ((GNUNET_SYSERR != res) &&
1877 (0 == rd_count) &&
1878 (1 == rd_nf_count) &&
1880 (GNUNET_YES == lctx.only_tombstone))
1881 {
1883 "Client tried to remove non-existent record\n");
1885 }
1886 }
1887
1888 if (GNUNET_SYSERR == res)
1889 {
1890 /* store not successful, no need to tell monitors */
1891 GNUNET_free (conv_name);
1893 }
1894 }
1895 return ec;
1896}
1897
1898
1905static void
1906handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1907{
1908 struct GNUNET_CRYPTO_PrivateKey zone;
1909 struct NamestoreClient *nc = cls;
1910 uint32_t rid;
1911 uint16_t rd_set_count;
1912 const char *buf;
1913 ssize_t read;
1914 size_t key_len;
1915 size_t kb_read;
1916 size_t rp_msg_len;
1917 size_t rs_len;
1918 size_t rs_off;
1919 struct StoreActivity *sa;
1920 struct RecordSet *rs;
1921 enum GNUNET_ErrorCode res;
1922
1923 key_len = ntohs (rp_msg->key_len);
1924 rp_msg_len = ntohs (rp_msg->gns_header.header.size);
1925 rs_off = sizeof (*rp_msg) + key_len;
1926 rs_len = rp_msg_len - rs_off;
1927 if ((GNUNET_SYSERR ==
1929 key_len,
1930 &zone,
1931 &kb_read)) ||
1932 (kb_read != key_len))
1933 {
1935 "Error reading private key\n");
1937 return;
1938 }
1940 "Received NAMESTORE_RECORD_STORE message\n");
1941 rid = ntohl (rp_msg->gns_header.r_id);
1942 rd_set_count = ntohs (rp_msg->rd_set_count);
1943 buf = (const char *) rp_msg + rs_off;
1944 if (GNUNET_YES == ntohs (rp_msg->single_tx))
1945 nc->GSN_database->begin_tx (nc->GSN_database->cls);
1946 for (int i = 0; i < rd_set_count; i++)
1947 {
1948 rs = (struct RecordSet *) buf;
1949 res = store_record_set (nc, &zone,
1950 rs, &read);
1951 if (GNUNET_EC_NONE != res)
1952 {
1953 if (GNUNET_YES == ntohs (rp_msg->single_tx))
1954 nc->GSN_database->rollback_tx (nc->GSN_database->cls);
1955 send_store_response (nc, res, rid);
1957 return;
1958 }
1959 buf += read;
1960 }
1961 if (GNUNET_YES == ntohs (rp_msg->single_tx))
1962 nc->GSN_database->commit_tx (nc->GSN_database->cls);
1963 sa = GNUNET_malloc (sizeof(struct StoreActivity) + rs_len);
1965 sa->nc = nc;
1966 sa->rs = (struct RecordSet *) &sa[1];
1967 sa->rd_set_count = rd_set_count;
1968 GNUNET_memcpy (&sa[1], (char *) rp_msg + rs_off, rs_len);
1969 sa->rid = rid;
1970 sa->rd_set_pos = 0;
1971 sa->private_key = zone;
1972 sa->zm_pos = monitor_head;
1974}
1975
1976
1982{
1987
1991 uint32_t rid;
1992
1999};
2000
2001
2012static void
2014 uint64_t seq,
2015 const char *editor_hint,
2016 const struct GNUNET_CRYPTO_PrivateKey *zone_key,
2017 const char *name,
2018 unsigned int rd_count,
2019 const struct GNUNET_GNSRECORD_Data *rd)
2020{
2021 struct ZoneToNameCtx *ztn_ctx = cls;
2022 struct GNUNET_MQ_Envelope *env;
2023 struct ZoneToNameResponseMessage *ztnr_msg;
2024 size_t name_len;
2025 size_t key_len;
2026 ssize_t rd_ser_len;
2027 size_t msg_size;
2028 char *name_tmp;
2029 char *rd_tmp;
2030
2031 GNUNET_assert (0 != seq);
2033 "Found result for zone-to-name lookup: `%s'\n",
2034 name);
2035 ztn_ctx->ec = GNUNET_EC_NONE;
2036 name_len = (NULL == name) ? 0 : strlen (name) + 1;
2038 if (rd_ser_len < 0)
2039 {
2040 GNUNET_break (0);
2041 ztn_ctx->ec = htonl (GNUNET_EC_NAMESTORE_UNKNOWN);
2042 return;
2043 }
2045 msg_size = sizeof(struct ZoneToNameResponseMessage)
2046 + name_len + rd_ser_len + key_len;
2047 if (msg_size >= GNUNET_MAX_MESSAGE_SIZE)
2048 {
2049 GNUNET_break (0);
2051 return;
2052 }
2053 env =
2054 GNUNET_MQ_msg_extra (ztnr_msg,
2055 key_len + name_len + rd_ser_len,
2057 ztnr_msg->gns_header.header.size = htons (msg_size);
2058 ztnr_msg->gns_header.r_id = htonl (ztn_ctx->rid);
2059 ztnr_msg->ec = htonl (ztn_ctx->ec);
2060 ztnr_msg->rd_len = htons (rd_ser_len);
2061 ztnr_msg->rd_count = htons (rd_count);
2062 ztnr_msg->name_len = htons (name_len);
2063 ztnr_msg->key_len = htons (key_len);
2065 &ztnr_msg[1],
2066 key_len);
2067 name_tmp = (char *) &ztnr_msg[1] + key_len;
2068 GNUNET_memcpy (name_tmp, name, name_len);
2069 rd_tmp = &name_tmp[name_len];
2071 rd_ser_len ==
2072 GNUNET_GNSRECORD_records_serialize (rd_count, rd, rd_ser_len, rd_tmp));
2073 ztn_ctx->ec = GNUNET_EC_NONE;
2074 GNUNET_MQ_send (ztn_ctx->nc->mq, env);
2075}
2076
2077
2078static enum GNUNET_GenericReturnValue
2080 const struct ZoneToNameMessage *zis_msg)
2081{
2082 return GNUNET_OK;
2083}
2084
2085
2092static void
2093handle_zone_to_name (void *cls, const struct ZoneToNameMessage *ztn_msg)
2094{
2095 struct GNUNET_CRYPTO_PrivateKey zone;
2096 struct GNUNET_CRYPTO_PublicKey value_zone;
2097 struct NamestoreClient *nc = cls;
2098 struct ZoneToNameCtx ztn_ctx;
2099 struct GNUNET_MQ_Envelope *env;
2100 struct ZoneToNameResponseMessage *ztnr_msg;
2101 size_t key_len;
2102 size_t pkey_len;
2103 size_t kb_read;
2104
2105 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_TO_NAME message\n");
2106 ztn_ctx.rid = ntohl (ztn_msg->gns_header.r_id);
2107 ztn_ctx.nc = nc;
2109 key_len = ntohs (ztn_msg->key_len);
2110 if ((GNUNET_SYSERR ==
2112 key_len,
2113 &zone,
2114 &kb_read)) ||
2115 (kb_read != key_len))
2116 {
2118 "Error parsing private key.\n");
2120 GNUNET_break (0);
2121 return;
2122 }
2123 pkey_len = ntohs (ztn_msg->pkey_len);
2124 if ((GNUNET_SYSERR ==
2126 + key_len,
2127 pkey_len,
2128 &value_zone,
2129 &kb_read)) ||
2130 (kb_read != pkey_len))
2131 {
2133 "Error parsing public key.\n");
2135 GNUNET_break (0);
2136 return;
2137 }
2138 if (GNUNET_SYSERR == nc->GSN_database->zone_to_name (nc->GSN_database->cls,
2139 &zone,
2140 &value_zone,
2142 &ztn_ctx))
2143 {
2144 /* internal error, hang up instead of signalling something
2145 that might be wrong */
2146 GNUNET_break (0);
2148 return;
2149 }
2151 {
2152 /* no result found, send empty response */
2154 "Found no result for zone-to-name lookup.\n");
2155 env = GNUNET_MQ_msg (ztnr_msg,
2157 ztnr_msg->gns_header.r_id = ztn_msg->gns_header.r_id;
2158 ztnr_msg->ec = htonl (GNUNET_EC_NAMESTORE_ZONE_NOT_FOUND);
2159 GNUNET_MQ_send (nc->mq, env);
2160 }
2162}
2163
2164
2170{
2175
2179 uint64_t limit;
2180
2185};
2186
2187
2198static void
2200 uint64_t seq,
2201 const char *editor_hint,
2202 const struct GNUNET_CRYPTO_PrivateKey *zone_key,
2203 const char *name,
2204 unsigned int rd_count,
2205 const struct GNUNET_GNSRECORD_Data *rd)
2206{
2207 struct ZoneIterationProcResult *proc = cls;
2208
2209 GNUNET_assert (0 != seq);
2210 if ((NULL == zone_key) && (NULL == name))
2211 {
2212 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
2213 return;
2214 }
2215 if ((NULL == zone_key) || (NULL == name))
2216 {
2217 /* what is this!? should never happen */
2218 GNUNET_break (0);
2219 return;
2220 }
2221 if (0 == proc->limit)
2222 {
2223 /* what is this!? should never happen */
2224 GNUNET_break (0);
2225 return;
2226 }
2227 proc->zi->seq = seq;
2228 if (0 < send_lookup_response_with_filter (proc->zi->nc,
2229 proc->zi->request_id,
2230 zone_key,
2231 name,
2232 rd_count,
2233 rd,
2234 proc->zi->filter))
2235 proc->limit--;
2236 else
2237 proc->run_again = GNUNET_YES;
2238}
2239
2240
2247static void
2249{
2250 struct ZoneIterationProcResult proc;
2253 struct NamestoreClient *nc = zi->nc;
2254
2255 memset (&proc, 0, sizeof(proc));
2257 "Asked to return up to %llu records at position %llu\n",
2258 (unsigned long long) limit,
2259 (unsigned long long) zi->seq);
2260 proc.zi = zi;
2261 proc.limit = limit;
2262 proc.run_again = GNUNET_YES;
2264 while (GNUNET_YES == proc.run_again)
2265 {
2266 proc.run_again = GNUNET_NO;
2268 nc->GSN_database->iterate_records (nc->GSN_database->cls,
2269 (GNUNET_YES ==
2271 &zi->zone))
2272 ? NULL
2273 : &zi->zone,
2274 zi->seq,
2275 proc.limit,
2277 &proc));
2278 }
2282 "NAMESTORE iteration delay (μs/record)",
2284 GNUNET_NO);
2285 if (0 == proc.limit)
2287 "Returned %llu results, more results available\n",
2288 (unsigned long long) limit);
2289 zi->send_end = (0 != proc.limit);
2291}
2292
2293
2294static enum GNUNET_GenericReturnValue
2296 const struct ZoneIterationStartMessage *zis_msg)
2297{
2298 uint16_t size;
2299 size_t key_len;
2300
2301 size = ntohs (zis_msg->gns_header.header.size);
2302 key_len = ntohs (zis_msg->key_len);
2303
2304 if (size < key_len + sizeof(*zis_msg))
2305 {
2306 GNUNET_break (0);
2307 return GNUNET_SYSERR;
2308 }
2309 return GNUNET_OK;
2310}
2311
2312
2319static void
2321 const struct ZoneIterationStartMessage *zis_msg)
2322{
2323 struct GNUNET_CRYPTO_PrivateKey zone;
2324 struct NamestoreClient *nc = cls;
2325 struct ZoneIteration *zi;
2326 size_t key_len;
2327 size_t kb_read;
2328
2330 "Received ZONE_ITERATION_START message\n");
2331 key_len = ntohs (zis_msg->key_len);
2332 zi = GNUNET_new (struct ZoneIteration);
2333 if (0 < key_len)
2334 {
2335 if ((GNUNET_SYSERR ==
2337 key_len,
2338 &zone,
2339 &kb_read)) ||
2340 (kb_read != key_len))
2341 {
2343 GNUNET_free (zi);
2344 return;
2345 }
2346 zi->zone = zone;
2347 }
2348 zi->request_id = ntohl (zis_msg->gns_header.r_id);
2349 zi->filter = ntohs (zis_msg->filter);
2350 zi->offset = 0;
2351 zi->nc = nc;
2352 GNUNET_CONTAINER_DLL_insert (nc->op_head, nc->op_tail, zi);
2354}
2355
2356
2363static void
2365 const struct ZoneIterationStopMessage *zis_msg)
2366{
2367 struct NamestoreClient *nc = cls;
2368 struct ZoneIteration *zi;
2369 uint32_t rid;
2370
2372 "Received ZONE_ITERATION_STOP message\n");
2373 rid = ntohl (zis_msg->gns_header.r_id);
2374 for (zi = nc->op_head; NULL != zi; zi = zi->next)
2375 if (zi->request_id == rid)
2376 break;
2377 if (NULL == zi)
2378 {
2379 GNUNET_break (0);
2381 return;
2382 }
2383 GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, zi);
2384 GNUNET_free (zi);
2386}
2387
2388
2395static void
2397 const struct ZoneIterationNextMessage *zis_msg)
2398{
2399 struct NamestoreClient *nc = cls;
2400 struct ZoneIteration *zi;
2401 uint32_t rid;
2402 uint64_t limit;
2403
2405 "Received ZONE_ITERATION_NEXT message\n");
2407 "Iteration NEXT messages received",
2408 1,
2409 GNUNET_NO);
2410 rid = ntohl (zis_msg->gns_header.r_id);
2411 limit = GNUNET_ntohll (zis_msg->limit);
2412 for (zi = nc->op_head; NULL != zi; zi = zi->next)
2413 if (zi->request_id == rid)
2414 break;
2415 if (NULL == zi)
2416 {
2417 GNUNET_break (0);
2419 return;
2420 }
2421 run_zone_iteration_round (zi, limit);
2422}
2423
2424
2430static void
2432{
2433 struct StoreActivity *sa = sa_head;
2434
2436 "Unblocking zone monitor %p\n", zm);
2437 while ((NULL != sa) && (zm->limit > zm->iteration_cnt))
2438 {
2439 struct StoreActivity *sn = sa->next;
2440
2441 if (sa->zm_pos == zm)
2443 sa = sn;
2444 }
2445 if (zm->limit > zm->iteration_cnt)
2446 {
2447 zm->sa_waiting = GNUNET_NO;
2448 if (NULL != zm->sa_wait_warning)
2449 {
2450 GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2451 zm->sa_wait_warning = NULL;
2452 }
2453 }
2454 else if (GNUNET_YES == zm->sa_waiting)
2455 {
2456 zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
2457 if (NULL != zm->sa_wait_warning)
2458 GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2459 zm->sa_wait_warning =
2462 zm);
2463 }
2464}
2465
2466
2472static void
2474{
2475 struct GNUNET_MQ_Envelope *env;
2476 struct GNUNET_MessageHeader *sync;
2478 "Syncing zone monitor %p\n", zm);
2479
2481 GNUNET_MQ_send (zm->nc->mq, env);
2482 /* mark iteration done */
2483 zm->in_first_iteration = GNUNET_NO;
2484 zm->iteration_cnt = 0;
2485 if ((zm->limit > 0) && (zm->sa_waiting))
2487}
2488
2489
2495static void
2496monitor_iteration_next (void *cls);
2497
2498
2509static void
2511 uint64_t seq,
2512 const char *editor_hint,
2513 const struct GNUNET_CRYPTO_PrivateKey *zone_key,
2514 const char *name,
2515 unsigned int rd_count,
2516 const struct GNUNET_GNSRECORD_Data *rd)
2517{
2518 struct ZoneMonitor *zm = cls;
2519
2520 GNUNET_assert (0 != seq);
2521 zm->seq = seq;
2522 GNUNET_assert (NULL != name);
2524 "Monitor notifications sent",
2525 1,
2526 GNUNET_NO);
2527 if (0 < send_lookup_response_with_filter (zm->nc, 0, zone_key, name,
2528 rd_count, rd, zm->filter))
2529 {
2531 "Sent records.\n");
2532 zm->limit--;
2533 zm->iteration_cnt--;
2534 }
2535 else
2536 zm->run_again = GNUNET_YES;
2537 if ((0 == zm->iteration_cnt) && (0 != zm->limit))
2538 {
2539 /* We are done with the current iteration batch, AND the
2540 client would right now accept more, so go again! */
2541 GNUNET_assert (NULL == zm->task);
2543 }
2544}
2545
2546
2547static enum GNUNET_GenericReturnValue
2549 const struct ZoneMonitorStartMessage *zis_msg)
2550{
2551 uint16_t size;
2552 size_t key_len;
2553
2554 size = ntohs (zis_msg->header.size);
2555 key_len = ntohs (zis_msg->key_len);
2556
2557 if (size < key_len + sizeof(*zis_msg))
2558 {
2559 GNUNET_break (0);
2560 return GNUNET_SYSERR;
2561 }
2562 return GNUNET_OK;
2563}
2564
2565
2572static void
2573handle_monitor_start (void *cls, const struct
2574 ZoneMonitorStartMessage *zis_msg)
2575{
2576 struct GNUNET_CRYPTO_PrivateKey zone;
2577 struct NamestoreClient *nc = cls;
2578 struct ZoneMonitor *zm;
2579 size_t key_len;
2580 size_t kb_read;
2581
2583 "Received ZONE_MONITOR_START message\n");
2584 zm = GNUNET_new (struct ZoneMonitor);
2585 zm->nc = nc;
2586 key_len = ntohs (zis_msg->key_len);
2587 if (0 < key_len)
2588 {
2589 if ((GNUNET_SYSERR ==
2591 key_len,
2592 &zone,
2593 &kb_read)) ||
2594 (kb_read != key_len))
2595 {
2597 "Error reading private key\n");
2599 GNUNET_free (zm);
2600 return;
2601 }
2602 zm->zone = zone;
2603 }
2604 zm->limit = 1;
2605 zm->filter = ntohs (zis_msg->filter);
2606 zm->in_first_iteration = (GNUNET_YES == ntohl (zis_msg->iterate_first));
2611 if (zm->in_first_iteration)
2613 else
2614 monitor_sync (zm);
2615}
2616
2617
2623static void
2625{
2626 struct ZoneMonitor *zm = cls;
2627 struct NamestoreClient *nc = zm->nc;
2628 int ret;
2629
2630 zm->task = NULL;
2631 GNUNET_assert (0 == zm->iteration_cnt);
2632 if (zm->limit > 16)
2633 zm->iteration_cnt = zm->limit / 2; /* leave half for monitor events */
2634 else
2635 zm->iteration_cnt = zm->limit; /* use it all */
2636 zm->run_again = GNUNET_YES;
2637 while (GNUNET_YES == zm->run_again)
2638 {
2640 "Running iteration\n");
2641 zm->run_again = GNUNET_NO;
2642 ret = nc->GSN_database->iterate_records (nc->GSN_database->cls,
2644 &zm->zone)) ? NULL : &zm->zone,
2645 zm->seq,
2646 zm->iteration_cnt,
2648 zm);
2649 }
2650 if (GNUNET_SYSERR == ret)
2651 {
2652 GNUNET_SERVICE_client_drop (zm->nc->client);
2653 return;
2654 }
2655 if (GNUNET_NO == ret)
2656 {
2658 "Zone empty... syncing\n");
2659 /* empty zone */
2660 monitor_sync (zm);
2661 return;
2662 }
2663}
2664
2665
2672static void
2673handle_monitor_next (void *cls, const struct ZoneMonitorNextMessage *nm)
2674{
2675 struct NamestoreClient *nc = cls;
2676 struct ZoneMonitor *zm;
2677 uint64_t inc;
2678
2679 inc = GNUNET_ntohll (nm->limit);
2681 "Received ZONE_MONITOR_NEXT message with limit %llu\n",
2682 (unsigned long long) inc);
2683 for (zm = monitor_head; NULL != zm; zm = zm->next)
2684 if (zm->nc == nc)
2685 break;
2686 if (NULL == zm)
2687 {
2688 GNUNET_break (0);
2690 return;
2691 }
2693 if (zm->limit + inc < zm->limit)
2694 {
2695 GNUNET_break (0);
2697 return;
2698 }
2699 zm->limit += inc;
2700 if ((zm->in_first_iteration) && (zm->limit == inc))
2701 {
2702 /* We are still iterating, and the previous iteration must
2703 have stopped due to the client's limit, so continue it! */
2704 GNUNET_assert (NULL == zm->task);
2706 }
2707 GNUNET_assert (zm->iteration_cnt <= zm->limit);
2708 if ((zm->limit > zm->iteration_cnt) && (zm->sa_waiting))
2709 {
2711 }
2712 else if (GNUNET_YES == zm->sa_waiting)
2713 {
2714 if (NULL != zm->sa_wait_warning)
2715 GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2716 zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
2717 zm->sa_wait_warning =
2720 zm);
2721 }
2722}
2723
2724
2732static void
2733run (void *cls,
2734 const struct GNUNET_CONFIGURATION_Handle *cfg,
2736{
2737 char *database;
2738 (void) cls;
2739 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n");
2741 "namestore",
2742 "RETURN_ORPHANED");
2743 GSN_cfg = cfg;
2745 statistics = GNUNET_STATISTICS_create ("namestore", cfg);
2746 /* Loading database plugin */
2748 "namestore",
2749 "database",
2750 &database))
2751 {
2752 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
2754 return;
2755 }
2756 GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
2759 GNUNET_free (database);
2760 if (NULL == GSN_database)
2761 {
2763 "Could not load database backend `%s'\n",
2764 db_lib_name);
2767 return;
2768 }
2770}
2771
2772
2777 "namestore",
2779 &run,
2782 NULL,
2783 GNUNET_MQ_hd_var_size (record_store,
2785 struct RecordStoreMessage,
2786 NULL),
2787 GNUNET_MQ_hd_var_size (edit_record_set,
2789 struct EditRecordSetMessage,
2790 NULL),
2791 GNUNET_MQ_hd_var_size (edit_record_set_cancel,
2794 NULL),
2795 GNUNET_MQ_hd_var_size (record_lookup,
2797 struct LabelLookupMessage,
2798 NULL),
2801 struct ZoneToNameMessage,
2802 NULL),
2803 GNUNET_MQ_hd_var_size (iteration_start,
2806 NULL),
2807 GNUNET_MQ_hd_fixed_size (iteration_next,
2810 NULL),
2811 GNUNET_MQ_hd_fixed_size (iteration_stop,
2814 NULL),
2815 GNUNET_MQ_hd_var_size (monitor_start,
2818 NULL),
2819 GNUNET_MQ_hd_fixed_size (monitor_next,
2822 NULL),
2824
2825
2826/* end of gnunet-service-namestore.c */
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
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 struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:108
static char * data
The data to insert into the dht.
static char * name
Name (label) of the records to list.
static unsigned int rd_count
Number of records for currently parsed set.
static char * res
Currently read line or NULL on EOF.
static struct GNUNET_GNSRECORD_Data rd[50]
The record data under a single label.
static struct GNUNET_NAMESTORE_ZoneMonitor * zm
Monitor handle.
static size_t data_size
Number of bytes in data.
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:47
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static struct GNUNET_NotificationContext * nc
Notification context for broadcasting to monitors.
static struct GNUNET_CONTAINER_BloomFilter * filter
Bloomfilter to quickly tell if we don't have the content.
static struct GNUNET_GNSRECORD_Data * get_nick_record(const struct GNUNET_CRYPTO_PrivateKey *zone)
Return the NICK record for the zone (if it exists).
static int check_edit_record_set(void *cls, const struct EditRecordSetMessage *er_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_SET_EDIT message.
static enum GNUNET_GenericReturnValue check_iteration_start(void *cls, const struct ZoneIterationStartMessage *zis_msg)
static int return_orphaned
Returned orphaned records?
static void handle_iteration_start(void *cls, const struct ZoneIterationStartMessage *zis_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START message.
static struct StoreActivity * sa_tail
Tail of DLL of monitor-blocked store activities.
static void handle_iteration_stop(void *cls, const struct ZoneIterationStopMessage *zis_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP message.
static void monitor_iterate_cb(void *cls, uint64_t seq, const char *editor_hint, const struct GNUNET_CRYPTO_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
A GNUNET_NAMESTORE_RecordIterator for monitors.
static void run_zone_iteration_round(struct ZoneIteration *zi, uint64_t limit)
Perform the next round of the zone iteration.
static void monitor_unblock(struct ZoneMonitor *zm)
Function called when the monitor is ready for more data, and we should thus unblock PUT operations th...
static void handle_record_store(void *cls, const struct RecordStoreMessage *rp_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message.
static const struct GNUNET_CRYPTO_PrivateKey zero
Public key of all zeros.
static void monitor_sync(struct ZoneMonitor *zm)
Send 'sync' message to zone monitor, we're now in sync.
static void handle_zone_to_name_it(void *cls, uint64_t seq, const char *editor_hint, const struct GNUNET_CRYPTO_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Zone to name iterator.
static void handle_monitor_next(void *cls, const struct ZoneMonitorNextMessage *nm)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_NEXT message.
static struct GNUNET_NotificationContext * monitor_nc
Notification context shared by all monitors.
struct GNUNET_NAMESTORE_PluginFunctions * GSN_database
Database handle for service.
static void cleanup_task(void *cls)
Task run during shutdown.
static char * db_lib_name
Name of the database plugin.
static int check_record_store(void *cls, const struct RecordStoreMessage *rp_msg)
Checks a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message.
static struct GNUNET_STATISTICS_Handle * statistics
Handle to the statistics service.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
Add a client to our list of active clients.
static void merge_with_nick_records(const struct GNUNET_GNSRECORD_Data *nick_rd, unsigned int rd2_length, const struct GNUNET_GNSRECORD_Data *rd2, unsigned int *rdc_res, struct GNUNET_GNSRECORD_Data **rd_res)
Merge the nick record nick_rd with the rest of the record set given in rd2.
static struct StoreActivity * sa_head
Head of DLL of monitor-blocked store activities.
static void handle_record_lookup(void *cls, const struct LabelLookupMessage *ll_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message.
static void free_store_activity(struct StoreActivity *sa)
Release memory used by sa.
static void handle_zone_to_name(void *cls, const struct ZoneToNameMessage *ztn_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME message.
static int continue_store_activity(struct StoreActivity *sa, int call_continue)
Continue processing the sa.
static struct ZoneMonitor * monitor_head
First active zone monitor.
static int check_record_lookup(void *cls, const struct LabelLookupMessage *ll_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message.
static void zone_iterate_proc(void *cls, uint64_t seq, const char *editor_hint, const struct GNUNET_CRYPTO_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process results for zone iteration from database.
static void zone_iteration_done_client_continue(struct ZoneIteration *zi)
Function called once we are done with the zone iteration and allow the zone iteration client to send ...
#define MONITOR_STALL_WARN_DELAY
If a monitor takes more than 1 minute to process an event, print a warning.
static enum GNUNET_GenericReturnValue check_zone_to_name(void *cls, const struct ZoneToNameMessage *zis_msg)
static enum GNUNET_ErrorCode store_record_set(struct NamestoreClient *nc, const struct GNUNET_CRYPTO_PrivateKey *private_key, const struct RecordSet *rd_set, ssize_t *len)
static void monitor_iteration_next(void *cls)
Obtain the next datum during the zone monitor's zone initial iteration.
static void handle_edit_record_set_cancel(void *cls, const struct EditRecordSetCancelMessage *er_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_SET_EDIT_CANCEL message.
static const struct GNUNET_CONFIGURATION_Handle * GSN_cfg
Configuration handle.
static void cache_nick(const struct GNUNET_CRYPTO_PrivateKey *zone, const struct GNUNET_GNSRECORD_Data *nick)
Add entry to the cache for zone and nick.
static void send_store_response(struct NamestoreClient *nc, enum GNUNET_ErrorCode ec, uint32_t rid)
Send response to the store request to the client.
static void handle_monitor_start(void *cls, const struct ZoneMonitorStartMessage *zis_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START message.
#define NC_SIZE
Size of the cache used by get_nick_record()
static struct ZoneMonitor * monitor_tail
Last active zone monitor.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
Called whenever a client is disconnected.
static struct NickCache nick_cache[16]
We cache nick records to reduce DB load.
static void handle_iteration_next(void *cls, const struct ZoneIterationNextMessage *zis_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT message.
static void handle_edit_record_set(void *cls, const struct EditRecordSetMessage *er_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_SET_EDIT message.
static void warn_monitor_slow(void *cls)
Print a warning that one of our monitors is no longer reacting.
static void get_existing_rd_exp(void *cls, uint64_t seq, const char *editor_hint, const struct GNUNET_CRYPTO_PrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Check if set contains a tombstone, store if necessary.
static int check_edit_record_set_cancel(void *cls, const struct EditRecordSetCancelMessage *er_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_SET_EDIT_CANCEL message.
static int send_lookup_response_with_filter(struct NamestoreClient *nc, uint32_t request_id, const struct GNUNET_CRYPTO_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, enum GNUNET_GNSRECORD_Filter filter)
Generate a struct LookupNameResponseMessage and send it to the given client using the given notificat...
static enum GNUNET_GenericReturnValue check_monitor_start(void *cls, const struct ZoneMonitorStartMessage *zis_msg)
static void lookup_nick_it(void *cls, uint64_t seq, const char *editor_hint, const struct GNUNET_CRYPTO_PrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Function called with the records for the GNUNET_GNS_EMPTY_LABEL_AT label in the zone.
GNUNET_SERVICE_MAIN("namestore", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(record_store, GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE, struct RecordStoreMessage, NULL), GNUNET_MQ_hd_var_size(edit_record_set, GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_SET_EDIT, struct EditRecordSetMessage, NULL), GNUNET_MQ_hd_var_size(edit_record_set_cancel, GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_SET_EDIT_CANCEL, struct EditRecordSetCancelMessage, NULL), GNUNET_MQ_hd_var_size(record_lookup, GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP, struct LabelLookupMessage, NULL), GNUNET_MQ_hd_var_size(zone_to_name, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME, struct ZoneToNameMessage, NULL), GNUNET_MQ_hd_var_size(iteration_start, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START, struct ZoneIterationStartMessage, NULL), GNUNET_MQ_hd_fixed_size(iteration_next, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT, struct ZoneIterationNextMessage, NULL), GNUNET_MQ_hd_fixed_size(iteration_stop, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP, struct ZoneIterationStopMessage, NULL), GNUNET_MQ_hd_var_size(monitor_start, GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START, struct ZoneMonitorStartMessage, NULL), GNUNET_MQ_hd_fixed_size(monitor_next, GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_NEXT, struct ZoneMonitorNextMessage, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
Process namestore requests.
static void lookup_it(void *cls, uint64_t seq, const char *editor_hint, const struct GNUNET_CRYPTO_PrivateKey *private_key, const char *label, unsigned int rd_count_nf, const struct GNUNET_GNSRECORD_Data *rd_nf)
Function called by the namestore plugin when we are trying to lookup a record as part of handle_recor...
static struct GNUNET_TIME_Relative duration
Option '-d': duration of the mapping.
Definition: gnunet-vpn.c:90
API that can be used to manipulate GNS record data.
Plugin API for the namestore database backend.
Constants for network protocols.
API to create, modify and access statistics.
#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.
#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.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_label_check(const char *label, char **emsg)
Check label for invalid characters.
const char * GNUNET_GNSRECORD_z2s(const struct GNUNET_CRYPTO_PublicKey *z)
Convert a zone to a string (for printing debug messages).
int GNUNET_GNSRECORD_records_deserialize(size_t len, const char *src, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *dest)
Deserialize the given records to the given destination.
ssize_t GNUNET_GNSRECORD_records_serialize(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, size_t dest_size, char *dest)
Serialize the given records to the given destination buffer.
ssize_t GNUNET_GNSRECORD_records_get_size(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Calculate how many bytes we will need to serialize the given records.
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
char * GNUNET_GNSRECORD_string_normalize(const char *src)
Normalize a UTF-8 string to a GNS name.
GNUNET_GNSRECORD_Filter
Filter for GNUNET_GNSRECORD_normalize_record_set().
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_normalize_record_set(const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *rd_public, unsigned int *rd_count_public, struct GNUNET_TIME_Absolute *min_expiry, enum GNUNET_GNSRECORD_Filter filter, char **emsg)
Normalize namestore records: Check for consistency and expirations.
@ GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION
This expiration time of the record is a relative time (not an absolute time).
@ GNUNET_GNSRECORD_RF_SUPPLEMENTAL
This is a supplemental record.
@ GNUNET_GNSRECORD_RF_MAINTENANCE
Maintenance records.
@ GNUNET_GNSRECORD_RF_PRIVATE
This is a private record of this peer and it should thus not be published.
@ GNUNET_GNSRECORD_FILTER_NONE
No filter flags set.
@ GNUNET_GNSRECORD_FILTER_INCLUDE_MAINTENANCE
Include maintenance records (TOMBSTONE etc).
@ GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE
Filter private records.
#define GNUNET_is_zero(a)
Check that memory in a is all zeros.
#define GNUNET_log(kind,...)
#define GNUNET_NZL(l)
Macro used to avoid using 0 for the length of a variable-size array (Non-Zero-Length).
#define GNUNET_LOG_CALL_STATUS
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_key_get_public(const struct GNUNET_CRYPTO_PrivateKey *privkey, struct GNUNET_CRYPTO_PublicKey *key)
Retrieves the public key representation of a private key.
Definition: crypto_pkey.c:430
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:54
int GNUNET_get_log_call_status(int caller_level, const char *comp, const char *file, const char *function, int line)
Decides whether a particular logging call should or should not be allowed to be made.
ssize_t GNUNET_CRYPTO_private_key_get_length(const struct GNUNET_CRYPTO_PrivateKey *key)
Get the compacted length of a GNUNET_CRYPTO_PrivateKey.
Definition: crypto_pkey.c:64
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
ssize_t GNUNET_CRYPTO_write_private_key_to_buffer(const struct GNUNET_CRYPTO_PrivateKey *key, void *buffer, size_t len)
Writes a GNUNET_CRYPTO_PrivateKey to a compact buffer.
Definition: crypto_pkey.c:172
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_read_public_key_from_buffer(const void *buffer, size_t len, struct GNUNET_CRYPTO_PublicKey *key, size_t *read)
Reads a GNUNET_CRYPTO_PublicKey from a compact buffer.
Definition: crypto_pkey.c:102
GNUNET_GenericReturnValue
Named constants for return values.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_read_private_key_from_buffer(const void *buffer, size_t len, struct GNUNET_CRYPTO_PrivateKey *key, size_t *read)
Reads a GNUNET_CRYPTO_PrivateKey from a compact buffer.
Definition: crypto_pkey.c:146
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
#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.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_BULK
@ GNUNET_ERROR_TYPE_DEBUG
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_malloc(size)
Wrapper around malloc.
#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.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:63
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
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_NAMESTORE_RECORD_RESULT_END
Service to client: end of list of results.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
Service to client: here is a (plaintext) record you requested.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_SET_EDIT
Message type for start of record edit with advisory lock.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE
Service to client: result of zone-to-name lookup.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_GENERIC_RESPONSE
Service to client: result of store operation.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_SET_EDIT_CANCEL
Message type for cancellation/reset of editor hint/advisory lock.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT
Client to service: next record(s) in iteration please.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START
Client to service: please start iteration; receives "GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPON...
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP
Client to service: stop iterating.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE
Service to client: lookup label.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_SET_EDIT_RESPONSE
Return record set to edit with previous editor hint/advisory lock.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE
Client to service: store records (as authority)
#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_NEXT
Client to service: I am now ready for the next (set of) monitor events.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START
Client to service: start monitoring (yields sequence of "ZONE_ITERATION_RESPONSES" — forever).
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME
Client to service: "reverse" lookup for zone name based on zone key.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_SYNC
Service to client: you're now in sync.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP
Client to service: lookup label.
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:1338
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:979
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:1303
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:1276
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the 'monitor' flag on this client.
Definition: service.c:2442
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2377
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2348
@ GNUNET_SERVICE_OPTION_NONE
Use defaults.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
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
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
#define GNUNET_TIME_absolute_cmp(t1, op, t2)
Compare two absolute times.
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
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:552
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:640
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:640
common internal definitions for namestore service
static unsigned int size
Size of the "table".
Definition: peer.c:68
static int zone_to_name(void *cls, const struct GNUNET_HashCode *key, void *value)
#define GNUNET_GNSRECORD_TYPE_NICK
GNS zone nickname.
#define GNUNET_GNSRECORD_TYPE_TOMBSTONE
Record type to indicate a previously delete record (PRIVATE only)
GNUNET_ErrorCode
Taler error codes.
@ GNUNET_EC_NAMESTORE_NO_RESULTS
No results given.
@ GNUNET_EC_NAMESTORE_LABEL_INVALID
Label invalid or malformed.
@ GNUNET_EC_NAMESTORE_BACKEND_FAILED
There was an error in the database backend.
@ GNUNET_EC_NAMESTORE_RECORD_TOO_BIG
Record size exceeds maximum limit.
@ GNUNET_EC_NAMESTORE_STORE_FAILED
Failed to store the given records.
@ GNUNET_EC_NAMESTORE_RECORD_DATA_INVALID
Record data invalid.
@ GNUNET_EC_NAMESTORE_ZONE_NOT_FOUND
Zone not found.
@ GNUNET_EC_NONE
No error (success).
@ GNUNET_EC_NAMESTORE_UNKNOWN
Unknown namestore error.
@ GNUNET_EC_NAMESTORE_RECORD_NOT_FOUND
Record not found.
Edit a record set and set editor hint/advisory lock.
Definition: namestore.h:253
struct GNUNET_NAMESTORE_Header gns_header
Type will be #GNUNET_MESSAGE_TYPE_NAMESTORE_EDIT_RECORD_SET_CANCEL.
Definition: namestore.h:257
uint16_t editor_hint_len
Unused.
Definition: namestore.h:267
uint16_t label_len
Length of the name.
Definition: namestore.h:262
uint16_t key_len
Length of the zone key.
Definition: namestore.h:277
Edit a record set and set editor hint/advisory lock.
Definition: namestore.h:215
struct GNUNET_NAMESTORE_Header gns_header
Type will be #GNUNET_MESSAGE_TYPE_NAMESTORE_EDIT_RECORD_SET.
Definition: namestore.h:219
uint16_t editor_hint_len
Unused.
Definition: namestore.h:229
uint16_t label_len
Length of the name.
Definition: namestore.h:224
uint16_t key_len
Length of the zone key.
Definition: namestore.h:239
Response to RecordSetEditMessage.
Definition: namestore.h:142
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_SET_EDIT_RESPONSE.
Definition: namestore.h:146
uint16_t editor_hint_len
Length of the editor hint.
Definition: namestore.h:151
uint16_t rd_count
Number of records contained.
Definition: namestore.h:166
uint16_t ec
Reserved.
Definition: namestore.h:156
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:161
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
uint32_t record_type
Type of the GNS/DNS record.
const void * data
Binary value stored in the DNS record.
size_t data_size
Number of bytes in data.
enum GNUNET_GNSRECORD_Flags flags
Flags for the record.
uint64_t expiration_time
Expiration time for the DNS record.
Handle to a message queue.
Definition: mq.c:87
Header for all communications.
Generic namestore message with op id.
Definition: namestore.h:41
uint32_t r_id
Request ID in NBO.
Definition: namestore.h:51
struct GNUNET_MessageHeader header
header.type will be GNUNET_MESSAGE_TYPE_NAMESTORE_* header.size will be message size
Definition: namestore.h:46
struct returned by the initialization function of the plugin
enum GNUNET_GenericReturnValue(* lookup_records)(void *cls, const struct GNUNET_CRYPTO_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Lookup records in the datastore for which we are the authority.
void * cls
Closure to pass to all plugin functions.
struct GNUNET_MQ_Handle * mq
Handle to namestore service.
enum GNUNET_GNSRECORD_Filter filter
Record set filter for this monitor.
struct GNUNET_CRYPTO_PrivateKey zone
Monitored zone.
The notification context is the key datastructure for a convenience API used for transmission of noti...
Definition: nc.c:77
Entry in list of pending tasks.
Definition: scheduler.c:135
Handle to a client that is connected to a service.
Definition: service.c:245
Handle to a service.
Definition: service.c:116
Handle for the service.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Lookup a label.
Definition: namestore.h:179
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP.
Definition: namestore.h:183
uint16_t key_len
Length of the zone key.
Definition: namestore.h:203
uint16_t filter
The record filter.
Definition: namestore.h:198
uint16_t label_len
Length of the name.
Definition: namestore.h:188
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:306
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE.
Definition: namestore.h:296
uint16_t reserved
Reserved (alignment)
Definition: namestore.h:322
uint16_t key_len
Length of the zone key.
Definition: namestore.h:327
uint16_t rd_count
Number of records contained.
Definition: namestore.h:311
uint16_t name_len
Name length.
Definition: namestore.h:301
int16_t found
Was the label found in the database?? GNUNET_YES or GNUNET_NO.
Definition: namestore.h:317
struct GNUNET_TIME_Absolute exp
The expiration of the existing records or tombstone.
int only_tombstone
Whether the existing record set consists only of a tombstone (e.g.
A namestore client.
struct ZoneIteration * op_head
Head of the DLL of Zone iteration operations in progress initiated by this client.
struct GNUNET_NAMESTORE_PluginFunctions * GSN_database
Database handle for client.
char * db_lib_name
Name of loaded plugin (needed for cleanup)
struct GNUNET_MQ_Handle * mq
Message queue for transmission to client.
struct GNUNET_SERVICE_Client * client
The client.
struct ZoneIteration * op_tail
Tail of the DLL of Zone iteration operations in progress initiated by this client.
Response to a record storage request.
Definition: namestore.h:125
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_GENERIC_RESPONSE.
Definition: namestore.h:129
uint32_t ec
GNUNET_ErrorCode.
Definition: namestore.h:134
Entry in list of cached nick resolutions.
struct GNUNET_GNSRECORD_Data * rd
Cached record data.
struct GNUNET_TIME_Absolute last_used
Timestamp when this cache entry was used last.
struct GNUNET_CRYPTO_PrivateKey zone
Zone the cache entry is for.
Closure for lookup_it().
char * editor_hint
The editor hint for set.
struct GNUNET_GNSRECORD_Data * nick
The nick for the zone.
char * res_rd
The record result.
const char * label
The label to look up.
int found
If a record set was found or not.
unsigned int res_rd_count
The number of found records.
ssize_t rd_ser_len
The length of the serialized records.
enum GNUNET_GNSRECORD_Filter filter
The record filter.
Record is returned from the namestore (as authority).
Definition: namestore.h:415
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:435
uint16_t name_len
Name length.
Definition: namestore.h:430
uint16_t rd_count
Number of records contained.
Definition: namestore.h:440
struct GNUNET_TIME_AbsoluteNBO expire
Expiration time if the record result (if any).
Definition: namestore.h:425
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT.
Definition: namestore.h:419
uint16_t key_len
Length of the zone key.
Definition: namestore.h:445
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:64
uint16_t rd_count
Number of records contained.
Definition: namestore.h:69
uint16_t name_len
Name length.
Definition: namestore.h:59
Store a record to the namestore (as authority).
Definition: namestore.h:87
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE.
Definition: namestore.h:91
uint16_t rd_set_count
Number of record sets.
Definition: namestore.h:107
uint16_t single_tx
GNUNET_YES if all sets should be stored in a single transaction (e.g.
Definition: namestore.h:102
uint16_t key_len
Length of the zone key.
Definition: namestore.h:112
Information for an ongoing handle_record_store() operation.
struct StoreActivity * next
Kept in a DLL.
uint32_t rid
The request ID.
const struct RecordSet * rs
Copy of the original record set (as data fields in rd will point into it!).
uint16_t rd_set_count
The number of records in this activity.
struct NamestoreClient * nc
Which client triggered the store activity?
uint16_t rd_set_pos
The currently processed record.
struct StoreActivity * prev
Kept in a DLL.
struct ZoneMonitor * zm_pos
Next zone monitor that still needs to be notified about this PUT.
struct GNUNET_CRYPTO_PrivateKey private_key
The zone private key.
Ask for next result of zone iteration for the given operation.
Definition: namestore.h:583
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT.
Definition: namestore.h:587
uint64_t limit
Number of records to return to the iterator in one shot (before GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_IT...
Definition: namestore.h:594
Context for record remove operations passed from run_zone_iteration_round to zone_iterate_proc as clo...
struct ZoneIteration * zi
The zone iteration handle.
int run_again
Skip a result and run again unless GNUNET_NO.
uint64_t limit
Number of results left to be returned in this iteration.
Start a zone iteration for the given zone.
Definition: namestore.h:556
uint16_t key_len
Length of the zone key.
Definition: namestore.h:571
uint16_t filter
Record set filter control flags.
Definition: namestore.h:566
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START.
Definition: namestore.h:560
Stop zone iteration for the given operation.
Definition: namestore.h:602
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP.
Definition: namestore.h:606
A namestore iteration operation.
struct NamestoreClient * nc
Namestore client which initiated this zone iteration.
uint64_t seq
Last sequence number in the zone iteration used to address next result of the zone iteration in the s...
struct GNUNET_GNSRECORD_Data * nick
The nick to add to the records.
enum GNUNET_GNSRECORD_Filter filter
The record set filter.
struct GNUNET_CRYPTO_PrivateKey zone
Key of the zone we are iterating over.
int send_end
Set to GNUNET_YES if the last iteration exhausted the limit set by the client and we should send the ...
uint32_t request_id
The operation id for the zone iteration in the response for the client.
struct ZoneIteration * prev
Previous element in the DLL.
uint32_t offset
Offset of the zone iteration used to address next result of the zone iteration in the store.
struct ZoneIteration * next
Next element in the DLL.
Ask for next result of zone iteration for the given operation.
Definition: namestore.h:532
uint64_t limit
Number of records to return to the iterator in one shot (before #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_M...
Definition: namestore.h:548
Start monitoring a zone.
Definition: namestore.h:499
uint32_t iterate_first
GNUNET_YES to first iterate over all records, GNUNET_NO to only monitor changes.o
Definition: namestore.h:509
uint16_t filter
Record set filter control flags.
Definition: namestore.h:515
uint16_t key_len
Length of the zone key.
Definition: namestore.h:520
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START.
Definition: namestore.h:503
A namestore monitor.
struct GNUNET_SCHEDULER_Task * sa_wait_warning
Task to warn about slow monitors.
struct GNUNET_TIME_Absolute sa_waiting_start
Since when are we blocked on this monitor?
int in_first_iteration
Are we (still) in the initial iteration pass?
enum GNUNET_GNSRECORD_Filter filter
The record set filter.
struct ZoneMonitor * prev
Previous element in the DLL.
int sa_waiting
Is there a store activity waiting for this monitor? We only raise the flag when it happens and search...
uint64_t iteration_cnt
How many more requests may we receive from the iterator before it is at the limit we gave it?...
uint64_t limit
Current limit of how many more messages we are allowed to queue to this monitor.
uint64_t seq
Last sequence number in the zone iteration used to address next result of the zone iteration in the s...
struct GNUNET_CRYPTO_PrivateKey zone
Private key of the zone.
struct GNUNET_SCHEDULER_Task * task
Task active during initial iteration.
struct NamestoreClient * nc
Namestore client which initiated this zone monitor.
int run_again
Run again because we skipped an orphan.
struct ZoneMonitor * next
Next element in the DLL.
Context for record remove operations passed from handle_zone_to_name to handle_zone_to_name_it as clo...
struct NamestoreClient * nc
Namestore client.
uint32_t rid
Request id (to be used in the response to the client).
enum GNUNET_ErrorCode ec
Set to GNUNET_OK on success, GNUNET_SYSERR on error.
Lookup a name for a zone hash.
Definition: namestore.h:341
uint16_t pkey_len
Length of the public value zone key.
Definition: namestore.h:355
uint16_t key_len
Length of the zone key.
Definition: namestore.h:350
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME.
Definition: namestore.h:345
Response for zone to name lookup.
Definition: namestore.h:369
uint16_t name_len
Length of the name.
Definition: namestore.h:386
int32_t ec
result in NBO: GNUNET_EC_NONE on success, GNUNET_EC_NAMESTORE_NO_RESULTS if there were no results.
Definition: namestore.h:381
uint16_t key_len
Length of the zone key.
Definition: namestore.h:401
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
Definition: namestore.h:373
uint16_t rd_count
Number of records contained.
Definition: namestore.h:396
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:391