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  target[rd2_length].expiration_time = latest_expiration;
699  target[rd2_length].data = (void *) &data[data_offset];
700  GNUNET_memcpy (&data[data_offset], nick_rd->data, nick_rd->data_size);
701  data_offset += nick_rd->data_size;
702  GNUNET_assert (req == (sizeof(struct GNUNET_GNSRECORD_Data)) * (*rdc_res)
703  + data_offset);
704 }
705 
706 
718 static void
720  uint32_t request_id,
721  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
722  const char *name,
723  unsigned int rd_count,
724  const struct GNUNET_GNSRECORD_Data *rd)
725 {
726  struct GNUNET_MQ_Envelope *env;
727  struct RecordResultMessage *zir_msg;
728  struct GNUNET_GNSRECORD_Data *nick;
729  struct GNUNET_GNSRECORD_Data *res;
730  unsigned int res_count;
731  size_t name_len;
732  ssize_t rd_ser_len;
733  char *name_tmp;
734  char *rd_ser;
735 
736  nick = get_nick_record (zone_key);
737  GNUNET_assert (-1 != GNUNET_GNSRECORD_records_get_size (rd_count, rd));
738 
739  if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT)))
740  {
741  nick->flags =
743  merge_with_nick_records (nick, rd_count, rd, &res_count, &res);
744  GNUNET_free (nick);
745  }
746  else
747  {
748  res_count = rd_count;
749  res = (struct GNUNET_GNSRECORD_Data *) rd;
750  }
751 
752  GNUNET_assert (-1 != GNUNET_GNSRECORD_records_get_size (res_count, res));
753 
754 
755  name_len = strlen (name) + 1;
756  rd_ser_len = GNUNET_GNSRECORD_records_get_size (res_count, res);
757  if (rd_ser_len < 0)
758  {
759  GNUNET_break (0);
761  return;
762  }
763  if (((size_t) rd_ser_len) >= UINT16_MAX - name_len - sizeof(*zir_msg))
764  {
765  GNUNET_break (0);
767  return;
768  }
769  env = GNUNET_MQ_msg_extra (zir_msg,
770  name_len + rd_ser_len,
772  zir_msg->gns_header.r_id = htonl (request_id);
773  zir_msg->name_len = htons (name_len);
774  zir_msg->rd_count = htons (res_count);
775  zir_msg->rd_len = htons ((uint16_t) rd_ser_len);
776  zir_msg->private_key = *zone_key;
777  name_tmp = (char *) &zir_msg[1];
778  GNUNET_memcpy (name_tmp, name, name_len);
779  rd_ser = &name_tmp[name_len];
780  GNUNET_assert (
781  rd_ser_len ==
782  GNUNET_GNSRECORD_records_serialize (res_count, res, rd_ser_len, rd_ser));
784  "Sending RECORD_RESULT message with %u records\n",
785  res_count);
786  GNUNET_STATISTICS_update (statistics,
787  "Record sets sent to clients",
788  1,
789  GNUNET_NO);
790  GNUNET_MQ_send (nc->mq, env);
791  if (rd != res)
792  GNUNET_free (res);
793 }
794 
795 
803 static void
804 send_store_response (struct NamestoreClient *nc, int res, uint32_t rid)
805 {
806  struct GNUNET_MQ_Envelope *env;
807  struct RecordStoreResponseMessage *rcr_msg;
808 
809  GNUNET_assert (NULL != nc);
811  "Sending RECORD_STORE_RESPONSE message\n");
812  GNUNET_STATISTICS_update (statistics,
813  "Store requests completed",
814  1,
815  GNUNET_NO);
816  env = GNUNET_MQ_msg (rcr_msg,
818  rcr_msg->gns_header.r_id = htonl (rid);
819  rcr_msg->op_result = htonl (res);
820  GNUNET_MQ_send (nc->mq, env);
821 }
822 
823 
830 static void
832 {
833  struct GNUNET_MQ_Envelope *env;
834  struct GNUNET_NAMESTORE_Header *em;
835 
837  if (! zi->send_end)
838  return;
839  /* send empty response to indicate end of list */
841  em->r_id = htonl (zi->request_id);
842  GNUNET_MQ_send (zi->nc->mq, env);
843 
845  GNUNET_free (zi);
846 }
847 
848 
856 static void
857 finish_cache_operation (void *cls, int32_t success, const char *emsg)
858 {
859  struct CacheOperation *cop = cls;
860  struct ZoneIteration *zi;
861 
862  if (NULL != emsg)
864  _ ("Failed to replicate block in namecache: %s\n"),
865  emsg);
866  else
867  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n");
868  GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop);
869  if (NULL != cop->nc)
870  send_store_response (cop->nc, success, cop->rid);
871  if (NULL != (zi = cop->zi))
872  {
873  zi->cache_ops--;
874  if (0 == zi->cache_ops)
875  {
876  /* unchoke zone iteration, cache has caught up */
878  }
879  }
880  GNUNET_free (cop);
881 }
882 
883 
896 static void
898  struct ZoneIteration *zi,
899  uint32_t rid,
900  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
901  const char *name,
902  unsigned int rd_count,
903  const struct GNUNET_GNSRECORD_Data *rd)
904 {
905  struct GNUNET_GNSRECORD_Block *block;
906  struct CacheOperation *cop;
907  struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
908  struct GNUNET_GNSRECORD_Data *nick;
909  struct GNUNET_GNSRECORD_Data *res;
910  unsigned int res_count;
911  struct GNUNET_TIME_Absolute exp_time;
912 
913  nick = get_nick_record (zone_key);
914  res_count = rd_count;
915  res = (struct GNUNET_GNSRECORD_Data *) rd; /* fixme: a bit unclean... */
916  if (NULL != nick)
917  {
918  nick->flags =
920  merge_with_nick_records (nick, rd_count, rd, &res_count, &res);
921  GNUNET_free (nick);
922  }
923  if (0 == res_count)
924  {
925  if (NULL != nc)
926  send_store_response (nc, GNUNET_OK, rid);
927  return; /* no data, no need to update cache */
928  }
930  {
931  GNUNET_STATISTICS_update (statistics,
932  "Namecache updates skipped (NC disabled)",
933  1,
934  GNUNET_NO);
935  if (NULL != nc)
936  send_store_response (nc, GNUNET_OK, rid);
937  return;
938  }
939  exp_time = GNUNET_GNSRECORD_record_get_expiration_time (res_count, res);
940  if (cache_keys)
941  block =
942  GNUNET_GNSRECORD_block_create2 (zone_key, exp_time, name, res, res_count);
943  else
944  block =
945  GNUNET_GNSRECORD_block_create (zone_key, exp_time, name, res, res_count);
946  GNUNET_assert (NULL != block);
947  GNUNET_CRYPTO_ecdsa_key_get_public (zone_key, &pkey);
948  GNUNET_log (
950  "Caching block for label `%s' with %u records and expiration %s in zone `%s' in namecache\n",
951  name,
952  res_count,
954  GNUNET_GNSRECORD_z2s (&pkey));
955  GNUNET_STATISTICS_update (statistics,
956  "Namecache updates pushed",
957  1,
958  GNUNET_NO);
959  cop = GNUNET_new (struct CacheOperation);
960  cop->nc = nc;
961  cop->zi = zi;
962  if (NULL != zi)
963  zi->cache_ops++;
964  cop->rid = rid;
965  GNUNET_CONTAINER_DLL_insert (cop_head, cop_tail, cop);
966  cop->qe = GNUNET_NAMECACHE_block_cache (namecache,
967  block,
969  cop);
970  GNUNET_free (block);
971 }
972 
973 
979 static void
980 warn_monitor_slow (void *cls)
981 {
982  struct ZoneMonitor *zm = cls;
983 
985  "No response from monitor since %s\n",
989  zm);
990 }
991 
992 
998 static void
1000 {
1001  const struct RecordStoreMessage *rp_msg = sa->rsm;
1002  unsigned int rd_count;
1003  size_t name_len;
1004  size_t rd_ser_len;
1005  uint32_t rid;
1006  const char *name_tmp;
1007  const char *rd_ser;
1008 
1009  rid = ntohl (rp_msg->gns_header.r_id);
1010  name_len = ntohs (rp_msg->name_len);
1011  rd_count = ntohs (rp_msg->rd_count);
1012  rd_ser_len = ntohs (rp_msg->rd_len);
1013  name_tmp = (const char *) &rp_msg[1];
1014  rd_ser = &name_tmp[name_len];
1015  {
1016  struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
1017 
1018  /* We did this before, must succeed again */
1019  GNUNET_assert (
1020  GNUNET_OK ==
1021  GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count, rd));
1022 
1023  for (struct ZoneMonitor *zm = sa->zm_pos; NULL != zm; zm = sa->zm_pos)
1024  {
1025  if ((0 != GNUNET_memcmp (&rp_msg->private_key, &zm->zone)) &&
1026  (0 != GNUNET_memcmp (&zm->zone, &zero)))
1027  {
1028  sa->zm_pos = zm->next; /* not interesting to this monitor */
1029  continue;
1030  }
1031  if (zm->limit == zm->iteration_cnt)
1032  {
1033  zm->sa_waiting = GNUNET_YES;
1034  zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
1035  if (NULL != zm->sa_wait_warning)
1036  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
1037  zm->sa_wait_warning =
1040  zm);
1041  return; /* blocked on zone monitor */
1042  }
1044  "Notifying monitor about changes under label `%s'\n",
1045  sa->conv_name);
1046  zm->limit--;
1047  send_lookup_response (zm->nc,
1048  0,
1049  &rp_msg->private_key,
1050  sa->conv_name,
1051  rd_count,
1052  rd);
1053  sa->zm_pos = zm->next;
1054  }
1055  /* great, done with the monitors, unpack (again) for refresh_block operation */
1056  refresh_block (sa->nc,
1057  NULL,
1058  rid,
1059  &rp_msg->private_key,
1060  sa->conv_name,
1061  rd_count,
1062  rd);
1063  }
1065  free_store_activity (sa);
1066 }
1067 
1068 
1077 static void
1079  struct GNUNET_SERVICE_Client *client,
1080  void *app_ctx)
1081 {
1082  struct NamestoreClient *nc = app_ctx;
1083  struct ZoneIteration *no;
1084  struct CacheOperation *cop;
1085 
1086  (void) cls;
1087  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
1088  for (struct ZoneMonitor *zm = monitor_head; NULL != zm; zm = zm->next)
1089  {
1090  struct StoreActivity *san;
1091 
1092  if (nc != zm->nc)
1093  continue;
1094  GNUNET_CONTAINER_DLL_remove (monitor_head, monitor_tail, zm);
1095  if (NULL != zm->task)
1096  {
1097  GNUNET_SCHEDULER_cancel (zm->task);
1098  zm->task = NULL;
1099  }
1100  if (NULL != zm->sa_wait_warning)
1101  {
1102  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
1103  zm->sa_wait_warning = NULL;
1104  }
1105  for (struct StoreActivity *sa = sa_head; NULL != sa; sa = san)
1106  {
1107  san = sa->next;
1108  if (zm == sa->zm_pos)
1109  {
1110  sa->zm_pos = zm->next;
1111  /* this may free sa */
1113  }
1114  }
1115  GNUNET_free (zm);
1116  break;
1117  }
1118  for (struct StoreActivity *sa = sa_head; NULL != sa; sa = sa->next)
1119  {
1120  if (sa->nc == nc)
1121  {
1122  /* this may free sa */
1123  free_store_activity (sa);
1124  break; /* there can only be one per nc */
1125  }
1126  }
1127  while (NULL != (no = nc->op_head))
1128  {
1130  GNUNET_free (no);
1131  }
1132  for (cop = cop_head; NULL != cop; cop = cop->next)
1133  if (nc == cop->nc)
1134  cop->nc = NULL;
1135  GNUNET_free (nc);
1136 }
1137 
1138 
1147 static void *
1149  struct GNUNET_SERVICE_Client *client,
1150  struct GNUNET_MQ_Handle *mq)
1151 {
1152  struct NamestoreClient *nc;
1153 
1154  (void) cls;
1155  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1156  nc = GNUNET_new (struct NamestoreClient);
1157  nc->client = client;
1158  nc->mq = mq;
1159  return nc;
1160 }
1161 
1162 
1167 {
1171  const char *label;
1172 
1176  char *res_rd;
1177 
1182 
1186  int found;
1187 
1191  unsigned int res_rd_count;
1192 
1196  ssize_t rd_ser_len;
1197 };
1198 
1199 
1212 static void
1213 lookup_it (void *cls,
1214  uint64_t seq,
1215  const struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key,
1216  const char *label,
1217  unsigned int rd_count,
1218  const struct GNUNET_GNSRECORD_Data *rd)
1219 {
1220  struct RecordLookupContext *rlc = cls;
1221 
1222  (void) private_key;
1223  GNUNET_assert (0 != seq);
1224  if (0 != strcmp (label, rlc->label))
1225  return;
1226  rlc->found = GNUNET_YES;
1227  if (0 == rd_count)
1228  {
1229  rlc->rd_ser_len = 0;
1230  rlc->res_rd_count = 0;
1231  rlc->res_rd = NULL;
1232  return;
1233  }
1234  if ((NULL != rlc->nick) && (0 != strcmp (label, GNUNET_GNS_EMPTY_LABEL_AT)))
1235  {
1236  /* Merge */
1237  struct GNUNET_GNSRECORD_Data *rd_res;
1238  unsigned int rdc_res;
1239 
1240  rd_res = NULL;
1241  rdc_res = 0;
1242  rlc->nick->flags = (rlc->nick->flags | GNUNET_GNSRECORD_RF_PRIVATE)
1244  merge_with_nick_records (rlc->nick, rd_count, rd, &rdc_res, &rd_res);
1245  rlc->rd_ser_len = GNUNET_GNSRECORD_records_get_size (rdc_res, rd_res);
1246  if (rlc->rd_ser_len < 0)
1247  {
1248  GNUNET_break (0);
1249  GNUNET_free (rd_res);
1250  rlc->found = GNUNET_NO;
1251  rlc->rd_ser_len = 0;
1252  return;
1253  }
1254  rlc->res_rd_count = rdc_res;
1255  rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1256  if (rlc->rd_ser_len != GNUNET_GNSRECORD_records_serialize (rdc_res,
1257  rd_res,
1258  rlc->rd_ser_len,
1259  rlc->res_rd))
1260  {
1261  GNUNET_break (0);
1262  GNUNET_free (rlc->res_rd);
1263  rlc->res_rd = NULL;
1264  rlc->res_rd_count = 0;
1265  rlc->rd_ser_len = 0;
1266  GNUNET_free (rd_res);
1267  rlc->found = GNUNET_NO;
1268  return;
1269  }
1270  GNUNET_free (rd_res);
1271  GNUNET_free (rlc->nick);
1272  rlc->nick = NULL;
1273  }
1274  else
1275  {
1276  rlc->rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1277  if (rlc->rd_ser_len < 0)
1278  {
1279  GNUNET_break (0);
1280  rlc->found = GNUNET_NO;
1281  rlc->rd_ser_len = 0;
1282  return;
1283  }
1284  rlc->res_rd_count = rd_count;
1285  rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1286  if (rlc->rd_ser_len != GNUNET_GNSRECORD_records_serialize (rd_count,
1287  rd,
1288  rlc->rd_ser_len,
1289  rlc->res_rd))
1290  {
1291  GNUNET_break (0);
1292  GNUNET_free (rlc->res_rd);
1293  rlc->res_rd = NULL;
1294  rlc->res_rd_count = 0;
1295  rlc->rd_ser_len = 0;
1296  rlc->found = GNUNET_NO;
1297  return;
1298  }
1299  }
1300 }
1301 
1302 
1310 static int
1311 check_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
1312 {
1313  uint32_t name_len;
1314  size_t src_size;
1315 
1316  (void) cls;
1317  name_len = ntohl (ll_msg->label_len);
1318  src_size = ntohs (ll_msg->gns_header.header.size);
1319  if (name_len != src_size - sizeof(struct LabelLookupMessage))
1320  {
1321  GNUNET_break (0);
1322  return GNUNET_SYSERR;
1323  }
1325  return GNUNET_OK;
1326 }
1327 
1328 
1335 static void
1336 handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
1337 {
1338  struct NamestoreClient *nc = cls;
1339  struct GNUNET_MQ_Envelope *env;
1340  struct LabelLookupResponseMessage *llr_msg;
1341  struct RecordLookupContext rlc;
1342  const char *name_tmp;
1343  char *res_name;
1344  char *conv_name;
1345  uint32_t name_len;
1346  int res;
1347 
1348  name_len = ntohl (ll_msg->label_len);
1349  name_tmp = (const char *) &ll_msg[1];
1352  "Received NAMESTORE_RECORD_LOOKUP message for name `%s'\n",
1353  name_tmp);
1354 
1355  conv_name = GNUNET_GNSRECORD_string_to_lowercase (name_tmp);
1356  if (NULL == conv_name)
1357  {
1359  "Error converting name `%s'\n",
1360  name_tmp);
1362  return;
1363  }
1364  rlc.label = conv_name;
1365  rlc.found = GNUNET_NO;
1366  rlc.res_rd_count = 0;
1367  rlc.res_rd = NULL;
1368  rlc.rd_ser_len = 0;
1369  rlc.nick = get_nick_record (&ll_msg->zone);
1370  res = GSN_database->lookup_records (GSN_database->cls,
1371  &ll_msg->zone,
1372  conv_name,
1373  &lookup_it,
1374  &rlc);
1375  GNUNET_free (conv_name);
1376  env =
1377  GNUNET_MQ_msg_extra (llr_msg,
1378  name_len + rlc.rd_ser_len,
1380  llr_msg->gns_header.r_id = ll_msg->gns_header.r_id;
1381  llr_msg->private_key = ll_msg->zone;
1382  llr_msg->name_len = htons (name_len);
1383  llr_msg->rd_count = htons (rlc.res_rd_count);
1384  llr_msg->rd_len = htons (rlc.rd_ser_len);
1385  res_name = (char *) &llr_msg[1];
1386  if ((GNUNET_YES == rlc.found) && (GNUNET_OK == res))
1387  llr_msg->found = ntohs (GNUNET_YES);
1388  else
1389  llr_msg->found = ntohs (GNUNET_NO);
1390  GNUNET_memcpy (&llr_msg[1], name_tmp, name_len);
1391  GNUNET_memcpy (&res_name[name_len], rlc.res_rd, rlc.rd_ser_len);
1392  GNUNET_MQ_send (nc->mq, env);
1394 }
1395 
1396 
1404 static int
1405 check_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1406 {
1407  size_t name_len;
1408  size_t msg_size;
1409  size_t msg_size_exp;
1410  size_t rd_ser_len;
1411  const char *name_tmp;
1412 
1413  (void) cls;
1414  name_len = ntohs (rp_msg->name_len);
1415  msg_size = ntohs (rp_msg->gns_header.header.size);
1416  rd_ser_len = ntohs (rp_msg->rd_len);
1417  msg_size_exp = sizeof(struct RecordStoreMessage) + name_len + rd_ser_len;
1418  if (msg_size != msg_size_exp)
1419  {
1420  GNUNET_break (0);
1421  return GNUNET_SYSERR;
1422  }
1423  if ((0 == name_len) || (name_len > MAX_NAME_LEN))
1424  {
1425  GNUNET_break (0);
1426  return GNUNET_SYSERR;
1427  }
1428  name_tmp = (const char *) &rp_msg[1];
1429  if ('\0' != name_tmp[name_len - 1])
1430  {
1431  GNUNET_break (0);
1432  return GNUNET_SYSERR;
1433  }
1434  return GNUNET_OK;
1435 }
1436 
1437 
1444 static void
1445 handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1446 {
1447  struct NamestoreClient *nc = cls;
1448  size_t name_len;
1449  size_t rd_ser_len;
1450  uint32_t rid;
1451  const char *name_tmp;
1452  char *conv_name;
1453  const char *rd_ser;
1454  unsigned int rd_count;
1455  int res;
1456  struct StoreActivity *sa;
1457 
1459  "Received NAMESTORE_RECORD_STORE message\n");
1460  rid = ntohl (rp_msg->gns_header.r_id);
1461  name_len = ntohs (rp_msg->name_len);
1462  rd_count = ntohs (rp_msg->rd_count);
1463  rd_ser_len = ntohs (rp_msg->rd_len);
1464  GNUNET_break (0 == ntohs (rp_msg->reserved));
1465  name_tmp = (const char *) &rp_msg[1];
1466  rd_ser = &name_tmp[name_len];
1467  {
1468  struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
1469 
1470  if (GNUNET_OK !=
1471  GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count, rd))
1472  {
1473  GNUNET_break (0);
1475  return;
1476  }
1477 
1478  /* Extracting and converting private key */
1479  conv_name = GNUNET_GNSRECORD_string_to_lowercase (name_tmp);
1480  if (NULL == conv_name)
1481  {
1483  "Error converting name `%s'\n",
1484  name_tmp);
1486  return;
1487  }
1488  GNUNET_STATISTICS_update (statistics,
1489  "Well-formed store requests received",
1490  1,
1491  GNUNET_NO);
1493  "Creating %u records for name `%s'\n",
1494  (unsigned int) rd_count,
1495  conv_name);
1496  if ((0 == rd_count) &&
1497  (GNUNET_NO == GSN_database->lookup_records (GSN_database->cls,
1498  &rp_msg->private_key,
1499  conv_name,
1500  NULL,
1501  0)))
1502  {
1503  /* This name does not exist, so cannot be removed */
1505  "Name `%s' does not exist, no deletion required\n",
1506  conv_name);
1507  res = GNUNET_NO;
1508  }
1509  else
1510  {
1511  /* remove "NICK" records, unless this is for the
1512  #GNUNET_GNS_EMPTY_LABEL_AT label */
1513  struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL (rd_count)];
1514  unsigned int rd_clean_off;
1515  int have_nick;
1516 
1517  rd_clean_off = 0;
1518  have_nick = GNUNET_NO;
1519  for (unsigned int i = 0; i < rd_count; i++)
1520  {
1521  rd_clean[rd_clean_off] = rd[i];
1522  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) ||
1524  rd_clean_off++;
1525 
1526  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1527  (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type))
1528  {
1529  cache_nick (&rp_msg->private_key, &rd[i]);
1530  have_nick = GNUNET_YES;
1531  }
1532  }
1533  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1534  (GNUNET_NO == have_nick))
1535  {
1536  /* remove nick record from cache, in case we have one there */
1537  cache_nick (&rp_msg->private_key, NULL);
1538  }
1539  res = GSN_database->store_records (GSN_database->cls,
1540  &rp_msg->private_key,
1541  conv_name,
1542  rd_clean_off,
1543  rd_clean);
1544  }
1545 
1546  if (GNUNET_OK != res)
1547  {
1548  /* store not successful, not need to tell monitors */
1549  send_store_response (nc, res, rid);
1551  GNUNET_free (conv_name);
1552  return;
1553  }
1554 
1555  sa = GNUNET_malloc (sizeof(struct StoreActivity)
1556  + ntohs (rp_msg->gns_header.header.size));
1557  GNUNET_CONTAINER_DLL_insert (sa_head, sa_tail, sa);
1558  sa->nc = nc;
1559  sa->rsm = (const struct RecordStoreMessage *) &sa[1];
1560  GNUNET_memcpy (&sa[1], rp_msg, ntohs (rp_msg->gns_header.header.size));
1561  sa->zm_pos = monitor_head;
1562  sa->conv_name = conv_name;
1564  }
1565 }
1566 
1567 
1573 {
1578 
1582  uint32_t rid;
1583 
1589  int success;
1590 };
1591 
1592 
1603 static void
1605  uint64_t seq,
1606  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
1607  const char *name,
1608  unsigned int rd_count,
1609  const struct GNUNET_GNSRECORD_Data *rd)
1610 {
1611  struct ZoneToNameCtx *ztn_ctx = cls;
1612  struct GNUNET_MQ_Envelope *env;
1613  struct ZoneToNameResponseMessage *ztnr_msg;
1614  int16_t res;
1615  size_t name_len;
1616  ssize_t rd_ser_len;
1617  size_t msg_size;
1618  char *name_tmp;
1619  char *rd_tmp;
1620 
1621  GNUNET_assert (0 != seq);
1623  "Found result for zone-to-name lookup: `%s'\n",
1624  name);
1625  res = GNUNET_YES;
1626  name_len = (NULL == name) ? 0 : strlen (name) + 1;
1627  rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1628  if (rd_ser_len < 0)
1629  {
1630  GNUNET_break (0);
1631  ztn_ctx->success = GNUNET_SYSERR;
1632  return;
1633  }
1634  msg_size = sizeof(struct ZoneToNameResponseMessage) + name_len + rd_ser_len;
1635  if (msg_size >= GNUNET_MAX_MESSAGE_SIZE)
1636  {
1637  GNUNET_break (0);
1638  ztn_ctx->success = GNUNET_SYSERR;
1639  return;
1640  }
1641  env =
1642  GNUNET_MQ_msg_extra (ztnr_msg,
1643  name_len + rd_ser_len,
1645  ztnr_msg->gns_header.header.size = htons (msg_size);
1646  ztnr_msg->gns_header.r_id = htonl (ztn_ctx->rid);
1647  ztnr_msg->res = htons (res);
1648  ztnr_msg->rd_len = htons (rd_ser_len);
1649  ztnr_msg->rd_count = htons (rd_count);
1650  ztnr_msg->name_len = htons (name_len);
1651  ztnr_msg->zone = *zone_key;
1652  name_tmp = (char *) &ztnr_msg[1];
1653  GNUNET_memcpy (name_tmp, name, name_len);
1654  rd_tmp = &name_tmp[name_len];
1655  GNUNET_assert (
1656  rd_ser_len ==
1657  GNUNET_GNSRECORD_records_serialize (rd_count, rd, rd_ser_len, rd_tmp));
1658  ztn_ctx->success = GNUNET_OK;
1659  GNUNET_MQ_send (ztn_ctx->nc->mq, env);
1660 }
1661 
1662 
1669 static void
1670 handle_zone_to_name (void *cls, const struct ZoneToNameMessage *ztn_msg)
1671 {
1672  struct NamestoreClient *nc = cls;
1673  struct ZoneToNameCtx ztn_ctx;
1674  struct GNUNET_MQ_Envelope *env;
1675  struct ZoneToNameResponseMessage *ztnr_msg;
1676 
1677  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_TO_NAME message\n");
1678  ztn_ctx.rid = ntohl (ztn_msg->gns_header.r_id);
1679  ztn_ctx.nc = nc;
1680  ztn_ctx.success = GNUNET_NO;
1681  if (GNUNET_SYSERR == GSN_database->zone_to_name (GSN_database->cls,
1682  &ztn_msg->zone,
1683  &ztn_msg->value_zone,
1685  &ztn_ctx))
1686  {
1687  /* internal error, hang up instead of signalling something
1688  that might be wrong */
1689  GNUNET_break (0);
1691  return;
1692  }
1693  if (GNUNET_NO == ztn_ctx.success)
1694  {
1695  /* no result found, send empty response */
1697  "Found no result for zone-to-name lookup.\n");
1698  env = GNUNET_MQ_msg (ztnr_msg,
1700  ztnr_msg->gns_header.r_id = ztn_msg->gns_header.r_id;
1701  ztnr_msg->res = htons (GNUNET_NO);
1702  GNUNET_MQ_send (nc->mq, env);
1703  }
1705 }
1706 
1707 
1713 {
1718 
1722  uint64_t limit;
1723 };
1724 
1725 
1736 static void
1738  uint64_t seq,
1739  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
1740  const char *name,
1741  unsigned int rd_count,
1742  const struct GNUNET_GNSRECORD_Data *rd)
1743 {
1744  struct ZoneIterationProcResult *proc = cls;
1745  int do_refresh_block;
1746 
1747  GNUNET_assert (0 != seq);
1748  if ((NULL == zone_key) && (NULL == name))
1749  {
1750  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
1751  return;
1752  }
1753  if ((NULL == zone_key) || (NULL == name))
1754  {
1755  /* what is this!? should never happen */
1756  GNUNET_break (0);
1757  return;
1758  }
1759  if (0 == proc->limit)
1760  {
1761  /* what is this!? should never happen */
1762  GNUNET_break (0);
1763  return;
1764  }
1765  proc->limit--;
1766  proc->zi->seq = seq;
1767  send_lookup_response (proc->zi->nc,
1768  proc->zi->request_id,
1769  zone_key,
1770  name,
1771  rd_count,
1772  rd);
1773 
1774 
1775  do_refresh_block = GNUNET_NO;
1776  for (unsigned int i = 0; i < rd_count; i++)
1777  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
1778  {
1779  do_refresh_block = GNUNET_YES;
1780  break;
1781  }
1782  if (GNUNET_YES == do_refresh_block)
1783  refresh_block (NULL, proc->zi, 0, zone_key, name, rd_count, rd);
1784 }
1785 
1786 
1793 static void
1795 {
1796  struct ZoneIterationProcResult proc;
1797  struct GNUNET_TIME_Absolute start;
1798  struct GNUNET_TIME_Relative duration;
1799 
1800  memset (&proc, 0, sizeof(proc));
1802  "Asked to return up to %llu records at position %llu\n",
1803  (unsigned long long) limit,
1804  (unsigned long long) zi->seq);
1805  proc.zi = zi;
1806  proc.limit = limit;
1807  start = GNUNET_TIME_absolute_get ();
1809  GSN_database->iterate_records (GSN_database->cls,
1810  (0 == GNUNET_is_zero (&zi->zone))
1811  ? NULL
1812  : &zi->zone,
1813  zi->seq,
1814  limit,
1816  &proc));
1817  duration = GNUNET_TIME_absolute_get_duration (start);
1818  duration = GNUNET_TIME_relative_divide (duration, limit - proc.limit);
1819  GNUNET_STATISTICS_set (statistics,
1820  "NAMESTORE iteration delay (μs/record)",
1821  duration.rel_value_us,
1822  GNUNET_NO);
1823  if (0 == proc.limit)
1825  "Returned %llu results, more results available\n",
1826  (unsigned long long) limit);
1827  zi->send_end = (0 != proc.limit);
1828  if (0 == zi->cache_ops)
1830 }
1831 
1832 
1839 static void
1841  const struct ZoneIterationStartMessage *zis_msg)
1842 {
1843  struct NamestoreClient *nc = cls;
1844  struct ZoneIteration *zi;
1845 
1847  "Received ZONE_ITERATION_START message\n");
1848  zi = GNUNET_new (struct ZoneIteration);
1849  zi->request_id = ntohl (zis_msg->gns_header.r_id);
1850  zi->offset = 0;
1851  zi->nc = nc;
1852  zi->zone = zis_msg->zone;
1853 
1855  run_zone_iteration_round (zi, 1);
1856 }
1857 
1858 
1865 static void
1867  const struct ZoneIterationStopMessage *zis_msg)
1868 {
1869  struct NamestoreClient *nc = cls;
1870  struct ZoneIteration *zi;
1871  uint32_t rid;
1872 
1874  "Received ZONE_ITERATION_STOP message\n");
1875  rid = ntohl (zis_msg->gns_header.r_id);
1876  for (zi = nc->op_head; NULL != zi; zi = zi->next)
1877  if (zi->request_id == rid)
1878  break;
1879  if (NULL == zi)
1880  {
1881  GNUNET_break (0);
1883  return;
1884  }
1886  GNUNET_free (zi);
1888 }
1889 
1890 
1897 static void
1899  const struct ZoneIterationNextMessage *zis_msg)
1900 {
1901  struct NamestoreClient *nc = cls;
1902  struct ZoneIteration *zi;
1903  uint32_t rid;
1904  uint64_t limit;
1905 
1907  "Received ZONE_ITERATION_NEXT message\n");
1908  GNUNET_STATISTICS_update (statistics,
1909  "Iteration NEXT messages received",
1910  1,
1911  GNUNET_NO);
1912  rid = ntohl (zis_msg->gns_header.r_id);
1913  limit = GNUNET_ntohll (zis_msg->limit);
1914  for (zi = nc->op_head; NULL != zi; zi = zi->next)
1915  if (zi->request_id == rid)
1916  break;
1917  if (NULL == zi)
1918  {
1919  GNUNET_break (0);
1921  return;
1922  }
1923  run_zone_iteration_round (zi, limit);
1924 }
1925 
1926 
1932 static void
1934 {
1935  struct StoreActivity *sa = sa_head;
1936 
1937  while ((NULL != sa) && (zm->limit > zm->iteration_cnt))
1938  {
1939  struct StoreActivity *sn = sa->next;
1940 
1941  if (sa->zm_pos == zm)
1943  sa = sn;
1944  }
1945  if (zm->limit > zm->iteration_cnt)
1946  {
1947  zm->sa_waiting = GNUNET_NO;
1948  if (NULL != zm->sa_wait_warning)
1949  {
1951  zm->sa_wait_warning = NULL;
1952  }
1953  }
1954  else if (GNUNET_YES == zm->sa_waiting)
1955  {
1957  if (NULL != zm->sa_wait_warning)
1959  zm->sa_wait_warning =
1962  zm);
1963  }
1964 }
1965 
1966 
1972 static void
1974 {
1975  struct GNUNET_MQ_Envelope *env;
1976  struct GNUNET_MessageHeader *sync;
1977 
1979  GNUNET_MQ_send (zm->nc->mq, env);
1980  /* mark iteration done */
1982  zm->iteration_cnt = 0;
1983  if ((zm->limit > 0) && (zm->sa_waiting))
1984  monitor_unblock (zm);
1985 }
1986 
1987 
1993 static void
1994 monitor_iteration_next (void *cls);
1995 
1996 
2007 static void
2009  uint64_t seq,
2010  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
2011  const char *name,
2012  unsigned int rd_count,
2013  const struct GNUNET_GNSRECORD_Data *rd)
2014 {
2015  struct ZoneMonitor *zm = cls;
2016 
2017  GNUNET_assert (0 != seq);
2018  zm->seq = seq;
2019  GNUNET_assert (NULL != name);
2020  GNUNET_STATISTICS_update (statistics,
2021  "Monitor notifications sent",
2022  1,
2023  GNUNET_NO);
2024  zm->limit--;
2025  zm->iteration_cnt--;
2026  send_lookup_response (zm->nc, 0, zone_key, name, rd_count, rd);
2027  if ((0 == zm->iteration_cnt) && (0 != zm->limit))
2028  {
2029  /* We are done with the current iteration batch, AND the
2030  client would right now accept more, so go again! */
2031  GNUNET_assert (NULL == zm->task);
2033  }
2034 }
2035 
2036 
2043 static void
2044 handle_monitor_start (void *cls, const struct ZoneMonitorStartMessage *zis_msg)
2045 {
2046  struct NamestoreClient *nc = cls;
2047  struct ZoneMonitor *zm;
2048 
2049  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_MONITOR_START message\n");
2050  zm = GNUNET_new (struct ZoneMonitor);
2051  zm->nc = nc;
2052  zm->zone = zis_msg->zone;
2053  zm->limit = 1;
2054  zm->in_first_iteration = (GNUNET_YES == ntohl (zis_msg->iterate_first));
2055  GNUNET_CONTAINER_DLL_insert (monitor_head, monitor_tail, zm);
2058  GNUNET_notification_context_add (monitor_nc, nc->mq);
2059  if (zm->in_first_iteration)
2061  else
2062  monitor_sync (zm);
2063 }
2064 
2065 
2071 static void
2073 {
2074  struct ZoneMonitor *zm = cls;
2075  int ret;
2076 
2077  zm->task = NULL;
2078  GNUNET_assert (0 == zm->iteration_cnt);
2079  if (zm->limit > 16)
2080  zm->iteration_cnt = zm->limit / 2; /* leave half for monitor events */
2081  else
2082  zm->iteration_cnt = zm->limit; /* use it all */
2083  ret = GSN_database->iterate_records (GSN_database->cls,
2084  (0 == GNUNET_is_zero (&zm->zone))
2085  ? NULL
2086  : &zm->zone,
2087  zm->seq,
2088  zm->iteration_cnt,
2090  zm);
2091  if (GNUNET_SYSERR == ret)
2092  {
2094  return;
2095  }
2096  if (GNUNET_NO == ret)
2097  {
2098  /* empty zone */
2099  monitor_sync (zm);
2100  return;
2101  }
2102 }
2103 
2104 
2111 static void
2112 handle_monitor_next (void *cls, const struct ZoneMonitorNextMessage *nm)
2113 {
2114  struct NamestoreClient *nc = cls;
2115  struct ZoneMonitor *zm;
2116  uint64_t inc;
2117 
2118  inc = GNUNET_ntohll (nm->limit);
2120  "Received ZONE_MONITOR_NEXT message with limit %llu\n",
2121  (unsigned long long) inc);
2122  for (zm = monitor_head; NULL != zm; zm = zm->next)
2123  if (zm->nc == nc)
2124  break;
2125  if (NULL == zm)
2126  {
2127  GNUNET_break (0);
2129  return;
2130  }
2132  if (zm->limit + inc < zm->limit)
2133  {
2134  GNUNET_break (0);
2136  return;
2137  }
2138  zm->limit += inc;
2139  if ((zm->in_first_iteration) && (zm->limit == inc))
2140  {
2141  /* We are still iterating, and the previous iteration must
2142  have stopped due to the client's limit, so continue it! */
2143  GNUNET_assert (NULL == zm->task);
2145  }
2146  GNUNET_assert (zm->iteration_cnt <= zm->limit);
2147  if ((zm->limit > zm->iteration_cnt) && (zm->sa_waiting))
2148  {
2149  monitor_unblock (zm);
2150  }
2151  else if (GNUNET_YES == zm->sa_waiting)
2152  {
2153  if (NULL != zm->sa_wait_warning)
2156  zm->sa_wait_warning =
2159  zm);
2160  }
2161 }
2162 
2163 
2171 static void
2172 run (void *cls,
2173  const struct GNUNET_CONFIGURATION_Handle *cfg,
2175 {
2176  char *database;
2177 
2178  (void) cls;
2179  (void) service;
2180  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n");
2181  cache_keys =
2182  GNUNET_CONFIGURATION_get_value_yesno (cfg, "namestore", "CACHE_KEYS");
2184  GNUNET_CONFIGURATION_get_value_yesno (cfg, "namecache", "DISABLE");
2185  GSN_cfg = cfg;
2186  monitor_nc = GNUNET_notification_context_create (1);
2188  {
2189  namecache = GNUNET_NAMECACHE_connect (cfg);
2190  GNUNET_assert (NULL != namecache);
2191  }
2192  /* Loading database plugin */
2194  "namestore",
2195  "database",
2196  &database))
2197  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
2198 
2199  GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
2200  GSN_database = GNUNET_PLUGIN_load (db_lib_name, (void *) GSN_cfg);
2201  GNUNET_free (database);
2202  statistics = GNUNET_STATISTICS_create ("namestore", cfg);
2204  if (NULL == GSN_database)
2205  {
2207  "Could not load database backend `%s'\n",
2208  db_lib_name);
2210  return;
2211  }
2212 }
2213 
2214 
2219  "namestore",
2221  &run,
2224  NULL,
2225  GNUNET_MQ_hd_var_size (record_store,
2227  struct RecordStoreMessage,
2228  NULL),
2229  GNUNET_MQ_hd_var_size (record_lookup,
2231  struct LabelLookupMessage,
2232  NULL),
2235  struct ZoneToNameMessage,
2236  NULL),
2240  NULL),
2241  GNUNET_MQ_hd_fixed_size (iteration_next,
2243  struct ZoneIterationNextMessage,
2244  NULL),
2245  GNUNET_MQ_hd_fixed_size (iteration_stop,
2247  struct ZoneIterationStopMessage,
2248  NULL),
2249  GNUNET_MQ_hd_fixed_size (monitor_start,
2251  struct ZoneMonitorStartMessage,
2252  NULL),
2253  GNUNET_MQ_hd_fixed_size (monitor_next,
2255  struct ZoneMonitorNextMessage,
2256  NULL),
2258 
2259 
2260 /* 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:1300
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.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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:526
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:181
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:1253
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:1280
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:2407
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:2324
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_SYSERR
Definition: gnunet_common.h:76
#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:239
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:85
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.
#define GNUNET_YES
Definition: gnunet_common.h:77
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:353
#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 flag is currently unused; former RF_PENDING flag.
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:742
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:2243
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:48
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:966
#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...