GNUnet  0.19.3
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 "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_gns_service.h"
33 #include "gnunet_signatures.h"
34 #include "namestore.h"
35 
36 #define LOG_STRERROR_FILE(kind, syscall, filename) \
37  GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
38 
42 #define MONITOR_STALL_WARN_DELAY GNUNET_TIME_UNIT_MINUTES
43 
47 #define NC_SIZE 16
48 
52 struct NamestoreClient;
53 
54 
59 {
64 
69 
74 
79 
84 
89 
97  uint64_t seq;
98 
102  uint32_t request_id;
103 
111  uint32_t offset;
112 
117  unsigned int cache_ops;
118 
124  int send_end;
125 };
126 
131 {
136 
141 
145  char *db_lib_name;
146 
151 
156 
162 
168 };
169 
170 
175 {
179  struct ZoneMonitor *next;
180 
184  struct ZoneMonitor *prev;
185 
190 
195 
200 
205 
210 
215 
223  uint64_t seq;
224 
229  uint64_t limit;
230 
237  uint64_t iteration_cnt;
238 
243 
248 
256 };
257 
258 
259 
265 {
270 
275 
280 
284  uint32_t rid;
285 
289  uint16_t rd_set_pos;
290 
294  uint16_t rd_set_count;
295 
301 
306 
311  const struct RecordSet *rs;
312 
317 
318 };
319 
320 
324 struct NickCache
325 {
330 
335 
340 };
341 
345 static struct NickCache nick_cache[NC_SIZE];
346 
350 static const struct GNUNET_IDENTITY_PrivateKey zero;
351 
356 
361 
365 static char *db_lib_name;
366 
371 
372 
376 static struct ZoneMonitor *monitor_head;
377 
381 static struct ZoneMonitor *monitor_tail;
382 
386 static struct StoreActivity *sa_head;
387 
391 static struct StoreActivity *sa_tail;
392 
397 
401 static int return_orphaned;
402 
408 static void
409 cleanup_task (void *cls)
410 {
411  (void) cls;
412  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n");
413  if (NULL != monitor_nc)
414  {
416  monitor_nc = NULL;
417  }
418  if (NULL != statistics)
419  {
421  statistics = NULL;
422  }
425  db_lib_name = NULL;
426 }
427 
428 
434 static void
436 {
438  GNUNET_free (sa);
439 }
440 
453 static void
454 lookup_nick_it (void *cls,
455  uint64_t seq,
456  const struct GNUNET_IDENTITY_PrivateKey *private_key,
457  const char *label,
458  unsigned int rd_count,
459  const struct GNUNET_GNSRECORD_Data *rd)
460 {
461  struct GNUNET_GNSRECORD_Data **res = cls;
462 
463  (void) private_key;
464  GNUNET_assert (0 != seq);
465  if (0 != strcmp (label, GNUNET_GNS_EMPTY_LABEL_AT))
466  {
467  GNUNET_break (0);
468  return;
469  }
470  for (unsigned int c = 0; c < rd_count; c++)
471  {
473  {
474  (*res) =
475  GNUNET_malloc (rd[c].data_size + sizeof(struct GNUNET_GNSRECORD_Data));
476  (*res)->data = &(*res)[1];
477  GNUNET_memcpy ((void *) (*res)->data, rd[c].data, rd[c].data_size);
478  (*res)->data_size = rd[c].data_size;
479  (*res)->expiration_time = rd[c].expiration_time;
480  (*res)->flags = rd[c].flags;
481  (*res)->record_type = GNUNET_GNSRECORD_TYPE_NICK;
482  return;
483  }
484  }
485  (*res) = NULL;
486 }
487 
488 
495 static void
497  const struct GNUNET_GNSRECORD_Data *nick)
498 {
499  struct NickCache *oldest;
500 
501  oldest = NULL;
502  for (unsigned int i = 0; i < NC_SIZE; i++)
503  {
504  struct NickCache *pos = &nick_cache[i];
505 
506  if ((NULL == oldest) ||
507  (oldest->last_used.abs_value_us > pos->last_used.abs_value_us))
508  oldest = pos;
509  if (0 == GNUNET_memcmp (zone, &pos->zone))
510  {
511  oldest = pos;
512  break;
513  }
514  }
515  GNUNET_free (oldest->rd);
516  oldest->zone = *zone;
517  if (NULL != nick)
518  {
519  oldest->rd = GNUNET_malloc (sizeof(*nick) + nick->data_size);
520  *oldest->rd = *nick;
521  oldest->rd->data = &oldest->rd[1];
522  memcpy (&oldest->rd[1], nick->data, nick->data_size);
523  }
524  else
525  {
526  oldest->rd = NULL;
527  }
528  oldest->last_used = GNUNET_TIME_absolute_get ();
529 }
530 
531 
539 static struct GNUNET_GNSRECORD_Data *
541 {
543  struct GNUNET_GNSRECORD_Data *nick;
544  int res;
545 
546  /* check cache first */
547  for (unsigned int i = 0; i < NC_SIZE; i++)
548  {
549  struct NickCache *pos = &nick_cache[i];
550  if ((NULL != pos->rd) && (0 == GNUNET_memcmp (zone, &pos->zone)))
551  {
552  if (NULL == pos->rd)
553  return NULL;
554  nick = GNUNET_malloc (sizeof(*nick) + pos->rd->data_size);
555  *nick = *pos->rd;
556  nick->data = &nick[1];
557  memcpy (&nick[1], pos->rd->data, pos->rd->data_size);
559  return nick;
560  }
561  }
562 
563  nick = NULL;
565  zone,
568  &nick);
569  if ((GNUNET_OK != res) || (NULL == nick))
570  {
571 #if ! defined(GNUNET_CULL_LOGGING)
572  static int do_log = GNUNET_LOG_CALL_STATUS;
573 
574  if (0 == do_log)
576  "namestore",
577  __FILE__,
578  __FUNCTION__,
579  __LINE__);
580  if (1 == do_log)
581  {
584  "No nick name set for zone `%s'\n",
586  }
587 #endif
588  /* update cache */
589  cache_nick (zone, NULL);
590  return NULL;
591  }
592 
593  /* update cache */
594  cache_nick (zone, nick);
595  return nick;
596 }
597 
598 
614 static void
616  unsigned int rd2_length,
617  const struct GNUNET_GNSRECORD_Data *rd2,
618  unsigned int *rdc_res,
619  struct GNUNET_GNSRECORD_Data **rd_res)
620 {
621  uint64_t latest_expiration;
622  size_t req;
623  char *data;
624  size_t data_offset;
625  struct GNUNET_GNSRECORD_Data *target;
626 
627  (*rdc_res) = 1 + rd2_length;
628  if (0 == 1 + rd2_length)
629  {
630  GNUNET_break (0);
631  (*rd_res) = NULL;
632  return;
633  }
634  req = sizeof(struct GNUNET_GNSRECORD_Data) + nick_rd->data_size;
635  for (unsigned int i = 0; i < rd2_length; i++)
636  {
637  const struct GNUNET_GNSRECORD_Data *orig = &rd2[i];
638 
639  if (req + sizeof(struct GNUNET_GNSRECORD_Data) + orig->data_size < req)
640  {
641  GNUNET_break (0);
642  (*rd_res) = NULL;
643  return;
644  }
645  req += sizeof(struct GNUNET_GNSRECORD_Data) + orig->data_size;
646  }
647  target = GNUNET_malloc (req);
648  (*rd_res) = target;
649  data = (char *) &target[1 + rd2_length];
650  data_offset = 0;
651  latest_expiration = 0;
652  for (unsigned int i = 0; i < rd2_length; i++)
653  {
654  const struct GNUNET_GNSRECORD_Data *orig = &rd2[i];
655 
657  {
658  if ((GNUNET_TIME_absolute_get ().abs_value_us + orig->expiration_time) >
659  latest_expiration)
660  latest_expiration = orig->expiration_time;
661  }
662  else if (orig->expiration_time > latest_expiration)
663  latest_expiration = orig->expiration_time;
664  target[i] = *orig;
665  target[i].data = (void *) &data[data_offset];
666  GNUNET_memcpy (&data[data_offset], orig->data, orig->data_size);
667  data_offset += orig->data_size;
668  }
669  /* append nick */
670  target[rd2_length] = *nick_rd;
671  /* Mark as supplemental */
672  target[rd2_length].flags = nick_rd->flags | GNUNET_GNSRECORD_RF_SUPPLEMENTAL;
673  target[rd2_length].expiration_time = latest_expiration;
674  target[rd2_length].data = (void *) &data[data_offset];
675  GNUNET_memcpy (&data[data_offset], nick_rd->data, nick_rd->data_size);
676  data_offset += nick_rd->data_size;
677  GNUNET_assert (req == (sizeof(struct GNUNET_GNSRECORD_Data)) * (*rdc_res)
678  + data_offset);
679 }
680 
681 
694 static int
696  uint32_t request_id,
697  const struct
699  const char *name,
700  unsigned int rd_count,
701  const struct GNUNET_GNSRECORD_Data *rd,
703 {
704  struct GNUNET_MQ_Envelope *env;
705  struct RecordResultMessage *zir_msg;
706  struct GNUNET_GNSRECORD_Data *nick;
707  struct GNUNET_GNSRECORD_Data *res;
708  struct GNUNET_GNSRECORD_Data rd_nf[rd_count];
710  unsigned int res_count;
711  unsigned int rd_nf_count;
712  size_t name_len;
713  size_t key_len;
714  ssize_t rd_ser_len;
715  char *name_tmp;
716  char *rd_ser;
717  char *emsg;
718 
719  nick = get_nick_record (zone_key);
721 
723  rd,
724  rd_count,
725  rd_nf,
726  &rd_nf_count,
727  &block_exp,
728  filter,
729  &emsg))
730  {
731  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
732  GNUNET_free (emsg);
733  GNUNET_assert (0);
734  }
735 
740  if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT)))
741  {
742  nick->flags =
744  merge_with_nick_records (nick, rd_nf_count, rd_nf, &res_count, &res);
745  }
746  else
747  {
748  res_count = rd_nf_count;
749  res = (struct GNUNET_GNSRECORD_Data *) rd_nf;
750  }
751  if (NULL != nick)
752  GNUNET_free (nick);
753 
754  if (0 == res_count)
755  {
756  if (rd_nf != res)
757  GNUNET_free (res);
758  return 0;
759  }
761 
762 
763  name_len = strlen (name) + 1;
764  rd_ser_len = GNUNET_GNSRECORD_records_get_size (res_count, res);
765  if (rd_ser_len < 0)
766  {
767  if (rd_nf != res)
768  GNUNET_free (res);
769  GNUNET_break (0);
770  GNUNET_SERVICE_client_drop (nc->client);
771  return 0;
772  }
773  if (((size_t) rd_ser_len) >= UINT16_MAX - name_len - sizeof(*zir_msg))
774  {
775  if (rd_nf != res)
776  GNUNET_free (res);
777  GNUNET_break (0);
778  GNUNET_SERVICE_client_drop (nc->client);
779  return 0;
780  }
782  env = GNUNET_MQ_msg_extra (zir_msg,
783  name_len + rd_ser_len + key_len,
785  zir_msg->gns_header.r_id = htonl (request_id);
786  zir_msg->name_len = htons (name_len);
787  zir_msg->rd_count = htons (res_count);
788  zir_msg->rd_len = htons ((uint16_t) rd_ser_len);
789  zir_msg->key_len = htons (key_len);
791  &zir_msg[1],
792  key_len);
793  zir_msg->expire = GNUNET_TIME_absolute_hton (block_exp);
794  name_tmp = (char *) &zir_msg[1] + key_len;
795  GNUNET_memcpy (name_tmp, name, name_len);
796  rd_ser = &name_tmp[name_len];
797  GNUNET_assert (
798  rd_ser_len ==
799  GNUNET_GNSRECORD_records_serialize (res_count, res, rd_ser_len, rd_ser));
801  "Sending RECORD_RESULT message with %u records\n",
802  res_count);
804  "Record sets sent to clients",
805  1,
806  GNUNET_NO);
807  GNUNET_MQ_send (nc->mq, env);
808  if (rd_nf != res)
809  GNUNET_free (res);
810  return res_count;
811 }
812 
820 static void
822  enum GNUNET_ErrorCode ec,
823  uint32_t rid)
824 {
825  struct GNUNET_MQ_Envelope *env;
826  struct RecordStoreResponseMessage *rcr_msg;
827 
828  GNUNET_assert (NULL != nc);
830  "Sending RECORD_STORE_RESPONSE message\n");
832  "Store requests completed",
833  1,
834  GNUNET_NO);
835  env = GNUNET_MQ_msg (rcr_msg,
837  rcr_msg->gns_header.r_id = htonl (rid);
838  rcr_msg->ec = htonl (ec);
839  GNUNET_MQ_send (nc->mq, env);
840 }
841 
842 
849 static void
851 {
852  struct GNUNET_MQ_Envelope *env;
853  struct GNUNET_NAMESTORE_Header *em;
854 
856  if (! zi->send_end)
857  return;
858  /* send empty response to indicate end of list */
860  em->r_id = htonl (zi->request_id);
861  GNUNET_MQ_send (zi->nc->mq, env);
862 
864  GNUNET_free (zi);
865 }
866 
867 
868 
869 
875 static void
876 warn_monitor_slow (void *cls)
877 {
878  struct ZoneMonitor *zm = cls;
879 
881  "No response from monitor since %s\n",
882  GNUNET_STRINGS_absolute_time_to_string (zm->sa_waiting_start));
885  zm);
886 }
887 
888 
894 static int
896  int call_continue)
897 {
898  const struct RecordSet *rd_set = sa->rs;
899  unsigned int rd_count;
900  size_t name_len;
901  size_t rd_ser_len;
902  const char *name_tmp;
903  const char *rd_ser;
904  const char *buf;
905  char *conv_name;
906 
907  // If we are in a transaction, do not notify monitors or update
908  // cached. This will be done when we are commiting.
909  if (GNUNET_YES == sa->uncommited)
910  {
912  "Transaction not yet committed, delaying monitor and cache updates\n");
914  if (GNUNET_YES == call_continue)
916  return GNUNET_OK;
917  }
918  buf = (const char *) &sa[1];
919  for (int i = sa->rd_set_pos; i < sa->rd_set_count; i++)
920  {
921  rd_set = (struct RecordSet *) buf;
922  name_len = ntohs (rd_set->name_len);
923  rd_count = ntohs (rd_set->rd_count);
924  rd_ser_len = ntohs (rd_set->rd_len);
925  name_tmp = (const char *) &rd_set[1];
926  rd_ser = &name_tmp[name_len];
927  conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
928  GNUNET_assert (NULL != conv_name);
929  {
931 
932  /* We did this before, must succeed again */
933  GNUNET_assert (
934  GNUNET_OK ==
935  GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count,
936  rd));
937 
939  "Checking monitors watching for `%s'\n",
940  conv_name);
941  for (struct ZoneMonitor *zm = sa->zm_pos; NULL != zm; zm = sa->zm_pos)
942  {
943  if ((0 != GNUNET_memcmp (&sa->private_key, &zm->zone)) &&
944  (0 != GNUNET_memcmp (&zm->zone, &zero)))
945  {
946  sa->zm_pos = zm->next; /* not interesting to this monitor */
947  continue;
948  }
949  if (zm->limit == zm->iteration_cnt)
950  {
951  zm->sa_waiting = GNUNET_YES;
952  zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
953  if (NULL != zm->sa_wait_warning)
954  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
955  zm->sa_wait_warning =
958  zm);
960  "Monitor is blocking client for `%s'\n",
961  conv_name);
962  GNUNET_free (conv_name);
963  return GNUNET_NO; /* blocked on zone monitor */
964  }
966  "Notifying monitor about changes under label `%s'\n",
967  conv_name);
969  0,
970  &sa->private_key,
971  conv_name,
972  rd_count,
973  rd,
974  zm->filter))
975  zm->limit--;
976  sa->zm_pos = zm->next;
977  }
978  sa->rd_set_pos++;
979  GNUNET_free (conv_name);
980  }
981  }
982  if (GNUNET_YES == call_continue)
985  free_store_activity (sa);
986  return GNUNET_OK;
987 }
988 
989 
998 static void
1000  struct GNUNET_SERVICE_Client *client,
1001  void *app_ctx)
1002 {
1003  struct NamestoreClient *nc = app_ctx;
1004  struct ZoneIteration *no;
1005  struct StoreActivity *sa = sa_head;
1006  struct StoreActivity *sn;
1007  char *emsg;
1008 
1009  (void) cls;
1010  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
1011  if (GNUNET_YES == nc->in_transaction)
1012  {
1014  "Client in transaction, rolling back...\n");
1015  if (GNUNET_SYSERR == nc->GSN_database->transaction_rollback (
1016  nc->GSN_database->cls,
1017  &emsg))
1018  {
1020  "Unable to roll back: %s\n", emsg);
1021  GNUNET_free (emsg);
1022  }
1023  else
1024  {
1025  nc->in_transaction = GNUNET_NO;
1026  while (NULL != sa)
1027  {
1028  if ((nc != sa->nc) ||
1029  (GNUNET_NO == sa->uncommited))
1030  {
1031  sa = sa->next;
1032  continue;
1033  }
1034  sn = sa->next;
1035  free_store_activity (sa);
1036  sa = sn;
1037  }
1038  }
1039  }
1040  for (struct ZoneMonitor *zm = monitor_head; NULL != zm; zm = zm->next)
1041  {
1042  if (nc != zm->nc)
1043  continue;
1045  if (NULL != zm->task)
1046  {
1047  GNUNET_SCHEDULER_cancel (zm->task);
1048  zm->task = NULL;
1049  }
1050  if (NULL != zm->sa_wait_warning)
1051  {
1052  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
1053  zm->sa_wait_warning = NULL;
1054  }
1055  for (sa = sa_head; NULL != sa; sa = sn)
1056  {
1057  sn = sa->next;
1058  if (zm == sa->zm_pos)
1059  {
1060  sa->zm_pos = zm->next;
1061  /* this may free sa */
1063  }
1064  }
1065  GNUNET_free (zm);
1066  break;
1067  }
1068  sa = sa_head;
1069  while (NULL != sa)
1070  {
1071  if (nc != sa->nc)
1072  {
1073  sa = sa->next;
1074  continue;
1075  }
1076  sn = sa->next;
1077  free_store_activity (sa);
1078  sa = sn;
1079  }
1080  while (NULL != (no = nc->op_head))
1081  {
1082  GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no);
1083  GNUNET_free (no);
1084  }
1085  GNUNET_break (NULL == GNUNET_PLUGIN_unload (nc->db_lib_name,
1086  nc->GSN_database));
1087  GNUNET_free (nc->db_lib_name);
1088  GNUNET_free (nc);
1089 }
1090 
1091 
1100 static void *
1102  struct GNUNET_SERVICE_Client *client,
1103  struct GNUNET_MQ_Handle *mq)
1104 {
1105  struct NamestoreClient *nc;
1106  char *database;
1107 
1108  (void) cls;
1109  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1110  nc = GNUNET_new (struct NamestoreClient);
1111  nc->client = client;
1112  nc->mq = mq;
1113  /* Loading database plugin */
1115  "namestore",
1116  "database",
1117  &database))
1118  {
1119  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
1120  GNUNET_free (nc);
1121  return NULL;
1122  }
1123  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loading %s\n", db_lib_name);
1124  nc->GSN_database = GNUNET_PLUGIN_load (db_lib_name, (void *) GSN_cfg);
1125  GNUNET_free (database);
1126  if (NULL == nc->GSN_database)
1127  {
1129  "Could not load database backend `%s'\n",
1130  db_lib_name);
1131  GNUNET_free (nc);
1132  return NULL;
1133  }
1134  nc->db_lib_name = GNUNET_strdup (db_lib_name);
1136  return nc;
1137 }
1138 
1139 
1144 {
1148  const char *label;
1149 
1153  char *res_rd;
1154 
1159 
1163  int found;
1164 
1169 
1173  unsigned int res_rd_count;
1174 
1178  ssize_t rd_ser_len;
1179 };
1180 
1181 
1194 static void
1195 lookup_it (void *cls,
1196  uint64_t seq,
1197  const struct GNUNET_IDENTITY_PrivateKey *private_key,
1198  const char *label,
1199  unsigned int rd_count_nf,
1200  const struct GNUNET_GNSRECORD_Data *rd_nf)
1201 {
1202  struct RecordLookupContext *rlc = cls;
1203  struct GNUNET_GNSRECORD_Data rd[rd_count_nf];
1204  struct GNUNET_TIME_Absolute block_exp;
1205  unsigned int rd_count = 0;
1206  char *emsg;
1207 
1208  (void) private_key;
1209  GNUNET_assert (0 != seq);
1210  if (0 != strcmp (label, rlc->label))
1211  return;
1212  rlc->found = GNUNET_YES;
1213 
1215  rd_nf,
1216  rd_count_nf,
1217  rd,
1218  &rd_count,
1219  &block_exp,
1220  rlc->filter,
1221  &emsg))
1222  {
1223  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
1224  GNUNET_free (emsg);
1225  GNUNET_assert (0);
1226  }
1227 
1228  if (0 == rd_count)
1229  {
1230  rlc->rd_ser_len = 0;
1231  rlc->res_rd_count = 0;
1232  rlc->res_rd = NULL;
1233  return;
1234  }
1235  if ((NULL != rlc->nick) && (0 != strcmp (label, GNUNET_GNS_EMPTY_LABEL_AT)))
1236  {
1237  /* Merge */
1238  struct GNUNET_GNSRECORD_Data *rd_res;
1239  unsigned int rdc_res;
1240 
1241  rd_res = NULL;
1242  rdc_res = 0;
1243  rlc->nick->flags = (rlc->nick->flags | GNUNET_GNSRECORD_RF_PRIVATE)
1245  merge_with_nick_records (rlc->nick, rd_count, rd, &rdc_res, &rd_res);
1246  rlc->rd_ser_len = GNUNET_GNSRECORD_records_get_size (rdc_res, rd_res);
1247  if (rlc->rd_ser_len < 0)
1248  {
1249  GNUNET_break (0);
1250  GNUNET_free (rd_res);
1251  rlc->found = GNUNET_NO;
1252  rlc->rd_ser_len = 0;
1253  return;
1254  }
1255  rlc->res_rd_count = rdc_res;
1256  rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1257  if (rlc->rd_ser_len != GNUNET_GNSRECORD_records_serialize (rdc_res,
1258  rd_res,
1259  rlc->rd_ser_len,
1260  rlc->res_rd))
1261  {
1262  GNUNET_break (0);
1263  GNUNET_free (rlc->res_rd);
1264  rlc->res_rd = NULL;
1265  rlc->res_rd_count = 0;
1266  rlc->rd_ser_len = 0;
1267  GNUNET_free (rd_res);
1268  rlc->found = GNUNET_NO;
1269  return;
1270  }
1271  GNUNET_free (rd_res);
1272  GNUNET_free (rlc->nick);
1273  rlc->nick = NULL;
1274  }
1275  else
1276  {
1278  if (rlc->rd_ser_len < 0)
1279  {
1280  GNUNET_break (0);
1281  rlc->found = GNUNET_NO;
1282  rlc->rd_ser_len = 0;
1283  return;
1284  }
1285  rlc->res_rd_count = rd_count;
1286  rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1288  rd,
1289  rlc->rd_ser_len,
1290  rlc->res_rd))
1291  {
1292  GNUNET_break (0);
1293  GNUNET_free (rlc->res_rd);
1294  rlc->res_rd = NULL;
1295  rlc->res_rd_count = 0;
1296  rlc->rd_ser_len = 0;
1297  rlc->found = GNUNET_NO;
1298  return;
1299  }
1300  }
1301 }
1302 
1303 
1311 static int
1312 check_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
1313 {
1314  uint32_t name_len;
1315  size_t src_size;
1316  size_t key_len;
1317 
1318  (void) cls;
1319  name_len = ntohs (ll_msg->label_len);
1320  key_len = ntohs (ll_msg->key_len);
1321  src_size = ntohs (ll_msg->gns_header.header.size);
1322  if (name_len + key_len != src_size - sizeof(struct LabelLookupMessage))
1323  {
1324  GNUNET_break (0);
1325  return GNUNET_SYSERR;
1326  }
1327  return GNUNET_OK;
1328 }
1329 
1330 
1337 static void
1338 handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
1339 {
1341  struct NamestoreClient *nc = cls;
1342  struct GNUNET_MQ_Envelope *env;
1343  struct LabelLookupResponseMessage *llr_msg;
1344  struct RecordLookupContext rlc;
1345  const char *name_tmp;
1346  char *res_name;
1347  char *conv_name;
1348  uint32_t name_len;
1349  int res;
1350  size_t key_len;
1351  size_t kb_read;
1352 
1353  key_len = ntohs (ll_msg->key_len);
1354  if ((GNUNET_SYSERR ==
1356  key_len,
1357  &zone,
1358  &kb_read)) ||
1359  (kb_read != key_len))
1360  {
1362  "Error reading private key\n");
1363  GNUNET_SERVICE_client_drop (nc->client);
1364  return;
1365  }
1366  name_tmp = (const char *) &ll_msg[1] + key_len;
1369  "Received NAMESTORE_RECORD_LOOKUP message for name `%s'\n",
1370  name_tmp);
1371 
1372  conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
1373  if (NULL == conv_name)
1374  {
1376  "Error converting name `%s'\n",
1377  name_tmp);
1378  GNUNET_SERVICE_client_drop (nc->client);
1379  return;
1380  }
1381  name_len = strlen (conv_name) + 1;
1382  rlc.label = conv_name;
1384  "Looking up with filter %u\n", ntohs (ll_msg->filter));
1385  rlc.filter = ntohs (ll_msg->filter);
1386  rlc.found = GNUNET_NO;
1387  rlc.res_rd_count = 0;
1388  rlc.res_rd = NULL;
1389  rlc.rd_ser_len = 0;
1390  rlc.nick = get_nick_record (&zone);
1391  if (GNUNET_YES != ntohs (ll_msg->is_edit_request))
1392  res = nc->GSN_database->lookup_records (nc->GSN_database->cls,
1393  &zone,
1394  conv_name,
1395  &lookup_it,
1396  &rlc);
1397  else
1398  res = nc->GSN_database->edit_records (nc->GSN_database->cls,
1399  &zone,
1400  conv_name,
1401  &lookup_it,
1402  &rlc);
1403 
1404  env =
1405  GNUNET_MQ_msg_extra (llr_msg,
1406  key_len + name_len + rlc.rd_ser_len,
1408  llr_msg->gns_header.r_id = ll_msg->gns_header.r_id;
1409  GNUNET_memcpy (&llr_msg[1], &ll_msg[1], key_len);
1410  llr_msg->key_len = ll_msg->key_len;
1411  llr_msg->name_len = htons (name_len);
1412  llr_msg->rd_count = htons (rlc.res_rd_count);
1413  llr_msg->rd_len = htons (rlc.rd_ser_len);
1414  llr_msg->reserved = htons (0);
1415  res_name = ((char *) &llr_msg[1]) + key_len;
1416  if (GNUNET_YES == rlc.found)
1417  llr_msg->found = htons (GNUNET_YES);
1418  else if (GNUNET_SYSERR == res)
1419  llr_msg->found = htons (GNUNET_SYSERR);
1420  else
1421  llr_msg->found = htons (GNUNET_NO);
1422  GNUNET_memcpy (res_name, conv_name, name_len);
1423  GNUNET_memcpy (&res_name[name_len], rlc.res_rd, rlc.rd_ser_len);
1424  GNUNET_MQ_send (nc->mq, env);
1425  GNUNET_free (rlc.res_rd);
1426  GNUNET_free (conv_name);
1427 }
1428 
1429 
1430 
1438 static int
1439 check_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1440 {
1441  size_t msg_size;
1442  size_t min_size_exp;
1443  size_t rd_set_count;
1444  size_t key_len;
1445 
1446  (void) cls;
1447  msg_size = ntohs (rp_msg->gns_header.header.size);
1448  rd_set_count = ntohs (rp_msg->rd_set_count);
1449  key_len = ntohs (rp_msg->key_len);
1450 
1451  min_size_exp = sizeof(*rp_msg) + key_len + sizeof (struct RecordSet)
1452  * rd_set_count;
1453  if (msg_size < min_size_exp)
1454  {
1455  GNUNET_break (0);
1456  return GNUNET_SYSERR;
1457  }
1458  return GNUNET_OK;
1459 }
1460 
1462 {
1463 
1467  struct GNUNET_TIME_Absolute exp;
1468 
1474 
1475 };
1476 
1477 
1488 static void
1490  uint64_t seq,
1491  const struct
1492  GNUNET_IDENTITY_PrivateKey *private_key,
1493  const char *label,
1494  unsigned int rd_count,
1495  const struct GNUNET_GNSRECORD_Data *rd)
1496 {
1497  struct LookupExistingRecordsContext *lctx = cls;
1498  struct GNUNET_GNSRECORD_Data rd_pub[rd_count];
1499  unsigned int rd_pub_count;
1500  char *emsg;
1501 
1502  if ((1 == rd_count) &&
1504  {
1505  /* This record set contains only a tombstone! */
1506  lctx->only_tombstone = GNUNET_YES;
1507  }
1508  if (GNUNET_OK !=
1510  rd,
1511  rd_count,
1512  rd_pub,
1513  &rd_pub_count,
1514  &lctx->exp,
1516  &emsg))
1517  {
1519  "%s\n", emsg);
1520  GNUNET_free (emsg);
1521  }
1522 }
1523 
1524 static enum GNUNET_ErrorCode
1526  const struct GNUNET_IDENTITY_PrivateKey *private_key,
1527  const struct RecordSet *rd_set,
1528  ssize_t *len)
1529 {
1530  size_t name_len;
1531  size_t rd_ser_len;
1532  const char *name_tmp;
1533  const char *rd_ser;
1534  char *conv_name;
1535  char *emsg;
1536  unsigned int rd_count;
1537  int res;
1538  enum GNUNET_ErrorCode ec;
1539  struct GNUNET_TIME_Absolute new_block_exp;
1540  struct LookupExistingRecordsContext lctx;
1541  *len = sizeof (struct RecordSet);
1542 
1543  ec = GNUNET_EC_NONE;
1544  lctx.only_tombstone = GNUNET_NO;
1545  lctx.exp = GNUNET_TIME_UNIT_ZERO_ABS;
1546  new_block_exp = GNUNET_TIME_UNIT_ZERO_ABS;
1547  name_len = ntohs (rd_set->name_len);
1548  *len += name_len;
1549  rd_count = ntohs (rd_set->rd_count);
1550  rd_ser_len = ntohs (rd_set->rd_len);
1551  *len += rd_ser_len;
1552  name_tmp = (const char *) &rd_set[1];
1553  rd_ser = &name_tmp[name_len];
1554  {
1556 
1557  /* Extracting and converting private key */
1558  conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
1559  if (NULL == conv_name)
1560  {
1562  "Error normalizing name `%s'\n",
1563  name_tmp);
1565  }
1566 
1567  /* Check name for validity */
1568  if (GNUNET_OK != GNUNET_GNSRECORD_label_check (conv_name, &emsg))
1569  {
1571  "Label invalid: `%s'\n",
1572  emsg);
1573  GNUNET_free (emsg);
1574  GNUNET_free (conv_name);
1576  }
1577 
1578  if (GNUNET_OK !=
1579  GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count,
1580  rd))
1581  {
1582  GNUNET_free (conv_name);
1584  }
1585 
1587  "Well-formed store requests received",
1588  1,
1589  GNUNET_NO);
1591  "Creating %u records for name `%s'\n",
1592  (unsigned int) rd_count,
1593  conv_name);
1594  if ((GNUNET_NO == nc->GSN_database->lookup_records (nc->GSN_database->cls,
1595  private_key,
1596  conv_name,
1598  &lctx))
1599  &&
1600  (rd_count == 0))
1601  {
1602  /* This name does not exist, so cannot be removed */
1604  "Name `%s' does not exist, no deletion required\n",
1605  conv_name);
1606  res = GNUNET_NO;
1608  }
1609  else
1610  {
1611  /* remove "NICK" records, unless this is for the
1612  #GNUNET_GNS_EMPTY_LABEL_AT label
1613  We may need one additional record later for tombstone.
1614  FIXME: Since we must normalize the record set (check for
1615  consistency etc) we have to iterate the set twice.
1616  May be inefficient.
1617  We cannot really move the nick caching into GNSRECORD.
1618  */
1619  struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL (rd_count)];
1620  struct GNUNET_GNSRECORD_Data rd_nf[GNUNET_NZL (rd_count) + 1];
1621  unsigned int rd_clean_off;
1622  unsigned int rd_nf_count;
1623  int have_nick;
1624 
1625  rd_clean_off = 0;
1626  have_nick = GNUNET_NO;
1627  for (unsigned int i = 0; i < rd_count; i++)
1628  {
1629  rd_clean[rd_clean_off] = rd[i];
1630 
1631  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) ||
1633  rd_clean_off++;
1634 
1635  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1637  {
1638  // FIXME: In case this is an uncommited transaction,
1639  // we should not do this here. Can we do this in the store activity?
1640  cache_nick (private_key, &rd[i]);
1641  have_nick = GNUNET_YES;
1642  }
1643  }
1644  if (GNUNET_OK !=
1646  rd_clean,
1647  rd_clean_off,
1648  rd_nf,
1649  &rd_nf_count,
1650  &new_block_exp,
1652  &emsg))
1653  {
1654  GNUNET_free (conv_name);
1656  "Error normalizing record set: `%s'\n",
1657  emsg);
1658  GNUNET_free (emsg);
1660  }
1662  "%u/%u records before tombstone\n", rd_nf_count,
1663  rd_clean_off);
1664  /*
1665  * If existing_block_exp is 0, then there was no record set
1666  * and no tombstone.
1667  * Otherwise, if the existing block expiration is after the
1668  * new block expiration would be, we need to add a tombstone
1669  * or update it.
1670  */
1671  if (GNUNET_TIME_absolute_cmp (new_block_exp, <=, lctx.exp))
1672  {
1673  rd_nf[rd_nf_count].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE;
1674  rd_nf[rd_nf_count].expiration_time =
1675  lctx.exp.abs_value_us;
1676  rd_nf[rd_nf_count].data = NULL;
1677  rd_nf[rd_nf_count].data_size = 0;
1678  rd_nf[rd_nf_count].flags = GNUNET_GNSRECORD_RF_PRIVATE;
1679  rd_nf_count++;
1680  }
1681  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1682  (GNUNET_NO == have_nick))
1683  {
1684  /* remove nick record from cache, in case we have one there */
1685  // FIXME: In case this is an uncommited transaction,
1686  // we should not do this here. Can we do this in the store activity?
1687  cache_nick (private_key, NULL);
1688  }
1689  res = nc->GSN_database->store_records (nc->GSN_database->cls,
1690  private_key,
1691  conv_name,
1692  rd_nf_count,
1693  rd_nf);
1694  /* If after a store there is only a TOMBSTONE left, and
1695  * there was >1 record under this label found (the tombstone; indicated
1696  * through res != GNUNET_NO) then we should return "NOT FOUND" == GNUNET_NO
1697  */
1698  if ((GNUNET_SYSERR != res) &&
1699  (0 == rd_count) &&
1700  (1 == rd_nf_count) &&
1702  (GNUNET_YES == lctx.only_tombstone))
1703  {
1705  "Client tried to remove non-existant record\n");
1707  }
1708  }
1709 
1710  if (GNUNET_SYSERR == res)
1711  {
1712  /* store not successful, no need to tell monitors */
1713  GNUNET_free (conv_name);
1715  }
1716  }
1717  GNUNET_free (conv_name);
1718  return ec;
1719 }
1720 
1727 static void
1728 handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1729 {
1731  struct NamestoreClient *nc = cls;
1732  uint32_t rid;
1733  uint16_t rd_set_count;
1734  const char *buf;
1735  ssize_t read;
1736  size_t key_len;
1737  size_t kb_read;
1738  size_t rp_msg_len;
1739  size_t rs_len;
1740  size_t rs_off;
1741  size_t body_len;
1742  struct StoreActivity *sa;
1743  struct RecordSet *rs;
1744  enum GNUNET_ErrorCode res;
1745 
1746  key_len = ntohs (rp_msg->key_len);
1747  rp_msg_len = ntohs (rp_msg->gns_header.header.size);
1748  body_len = rp_msg_len - sizeof (*rp_msg);
1749  rs_off = sizeof (*rp_msg) + key_len;
1750  rs_len = rp_msg_len - rs_off;
1751  if ((GNUNET_SYSERR ==
1753  key_len,
1754  &zone,
1755  &kb_read)) ||
1756  (kb_read != key_len))
1757  {
1759  "Error reading private key\n");
1760  GNUNET_SERVICE_client_drop (nc->client);
1761  return;
1762  }
1764  "Received NAMESTORE_RECORD_STORE message\n");
1765  rid = ntohl (rp_msg->gns_header.r_id);
1766  rd_set_count = ntohs (rp_msg->rd_set_count);
1767  buf = (const char *) rp_msg + rs_off;
1768  for (int i = 0; i < rd_set_count; i++)
1769  {
1770  rs = (struct RecordSet *) buf;
1771  res = store_record_set (nc, &zone,
1772  rs, &read);
1773  if (GNUNET_EC_NONE != res)
1774  {
1775  send_store_response (nc, res, rid);
1777  return;
1778  }
1779  buf += read;
1780  }
1781  sa = GNUNET_malloc (sizeof(struct StoreActivity) + rs_len);
1783  sa->nc = nc;
1784  sa->rs = (struct RecordSet *) &sa[1];
1785  sa->rd_set_count = rd_set_count;
1786  GNUNET_memcpy (&sa[1], (char *) rp_msg + rs_off, rs_len);
1787  sa->rid = rid;
1788  sa->rd_set_pos = 0;
1789  sa->private_key = zone;
1790  sa->zm_pos = monitor_head;
1791  sa->uncommited = nc->in_transaction;
1793 }
1794 
1795 static void
1797 {
1798  struct TxControlResultMessage *txr_msg;
1799  struct GNUNET_MQ_Envelope *env;
1800 
1801  env =
1803  txr_msg->gns_header.r_id = rid;
1804  txr_msg->ec = htonl (ec);
1805  GNUNET_MQ_send (nc->mq, env);
1806 }
1807 
1814 static void
1815 handle_tx_control (void *cls, const struct TxControlMessage *tx_msg)
1816 {
1817  struct NamestoreClient *nc = cls;
1818  struct StoreActivity *sa = sa_head;
1819  struct StoreActivity *sn;
1821  char *emsg = NULL;
1822  int blocked = GNUNET_NO;
1823 
1824  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received TX_CONTROL message\n");
1825 
1826  switch (ntohs (tx_msg->control))
1827  {
1829  ret = nc->GSN_database->transaction_begin (nc->GSN_database->cls,
1830  &emsg);
1831  send_tx_response (tx_msg->gns_header.r_id,
1832  (GNUNET_SYSERR == ret) ?
1834  if (GNUNET_SYSERR == ret)
1835  {
1837  "Databse backend error: `%s'", emsg);
1838  GNUNET_free (emsg);
1839  }
1841  nc->in_transaction = GNUNET_YES;
1842  break;
1844  ret = nc->GSN_database->transaction_commit (nc->GSN_database->cls,
1845  &emsg);
1846  send_tx_response (tx_msg->gns_header.r_id,
1847  (GNUNET_SYSERR == ret) ?
1849  nc);
1850  if (GNUNET_SYSERR == ret)
1851  {
1853  "Databse backend error: `%s'", emsg);
1854  GNUNET_free (emsg);
1855  }
1856  if (GNUNET_SYSERR != ret)
1857  {
1858  nc->in_transaction = GNUNET_NO;
1859  while (NULL != sa)
1860  {
1861  if ((nc != sa->nc) ||
1862  (GNUNET_NO == sa->uncommited))
1863  {
1864  sa = sa->next;
1865  continue;
1866  }
1867  sa->uncommited = GNUNET_NO;
1868  sn = sa->next;
1870  blocked = GNUNET_YES;
1871  sa = sn;
1872  }
1873  if (GNUNET_YES != blocked)
1875  }
1876  break;
1878  ret = nc->GSN_database->transaction_rollback (nc->GSN_database->cls,
1879  &emsg);
1880  send_tx_response (tx_msg->gns_header.r_id,
1881  (GNUNET_SYSERR == ret) ?
1884  if (GNUNET_SYSERR == ret)
1885  {
1887  "Databse backend error: `%s'", emsg);
1888  GNUNET_free (emsg);
1889  }
1890  if (GNUNET_SYSERR != ret)
1891  {
1892  nc->in_transaction = GNUNET_NO;
1893  while (NULL != sa)
1894  {
1895  if ((nc != sa->nc) ||
1896  (GNUNET_NO == sa->uncommited))
1897  {
1898  sa = sa->next;
1899  continue;
1900  }
1902  "Discarding uncommited StoreActivity\n");
1903  sn = sa->next;
1904  free_store_activity (sa);
1905  sa = sn;
1906  }
1907  }
1908  break;
1909  default:
1911  "Unknown control type %u\n", ntohs (tx_msg->control));
1912  GNUNET_break (0);
1913  }
1914 }
1915 
1921 {
1926 
1930  uint32_t rid;
1931 
1937  enum GNUNET_ErrorCode ec;
1938 };
1939 
1940 
1951 static void
1953  uint64_t seq,
1954  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
1955  const char *name,
1956  unsigned int rd_count,
1957  const struct GNUNET_GNSRECORD_Data *rd)
1958 {
1959  struct ZoneToNameCtx *ztn_ctx = cls;
1960  struct GNUNET_MQ_Envelope *env;
1961  struct ZoneToNameResponseMessage *ztnr_msg;
1962  size_t name_len;
1963  size_t key_len;
1964  ssize_t rd_ser_len;
1965  size_t msg_size;
1966  char *name_tmp;
1967  char *rd_tmp;
1968 
1969  GNUNET_assert (0 != seq);
1971  "Found result for zone-to-name lookup: `%s'\n",
1972  name);
1973  ztn_ctx->ec = GNUNET_EC_NONE;
1974  name_len = (NULL == name) ? 0 : strlen (name) + 1;
1976  if (rd_ser_len < 0)
1977  {
1978  GNUNET_break (0);
1979  ztn_ctx->ec = htonl (GNUNET_EC_NAMESTORE_UNKNOWN);
1980  return;
1981  }
1983  msg_size = sizeof(struct ZoneToNameResponseMessage)
1984  + name_len + rd_ser_len + key_len;
1985  if (msg_size >= GNUNET_MAX_MESSAGE_SIZE)
1986  {
1987  GNUNET_break (0);
1989  return;
1990  }
1991  env =
1992  GNUNET_MQ_msg_extra (ztnr_msg,
1993  key_len + name_len + rd_ser_len,
1995  ztnr_msg->gns_header.header.size = htons (msg_size);
1996  ztnr_msg->gns_header.r_id = htonl (ztn_ctx->rid);
1997  ztnr_msg->ec = htonl (ztn_ctx->ec);
1998  ztnr_msg->rd_len = htons (rd_ser_len);
1999  ztnr_msg->rd_count = htons (rd_count);
2000  ztnr_msg->name_len = htons (name_len);
2001  ztnr_msg->key_len = htons (key_len);
2003  &ztnr_msg[1],
2004  key_len);
2005  name_tmp = (char *) &ztnr_msg[1] + key_len;
2006  GNUNET_memcpy (name_tmp, name, name_len);
2007  rd_tmp = &name_tmp[name_len];
2008  GNUNET_assert (
2009  rd_ser_len ==
2010  GNUNET_GNSRECORD_records_serialize (rd_count, rd, rd_ser_len, rd_tmp));
2011  ztn_ctx->ec = GNUNET_EC_NONE;
2012  GNUNET_MQ_send (ztn_ctx->nc->mq, env);
2013 }
2014 
2015 static enum GNUNET_GenericReturnValue
2016 check_zone_to_name (void *cls,
2017  const struct ZoneToNameMessage *zis_msg)
2018 {
2019  return GNUNET_OK;
2020 }
2021 
2022 
2029 static void
2030 handle_zone_to_name (void *cls, const struct ZoneToNameMessage *ztn_msg)
2031 {
2033  struct GNUNET_IDENTITY_PublicKey value_zone;
2034  struct NamestoreClient *nc = cls;
2035  struct ZoneToNameCtx ztn_ctx;
2036  struct GNUNET_MQ_Envelope *env;
2037  struct ZoneToNameResponseMessage *ztnr_msg;
2038  size_t key_len;
2039  size_t pkey_len;
2040  size_t kb_read;
2041 
2042  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_TO_NAME message\n");
2043  ztn_ctx.rid = ntohl (ztn_msg->gns_header.r_id);
2044  ztn_ctx.nc = nc;
2046  key_len = ntohs (ztn_msg->key_len);
2047  if ((GNUNET_SYSERR ==
2049  key_len,
2050  &zone,
2051  &kb_read)) ||
2052  (kb_read != key_len))
2053  {
2055  "Error parsing private key.\n");
2056  GNUNET_SERVICE_client_drop (nc->client);
2057  GNUNET_break (0);
2058  return;
2059  }
2060  pkey_len = ntohs (ztn_msg->pkey_len);
2061  if ((GNUNET_SYSERR ==
2062  GNUNET_IDENTITY_read_public_key_from_buffer ((char*) &ztn_msg[1]
2063  + key_len,
2064  pkey_len,
2065  &value_zone,
2066  &kb_read)) ||
2067  (kb_read != pkey_len))
2068  {
2070  "Error parsing public key.\n");
2071  GNUNET_SERVICE_client_drop (nc->client);
2072  GNUNET_break (0);
2073  return;
2074  }
2075  if (GNUNET_SYSERR == nc->GSN_database->zone_to_name (nc->GSN_database->cls,
2076  &zone,
2077  &value_zone,
2079  &ztn_ctx))
2080  {
2081  /* internal error, hang up instead of signalling something
2082  that might be wrong */
2083  GNUNET_break (0);
2084  GNUNET_SERVICE_client_drop (nc->client);
2085  return;
2086  }
2087  if (GNUNET_EC_NAMESTORE_ZONE_NOT_FOUND == ztn_ctx.ec)
2088  {
2089  /* no result found, send empty response */
2091  "Found no result for zone-to-name lookup.\n");
2092  env = GNUNET_MQ_msg (ztnr_msg,
2094  ztnr_msg->gns_header.r_id = ztn_msg->gns_header.r_id;
2095  ztnr_msg->ec = htonl (GNUNET_EC_NAMESTORE_ZONE_NOT_FOUND);
2096  GNUNET_MQ_send (nc->mq, env);
2097  }
2099 }
2100 
2101 
2107 {
2112 
2116  uint64_t limit;
2117 
2122 };
2123 
2124 
2135 static void
2137  uint64_t seq,
2138  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
2139  const char *name,
2140  unsigned int rd_count,
2141  const struct GNUNET_GNSRECORD_Data *rd)
2142 {
2143  struct ZoneIterationProcResult *proc = cls;
2144 
2145  GNUNET_assert (0 != seq);
2146  if ((NULL == zone_key) && (NULL == name))
2147  {
2148  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
2149  return;
2150  }
2151  if ((NULL == zone_key) || (NULL == name))
2152  {
2153  /* what is this!? should never happen */
2154  GNUNET_break (0);
2155  return;
2156  }
2157  if (0 == proc->limit)
2158  {
2159  /* what is this!? should never happen */
2160  GNUNET_break (0);
2161  return;
2162  }
2163  proc->zi->seq = seq;
2164  if (0 < send_lookup_response_with_filter (proc->zi->nc,
2165  proc->zi->request_id,
2166  zone_key,
2167  name,
2168  rd_count,
2169  rd,
2170  proc->zi->filter))
2171  proc->limit--;
2172  else
2173  proc->run_again = GNUNET_YES;
2174 }
2175 
2176 
2183 static void
2185 {
2186  struct ZoneIterationProcResult proc;
2187  struct GNUNET_TIME_Absolute start;
2189  struct NamestoreClient *nc = zi->nc;
2190 
2191  memset (&proc, 0, sizeof(proc));
2193  "Asked to return up to %llu records at position %llu\n",
2194  (unsigned long long) limit,
2195  (unsigned long long) zi->seq);
2196  proc.zi = zi;
2197  proc.limit = limit;
2198  proc.run_again = GNUNET_YES;
2200  while (GNUNET_YES == proc.run_again)
2201  {
2202  proc.run_again = GNUNET_NO;
2204  nc->GSN_database->iterate_records (nc->GSN_database->cls,
2205  (GNUNET_YES ==
2206  GNUNET_is_zero (
2207  &zi->zone))
2208  ? NULL
2209  : &zi->zone,
2210  zi->seq,
2211  proc.limit,
2213  &proc));
2214  }
2218  "NAMESTORE iteration delay (μs/record)",
2220  GNUNET_NO);
2221  if (0 == proc.limit)
2223  "Returned %llu results, more results available\n",
2224  (unsigned long long) limit);
2225  zi->send_end = (0 != proc.limit);
2226  if (0 == zi->cache_ops)
2228 }
2229 
2230 static enum GNUNET_GenericReturnValue
2231 check_iteration_start (void *cls,
2232  const struct ZoneIterationStartMessage *zis_msg)
2233 {
2234  uint16_t size;
2235  size_t key_len;
2236 
2237  size = ntohs (zis_msg->gns_header.header.size);
2238  key_len = ntohs (zis_msg->key_len);
2239 
2240  if (size < key_len + sizeof(*zis_msg))
2241  {
2242  GNUNET_break (0);
2243  return GNUNET_SYSERR;
2244  }
2245  return GNUNET_OK;
2246 }
2247 
2248 
2255 static void
2257  const struct ZoneIterationStartMessage *zis_msg)
2258 {
2260  struct NamestoreClient *nc = cls;
2261  struct ZoneIteration *zi;
2262  size_t key_len;
2263  size_t kb_read;
2264 
2266  "Received ZONE_ITERATION_START message\n");
2267  key_len = ntohs (zis_msg->key_len);
2268  zi = GNUNET_new (struct ZoneIteration);
2269  if (0 < key_len)
2270  {
2271  if ((GNUNET_SYSERR ==
2273  key_len,
2274  &zone,
2275  &kb_read)) ||
2276  (kb_read != key_len))
2277  {
2278  GNUNET_SERVICE_client_drop (nc->client);
2279  GNUNET_free (zi);
2280  return;
2281  }
2282  zi->zone = zone;
2283  }
2284  zi->request_id = ntohl (zis_msg->gns_header.r_id);
2285  zi->filter = ntohs (zis_msg->filter);
2286  zi->offset = 0;
2287  zi->nc = nc;
2288  GNUNET_CONTAINER_DLL_insert (nc->op_head, nc->op_tail, zi);
2289  run_zone_iteration_round (zi, 1);
2290 }
2291 
2292 
2299 static void
2301  const struct ZoneIterationStopMessage *zis_msg)
2302 {
2303  struct NamestoreClient *nc = cls;
2304  struct ZoneIteration *zi;
2305  uint32_t rid;
2306 
2308  "Received ZONE_ITERATION_STOP message\n");
2309  rid = ntohl (zis_msg->gns_header.r_id);
2310  for (zi = nc->op_head; NULL != zi; zi = zi->next)
2311  if (zi->request_id == rid)
2312  break;
2313  if (NULL == zi)
2314  {
2315  GNUNET_break (0);
2316  GNUNET_SERVICE_client_drop (nc->client);
2317  return;
2318  }
2319  GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, zi);
2320  GNUNET_free (zi);
2322 }
2323 
2324 
2331 static void
2333  const struct ZoneIterationNextMessage *zis_msg)
2334 {
2335  struct NamestoreClient *nc = cls;
2336  struct ZoneIteration *zi;
2337  uint32_t rid;
2338  uint64_t limit;
2339 
2341  "Received ZONE_ITERATION_NEXT message\n");
2343  "Iteration NEXT messages received",
2344  1,
2345  GNUNET_NO);
2346  rid = ntohl (zis_msg->gns_header.r_id);
2347  limit = GNUNET_ntohll (zis_msg->limit);
2348  for (zi = nc->op_head; NULL != zi; zi = zi->next)
2349  if (zi->request_id == rid)
2350  break;
2351  if (NULL == zi)
2352  {
2353  GNUNET_break (0);
2354  GNUNET_SERVICE_client_drop (nc->client);
2355  return;
2356  }
2357  run_zone_iteration_round (zi, limit);
2358 }
2359 
2360 
2366 static void
2368 {
2369  struct StoreActivity *sa = sa_head;
2370 
2372  "Unblocking zone monitor %p\n", zm);
2373  while ((NULL != sa) && (zm->limit > zm->iteration_cnt))
2374  {
2375  struct StoreActivity *sn = sa->next;
2376 
2377  if (sa->zm_pos == zm)
2379  sa = sn;
2380  }
2381  if (zm->limit > zm->iteration_cnt)
2382  {
2383  zm->sa_waiting = GNUNET_NO;
2384  if (NULL != zm->sa_wait_warning)
2385  {
2386  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2387  zm->sa_wait_warning = NULL;
2388  }
2389  }
2390  else if (GNUNET_YES == zm->sa_waiting)
2391  {
2392  zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
2393  if (NULL != zm->sa_wait_warning)
2394  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2395  zm->sa_wait_warning =
2398  zm);
2399  }
2400 }
2401 
2402 
2408 static void
2410 {
2411  struct GNUNET_MQ_Envelope *env;
2412  struct GNUNET_MessageHeader *sync;
2414  "Synching zone monitor %p\n", zm);
2415 
2417  GNUNET_MQ_send (zm->nc->mq, env);
2418  /* mark iteration done */
2419  zm->in_first_iteration = GNUNET_NO;
2420  zm->iteration_cnt = 0;
2421  if ((zm->limit > 0) && (zm->sa_waiting))
2422  monitor_unblock (zm);
2423 }
2424 
2425 
2431 static void
2432 monitor_iteration_next (void *cls);
2433 
2434 
2445 static void
2447  uint64_t seq,
2448  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
2449  const char *name,
2450  unsigned int rd_count,
2451  const struct GNUNET_GNSRECORD_Data *rd)
2452 {
2453  struct ZoneMonitor *zm = cls;
2454 
2455  GNUNET_assert (0 != seq);
2456  zm->seq = seq;
2457  GNUNET_assert (NULL != name);
2459  "Monitor notifications sent",
2460  1,
2461  GNUNET_NO);
2463  rd_count, rd, zm->filter))
2464  {
2466  "Sent records.\n");
2467  zm->limit--;
2468  zm->iteration_cnt--;
2469  }
2470  else
2471  zm->run_again = GNUNET_YES;
2472  if ((0 == zm->iteration_cnt) && (0 != zm->limit))
2473  {
2474  /* We are done with the current iteration batch, AND the
2475  client would right now accept more, so go again! */
2476  GNUNET_assert (NULL == zm->task);
2478  }
2479 }
2480 
2481 static enum GNUNET_GenericReturnValue
2482 check_monitor_start (void *cls,
2483  const struct ZoneMonitorStartMessage *zis_msg)
2484 {
2485  uint16_t size;
2486  size_t key_len;
2487 
2488  size = ntohs (zis_msg->header.size);
2489  key_len = ntohs (zis_msg->key_len);
2490 
2491  if (size < key_len + sizeof(*zis_msg))
2492  {
2493  GNUNET_break (0);
2494  return GNUNET_SYSERR;
2495  }
2496  return GNUNET_OK;
2497 }
2498 
2499 
2506 static void
2507 handle_monitor_start (void *cls, const struct
2508  ZoneMonitorStartMessage *zis_msg)
2509 {
2511  struct NamestoreClient *nc = cls;
2512  struct ZoneMonitor *zm;
2513  size_t key_len;
2514  size_t kb_read;
2515 
2517  "Received ZONE_MONITOR_START message\n");
2518  zm = GNUNET_new (struct ZoneMonitor);
2519  zm->nc = nc;
2520  key_len = ntohs (zis_msg->key_len);
2521  if (0 < key_len)
2522  {
2523  if ((GNUNET_SYSERR ==
2525  key_len,
2526  &zone,
2527  &kb_read)) ||
2528  (kb_read != key_len))
2529  {
2531  "Error reading private key\n");
2532  GNUNET_SERVICE_client_drop (nc->client);
2533  GNUNET_free (zm);
2534  return;
2535  }
2536  zm->zone = zone;
2537  }
2538  zm->limit = 1;
2539  zm->filter = ntohs (zis_msg->filter);
2540  zm->in_first_iteration = (GNUNET_YES == ntohl (zis_msg->iterate_first));
2545  if (zm->in_first_iteration)
2547  else
2548  monitor_sync (zm);
2549 }
2550 
2551 
2557 static void
2559 {
2560  struct ZoneMonitor *zm = cls;
2561  struct NamestoreClient *nc = zm->nc;
2562  int ret;
2563 
2564  zm->task = NULL;
2565  GNUNET_assert (0 == zm->iteration_cnt);
2566  if (zm->limit > 16)
2567  zm->iteration_cnt = zm->limit / 2; /* leave half for monitor events */
2568  else
2569  zm->iteration_cnt = zm->limit; /* use it all */
2570  zm->run_again = GNUNET_YES;
2571  while (GNUNET_YES == zm->run_again)
2572  {
2574  "Running iteration\n");
2575  zm->run_again = GNUNET_NO;
2576  ret = nc->GSN_database->iterate_records (nc->GSN_database->cls,
2578  &zm->zone)) ? NULL : &zm->zone,
2579  zm->seq,
2580  zm->iteration_cnt,
2582  zm);
2583  }
2584  if (GNUNET_SYSERR == ret)
2585  {
2586  GNUNET_SERVICE_client_drop (zm->nc->client);
2587  return;
2588  }
2589  if (GNUNET_NO == ret)
2590  {
2592  "Zone empty... syncing\n");
2593  /* empty zone */
2594  monitor_sync (zm);
2595  return;
2596  }
2597 }
2598 
2605 static void
2606 handle_monitor_next (void *cls, const struct ZoneMonitorNextMessage *nm)
2607 {
2608  struct NamestoreClient *nc = cls;
2609  struct ZoneMonitor *zm;
2610  uint64_t inc;
2611 
2612  inc = GNUNET_ntohll (nm->limit);
2614  "Received ZONE_MONITOR_NEXT message with limit %llu\n",
2615  (unsigned long long) inc);
2616  for (zm = monitor_head; NULL != zm; zm = zm->next)
2617  if (zm->nc == nc)
2618  break;
2619  if (NULL == zm)
2620  {
2621  GNUNET_break (0);
2622  GNUNET_SERVICE_client_drop (nc->client);
2623  return;
2624  }
2626  if (zm->limit + inc < zm->limit)
2627  {
2628  GNUNET_break (0);
2629  GNUNET_SERVICE_client_drop (nc->client);
2630  return;
2631  }
2632  zm->limit += inc;
2633  if ((zm->in_first_iteration) && (zm->limit == inc))
2634  {
2635  /* We are still iterating, and the previous iteration must
2636  have stopped due to the client's limit, so continue it! */
2637  GNUNET_assert (NULL == zm->task);
2639  }
2640  GNUNET_assert (zm->iteration_cnt <= zm->limit);
2641  if ((zm->limit > zm->iteration_cnt) && (zm->sa_waiting))
2642  {
2643  monitor_unblock (zm);
2644  }
2645  else if (GNUNET_YES == zm->sa_waiting)
2646  {
2647  if (NULL != zm->sa_wait_warning)
2648  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2649  zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
2650  zm->sa_wait_warning =
2653  zm);
2654  }
2655 }
2656 
2664 static void
2665 run (void *cls,
2666  const struct GNUNET_CONFIGURATION_Handle *cfg,
2668 {
2669  char *database;
2670  (void) cls;
2671  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n");
2673  "namestore",
2674  "RETURN_ORPHANED");
2675  GSN_cfg = cfg;
2677  statistics = GNUNET_STATISTICS_create ("namestore", cfg);
2678  /* Loading database plugin */
2680  "namestore",
2681  "database",
2682  &database))
2683  {
2684  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
2686  return;
2687  }
2688  GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
2689  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loading %s\n", db_lib_name);
2691  GNUNET_free (database);
2692  if (NULL == GSN_database)
2693  {
2695  "Could not load database backend `%s'\n",
2696  db_lib_name);
2699  return;
2700  }
2702 }
2703 
2704 
2709  "namestore",
2711  &run,
2714  NULL,
2715  GNUNET_MQ_hd_fixed_size (tx_control,
2717  struct TxControlMessage,
2718  NULL),
2719  GNUNET_MQ_hd_var_size (record_store,
2721  struct RecordStoreMessage,
2722  NULL),
2723  GNUNET_MQ_hd_var_size (record_lookup,
2725  struct LabelLookupMessage,
2726  NULL),
2729  struct ZoneToNameMessage,
2730  NULL),
2734  NULL),
2735  GNUNET_MQ_hd_fixed_size (iteration_next,
2737  struct ZoneIterationNextMessage,
2738  NULL),
2739  GNUNET_MQ_hd_fixed_size (iteration_stop,
2741  struct ZoneIterationStopMessage,
2742  NULL),
2743  GNUNET_MQ_hd_var_size (monitor_start,
2745  struct ZoneMonitorStartMessage,
2746  NULL),
2747  GNUNET_MQ_hd_fixed_size (monitor_next,
2749  struct ZoneMonitorNextMessage,
2750  NULL),
2752 
2753 
2754 /* end of gnunet-service-namestore.c */
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_GNSRECORD_TYPE_NICK
GNS nick names.
#define GNUNET_GNSRECORD_TYPE_TOMBSTONE
Record type to indicate a previously delete record (PRIVATE only)
GNUNET_ErrorCode
Taler error codes.
@ GNUNET_EC_NAMESTORE_UNKNOWN
Unknown namestore error.
@ GNUNET_EC_NAMESTORE_RECORD_DATA_INVALID
Record data invalid.
@ GNUNET_EC_NAMESTORE_BACKEND_FAILED
There was an error in the database backend.
@ GNUNET_EC_NAMESTORE_LABEL_INVALID
Label invalid or malformed.
@ GNUNET_EC_NONE
No error (success).
@ GNUNET_EC_NAMESTORE_RECORD_NOT_FOUND
Record not found.
@ GNUNET_EC_NAMESTORE_ZONE_NOT_FOUND
Zone not found.
@ GNUNET_EC_NAMESTORE_RECORD_TOO_BIG
Record size exceeds maximum limit.
@ GNUNET_EC_NAMESTORE_STORE_FAILED
Failed to store the given records.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static int res
uint32_t data
The data value.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static char * zone
Name of the zone being managed.
static const struct GNUNET_IDENTITY_PrivateKey * zone_key
Private key of the zone.
static unsigned int rd_count
Number of records for currently parsed set.
static struct GNUNET_GNSRECORD_Data rd[50]
The record data under a single label.
static struct GNUNET_NAMESTORE_ZoneMonitor * zm
Monitor handle.
static struct GNUNET_TIME_Relative duration
How long do we run the test?
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_PEERINFO_NotifyContext * nc
Iterator context.
static struct GNUNET_CONTAINER_BloomFilter * filter
Bloomfilter to quickly tell if we don't have the content.
static void get_existing_rd_exp(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_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 void handle_zone_to_name_it(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Zone to name iterator.
static enum GNUNET_GenericReturnValue check_iteration_start(void *cls, const struct ZoneIterationStartMessage *zis_msg)
static void send_tx_response(int rid, enum GNUNET_ErrorCode ec, struct NamestoreClient *nc)
static int return_orphaned
Returned orphaned records?
static void lookup_it(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_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...
GNUNET_SERVICE_MAIN("namestore", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_fixed_size(tx_control, GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL, struct TxControlMessage, NULL), GNUNET_MQ_hd_var_size(record_store, GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE, struct RecordStoreMessage, 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 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 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 enum GNUNET_ErrorCode store_record_set(struct NamestoreClient *nc, const struct GNUNET_IDENTITY_PrivateKey *private_key, const struct RecordSet *rd_set, ssize_t *len)
static void monitor_sync(struct ZoneMonitor *zm)
Send 'sync' message to zone monitor, we're now in sync.
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 monitor_iterate_cb(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
A GNUNET_NAMESTORE_RecordIterator for monitors.
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 void lookup_nick_it(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_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.
static struct GNUNET_STATISTICS_Handle * statistics
Handle to the statistics service.
static void handle_tx_control(void *cls, const struct TxControlMessage *tx_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL message.
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 cache_nick(const struct GNUNET_IDENTITY_PrivateKey *zone, const struct GNUNET_GNSRECORD_Data *nick)
Add entry to the cache for zone and nick.
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 ...
static int send_lookup_response_with_filter(struct NamestoreClient *nc, uint32_t request_id, const struct GNUNET_IDENTITY_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...
#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 void monitor_iteration_next(void *cls)
Obtain the next datum during the zone monitor's zone initial iteration.
static const struct GNUNET_CONFIGURATION_Handle * GSN_cfg
Configuration handle.
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 * 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 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 const struct GNUNET_IDENTITY_PrivateKey zero
Public key of all zeros.
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 warn_monitor_slow(void *cls)
Print a warning that one of our monitors is no longer reacting.
static enum GNUNET_GenericReturnValue check_monitor_start(void *cls, const struct ZoneMonitorStartMessage *zis_msg)
static void zone_iterate_proc(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process results for zone iteration from database.
static struct GNUNET_GNSRECORD_Data * get_nick_record(const struct GNUNET_IDENTITY_PrivateKey *zone)
Return the NICK record for the zone (if it exists).
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
Process namestore requests.
static char buf[2048]
static void iteration_start()
API to the GNS service.
Plugin API for the namestore database backend.
API that can be used to store naming information on a GNUnet node;.
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.
char * GNUNET_GNSRECORD_string_normalize(const char *src)
Normalize a UTF-8 string to a GNS name.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_label_check(const char *label, char **emsg)
Check label for invalid characters.
@ 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_PRIVATE
This is a private record of this peer and it should thus not be published.
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.
GNUNET_NETWORK_STRUCT_END 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).
const char * GNUNET_GNSRECORD_z2s(const struct GNUNET_IDENTITY_PublicKey *z)
Convert a zone to a string (for printing debug messages).
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 *expiry, enum GNUNET_GNSRECORD_Filter filter, char **emsg)
Normalize namestore records: Check for consistency and expirations.
@ GNUNET_GNSRECORD_FILTER_NONE
No filter flags set.
@ GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE
Filter private records.
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_key_get_public(const struct GNUNET_IDENTITY_PrivateKey *privkey, struct GNUNET_IDENTITY_PublicKey *key)
Retrieves the public key representation of a private key.
Definition: identity_api.c:179
ssize_t GNUNET_IDENTITY_write_private_key_to_buffer(const struct GNUNET_IDENTITY_PrivateKey *key, void *buffer, size_t len)
Writes a GNUNET_IDENTITY_PrivateKey to a compact buffer.
Definition: identity_api.c:933
ssize_t GNUNET_IDENTITY_private_key_get_length(const struct GNUNET_IDENTITY_PrivateKey *key)
Get the compacted length of a GNUNET_IDENTITY_PrivateKey.
Definition: identity_api.c:809
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_read_public_key_from_buffer(const void *buffer, size_t len, struct GNUNET_IDENTITY_PublicKey *key, size_t *kb_read)
Reads a GNUNET_IDENTITY_PublicKey from a compact buffer.
Definition: identity_api.c:865
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_read_private_key_from_buffer(const void *buffer, size_t len, struct GNUNET_IDENTITY_PrivateKey *key, size_t *kb_read)
Reads a GNUNET_IDENTITY_PrivateKey from a compact buffer.
Definition: identity_api.c:908
#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
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.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
@ 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:304
#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:62
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:77
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition: nc.c:122
#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
@ GNUNET_NAMESTORE_TX_COMMIT
@ GNUNET_NAMESTORE_TX_ROLLBACK
@ GNUNET_NAMESTORE_TX_BEGIN
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
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
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT_END
Service to client: end of list of results.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL_RESULT
Return status message for control message.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
Service to client: here is a (plaintext) record you requested.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE
Service to client: result of zone-to-name lookup.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
Service to client: result of store operation.
#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_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_TX_CONTROL
Message type for Begin, Commit or Rollback.
#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_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1299
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1334
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1272
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the 'monitor' flag on this client.
Definition: service.c:2413
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2330
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2249
@ 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
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:616
#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
common internal definitions for namestore service
static unsigned int size
Size of the "table".
Definition: peer.c:68
const char * name
static int zone_to_name(void *cls, const struct GNUNET_HashCode *key, void *value)
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.
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
Handle to a message queue.
Definition: mq.c:87
Header for all communications.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
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_IDENTITY_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_IDENTITY_PrivateKey zone
Monitored zone.
struct GNUNET_MQ_Handle * mq
Handle to namestore service.
enum GNUNET_GNSRECORD_Filter filter
Record set filter for this monitor.
The notification context is the key datastructure for a convenience API used for transmission of noti...
Definition: nc.c:77
struct GNUNET_MQ_Handle * mq
Our connection to the PEERINFO service.
Entry in list of pending tasks.
Definition: scheduler.c:136
Handle to a client that is connected to a service.
Definition: service.c:252
Handle to a service.
Definition: service.c:118
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:132
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP.
Definition: namestore.h:136
uint16_t key_len
Length of the zone key.
Definition: namestore.h:156
uint16_t is_edit_request
GNUNET_YES if this lookup corresponds to an edit request.
Definition: namestore.h:146
uint16_t filter
The record filter.
Definition: namestore.h:151
uint16_t label_len
Length of the name.
Definition: namestore.h:141
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:183
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE.
Definition: namestore.h:173
uint16_t reserved
Reserved (alignment)
Definition: namestore.h:199
uint16_t key_len
Length of the zone key.
Definition: namestore.h:204
uint16_t rd_count
Number of records contained.
Definition: namestore.h:188
uint16_t name_len
Name length.
Definition: namestore.h:178
int16_t found
Was the label found in the database?? GNUNET_YES or GNUNET_NO.
Definition: namestore.h:194
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.
int in_transaction
GNUNET_YES if this nc has begun a transaction which is uncommited.
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 (neeed 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.
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_IDENTITY_PrivateKey zone
Zone the cache entry is for.
Closure for lookup_it().
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:292
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:312
uint16_t name_len
Name length.
Definition: namestore.h:307
uint16_t rd_count
Number of records contained.
Definition: namestore.h:317
struct GNUNET_TIME_AbsoluteNBO expire
Expiration time if the record result (if any).
Definition: namestore.h:302
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT.
Definition: namestore.h:296
uint16_t key_len
Length of the zone key.
Definition: namestore.h:322
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:96
uint16_t key_len
Length of the zone key.
Definition: namestore.h:101
Response to a record storage request.
Definition: namestore.h:114
uint32_t ec
GNUNET_ErrorCode.
Definition: namestore.h:123
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE.
Definition: namestore.h:118
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 GNUNET_IDENTITY_PrivateKey private_key
The zone private key.
struct NamestoreClient * nc
Which client triggered the store activity?
int uncommited
Wheather or not this store action is already commited.
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.
Send a transaction control message.
Definition: namestore.h:335
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL.
Definition: namestore.h:339
uint16_t control
The type of control message to send.
Definition: namestore.h:349
Result of a transaction control message.
Definition: namestore.h:357
uint32_t ec
Of type GNUNET_ErrorCode.
Definition: namestore.h:366
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL_RESULT.
Definition: namestore.h:361
Ask for next result of zone iteration for the given operation.
Definition: namestore.h:460
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT.
Definition: namestore.h:464
uint64_t limit
Number of records to return to the iterator in one shot (before GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_IT...
Definition: namestore.h:471
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:433
uint16_t key_len
Length of the zone key.
Definition: namestore.h:448
uint16_t filter
Record set filter control flags.
Definition: namestore.h:443
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START.
Definition: namestore.h:437
Stop zone iteration for the given operation.
Definition: namestore.h:479
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP.
Definition: namestore.h:483
A namestore iteration operation.
struct NamestoreClient * nc
Namestore client which intiated 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.
struct GNUNET_IDENTITY_PrivateKey zone
Key of the zone we are iterating over.
enum GNUNET_GNSRECORD_Filter filter
The record set filter.
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.
unsigned int cache_ops
Number of pending cache operations triggered by this zone iteration which we need to wait for before ...
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:409
uint64_t limit
Number of records to return to the iterator in one shot (before #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_M...
Definition: namestore.h:425
Start monitoring a zone.
Definition: namestore.h:376
uint32_t iterate_first
GNUNET_YES to first iterate over all records, GNUNET_NO to only monitor changes.o
Definition: namestore.h:386
uint16_t filter
Record set filter control flags.
Definition: namestore.h:392
uint16_t key_len
Length of the zone key.
Definition: namestore.h:397
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START.
Definition: namestore.h:380
A namestore monitor.
struct GNUNET_SCHEDULER_Task * sa_wait_warning
Task to warn about slow monitors.
struct GNUNET_IDENTITY_PrivateKey zone
Private key of the zone.
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_SCHEDULER_Task * task
Task active during initial iteration.
struct NamestoreClient * nc
Namestore client which intiated 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:218
uint16_t pkey_len
Length of the public value zone key.
Definition: namestore.h:232
uint16_t key_len
Length of the zone key.
Definition: namestore.h:227
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME.
Definition: namestore.h:222
Respone for zone to name lookup.
Definition: namestore.h:246
uint16_t name_len
Length of the name.
Definition: namestore.h:263
int32_t ec
result in NBO: GNUNET_EC_NONE on success, GNUNET_EC_NAMESTORE_NO_RESULTS if there were no results.
Definition: namestore.h:258
uint16_t key_len
Length of the zone key.
Definition: namestore.h:278
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
Definition: namestore.h:250
uint16_t rd_count
Number of records contained.
Definition: namestore.h:273
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:268