GNUnet  0.11.x
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 
94  uint64_t seq;
95 
99  uint32_t request_id;
100 
108  uint32_t offset;
109 
114  unsigned int cache_ops;
115 
121  int send_end;
122 };
123 
124 
129 {
134 
139 
145 
151 };
152 
153 
158 {
162  struct ZoneMonitor *next;
163 
167  struct ZoneMonitor *prev;
168 
173 
178 
183 
188 
192  struct GNUNET_TIME_Absolute sa_waiting_start;
193 
201  uint64_t seq;
202 
207  uint64_t limit;
208 
215  uint64_t iteration_cnt;
216 
221 
229 };
230 
231 
236 {
241 
246 
251 
256 
261  struct ZoneIteration *zi;
262 
266  uint32_t rid;
267 };
268 
269 
275 {
280 
285 
290 
295  const struct RecordStoreMessage *rsm;
296 
301 
305  char *conv_name;
306 };
307 
308 
312 struct NickCache
313 {
318 
323 
327  struct GNUNET_TIME_Absolute last_used;
328 };
329 
330 
334 static struct NickCache nick_cache[NC_SIZE];
335 
340 
345 
350 
355 
360 
364 static char *db_lib_name;
365 
369 static struct CacheOperation *cop_head;
370 
374 static struct CacheOperation *cop_tail;
375 
379 static struct ZoneMonitor *monitor_head;
380 
384 static struct ZoneMonitor *monitor_tail;
385 
389 static struct StoreActivity *sa_head;
390 
394 static struct StoreActivity *sa_tail;
395 
400 
405 static int cache_keys;
406 
411 static int disable_namecache;
412 
413 
419 static void
420 cleanup_task (void *cls)
421 {
422  struct CacheOperation *cop;
423 
424  (void) cls;
425  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n");
426  while (NULL != (cop = cop_head))
427  {
429  "Aborting incomplete namecache operation\n");
431  GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop);
432  GNUNET_free (cop);
433  }
434  if (NULL != namecache)
435  {
436  GNUNET_NAMECACHE_disconnect (namecache);
437  namecache = NULL;
438  }
439  GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, GSN_database));
441  db_lib_name = NULL;
442  if (NULL != monitor_nc)
443  {
445  monitor_nc = NULL;
446  }
447  if (NULL != statistics)
448  {
449  GNUNET_STATISTICS_destroy (statistics, GNUNET_NO);
450  statistics = NULL;
451  }
452 }
453 
454 
460 static void
462 {
463  GNUNET_CONTAINER_DLL_remove (sa_head, sa_tail, sa);
464  GNUNET_free (sa->conv_name);
465  GNUNET_free (sa);
466 }
467 
468 
481 static void
482 lookup_nick_it (void *cls,
483  uint64_t seq,
484  const struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key,
485  const char *label,
486  unsigned int rd_count,
487  const struct GNUNET_GNSRECORD_Data *rd)
488 {
489  struct GNUNET_GNSRECORD_Data **res = cls;
490 
491  (void) private_key;
492  GNUNET_assert (0 != seq);
493  if (0 != strcmp (label, GNUNET_GNS_EMPTY_LABEL_AT))
494  {
495  GNUNET_break (0);
496  return;
497  }
498  for (unsigned int c = 0; c < rd_count; c++)
499  {
501  {
502  (*res) =
503  GNUNET_malloc (rd[c].data_size + sizeof(struct GNUNET_GNSRECORD_Data));
504  (*res)->data = &(*res)[1];
505  GNUNET_memcpy ((void *) (*res)->data, rd[c].data, rd[c].data_size);
506  (*res)->data_size = rd[c].data_size;
507  (*res)->expiration_time = rd[c].expiration_time;
508  (*res)->flags = rd[c].flags;
509  (*res)->record_type = GNUNET_GNSRECORD_TYPE_NICK;
510  return;
511  }
512  }
513  (*res) = NULL;
514 }
515 
516 
523 static void
525  const struct GNUNET_GNSRECORD_Data *nick)
526 {
527  struct NickCache *oldest;
528 
529  oldest = NULL;
530  for (unsigned int i = 0; i < NC_SIZE; i++)
531  {
532  struct NickCache *pos = &nick_cache[i];
533 
534  if ((NULL == oldest) ||
535  (oldest->last_used.abs_value_us > pos->last_used.abs_value_us))
536  oldest = pos;
537  if (0 == GNUNET_memcmp (zone, &pos->zone))
538  {
539  oldest = pos;
540  break;
541  }
542  }
543  GNUNET_free_non_null (oldest->rd);
544  oldest->zone = *zone;
545  if (NULL != nick)
546  {
547  oldest->rd = GNUNET_malloc (sizeof(*nick) + nick->data_size);
548  *oldest->rd = *nick;
549  oldest->rd->data = &oldest->rd[1];
550  memcpy (&oldest->rd[1], nick->data, nick->data_size);
551  }
552  else
553  {
554  oldest->rd = NULL;
555  }
556  oldest->last_used = GNUNET_TIME_absolute_get ();
557 }
558 
559 
566 static struct GNUNET_GNSRECORD_Data *
568 {
569  struct GNUNET_CRYPTO_EcdsaPublicKey pub;
570  struct GNUNET_GNSRECORD_Data *nick;
571  int res;
572 
573  /* check cache first */
574  for (unsigned int i = 0; i < NC_SIZE; i++)
575  {
576  struct NickCache *pos = &nick_cache[i];
577  if ((NULL != pos->rd) && (0 == GNUNET_memcmp (zone, &pos->zone)))
578  {
579  if (NULL == pos->rd)
580  return NULL;
581  nick = GNUNET_malloc (sizeof(*nick) + pos->rd->data_size);
582  *nick = *pos->rd;
583  nick->data = &nick[1];
584  memcpy (&nick[1], pos->rd->data, pos->rd->data_size);
586  return nick;
587  }
588  }
589 
590  nick = NULL;
591  res = GSN_database->lookup_records (GSN_database->cls,
592  zone,
595  &nick);
596  if ((GNUNET_OK != res) || (NULL == nick))
597  {
598 #if ! defined(GNUNET_CULL_LOGGING)
599  static int do_log = GNUNET_LOG_CALL_STATUS;
600 
601  if (0 == do_log)
603  "namestore",
604  __FILE__,
605  __FUNCTION__,
606  __LINE__);
607  if (1 == do_log)
608  {
611  "No nick name set for zone `%s'\n",
612  GNUNET_GNSRECORD_z2s (&pub));
613  }
614 #endif
615  /* update cache */
616  cache_nick (zone, NULL);
617  return NULL;
618  }
619 
620  /* update cache */
621  cache_nick (zone, nick);
622  return nick;
623 }
624 
625 
641 static void
643  unsigned int rd2_length,
644  const struct GNUNET_GNSRECORD_Data *rd2,
645  unsigned int *rdc_res,
646  struct GNUNET_GNSRECORD_Data **rd_res)
647 {
648  uint64_t latest_expiration;
649  size_t req;
650  char *data;
651  size_t data_offset;
652  struct GNUNET_GNSRECORD_Data *target;
653 
654  (*rdc_res) = 1 + rd2_length;
655  if (0 == 1 + rd2_length)
656  {
657  GNUNET_break (0);
658  (*rd_res) = NULL;
659  return;
660  }
661  req = sizeof(struct GNUNET_GNSRECORD_Data) + nick_rd->data_size;
662  for (unsigned int i = 0; i < rd2_length; i++)
663  {
664  const struct GNUNET_GNSRECORD_Data *orig = &rd2[i];
665 
666  if (req + sizeof(struct GNUNET_GNSRECORD_Data) + orig->data_size < req)
667  {
668  GNUNET_break (0);
669  (*rd_res) = NULL;
670  return;
671  }
672  req += sizeof(struct GNUNET_GNSRECORD_Data) + orig->data_size;
673  }
674  target = GNUNET_malloc (req);
675  (*rd_res) = target;
676  data = (char *) &target[1 + rd2_length];
677  data_offset = 0;
678  latest_expiration = 0;
679  for (unsigned int i = 0; i < rd2_length; i++)
680  {
681  const struct GNUNET_GNSRECORD_Data *orig = &rd2[i];
682 
684  {
685  if ((GNUNET_TIME_absolute_get ().abs_value_us + orig->expiration_time) >
686  latest_expiration)
687  latest_expiration = orig->expiration_time;
688  }
689  else if (orig->expiration_time > latest_expiration)
690  latest_expiration = orig->expiration_time;
691  target[i] = *orig;
692  target[i].data = (void *) &data[data_offset];
693  GNUNET_memcpy (&data[data_offset], orig->data, orig->data_size);
694  data_offset += orig->data_size;
695  }
696  /* append nick */
697  target[rd2_length] = *nick_rd;
698  /* Mark as supplemental */
699  target[rd2_length].flags = nick_rd->flags | GNUNET_GNSRECORD_RF_SUPPLEMENTAL;
700  target[rd2_length].expiration_time = latest_expiration;
701  target[rd2_length].data = (void *) &data[data_offset];
702  GNUNET_memcpy (&data[data_offset], nick_rd->data, nick_rd->data_size);
703  data_offset += nick_rd->data_size;
704  GNUNET_assert (req == (sizeof(struct GNUNET_GNSRECORD_Data)) * (*rdc_res)
705  + data_offset);
706 }
707 
708 
720 static void
722  uint32_t request_id,
723  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
724  const char *name,
725  unsigned int rd_count,
726  const struct GNUNET_GNSRECORD_Data *rd)
727 {
728  struct GNUNET_MQ_Envelope *env;
729  struct RecordResultMessage *zir_msg;
730  struct GNUNET_GNSRECORD_Data *nick;
731  struct GNUNET_GNSRECORD_Data *res;
732  unsigned int res_count;
733  size_t name_len;
734  ssize_t rd_ser_len;
735  char *name_tmp;
736  char *rd_ser;
737 
738  nick = get_nick_record (zone_key);
739  GNUNET_assert (-1 != GNUNET_GNSRECORD_records_get_size (rd_count, rd));
740 
741  if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT)))
742  {
743  nick->flags =
745  merge_with_nick_records (nick, rd_count, rd, &res_count, &res);
746  GNUNET_free (nick);
747  }
748  else
749  {
750  res_count = rd_count;
751  res = (struct GNUNET_GNSRECORD_Data *) rd;
752  }
753 
754  GNUNET_assert (-1 != GNUNET_GNSRECORD_records_get_size (res_count, res));
755 
756 
757  name_len = strlen (name) + 1;
758  rd_ser_len = GNUNET_GNSRECORD_records_get_size (res_count, res);
759  if (rd_ser_len < 0)
760  {
761  GNUNET_break (0);
763  return;
764  }
765  if (((size_t) rd_ser_len) >= UINT16_MAX - name_len - sizeof(*zir_msg))
766  {
767  GNUNET_break (0);
769  return;
770  }
771  env = GNUNET_MQ_msg_extra (zir_msg,
772  name_len + rd_ser_len,
774  zir_msg->gns_header.r_id = htonl (request_id);
775  zir_msg->name_len = htons (name_len);
776  zir_msg->rd_count = htons (res_count);
777  zir_msg->rd_len = htons ((uint16_t) rd_ser_len);
778  zir_msg->private_key = *zone_key;
779  name_tmp = (char *) &zir_msg[1];
780  GNUNET_memcpy (name_tmp, name, name_len);
781  rd_ser = &name_tmp[name_len];
782  GNUNET_assert (
783  rd_ser_len ==
784  GNUNET_GNSRECORD_records_serialize (res_count, res, rd_ser_len, rd_ser));
786  "Sending RECORD_RESULT message with %u records\n",
787  res_count);
788  GNUNET_STATISTICS_update (statistics,
789  "Record sets sent to clients",
790  1,
791  GNUNET_NO);
792  GNUNET_MQ_send (nc->mq, env);
793  if (rd != res)
794  GNUNET_free (res);
795 }
796 
797 
805 static void
806 send_store_response (struct NamestoreClient *nc, int res, uint32_t rid)
807 {
808  struct GNUNET_MQ_Envelope *env;
809  struct RecordStoreResponseMessage *rcr_msg;
810 
811  GNUNET_assert (NULL != nc);
813  "Sending RECORD_STORE_RESPONSE message\n");
814  GNUNET_STATISTICS_update (statistics,
815  "Store requests completed",
816  1,
817  GNUNET_NO);
818  env = GNUNET_MQ_msg (rcr_msg,
820  rcr_msg->gns_header.r_id = htonl (rid);
821  rcr_msg->op_result = htonl (res);
822  GNUNET_MQ_send (nc->mq, env);
823 }
824 
825 
832 static void
834 {
835  struct GNUNET_MQ_Envelope *env;
836  struct GNUNET_NAMESTORE_Header *em;
837 
839  if (! zi->send_end)
840  return;
841  /* send empty response to indicate end of list */
843  em->r_id = htonl (zi->request_id);
844  GNUNET_MQ_send (zi->nc->mq, env);
845 
847  GNUNET_free (zi);
848 }
849 
850 
858 static void
859 finish_cache_operation (void *cls, int32_t success, const char *emsg)
860 {
861  struct CacheOperation *cop = cls;
862  struct ZoneIteration *zi;
863 
864  if (NULL != emsg)
866  _ ("Failed to replicate block in namecache: %s\n"),
867  emsg);
868  else
869  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n");
870  GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop);
871  if (NULL != cop->nc)
872  send_store_response (cop->nc, success, cop->rid);
873  if (NULL != (zi = cop->zi))
874  {
875  zi->cache_ops--;
876  if (0 == zi->cache_ops)
877  {
878  /* unchoke zone iteration, cache has caught up */
880  }
881  }
882  GNUNET_free (cop);
883 }
884 
885 
898 static void
900  struct ZoneIteration *zi,
901  uint32_t rid,
902  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
903  const char *name,
904  unsigned int rd_count,
905  const struct GNUNET_GNSRECORD_Data *rd)
906 {
907  struct GNUNET_GNSRECORD_Block *block;
908  struct CacheOperation *cop;
909  struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
910  struct GNUNET_GNSRECORD_Data *nick;
911  struct GNUNET_GNSRECORD_Data *res;
912  unsigned int res_count;
913  struct GNUNET_TIME_Absolute exp_time;
914 
915  nick = get_nick_record (zone_key);
916  res_count = rd_count;
917  res = (struct GNUNET_GNSRECORD_Data *) rd; /* fixme: a bit unclean... */
918  if (NULL != nick && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT)))
919  {
920  nick->flags =
922  merge_with_nick_records (nick, rd_count, rd, &res_count, &res);
923  GNUNET_free (nick);
924  }
925  if (0 == res_count)
926  {
927  if (NULL != nc)
928  send_store_response (nc, GNUNET_OK, rid);
929  return; /* no data, no need to update cache */
930  }
932  {
933  GNUNET_STATISTICS_update (statistics,
934  "Namecache updates skipped (NC disabled)",
935  1,
936  GNUNET_NO);
937  if (NULL != nc)
938  send_store_response (nc, GNUNET_OK, rid);
939  return;
940  }
941  exp_time = GNUNET_GNSRECORD_record_get_expiration_time (res_count, res);
942  if (cache_keys)
943  block =
944  GNUNET_GNSRECORD_block_create2 (zone_key, exp_time, name, res, res_count);
945  else
946  block =
947  GNUNET_GNSRECORD_block_create (zone_key, exp_time, name, res, res_count);
948  GNUNET_assert (NULL != block);
949  GNUNET_CRYPTO_ecdsa_key_get_public (zone_key, &pkey);
950  GNUNET_log (
952  "Caching block for label `%s' with %u records and expiration %s in zone `%s' in namecache\n",
953  name,
954  res_count,
956  GNUNET_GNSRECORD_z2s (&pkey));
957  GNUNET_STATISTICS_update (statistics,
958  "Namecache updates pushed",
959  1,
960  GNUNET_NO);
961  cop = GNUNET_new (struct CacheOperation);
962  cop->nc = nc;
963  cop->zi = zi;
964  if (NULL != zi)
965  zi->cache_ops++;
966  cop->rid = rid;
967  GNUNET_CONTAINER_DLL_insert (cop_head, cop_tail, cop);
968  cop->qe = GNUNET_NAMECACHE_block_cache (namecache,
969  block,
971  cop);
972  GNUNET_free (block);
973 }
974 
975 
981 static void
982 warn_monitor_slow (void *cls)
983 {
984  struct ZoneMonitor *zm = cls;
985 
987  "No response from monitor since %s\n",
991  zm);
992 }
993 
994 
1000 static void
1002 {
1003  const struct RecordStoreMessage *rp_msg = sa->rsm;
1004  unsigned int rd_count;
1005  size_t name_len;
1006  size_t rd_ser_len;
1007  uint32_t rid;
1008  const char *name_tmp;
1009  const char *rd_ser;
1010 
1011  rid = ntohl (rp_msg->gns_header.r_id);
1012  name_len = ntohs (rp_msg->name_len);
1013  rd_count = ntohs (rp_msg->rd_count);
1014  rd_ser_len = ntohs (rp_msg->rd_len);
1015  name_tmp = (const char *) &rp_msg[1];
1016  rd_ser = &name_tmp[name_len];
1017  {
1018  struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
1019 
1020  /* We did this before, must succeed again */
1021  GNUNET_assert (
1022  GNUNET_OK ==
1023  GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count, rd));
1024 
1025  for (struct ZoneMonitor *zm = sa->zm_pos; NULL != zm; zm = sa->zm_pos)
1026  {
1027  if ((0 != GNUNET_memcmp (&rp_msg->private_key, &zm->zone)) &&
1028  (0 != GNUNET_memcmp (&zm->zone, &zero)))
1029  {
1030  sa->zm_pos = zm->next; /* not interesting to this monitor */
1031  continue;
1032  }
1033  if (zm->limit == zm->iteration_cnt)
1034  {
1035  zm->sa_waiting = GNUNET_YES;
1036  zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
1037  if (NULL != zm->sa_wait_warning)
1038  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
1039  zm->sa_wait_warning =
1042  zm);
1043  return; /* blocked on zone monitor */
1044  }
1046  "Notifying monitor about changes under label `%s'\n",
1047  sa->conv_name);
1048  zm->limit--;
1049  send_lookup_response (zm->nc,
1050  0,
1051  &rp_msg->private_key,
1052  sa->conv_name,
1053  rd_count,
1054  rd);
1055  sa->zm_pos = zm->next;
1056  }
1057  /* great, done with the monitors, unpack (again) for refresh_block operation */
1058  refresh_block (sa->nc,
1059  NULL,
1060  rid,
1061  &rp_msg->private_key,
1062  sa->conv_name,
1063  rd_count,
1064  rd);
1065  }
1067  free_store_activity (sa);
1068 }
1069 
1070 
1079 static void
1081  struct GNUNET_SERVICE_Client *client,
1082  void *app_ctx)
1083 {
1084  struct NamestoreClient *nc = app_ctx;
1085  struct ZoneIteration *no;
1086  struct CacheOperation *cop;
1087 
1088  (void) cls;
1089  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
1090  for (struct ZoneMonitor *zm = monitor_head; NULL != zm; zm = zm->next)
1091  {
1092  struct StoreActivity *san;
1093 
1094  if (nc != zm->nc)
1095  continue;
1096  GNUNET_CONTAINER_DLL_remove (monitor_head, monitor_tail, zm);
1097  if (NULL != zm->task)
1098  {
1099  GNUNET_SCHEDULER_cancel (zm->task);
1100  zm->task = NULL;
1101  }
1102  if (NULL != zm->sa_wait_warning)
1103  {
1104  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
1105  zm->sa_wait_warning = NULL;
1106  }
1107  for (struct StoreActivity *sa = sa_head; NULL != sa; sa = san)
1108  {
1109  san = sa->next;
1110  if (zm == sa->zm_pos)
1111  {
1112  sa->zm_pos = zm->next;
1113  /* this may free sa */
1115  }
1116  }
1117  GNUNET_free (zm);
1118  break;
1119  }
1120  for (struct StoreActivity *sa = sa_head; NULL != sa; sa = sa->next)
1121  {
1122  if (sa->nc == nc)
1123  {
1124  /* this may free sa */
1125  free_store_activity (sa);
1126  break; /* there can only be one per nc */
1127  }
1128  }
1129  while (NULL != (no = nc->op_head))
1130  {
1132  GNUNET_free (no);
1133  }
1134  for (cop = cop_head; NULL != cop; cop = cop->next)
1135  if (nc == cop->nc)
1136  cop->nc = NULL;
1137  GNUNET_free (nc);
1138 }
1139 
1140 
1149 static void *
1151  struct GNUNET_SERVICE_Client *client,
1152  struct GNUNET_MQ_Handle *mq)
1153 {
1154  struct NamestoreClient *nc;
1155 
1156  (void) cls;
1157  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1158  nc = GNUNET_new (struct NamestoreClient);
1159  nc->client = client;
1160  nc->mq = mq;
1161  return nc;
1162 }
1163 
1164 
1169 {
1173  const char *label;
1174 
1178  char *res_rd;
1179 
1184 
1188  int found;
1189 
1193  unsigned int res_rd_count;
1194 
1198  ssize_t rd_ser_len;
1199 };
1200 
1201 
1214 static void
1215 lookup_it (void *cls,
1216  uint64_t seq,
1217  const struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key,
1218  const char *label,
1219  unsigned int rd_count,
1220  const struct GNUNET_GNSRECORD_Data *rd)
1221 {
1222  struct RecordLookupContext *rlc = cls;
1223 
1224  (void) private_key;
1225  GNUNET_assert (0 != seq);
1226  if (0 != strcmp (label, rlc->label))
1227  return;
1228  rlc->found = GNUNET_YES;
1229  if (0 == rd_count)
1230  {
1231  rlc->rd_ser_len = 0;
1232  rlc->res_rd_count = 0;
1233  rlc->res_rd = NULL;
1234  return;
1235  }
1236  if ((NULL != rlc->nick) && (0 != strcmp (label, GNUNET_GNS_EMPTY_LABEL_AT)))
1237  {
1238  /* Merge */
1239  struct GNUNET_GNSRECORD_Data *rd_res;
1240  unsigned int rdc_res;
1241 
1242  rd_res = NULL;
1243  rdc_res = 0;
1244  rlc->nick->flags = (rlc->nick->flags | GNUNET_GNSRECORD_RF_PRIVATE)
1246  merge_with_nick_records (rlc->nick, rd_count, rd, &rdc_res, &rd_res);
1247  rlc->rd_ser_len = GNUNET_GNSRECORD_records_get_size (rdc_res, rd_res);
1248  if (rlc->rd_ser_len < 0)
1249  {
1250  GNUNET_break (0);
1251  GNUNET_free (rd_res);
1252  rlc->found = GNUNET_NO;
1253  rlc->rd_ser_len = 0;
1254  return;
1255  }
1256  rlc->res_rd_count = rdc_res;
1257  rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1258  if (rlc->rd_ser_len != GNUNET_GNSRECORD_records_serialize (rdc_res,
1259  rd_res,
1260  rlc->rd_ser_len,
1261  rlc->res_rd))
1262  {
1263  GNUNET_break (0);
1264  GNUNET_free (rlc->res_rd);
1265  rlc->res_rd = NULL;
1266  rlc->res_rd_count = 0;
1267  rlc->rd_ser_len = 0;
1268  GNUNET_free (rd_res);
1269  rlc->found = GNUNET_NO;
1270  return;
1271  }
1272  GNUNET_free (rd_res);
1273  GNUNET_free (rlc->nick);
1274  rlc->nick = NULL;
1275  }
1276  else
1277  {
1278  rlc->rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1279  if (rlc->rd_ser_len < 0)
1280  {
1281  GNUNET_break (0);
1282  rlc->found = GNUNET_NO;
1283  rlc->rd_ser_len = 0;
1284  return;
1285  }
1286  rlc->res_rd_count = rd_count;
1287  rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1288  if (rlc->rd_ser_len != GNUNET_GNSRECORD_records_serialize (rd_count,
1289  rd,
1290  rlc->rd_ser_len,
1291  rlc->res_rd))
1292  {
1293  GNUNET_break (0);
1294  GNUNET_free (rlc->res_rd);
1295  rlc->res_rd = NULL;
1296  rlc->res_rd_count = 0;
1297  rlc->rd_ser_len = 0;
1298  rlc->found = GNUNET_NO;
1299  return;
1300  }
1301  }
1302 }
1303 
1304 
1312 static int
1313 check_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
1314 {
1315  uint32_t name_len;
1316  size_t src_size;
1317 
1318  (void) cls;
1319  name_len = ntohl (ll_msg->label_len);
1320  src_size = ntohs (ll_msg->gns_header.header.size);
1321  if (name_len != src_size - sizeof(struct LabelLookupMessage))
1322  {
1323  GNUNET_break (0);
1324  return GNUNET_SYSERR;
1325  }
1327  return GNUNET_OK;
1328 }
1329 
1330 
1337 static void
1338 handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
1339 {
1340  struct NamestoreClient *nc = cls;
1341  struct GNUNET_MQ_Envelope *env;
1342  struct LabelLookupResponseMessage *llr_msg;
1343  struct RecordLookupContext rlc;
1344  const char *name_tmp;
1345  char *res_name;
1346  char *conv_name;
1347  uint32_t name_len;
1348  int res;
1349 
1350  name_len = ntohl (ll_msg->label_len);
1351  name_tmp = (const char *) &ll_msg[1];
1354  "Received NAMESTORE_RECORD_LOOKUP message for name `%s'\n",
1355  name_tmp);
1356 
1357  conv_name = GNUNET_GNSRECORD_string_to_lowercase (name_tmp);
1358  if (NULL == conv_name)
1359  {
1361  "Error converting name `%s'\n",
1362  name_tmp);
1364  return;
1365  }
1366  rlc.label = conv_name;
1367  rlc.found = GNUNET_NO;
1368  rlc.res_rd_count = 0;
1369  rlc.res_rd = NULL;
1370  rlc.rd_ser_len = 0;
1371  rlc.nick = get_nick_record (&ll_msg->zone);
1372  res = GSN_database->lookup_records (GSN_database->cls,
1373  &ll_msg->zone,
1374  conv_name,
1375  &lookup_it,
1376  &rlc);
1377  GNUNET_free (conv_name);
1378  env =
1379  GNUNET_MQ_msg_extra (llr_msg,
1380  name_len + rlc.rd_ser_len,
1382  llr_msg->gns_header.r_id = ll_msg->gns_header.r_id;
1383  llr_msg->private_key = ll_msg->zone;
1384  llr_msg->name_len = htons (name_len);
1385  llr_msg->rd_count = htons (rlc.res_rd_count);
1386  llr_msg->rd_len = htons (rlc.rd_ser_len);
1387  res_name = (char *) &llr_msg[1];
1388  if ((GNUNET_YES == rlc.found) && (GNUNET_OK == res))
1389  llr_msg->found = ntohs (GNUNET_YES);
1390  else
1391  llr_msg->found = ntohs (GNUNET_NO);
1392  GNUNET_memcpy (&llr_msg[1], name_tmp, name_len);
1393  GNUNET_memcpy (&res_name[name_len], rlc.res_rd, rlc.rd_ser_len);
1394  GNUNET_MQ_send (nc->mq, env);
1396 }
1397 
1398 
1406 static int
1407 check_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1408 {
1409  size_t name_len;
1410  size_t msg_size;
1411  size_t msg_size_exp;
1412  size_t rd_ser_len;
1413  const char *name_tmp;
1414 
1415  (void) cls;
1416  name_len = ntohs (rp_msg->name_len);
1417  msg_size = ntohs (rp_msg->gns_header.header.size);
1418  rd_ser_len = ntohs (rp_msg->rd_len);
1419  msg_size_exp = sizeof(struct RecordStoreMessage) + name_len + rd_ser_len;
1420  if (msg_size != msg_size_exp)
1421  {
1422  GNUNET_break (0);
1423  return GNUNET_SYSERR;
1424  }
1425  if ((0 == name_len) || (name_len > MAX_NAME_LEN))
1426  {
1427  GNUNET_break (0);
1428  return GNUNET_SYSERR;
1429  }
1430  name_tmp = (const char *) &rp_msg[1];
1431  if ('\0' != name_tmp[name_len - 1])
1432  {
1433  GNUNET_break (0);
1434  return GNUNET_SYSERR;
1435  }
1436  return GNUNET_OK;
1437 }
1438 
1439 
1446 static void
1447 handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1448 {
1449  struct NamestoreClient *nc = cls;
1450  size_t name_len;
1451  size_t rd_ser_len;
1452  uint32_t rid;
1453  const char *name_tmp;
1454  char *conv_name;
1455  const char *rd_ser;
1456  unsigned int rd_count;
1457  int res;
1458  struct StoreActivity *sa;
1459 
1461  "Received NAMESTORE_RECORD_STORE message\n");
1462  rid = ntohl (rp_msg->gns_header.r_id);
1463  name_len = ntohs (rp_msg->name_len);
1464  rd_count = ntohs (rp_msg->rd_count);
1465  rd_ser_len = ntohs (rp_msg->rd_len);
1466  GNUNET_break (0 == ntohs (rp_msg->reserved));
1467  name_tmp = (const char *) &rp_msg[1];
1468  rd_ser = &name_tmp[name_len];
1469  {
1470  struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
1471 
1472  if (GNUNET_OK !=
1473  GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count, rd))
1474  {
1475  GNUNET_break (0);
1477  return;
1478  }
1479 
1480  /* Extracting and converting private key */
1481  conv_name = GNUNET_GNSRECORD_string_to_lowercase (name_tmp);
1482  if (NULL == conv_name)
1483  {
1485  "Error converting name `%s'\n",
1486  name_tmp);
1488  return;
1489  }
1490  GNUNET_STATISTICS_update (statistics,
1491  "Well-formed store requests received",
1492  1,
1493  GNUNET_NO);
1495  "Creating %u records for name `%s'\n",
1496  (unsigned int) rd_count,
1497  conv_name);
1498  if ((0 == rd_count) &&
1499  (GNUNET_NO == GSN_database->lookup_records (GSN_database->cls,
1500  &rp_msg->private_key,
1501  conv_name,
1502  NULL,
1503  0)))
1504  {
1505  /* This name does not exist, so cannot be removed */
1507  "Name `%s' does not exist, no deletion required\n",
1508  conv_name);
1509  res = GNUNET_NO;
1510  }
1511  else
1512  {
1513  /* remove "NICK" records, unless this is for the
1514  #GNUNET_GNS_EMPTY_LABEL_AT label */
1515  struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL (rd_count)];
1516  unsigned int rd_clean_off;
1517  int have_nick;
1518 
1519  rd_clean_off = 0;
1520  have_nick = GNUNET_NO;
1521  for (unsigned int i = 0; i < rd_count; i++)
1522  {
1523  rd_clean[rd_clean_off] = rd[i];
1524  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) ||
1526  rd_clean_off++;
1527 
1528  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1529  (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type))
1530  {
1531  cache_nick (&rp_msg->private_key, &rd[i]);
1532  have_nick = GNUNET_YES;
1533  }
1534  }
1535  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1536  (GNUNET_NO == have_nick))
1537  {
1538  /* remove nick record from cache, in case we have one there */
1539  cache_nick (&rp_msg->private_key, NULL);
1540  }
1541  res = GSN_database->store_records (GSN_database->cls,
1542  &rp_msg->private_key,
1543  conv_name,
1544  rd_clean_off,
1545  rd_clean);
1546  }
1547 
1548  if (GNUNET_OK != res)
1549  {
1550  /* store not successful, not need to tell monitors */
1551  send_store_response (nc, res, rid);
1553  GNUNET_free (conv_name);
1554  return;
1555  }
1556 
1557  sa = GNUNET_malloc (sizeof(struct StoreActivity)
1558  + ntohs (rp_msg->gns_header.header.size));
1559  GNUNET_CONTAINER_DLL_insert (sa_head, sa_tail, sa);
1560  sa->nc = nc;
1561  sa->rsm = (const struct RecordStoreMessage *) &sa[1];
1562  GNUNET_memcpy (&sa[1], rp_msg, ntohs (rp_msg->gns_header.header.size));
1563  sa->zm_pos = monitor_head;
1564  sa->conv_name = conv_name;
1566  }
1567 }
1568 
1569 
1575 {
1580 
1584  uint32_t rid;
1585 
1591  int success;
1592 };
1593 
1594 
1605 static void
1607  uint64_t seq,
1608  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
1609  const char *name,
1610  unsigned int rd_count,
1611  const struct GNUNET_GNSRECORD_Data *rd)
1612 {
1613  struct ZoneToNameCtx *ztn_ctx = cls;
1614  struct GNUNET_MQ_Envelope *env;
1615  struct ZoneToNameResponseMessage *ztnr_msg;
1616  int16_t res;
1617  size_t name_len;
1618  ssize_t rd_ser_len;
1619  size_t msg_size;
1620  char *name_tmp;
1621  char *rd_tmp;
1622 
1623  GNUNET_assert (0 != seq);
1625  "Found result for zone-to-name lookup: `%s'\n",
1626  name);
1627  res = GNUNET_YES;
1628  name_len = (NULL == name) ? 0 : strlen (name) + 1;
1629  rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1630  if (rd_ser_len < 0)
1631  {
1632  GNUNET_break (0);
1633  ztn_ctx->success = GNUNET_SYSERR;
1634  return;
1635  }
1636  msg_size = sizeof(struct ZoneToNameResponseMessage) + name_len + rd_ser_len;
1637  if (msg_size >= GNUNET_MAX_MESSAGE_SIZE)
1638  {
1639  GNUNET_break (0);
1640  ztn_ctx->success = GNUNET_SYSERR;
1641  return;
1642  }
1643  env =
1644  GNUNET_MQ_msg_extra (ztnr_msg,
1645  name_len + rd_ser_len,
1647  ztnr_msg->gns_header.header.size = htons (msg_size);
1648  ztnr_msg->gns_header.r_id = htonl (ztn_ctx->rid);
1649  ztnr_msg->res = htons (res);
1650  ztnr_msg->rd_len = htons (rd_ser_len);
1651  ztnr_msg->rd_count = htons (rd_count);
1652  ztnr_msg->name_len = htons (name_len);
1653  ztnr_msg->zone = *zone_key;
1654  name_tmp = (char *) &ztnr_msg[1];
1655  GNUNET_memcpy (name_tmp, name, name_len);
1656  rd_tmp = &name_tmp[name_len];
1657  GNUNET_assert (
1658  rd_ser_len ==
1659  GNUNET_GNSRECORD_records_serialize (rd_count, rd, rd_ser_len, rd_tmp));
1660  ztn_ctx->success = GNUNET_OK;
1661  GNUNET_MQ_send (ztn_ctx->nc->mq, env);
1662 }
1663 
1664 
1671 static void
1672 handle_zone_to_name (void *cls, const struct ZoneToNameMessage *ztn_msg)
1673 {
1674  struct NamestoreClient *nc = cls;
1675  struct ZoneToNameCtx ztn_ctx;
1676  struct GNUNET_MQ_Envelope *env;
1677  struct ZoneToNameResponseMessage *ztnr_msg;
1678 
1679  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_TO_NAME message\n");
1680  ztn_ctx.rid = ntohl (ztn_msg->gns_header.r_id);
1681  ztn_ctx.nc = nc;
1682  ztn_ctx.success = GNUNET_NO;
1683  if (GNUNET_SYSERR == GSN_database->zone_to_name (GSN_database->cls,
1684  &ztn_msg->zone,
1685  &ztn_msg->value_zone,
1687  &ztn_ctx))
1688  {
1689  /* internal error, hang up instead of signalling something
1690  that might be wrong */
1691  GNUNET_break (0);
1693  return;
1694  }
1695  if (GNUNET_NO == ztn_ctx.success)
1696  {
1697  /* no result found, send empty response */
1699  "Found no result for zone-to-name lookup.\n");
1700  env = GNUNET_MQ_msg (ztnr_msg,
1702  ztnr_msg->gns_header.r_id = ztn_msg->gns_header.r_id;
1703  ztnr_msg->res = htons (GNUNET_NO);
1704  GNUNET_MQ_send (nc->mq, env);
1705  }
1707 }
1708 
1709 
1715 {
1720 
1724  uint64_t limit;
1725 };
1726 
1727 
1738 static void
1740  uint64_t seq,
1741  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
1742  const char *name,
1743  unsigned int rd_count,
1744  const struct GNUNET_GNSRECORD_Data *rd)
1745 {
1746  struct ZoneIterationProcResult *proc = cls;
1747  int do_refresh_block;
1748 
1749  GNUNET_assert (0 != seq);
1750  if ((NULL == zone_key) && (NULL == name))
1751  {
1752  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
1753  return;
1754  }
1755  if ((NULL == zone_key) || (NULL == name))
1756  {
1757  /* what is this!? should never happen */
1758  GNUNET_break (0);
1759  return;
1760  }
1761  if (0 == proc->limit)
1762  {
1763  /* what is this!? should never happen */
1764  GNUNET_break (0);
1765  return;
1766  }
1767  proc->limit--;
1768  proc->zi->seq = seq;
1769  send_lookup_response (proc->zi->nc,
1770  proc->zi->request_id,
1771  zone_key,
1772  name,
1773  rd_count,
1774  rd);
1775 
1776 
1777  do_refresh_block = GNUNET_NO;
1778  for (unsigned int i = 0; i < rd_count; i++)
1779  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
1780  {
1781  do_refresh_block = GNUNET_YES;
1782  break;
1783  }
1784  if (GNUNET_YES == do_refresh_block)
1785  refresh_block (NULL, proc->zi, 0, zone_key, name, rd_count, rd);
1786 }
1787 
1788 
1795 static void
1797 {
1798  struct ZoneIterationProcResult proc;
1799  struct GNUNET_TIME_Absolute start;
1800  struct GNUNET_TIME_Relative duration;
1801 
1802  memset (&proc, 0, sizeof(proc));
1804  "Asked to return up to %llu records at position %llu\n",
1805  (unsigned long long) limit,
1806  (unsigned long long) zi->seq);
1807  proc.zi = zi;
1808  proc.limit = limit;
1809  start = GNUNET_TIME_absolute_get ();
1811  GSN_database->iterate_records (GSN_database->cls,
1812  (0 == GNUNET_is_zero (&zi->zone))
1813  ? NULL
1814  : &zi->zone,
1815  zi->seq,
1816  limit,
1818  &proc));
1819  duration = GNUNET_TIME_absolute_get_duration (start);
1820  duration = GNUNET_TIME_relative_divide (duration, limit - proc.limit);
1821  GNUNET_STATISTICS_set (statistics,
1822  "NAMESTORE iteration delay (μs/record)",
1823  duration.rel_value_us,
1824  GNUNET_NO);
1825  if (0 == proc.limit)
1827  "Returned %llu results, more results available\n",
1828  (unsigned long long) limit);
1829  zi->send_end = (0 != proc.limit);
1830  if (0 == zi->cache_ops)
1832 }
1833 
1834 
1841 static void
1843  const struct ZoneIterationStartMessage *zis_msg)
1844 {
1845  struct NamestoreClient *nc = cls;
1846  struct ZoneIteration *zi;
1847 
1849  "Received ZONE_ITERATION_START message\n");
1850  zi = GNUNET_new (struct ZoneIteration);
1851  zi->request_id = ntohl (zis_msg->gns_header.r_id);
1852  zi->offset = 0;
1853  zi->nc = nc;
1854  zi->zone = zis_msg->zone;
1855 
1857  run_zone_iteration_round (zi, 1);
1858 }
1859 
1860 
1867 static void
1869  const struct ZoneIterationStopMessage *zis_msg)
1870 {
1871  struct NamestoreClient *nc = cls;
1872  struct ZoneIteration *zi;
1873  uint32_t rid;
1874 
1876  "Received ZONE_ITERATION_STOP message\n");
1877  rid = ntohl (zis_msg->gns_header.r_id);
1878  for (zi = nc->op_head; NULL != zi; zi = zi->next)
1879  if (zi->request_id == rid)
1880  break;
1881  if (NULL == zi)
1882  {
1883  GNUNET_break (0);
1885  return;
1886  }
1888  GNUNET_free (zi);
1890 }
1891 
1892 
1899 static void
1901  const struct ZoneIterationNextMessage *zis_msg)
1902 {
1903  struct NamestoreClient *nc = cls;
1904  struct ZoneIteration *zi;
1905  uint32_t rid;
1906  uint64_t limit;
1907 
1909  "Received ZONE_ITERATION_NEXT message\n");
1910  GNUNET_STATISTICS_update (statistics,
1911  "Iteration NEXT messages received",
1912  1,
1913  GNUNET_NO);
1914  rid = ntohl (zis_msg->gns_header.r_id);
1915  limit = GNUNET_ntohll (zis_msg->limit);
1916  for (zi = nc->op_head; NULL != zi; zi = zi->next)
1917  if (zi->request_id == rid)
1918  break;
1919  if (NULL == zi)
1920  {
1921  GNUNET_break (0);
1923  return;
1924  }
1925  run_zone_iteration_round (zi, limit);
1926 }
1927 
1928 
1934 static void
1936 {
1937  struct StoreActivity *sa = sa_head;
1938 
1939  while ((NULL != sa) && (zm->limit > zm->iteration_cnt))
1940  {
1941  struct StoreActivity *sn = sa->next;
1942 
1943  if (sa->zm_pos == zm)
1945  sa = sn;
1946  }
1947  if (zm->limit > zm->iteration_cnt)
1948  {
1949  zm->sa_waiting = GNUNET_NO;
1950  if (NULL != zm->sa_wait_warning)
1951  {
1953  zm->sa_wait_warning = NULL;
1954  }
1955  }
1956  else if (GNUNET_YES == zm->sa_waiting)
1957  {
1959  if (NULL != zm->sa_wait_warning)
1961  zm->sa_wait_warning =
1964  zm);
1965  }
1966 }
1967 
1968 
1974 static void
1976 {
1977  struct GNUNET_MQ_Envelope *env;
1978  struct GNUNET_MessageHeader *sync;
1979 
1981  GNUNET_MQ_send (zm->nc->mq, env);
1982  /* mark iteration done */
1984  zm->iteration_cnt = 0;
1985  if ((zm->limit > 0) && (zm->sa_waiting))
1986  monitor_unblock (zm);
1987 }
1988 
1989 
1995 static void
1996 monitor_iteration_next (void *cls);
1997 
1998 
2009 static void
2011  uint64_t seq,
2012  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
2013  const char *name,
2014  unsigned int rd_count,
2015  const struct GNUNET_GNSRECORD_Data *rd)
2016 {
2017  struct ZoneMonitor *zm = cls;
2018 
2019  GNUNET_assert (0 != seq);
2020  zm->seq = seq;
2021  GNUNET_assert (NULL != name);
2022  GNUNET_STATISTICS_update (statistics,
2023  "Monitor notifications sent",
2024  1,
2025  GNUNET_NO);
2026  zm->limit--;
2027  zm->iteration_cnt--;
2028  send_lookup_response (zm->nc, 0, zone_key, name, rd_count, rd);
2029  if ((0 == zm->iteration_cnt) && (0 != zm->limit))
2030  {
2031  /* We are done with the current iteration batch, AND the
2032  client would right now accept more, so go again! */
2033  GNUNET_assert (NULL == zm->task);
2035  }
2036 }
2037 
2038 
2045 static void
2046 handle_monitor_start (void *cls, const struct ZoneMonitorStartMessage *zis_msg)
2047 {
2048  struct NamestoreClient *nc = cls;
2049  struct ZoneMonitor *zm;
2050 
2051  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_MONITOR_START message\n");
2052  zm = GNUNET_new (struct ZoneMonitor);
2053  zm->nc = nc;
2054  zm->zone = zis_msg->zone;
2055  zm->limit = 1;
2056  zm->in_first_iteration = (GNUNET_YES == ntohl (zis_msg->iterate_first));
2057  GNUNET_CONTAINER_DLL_insert (monitor_head, monitor_tail, zm);
2060  GNUNET_notification_context_add (monitor_nc, nc->mq);
2061  if (zm->in_first_iteration)
2063  else
2064  monitor_sync (zm);
2065 }
2066 
2067 
2073 static void
2075 {
2076  struct ZoneMonitor *zm = cls;
2077  int ret;
2078 
2079  zm->task = NULL;
2080  GNUNET_assert (0 == zm->iteration_cnt);
2081  if (zm->limit > 16)
2082  zm->iteration_cnt = zm->limit / 2; /* leave half for monitor events */
2083  else
2084  zm->iteration_cnt = zm->limit; /* use it all */
2085  ret = GSN_database->iterate_records (GSN_database->cls,
2086  (0 == GNUNET_is_zero (&zm->zone))
2087  ? NULL
2088  : &zm->zone,
2089  zm->seq,
2090  zm->iteration_cnt,
2092  zm);
2093  if (GNUNET_SYSERR == ret)
2094  {
2096  return;
2097  }
2098  if (GNUNET_NO == ret)
2099  {
2100  /* empty zone */
2101  monitor_sync (zm);
2102  return;
2103  }
2104 }
2105 
2106 
2113 static void
2114 handle_monitor_next (void *cls, const struct ZoneMonitorNextMessage *nm)
2115 {
2116  struct NamestoreClient *nc = cls;
2117  struct ZoneMonitor *zm;
2118  uint64_t inc;
2119 
2120  inc = GNUNET_ntohll (nm->limit);
2122  "Received ZONE_MONITOR_NEXT message with limit %llu\n",
2123  (unsigned long long) inc);
2124  for (zm = monitor_head; NULL != zm; zm = zm->next)
2125  if (zm->nc == nc)
2126  break;
2127  if (NULL == zm)
2128  {
2129  GNUNET_break (0);
2131  return;
2132  }
2134  if (zm->limit + inc < zm->limit)
2135  {
2136  GNUNET_break (0);
2138  return;
2139  }
2140  zm->limit += inc;
2141  if ((zm->in_first_iteration) && (zm->limit == inc))
2142  {
2143  /* We are still iterating, and the previous iteration must
2144  have stopped due to the client's limit, so continue it! */
2145  GNUNET_assert (NULL == zm->task);
2147  }
2148  GNUNET_assert (zm->iteration_cnt <= zm->limit);
2149  if ((zm->limit > zm->iteration_cnt) && (zm->sa_waiting))
2150  {
2151  monitor_unblock (zm);
2152  }
2153  else if (GNUNET_YES == zm->sa_waiting)
2154  {
2155  if (NULL != zm->sa_wait_warning)
2158  zm->sa_wait_warning =
2161  zm);
2162  }
2163 }
2164 
2165 
2173 static void
2174 run (void *cls,
2175  const struct GNUNET_CONFIGURATION_Handle *cfg,
2177 {
2178  char *database;
2179 
2180  (void) cls;
2181  (void) service;
2182  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n");
2183  cache_keys =
2184  GNUNET_CONFIGURATION_get_value_yesno (cfg, "namestore", "CACHE_KEYS");
2186  GNUNET_CONFIGURATION_get_value_yesno (cfg, "namecache", "DISABLE");
2187  GSN_cfg = cfg;
2188  monitor_nc = GNUNET_notification_context_create (1);
2190  {
2191  namecache = GNUNET_NAMECACHE_connect (cfg);
2192  GNUNET_assert (NULL != namecache);
2193  }
2194  /* Loading database plugin */
2196  "namestore",
2197  "database",
2198  &database))
2199  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
2200 
2201  GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
2202  GSN_database = GNUNET_PLUGIN_load (db_lib_name, (void *) GSN_cfg);
2203  GNUNET_free (database);
2204  statistics = GNUNET_STATISTICS_create ("namestore", cfg);
2206  if (NULL == GSN_database)
2207  {
2209  "Could not load database backend `%s'\n",
2210  db_lib_name);
2212  return;
2213  }
2214 }
2215 
2216 
2221  "namestore",
2223  &run,
2226  NULL,
2227  GNUNET_MQ_hd_var_size (record_store,
2229  struct RecordStoreMessage,
2230  NULL),
2231  GNUNET_MQ_hd_var_size (record_lookup,
2233  struct LabelLookupMessage,
2234  NULL),
2237  struct ZoneToNameMessage,
2238  NULL),
2242  NULL),
2243  GNUNET_MQ_hd_fixed_size (iteration_next,
2245  struct ZoneIterationNextMessage,
2246  NULL),
2247  GNUNET_MQ_hd_fixed_size (iteration_stop,
2249  struct ZoneIterationStopMessage,
2250  NULL),
2251  GNUNET_MQ_hd_fixed_size (monitor_start,
2253  struct ZoneMonitorStartMessage,
2254  NULL),
2255  GNUNET_MQ_hd_fixed_size (monitor_next,
2257  struct ZoneMonitorNextMessage,
2258  NULL),
2260 
2261 
2262 /* end of gnunet-service-namestore.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
int send_end
Set to GNUNET_YES if the last iteration exhausted the limit set by the client and we should send the ...
struct CacheOperation * next
Kept in a DLL.
static const struct GNUNET_CRYPTO_EcdsaPrivateKey zero
Public key of all zeros.
static void handle_iteration_next(void *cls, const struct ZoneIterationNextMessage *zis_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT message.
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE.
Definition: namestore.h:110
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE.
Definition: namestore.h:63
struct GNUNET_NAMECACHE_Handle * GNUNET_NAMECACHE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namecache service.
static char * db_lib_name
Name of the database plugin.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
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.
The notification context is the key datastructure for a convenience API used for transmission of noti...
Definition: nc.c:75
static struct GNUNET_NotificationContext * monitor_nc
Notification context shared by all monitors.
struct GNUNET_MQ_Handle * mq
Message queue for transmission to client.
Start monitoring a zone.
Definition: namestore.h:298
static void zone_iterate_proc(void *cls, uint64_t seq, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process results for zone iteration from database.
char * GNUNET_GNSRECORD_string_to_lowercase(const char *src)
Convert a UTF-8 string to UTF-8 lowercase.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
uint32_t label_len
Length of the name.
Definition: namestore.h:132
struct NamestoreClient * nc
Namestore client.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE
Service to client: result of zone-to-name lookup.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
Called whenever a client is disconnected.
struct GNUNET_GNSRECORD_Block * GNUNET_GNSRECORD_block_create(const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count)
Sign name and records.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_NEXT
Client to service: I am now ready for the next (set of) monitor events.
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
Handle to a service.
Definition: service.c:116
Ask for next result of zone iteration for the given operation.
Definition: namestore.h:362
struct GNUNET_NAMECACHE_QueueEntry * qe
Handle to namecache queue.
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:163
static void monitor_iterate_cb(void *cls, uint64_t seq, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
A GNUNET_NAMESTORE_RecordIterator for monitors.
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, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1333
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.
int(* zone_to_name)(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Look for an existing PKEY delegation record for a given public key.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
struct NamestoreClient * nc
Namestore client which intiated this zone monitor.
uint64_t limit
Number of results left to be returned in this iteration.
uint64_t iteration_cnt
How many more requests may we receive from the iterator before it is at the limit we gave it...
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
struct ZoneMonitor * prev
Previous element in the DLL.
uint32_t r_id
Request ID in NBO.
Definition: namestore.h:51
uint16_t rd_count
Number of records contained.
Definition: namestore.h:168
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_GNSRECORD_Block * GNUNET_GNSRECORD_block_create2(const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count)
Sign name and records, cache derived public key (also keeps the private key in static memory...
Start a zone iteration for the given zone.
Definition: namestore.h:345
static void send_lookup_response(struct NamestoreClient *nc, uint32_t request_id, const struct GNUNET_CRYPTO_EcdsaPrivateKey *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 struct ZoneMonitor * monitor_head
First active zone 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_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME.
Definition: namestore.h:196
uint16_t name_len
Length of the name.
Definition: namestore.h:223
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
struct ZoneMonitor * zm_pos
Next zone monitor that still needs to be notified about this PUT.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static void handle_monitor_next(void *cls, const struct ZoneMonitorNextMessage *nm)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_NEXT message.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
struct GNUNET_TIME_Absolute sa_waiting_start
Since when are we blocked on this monitor?
int16_t res
result in NBO: GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error ...
Definition: namestore.h:239
static struct GNUNET_NAMESTORE_ZoneMonitor * zm
Monitor handle.
This is a supplemental record.
size_t data_size
Number of bytes in data.
struct StoreActivity * next
Kept in a DLL.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Private ECC key encoded for transmission.
static struct CacheOperation * cop_head
Head of cop DLL.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT_END
Service to client: end of list of results.
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.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
Information we have in an encrypted block with record data (i.e.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static struct NickCache nick_cache[16]
We cache nick records to reduce DB load.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:531
Handle for the service.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP
Client to service: lookup label.
#define GNUNET_GNSRECORD_TYPE_NICK
Record type for GNS nick names ("NICK").
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
uint64_t abs_value_us
The actual value.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP
Client to service: stop iterating.
uint16_t reserved
always zero (for alignment)
Definition: namestore.h:88
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
Zone the cache entry is for.
int success
Set to GNUNET_OK on success, GNUNET_SYSERR on error.
static void run_zone_iteration_round(struct ZoneIteration *zi, uint64_t limit)
Perform the next round of the zone iteration.
Entry in list of cached nick resolutions.
struct ZoneIteration * op_head
Head of the DLL of Zone iteration operations in progress initiated by this client.
#define _(String)
GNU gettext support macro.
Definition: platform.h:180
uint16_t name_len
Name length.
Definition: namestore.h:266
static int disable_namecache
Use the namecache? Doing so creates additional cryptographic operations whenever we touch a record...
#define NC_SIZE
Size of the cache used by get_nick_record()
void * GNUNET_PLUGIN_unload(const char *library_name, void *arg)
Unload plugin (runs the "done" callback and returns whatever "done" returned).
Definition: plugin.c:256
common internal definitions for namestore service
Handle to a client that is connected to a service.
Definition: service.c:250
uint16_t rd_count
Number of records contained.
Definition: namestore.h:233
void * cls
Closure to pass to all plugin functions.
uint64_t seq
Last sequence number in the zone iteration used to address next result of the zone iteration in the s...
int32_t op_result
GNUNET_SYSERR on failure, GNUNET_OK on success
Definition: namestore.h:115
struct GNUNET_MessageHeader header
header.type will be GNUNET_MESSAGE_TYPE_NAMESTORE_* header.size will be message size ...
Definition: namestore.h:46
struct GNUNET_CRYPTO_EcdsaPrivateKey private_key
The private key of the authority.
Definition: namestore.h:286
uint64_t limit
Number of records to return to the iterator in one shot (before #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_M...
Definition: namestore.h:338
static void monitor_iteration_next(void *cls)
Obtain the next datum during the zone monitor&#39;s zone initial iteration.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
struct GNUNET_CRYPTO_EcdsaPublicKey value_zone
The public key of the target zone.
Definition: namestore.h:206
#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:52
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:1271
static void lookup_nick_it(void *cls, uint64_t seq, const struct GNUNET_CRYPTO_EcdsaPrivateKey *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.
uint32_t rid
Client&#39;s request ID.
static int check_record_lookup(void *cls, const struct LabelLookupMessage *ll_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message.
#define GNUNET_MQ_check_zero_termination(m)
Insert code for a "check_" function that verifies that a given variable-length message received over ...
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:78
const void * data
Binary value stored in the DNS record.
static struct ZoneMonitor * monitor_tail
Last active zone monitor.
A namestore client.
uint16_t rd_count
Number of records contained.
Definition: namestore.h:276
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE
Client to service: store records (as authority)
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
struct GNUNET_TIME_Absolute last_used
Timestamp when this cache entry was used last.
static int check_record_store(void *cls, const struct RecordStoreMessage *rp_msg)
Checks a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message.
struct ZoneIteration * zi
The zone iteration handle.
#define MONITOR_STALL_WARN_DELAY
If a monitor takes more than 1 minute to process an event, print a warning.
uint64_t expiration_time
Expiration time for the DNS record.
Closure for lookup_it().
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:1298
static void continue_store_activity(struct StoreActivity *sa)
Continue processing the sa.
GNUNET_SERVICE_MAIN("namestore", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(record_store, GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE, struct RecordStoreMessage, NULL), GNUNET_MQ_hd_var_size(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.
struct NamestoreClient * nc
Which client triggered the store activity?
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
Zone key.
Definition: namestore.h:314
static void finish_cache_operation(void *cls, int32_t success, const char *emsg)
Cache operation complete, clean up.
Stop zone iteration for the given operation.
Definition: namestore.h:381
static void monitor_sync(struct ZoneMonitor *zm)
Send &#39;sync&#39; message to zone monitor, we&#39;re now in sync.
struct StoreActivity * prev
Kept in a DLL.
uint16_t name_len
Name length.
Definition: namestore.h:73
uint64_t limit
Current limit of how many more messages we are allowed to queue to this monitor.
unsigned int cache_ops
Number of pending cache operations triggered by this zone iteration which we need to wait for before ...
static void handle_record_store(void *cls, const struct RecordStoreMessage *rp_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message.
void GNUNET_NAMECACHE_cancel(struct GNUNET_NAMECACHE_QueueEntry *qe)
Cancel a namecache operation.
int in_first_iteration
Are we (still) in the initial iteration pass?
uint16_t name_len
Name length.
Definition: namestore.h:158
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the &#39;monitor&#39; flag on this client.
Definition: service.c:2403
This is a private record of this peer and it should thus not be handed out to other peers...
static void handle_monitor_start(void *cls, const struct ZoneMonitorStartMessage *zis_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START message.
struct ZoneIteration * next
Next element in the DLL.
struct GNUNET_SERVICE_Client * client
The client.
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.
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_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2320
const char * GNUNET_GNSRECORD_z2s(const struct GNUNET_CRYPTO_EcdsaPublicKey *z)
Convert a zone key to a string (for printing debug messages).
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START.
Definition: namestore.h:350
static int res
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
uint16_t rd_count
Number of records contained.
Definition: namestore.h:83
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.
struct GNUNET_TIME_Absolute GNUNET_GNSRECORD_record_get_expiration_time(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Returns the expiration time of the given block of records.
struct GNUNET_SCHEDULER_Task * task
Task active during initial iteration.
int 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_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME
Client to service: "reverse" lookup for zone name based on zone key.
char * conv_name
Label nicely canonicalized (lower case).
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
The private key of the zone that contained the name.
Definition: namestore.h:244
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START
Client to service: please start iteration; receives "GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPON...
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.
uint32_t offset
Offset of the zone iteration used to address next result of the zone iteration in the store...
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT
Client to service: next record(s) in iteration please.
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:172
struct ZoneIteration * zi
Zone iteration to call zone_iteration_done_client_continue() for if applicable, can be NULL...
uint32_t request_id
The operation id fot the zone iteration in the response for the client.
unsigned int res_rd_count
FIXME.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static struct StoreActivity * sa_tail
Tail of DLL of monitor-blocked store activities.
uint16_t found
Was the label found in the database?? GNUNET_YES or GNUNET_NO.
Definition: namestore.h:174
static struct GNUNET_STATISTICS_Handle * statistics
Handle to the statistics service.
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:271
static void iteration_start()
Information for an ongoing handle_record_store() operation.
static void handle_zone_to_name_it(void *cls, uint64_t seq, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Zone to name iterator.
#define GNUNET_is_zero(a)
Check that memory in a is all zeros.
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT.
Definition: namestore.h:261
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
uint32_t iterate_first
GNUNET_YES to first iterate over all records, GNUNET_NO to only monitor changes.o ...
Definition: namestore.h:309
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE
Service to client: lookup label.
static void handle_zone_to_name(void *cls, const struct ZoneToNameMessage *ztn_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME message.
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition: nc.c:121
#define GNUNET_LOG_CALL_STATUS
struct CacheOperation * prev
Kept in a DLL.
Ask for next result of zone iteration for the given operation.
Definition: namestore.h:321
Handle to a message queue.
Definition: mq.c:85
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
Definition: namestore.h:218
struct GNUNET_CRYPTO_EcdsaPrivateKey private_key
The private key of the authority.
Definition: namestore.h:93
Store a record to the namestore (as authority).
Definition: namestore.h:58
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
Process namestore requests.
struct ZoneIteration * prev
Previous element in the DLL.
Context for record remove operations passed from handle_zone_to_name to handle_zone_to_name_it as clo...
static void cache_nick(const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const struct GNUNET_GNSRECORD_Data *nick)
Add entry to the cache for zone and nick.
Respone for zone to name lookup.
Definition: namestore.h:213
struct GNUNET_GNSRECORD_Data * nick
FIXME.
int(* lookup_records)(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Lookup records in the datastore for which we are the authority.
static const struct GNUNET_CONFIGURATION_Handle * GSN_cfg
Configuration handle.
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
The private key of the zone to look up in.
Definition: namestore.h:201
static void send_store_response(struct NamestoreClient *nc, int res, uint32_t rid)
Send response to the store request to the client.
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE.
Definition: namestore.h:153
uint32_t record_type
Type of the GNS/DNS record.
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
Private key of the zone.
static void free_store_activity(struct StoreActivity *sa)
Release memory used by sa.
struct ZoneIteration * op_tail
Tail of the DLL of Zone iteration operations in progress initiated by this client.
struct GNUNET_GNSRECORD_Data * nick
The nick to add to the records.
configuration data
Definition: configuration.c:84
Response to a record storage request.
Definition: namestore.h:105
const char * name
static struct StoreActivity * sa_head
Head of DLL of monitor-blocked store activities.
static struct GNUNET_NAMESTORE_PluginFunctions * GSN_database
Database handle.
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:375
A namestore iteration operation.
Pending operation on the namecache.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define MAX_NAME_LEN
Maximum length of any name, including 0-termination.
Definition: namecache.h:33
Connection to the NAMECACHE service.
Definition: namecache_api.c:94
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
struct GNUNET_CRYPTO_EcdsaPrivateKey private_key
The private key of the authority.
Definition: namestore.h:179
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
Key of the zone we are iterating over.
Entry in list of pending tasks.
Definition: scheduler.c:134
Generic namestore message with op id.
Definition: namestore.h:40
static void refresh_block(struct NamestoreClient *nc, struct ZoneIteration *zi, uint32_t rid, const struct GNUNET_CRYPTO_EcdsaPrivateKey *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...
#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_SYNC
Service to client: you&#39;re now in sync.
static struct GNUNET_GNSRECORD_Data * get_nick_record(const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone)
Return the NICK record for the zone (if it exists).
#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START
Client to service: start monitoring (yields sequence of "ZONE_ITERATION_RESPONSES" — forever)...
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:228
struct ZoneMonitor * next
Next element in the DLL.
void GNUNET_NAMECACHE_disconnect(struct GNUNET_NAMECACHE_Handle *h)
Disconnect from the namecache service (and free associated resources).
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP.
Definition: namestore.h:127
Lookup a name for a zone hash.
Definition: namestore.h:191
const struct RecordStoreMessage * rsm
Copy of the original store message (as data fields in rd will point into it!).
Lookup a label.
Definition: namestore.h:122
static int zone_to_name(void *cls, const struct GNUNET_HashCode *key, void *value)
static void cleanup_task(void *cls)
Task run during shutdown.
Header for all communications.
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:527
struct NamestoreClient * nc
Client to notify about the result, can be NULL.
Time for absolute times used by GNUnet, in microseconds.
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition: nc.c:137
An QueueEntry used to store information for a pending NAMECACHE record operation. ...
Definition: namecache_api.c:47
void * GNUNET_PLUGIN_load(const char *library_name, void *arg)
Setup plugin (runs the "init" callback and returns whatever "init" returned).
Definition: plugin.c:207
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:355
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
Service to client: here is a (plaintext) record you requested.
static struct GNUNET_NAMECACHE_Handle * namecache
Namecache handle.
Record is returned from the namestore (as authority).
Definition: namestore.h:256
uint64_t limit
Number of records to return to the iterator in one shot (before GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_IT...
Definition: namestore.h:374
enum GNUNET_GNSRECORD_Flags flags
Flags for the record.
This expiration time of the record is a relative time (not an absolute time).
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:756
static int cache_keys
Optimize block insertion by caching map of private keys to public keys in memory? ...
struct GNUNET_SCHEDULER_Task * sa_wait_warning
Task to warn about slow monitors.
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.
int 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".
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 ...
uint32_t data
The data value.
int sa_waiting
Is there a store activity waiting for this monitor? We only raise the flag when it happens and search...
int(* store_records)(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Store a record in the datastore for which we are the authority.
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
Zone key.
Definition: namestore.h:355
struct NamestoreClient * nc
Namestore client which intiated this zone iteration.
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT.
Definition: namestore.h:367
struct returned by the initialization function of the plugin
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
Monitored zone.
static struct CacheOperation * cop_tail
Tail of cop DLL.
static void handle_iteration_start(void *cls, const struct ZoneIterationStartMessage *zis_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START message.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2239
static void handle_record_lookup(void *cls, const struct LabelLookupMessage *ll_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message.
static void warn_monitor_slow(void *cls)
Print a warning that one of our monitors is no longer reacting.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP.
Definition: namestore.h:386
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_iteration_stop(void *cls, const struct ZoneIterationStopMessage *zis_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP message.
Lookup a label.
Definition: namestore.h:148
int(* iterate_records)(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, uint64_t serial, uint64_t limit, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Iterate over the results for a particular zone in the datastore.
#define GNUNET_malloc(size)
Wrapper around malloc.
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
The private key of the zone to look up in.
Definition: namestore.h:137
struct GNUNET_GNSRECORD_Data * rd
Cached record data.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:53
A namestore monitor.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
Context for record remove operations passed from run_zone_iteration_round to zone_iterate_proc as clo...
uint32_t rid
Request id (to be used in the response to the client).
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:974
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
Service to client: result of store operation.
static void lookup_it(void *cls, uint64_t seq, const struct GNUNET_CRYPTO_EcdsaPrivateKey *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...