GNUnet  0.17.6
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_dnsparser_lib.h"
30 #include "gnunet_gns_service.h"
35 #include "gnunet_signatures.h"
36 #include "namestore.h"
37 
38 #define LOG_STRERROR_FILE(kind, syscall, filename) \
39  GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
40 
44 #define MONITOR_STALL_WARN_DELAY GNUNET_TIME_UNIT_MINUTES
45 
49 #define NC_SIZE 16
50 
54 struct NamestoreClient;
55 
56 
61 {
66 
71 
76 
81 
86 
91 
99  uint64_t seq;
100 
104  uint32_t request_id;
105 
113  uint32_t offset;
114 
119  unsigned int cache_ops;
120 
126  int send_end;
127 };
128 
133 {
138 
143 
147  char *db_lib_name;
148 
153 
159 
165 };
166 
167 
172 {
176  struct ZoneMonitor *next;
177 
181  struct ZoneMonitor *prev;
182 
187 
192 
197 
202 
207 
212 
220  uint64_t seq;
221 
226  uint64_t limit;
227 
234  uint64_t iteration_cnt;
235 
240 
248 };
249 
250 
255 {
260 
265 
270 
275 
280  struct ZoneIteration *zi;
281 
285  uint32_t rid;
286 };
287 
288 
294 {
299 
304 
309 
314  const struct RecordStoreMessage *rsm;
315 
320 
324  char *conv_name;
325 };
326 
327 
331 struct NickCache
332 {
337 
342 
347 };
348 
349 
353 static struct NickCache nick_cache[NC_SIZE];
354 
358 static const struct GNUNET_IDENTITY_PrivateKey zero;
359 
364 
369 
374 
378 static char *db_lib_name;
379 
384 
385 
389 static struct CacheOperation *cop_head;
390 
394 static struct CacheOperation *cop_tail;
395 
399 static struct ZoneMonitor *monitor_head;
400 
404 static struct ZoneMonitor *monitor_tail;
405 
409 static struct StoreActivity *sa_head;
410 
414 static struct StoreActivity *sa_tail;
415 
420 
425 static int cache_keys;
426 
431 static int disable_namecache;
432 
433 
439 static void
440 cleanup_task (void *cls)
441 {
442  struct CacheOperation *cop;
443 
444  (void) cls;
445  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n");
446  while (NULL != (cop = cop_head))
447  {
449  "Aborting incomplete namecache operation\n");
452  GNUNET_free (cop);
453  }
454 
455  if (NULL != namecache)
456  {
458  namecache = NULL;
459  }
460  if (NULL != monitor_nc)
461  {
463  monitor_nc = NULL;
464  }
465  if (NULL != statistics)
466  {
468  statistics = NULL;
469  }
472  db_lib_name = NULL;
473 }
474 
475 
481 static void
483 {
485  GNUNET_free (sa->conv_name);
486  GNUNET_free (sa);
487 }
488 
489 
502 static void
503 lookup_nick_it (void *cls,
504  uint64_t seq,
505  const struct GNUNET_IDENTITY_PrivateKey *private_key,
506  const char *label,
507  unsigned int rd_count,
508  const struct GNUNET_GNSRECORD_Data *rd)
509 {
510  struct GNUNET_GNSRECORD_Data **res = cls;
511 
512  (void) private_key;
513  GNUNET_assert (0 != seq);
514  if (0 != strcmp (label, GNUNET_GNS_EMPTY_LABEL_AT))
515  {
516  GNUNET_break (0);
517  return;
518  }
519  for (unsigned int c = 0; c < rd_count; c++)
520  {
522  {
523  (*res) =
524  GNUNET_malloc (rd[c].data_size + sizeof(struct GNUNET_GNSRECORD_Data));
525  (*res)->data = &(*res)[1];
526  GNUNET_memcpy ((void *) (*res)->data, rd[c].data, rd[c].data_size);
527  (*res)->data_size = rd[c].data_size;
528  (*res)->expiration_time = rd[c].expiration_time;
529  (*res)->flags = rd[c].flags;
530  (*res)->record_type = GNUNET_GNSRECORD_TYPE_NICK;
531  return;
532  }
533  }
534  (*res) = NULL;
535 }
536 
537 
544 static void
546  const struct GNUNET_GNSRECORD_Data *nick)
547 {
548  struct NickCache *oldest;
549 
550  oldest = NULL;
551  for (unsigned int i = 0; i < NC_SIZE; i++)
552  {
553  struct NickCache *pos = &nick_cache[i];
554 
555  if ((NULL == oldest) ||
556  (oldest->last_used.abs_value_us > pos->last_used.abs_value_us))
557  oldest = pos;
558  if (0 == GNUNET_memcmp (zone, &pos->zone))
559  {
560  oldest = pos;
561  break;
562  }
563  }
564  GNUNET_free (oldest->rd);
565  oldest->zone = *zone;
566  if (NULL != nick)
567  {
568  oldest->rd = GNUNET_malloc (sizeof(*nick) + nick->data_size);
569  *oldest->rd = *nick;
570  oldest->rd->data = &oldest->rd[1];
571  memcpy (&oldest->rd[1], nick->data, nick->data_size);
572  }
573  else
574  {
575  oldest->rd = NULL;
576  }
577  oldest->last_used = GNUNET_TIME_absolute_get ();
578 }
579 
580 
588 static struct GNUNET_GNSRECORD_Data *
590 {
592  struct GNUNET_GNSRECORD_Data *nick;
593  int res;
594 
595  /* check cache first */
596  for (unsigned int i = 0; i < NC_SIZE; i++)
597  {
598  struct NickCache *pos = &nick_cache[i];
599  if ((NULL != pos->rd) && (0 == GNUNET_memcmp (zone, &pos->zone)))
600  {
601  if (NULL == pos->rd)
602  return NULL;
603  nick = GNUNET_malloc (sizeof(*nick) + pos->rd->data_size);
604  *nick = *pos->rd;
605  nick->data = &nick[1];
606  memcpy (&nick[1], pos->rd->data, pos->rd->data_size);
608  return nick;
609  }
610  }
611 
612  nick = NULL;
614  zone,
617  &nick);
618  if ((GNUNET_OK != res) || (NULL == nick))
619  {
620 #if ! defined(GNUNET_CULL_LOGGING)
621  static int do_log = GNUNET_LOG_CALL_STATUS;
622 
623  if (0 == do_log)
625  "namestore",
626  __FILE__,
627  __FUNCTION__,
628  __LINE__);
629  if (1 == do_log)
630  {
633  "No nick name set for zone `%s'\n",
635  }
636 #endif
637  /* update cache */
638  cache_nick (zone, NULL);
639  return NULL;
640  }
641 
642  /* update cache */
643  cache_nick (zone, nick);
644  return nick;
645 }
646 
647 
663 static void
665  unsigned int rd2_length,
666  const struct GNUNET_GNSRECORD_Data *rd2,
667  unsigned int *rdc_res,
668  struct GNUNET_GNSRECORD_Data **rd_res)
669 {
670  uint64_t latest_expiration;
671  size_t req;
672  char *data;
673  size_t data_offset;
674  struct GNUNET_GNSRECORD_Data *target;
675 
676  (*rdc_res) = 1 + rd2_length;
677  if (0 == 1 + rd2_length)
678  {
679  GNUNET_break (0);
680  (*rd_res) = NULL;
681  return;
682  }
683  req = sizeof(struct GNUNET_GNSRECORD_Data) + nick_rd->data_size;
684  for (unsigned int i = 0; i < rd2_length; i++)
685  {
686  const struct GNUNET_GNSRECORD_Data *orig = &rd2[i];
687 
688  if (req + sizeof(struct GNUNET_GNSRECORD_Data) + orig->data_size < req)
689  {
690  GNUNET_break (0);
691  (*rd_res) = NULL;
692  return;
693  }
694  req += sizeof(struct GNUNET_GNSRECORD_Data) + orig->data_size;
695  }
696  target = GNUNET_malloc (req);
697  (*rd_res) = target;
698  data = (char *) &target[1 + rd2_length];
699  data_offset = 0;
700  latest_expiration = 0;
701  for (unsigned int i = 0; i < rd2_length; i++)
702  {
703  const struct GNUNET_GNSRECORD_Data *orig = &rd2[i];
704 
706  {
707  if ((GNUNET_TIME_absolute_get ().abs_value_us + orig->expiration_time) >
708  latest_expiration)
709  latest_expiration = orig->expiration_time;
710  }
711  else if (orig->expiration_time > latest_expiration)
712  latest_expiration = orig->expiration_time;
713  target[i] = *orig;
714  target[i].data = (void *) &data[data_offset];
715  GNUNET_memcpy (&data[data_offset], orig->data, orig->data_size);
716  data_offset += orig->data_size;
717  }
718  /* append nick */
719  target[rd2_length] = *nick_rd;
720  /* Mark as supplemental */
721  target[rd2_length].flags = nick_rd->flags | GNUNET_GNSRECORD_RF_SUPPLEMENTAL;
722  target[rd2_length].expiration_time = latest_expiration;
723  target[rd2_length].data = (void *) &data[data_offset];
724  GNUNET_memcpy (&data[data_offset], nick_rd->data, nick_rd->data_size);
725  data_offset += nick_rd->data_size;
726  GNUNET_assert (req == (sizeof(struct GNUNET_GNSRECORD_Data)) * (*rdc_res)
727  + data_offset);
728 }
729 
730 
743 static void
745  uint32_t request_id,
746  const struct
748  const char *name,
749  unsigned int rd_count,
750  const struct GNUNET_GNSRECORD_Data *rd,
752 {
753  struct GNUNET_MQ_Envelope *env;
754  struct RecordResultMessage *zir_msg;
755  struct GNUNET_GNSRECORD_Data *nick;
756  struct GNUNET_GNSRECORD_Data *res;
757  struct GNUNET_GNSRECORD_Data rd_nf[rd_count];
759  unsigned int res_count;
760  unsigned int rd_nf_count;
761  size_t name_len;
762  ssize_t rd_ser_len;
763  char *name_tmp;
764  char *rd_ser;
765  char *emsg;
766 
767  nick = get_nick_record (zone_key);
768  GNUNET_assert (-1 != GNUNET_GNSRECORD_records_get_size (rd_count, rd));
769 
771  rd,
772  rd_count,
773  rd_nf,
774  &rd_nf_count,
775  &block_exp,
776  filter,
777  &emsg))
778  {
779  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
780  GNUNET_free (emsg);
781  GNUNET_assert (0);
782  }
783 
788  if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT)))
789  {
790  nick->flags =
792  merge_with_nick_records (nick, rd_nf_count, rd_nf, &res_count, &res);
793  }
794  else
795  {
796  res_count = rd_nf_count;
797  res = (struct GNUNET_GNSRECORD_Data *) rd_nf;
798  }
799  if (NULL != nick)
800  GNUNET_free (nick);
801 
803 
804 
805  name_len = strlen (name) + 1;
806  rd_ser_len = GNUNET_GNSRECORD_records_get_size (res_count, res);
807  if (rd_ser_len < 0)
808  {
809  if (rd_nf != res)
810  GNUNET_free (res);
811  GNUNET_break (0);
812  GNUNET_SERVICE_client_drop (nc->client);
813  return;
814  }
815  if (((size_t) rd_ser_len) >= UINT16_MAX - name_len - sizeof(*zir_msg))
816  {
817  if (rd_nf != res)
818  GNUNET_free (res);
819  GNUNET_break (0);
820  GNUNET_SERVICE_client_drop (nc->client);
821  return;
822  }
823  env = GNUNET_MQ_msg_extra (zir_msg,
824  name_len + rd_ser_len,
826  zir_msg->gns_header.r_id = htonl (request_id);
827  zir_msg->name_len = htons (name_len);
828  zir_msg->rd_count = htons (res_count);
829  zir_msg->rd_len = htons ((uint16_t) rd_ser_len);
830  zir_msg->private_key = *zone_key;
831  zir_msg->expire = GNUNET_TIME_absolute_hton (block_exp);
832  name_tmp = (char *) &zir_msg[1];
833  GNUNET_memcpy (name_tmp, name, name_len);
834  rd_ser = &name_tmp[name_len];
835  GNUNET_assert (
836  rd_ser_len ==
837  GNUNET_GNSRECORD_records_serialize (res_count, res, rd_ser_len, rd_ser));
839  "Sending RECORD_RESULT message with %u records\n",
840  res_count);
842  "Record sets sent to clients",
843  1,
844  GNUNET_NO);
845  GNUNET_MQ_send (nc->mq, env);
846  if (rd_nf != res)
847  GNUNET_free (res);
848 }
849 
861 static void
863  uint32_t request_id,
864  const struct
866  const char *name,
867  unsigned int rd_count,
868  const struct GNUNET_GNSRECORD_Data *rd)
869 {
871  rd_count, rd, GNUNET_GNSRECORD_FILTER_NONE);
872 }
873 
881 static void
882 send_store_response (struct NamestoreClient *nc, int res, const char*emsg,
883  uint32_t rid)
884 {
885  struct GNUNET_MQ_Envelope *env;
886  struct RecordStoreResponseMessage *rcr_msg;
887 
888  GNUNET_assert (NULL != nc);
890  "Sending RECORD_STORE_RESPONSE message\n");
892  "Store requests completed",
893  1,
894  GNUNET_NO);
895  env = GNUNET_MQ_msg_extra (rcr_msg,
896  (NULL != emsg) ? strlen (emsg) + 1 : 0,
898  rcr_msg->gns_header.r_id = htonl (rid);
899  rcr_msg->op_result = htonl (res);
900  rcr_msg->reserved = htons (0);
901  if (NULL != emsg)
902  {
903  rcr_msg->emsg_len = htons (strlen (emsg) + 1);
904  memcpy (&rcr_msg[1], emsg, strlen (emsg) + 1);
905  }
906  GNUNET_MQ_send (nc->mq, env);
907 }
908 
909 
916 static void
918 {
919  struct GNUNET_MQ_Envelope *env;
920  struct GNUNET_NAMESTORE_Header *em;
921 
923  if (! zi->send_end)
924  return;
925  /* send empty response to indicate end of list */
927  em->r_id = htonl (zi->request_id);
928  GNUNET_MQ_send (zi->nc->mq, env);
929 
931  GNUNET_free (zi);
932 }
933 
934 
942 static void
943 finish_cache_operation (void *cls, int32_t success, const char *emsg)
944 {
945  struct CacheOperation *cop = cls;
946  struct ZoneIteration *zi;
947 
948  if (NULL != emsg)
950  _ ("Failed to replicate block in namecache: %s\n"),
951  emsg);
952  else
953  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n");
955  if (NULL != cop->nc)
956  send_store_response (cop->nc, success, emsg, cop->rid);
957  if (NULL != (zi = cop->zi))
958  {
959  zi->cache_ops--;
960  if (0 == zi->cache_ops)
961  {
962  /* unchoke zone iteration, cache has caught up */
964  }
965  }
966  GNUNET_free (cop);
967 }
968 
969 
982 static void
984  struct ZoneIteration *zi,
985  uint32_t rid,
986  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
987  const char *name,
988  unsigned int rd_count,
989  const struct GNUNET_GNSRECORD_Data *rd)
990 {
991  struct GNUNET_GNSRECORD_Block *block;
992  struct GNUNET_GNSRECORD_Data rd_clean[rd_count];
993  struct CacheOperation *cop;
995  struct GNUNET_GNSRECORD_Data *nick;
996  struct GNUNET_GNSRECORD_Data *res;
997  unsigned int res_count;
998  unsigned int rd_count_clean;
999  struct GNUNET_TIME_Absolute exp_time;
1000 
1002  rd_count_clean = 0;
1003  for (int i = 0; i < rd_count; i++)
1004  {
1005  if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type)
1006  continue;
1007  rd_clean[rd_count_clean++] = rd[i];
1008  }
1009 
1010  nick = get_nick_record (zone_key);
1011  res_count = rd_count_clean;
1012  res = (struct GNUNET_GNSRECORD_Data *) rd_clean; /* fixme: a bit unclean... */
1013  if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT)))
1014  {
1015  nick->flags =
1017  merge_with_nick_records (nick, rd_count_clean, rd_clean, &res_count, &res);
1018  }
1019  if (NULL != nick)
1020  GNUNET_free (nick);
1021  if (0 == res_count)
1022  {
1023  if (NULL != nc)
1024  send_store_response (nc, GNUNET_OK, NULL, rid);
1025  if (rd_clean != res)
1026  GNUNET_free (res);
1027  return; /* no data, no need to update cache */
1028  }
1030  {
1032  "Namecache updates skipped (NC disabled)",
1033  1,
1034  GNUNET_NO);
1035  if (NULL != nc)
1036  send_store_response (nc, GNUNET_OK, NULL, rid);
1037  if (rd_clean != res)
1038  GNUNET_free (res);
1039  return;
1040  }
1041  exp_time = GNUNET_GNSRECORD_record_get_expiration_time (res_count, res,
1043  if (cache_keys)
1046  res, res_count, &block));
1047  else
1050  res, res_count, &block));
1051  GNUNET_assert (NULL != block);
1053  GNUNET_log (
1055  "Caching block for label `%s' with %u records and expiration %s in zone `%s' in namecache\n",
1056  name,
1057  res_count,
1061  "Namecache updates pushed",
1062  1,
1063  GNUNET_NO);
1064  cop = GNUNET_new (struct CacheOperation);
1065  cop->nc = nc;
1066  cop->zi = zi;
1067  if (NULL != zi)
1068  zi->cache_ops++;
1069  cop->rid = rid;
1072  block,
1074  cop);
1075  GNUNET_free (block);
1076  if (rd_clean != res)
1077  GNUNET_free (res);
1078 }
1079 
1080 
1086 static void
1088 {
1089  struct ZoneMonitor *zm = cls;
1090 
1092  "No response from monitor since %s\n",
1093  GNUNET_STRINGS_absolute_time_to_string (zm->sa_waiting_start));
1096  zm);
1097 }
1098 
1099 
1105 static void
1107 {
1108  const struct RecordStoreMessage *rp_msg = sa->rsm;
1109  unsigned int rd_count;
1110  size_t name_len;
1111  size_t rd_ser_len;
1112  uint32_t rid;
1113  const char *name_tmp;
1114  const char *rd_ser;
1115 
1116  rid = ntohl (rp_msg->gns_header.r_id);
1117  name_len = ntohs (rp_msg->name_len);
1118  rd_count = ntohs (rp_msg->rd_count);
1119  rd_ser_len = ntohs (rp_msg->rd_len);
1120  name_tmp = (const char *) &rp_msg[1];
1121  rd_ser = &name_tmp[name_len];
1122  {
1123  struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
1124 
1125  /* We did this before, must succeed again */
1126  GNUNET_assert (
1127  GNUNET_OK ==
1128  GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count, rd));
1129 
1130  for (struct ZoneMonitor *zm = sa->zm_pos; NULL != zm; zm = sa->zm_pos)
1131  {
1132  if ((0 != GNUNET_memcmp (&rp_msg->private_key, &zm->zone)) &&
1133  (0 != GNUNET_memcmp (&zm->zone, &zero)))
1134  {
1135  sa->zm_pos = zm->next; /* not interesting to this monitor */
1136  continue;
1137  }
1138  if (zm->limit == zm->iteration_cnt)
1139  {
1140  zm->sa_waiting = GNUNET_YES;
1141  zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
1142  if (NULL != zm->sa_wait_warning)
1143  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
1144  zm->sa_wait_warning =
1147  zm);
1148  return; /* blocked on zone monitor */
1149  }
1151  "Notifying monitor about changes under label `%s'\n",
1152  sa->conv_name);
1153  zm->limit--;
1155  0,
1156  &rp_msg->private_key,
1157  sa->conv_name,
1158  rd_count,
1159  rd,
1160  zm->filter);
1161  sa->zm_pos = zm->next;
1162  }
1163  /* great, done with the monitors, unpack (again) for refresh_block operation */
1164  refresh_block (sa->nc,
1165  NULL,
1166  rid,
1167  &rp_msg->private_key,
1168  sa->conv_name,
1169  rd_count,
1170  rd);
1171  }
1173  free_store_activity (sa);
1174 }
1175 
1176 
1185 static void
1187  struct GNUNET_SERVICE_Client *client,
1188  void *app_ctx)
1189 {
1190  struct NamestoreClient *nc = app_ctx;
1191  struct ZoneIteration *no;
1192  struct CacheOperation *cop;
1193 
1194  (void) cls;
1195  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
1196  for (struct ZoneMonitor *zm = monitor_head; NULL != zm; zm = zm->next)
1197  {
1198  struct StoreActivity *san;
1199 
1200  if (nc != zm->nc)
1201  continue;
1203  if (NULL != zm->task)
1204  {
1205  GNUNET_SCHEDULER_cancel (zm->task);
1206  zm->task = NULL;
1207  }
1208  if (NULL != zm->sa_wait_warning)
1209  {
1210  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
1211  zm->sa_wait_warning = NULL;
1212  }
1213  for (struct StoreActivity *sa = sa_head; NULL != sa; sa = san)
1214  {
1215  san = sa->next;
1216  if (zm == sa->zm_pos)
1217  {
1218  sa->zm_pos = zm->next;
1219  /* this may free sa */
1221  }
1222  }
1223  GNUNET_free (zm);
1224  break;
1225  }
1226  for (struct StoreActivity *sa = sa_head; NULL != sa; sa = sa->next)
1227  {
1228  if (sa->nc == nc)
1229  {
1230  /* this may free sa */
1231  free_store_activity (sa);
1232  break; /* there can only be one per nc */
1233  }
1234  }
1235  while (NULL != (no = nc->op_head))
1236  {
1237  GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no);
1238  GNUNET_free (no);
1239  }
1240  for (cop = cop_head; NULL != cop; cop = cop->next)
1241  if (nc == cop->nc)
1242  cop->nc = NULL;
1243  GNUNET_break (NULL == GNUNET_PLUGIN_unload (nc->db_lib_name, nc->GSN_database));
1244  GNUNET_free (nc->db_lib_name);
1245  GNUNET_free (nc);
1246 }
1247 
1248 
1257 static void *
1259  struct GNUNET_SERVICE_Client *client,
1260  struct GNUNET_MQ_Handle *mq)
1261 {
1262  struct NamestoreClient *nc;
1263  char *database;
1264 
1265  (void) cls;
1266  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1267  nc = GNUNET_new (struct NamestoreClient);
1268  nc->client = client;
1269  nc->mq = mq;
1270  /* Loading database plugin */
1272  "namestore",
1273  "database",
1274  &database))
1275  {
1276  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
1277  GNUNET_free (nc);
1278  return NULL;
1279  }
1280  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loading %s\n", db_lib_name);
1281  nc->GSN_database = GNUNET_PLUGIN_load (db_lib_name, (void *) GSN_cfg);
1282  GNUNET_free (database);
1283  if (NULL == nc->GSN_database)
1284  {
1286  "Could not load database backend `%s'\n",
1287  db_lib_name);
1288  GNUNET_free (nc);
1289  return NULL;
1290  }
1291  nc->db_lib_name = GNUNET_strdup (db_lib_name);
1293  return nc;
1294 }
1295 
1296 
1301 {
1305  const char *label;
1306 
1310  char *res_rd;
1311 
1316 
1320  int found;
1321 
1325  unsigned int res_rd_count;
1326 
1330  ssize_t rd_ser_len;
1331 };
1332 
1333 
1346 static void
1347 lookup_it (void *cls,
1348  uint64_t seq,
1349  const struct GNUNET_IDENTITY_PrivateKey *private_key,
1350  const char *label,
1351  unsigned int rd_count,
1352  const struct GNUNET_GNSRECORD_Data *rd)
1353 {
1354  struct RecordLookupContext *rlc = cls;
1355 
1356  (void) private_key;
1357  GNUNET_assert (0 != seq);
1358  if (0 != strcmp (label, rlc->label))
1359  return;
1360  rlc->found = GNUNET_YES;
1361  if (0 == rd_count)
1362  {
1363  rlc->rd_ser_len = 0;
1364  rlc->res_rd_count = 0;
1365  rlc->res_rd = NULL;
1366  return;
1367  }
1368  if ((NULL != rlc->nick) && (0 != strcmp (label, GNUNET_GNS_EMPTY_LABEL_AT)))
1369  {
1370  /* Merge */
1371  struct GNUNET_GNSRECORD_Data *rd_res;
1372  unsigned int rdc_res;
1373 
1374  rd_res = NULL;
1375  rdc_res = 0;
1376  rlc->nick->flags = (rlc->nick->flags | GNUNET_GNSRECORD_RF_PRIVATE)
1378  merge_with_nick_records (rlc->nick, rd_count, rd, &rdc_res, &rd_res);
1379  rlc->rd_ser_len = GNUNET_GNSRECORD_records_get_size (rdc_res, rd_res);
1380  if (rlc->rd_ser_len < 0)
1381  {
1382  GNUNET_break (0);
1383  GNUNET_free (rd_res);
1384  rlc->found = GNUNET_NO;
1385  rlc->rd_ser_len = 0;
1386  return;
1387  }
1388  rlc->res_rd_count = rdc_res;
1389  rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1390  if (rlc->rd_ser_len != GNUNET_GNSRECORD_records_serialize (rdc_res,
1391  rd_res,
1392  rlc->rd_ser_len,
1393  rlc->res_rd))
1394  {
1395  GNUNET_break (0);
1396  GNUNET_free (rlc->res_rd);
1397  rlc->res_rd = NULL;
1398  rlc->res_rd_count = 0;
1399  rlc->rd_ser_len = 0;
1400  GNUNET_free (rd_res);
1401  rlc->found = GNUNET_NO;
1402  return;
1403  }
1404  GNUNET_free (rd_res);
1405  GNUNET_free (rlc->nick);
1406  rlc->nick = NULL;
1407  }
1408  else
1409  {
1410  rlc->rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1411  if (rlc->rd_ser_len < 0)
1412  {
1413  GNUNET_break (0);
1414  rlc->found = GNUNET_NO;
1415  rlc->rd_ser_len = 0;
1416  return;
1417  }
1418  rlc->res_rd_count = rd_count;
1419  rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1420  if (rlc->rd_ser_len != GNUNET_GNSRECORD_records_serialize (rd_count,
1421  rd,
1422  rlc->rd_ser_len,
1423  rlc->res_rd))
1424  {
1425  GNUNET_break (0);
1426  GNUNET_free (rlc->res_rd);
1427  rlc->res_rd = NULL;
1428  rlc->res_rd_count = 0;
1429  rlc->rd_ser_len = 0;
1430  rlc->found = GNUNET_NO;
1431  return;
1432  }
1433  }
1434 }
1435 
1436 
1444 static int
1445 check_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
1446 {
1447  uint32_t name_len;
1448  size_t src_size;
1449 
1450  (void) cls;
1451  name_len = ntohl (ll_msg->label_len);
1452  src_size = ntohs (ll_msg->gns_header.header.size);
1453  if (name_len != src_size - sizeof(struct LabelLookupMessage))
1454  {
1455  GNUNET_break (0);
1456  return GNUNET_SYSERR;
1457  }
1459  return GNUNET_OK;
1460 }
1461 
1462 
1469 static void
1470 handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
1471 {
1472  struct NamestoreClient *nc = cls;
1473  struct GNUNET_MQ_Envelope *env;
1474  struct LabelLookupResponseMessage *llr_msg;
1475  struct RecordLookupContext rlc;
1476  const char *name_tmp;
1477  char *res_name;
1478  char *conv_name;
1479  uint32_t name_len;
1480  int res;
1481 
1482  name_tmp = (const char *) &ll_msg[1];
1485  "Received NAMESTORE_RECORD_LOOKUP message for name `%s'\n",
1486  name_tmp);
1487 
1488  conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
1489  if (NULL == conv_name)
1490  {
1492  "Error converting name `%s'\n",
1493  name_tmp);
1494  GNUNET_SERVICE_client_drop (nc->client);
1495  return;
1496  }
1497  name_len = strlen (conv_name) + 1;
1498  rlc.label = conv_name;
1499  rlc.found = GNUNET_NO;
1500  rlc.res_rd_count = 0;
1501  rlc.res_rd = NULL;
1502  rlc.rd_ser_len = 0;
1503  rlc.nick = get_nick_record (&ll_msg->zone);
1504  if (GNUNET_YES != ntohl (ll_msg->is_edit_request))
1505  res = nc->GSN_database->lookup_records (nc->GSN_database->cls,
1506  &ll_msg->zone,
1507  conv_name,
1508  &lookup_it,
1509  &rlc);
1510  else
1511  res = nc->GSN_database->edit_records (nc->GSN_database->cls,
1512  &ll_msg->zone,
1513  conv_name,
1514  &lookup_it,
1515  &rlc);
1516 
1517  env =
1518  GNUNET_MQ_msg_extra (llr_msg,
1519  name_len + rlc.rd_ser_len,
1521  llr_msg->gns_header.r_id = ll_msg->gns_header.r_id;
1522  llr_msg->private_key = ll_msg->zone;
1523  llr_msg->name_len = htons (name_len);
1524  llr_msg->rd_count = htons (rlc.res_rd_count);
1525  llr_msg->rd_len = htons (rlc.rd_ser_len);
1526  res_name = (char *) &llr_msg[1];
1527  if (GNUNET_YES == rlc.found)
1528  llr_msg->found = htons (GNUNET_YES);
1529  else if (GNUNET_SYSERR == res)
1530  llr_msg->found = htons (GNUNET_SYSERR);
1531  else
1532  llr_msg->found = htons (GNUNET_NO);
1533  GNUNET_memcpy (&llr_msg[1], conv_name, name_len);
1534  GNUNET_memcpy (&res_name[name_len], rlc.res_rd, rlc.rd_ser_len);
1535  GNUNET_MQ_send (nc->mq, env);
1536  GNUNET_free (rlc.res_rd);
1537  GNUNET_free (conv_name);
1538 }
1539 
1540 
1541 
1549 static int
1550 check_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1551 {
1552  size_t name_len;
1553  size_t msg_size;
1554  size_t msg_size_exp;
1555  size_t rd_ser_len;
1556  const char *name_tmp;
1557 
1558  (void) cls;
1559  name_len = ntohs (rp_msg->name_len);
1560  msg_size = ntohs (rp_msg->gns_header.header.size);
1561  rd_ser_len = ntohs (rp_msg->rd_len);
1562  msg_size_exp = sizeof(struct RecordStoreMessage) + name_len + rd_ser_len;
1563  if (msg_size != msg_size_exp)
1564  {
1565  GNUNET_break (0);
1566  return GNUNET_SYSERR;
1567  }
1568  if ((0 == name_len) || (name_len > MAX_NAME_LEN))
1569  {
1570  GNUNET_break (0);
1571  return GNUNET_SYSERR;
1572  }
1573  name_tmp = (const char *) &rp_msg[1];
1574  if ('\0' != name_tmp[name_len - 1])
1575  {
1576  GNUNET_break (0);
1577  return GNUNET_SYSERR;
1578  }
1579  return GNUNET_OK;
1580 }
1581 
1582 
1593 static void
1595  uint64_t seq,
1596  const struct
1598  const char *label,
1599  unsigned int rd_count,
1600  const struct GNUNET_GNSRECORD_Data *rd)
1601 {
1602  struct GNUNET_TIME_Absolute *exp = cls;
1603  struct GNUNET_GNSRECORD_Data rd_pub[rd_count];
1604  unsigned int rd_pub_count;
1605  char *emsg;
1606 
1607  if (GNUNET_OK !=
1609  rd,
1610  rd_count,
1611  rd_pub,
1612  &rd_pub_count,
1613  exp,
1615  &emsg))
1616  {
1618  "%s\n", emsg);
1619  GNUNET_free (emsg);
1620  }
1621 }
1622 
1623 
1630 static void
1631 handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1632 {
1633  struct NamestoreClient *nc = cls;
1634  size_t name_len;
1635  size_t rd_ser_len;
1636  uint32_t rid;
1637  const char *name_tmp;
1638  char *conv_name;
1639  const char *rd_ser;
1640  unsigned int rd_count;
1641  int res;
1642  struct StoreActivity *sa;
1643  struct GNUNET_TIME_Absolute existing_block_exp;
1644  struct GNUNET_TIME_Absolute new_block_exp;
1645 
1647  "Received NAMESTORE_RECORD_STORE message\n");
1648  existing_block_exp = GNUNET_TIME_UNIT_ZERO_ABS;
1649  new_block_exp = GNUNET_TIME_UNIT_ZERO_ABS;
1650  rid = ntohl (rp_msg->gns_header.r_id);
1651  name_len = ntohs (rp_msg->name_len);
1652  rd_count = ntohs (rp_msg->rd_count);
1653  rd_ser_len = ntohs (rp_msg->rd_len);
1654  name_tmp = (const char *) &rp_msg[1];
1655  rd_ser = &name_tmp[name_len];
1656  {
1657  struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
1658  char *emsg;
1659 
1660  /* Extracting and converting private key */
1661  conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
1662  if (NULL == conv_name)
1663  {
1665  "Error normalizing name `%s'\n",
1666  name_tmp);
1667  send_store_response (nc, GNUNET_SYSERR, _ ("Error normalizing name."),
1668  rid);
1670  return;
1671  }
1672 
1673  /* Check name for validity */
1674  if (GNUNET_OK != GNUNET_GNSRECORD_label_check (conv_name, &emsg))
1675  {
1677  "Label invalid: `%s'\n",
1678  emsg);
1679  send_store_response (nc, GNUNET_SYSERR, emsg, rid);
1680  GNUNET_free (emsg);
1681  GNUNET_free (conv_name);
1683  return;
1684  }
1685 
1686  if (GNUNET_OK !=
1687  GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count, rd))
1688  {
1690  _ ("Error deserializing records."), rid);
1691  GNUNET_free (conv_name);
1693  return;
1694  }
1695 
1697  "Well-formed store requests received",
1698  1,
1699  GNUNET_NO);
1701  "Creating %u records for name `%s'\n",
1702  (unsigned int) rd_count,
1703  conv_name);
1704  if ((GNUNET_NO == nc->GSN_database->lookup_records (nc->GSN_database->cls,
1705  &rp_msg->private_key,
1706  conv_name,
1708  &existing_block_exp)) &&
1709  (rd_count == 0))
1710  {
1711  /* This name does not exist, so cannot be removed */
1713  "Name `%s' does not exist, no deletion required\n",
1714  conv_name);
1715  res = GNUNET_NO;
1716  }
1717  else
1718  {
1719  /* remove "NICK" records, unless this is for the
1720  #GNUNET_GNS_EMPTY_LABEL_AT label
1721  We may need one additional record later for tombstone.
1722  FIXME: Since we must normalize the record set (check for
1723  consistency etc) we have to iterate the set twice.
1724  May be inefficient.
1725  We cannot really move the nick caching into GNSRECORD.
1726  */
1727  struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL (rd_count)];
1728  struct GNUNET_GNSRECORD_Data rd_nf[GNUNET_NZL (rd_count) + 1];
1729  unsigned int rd_clean_off;
1730  unsigned int rd_nf_count;
1731  char *emsg;
1732  int have_nick;
1733 
1734  rd_clean_off = 0;
1735  have_nick = GNUNET_NO;
1736  for (unsigned int i = 0; i < rd_count; i++)
1737  {
1738  rd_clean[rd_clean_off] = rd[i];
1739 
1740  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) ||
1742  rd_clean_off++;
1743 
1744  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1746  {
1747  cache_nick (&rp_msg->private_key, &rd[i]);
1748  have_nick = GNUNET_YES;
1749  }
1750  }
1751  if (GNUNET_OK !=
1753  rd_clean,
1754  rd_clean_off,
1755  rd_nf,
1756  &rd_nf_count,
1757  &new_block_exp,
1759  &emsg))
1760  {
1761  send_store_response (nc, GNUNET_SYSERR, emsg, rid);
1762  GNUNET_free (emsg);
1764  GNUNET_free (conv_name);
1765  return;
1766  }
1767  /*
1768  * If existing_block_exp is 0, then there was not record set
1769  * and no tombstone.
1770  * Otherwise, if the existing block expiration is after the
1771  * new block expiration would be, we need to add a tombstone
1772  * or update it.
1773  */
1774  if (GNUNET_TIME_absolute_cmp (new_block_exp, <=, existing_block_exp))
1775  {
1776  rd_nf[rd_nf_count].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE;
1777  rd_nf[rd_nf_count].expiration_time =
1778  existing_block_exp.abs_value_us;
1779  rd_nf[rd_nf_count].data = NULL;
1780  rd_nf[rd_nf_count].data_size = 0;
1781  rd_nf[rd_nf_count].flags = GNUNET_GNSRECORD_RF_PRIVATE;
1782  rd_nf_count++;
1783  }
1784  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1785  (GNUNET_NO == have_nick))
1786  {
1787  /* remove nick record from cache, in case we have one there */
1788  cache_nick (&rp_msg->private_key, NULL);
1789  }
1790  res = nc->GSN_database->store_records (nc->GSN_database->cls,
1791  &rp_msg->private_key,
1792  conv_name,
1793  rd_nf_count,
1794  rd_nf);
1795  }
1796 
1797  if (GNUNET_OK != res)
1798  {
1799  /* store not successful, no need to tell monitors */
1800  send_store_response (nc, res, _ ("Store failed"), rid);
1802  GNUNET_free (conv_name);
1803  return;
1804  }
1805  sa = GNUNET_malloc (sizeof(struct StoreActivity)
1806  + ntohs (rp_msg->gns_header.header.size));
1808  sa->nc = nc;
1809  sa->rsm = (const struct RecordStoreMessage *) &sa[1];
1810  GNUNET_memcpy (&sa[1], rp_msg, ntohs (rp_msg->gns_header.header.size));
1811  sa->zm_pos = monitor_head;
1812  sa->conv_name = conv_name;
1814  }
1815 }
1816 
1823 static void
1824 handle_tx_control (void *cls, const struct TxControlMessage *tx_msg)
1825 {
1826  struct NamestoreClient *nc = cls;
1827  struct TxControlResultMessage *txr_msg;
1828  struct GNUNET_MQ_Envelope *env;
1830  char *emsg = NULL;
1831  char *err_tmp;
1832  size_t err_len;
1833 
1834  switch (ntohs (tx_msg->control))
1835  {
1837  ret = nc->GSN_database->transaction_begin (nc->GSN_database->cls,
1838  &emsg);
1839  break;
1841  ret = nc->GSN_database->transaction_commit (nc->GSN_database->cls,
1842  &emsg);
1843  break;
1845  ret = nc->GSN_database->transaction_rollback (nc->GSN_database->cls,
1846  &emsg);
1847  break;
1848  default:
1850  "Unknown control type %u\n", ntohs (tx_msg->control));
1851  GNUNET_break (0);
1852  }
1854  "TX status is %u\n", ret);
1855  err_len = (NULL == emsg) ? 0 : strlen (emsg) + 1;
1856  env =
1857  GNUNET_MQ_msg_extra (txr_msg,
1858  err_len,
1860  txr_msg->gns_header.header.size = htons (sizeof (struct
1862  + err_len);
1863  txr_msg->gns_header.r_id = tx_msg->gns_header.r_id;
1864  txr_msg->success = htons (ret);
1865  err_tmp = (char *) &txr_msg[1];
1866  GNUNET_memcpy (err_tmp, emsg, err_len);
1867  GNUNET_MQ_send (nc->mq, env);
1869 }
1870 
1876 {
1881 
1885  uint32_t rid;
1886 
1892  int success;
1893 };
1894 
1895 
1906 static void
1908  uint64_t seq,
1909  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
1910  const char *name,
1911  unsigned int rd_count,
1912  const struct GNUNET_GNSRECORD_Data *rd)
1913 {
1914  struct ZoneToNameCtx *ztn_ctx = cls;
1915  struct GNUNET_MQ_Envelope *env;
1916  struct ZoneToNameResponseMessage *ztnr_msg;
1917  int16_t res;
1918  size_t name_len;
1919  ssize_t rd_ser_len;
1920  size_t msg_size;
1921  char *name_tmp;
1922  char *rd_tmp;
1923 
1924  GNUNET_assert (0 != seq);
1926  "Found result for zone-to-name lookup: `%s'\n",
1927  name);
1928  res = GNUNET_YES;
1929  name_len = (NULL == name) ? 0 : strlen (name) + 1;
1930  rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1931  if (rd_ser_len < 0)
1932  {
1933  GNUNET_break (0);
1934  ztn_ctx->success = GNUNET_SYSERR;
1935  return;
1936  }
1937  msg_size = sizeof(struct ZoneToNameResponseMessage) + name_len + rd_ser_len;
1938  if (msg_size >= GNUNET_MAX_MESSAGE_SIZE)
1939  {
1940  GNUNET_break (0);
1941  ztn_ctx->success = GNUNET_SYSERR;
1942  return;
1943  }
1944  env =
1945  GNUNET_MQ_msg_extra (ztnr_msg,
1946  name_len + rd_ser_len,
1948  ztnr_msg->gns_header.header.size = htons (msg_size);
1949  ztnr_msg->gns_header.r_id = htonl (ztn_ctx->rid);
1950  ztnr_msg->res = htons (res);
1951  ztnr_msg->rd_len = htons (rd_ser_len);
1952  ztnr_msg->rd_count = htons (rd_count);
1953  ztnr_msg->name_len = htons (name_len);
1954  ztnr_msg->zone = *zone_key;
1955  name_tmp = (char *) &ztnr_msg[1];
1956  GNUNET_memcpy (name_tmp, name, name_len);
1957  rd_tmp = &name_tmp[name_len];
1958  GNUNET_assert (
1959  rd_ser_len ==
1960  GNUNET_GNSRECORD_records_serialize (rd_count, rd, rd_ser_len, rd_tmp));
1961  ztn_ctx->success = GNUNET_OK;
1962  GNUNET_MQ_send (ztn_ctx->nc->mq, env);
1963 }
1964 
1965 
1972 static void
1973 handle_zone_to_name (void *cls, const struct ZoneToNameMessage *ztn_msg)
1974 {
1975  struct NamestoreClient *nc = cls;
1976  struct ZoneToNameCtx ztn_ctx;
1977  struct GNUNET_MQ_Envelope *env;
1978  struct ZoneToNameResponseMessage *ztnr_msg;
1979 
1980  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_TO_NAME message\n");
1981  ztn_ctx.rid = ntohl (ztn_msg->gns_header.r_id);
1982  ztn_ctx.nc = nc;
1983  ztn_ctx.success = GNUNET_NO;
1984  if (GNUNET_SYSERR == nc->GSN_database->zone_to_name (nc->GSN_database->cls,
1985  &ztn_msg->zone,
1986  &ztn_msg->value_zone,
1988  &ztn_ctx))
1989  {
1990  /* internal error, hang up instead of signalling something
1991  that might be wrong */
1992  GNUNET_break (0);
1993  GNUNET_SERVICE_client_drop (nc->client);
1994  return;
1995  }
1996  if (GNUNET_NO == ztn_ctx.success)
1997  {
1998  /* no result found, send empty response */
2000  "Found no result for zone-to-name lookup.\n");
2001  env = GNUNET_MQ_msg (ztnr_msg,
2003  ztnr_msg->gns_header.r_id = ztn_msg->gns_header.r_id;
2004  ztnr_msg->res = htons (GNUNET_NO);
2005  GNUNET_MQ_send (nc->mq, env);
2006  }
2008 }
2009 
2010 
2016 {
2021 
2025  uint64_t limit;
2026 };
2027 
2028 
2039 static void
2041  uint64_t seq,
2042  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
2043  const char *name,
2044  unsigned int rd_count,
2045  const struct GNUNET_GNSRECORD_Data *rd)
2046 {
2047  struct ZoneIterationProcResult *proc = cls;
2048  int do_refresh_block;
2049 
2050  GNUNET_assert (0 != seq);
2051  if ((NULL == zone_key) && (NULL == name))
2052  {
2053  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
2054  return;
2055  }
2056  if ((NULL == zone_key) || (NULL == name))
2057  {
2058  /* what is this!? should never happen */
2059  GNUNET_break (0);
2060  return;
2061  }
2062  if (0 == proc->limit)
2063  {
2064  /* what is this!? should never happen */
2065  GNUNET_break (0);
2066  return;
2067  }
2068  proc->limit--;
2069  proc->zi->seq = seq;
2071  proc->zi->request_id,
2072  zone_key,
2073  name,
2074  rd_count,
2075  rd,
2076  proc->zi->filter);
2077 
2078 
2079  do_refresh_block = GNUNET_NO;
2080  for (unsigned int i = 0; i < rd_count; i++)
2081  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
2082  {
2083  do_refresh_block = GNUNET_YES;
2084  break;
2085  }
2086  if (GNUNET_YES == do_refresh_block)
2087  refresh_block (NULL, proc->zi, 0, zone_key, name, rd_count, rd);
2088 }
2089 
2090 
2097 static void
2099 {
2100  struct ZoneIterationProcResult proc;
2101  struct GNUNET_TIME_Absolute start;
2103  struct NamestoreClient *nc = zi->nc;
2104 
2105  memset (&proc, 0, sizeof(proc));
2107  "Asked to return up to %llu records at position %llu\n",
2108  (unsigned long long) limit,
2109  (unsigned long long) zi->seq);
2110  proc.zi = zi;
2111  proc.limit = limit;
2114  nc->GSN_database->iterate_records (nc->GSN_database->cls,
2115  (GNUNET_YES ==
2116  GNUNET_is_zero (
2117  &zi->zone))
2118  ? NULL
2119  : &zi->zone,
2120  zi->seq,
2121  limit,
2123  &proc));
2127  "NAMESTORE iteration delay (μs/record)",
2129  GNUNET_NO);
2130  if (0 == proc.limit)
2132  "Returned %llu results, more results available\n",
2133  (unsigned long long) limit);
2134  zi->send_end = (0 != proc.limit);
2135  if (0 == zi->cache_ops)
2137 }
2138 
2139 
2146 static void
2148  const struct ZoneIterationStartMessage *zis_msg)
2149 {
2150  struct NamestoreClient *nc = cls;
2151  struct ZoneIteration *zi;
2152 
2154  "Received ZONE_ITERATION_START message\n");
2155  zi = GNUNET_new (struct ZoneIteration);
2156  zi->request_id = ntohl (zis_msg->gns_header.r_id);
2157  zi->filter = ntohs (zis_msg->filter);
2158  zi->offset = 0;
2159  zi->nc = nc;
2160  zi->zone = zis_msg->zone;
2161 
2162  GNUNET_CONTAINER_DLL_insert (nc->op_head, nc->op_tail, zi);
2163  run_zone_iteration_round (zi, 1);
2164 }
2165 
2166 
2173 static void
2175  const struct ZoneIterationStopMessage *zis_msg)
2176 {
2177  struct NamestoreClient *nc = cls;
2178  struct ZoneIteration *zi;
2179  uint32_t rid;
2180 
2182  "Received ZONE_ITERATION_STOP message\n");
2183  rid = ntohl (zis_msg->gns_header.r_id);
2184  for (zi = nc->op_head; NULL != zi; zi = zi->next)
2185  if (zi->request_id == rid)
2186  break;
2187  if (NULL == zi)
2188  {
2189  GNUNET_break (0);
2190  GNUNET_SERVICE_client_drop (nc->client);
2191  return;
2192  }
2193  GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, zi);
2194  GNUNET_free (zi);
2196 }
2197 
2198 
2205 static void
2207  const struct ZoneIterationNextMessage *zis_msg)
2208 {
2209  struct NamestoreClient *nc = cls;
2210  struct ZoneIteration *zi;
2211  uint32_t rid;
2212  uint64_t limit;
2213 
2215  "Received ZONE_ITERATION_NEXT message\n");
2217  "Iteration NEXT messages received",
2218  1,
2219  GNUNET_NO);
2220  rid = ntohl (zis_msg->gns_header.r_id);
2221  limit = GNUNET_ntohll (zis_msg->limit);
2222  for (zi = nc->op_head; NULL != zi; zi = zi->next)
2223  if (zi->request_id == rid)
2224  break;
2225  if (NULL == zi)
2226  {
2227  GNUNET_break (0);
2228  GNUNET_SERVICE_client_drop (nc->client);
2229  return;
2230  }
2231  run_zone_iteration_round (zi, limit);
2232 }
2233 
2234 
2240 static void
2242 {
2243  struct StoreActivity *sa = sa_head;
2244 
2245  while ((NULL != sa) && (zm->limit > zm->iteration_cnt))
2246  {
2247  struct StoreActivity *sn = sa->next;
2248 
2249  if (sa->zm_pos == zm)
2251  sa = sn;
2252  }
2253  if (zm->limit > zm->iteration_cnt)
2254  {
2255  zm->sa_waiting = GNUNET_NO;
2256  if (NULL != zm->sa_wait_warning)
2257  {
2258  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2259  zm->sa_wait_warning = NULL;
2260  }
2261  }
2262  else if (GNUNET_YES == zm->sa_waiting)
2263  {
2264  zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
2265  if (NULL != zm->sa_wait_warning)
2266  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2267  zm->sa_wait_warning =
2270  zm);
2271  }
2272 }
2273 
2274 
2280 static void
2282 {
2283  struct GNUNET_MQ_Envelope *env;
2284  struct GNUNET_MessageHeader *sync;
2285 
2287  GNUNET_MQ_send (zm->nc->mq, env);
2288  /* mark iteration done */
2289  zm->in_first_iteration = GNUNET_NO;
2290  zm->iteration_cnt = 0;
2291  if ((zm->limit > 0) && (zm->sa_waiting))
2292  monitor_unblock (zm);
2293 }
2294 
2295 
2301 static void
2302 monitor_iteration_next (void *cls);
2303 
2304 
2315 static void
2317  uint64_t seq,
2318  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
2319  const char *name,
2320  unsigned int rd_count,
2321  const struct GNUNET_GNSRECORD_Data *rd)
2322 {
2323  struct ZoneMonitor *zm = cls;
2324 
2325  GNUNET_assert (0 != seq);
2326  zm->seq = seq;
2327  GNUNET_assert (NULL != name);
2329  "Monitor notifications sent",
2330  1,
2331  GNUNET_NO);
2332  zm->limit--;
2333  zm->iteration_cnt--;
2334  send_lookup_response (zm->nc, 0, zone_key, name, rd_count, rd);
2335  if ((0 == zm->iteration_cnt) && (0 != zm->limit))
2336  {
2337  /* We are done with the current iteration batch, AND the
2338  client would right now accept more, so go again! */
2339  GNUNET_assert (NULL == zm->task);
2341  }
2342 }
2343 
2344 
2351 static void
2352 handle_monitor_start (void *cls, const struct ZoneMonitorStartMessage *zis_msg)
2353 {
2354  struct NamestoreClient *nc = cls;
2355  struct ZoneMonitor *zm;
2356 
2357  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_MONITOR_START message\n");
2358  zm = GNUNET_new (struct ZoneMonitor);
2359  zm->nc = nc;
2360  zm->zone = zis_msg->zone;
2361  zm->limit = 1;
2362  zm->filter = ntohs (zis_msg->filter);
2363  zm->in_first_iteration = (GNUNET_YES == ntohl (zis_msg->iterate_first));
2368  if (zm->in_first_iteration)
2370  else
2371  monitor_sync (zm);
2372 }
2373 
2374 
2380 static void
2382 {
2383  struct ZoneMonitor *zm = cls;
2384  struct NamestoreClient *nc = zm->nc;
2385  int ret;
2386 
2387  zm->task = NULL;
2388  GNUNET_assert (0 == zm->iteration_cnt);
2389  if (zm->limit > 16)
2390  zm->iteration_cnt = zm->limit / 2; /* leave half for monitor events */
2391  else
2392  zm->iteration_cnt = zm->limit; /* use it all */
2393  ret = nc->GSN_database->iterate_records (nc->GSN_database->cls,
2395  &zm->zone)) ? NULL : &zm->zone,
2396  zm->seq,
2397  zm->iteration_cnt,
2399  zm);
2400  if (GNUNET_SYSERR == ret)
2401  {
2402  GNUNET_SERVICE_client_drop (zm->nc->client);
2403  return;
2404  }
2405  if (GNUNET_NO == ret)
2406  {
2407  /* empty zone */
2408  monitor_sync (zm);
2409  return;
2410  }
2411 }
2412 
2413 
2420 static void
2421 handle_monitor_next (void *cls, const struct ZoneMonitorNextMessage *nm)
2422 {
2423  struct NamestoreClient *nc = cls;
2424  struct ZoneMonitor *zm;
2425  uint64_t inc;
2426 
2427  inc = GNUNET_ntohll (nm->limit);
2429  "Received ZONE_MONITOR_NEXT message with limit %llu\n",
2430  (unsigned long long) inc);
2431  for (zm = monitor_head; NULL != zm; zm = zm->next)
2432  if (zm->nc == nc)
2433  break;
2434  if (NULL == zm)
2435  {
2436  GNUNET_break (0);
2437  GNUNET_SERVICE_client_drop (nc->client);
2438  return;
2439  }
2441  if (zm->limit + inc < zm->limit)
2442  {
2443  GNUNET_break (0);
2444  GNUNET_SERVICE_client_drop (nc->client);
2445  return;
2446  }
2447  zm->limit += inc;
2448  if ((zm->in_first_iteration) && (zm->limit == inc))
2449  {
2450  /* We are still iterating, and the previous iteration must
2451  have stopped due to the client's limit, so continue it! */
2452  GNUNET_assert (NULL == zm->task);
2454  }
2455  GNUNET_assert (zm->iteration_cnt <= zm->limit);
2456  if ((zm->limit > zm->iteration_cnt) && (zm->sa_waiting))
2457  {
2458  monitor_unblock (zm);
2459  }
2460  else if (GNUNET_YES == zm->sa_waiting)
2461  {
2462  if (NULL != zm->sa_wait_warning)
2463  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2464  zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
2465  zm->sa_wait_warning =
2468  zm);
2469  }
2470 }
2471 
2472 
2480 static void
2481 run (void *cls,
2482  const struct GNUNET_CONFIGURATION_Handle *cfg,
2484 {
2485  char *database;
2486  (void) cls;
2487  (void) service;
2488  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n");
2489  cache_keys =
2490  GNUNET_CONFIGURATION_get_value_yesno (cfg, "namestore", "CACHE_KEYS");
2492  GNUNET_CONFIGURATION_get_value_yesno (cfg, "namecache", "DISABLE");
2493  GSN_cfg = cfg;
2496  {
2498  GNUNET_assert (NULL != namecache);
2499  }
2500  statistics = GNUNET_STATISTICS_create ("namestore", cfg);
2501  /* Loading database plugin */
2503  "namestore",
2504  "database",
2505  &database))
2506  {
2507  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
2509  return;
2510  }
2511  GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
2512  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loading %s\n", db_lib_name);
2514  GNUNET_free (database);
2515  if (NULL == GSN_database)
2516  {
2518  "Could not load database backend `%s'\n",
2519  db_lib_name);
2522  return;
2523  }
2525 }
2526 
2527 
2532  "namestore",
2534  &run,
2537  NULL,
2538  GNUNET_MQ_hd_fixed_size (tx_control,
2540  struct TxControlMessage,
2541  NULL),
2542  GNUNET_MQ_hd_var_size (record_store,
2544  struct RecordStoreMessage,
2545  NULL),
2546  GNUNET_MQ_hd_var_size (record_lookup,
2548  struct LabelLookupMessage,
2549  NULL),
2550  GNUNET_MQ_hd_fixed_size (zone_to_name,
2552  struct ZoneToNameMessage,
2553  NULL),
2557  NULL),
2558  GNUNET_MQ_hd_fixed_size (iteration_next,
2560  struct ZoneIterationNextMessage,
2561  NULL),
2562  GNUNET_MQ_hd_fixed_size (iteration_stop,
2564  struct ZoneIterationStopMessage,
2565  NULL),
2566  GNUNET_MQ_hd_fixed_size (monitor_start,
2568  struct ZoneMonitorStartMessage,
2569  NULL),
2570  GNUNET_MQ_hd_fixed_size (monitor_next,
2572  struct ZoneMonitorNextMessage,
2573  NULL),
2575 
2576 
2577 /* 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)
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.
static char * pkey
Public key of the zone to look in, in ASCII.
static char * zone
Name of the zone being managed.
static const struct GNUNET_IDENTITY_PrivateKey * zone_key
Private key of the zone.
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:46
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 send_lookup_response(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)
Generate a struct LookupNameResponseMessage and send it to the given client using the given notificat...
static int disable_namecache
Use the namecache? Doing so creates additional cryptographic operations whenever we touch a record.
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 struct CacheOperation * cop_head
Head of cop DLL.
static struct GNUNET_NAMECACHE_Handle * namecache
Namecache handle.
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 refresh_block(struct NamestoreClient *nc, struct ZoneIteration *zi, uint32_t rid, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
We just touched the plaintext information about a name in our zone; refresh the corresponding (encryp...
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 void monitor_sync(struct ZoneMonitor *zm)
Send 'sync' message to zone monitor, we're now in sync.
static struct CacheOperation * cop_tail
Tail of cop DLL.
static void finish_cache_operation(void *cls, int32_t success, const char *emsg)
Cache operation complete, clean up.
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 get_block_exp_existing(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 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 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 send_store_response(struct NamestoreClient *nc, int res, const char *emsg, uint32_t rid)
Send response to the store request to the client.
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 ...
#define MONITOR_STALL_WARN_DELAY
If a monitor takes more than 1 minute to process an event, print a warning.
static int cache_keys
Optimize block insertion by caching map of private keys to public keys in memory?
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.
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_fixed_size(zone_to_name, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME, struct ZoneToNameMessage, NULL), GNUNET_MQ_hd_fixed_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_fixed_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 * 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.
static void continue_store_activity(struct StoreActivity *sa)
Continue processing the sa.
#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 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 void lookup_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 by the namestore plugin when we are trying to lookup a record as part of handle_recor...
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 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...
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
Process namestore requests.
static void iteration_start()
API for helper library to parse DNS packets.
API to the GNS service.
API that can be used to store naming information on a GNUnet node.
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.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_block_create2(const struct GNUNET_IDENTITY_PrivateKey *pkey, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, struct GNUNET_GNSRECORD_Block **result)
Sign name and records, cache derived public key (also keeps the private key in static memory,...
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_block_create(const struct GNUNET_IDENTITY_PrivateKey *key, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, struct GNUNET_GNSRECORD_Block **result)
Sign name and records.
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.
struct GNUNET_TIME_Absolute GNUNET_GNSRECORD_record_get_expiration_time(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, struct GNUNET_TIME_Absolute min)
Returns the expiration time of the given block of records.
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 key 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_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 handed out to other peers.
@ 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:175
#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:53
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.
Definition: gnunet_common.h:96
@ GNUNET_OK
Definition: gnunet_common.h:99
@ GNUNET_YES
@ GNUNET_NO
Definition: gnunet_common.h:98
@ GNUNET_SYSERR
Definition: gnunet_common.h:97
#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:137
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:302
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_check_zero_termination(m)
Insert code for a "check_" function that verifies that a given variable-length message received over ...
#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:56
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:71
#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:121
#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:160
void GNUNET_NAMECACHE_disconnect(struct GNUNET_NAMECACHE_Handle *h)
Disconnect from the namecache service (and free associated resources).
void GNUNET_NAMECACHE_cancel(struct GNUNET_NAMECACHE_QueueEntry *qe)
Cancel a namecache operation.
struct GNUNET_NAMECACHE_Handle * GNUNET_NAMECACHE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namecache service.
struct GNUNET_NAMECACHE_QueueEntry * GNUNET_NAMECACHE_block_cache(struct GNUNET_NAMECACHE_Handle *h, const struct GNUNET_GNSRECORD_Block *block, GNUNET_NAMECACHE_ContinuationWithStatus cont, void *cont_cls)
Store an item in the namecache.
@ 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:241
void * GNUNET_PLUGIN_load(const char *library_name, void *arg)
Setup plugin (runs the "init" callback and returns whatever "init" returned).
Definition: plugin.c:197
#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:1281
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:1316
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
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:1254
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the 'monitor' flag on this client.
Definition: service.c:2412
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2329
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2248
@ 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:435
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:110
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:617
#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:549
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:637
#define MAX_NAME_LEN
Maximum length of any name, including 0-termination.
Definition: namecache.h:33
common internal definitions for namestore service
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
const char * name
Pending operation on the namecache.
struct CacheOperation * next
Kept in a DLL.
struct GNUNET_NAMECACHE_QueueEntry * qe
Handle to namecache queue.
struct CacheOperation * prev
Kept in a DLL.
uint32_t rid
Client's request ID.
struct NamestoreClient * nc
Client to notify about the result, can be NULL.
struct ZoneIteration * zi
Zone iteration to call zone_iteration_done_client_continue() for if applicable, can be NULL.
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:86
Header for all communications.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Connection to the NAMECACHE service.
Definition: namecache_api.c:95
An QueueEntry used to store information for a pending NAMECACHE record operation.
Definition: namecache_api.c:48
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
int(* 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:76
struct GNUNET_MQ_Handle * mq
Our connection to the PEERINFO service.
Entry in list of pending tasks.
Definition: scheduler.c:135
Handle to a client that is connected to a service.
Definition: service.c:251
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:137
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP.
Definition: namestore.h:141
uint32_t is_edit_request
GNUNET_YES if this lookup corresponds to an edit request.
Definition: namestore.h:151
struct GNUNET_IDENTITY_PrivateKey zone
The private key of the zone to look up in.
Definition: namestore.h:156
uint32_t label_len
Length of the name.
Definition: namestore.h:146
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:182
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE.
Definition: namestore.h:172
uint16_t rd_count
Number of records contained.
Definition: namestore.h:187
uint16_t name_len
Name length.
Definition: namestore.h:177
int16_t found
Was the label found in the database?? GNUNET_YES or GNUNET_NO.
Definition: namestore.h:193
struct GNUNET_IDENTITY_PrivateKey private_key
The private key of the authority.
Definition: namestore.h:198
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 (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
FIXME.
unsigned int res_rd_count
FIXME.
Record is returned from the namestore (as authority).
Definition: namestore.h:276
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:296
uint16_t name_len
Name length.
Definition: namestore.h:291
struct GNUNET_IDENTITY_PrivateKey private_key
The private key of the authority.
Definition: namestore.h:311
uint16_t rd_count
Number of records contained.
Definition: namestore.h:301
struct GNUNET_TIME_AbsoluteNBO expire
Expiration time if the record result (if any).
Definition: namestore.h:286
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT.
Definition: namestore.h:280
Store a record to the namestore (as authority).
Definition: namestore.h:59
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE.
Definition: namestore.h:63
uint16_t rd_count
Number of records contained.
Definition: namestore.h:83
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:78
struct GNUNET_IDENTITY_PrivateKey private_key
The private key of the authority.
Definition: namestore.h:93
uint16_t name_len
Name length.
Definition: namestore.h:73
Response to a record storage request.
Definition: namestore.h:106
uint16_t emsg_len
Error message length.
Definition: namestore.h:120
uint16_t reserved
Reserved for alignment.
Definition: namestore.h:125
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE.
Definition: namestore.h:110
int32_t op_result
GNUNET_SYSERR on failure, GNUNET_OK on success
Definition: namestore.h:115
Information for an ongoing handle_record_store() operation.
struct StoreActivity * next
Kept in a DLL.
char * conv_name
Label nicely canonicalized (lower case).
const struct RecordStoreMessage * rsm
Copy of the original store message (as data fields in rd will point into it!).
struct NamestoreClient * nc
Which client triggered the store activity?
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:323
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL.
Definition: namestore.h:327
uint16_t control
The type of control message to send.
Definition: namestore.h:332
Result of a transaction control message.
Definition: namestore.h:345
uint16_t success
Of type GNUNET_GenericReturnValue.
Definition: namestore.h:359
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL_RESULT.
Definition: namestore.h:349
Ask for next result of zone iteration for the given operation.
Definition: namestore.h:458
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT.
Definition: namestore.h:462
uint64_t limit
Number of records to return to the iterator in one shot (before GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_IT...
Definition: namestore.h:469
Context for record remove operations passed from run_zone_iteration_round to zone_iterate_proc as clo...
struct ZoneIteration * zi
The zone iteration handle.
uint64_t limit
Number of results left to be returned in this iteration.
Start a zone iteration for the given zone.
Definition: namestore.h:430
struct GNUNET_IDENTITY_PrivateKey zone
Zone key.
Definition: namestore.h:439
uint16_t filter
Record set filter control flags.
Definition: namestore.h:445
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START.
Definition: namestore.h:434
Stop zone iteration for the given operation.
Definition: namestore.h:477
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP.
Definition: namestore.h:481
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:406
uint64_t limit
Number of records to return to the iterator in one shot (before #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_M...
Definition: namestore.h:422
Start monitoring a zone.
Definition: namestore.h:372
uint32_t iterate_first
GNUNET_YES to first iterate over all records, GNUNET_NO to only monitor changes.o
Definition: namestore.h:382
uint16_t filter
Record set filter control flags.
Definition: namestore.h:388
struct GNUNET_IDENTITY_PrivateKey zone
Zone key.
Definition: namestore.h:398
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.
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).
int success
Set to GNUNET_OK on success, GNUNET_SYSERR on error.
Lookup a name for a zone hash.
Definition: namestore.h:211
struct GNUNET_IDENTITY_PrivateKey zone
The private key of the zone to look up in.
Definition: namestore.h:220
struct GNUNET_IDENTITY_PublicKey value_zone
The public key of the target zone.
Definition: namestore.h:225
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME.
Definition: namestore.h:215
Respone for zone to name lookup.
Definition: namestore.h:233
int16_t res
result in NBO: GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error
Definition: namestore.h:258
uint16_t name_len
Length of the name.
Definition: namestore.h:242
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
Definition: namestore.h:237
struct GNUNET_IDENTITY_PrivateKey zone
The private key of the zone that contained the name.
Definition: namestore.h:263
uint16_t rd_count
Number of records contained.
Definition: namestore.h:252
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:247