GNUnet 0.21.2
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];
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 nick = get_nick_record (zone_key);
704
706 rd,
707 rd_count,
708 rd_nf,
709 &rd_nf_count,
710 &block_exp,
711 filter,
712 &emsg))
713 {
714 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
715 GNUNET_free (emsg);
716 GNUNET_assert (0);
717 }
718
723 if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT)))
724 {
725 nick->flags =
727 merge_with_nick_records (nick, rd_nf_count, rd_nf, &res_count, &res);
728 }
729 else
730 {
731 res_count = rd_nf_count;
732 res = (struct GNUNET_GNSRECORD_Data *) rd_nf;
733 }
734 if (NULL != nick)
735 GNUNET_free (nick);
736
737 if (0 == res_count)
738 {
739 if (rd_nf != res)
741 return 0;
742 }
744
745
746 name_len = strlen (name) + 1;
747 rd_ser_len = GNUNET_GNSRECORD_records_get_size (res_count, res);
748 if (rd_ser_len < 0)
749 {
750 if (rd_nf != res)
752 GNUNET_break (0);
754 return 0;
755 }
756 if (((size_t) rd_ser_len) >= UINT16_MAX - name_len - sizeof(*zir_msg))
757 {
758 if (rd_nf != res)
760 GNUNET_break (0);
762 return 0;
763 }
764 key_len = GNUNET_CRYPTO_private_key_get_length (zone_key);
765 env = GNUNET_MQ_msg_extra (zir_msg,
766 name_len + rd_ser_len + key_len,
768 zir_msg->gns_header.r_id = htonl (request_id);
769 zir_msg->name_len = htons (name_len);
770 zir_msg->rd_count = htons (res_count);
771 zir_msg->rd_len = htons ((uint16_t) rd_ser_len);
772 zir_msg->key_len = htons (key_len);
774 &zir_msg[1],
775 key_len);
776 zir_msg->expire = GNUNET_TIME_absolute_hton (block_exp);
777 name_tmp = (char *) &zir_msg[1] + key_len;
778 GNUNET_memcpy (name_tmp, name, name_len);
779 rd_ser = &name_tmp[name_len];
781 rd_ser_len ==
782 GNUNET_GNSRECORD_records_serialize (res_count, res, rd_ser_len, rd_ser));
784 "Sending RECORD_RESULT message with %u records\n",
785 res_count);
787 "Record sets sent to clients",
788 1,
789 GNUNET_NO);
790 GNUNET_MQ_send (nc->mq, env);
791 if (rd_nf != res)
793 return res_count;
794}
795
796
804static void
806 enum GNUNET_ErrorCode ec,
807 uint32_t rid)
808{
809 struct GNUNET_MQ_Envelope *env;
810 struct NamestoreResponseMessage *rcr_msg;
811
812 GNUNET_assert (NULL != nc);
814 "Sending GENERIC_RESPONSE message\n");
816 "Store requests completed",
817 1,
818 GNUNET_NO);
819 env = GNUNET_MQ_msg (rcr_msg,
821 rcr_msg->gns_header.r_id = htonl (rid);
822 rcr_msg->ec = htonl (ec);
823 GNUNET_MQ_send (nc->mq, env);
824}
825
826
833static void
835{
836 struct GNUNET_MQ_Envelope *env;
837 struct GNUNET_NAMESTORE_Header *em;
838
840 if (! zi->send_end)
841 return;
842 /* send empty response to indicate end of list */
844 em->r_id = htonl (zi->request_id);
845 GNUNET_MQ_send (zi->nc->mq, env);
846
848 GNUNET_free (zi);
849}
850
851
857static void
859{
860 struct ZoneMonitor *zm = cls;
861
863 "No response from monitor since %s\n",
864 GNUNET_STRINGS_absolute_time_to_string (zm->sa_waiting_start));
867 zm);
868}
869
870
876static int
878 int call_continue)
879{
880 const struct RecordSet *rd_set = sa->rs;
881 unsigned int rd_count;
882 size_t name_len;
883 size_t rd_ser_len;
884 const char *name;
885 const char *rd_ser;
886 const char *buf;
887
888 buf = (const char *) &sa[1];
889 for (int i = sa->rd_set_pos; i < sa->rd_set_count; i++)
890 {
891 rd_set = (struct RecordSet *) buf;
892 name_len = ntohs (rd_set->name_len);
893 rd_count = ntohs (rd_set->rd_count);
894 rd_ser_len = ntohs (rd_set->rd_len);
895 name = (const char *) &rd_set[1];
896 buf += sizeof (struct RecordSet) + name_len + rd_ser_len;
897 rd_ser = &name[name_len];
898 {
900
901 /* We did this before, must succeed again */
903 GNUNET_OK ==
905 rd));
906
908 "Checking monitors watching for `%s'\n",
909 name);
910 for (struct ZoneMonitor *zm = sa->zm_pos; NULL != zm; zm = sa->zm_pos)
911 {
912 if ((0 != GNUNET_memcmp (&sa->private_key, &zm->zone)) &&
913 (0 != GNUNET_memcmp (&zm->zone, &zero)))
914 {
915 sa->zm_pos = zm->next; /* not interesting to this monitor */
916 continue;
917 }
918 if (zm->limit == zm->iteration_cnt)
919 {
920 zm->sa_waiting = GNUNET_YES;
921 zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
922 if (NULL != zm->sa_wait_warning)
923 GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
924 zm->sa_wait_warning =
927 zm);
929 "Monitor is blocking client for `%s'\n",
930 name);
931 return GNUNET_NO; /* blocked on zone monitor */
932 }
934 "Notifying monitor about changes under label `%s'\n",
935 name);
937 0,
938 &sa->private_key,
939 name,
940 rd_count,
941 rd,
942 zm->filter))
943 zm->limit--;
944 sa->zm_pos = zm->next;
945 }
946 sa->rd_set_pos++;
947 }
948 }
949 if (GNUNET_YES == call_continue)
953 return GNUNET_OK;
954}
955
956
965static void
967 struct GNUNET_SERVICE_Client *client,
968 void *app_ctx)
969{
970 struct NamestoreClient *nc = app_ctx;
971 struct ZoneIteration *no;
972 struct StoreActivity *sa = sa_head;
973 struct StoreActivity *sn;
974
975 (void) cls;
976 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
977 for (struct ZoneMonitor *zm = monitor_head; NULL != zm; zm = zm->next)
978 {
979 if (nc != zm->nc)
980 continue;
982 if (NULL != zm->task)
983 {
985 zm->task = NULL;
986 }
987 if (NULL != zm->sa_wait_warning)
988 {
989 GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
990 zm->sa_wait_warning = NULL;
991 }
992 for (sa = sa_head; NULL != sa; sa = sn)
993 {
994 sn = sa->next;
995 if (zm == sa->zm_pos)
996 {
997 sa->zm_pos = zm->next;
998 /* this may free sa */
1000 }
1001 }
1002 GNUNET_free (zm);
1003 break;
1004 }
1005 sa = sa_head;
1006 while (NULL != sa)
1007 {
1008 if (nc != sa->nc)
1009 {
1010 sa = sa->next;
1011 continue;
1012 }
1013 sn = sa->next;
1015 sa = sn;
1016 }
1017 while (NULL != (no = nc->op_head))
1018 {
1019 GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no);
1020 GNUNET_free (no);
1021 }
1022 GNUNET_break (NULL == GNUNET_PLUGIN_unload (nc->db_lib_name,
1023 nc->GSN_database));
1024 GNUNET_free (nc->db_lib_name);
1025 GNUNET_free (nc);
1026}
1027
1028
1037static void *
1039 struct GNUNET_SERVICE_Client *client,
1040 struct GNUNET_MQ_Handle *mq)
1041{
1042 struct NamestoreClient *nc;
1043 char *database;
1044
1045 (void) cls;
1046 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1047 nc = GNUNET_new (struct NamestoreClient);
1048 nc->client = client;
1049 nc->mq = mq;
1050 /* Loading database plugin */
1052 "namestore",
1053 "database",
1054 &database))
1055 {
1056 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
1057 GNUNET_free (nc);
1058 return NULL;
1059 }
1061 nc->GSN_database = GNUNET_PLUGIN_load (db_lib_name, (void *) GSN_cfg);
1062 GNUNET_free (database);
1063 if (NULL == nc->GSN_database)
1064 {
1066 "Could not load database backend `%s'\n",
1067 db_lib_name);
1068 GNUNET_free (nc);
1069 return NULL;
1070 }
1071 nc->db_lib_name = GNUNET_strdup (db_lib_name);
1073 return nc;
1074}
1075
1076
1081{
1085 const char *label;
1086
1091
1095 char *res_rd;
1096
1101
1106
1111
1115 unsigned int res_rd_count;
1116
1120 ssize_t rd_ser_len;
1121};
1122
1123
1136static void
1137lookup_it (void *cls,
1138 uint64_t seq,
1139 const char *editor_hint,
1140 const struct GNUNET_CRYPTO_PrivateKey *private_key,
1141 const char *label,
1142 unsigned int rd_count_nf,
1143 const struct GNUNET_GNSRECORD_Data *rd_nf)
1144{
1145 struct RecordLookupContext *rlc = cls;
1146 struct GNUNET_GNSRECORD_Data rd[rd_count_nf];
1147 struct GNUNET_TIME_Absolute block_exp;
1148 unsigned int rd_count = 0;
1149 char *emsg;
1150
1151 (void) private_key;
1152 GNUNET_assert (0 != seq);
1153 if (0 != strcmp (label, rlc->label))
1154 return;
1155 rlc->found = GNUNET_YES;
1156 if (NULL == rlc->editor_hint)
1157 rlc->editor_hint = GNUNET_strdup (editor_hint);
1159 rd_nf,
1160 rd_count_nf,
1161 rd,
1162 &rd_count,
1163 &block_exp,
1164 rlc->filter,
1165 &emsg))
1166 {
1167 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
1168 GNUNET_free (emsg);
1169 GNUNET_assert (0);
1170 }
1171
1172 if (0 == rd_count)
1173 {
1174 rlc->rd_ser_len = 0;
1175 rlc->res_rd_count = 0;
1176 rlc->res_rd = NULL;
1177 return;
1178 }
1179 if ((NULL != rlc->nick) && (0 != strcmp (label, GNUNET_GNS_EMPTY_LABEL_AT)))
1180 {
1181 /* Merge */
1182 struct GNUNET_GNSRECORD_Data *rd_res;
1183 unsigned int rdc_res;
1184
1185 rd_res = NULL;
1186 rdc_res = 0;
1189 merge_with_nick_records (rlc->nick, rd_count, rd, &rdc_res, &rd_res);
1190 rlc->rd_ser_len = GNUNET_GNSRECORD_records_get_size (rdc_res, rd_res);
1191 if (rlc->rd_ser_len < 0)
1192 {
1193 GNUNET_break (0);
1194 GNUNET_free (rd_res);
1195 rlc->found = GNUNET_NO;
1196 rlc->rd_ser_len = 0;
1197 return;
1198 }
1199 rlc->res_rd_count = rdc_res;
1200 rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1202 rd_res,
1203 rlc->rd_ser_len,
1204 rlc->res_rd))
1205 {
1206 GNUNET_break (0);
1207 GNUNET_free (rlc->res_rd);
1208 rlc->res_rd = NULL;
1209 rlc->res_rd_count = 0;
1210 rlc->rd_ser_len = 0;
1211 GNUNET_free (rd_res);
1212 rlc->found = GNUNET_NO;
1213 return;
1214 }
1215 GNUNET_free (rd_res);
1216 GNUNET_free (rlc->nick);
1217 rlc->nick = NULL;
1218 }
1219 else
1220 {
1222 if (rlc->rd_ser_len < 0)
1223 {
1224 GNUNET_break (0);
1225 rlc->found = GNUNET_NO;
1226 rlc->rd_ser_len = 0;
1227 return;
1228 }
1229 rlc->res_rd_count = rd_count;
1230 rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1232 rd,
1233 rlc->rd_ser_len,
1234 rlc->res_rd))
1235 {
1236 GNUNET_break (0);
1237 GNUNET_free (rlc->res_rd);
1238 rlc->res_rd = NULL;
1239 rlc->res_rd_count = 0;
1240 rlc->rd_ser_len = 0;
1241 rlc->found = GNUNET_NO;
1242 return;
1243 }
1244 }
1245}
1246
1247
1255static int
1256check_edit_record_set (void *cls, const struct EditRecordSetMessage *er_msg)
1257{
1258 uint16_t name_len;
1259 uint16_t editor_hint_len;
1260 size_t src_size;
1261 size_t key_len;
1262
1263 (void) cls;
1264 name_len = ntohs (er_msg->label_len);
1265 editor_hint_len = ntohs (er_msg->editor_hint_len);
1266 key_len = ntohs (er_msg->key_len);
1267 src_size = ntohs (er_msg->gns_header.header.size);
1268 if (name_len + editor_hint_len + key_len != src_size - sizeof(struct
1270 {
1271 GNUNET_break (0);
1272 return GNUNET_SYSERR;
1273 }
1274 return GNUNET_OK;
1275}
1276
1277
1284static void
1285handle_edit_record_set (void *cls, const struct EditRecordSetMessage *er_msg)
1286{
1287 struct GNUNET_CRYPTO_PrivateKey zone;
1288 struct NamestoreClient *nc = cls;
1289 struct GNUNET_MQ_Envelope *env;
1290 struct EditRecordSetResponseMessage *rer_msg;
1291 struct RecordLookupContext rlc;
1292 const char *name_tmp;
1293 const char *editor_hint;
1294 char *conv_name;
1295 uint16_t name_len;
1296 uint16_t old_editor_hint_len;
1297 int res;
1298 size_t key_len;
1299 size_t kb_read;
1300
1301 key_len = ntohs (er_msg->key_len);
1302 name_len = ntohs (er_msg->label_len);
1303 if ((GNUNET_SYSERR ==
1305 key_len,
1306 &zone,
1307 &kb_read)) ||
1308 (kb_read != key_len))
1309 {
1311 "Error reading private key\n");
1313 return;
1314 }
1315 name_tmp = (const char *) &er_msg[1] + key_len;
1316 editor_hint = (const char *) name_tmp + name_len;
1319 "Received NAMESTORE_RECORD_SET_EDIT message for name `%s'\n",
1320 name_tmp);
1321
1322 conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
1323 if (NULL == conv_name)
1324 {
1326 "Error converting name `%s'\n",
1327 name_tmp);
1329 return;
1330 }
1331 name_len = strlen (conv_name) + 1;
1332 rlc.editor_hint = NULL;
1333 rlc.label = conv_name;
1335 "Looking up without filter\n");
1337 rlc.found = GNUNET_NO;
1338 rlc.res_rd_count = 0;
1339 rlc.res_rd = NULL;
1340 rlc.rd_ser_len = 0;
1341 rlc.nick = get_nick_record (&zone);
1342 res = nc->GSN_database->edit_records (nc->GSN_database->cls,
1344 &zone,
1345 conv_name,
1346 &lookup_it,
1347 &rlc);
1348
1349 old_editor_hint_len = 0;
1350 if (NULL != rlc.editor_hint)
1351 old_editor_hint_len = strlen (rlc.editor_hint) + 1;
1352 env =
1353 GNUNET_MQ_msg_extra (rer_msg,
1354 rlc.rd_ser_len + old_editor_hint_len,
1356 ;
1357 rer_msg->editor_hint_len = htons (old_editor_hint_len);
1358 rer_msg->gns_header.r_id = er_msg->gns_header.r_id;
1359 rer_msg->rd_count = htons (rlc.res_rd_count);
1360 rer_msg->rd_len = htons (rlc.rd_ser_len);
1361 if (GNUNET_YES == rlc.found)
1362 rer_msg->ec = htons (GNUNET_EC_NONE);
1363 else if (GNUNET_SYSERR == res)
1364 rer_msg->ec = htons (GNUNET_EC_NAMESTORE_UNKNOWN);
1365 else
1366 rer_msg->ec = htons (GNUNET_EC_NAMESTORE_NO_RESULTS);
1367 GNUNET_memcpy (&rer_msg[1], rlc.editor_hint, old_editor_hint_len);
1368 GNUNET_memcpy ((char*) &rer_msg[1] + old_editor_hint_len, rlc.res_rd,
1369 rlc.rd_ser_len);
1370 GNUNET_MQ_send (nc->mq, env);
1372 GNUNET_free (rlc.res_rd);
1373 GNUNET_free (conv_name);
1374}
1375
1376
1384static int
1385check_edit_record_set_cancel (void *cls, const struct
1387{
1388 uint16_t name_len;
1389 uint16_t editor_hint_len;
1390 uint16_t editor_hint_repl_len;
1391 size_t src_size;
1392 size_t key_len;
1393
1394 (void) cls;
1395 name_len = ntohs (er_msg->label_len);
1396 editor_hint_len = ntohs (er_msg->editor_hint_len);
1397 editor_hint_repl_len = ntohs (er_msg->editor_hint_len);
1398 key_len = ntohs (er_msg->key_len);
1399 src_size = ntohs (er_msg->gns_header.header.size);
1400 if (name_len + editor_hint_len + editor_hint_repl_len + key_len != src_size
1401 - sizeof(struct
1403 {
1404 GNUNET_break (0);
1405 return GNUNET_SYSERR;
1406 }
1407 return GNUNET_OK;
1408}
1409
1410
1417static void
1418handle_edit_record_set_cancel (void *cls, const struct
1420{
1421 struct GNUNET_CRYPTO_PrivateKey zone;
1422 struct NamestoreClient *nc = cls;
1423 struct GNUNET_MQ_Envelope *env;
1424 struct NamestoreResponseMessage *rer_msg;
1425 const char *name_tmp;
1426 const char *editor_hint;
1427 const char *editor_hint_repl;
1428 char *conv_name;
1429 uint16_t name_len;
1430 uint16_t editor_hint_len;
1431 int res;
1432 size_t key_len;
1433 size_t kb_read;
1434
1435 key_len = ntohs (er_msg->key_len);
1436 name_len = ntohs (er_msg->label_len);
1437 editor_hint_len = ntohs (er_msg->editor_hint_len);
1438 if ((GNUNET_SYSERR ==
1440 key_len,
1441 &zone,
1442 &kb_read)) ||
1443 (kb_read != key_len))
1444 {
1446 "Error reading private key\n");
1448 return;
1449 }
1450 name_tmp = (const char *) &er_msg[1] + key_len;
1451 editor_hint = (const char *) name_tmp + name_len;
1452 editor_hint_repl = (const char *) name_tmp + name_len + editor_hint_len;
1455 "Received NAMESTORE_RECORD_SET_EDIT message for name `%s'\n",
1456 name_tmp);
1457
1458 conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
1459 if (NULL == conv_name)
1460 {
1462 "Error converting name `%s'\n",
1463 name_tmp);
1465 return;
1466 }
1467 name_len = strlen (conv_name) + 1;
1469 "Clearing editor hint\n");
1470 res = nc->GSN_database->clear_editor_hint (nc->GSN_database->cls,
1471 editor_hint,
1472 editor_hint_repl,
1473 &zone,
1474 conv_name);
1476 "Clearing editor hint %s\n", (GNUNET_SYSERR == res) ? "failed." :
1477 "successful.");
1478
1479 env =
1480 GNUNET_MQ_msg (rer_msg,
1482 rer_msg->gns_header.r_id = er_msg->gns_header.r_id;
1483 rer_msg->ec = htons ((GNUNET_OK == res) ? GNUNET_EC_NONE :
1485 GNUNET_MQ_send (nc->mq, env);
1486 GNUNET_free (conv_name);
1487}
1488
1489
1497static int
1498check_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
1499{
1500 uint32_t name_len;
1501 size_t src_size;
1502 size_t key_len;
1503
1504 (void) cls;
1505 name_len = ntohs (ll_msg->label_len);
1506 key_len = ntohs (ll_msg->key_len);
1507 src_size = ntohs (ll_msg->gns_header.header.size);
1508 if (name_len + key_len != src_size - sizeof(struct LabelLookupMessage))
1509 {
1510 GNUNET_break (0);
1511 return GNUNET_SYSERR;
1512 }
1513 return GNUNET_OK;
1514}
1515
1516
1523static void
1524handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
1525{
1526 struct GNUNET_CRYPTO_PrivateKey zone;
1527 struct NamestoreClient *nc = cls;
1528 struct GNUNET_MQ_Envelope *env;
1529 struct LabelLookupResponseMessage *llr_msg;
1530 struct RecordLookupContext rlc;
1531 const char *name_tmp;
1532 char *res_name;
1533 char *conv_name;
1534 uint32_t name_len;
1535 int res;
1536 size_t key_len;
1537 size_t kb_read;
1538
1539 key_len = ntohs (ll_msg->key_len);
1540 if ((GNUNET_SYSERR ==
1542 key_len,
1543 &zone,
1544 &kb_read)) ||
1545 (kb_read != key_len))
1546 {
1548 "Error reading private key\n");
1550 return;
1551 }
1552 name_tmp = (const char *) &ll_msg[1] + key_len;
1555 "Received NAMESTORE_RECORD_LOOKUP message for name `%s'\n",
1556 name_tmp);
1557
1558 conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
1559 if (NULL == conv_name)
1560 {
1562 "Error converting name `%s'\n",
1563 name_tmp);
1565 return;
1566 }
1567 name_len = strlen (conv_name) + 1;
1568 rlc.editor_hint = NULL;
1569 rlc.label = conv_name;
1571 "Looking up with filter %u\n", ntohs (ll_msg->filter));
1572 rlc.filter = ntohs (ll_msg->filter);
1573 rlc.found = GNUNET_NO;
1574 rlc.res_rd_count = 0;
1575 rlc.res_rd = NULL;
1576 rlc.rd_ser_len = 0;
1577 rlc.nick = get_nick_record (&zone);
1578 res = nc->GSN_database->lookup_records (nc->GSN_database->cls,
1579 &zone,
1580 conv_name,
1581 &lookup_it,
1582 &rlc);
1583 env =
1584 GNUNET_MQ_msg_extra (llr_msg,
1585 key_len + name_len + rlc.rd_ser_len,
1587 llr_msg->gns_header.r_id = ll_msg->gns_header.r_id;
1588 GNUNET_memcpy (&llr_msg[1], &ll_msg[1], key_len);
1589 llr_msg->key_len = ll_msg->key_len;
1590 llr_msg->name_len = htons (name_len);
1591 llr_msg->rd_count = htons (rlc.res_rd_count);
1592 llr_msg->rd_len = htons (rlc.rd_ser_len);
1593 llr_msg->reserved = htons (0);
1594 res_name = ((char *) &llr_msg[1]) + key_len;
1595 if (GNUNET_YES == rlc.found)
1596 llr_msg->found = htons (GNUNET_YES);
1597 else if (GNUNET_SYSERR == res)
1598 llr_msg->found = htons (GNUNET_SYSERR);
1599 else
1600 llr_msg->found = htons (GNUNET_NO);
1601 GNUNET_memcpy (res_name, conv_name, name_len);
1602 GNUNET_memcpy (&res_name[name_len], rlc.res_rd, rlc.rd_ser_len);
1603 GNUNET_MQ_send (nc->mq, env);
1605 GNUNET_free (rlc.res_rd);
1606 GNUNET_free (conv_name);
1607}
1608
1609
1617static int
1618check_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1619{
1620 size_t msg_size;
1621 size_t min_size_exp;
1622 size_t rd_set_count;
1623 size_t key_len;
1624
1625 (void) cls;
1626 msg_size = ntohs (rp_msg->gns_header.header.size);
1627 rd_set_count = ntohs (rp_msg->rd_set_count);
1628 key_len = ntohs (rp_msg->key_len);
1629
1630 min_size_exp = sizeof(*rp_msg) + key_len + sizeof (struct RecordSet)
1631 * rd_set_count;
1632 if (msg_size < min_size_exp)
1633 {
1634 GNUNET_break (0);
1635 return GNUNET_SYSERR;
1636 }
1637 return GNUNET_OK;
1638}
1639
1640
1642{
1643
1648
1654
1655};
1656
1657
1668static void
1670 uint64_t seq,
1671 const char *editor_hint,
1672 const struct
1673 GNUNET_CRYPTO_PrivateKey *private_key,
1674 const char *label,
1675 unsigned int rd_count,
1676 const struct GNUNET_GNSRECORD_Data *rd)
1677{
1678 struct LookupExistingRecordsContext *lctx = cls;
1679 struct GNUNET_GNSRECORD_Data rd_pub[rd_count];
1680 unsigned int rd_pub_count;
1681 char *emsg;
1682
1683 if ((1 == rd_count) &&
1685 {
1686 /* This record set contains only a tombstone! */
1687 lctx->only_tombstone = GNUNET_YES;
1688 }
1689 if (GNUNET_OK !=
1691 rd,
1692 rd_count,
1693 rd_pub,
1694 &rd_pub_count,
1695 &lctx->exp,
1697 &emsg))
1698 {
1700 "%s\n", emsg);
1701 GNUNET_free (emsg);
1702 }
1703}
1704
1705
1706static enum GNUNET_ErrorCode
1708 const struct GNUNET_CRYPTO_PrivateKey *private_key,
1709 const struct RecordSet *rd_set,
1710 ssize_t *len)
1711{
1712 size_t name_len;
1713 size_t rd_ser_len;
1714 const char *name_tmp;
1715 const char *rd_ser;
1716 char *emsg;
1717 char *conv_name;
1718 unsigned int rd_count;
1719 int res;
1720 enum GNUNET_ErrorCode ec;
1721 struct GNUNET_TIME_Absolute new_block_exp;
1722 struct LookupExistingRecordsContext lctx;
1723 *len = sizeof (struct RecordSet);
1724
1725 ec = GNUNET_EC_NONE;
1728 new_block_exp = GNUNET_TIME_UNIT_ZERO_ABS;
1729 name_len = ntohs (rd_set->name_len);
1730 *len += name_len;
1731 rd_count = ntohs (rd_set->rd_count);
1732 rd_ser_len = ntohs (rd_set->rd_len);
1733 *len += rd_ser_len;
1734 name_tmp = (const char *) &rd_set[1];
1735 rd_ser = &name_tmp[name_len];
1736 {
1738
1739 /* Extracting and converting private key */
1740 conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
1741 if (NULL == conv_name)
1742 {
1744 "Error normalizing name `%s'\n",
1745 name_tmp);
1747 }
1748
1749 /* Check name for validity */
1750 if (GNUNET_OK != GNUNET_GNSRECORD_label_check (conv_name, &emsg))
1751 {
1753 "Label invalid: `%s'\n",
1754 emsg);
1755 GNUNET_free (emsg);
1756 GNUNET_free (conv_name);
1758 }
1759
1760 if (GNUNET_OK !=
1762 rd))
1763 {
1764 GNUNET_free (conv_name);
1766 }
1767
1769 "Well-formed store requests received",
1770 1,
1771 GNUNET_NO);
1773 "Creating %u records for name `%s'\n",
1774 (unsigned int) rd_count,
1775 conv_name);
1776 if ((0 == rd_count) &&
1777 (GNUNET_NO == nc->GSN_database->lookup_records (nc->GSN_database->cls,
1778 private_key,
1779 conv_name,
1781 &lctx)))
1782 {
1783 /* This name does not exist, so cannot be removed */
1785 "Name `%s' does not exist, no deletion required\n",
1786 conv_name);
1787 res = GNUNET_NO;
1789 }
1790 else
1791 {
1792 /* remove "NICK" records, unless this is for the
1793 #GNUNET_GNS_EMPTY_LABEL_AT label
1794 We may need one additional record later for tombstone.
1795 FIXME: Since we must normalize the record set (check for
1796 consistency etc) we have to iterate the set twice.
1797 May be inefficient.
1798 We cannot really move the nick caching into GNSRECORD.
1799 */
1800 struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL (rd_count)];
1801 struct GNUNET_GNSRECORD_Data rd_nf[GNUNET_NZL (rd_count) + 1];
1802 unsigned int rd_clean_off;
1803 unsigned int rd_nf_count;
1804 int have_nick;
1805
1806 rd_clean_off = 0;
1807 have_nick = GNUNET_NO;
1808 for (unsigned int i = 0; i < rd_count; i++)
1809 {
1810 rd_clean[rd_clean_off] = rd[i];
1811
1812 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) ||
1814 rd_clean_off++;
1815
1816 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1818 {
1819 cache_nick (private_key, &rd[i]);
1820 have_nick = GNUNET_YES;
1821 }
1822 }
1823 if (GNUNET_OK !=
1825 rd_clean,
1826 rd_clean_off,
1827 rd_nf,
1828 &rd_nf_count,
1829 &new_block_exp,
1831 &emsg))
1832 {
1833 GNUNET_free (conv_name);
1835 "Error normalizing record set: `%s'\n",
1836 emsg);
1837 GNUNET_free (emsg);
1839 }
1841 "%u/%u records before tombstone\n", rd_nf_count,
1842 rd_clean_off);
1843 /*
1844 * If existing_block_exp is 0, then there was no record set
1845 * and no tombstone.
1846 * Otherwise, if the existing block expiration is after the
1847 * new block expiration would be, we need to add a tombstone
1848 * or update it.
1849 */
1850 if (GNUNET_TIME_absolute_cmp (new_block_exp, <=, lctx.exp))
1851 {
1852 rd_nf[rd_nf_count].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE;
1853 rd_nf[rd_nf_count].expiration_time =
1854 lctx.exp.abs_value_us;
1855 rd_nf[rd_nf_count].data = NULL;
1856 rd_nf[rd_nf_count].data_size = 0;
1857 rd_nf[rd_nf_count].flags = GNUNET_GNSRECORD_RF_PRIVATE
1859 rd_nf_count++;
1860 }
1861 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1862 (GNUNET_NO == have_nick))
1863 {
1864 cache_nick (private_key, NULL);
1865 }
1866 res = nc->GSN_database->store_records (nc->GSN_database->cls,
1867 private_key,
1868 conv_name,
1869 rd_nf_count,
1870 rd_nf);
1871 /* If after a store there is only a TOMBSTONE left, and
1872 * there was >1 record under this label found (the tombstone; indicated
1873 * through res != GNUNET_NO) then we should return "NOT FOUND" == GNUNET_NO
1874 */
1875 if ((GNUNET_SYSERR != res) &&
1876 (0 == rd_count) &&
1877 (1 == rd_nf_count) &&
1879 (GNUNET_YES == lctx.only_tombstone))
1880 {
1882 "Client tried to remove non-existent record\n");
1884 }
1885 }
1886
1887 if (GNUNET_SYSERR == res)
1888 {
1889 /* store not successful, no need to tell monitors */
1890 GNUNET_free (conv_name);
1892 }
1893 }
1894 return ec;
1895}
1896
1897
1904static void
1905handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1906{
1907 struct GNUNET_CRYPTO_PrivateKey zone;
1908 struct NamestoreClient *nc = cls;
1909 uint32_t rid;
1910 uint16_t rd_set_count;
1911 const char *buf;
1912 ssize_t read;
1913 size_t key_len;
1914 size_t kb_read;
1915 size_t rp_msg_len;
1916 size_t rs_len;
1917 size_t rs_off;
1918 struct StoreActivity *sa;
1919 struct RecordSet *rs;
1920 enum GNUNET_ErrorCode res;
1921
1922 key_len = ntohs (rp_msg->key_len);
1923 rp_msg_len = ntohs (rp_msg->gns_header.header.size);
1924 rs_off = sizeof (*rp_msg) + key_len;
1925 rs_len = rp_msg_len - rs_off;
1926 if ((GNUNET_SYSERR ==
1928 key_len,
1929 &zone,
1930 &kb_read)) ||
1931 (kb_read != key_len))
1932 {
1934 "Error reading private key\n");
1936 return;
1937 }
1939 "Received NAMESTORE_RECORD_STORE message\n");
1940 rid = ntohl (rp_msg->gns_header.r_id);
1941 rd_set_count = ntohs (rp_msg->rd_set_count);
1942 buf = (const char *) rp_msg + rs_off;
1943 if (GNUNET_YES == ntohs (rp_msg->single_tx))
1944 nc->GSN_database->begin_tx (nc->GSN_database->cls);
1945 for (int i = 0; i < rd_set_count; i++)
1946 {
1947 rs = (struct RecordSet *) buf;
1948 res = store_record_set (nc, &zone,
1949 rs, &read);
1950 if (GNUNET_EC_NONE != res)
1951 {
1952 if (GNUNET_YES == ntohs (rp_msg->single_tx))
1953 nc->GSN_database->rollback_tx (nc->GSN_database->cls);
1954 send_store_response (nc, res, rid);
1956 return;
1957 }
1958 buf += read;
1959 }
1960 if (GNUNET_YES == ntohs (rp_msg->single_tx))
1961 nc->GSN_database->commit_tx (nc->GSN_database->cls);
1962 sa = GNUNET_malloc (sizeof(struct StoreActivity) + rs_len);
1964 sa->nc = nc;
1965 sa->rs = (struct RecordSet *) &sa[1];
1966 sa->rd_set_count = rd_set_count;
1967 GNUNET_memcpy (&sa[1], (char *) rp_msg + rs_off, rs_len);
1968 sa->rid = rid;
1969 sa->rd_set_pos = 0;
1970 sa->private_key = zone;
1971 sa->zm_pos = monitor_head;
1973}
1974
1975
1981{
1986
1990 uint32_t rid;
1991
1998};
1999
2000
2011static void
2013 uint64_t seq,
2014 const char *editor_hint,
2015 const struct GNUNET_CRYPTO_PrivateKey *zone_key,
2016 const char *name,
2017 unsigned int rd_count,
2018 const struct GNUNET_GNSRECORD_Data *rd)
2019{
2020 struct ZoneToNameCtx *ztn_ctx = cls;
2021 struct GNUNET_MQ_Envelope *env;
2022 struct ZoneToNameResponseMessage *ztnr_msg;
2023 size_t name_len;
2024 size_t key_len;
2025 ssize_t rd_ser_len;
2026 size_t msg_size;
2027 char *name_tmp;
2028 char *rd_tmp;
2029
2030 GNUNET_assert (0 != seq);
2032 "Found result for zone-to-name lookup: `%s'\n",
2033 name);
2034 ztn_ctx->ec = GNUNET_EC_NONE;
2035 name_len = (NULL == name) ? 0 : strlen (name) + 1;
2037 if (rd_ser_len < 0)
2038 {
2039 GNUNET_break (0);
2040 ztn_ctx->ec = htonl (GNUNET_EC_NAMESTORE_UNKNOWN);
2041 return;
2042 }
2044 msg_size = sizeof(struct ZoneToNameResponseMessage)
2045 + name_len + rd_ser_len + key_len;
2046 if (msg_size >= GNUNET_MAX_MESSAGE_SIZE)
2047 {
2048 GNUNET_break (0);
2050 return;
2051 }
2052 env =
2053 GNUNET_MQ_msg_extra (ztnr_msg,
2054 key_len + name_len + rd_ser_len,
2056 ztnr_msg->gns_header.header.size = htons (msg_size);
2057 ztnr_msg->gns_header.r_id = htonl (ztn_ctx->rid);
2058 ztnr_msg->ec = htonl (ztn_ctx->ec);
2059 ztnr_msg->rd_len = htons (rd_ser_len);
2060 ztnr_msg->rd_count = htons (rd_count);
2061 ztnr_msg->name_len = htons (name_len);
2062 ztnr_msg->key_len = htons (key_len);
2064 &ztnr_msg[1],
2065 key_len);
2066 name_tmp = (char *) &ztnr_msg[1] + key_len;
2067 GNUNET_memcpy (name_tmp, name, name_len);
2068 rd_tmp = &name_tmp[name_len];
2070 rd_ser_len ==
2071 GNUNET_GNSRECORD_records_serialize (rd_count, rd, rd_ser_len, rd_tmp));
2072 ztn_ctx->ec = GNUNET_EC_NONE;
2073 GNUNET_MQ_send (ztn_ctx->nc->mq, env);
2074}
2075
2076
2077static enum GNUNET_GenericReturnValue
2079 const struct ZoneToNameMessage *zis_msg)
2080{
2081 return GNUNET_OK;
2082}
2083
2084
2091static void
2092handle_zone_to_name (void *cls, const struct ZoneToNameMessage *ztn_msg)
2093{
2094 struct GNUNET_CRYPTO_PrivateKey zone;
2095 struct GNUNET_CRYPTO_PublicKey value_zone;
2096 struct NamestoreClient *nc = cls;
2097 struct ZoneToNameCtx ztn_ctx;
2098 struct GNUNET_MQ_Envelope *env;
2099 struct ZoneToNameResponseMessage *ztnr_msg;
2100 size_t key_len;
2101 size_t pkey_len;
2102 size_t kb_read;
2103
2104 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_TO_NAME message\n");
2105 ztn_ctx.rid = ntohl (ztn_msg->gns_header.r_id);
2106 ztn_ctx.nc = nc;
2108 key_len = ntohs (ztn_msg->key_len);
2109 if ((GNUNET_SYSERR ==
2111 key_len,
2112 &zone,
2113 &kb_read)) ||
2114 (kb_read != key_len))
2115 {
2117 "Error parsing private key.\n");
2119 GNUNET_break (0);
2120 return;
2121 }
2122 pkey_len = ntohs (ztn_msg->pkey_len);
2123 if ((GNUNET_SYSERR ==
2125 + key_len,
2126 pkey_len,
2127 &value_zone,
2128 &kb_read)) ||
2129 (kb_read != pkey_len))
2130 {
2132 "Error parsing public key.\n");
2134 GNUNET_break (0);
2135 return;
2136 }
2137 if (GNUNET_SYSERR == nc->GSN_database->zone_to_name (nc->GSN_database->cls,
2138 &zone,
2139 &value_zone,
2141 &ztn_ctx))
2142 {
2143 /* internal error, hang up instead of signalling something
2144 that might be wrong */
2145 GNUNET_break (0);
2147 return;
2148 }
2150 {
2151 /* no result found, send empty response */
2153 "Found no result for zone-to-name lookup.\n");
2154 env = GNUNET_MQ_msg (ztnr_msg,
2156 ztnr_msg->gns_header.r_id = ztn_msg->gns_header.r_id;
2157 ztnr_msg->ec = htonl (GNUNET_EC_NAMESTORE_ZONE_NOT_FOUND);
2158 GNUNET_MQ_send (nc->mq, env);
2159 }
2161}
2162
2163
2169{
2174
2178 uint64_t limit;
2179
2184};
2185
2186
2197static void
2199 uint64_t seq,
2200 const char *editor_hint,
2201 const struct GNUNET_CRYPTO_PrivateKey *zone_key,
2202 const char *name,
2203 unsigned int rd_count,
2204 const struct GNUNET_GNSRECORD_Data *rd)
2205{
2206 struct ZoneIterationProcResult *proc = cls;
2207
2208 GNUNET_assert (0 != seq);
2209 if ((NULL == zone_key) && (NULL == name))
2210 {
2211 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
2212 return;
2213 }
2214 if ((NULL == zone_key) || (NULL == name))
2215 {
2216 /* what is this!? should never happen */
2217 GNUNET_break (0);
2218 return;
2219 }
2220 if (0 == proc->limit)
2221 {
2222 /* what is this!? should never happen */
2223 GNUNET_break (0);
2224 return;
2225 }
2226 proc->zi->seq = seq;
2227 if (0 < send_lookup_response_with_filter (proc->zi->nc,
2228 proc->zi->request_id,
2229 zone_key,
2230 name,
2231 rd_count,
2232 rd,
2233 proc->zi->filter))
2234 proc->limit--;
2235 else
2236 proc->run_again = GNUNET_YES;
2237}
2238
2239
2246static void
2248{
2249 struct ZoneIterationProcResult proc;
2252 struct NamestoreClient *nc = zi->nc;
2253
2254 memset (&proc, 0, sizeof(proc));
2256 "Asked to return up to %llu records at position %llu\n",
2257 (unsigned long long) limit,
2258 (unsigned long long) zi->seq);
2259 proc.zi = zi;
2260 proc.limit = limit;
2261 proc.run_again = GNUNET_YES;
2263 while (GNUNET_YES == proc.run_again)
2264 {
2265 proc.run_again = GNUNET_NO;
2267 nc->GSN_database->iterate_records (nc->GSN_database->cls,
2268 (GNUNET_YES ==
2270 &zi->zone))
2271 ? NULL
2272 : &zi->zone,
2273 zi->seq,
2274 proc.limit,
2276 &proc));
2277 }
2281 "NAMESTORE iteration delay (μs/record)",
2283 GNUNET_NO);
2284 if (0 == proc.limit)
2286 "Returned %llu results, more results available\n",
2287 (unsigned long long) limit);
2288 zi->send_end = (0 != proc.limit);
2290}
2291
2292
2293static enum GNUNET_GenericReturnValue
2295 const struct ZoneIterationStartMessage *zis_msg)
2296{
2297 uint16_t size;
2298 size_t key_len;
2299
2300 size = ntohs (zis_msg->gns_header.header.size);
2301 key_len = ntohs (zis_msg->key_len);
2302
2303 if (size < key_len + sizeof(*zis_msg))
2304 {
2305 GNUNET_break (0);
2306 return GNUNET_SYSERR;
2307 }
2308 return GNUNET_OK;
2309}
2310
2311
2318static void
2320 const struct ZoneIterationStartMessage *zis_msg)
2321{
2322 struct GNUNET_CRYPTO_PrivateKey zone;
2323 struct NamestoreClient *nc = cls;
2324 struct ZoneIteration *zi;
2325 size_t key_len;
2326 size_t kb_read;
2327
2329 "Received ZONE_ITERATION_START message\n");
2330 key_len = ntohs (zis_msg->key_len);
2331 zi = GNUNET_new (struct ZoneIteration);
2332 if (0 < key_len)
2333 {
2334 if ((GNUNET_SYSERR ==
2336 key_len,
2337 &zone,
2338 &kb_read)) ||
2339 (kb_read != key_len))
2340 {
2342 GNUNET_free (zi);
2343 return;
2344 }
2345 zi->zone = zone;
2346 }
2347 zi->request_id = ntohl (zis_msg->gns_header.r_id);
2348 zi->filter = ntohs (zis_msg->filter);
2349 zi->offset = 0;
2350 zi->nc = nc;
2351 GNUNET_CONTAINER_DLL_insert (nc->op_head, nc->op_tail, zi);
2353}
2354
2355
2362static void
2364 const struct ZoneIterationStopMessage *zis_msg)
2365{
2366 struct NamestoreClient *nc = cls;
2367 struct ZoneIteration *zi;
2368 uint32_t rid;
2369
2371 "Received ZONE_ITERATION_STOP message\n");
2372 rid = ntohl (zis_msg->gns_header.r_id);
2373 for (zi = nc->op_head; NULL != zi; zi = zi->next)
2374 if (zi->request_id == rid)
2375 break;
2376 if (NULL == zi)
2377 {
2378 GNUNET_break (0);
2380 return;
2381 }
2382 GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, zi);
2383 GNUNET_free (zi);
2385}
2386
2387
2394static void
2396 const struct ZoneIterationNextMessage *zis_msg)
2397{
2398 struct NamestoreClient *nc = cls;
2399 struct ZoneIteration *zi;
2400 uint32_t rid;
2401 uint64_t limit;
2402
2404 "Received ZONE_ITERATION_NEXT message\n");
2406 "Iteration NEXT messages received",
2407 1,
2408 GNUNET_NO);
2409 rid = ntohl (zis_msg->gns_header.r_id);
2410 limit = GNUNET_ntohll (zis_msg->limit);
2411 for (zi = nc->op_head; NULL != zi; zi = zi->next)
2412 if (zi->request_id == rid)
2413 break;
2414 if (NULL == zi)
2415 {
2416 GNUNET_break (0);
2418 return;
2419 }
2420 run_zone_iteration_round (zi, limit);
2421}
2422
2423
2429static void
2431{
2432 struct StoreActivity *sa = sa_head;
2433
2435 "Unblocking zone monitor %p\n", zm);
2436 while ((NULL != sa) && (zm->limit > zm->iteration_cnt))
2437 {
2438 struct StoreActivity *sn = sa->next;
2439
2440 if (sa->zm_pos == zm)
2442 sa = sn;
2443 }
2444 if (zm->limit > zm->iteration_cnt)
2445 {
2446 zm->sa_waiting = GNUNET_NO;
2447 if (NULL != zm->sa_wait_warning)
2448 {
2449 GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2450 zm->sa_wait_warning = NULL;
2451 }
2452 }
2453 else if (GNUNET_YES == zm->sa_waiting)
2454 {
2455 zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
2456 if (NULL != zm->sa_wait_warning)
2457 GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2458 zm->sa_wait_warning =
2461 zm);
2462 }
2463}
2464
2465
2471static void
2473{
2474 struct GNUNET_MQ_Envelope *env;
2475 struct GNUNET_MessageHeader *sync;
2477 "Syncing zone monitor %p\n", zm);
2478
2480 GNUNET_MQ_send (zm->nc->mq, env);
2481 /* mark iteration done */
2482 zm->in_first_iteration = GNUNET_NO;
2483 zm->iteration_cnt = 0;
2484 if ((zm->limit > 0) && (zm->sa_waiting))
2486}
2487
2488
2494static void
2495monitor_iteration_next (void *cls);
2496
2497
2508static void
2510 uint64_t seq,
2511 const char *editor_hint,
2512 const struct GNUNET_CRYPTO_PrivateKey *zone_key,
2513 const char *name,
2514 unsigned int rd_count,
2515 const struct GNUNET_GNSRECORD_Data *rd)
2516{
2517 struct ZoneMonitor *zm = cls;
2518
2519 GNUNET_assert (0 != seq);
2520 zm->seq = seq;
2521 GNUNET_assert (NULL != name);
2523 "Monitor notifications sent",
2524 1,
2525 GNUNET_NO);
2526 if (0 < send_lookup_response_with_filter (zm->nc, 0, zone_key, name,
2527 rd_count, rd, zm->filter))
2528 {
2530 "Sent records.\n");
2531 zm->limit--;
2532 zm->iteration_cnt--;
2533 }
2534 else
2535 zm->run_again = GNUNET_YES;
2536 if ((0 == zm->iteration_cnt) && (0 != zm->limit))
2537 {
2538 /* We are done with the current iteration batch, AND the
2539 client would right now accept more, so go again! */
2540 GNUNET_assert (NULL == zm->task);
2542 }
2543}
2544
2545
2546static enum GNUNET_GenericReturnValue
2548 const struct ZoneMonitorStartMessage *zis_msg)
2549{
2550 uint16_t size;
2551 size_t key_len;
2552
2553 size = ntohs (zis_msg->header.size);
2554 key_len = ntohs (zis_msg->key_len);
2555
2556 if (size < key_len + sizeof(*zis_msg))
2557 {
2558 GNUNET_break (0);
2559 return GNUNET_SYSERR;
2560 }
2561 return GNUNET_OK;
2562}
2563
2564
2571static void
2572handle_monitor_start (void *cls, const struct
2573 ZoneMonitorStartMessage *zis_msg)
2574{
2575 struct GNUNET_CRYPTO_PrivateKey zone;
2576 struct NamestoreClient *nc = cls;
2577 struct ZoneMonitor *zm;
2578 size_t key_len;
2579 size_t kb_read;
2580
2582 "Received ZONE_MONITOR_START message\n");
2583 zm = GNUNET_new (struct ZoneMonitor);
2584 zm->nc = nc;
2585 key_len = ntohs (zis_msg->key_len);
2586 if (0 < key_len)
2587 {
2588 if ((GNUNET_SYSERR ==
2590 key_len,
2591 &zone,
2592 &kb_read)) ||
2593 (kb_read != key_len))
2594 {
2596 "Error reading private key\n");
2598 GNUNET_free (zm);
2599 return;
2600 }
2601 zm->zone = zone;
2602 }
2603 zm->limit = 1;
2604 zm->filter = ntohs (zis_msg->filter);
2605 zm->in_first_iteration = (GNUNET_YES == ntohl (zis_msg->iterate_first));
2610 if (zm->in_first_iteration)
2612 else
2613 monitor_sync (zm);
2614}
2615
2616
2622static void
2624{
2625 struct ZoneMonitor *zm = cls;
2626 struct NamestoreClient *nc = zm->nc;
2627 int ret;
2628
2629 zm->task = NULL;
2630 GNUNET_assert (0 == zm->iteration_cnt);
2631 if (zm->limit > 16)
2632 zm->iteration_cnt = zm->limit / 2; /* leave half for monitor events */
2633 else
2634 zm->iteration_cnt = zm->limit; /* use it all */
2635 zm->run_again = GNUNET_YES;
2636 while (GNUNET_YES == zm->run_again)
2637 {
2639 "Running iteration\n");
2640 zm->run_again = GNUNET_NO;
2641 ret = nc->GSN_database->iterate_records (nc->GSN_database->cls,
2643 &zm->zone)) ? NULL : &zm->zone,
2644 zm->seq,
2645 zm->iteration_cnt,
2647 zm);
2648 }
2649 if (GNUNET_SYSERR == ret)
2650 {
2651 GNUNET_SERVICE_client_drop (zm->nc->client);
2652 return;
2653 }
2654 if (GNUNET_NO == ret)
2655 {
2657 "Zone empty... syncing\n");
2658 /* empty zone */
2659 monitor_sync (zm);
2660 return;
2661 }
2662}
2663
2664
2671static void
2672handle_monitor_next (void *cls, const struct ZoneMonitorNextMessage *nm)
2673{
2674 struct NamestoreClient *nc = cls;
2675 struct ZoneMonitor *zm;
2676 uint64_t inc;
2677
2678 inc = GNUNET_ntohll (nm->limit);
2680 "Received ZONE_MONITOR_NEXT message with limit %llu\n",
2681 (unsigned long long) inc);
2682 for (zm = monitor_head; NULL != zm; zm = zm->next)
2683 if (zm->nc == nc)
2684 break;
2685 if (NULL == zm)
2686 {
2687 GNUNET_break (0);
2689 return;
2690 }
2692 if (zm->limit + inc < zm->limit)
2693 {
2694 GNUNET_break (0);
2696 return;
2697 }
2698 zm->limit += inc;
2699 if ((zm->in_first_iteration) && (zm->limit == inc))
2700 {
2701 /* We are still iterating, and the previous iteration must
2702 have stopped due to the client's limit, so continue it! */
2703 GNUNET_assert (NULL == zm->task);
2705 }
2706 GNUNET_assert (zm->iteration_cnt <= zm->limit);
2707 if ((zm->limit > zm->iteration_cnt) && (zm->sa_waiting))
2708 {
2710 }
2711 else if (GNUNET_YES == zm->sa_waiting)
2712 {
2713 if (NULL != zm->sa_wait_warning)
2714 GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2715 zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
2716 zm->sa_wait_warning =
2719 zm);
2720 }
2721}
2722
2723
2731static void
2732run (void *cls,
2733 const struct GNUNET_CONFIGURATION_Handle *cfg,
2735{
2736 char *database;
2737 (void) cls;
2738 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n");
2740 "namestore",
2741 "RETURN_ORPHANED");
2742 GSN_cfg = cfg;
2744 statistics = GNUNET_STATISTICS_create ("namestore", cfg);
2745 /* Loading database plugin */
2747 "namestore",
2748 "database",
2749 &database))
2750 {
2751 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
2753 return;
2754 }
2755 GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
2758 GNUNET_free (database);
2759 if (NULL == GSN_database)
2760 {
2762 "Could not load database backend `%s'\n",
2763 db_lib_name);
2766 return;
2767 }
2769}
2770
2771
2776 "namestore",
2778 &run,
2781 NULL,
2782 GNUNET_MQ_hd_var_size (record_store,
2784 struct RecordStoreMessage,
2785 NULL),
2786 GNUNET_MQ_hd_var_size (edit_record_set,
2788 struct EditRecordSetMessage,
2789 NULL),
2790 GNUNET_MQ_hd_var_size (edit_record_set_cancel,
2793 NULL),
2794 GNUNET_MQ_hd_var_size (record_lookup,
2796 struct LabelLookupMessage,
2797 NULL),
2800 struct ZoneToNameMessage,
2801 NULL),
2802 GNUNET_MQ_hd_var_size (iteration_start,
2805 NULL),
2806 GNUNET_MQ_hd_fixed_size (iteration_next,
2809 NULL),
2810 GNUNET_MQ_hd_fixed_size (iteration_stop,
2813 NULL),
2814 GNUNET_MQ_hd_var_size (monitor_start,
2817 NULL),
2818 GNUNET_MQ_hd_fixed_size (monitor_next,
2821 NULL),
2823
2824
2825/* 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:39
static int ret
Final status code.
Definition: gnunet-arm.c:94
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:109
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:619
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:188
#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:120
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:163
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:1340
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:981
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1305
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1278
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the 'monitor' flag on this client.
Definition: service.c:2549
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2484
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2455
@ GNUNET_SERVICE_OPTION_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:436
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:550
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:638
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:617
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:136
Handle to a client that is connected to a service.
Definition: service.c:246
Handle to a service.
Definition: service.c:117
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