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 
128 {
133 
138 
144 
150 };
151 
152 
157 {
161  struct ZoneMonitor *next;
162 
166  struct ZoneMonitor *prev;
167 
172 
177 
182 
187 
192 
200  uint64_t seq;
201 
206  uint64_t limit;
207 
214  uint64_t iteration_cnt;
215 
220 
228 };
229 
230 
235 {
240 
245 
250 
255 
260  struct ZoneIteration *zi;
261 
265  uint32_t rid;
266 };
267 
268 
274 {
279 
284 
289 
294  const struct RecordStoreMessage *rsm;
295 
300 
304  char *conv_name;
305 };
306 
307 
311 struct NickCache
312 {
317 
322 
327 };
328 
329 
333 static struct NickCache nick_cache[NC_SIZE];
334 
338 static const struct GNUNET_IDENTITY_PrivateKey zero;
339 
344 
349 
354 
359 
363 static char *db_lib_name;
364 
368 static struct CacheOperation *cop_head;
369 
373 static struct CacheOperation *cop_tail;
374 
378 static struct ZoneMonitor *monitor_head;
379 
383 static struct ZoneMonitor *monitor_tail;
384 
388 static struct StoreActivity *sa_head;
389 
393 static struct StoreActivity *sa_tail;
394 
399 
404 static int cache_keys;
405 
410 static int disable_namecache;
411 
412 
418 static void
419 cleanup_task (void *cls)
420 {
421  struct CacheOperation *cop;
422 
423  (void) cls;
424  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n");
425  while (NULL != (cop = cop_head))
426  {
428  "Aborting incomplete namecache operation\n");
431  GNUNET_free (cop);
432  }
433 
434  if (NULL != namecache)
435  {
437  namecache = NULL;
438  }
441  db_lib_name = NULL;
442  if (NULL != monitor_nc)
443  {
445  monitor_nc = NULL;
446  }
447  if (NULL != statistics)
448  {
450  statistics = NULL;
451  }
452 }
453 
454 
460 static void
462 {
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_IDENTITY_PrivateKey *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 (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 {
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;
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",
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_IDENTITY_PrivateKey *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  }
747  else
748  {
749  res_count = rd_count;
750  res = (struct GNUNET_GNSRECORD_Data *) rd;
751  }
752  if (NULL != nick)
753  GNUNET_free (nick);
754 
756 
757 
758  name_len = strlen (name) + 1;
759  rd_ser_len = GNUNET_GNSRECORD_records_get_size (res_count, res);
760  if (rd_ser_len < 0)
761  {
762  if (rd != res)
763  GNUNET_free (res);
764  GNUNET_break (0);
765  GNUNET_SERVICE_client_drop (nc->client);
766  return;
767  }
768  if (((size_t) rd_ser_len) >= UINT16_MAX - name_len - sizeof(*zir_msg))
769  {
770  if (rd != res)
771  GNUNET_free (res);
772  GNUNET_break (0);
773  GNUNET_SERVICE_client_drop (nc->client);
774  return;
775  }
776  env = GNUNET_MQ_msg_extra (zir_msg,
777  name_len + rd_ser_len,
779  zir_msg->gns_header.r_id = htonl (request_id);
780  zir_msg->name_len = htons (name_len);
781  zir_msg->rd_count = htons (res_count);
782  zir_msg->rd_len = htons ((uint16_t) rd_ser_len);
783  zir_msg->private_key = *zone_key;
784  name_tmp = (char *) &zir_msg[1];
785  GNUNET_memcpy (name_tmp, name, name_len);
786  rd_ser = &name_tmp[name_len];
787  GNUNET_assert (
788  rd_ser_len ==
789  GNUNET_GNSRECORD_records_serialize (res_count, res, rd_ser_len, rd_ser));
791  "Sending RECORD_RESULT message with %u records\n",
792  res_count);
794  "Record sets sent to clients",
795  1,
796  GNUNET_NO);
797  GNUNET_MQ_send (nc->mq, env);
798  if (rd != res)
799  GNUNET_free (res);
800 }
801 
802 
810 static void
811 send_store_response (struct NamestoreClient *nc, int res, const char*emsg,
812  uint32_t rid)
813 {
814  struct GNUNET_MQ_Envelope *env;
815  struct RecordStoreResponseMessage *rcr_msg;
816 
817  GNUNET_assert (NULL != nc);
819  "Sending RECORD_STORE_RESPONSE message\n");
821  "Store requests completed",
822  1,
823  GNUNET_NO);
824  env = GNUNET_MQ_msg_extra (rcr_msg,
825  (NULL != emsg) ? strlen (emsg) + 1 : 0,
827  rcr_msg->gns_header.r_id = htonl (rid);
828  rcr_msg->op_result = htonl (res);
829  rcr_msg->reserved = htons (0);
830  if (NULL != emsg)
831  {
832  rcr_msg->emsg_len = htons (strlen (emsg) + 1);
833  memcpy (&rcr_msg[1], emsg, strlen (emsg) + 1);
834  }
835  GNUNET_MQ_send (nc->mq, env);
836 }
837 
838 
845 static void
847 {
848  struct GNUNET_MQ_Envelope *env;
849  struct GNUNET_NAMESTORE_Header *em;
850 
852  if (! zi->send_end)
853  return;
854  /* send empty response to indicate end of list */
856  em->r_id = htonl (zi->request_id);
857  GNUNET_MQ_send (zi->nc->mq, env);
858 
860  GNUNET_free (zi);
861 }
862 
863 
871 static void
872 finish_cache_operation (void *cls, int32_t success, const char *emsg)
873 {
874  struct CacheOperation *cop = cls;
875  struct ZoneIteration *zi;
876 
877  if (NULL != emsg)
879  _ ("Failed to replicate block in namecache: %s\n"),
880  emsg);
881  else
882  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n");
884  if (NULL != cop->nc)
885  send_store_response (cop->nc, success, emsg, cop->rid);
886  if (NULL != (zi = cop->zi))
887  {
888  zi->cache_ops--;
889  if (0 == zi->cache_ops)
890  {
891  /* unchoke zone iteration, cache has caught up */
893  }
894  }
895  GNUNET_free (cop);
896 }
897 
898 
911 static void
913  struct ZoneIteration *zi,
914  uint32_t rid,
915  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
916  const char *name,
917  unsigned int rd_count,
918  const struct GNUNET_GNSRECORD_Data *rd)
919 {
920  struct GNUNET_GNSRECORD_Block *block;
921  struct GNUNET_GNSRECORD_Data rd_clean[rd_count];
922  struct CacheOperation *cop;
924  struct GNUNET_GNSRECORD_Data *nick;
925  struct GNUNET_GNSRECORD_Data *res;
926  unsigned int res_count;
927  unsigned int rd_count_clean;
928  struct GNUNET_TIME_Absolute exp_time;
929 
931  rd_count_clean = 0;
932  for (int i = 0; i < rd_count; i++)
933  {
934  if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type)
935  continue;
936  rd_clean[rd_count_clean++] = rd[i];
937  }
938 
939  nick = get_nick_record (zone_key);
940  res_count = rd_count_clean;
941  res = (struct GNUNET_GNSRECORD_Data *) rd_clean; /* fixme: a bit unclean... */
942  if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT)))
943  {
944  nick->flags =
946  merge_with_nick_records (nick, rd_count_clean, rd_clean, &res_count, &res);
947  }
948  if (NULL != nick)
949  GNUNET_free (nick);
950  if (0 == res_count)
951  {
952  if (NULL != nc)
953  send_store_response (nc, GNUNET_OK, NULL, rid);
954  if (rd_clean != res)
955  GNUNET_free (res);
956  return; /* no data, no need to update cache */
957  }
959  {
961  "Namecache updates skipped (NC disabled)",
962  1,
963  GNUNET_NO);
964  if (NULL != nc)
965  send_store_response (nc, GNUNET_OK, NULL, rid);
966  if (rd_clean != res)
967  GNUNET_free (res);
968  return;
969  }
970  exp_time = GNUNET_GNSRECORD_record_get_expiration_time (res_count, res,
972  if (cache_keys)
975  res, res_count, &block));
976  else
979  res, res_count, &block));
980  GNUNET_assert (NULL != block);
982  GNUNET_log (
984  "Caching block for label `%s' with %u records and expiration %s in zone `%s' in namecache\n",
985  name,
986  res_count,
990  "Namecache updates pushed",
991  1,
992  GNUNET_NO);
993  cop = GNUNET_new (struct CacheOperation);
994  cop->nc = nc;
995  cop->zi = zi;
996  if (NULL != zi)
997  zi->cache_ops ++;
998  cop->rid = rid;
1001  block,
1003  cop);
1004  GNUNET_free (block);
1005  if (rd_clean != res)
1006  GNUNET_free (res);
1007 }
1008 
1009 
1015 static void
1017 {
1018  struct ZoneMonitor *zm = cls;
1019 
1021  "No response from monitor since %s\n",
1022  GNUNET_STRINGS_absolute_time_to_string (zm->sa_waiting_start));
1025  zm);
1026 }
1027 
1028 
1034 static void
1036 {
1037  const struct RecordStoreMessage *rp_msg = sa->rsm;
1038  unsigned int rd_count;
1039  size_t name_len;
1040  size_t rd_ser_len;
1041  uint32_t rid;
1042  const char *name_tmp;
1043  const char *rd_ser;
1044 
1045  rid = ntohl (rp_msg->gns_header.r_id);
1046  name_len = ntohs (rp_msg->name_len);
1047  rd_count = ntohs (rp_msg->rd_count);
1048  rd_ser_len = ntohs (rp_msg->rd_len);
1049  name_tmp = (const char *) &rp_msg[1];
1050  rd_ser = &name_tmp[name_len];
1051  {
1052  struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
1053 
1054  /* We did this before, must succeed again */
1055  GNUNET_assert (
1056  GNUNET_OK ==
1057  GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count, rd));
1058 
1059  for (struct ZoneMonitor *zm = sa->zm_pos; NULL != zm; zm = sa->zm_pos)
1060  {
1061  if ((0 != GNUNET_memcmp (&rp_msg->private_key, &zm->zone)) &&
1062  (0 != GNUNET_memcmp (&zm->zone, &zero)))
1063  {
1064  sa->zm_pos = zm->next; /* not interesting to this monitor */
1065  continue;
1066  }
1067  if (zm->limit == zm->iteration_cnt)
1068  {
1069  zm->sa_waiting = GNUNET_YES;
1070  zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
1071  if (NULL != zm->sa_wait_warning)
1072  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
1073  zm->sa_wait_warning =
1076  zm);
1077  return; /* blocked on zone monitor */
1078  }
1080  "Notifying monitor about changes under label `%s'\n",
1081  sa->conv_name);
1082  zm->limit--;
1083  send_lookup_response (zm->nc,
1084  0,
1085  &rp_msg->private_key,
1086  sa->conv_name,
1087  rd_count,
1088  rd);
1089  sa->zm_pos = zm->next;
1090  }
1091  /* great, done with the monitors, unpack (again) for refresh_block operation */
1092  refresh_block (sa->nc,
1093  NULL,
1094  rid,
1095  &rp_msg->private_key,
1096  sa->conv_name,
1097  rd_count,
1098  rd);
1099  }
1101  free_store_activity (sa);
1102 }
1103 
1104 
1113 static void
1115  struct GNUNET_SERVICE_Client *client,
1116  void *app_ctx)
1117 {
1118  struct NamestoreClient *nc = app_ctx;
1119  struct ZoneIteration *no;
1120  struct CacheOperation *cop;
1121 
1122  (void) cls;
1123  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
1124  for (struct ZoneMonitor *zm = monitor_head; NULL != zm; zm = zm->next)
1125  {
1126  struct StoreActivity *san;
1127 
1128  if (nc != zm->nc)
1129  continue;
1131  if (NULL != zm->task)
1132  {
1133  GNUNET_SCHEDULER_cancel (zm->task);
1134  zm->task = NULL;
1135  }
1136  if (NULL != zm->sa_wait_warning)
1137  {
1138  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
1139  zm->sa_wait_warning = NULL;
1140  }
1141  for (struct StoreActivity *sa = sa_head; NULL != sa; sa = san)
1142  {
1143  san = sa->next;
1144  if (zm == sa->zm_pos)
1145  {
1146  sa->zm_pos = zm->next;
1147  /* this may free sa */
1149  }
1150  }
1151  GNUNET_free (zm);
1152  break;
1153  }
1154  for (struct StoreActivity *sa = sa_head; NULL != sa; sa = sa->next)
1155  {
1156  if (sa->nc == nc)
1157  {
1158  /* this may free sa */
1159  free_store_activity (sa);
1160  break; /* there can only be one per nc */
1161  }
1162  }
1163  while (NULL != (no = nc->op_head))
1164  {
1165  GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no);
1166  GNUNET_free (no);
1167  }
1168  for (cop = cop_head; NULL != cop; cop = cop->next)
1169  if (nc == cop->nc)
1170  cop->nc = NULL;
1171  GNUNET_free (nc);
1172 }
1173 
1174 
1183 static void *
1185  struct GNUNET_SERVICE_Client *client,
1186  struct GNUNET_MQ_Handle *mq)
1187 {
1188  struct NamestoreClient *nc;
1189 
1190  (void) cls;
1191  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1192  nc = GNUNET_new (struct NamestoreClient);
1193  nc->client = client;
1194  nc->mq = mq;
1195  return nc;
1196 }
1197 
1198 
1203 {
1207  const char *label;
1208 
1212  char *res_rd;
1213 
1218 
1222  int found;
1223 
1227  unsigned int res_rd_count;
1228 
1232  ssize_t rd_ser_len;
1233 };
1234 
1235 
1248 static void
1249 lookup_it (void *cls,
1250  uint64_t seq,
1251  const struct GNUNET_IDENTITY_PrivateKey *private_key,
1252  const char *label,
1253  unsigned int rd_count,
1254  const struct GNUNET_GNSRECORD_Data *rd)
1255 {
1256  struct RecordLookupContext *rlc = cls;
1257 
1258  (void) private_key;
1259  GNUNET_assert (0 != seq);
1260  if (0 != strcmp (label, rlc->label))
1261  return;
1262  rlc->found = GNUNET_YES;
1263  if (0 == rd_count)
1264  {
1265  rlc->rd_ser_len = 0;
1266  rlc->res_rd_count = 0;
1267  rlc->res_rd = NULL;
1268  return;
1269  }
1270  if ((NULL != rlc->nick) && (0 != strcmp (label, GNUNET_GNS_EMPTY_LABEL_AT)))
1271  {
1272  /* Merge */
1273  struct GNUNET_GNSRECORD_Data *rd_res;
1274  unsigned int rdc_res;
1275 
1276  rd_res = NULL;
1277  rdc_res = 0;
1278  rlc->nick->flags = (rlc->nick->flags | GNUNET_GNSRECORD_RF_PRIVATE)
1280  merge_with_nick_records (rlc->nick, rd_count, rd, &rdc_res, &rd_res);
1281  rlc->rd_ser_len = GNUNET_GNSRECORD_records_get_size (rdc_res, rd_res);
1282  if (rlc->rd_ser_len < 0)
1283  {
1284  GNUNET_break (0);
1285  GNUNET_free (rd_res);
1286  rlc->found = GNUNET_NO;
1287  rlc->rd_ser_len = 0;
1288  return;
1289  }
1290  rlc->res_rd_count = rdc_res;
1291  rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1292  if (rlc->rd_ser_len != GNUNET_GNSRECORD_records_serialize (rdc_res,
1293  rd_res,
1294  rlc->rd_ser_len,
1295  rlc->res_rd))
1296  {
1297  GNUNET_break (0);
1298  GNUNET_free (rlc->res_rd);
1299  rlc->res_rd = NULL;
1300  rlc->res_rd_count = 0;
1301  rlc->rd_ser_len = 0;
1302  GNUNET_free (rd_res);
1303  rlc->found = GNUNET_NO;
1304  return;
1305  }
1306  GNUNET_free (rd_res);
1307  GNUNET_free (rlc->nick);
1308  rlc->nick = NULL;
1309  }
1310  else
1311  {
1312  rlc->rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1313  if (rlc->rd_ser_len < 0)
1314  {
1315  GNUNET_break (0);
1316  rlc->found = GNUNET_NO;
1317  rlc->rd_ser_len = 0;
1318  return;
1319  }
1320  rlc->res_rd_count = rd_count;
1321  rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1322  if (rlc->rd_ser_len != GNUNET_GNSRECORD_records_serialize (rd_count,
1323  rd,
1324  rlc->rd_ser_len,
1325  rlc->res_rd))
1326  {
1327  GNUNET_break (0);
1328  GNUNET_free (rlc->res_rd);
1329  rlc->res_rd = NULL;
1330  rlc->res_rd_count = 0;
1331  rlc->rd_ser_len = 0;
1332  rlc->found = GNUNET_NO;
1333  return;
1334  }
1335  }
1336 }
1337 
1338 
1346 static int
1347 check_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
1348 {
1349  uint32_t name_len;
1350  size_t src_size;
1351 
1352  (void) cls;
1353  name_len = ntohl (ll_msg->label_len);
1354  src_size = ntohs (ll_msg->gns_header.header.size);
1355  if (name_len != src_size - sizeof(struct LabelLookupMessage))
1356  {
1357  GNUNET_break (0);
1358  return GNUNET_SYSERR;
1359  }
1361  return GNUNET_OK;
1362 }
1363 
1364 
1371 static void
1372 handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
1373 {
1374  struct NamestoreClient *nc = cls;
1375  struct GNUNET_MQ_Envelope *env;
1376  struct LabelLookupResponseMessage *llr_msg;
1377  struct RecordLookupContext rlc;
1378  const char *name_tmp;
1379  char *res_name;
1380  char *conv_name;
1381  uint32_t name_len;
1382  int res;
1383 
1384  name_tmp = (const char *) &ll_msg[1];
1387  "Received NAMESTORE_RECORD_LOOKUP message for name `%s'\n",
1388  name_tmp);
1389 
1390  conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
1391  if (NULL == conv_name)
1392  {
1394  "Error converting name `%s'\n",
1395  name_tmp);
1396  GNUNET_SERVICE_client_drop (nc->client);
1397  return;
1398  }
1399  name_len = strlen (conv_name) + 1;
1400  rlc.label = conv_name;
1401  rlc.found = GNUNET_NO;
1402  rlc.res_rd_count = 0;
1403  rlc.res_rd = NULL;
1404  rlc.rd_ser_len = 0;
1405  rlc.nick = get_nick_record (&ll_msg->zone);
1407  &ll_msg->zone,
1408  conv_name,
1409  &lookup_it,
1410  &rlc);
1411  env =
1412  GNUNET_MQ_msg_extra (llr_msg,
1413  name_len + rlc.rd_ser_len,
1415  llr_msg->gns_header.r_id = ll_msg->gns_header.r_id;
1416  llr_msg->private_key = ll_msg->zone;
1417  llr_msg->name_len = htons (name_len);
1418  llr_msg->rd_count = htons (rlc.res_rd_count);
1419  llr_msg->rd_len = htons (rlc.rd_ser_len);
1420  res_name = (char *) &llr_msg[1];
1421  if ((GNUNET_YES == rlc.found) && (GNUNET_OK == res))
1422  llr_msg->found = htons (GNUNET_YES);
1423  else
1424  llr_msg->found = htons (GNUNET_NO);
1425  GNUNET_memcpy (&llr_msg[1], conv_name, name_len);
1426  GNUNET_memcpy (&res_name[name_len], rlc.res_rd, rlc.rd_ser_len);
1427  GNUNET_MQ_send (nc->mq, env);
1428  GNUNET_free (rlc.res_rd);
1429  GNUNET_free (conv_name);
1430 }
1431 
1432 
1433 
1441 static int
1442 check_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1443 {
1444  size_t name_len;
1445  size_t msg_size;
1446  size_t msg_size_exp;
1447  size_t rd_ser_len;
1448  const char *name_tmp;
1449 
1450  (void) cls;
1451  name_len = ntohs (rp_msg->name_len);
1452  msg_size = ntohs (rp_msg->gns_header.header.size);
1453  rd_ser_len = ntohs (rp_msg->rd_len);
1454  msg_size_exp = sizeof(struct RecordStoreMessage) + name_len + rd_ser_len;
1455  if (msg_size != msg_size_exp)
1456  {
1457  GNUNET_break (0);
1458  return GNUNET_SYSERR;
1459  }
1460  if ((0 == name_len) || (name_len > MAX_NAME_LEN))
1461  {
1462  GNUNET_break (0);
1463  return GNUNET_SYSERR;
1464  }
1465  name_tmp = (const char *) &rp_msg[1];
1466  if ('\0' != name_tmp[name_len - 1])
1467  {
1468  GNUNET_break (0);
1469  return GNUNET_SYSERR;
1470  }
1471  return GNUNET_OK;
1472 }
1473 
1474 
1485 static void
1487  uint64_t seq,
1488  const struct
1490  const char *label,
1491  unsigned int rd_count,
1492  const struct GNUNET_GNSRECORD_Data *rd)
1493 {
1494  struct GNUNET_TIME_Absolute *exp = cls;
1495  struct GNUNET_GNSRECORD_Data rd_pub[rd_count];
1496  unsigned int rd_pub_count;
1497  char *emsg;
1498 
1500  rd,
1501  rd_count,
1502  rd_pub,
1503  &rd_pub_count,
1504  exp,
1505  &emsg))
1506  {
1508  "%s\n", emsg);
1509  GNUNET_free (emsg);
1510  }
1511 }
1512 
1513 
1520 static void
1521 handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1522 {
1523  struct NamestoreClient *nc = cls;
1524  size_t name_len;
1525  size_t rd_ser_len;
1526  uint32_t rid;
1527  const char *name_tmp;
1528  char *conv_name;
1529  const char *rd_ser;
1530  unsigned int rd_count;
1531  int res;
1532  struct StoreActivity *sa;
1533  struct GNUNET_TIME_Absolute existing_block_exp;
1534  struct GNUNET_TIME_Absolute new_block_exp;
1535 
1537  "Received NAMESTORE_RECORD_STORE message\n");
1538  existing_block_exp = GNUNET_TIME_UNIT_ZERO_ABS;
1539  new_block_exp = GNUNET_TIME_UNIT_ZERO_ABS;
1540  rid = ntohl (rp_msg->gns_header.r_id);
1541  name_len = ntohs (rp_msg->name_len);
1542  rd_count = ntohs (rp_msg->rd_count);
1543  rd_ser_len = ntohs (rp_msg->rd_len);
1544  name_tmp = (const char *) &rp_msg[1];
1545  rd_ser = &name_tmp[name_len];
1546  {
1547  struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
1548  char *emsg;
1549 
1550  /* Extracting and converting private key */
1551  conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
1552  if (NULL == conv_name)
1553  {
1555  "Error normalizing name `%s'\n",
1556  name_tmp);
1557  send_store_response (nc, GNUNET_SYSERR, _ ("Error normalizing name."),
1558  rid);
1560  return;
1561  }
1562 
1563  /* Check name for validity */
1564  if (GNUNET_OK != GNUNET_GNSRECORD_label_check (conv_name, &emsg))
1565  {
1567  "Label invalid: `%s'\n",
1568  emsg);
1569  send_store_response (nc, GNUNET_SYSERR, emsg, rid);
1570  GNUNET_free (emsg);
1571  GNUNET_free (conv_name);
1573  return;
1574  }
1575 
1576  if (GNUNET_OK !=
1577  GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count, rd))
1578  {
1580  _ ("Error deserializing records."), rid);
1581  GNUNET_free (conv_name);
1583  return;
1584  }
1585 
1587  "Well-formed store requests received",
1588  1,
1589  GNUNET_NO);
1591  "Creating %u records for name `%s'\n",
1592  (unsigned int) rd_count,
1593  conv_name);
1595  &rp_msg->private_key,
1596  conv_name,
1598  &existing_block_exp)) &&
1599  (rd_count == 0))
1600  {
1601  /* This name does not exist, so cannot be removed */
1603  "Name `%s' does not exist, no deletion required\n",
1604  conv_name);
1605  res = GNUNET_NO;
1606  }
1607  else
1608  {
1609  /* remove "NICK" records, unless this is for the
1610  #GNUNET_GNS_EMPTY_LABEL_AT label
1611  We may need one additional record later for tombstone.
1612  FIXME: Since we must normalize the record set (check for
1613  consistency etc) we have to iterate the set twice.
1614  May be inefficient.
1615  We cannot really move the nick caching into GNSRECORD.
1616  */
1617  struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL (rd_count)];
1618  struct GNUNET_GNSRECORD_Data rd_nf[GNUNET_NZL (rd_count) + 1];
1619  unsigned int rd_clean_off;
1620  unsigned int rd_nf_count;
1621  char *emsg;
1622  int have_nick;
1623 
1624  rd_clean_off = 0;
1625  have_nick = GNUNET_NO;
1626  for (unsigned int i = 0; i < rd_count; i++)
1627  {
1628  rd_clean[rd_clean_off] = rd[i];
1629 
1630  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) ||
1632  rd_clean_off++;
1633 
1634  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1636  {
1637  cache_nick (&rp_msg->private_key, &rd[i]);
1638  have_nick = GNUNET_YES;
1639  }
1640  }
1642  rd_clean,
1643  rd_clean_off,
1644  rd_nf,
1645  &rd_nf_count,
1646  &new_block_exp,
1647  GNUNET_YES,
1648  &emsg))
1649  {
1650  send_store_response (nc, GNUNET_SYSERR, emsg, rid);
1651  GNUNET_free (emsg);
1653  GNUNET_free (conv_name);
1654  return;
1655  }
1656  /*
1657  * If existing_block_exp is 0, then there was not record set
1658  * and no tombstone.
1659  * Otherwise, if the existing block expiration is after the
1660  * new block expiration would be, we need to add a tombstone
1661  * or update it.
1662  */
1663  if (GNUNET_TIME_absolute_cmp (new_block_exp, <=, existing_block_exp))
1664  {
1665  rd_nf[rd_nf_count].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE;
1666  rd_nf[rd_nf_count].expiration_time =
1667  existing_block_exp.abs_value_us;
1668  rd_nf[rd_nf_count].data = NULL;
1669  rd_nf[rd_nf_count].data_size = 0;
1670  rd_nf[rd_nf_count].flags = GNUNET_GNSRECORD_RF_PRIVATE;
1671  rd_nf_count++;
1672  }
1673  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1674  (GNUNET_NO == have_nick))
1675  {
1676  /* remove nick record from cache, in case we have one there */
1677  cache_nick (&rp_msg->private_key, NULL);
1678  }
1680  &rp_msg->private_key,
1681  conv_name,
1682  rd_nf_count,
1683  rd_nf);
1684  }
1685 
1686  if (GNUNET_OK != res)
1687  {
1688  /* store not successful, no need to tell monitors */
1689  send_store_response (nc, res, _ ("Store failed"), rid);
1691  GNUNET_free (conv_name);
1692  return;
1693  }
1694  sa = GNUNET_malloc (sizeof(struct StoreActivity)
1695  + ntohs (rp_msg->gns_header.header.size));
1697  sa->nc = nc;
1698  sa->rsm = (const struct RecordStoreMessage *) &sa[1];
1699  GNUNET_memcpy (&sa[1], rp_msg, ntohs (rp_msg->gns_header.header.size));
1700  sa->zm_pos = monitor_head;
1701  sa->conv_name = conv_name;
1703  }
1704 }
1705 
1706 
1712 {
1717 
1721  uint32_t rid;
1722 
1728  int success;
1729 };
1730 
1731 
1742 static void
1744  uint64_t seq,
1745  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
1746  const char *name,
1747  unsigned int rd_count,
1748  const struct GNUNET_GNSRECORD_Data *rd)
1749 {
1750  struct ZoneToNameCtx *ztn_ctx = cls;
1751  struct GNUNET_MQ_Envelope *env;
1752  struct ZoneToNameResponseMessage *ztnr_msg;
1753  int16_t res;
1754  size_t name_len;
1755  ssize_t rd_ser_len;
1756  size_t msg_size;
1757  char *name_tmp;
1758  char *rd_tmp;
1759 
1760  GNUNET_assert (0 != seq);
1762  "Found result for zone-to-name lookup: `%s'\n",
1763  name);
1764  res = GNUNET_YES;
1765  name_len = (NULL == name) ? 0 : strlen (name) + 1;
1766  rd_ser_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1767  if (rd_ser_len < 0)
1768  {
1769  GNUNET_break (0);
1770  ztn_ctx->success = GNUNET_SYSERR;
1771  return;
1772  }
1773  msg_size = sizeof(struct ZoneToNameResponseMessage) + name_len + rd_ser_len;
1774  if (msg_size >= GNUNET_MAX_MESSAGE_SIZE)
1775  {
1776  GNUNET_break (0);
1777  ztn_ctx->success = GNUNET_SYSERR;
1778  return;
1779  }
1780  env =
1781  GNUNET_MQ_msg_extra (ztnr_msg,
1782  name_len + rd_ser_len,
1784  ztnr_msg->gns_header.header.size = htons (msg_size);
1785  ztnr_msg->gns_header.r_id = htonl (ztn_ctx->rid);
1786  ztnr_msg->res = htons (res);
1787  ztnr_msg->rd_len = htons (rd_ser_len);
1788  ztnr_msg->rd_count = htons (rd_count);
1789  ztnr_msg->name_len = htons (name_len);
1790  ztnr_msg->zone = *zone_key;
1791  name_tmp = (char *) &ztnr_msg[1];
1792  GNUNET_memcpy (name_tmp, name, name_len);
1793  rd_tmp = &name_tmp[name_len];
1794  GNUNET_assert (
1795  rd_ser_len ==
1796  GNUNET_GNSRECORD_records_serialize (rd_count, rd, rd_ser_len, rd_tmp));
1797  ztn_ctx->success = GNUNET_OK;
1798  GNUNET_MQ_send (ztn_ctx->nc->mq, env);
1799 }
1800 
1801 
1808 static void
1809 handle_zone_to_name (void *cls, const struct ZoneToNameMessage *ztn_msg)
1810 {
1811  struct NamestoreClient *nc = cls;
1812  struct ZoneToNameCtx ztn_ctx;
1813  struct GNUNET_MQ_Envelope *env;
1814  struct ZoneToNameResponseMessage *ztnr_msg;
1815 
1816  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_TO_NAME message\n");
1817  ztn_ctx.rid = ntohl (ztn_msg->gns_header.r_id);
1818  ztn_ctx.nc = nc;
1819  ztn_ctx.success = GNUNET_NO;
1821  &ztn_msg->zone,
1822  &ztn_msg->value_zone,
1824  &ztn_ctx))
1825  {
1826  /* internal error, hang up instead of signalling something
1827  that might be wrong */
1828  GNUNET_break (0);
1829  GNUNET_SERVICE_client_drop (nc->client);
1830  return;
1831  }
1832  if (GNUNET_NO == ztn_ctx.success)
1833  {
1834  /* no result found, send empty response */
1836  "Found no result for zone-to-name lookup.\n");
1837  env = GNUNET_MQ_msg (ztnr_msg,
1839  ztnr_msg->gns_header.r_id = ztn_msg->gns_header.r_id;
1840  ztnr_msg->res = htons (GNUNET_NO);
1841  GNUNET_MQ_send (nc->mq, env);
1842  }
1844 }
1845 
1846 
1852 {
1857 
1861  uint64_t limit;
1862 };
1863 
1864 
1875 static void
1877  uint64_t seq,
1878  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
1879  const char *name,
1880  unsigned int rd_count,
1881  const struct GNUNET_GNSRECORD_Data *rd)
1882 {
1883  struct ZoneIterationProcResult *proc = cls;
1884  int do_refresh_block;
1885 
1886  GNUNET_assert (0 != seq);
1887  if ((NULL == zone_key) && (NULL == name))
1888  {
1889  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
1890  return;
1891  }
1892  if ((NULL == zone_key) || (NULL == name))
1893  {
1894  /* what is this!? should never happen */
1895  GNUNET_break (0);
1896  return;
1897  }
1898  if (0 == proc->limit)
1899  {
1900  /* what is this!? should never happen */
1901  GNUNET_break (0);
1902  return;
1903  }
1904  proc->limit--;
1905  proc->zi->seq = seq;
1906  send_lookup_response (proc->zi->nc,
1907  proc->zi->request_id,
1908  zone_key,
1909  name,
1910  rd_count,
1911  rd);
1912 
1913 
1914  do_refresh_block = GNUNET_NO;
1915  for (unsigned int i = 0; i < rd_count; i++)
1916  if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
1917  {
1918  do_refresh_block = GNUNET_YES;
1919  break;
1920  }
1921  if (GNUNET_YES == do_refresh_block)
1922  refresh_block (NULL, proc->zi, 0, zone_key, name, rd_count, rd);
1923 }
1924 
1925 
1932 static void
1934 {
1935  struct ZoneIterationProcResult proc;
1936  struct GNUNET_TIME_Absolute start;
1938 
1939  memset (&proc, 0, sizeof(proc));
1941  "Asked to return up to %llu records at position %llu\n",
1942  (unsigned long long) limit,
1943  (unsigned long long) zi->seq);
1944  proc.zi = zi;
1945  proc.limit = limit;
1950  &zi->zone))
1951  ? NULL
1952  : &zi->zone,
1953  zi->seq,
1954  limit,
1956  &proc));
1960  "NAMESTORE iteration delay (μs/record)",
1962  GNUNET_NO);
1963  if (0 == proc.limit)
1965  "Returned %llu results, more results available\n",
1966  (unsigned long long) limit);
1967  zi->send_end = (0 != proc.limit);
1968  if (0 == zi->cache_ops)
1970 }
1971 
1972 
1979 static void
1981  const struct ZoneIterationStartMessage *zis_msg)
1982 {
1983  struct NamestoreClient *nc = cls;
1984  struct ZoneIteration *zi;
1985 
1987  "Received ZONE_ITERATION_START message\n");
1988  zi = GNUNET_new (struct ZoneIteration);
1989  zi->request_id = ntohl (zis_msg->gns_header.r_id);
1990  zi->offset = 0;
1991  zi->nc = nc;
1992  zi->zone = zis_msg->zone;
1993 
1994  GNUNET_CONTAINER_DLL_insert (nc->op_head, nc->op_tail, zi);
1995  run_zone_iteration_round (zi, 1);
1996 }
1997 
1998 
2005 static void
2007  const struct ZoneIterationStopMessage *zis_msg)
2008 {
2009  struct NamestoreClient *nc = cls;
2010  struct ZoneIteration *zi;
2011  uint32_t rid;
2012 
2014  "Received ZONE_ITERATION_STOP message\n");
2015  rid = ntohl (zis_msg->gns_header.r_id);
2016  for (zi = nc->op_head; NULL != zi; zi = zi->next)
2017  if (zi->request_id == rid)
2018  break;
2019  if (NULL == zi)
2020  {
2021  GNUNET_break (0);
2022  GNUNET_SERVICE_client_drop (nc->client);
2023  return;
2024  }
2025  GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, zi);
2026  GNUNET_free (zi);
2028 }
2029 
2030 
2037 static void
2039  const struct ZoneIterationNextMessage *zis_msg)
2040 {
2041  struct NamestoreClient *nc = cls;
2042  struct ZoneIteration *zi;
2043  uint32_t rid;
2044  uint64_t limit;
2045 
2047  "Received ZONE_ITERATION_NEXT message\n");
2049  "Iteration NEXT messages received",
2050  1,
2051  GNUNET_NO);
2052  rid = ntohl (zis_msg->gns_header.r_id);
2053  limit = GNUNET_ntohll (zis_msg->limit);
2054  for (zi = nc->op_head; NULL != zi; zi = zi->next)
2055  if (zi->request_id == rid)
2056  break;
2057  if (NULL == zi)
2058  {
2059  GNUNET_break (0);
2060  GNUNET_SERVICE_client_drop (nc->client);
2061  return;
2062  }
2063  run_zone_iteration_round (zi, limit);
2064 }
2065 
2066 
2072 static void
2074 {
2075  struct StoreActivity *sa = sa_head;
2076 
2077  while ((NULL != sa) && (zm->limit > zm->iteration_cnt))
2078  {
2079  struct StoreActivity *sn = sa->next;
2080 
2081  if (sa->zm_pos == zm)
2083  sa = sn;
2084  }
2085  if (zm->limit > zm->iteration_cnt)
2086  {
2087  zm->sa_waiting = GNUNET_NO;
2088  if (NULL != zm->sa_wait_warning)
2089  {
2090  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2091  zm->sa_wait_warning = NULL;
2092  }
2093  }
2094  else if (GNUNET_YES == zm->sa_waiting)
2095  {
2096  zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
2097  if (NULL != zm->sa_wait_warning)
2098  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2099  zm->sa_wait_warning =
2102  zm);
2103  }
2104 }
2105 
2106 
2112 static void
2114 {
2115  struct GNUNET_MQ_Envelope *env;
2116  struct GNUNET_MessageHeader *sync;
2117 
2119  GNUNET_MQ_send (zm->nc->mq, env);
2120  /* mark iteration done */
2121  zm->in_first_iteration = GNUNET_NO;
2122  zm->iteration_cnt = 0;
2123  if ((zm->limit > 0) && (zm->sa_waiting))
2124  monitor_unblock (zm);
2125 }
2126 
2127 
2133 static void
2134 monitor_iteration_next (void *cls);
2135 
2136 
2147 static void
2149  uint64_t seq,
2150  const struct GNUNET_IDENTITY_PrivateKey *zone_key,
2151  const char *name,
2152  unsigned int rd_count,
2153  const struct GNUNET_GNSRECORD_Data *rd)
2154 {
2155  struct ZoneMonitor *zm = cls;
2156 
2157  GNUNET_assert (0 != seq);
2158  zm->seq = seq;
2159  GNUNET_assert (NULL != name);
2161  "Monitor notifications sent",
2162  1,
2163  GNUNET_NO);
2164  zm->limit--;
2165  zm->iteration_cnt--;
2166  send_lookup_response (zm->nc, 0, zone_key, name, rd_count, rd);
2167  if ((0 == zm->iteration_cnt) && (0 != zm->limit))
2168  {
2169  /* We are done with the current iteration batch, AND the
2170  client would right now accept more, so go again! */
2171  GNUNET_assert (NULL == zm->task);
2173  }
2174 }
2175 
2176 
2183 static void
2184 handle_monitor_start (void *cls, const struct ZoneMonitorStartMessage *zis_msg)
2185 {
2186  struct NamestoreClient *nc = cls;
2187  struct ZoneMonitor *zm;
2188 
2189  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_MONITOR_START message\n");
2190  zm = GNUNET_new (struct ZoneMonitor);
2191  zm->nc = nc;
2192  zm->zone = zis_msg->zone;
2193  zm->limit = 1;
2194  zm->in_first_iteration = (GNUNET_YES == ntohl (zis_msg->iterate_first));
2199  if (zm->in_first_iteration)
2201  else
2202  monitor_sync (zm);
2203 }
2204 
2205 
2211 static void
2213 {
2214  struct ZoneMonitor *zm = cls;
2215  int ret;
2216 
2217  zm->task = NULL;
2218  GNUNET_assert (0 == zm->iteration_cnt);
2219  if (zm->limit > 16)
2220  zm->iteration_cnt = zm->limit / 2; /* leave half for monitor events */
2221  else
2222  zm->iteration_cnt = zm->limit; /* use it all */
2225  &zm->zone))
2226  ? NULL
2227  : &zm->zone,
2228  zm->seq,
2229  zm->iteration_cnt,
2231  zm);
2232  if (GNUNET_SYSERR == ret)
2233  {
2234  GNUNET_SERVICE_client_drop (zm->nc->client);
2235  return;
2236  }
2237  if (GNUNET_NO == ret)
2238  {
2239  /* empty zone */
2240  monitor_sync (zm);
2241  return;
2242  }
2243 }
2244 
2245 
2252 static void
2253 handle_monitor_next (void *cls, const struct ZoneMonitorNextMessage *nm)
2254 {
2255  struct NamestoreClient *nc = cls;
2256  struct ZoneMonitor *zm;
2257  uint64_t inc;
2258 
2259  inc = GNUNET_ntohll (nm->limit);
2261  "Received ZONE_MONITOR_NEXT message with limit %llu\n",
2262  (unsigned long long) inc);
2263  for (zm = monitor_head; NULL != zm; zm = zm->next)
2264  if (zm->nc == nc)
2265  break;
2266  if (NULL == zm)
2267  {
2268  GNUNET_break (0);
2269  GNUNET_SERVICE_client_drop (nc->client);
2270  return;
2271  }
2273  if (zm->limit + inc < zm->limit)
2274  {
2275  GNUNET_break (0);
2276  GNUNET_SERVICE_client_drop (nc->client);
2277  return;
2278  }
2279  zm->limit += inc;
2280  if ((zm->in_first_iteration) && (zm->limit == inc))
2281  {
2282  /* We are still iterating, and the previous iteration must
2283  have stopped due to the client's limit, so continue it! */
2284  GNUNET_assert (NULL == zm->task);
2286  }
2287  GNUNET_assert (zm->iteration_cnt <= zm->limit);
2288  if ((zm->limit > zm->iteration_cnt) && (zm->sa_waiting))
2289  {
2290  monitor_unblock (zm);
2291  }
2292  else if (GNUNET_YES == zm->sa_waiting)
2293  {
2294  if (NULL != zm->sa_wait_warning)
2295  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2296  zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
2297  zm->sa_wait_warning =
2300  zm);
2301  }
2302 }
2303 
2304 
2312 static void
2313 run (void *cls,
2314  const struct GNUNET_CONFIGURATION_Handle *cfg,
2316 {
2317  char *database;
2318 
2319  (void) cls;
2320  (void) service;
2321  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n");
2322  cache_keys =
2323  GNUNET_CONFIGURATION_get_value_yesno (cfg, "namestore", "CACHE_KEYS");
2325  GNUNET_CONFIGURATION_get_value_yesno (cfg, "namecache", "DISABLE");
2326  GSN_cfg = cfg;
2329  {
2331  GNUNET_assert (NULL != namecache);
2332  }
2333  /* Loading database plugin */
2335  "namestore",
2336  "database",
2337  &database))
2338  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
2339 
2340  GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
2342  GNUNET_free (database);
2343  statistics = GNUNET_STATISTICS_create ("namestore", cfg);
2345  if (NULL == GSN_database)
2346  {
2348  "Could not load database backend `%s'\n",
2349  db_lib_name);
2351  return;
2352  }
2353 }
2354 
2355 
2360  "namestore",
2362  &run,
2365  NULL,
2366  GNUNET_MQ_hd_var_size (record_store,
2368  struct RecordStoreMessage,
2369  NULL),
2370  GNUNET_MQ_hd_var_size (record_lookup,
2372  struct LabelLookupMessage,
2373  NULL),
2376  struct ZoneToNameMessage,
2377  NULL),
2381  NULL),
2382  GNUNET_MQ_hd_fixed_size (iteration_next,
2384  struct ZoneIterationNextMessage,
2385  NULL),
2386  GNUNET_MQ_hd_fixed_size (iteration_stop,
2388  struct ZoneIterationStopMessage,
2389  NULL),
2390  GNUNET_MQ_hd_fixed_size (monitor_start,
2392  struct ZoneMonitorStartMessage,
2393  NULL),
2394  GNUNET_MQ_hd_fixed_size (monitor_next,
2396  struct ZoneMonitorNextMessage,
2397  NULL),
2399 
2400 
2401 /* end of gnunet-service-namestore.c */
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_GNSRECORD_TYPE_NICK
GNS nick names.
#define GNUNET_GNSRECORD_TYPE_TOMBSTONE
Record type to indicate a previously delete record (PRIVATE only)
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static int res
uint32_t data
The data value.
static char * pkey
Public key of the zone to look in, in ASCII.
static char * zone
Name of the zone being managed.
static const struct GNUNET_IDENTITY_PrivateKey * zone_key
Private key of the zone.
static struct GNUNET_NAMESTORE_ZoneMonitor * zm
Monitor handle.
static struct GNUNET_TIME_Relative duration
How long do we run the test?
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:46
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static struct GNUNET_PEERINFO_NotifyContext * nc
Iterator context.
static void send_lookup_response(struct NamestoreClient *nc, uint32_t request_id, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Generate a struct LookupNameResponseMessage and send it to the given client using the given notificat...
static int disable_namecache
Use the namecache? Doing so creates additional cryptographic operations whenever we touch a record.
static void handle_zone_to_name_it(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Zone to name iterator.
static struct CacheOperation * cop_head
Head of cop DLL.
static struct GNUNET_NAMECACHE_Handle * namecache
Namecache handle.
static void handle_iteration_start(void *cls, const struct ZoneIterationStartMessage *zis_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START message.
static struct StoreActivity * sa_tail
Tail of DLL of monitor-blocked store activities.
static void handle_iteration_stop(void *cls, const struct ZoneIterationStopMessage *zis_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP message.
static void run_zone_iteration_round(struct ZoneIteration *zi, uint64_t limit)
Perform the next round of the zone iteration.
static void refresh_block(struct NamestoreClient *nc, struct ZoneIteration *zi, uint32_t rid, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
We just touched the plaintext information about a name in our zone; refresh the corresponding (encryp...
static void monitor_unblock(struct ZoneMonitor *zm)
Function called when the monitor is ready for more data, and we should thus unblock PUT operations th...
static void handle_record_store(void *cls, const struct RecordStoreMessage *rp_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message.
static void monitor_sync(struct ZoneMonitor *zm)
Send 'sync' message to zone monitor, we're now in sync.
static struct CacheOperation * cop_tail
Tail of cop DLL.
static void finish_cache_operation(void *cls, int32_t success, const char *emsg)
Cache operation complete, clean up.
static void handle_monitor_next(void *cls, const struct ZoneMonitorNextMessage *nm)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_NEXT message.
static struct GNUNET_NotificationContext * monitor_nc
Notification context shared by all monitors.
static struct GNUNET_NAMESTORE_PluginFunctions * GSN_database
Database handle.
static void get_block_exp_existing(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Check if set contains a tombstone, store if necessary.
static void monitor_iterate_cb(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
A GNUNET_NAMESTORE_RecordIterator for monitors.
static void cleanup_task(void *cls)
Task run during shutdown.
static char * db_lib_name
Name of the database plugin.
static int check_record_store(void *cls, const struct RecordStoreMessage *rp_msg)
Checks a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message.
static void lookup_nick_it(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Function called with the records for the GNUNET_GNS_EMPTY_LABEL_AT label in the zone.
static struct GNUNET_STATISTICS_Handle * statistics
Handle to the statistics service.
static void merge_with_nick_records(const struct GNUNET_GNSRECORD_Data *nick_rd, unsigned int rd2_length, const struct GNUNET_GNSRECORD_Data *rd2, unsigned int *rdc_res, struct GNUNET_GNSRECORD_Data **rd_res)
Merge the nick record nick_rd with the rest of the record set given in rd2.
static struct StoreActivity * sa_head
Head of DLL of monitor-blocked store activities.
static void handle_record_lookup(void *cls, const struct LabelLookupMessage *ll_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message.
static void free_store_activity(struct StoreActivity *sa)
Release memory used by sa.
static void handle_zone_to_name(void *cls, const struct ZoneToNameMessage *ztn_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME message.
static struct ZoneMonitor * monitor_head
First active zone monitor.
static int check_record_lookup(void *cls, const struct LabelLookupMessage *ll_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message.
static void send_store_response(struct NamestoreClient *nc, int res, const char *emsg, uint32_t rid)
Send response to the store request to the client.
static void cache_nick(const struct GNUNET_IDENTITY_PrivateKey *zone, const struct GNUNET_GNSRECORD_Data *nick)
Add entry to the cache for zone and nick.
static void zone_iteration_done_client_continue(struct ZoneIteration *zi)
Function called once we are done with the zone iteration and allow the zone iteration client to send ...
#define MONITOR_STALL_WARN_DELAY
If a monitor takes more than 1 minute to process an event, print a warning.
static int cache_keys
Optimize block insertion by caching map of private keys to public keys in memory?
static void monitor_iteration_next(void *cls)
Obtain the next datum during the zone monitor's zone initial iteration.
static const struct GNUNET_CONFIGURATION_Handle * GSN_cfg
Configuration handle.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
Add a client to our list of active clients.
static void handle_monitor_start(void *cls, const struct ZoneMonitorStartMessage *zis_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START message.
static void continue_store_activity(struct StoreActivity *sa)
Continue processing the sa.
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.
#define NC_SIZE
Size of the cache used by get_nick_record()
static const struct GNUNET_IDENTITY_PrivateKey zero
Public key of all zeros.
static struct ZoneMonitor * monitor_tail
Last active zone monitor.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
Called whenever a client is disconnected.
static struct NickCache nick_cache[16]
We cache nick records to reduce DB load.
static void handle_iteration_next(void *cls, const struct ZoneIterationNextMessage *zis_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT message.
static void warn_monitor_slow(void *cls)
Print a warning that one of our monitors is no longer reacting.
static void zone_iterate_proc(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process results for zone iteration from database.
static void lookup_it(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Function called by the namestore plugin when we are trying to lookup a record as part of handle_recor...
static struct GNUNET_GNSRECORD_Data * get_nick_record(const struct GNUNET_IDENTITY_PrivateKey *zone)
Return the NICK record for the zone (if it exists).
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
Process namestore requests.
static void iteration_start()
#define GNUNET_is_zero(a)
Check that memory in a is all zeros.
#define GNUNET_log(kind,...)
#define GNUNET_NZL(l)
Macro used to avoid using 0 for the length of a variable-size array (Non-Zero-Length).
#define GNUNET_LOG_CALL_STATUS
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:53
int GNUNET_get_log_call_status(int caller_level, const char *comp, const char *file, const char *function, int line)
Decides whether a particular logging call should or should not be allowed to be made.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
char * GNUNET_GNSRECORD_string_normalize(const char *src)
Normalize a UTF-8 string to a GNS name.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_label_check(const char *label, char **emsg)
Check label for invalid characters.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_normalize_record_set(const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *rd_public, unsigned int *rd_count_public, struct GNUNET_TIME_Absolute *expiry, int include_private, char **emsg)
Normalize namestore records: Check for consistency and expirations.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_block_create2(const struct GNUNET_IDENTITY_PrivateKey *pkey, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, struct GNUNET_GNSRECORD_Block **result)
Sign name and records, cache derived public key (also keeps the private key in static memory,...
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_block_create(const struct GNUNET_IDENTITY_PrivateKey *key, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, struct GNUNET_GNSRECORD_Block **result)
Sign name and records.
int GNUNET_GNSRECORD_records_deserialize(size_t len, const char *src, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *dest)
Deserialize the given records to the given destination.
ssize_t GNUNET_GNSRECORD_records_serialize(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, size_t dest_size, char *dest)
Serialize the given records to the given destination buffer.
struct GNUNET_TIME_Absolute GNUNET_GNSRECORD_record_get_expiration_time(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, struct GNUNET_TIME_Absolute min)
Returns the expiration time of the given block of records.
GNUNET_NETWORK_STRUCT_END ssize_t GNUNET_GNSRECORD_records_get_size(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Calculate how many bytes we will need to serialize the given records.
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_convert_records_for_export(const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *rd_public, unsigned int *rd_count_public, struct GNUNET_TIME_Absolute *expiry, char **emsg)
Convert namestore records from the internal format to that suitable for publication (removes private ...
const char * GNUNET_GNSRECORD_z2s(const struct GNUNET_IDENTITY_PublicKey *z)
Convert a zone key to a string (for printing debug messages).
@ GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION
This expiration time of the record is a relative time (not an absolute time).
@ GNUNET_GNSRECORD_RF_SUPPLEMENTAL
This is a supplemental record.
@ GNUNET_GNSRECORD_RF_PRIVATE
This is a private record of this peer and it should thus not be handed out to other peers.
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_key_get_public(const struct GNUNET_IDENTITY_PrivateKey *privkey, struct GNUNET_IDENTITY_PublicKey *key)
Retrieves the public key representation of a private key.
Definition: identity_api.c:175
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_BULK
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition: nc.c:137
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:302
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_check_zero_termination(m)
Insert code for a "check_" function that verifies that a given variable-length message received over ...
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:52
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition: nc.c:121
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_notification_context_add(struct GNUNET_NotificationContext *nc, struct GNUNET_MQ_Handle *mq)
Add a subscriber to the notification context.
Definition: nc.c:160
void GNUNET_NAMECACHE_disconnect(struct GNUNET_NAMECACHE_Handle *h)
Disconnect from the namecache service (and free associated resources).
void GNUNET_NAMECACHE_cancel(struct GNUNET_NAMECACHE_QueueEntry *qe)
Cancel a namecache operation.
struct GNUNET_NAMECACHE_Handle * GNUNET_NAMECACHE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namecache service.
struct GNUNET_NAMECACHE_QueueEntry * GNUNET_NAMECACHE_block_cache(struct GNUNET_NAMECACHE_Handle *h, const struct GNUNET_GNSRECORD_Block *block, GNUNET_NAMECACHE_ContinuationWithStatus cont, void *cont_cls)
Store an item in the namecache.
void * GNUNET_PLUGIN_unload(const char *library_name, void *arg)
Unload plugin (runs the "done" callback and returns whatever "done" returned).
Definition: plugin.c:269
void * GNUNET_PLUGIN_load(const char *library_name, void *arg)
Setup plugin (runs the "init" callback and returns whatever "init" returned).
Definition: plugin.c:217
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT_END
Service to client: end of list of results.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
Service to client: here is a (plaintext) record you requested.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE
Service to client: result of zone-to-name lookup.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
Service to client: result of store operation.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT
Client to service: next record(s) in iteration please.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START
Client to service: please start iteration; receives "GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPON...
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP
Client to service: stop iterating.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE
Service to client: lookup label.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE
Client to service: store records (as authority)
#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_NEXT
Client to service: I am now ready for the next (set of) monitor events.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START
Client to service: start monitoring (yields sequence of "ZONE_ITERATION_RESPONSES" — forever).
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME
Client to service: "reverse" lookup for zone name based on zone key.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_SYNC
Service to client: you're now in sync.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP
Client to service: lookup label.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:533
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1281
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1316
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1254
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the 'monitor' flag on this client.
Definition: service.c:2412
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2329
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2248
@ GNUNET_SERVICE_OPTION_NONE
Use defaults.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:435
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:110
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:617
#define GNUNET_TIME_absolute_cmp(t1, op, t2)
Compare two absolute times.
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_divide(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Divide relative time by a given factor.
Definition: time.c:549
#define MAX_NAME_LEN
Maximum length of any name, including 0-termination.
Definition: namecache.h:33
common internal definitions for namestore service
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
const char * name
static int zone_to_name(void *cls, const struct GNUNET_HashCode *key, void *value)
Pending operation on the namecache.
struct CacheOperation * next
Kept in a DLL.
struct GNUNET_NAMECACHE_QueueEntry * qe
Handle to namecache queue.
struct CacheOperation * prev
Kept in a DLL.
uint32_t rid
Client's request ID.
struct NamestoreClient * nc
Client to notify about the result, can be NULL.
struct ZoneIteration * zi
Zone iteration to call zone_iteration_done_client_continue() for if applicable, can be NULL.
uint32_t record_type
Type of the GNS/DNS record.
const void * data
Binary value stored in the DNS record.
size_t data_size
Number of bytes in data.
enum GNUNET_GNSRECORD_Flags flags
Flags for the record.
uint64_t expiration_time
Expiration time for the DNS record.
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
Handle to a message queue.
Definition: mq.c:86
Header for all communications.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Connection to the NAMECACHE service.
Definition: namecache_api.c:95
An QueueEntry used to store information for a pending NAMECACHE record operation.
Definition: namecache_api.c:48
Generic namestore message with op id.
Definition: namestore.h:41
uint32_t r_id
Request ID in NBO.
Definition: namestore.h:51
struct GNUNET_MessageHeader header
header.type will be GNUNET_MESSAGE_TYPE_NAMESTORE_* header.size will be message size
Definition: namestore.h:46
struct returned by the initialization function of the plugin
int(* lookup_records)(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Lookup records in the datastore for which we are the authority.
int(* zone_to_name)(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const struct GNUNET_IDENTITY_PublicKey *value_zone, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Look for an existing PKEY delegation record for a given public key.
int(* iterate_records)(void *cls, const struct GNUNET_IDENTITY_PrivateKey *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.
int(* store_records)(void *cls, const struct GNUNET_IDENTITY_PrivateKey *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.
void * cls
Closure to pass to all plugin functions.
struct GNUNET_IDENTITY_PrivateKey zone
Monitored zone.
struct GNUNET_MQ_Handle * mq
Handle to namestore service.
The notification context is the key datastructure for a convenience API used for transmission of noti...
Definition: nc.c:76
struct GNUNET_MQ_Handle * mq
Our connection to the PEERINFO service.
Entry in list of pending tasks.
Definition: scheduler.c:135
Handle to a client that is connected to a service.
Definition: service.c:251
Handle to a service.
Definition: service.c:117
Handle for the service.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Lookup a label.
Definition: namestore.h:137
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP.
Definition: namestore.h:141
struct GNUNET_IDENTITY_PrivateKey zone
The private key of the zone to look up in.
Definition: namestore.h:151
uint32_t label_len
Length of the name.
Definition: namestore.h:146
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:177
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE.
Definition: namestore.h:167
uint16_t rd_count
Number of records contained.
Definition: namestore.h:182
uint16_t name_len
Name length.
Definition: namestore.h:172
int16_t found
Was the label found in the database?? GNUNET_YES or GNUNET_NO.
Definition: namestore.h:188
struct GNUNET_IDENTITY_PrivateKey private_key
The private key of the authority.
Definition: namestore.h:193
A namestore client.
struct ZoneIteration * op_head
Head of the DLL of Zone iteration operations in progress initiated by this client.
struct GNUNET_MQ_Handle * mq
Message queue for transmission to client.
struct GNUNET_SERVICE_Client * client
The client.
struct ZoneIteration * op_tail
Tail of the DLL of Zone iteration operations in progress initiated by this client.
Entry in list of cached nick resolutions.
struct GNUNET_GNSRECORD_Data * rd
Cached record data.
struct GNUNET_TIME_Absolute last_used
Timestamp when this cache entry was used last.
struct GNUNET_IDENTITY_PrivateKey zone
Zone the cache entry is for.
Closure for lookup_it().
struct GNUNET_GNSRECORD_Data * nick
FIXME.
unsigned int res_rd_count
FIXME.
Record is returned from the namestore (as authority).
Definition: namestore.h:271
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:285
uint16_t name_len
Name length.
Definition: namestore.h:280
struct GNUNET_IDENTITY_PrivateKey private_key
The private key of the authority.
Definition: namestore.h:300
uint16_t rd_count
Number of records contained.
Definition: namestore.h:290
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT.
Definition: namestore.h:275
Store a record to the namestore (as authority).
Definition: namestore.h:59
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE.
Definition: namestore.h:63
uint16_t rd_count
Number of records contained.
Definition: namestore.h:83
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:78
struct GNUNET_IDENTITY_PrivateKey private_key
The private key of the authority.
Definition: namestore.h:93
uint16_t name_len
Name length.
Definition: namestore.h:73
Response to a record storage request.
Definition: namestore.h:106
uint16_t emsg_len
Error message length.
Definition: namestore.h:120
uint16_t reserved
Reserved for alignment.
Definition: namestore.h:125
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE.
Definition: namestore.h:110
int32_t op_result
GNUNET_SYSERR on failure, GNUNET_OK on success
Definition: namestore.h:115
Information for an ongoing handle_record_store() operation.
struct StoreActivity * next
Kept in a DLL.
char * conv_name
Label nicely canonicalized (lower case).
const struct RecordStoreMessage * rsm
Copy of the original store message (as data fields in rd will point into it!).
struct NamestoreClient * nc
Which client triggered the store activity?
struct StoreActivity * prev
Kept in a DLL.
struct ZoneMonitor * zm_pos
Next zone monitor that still needs to be notified about this PUT.
Ask for next result of zone iteration for the given operation.
Definition: namestore.h:377
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT.
Definition: namestore.h:381
uint64_t limit
Number of records to return to the iterator in one shot (before GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_IT...
Definition: namestore.h:388
Context for record remove operations passed from run_zone_iteration_round to zone_iterate_proc as clo...
struct ZoneIteration * zi
The zone iteration handle.
uint64_t limit
Number of results left to be returned in this iteration.
Start a zone iteration for the given zone.
Definition: namestore.h:360
struct GNUNET_IDENTITY_PrivateKey zone
Zone key.
Definition: namestore.h:369
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START.
Definition: namestore.h:364
Stop zone iteration for the given operation.
Definition: namestore.h:396
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP.
Definition: namestore.h:400
A namestore iteration operation.
struct NamestoreClient * nc
Namestore client which intiated this zone iteration.
uint64_t seq
Last sequence number in the zone iteration used to address next result of the zone iteration in the s...
struct GNUNET_GNSRECORD_Data * nick
The nick to add to the records.
struct GNUNET_IDENTITY_PrivateKey zone
Key of the zone we are iterating over.
int send_end
Set to GNUNET_YES if the last iteration exhausted the limit set by the client and we should send the ...
uint32_t request_id
The operation id for the zone iteration in the response for the client.
unsigned int cache_ops
Number of pending cache operations triggered by this zone iteration which we need to wait for before ...
struct ZoneIteration * prev
Previous element in the DLL.
uint32_t offset
Offset of the zone iteration used to address next result of the zone iteration in the store.
struct ZoneIteration * next
Next element in the DLL.
Ask for next result of zone iteration for the given operation.
Definition: namestore.h:336
uint64_t limit
Number of records to return to the iterator in one shot (before #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_M...
Definition: namestore.h:352
Start monitoring a zone.
Definition: namestore.h:313
uint32_t iterate_first
GNUNET_YES to first iterate over all records, GNUNET_NO to only monitor changes.o
Definition: namestore.h:323
struct GNUNET_IDENTITY_PrivateKey zone
Zone key.
Definition: namestore.h:328
A namestore monitor.
struct GNUNET_SCHEDULER_Task * sa_wait_warning
Task to warn about slow monitors.
struct GNUNET_IDENTITY_PrivateKey zone
Private key of the zone.
struct GNUNET_TIME_Absolute sa_waiting_start
Since when are we blocked on this monitor?
int in_first_iteration
Are we (still) in the initial iteration pass?
struct ZoneMonitor * prev
Previous element in the DLL.
int sa_waiting
Is there a store activity waiting for this monitor? We only raise the flag when it happens and search...
uint64_t iteration_cnt
How many more requests may we receive from the iterator before it is at the limit we gave it?...
uint64_t limit
Current limit of how many more messages we are allowed to queue to this monitor.
uint64_t seq
Last sequence number in the zone iteration used to address next result of the zone iteration in the s...
struct GNUNET_SCHEDULER_Task * task
Task active during initial iteration.
struct NamestoreClient * nc
Namestore client which intiated this zone monitor.
struct ZoneMonitor * next
Next element in the DLL.
Context for record remove operations passed from handle_zone_to_name to handle_zone_to_name_it as clo...
struct NamestoreClient * nc
Namestore client.
uint32_t rid
Request id (to be used in the response to the client).
int success
Set to GNUNET_OK on success, GNUNET_SYSERR on error.
Lookup a name for a zone hash.
Definition: namestore.h:206
struct GNUNET_IDENTITY_PrivateKey zone
The private key of the zone to look up in.
Definition: namestore.h:215
struct GNUNET_IDENTITY_PublicKey value_zone
The public key of the target zone.
Definition: namestore.h:220
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME.
Definition: namestore.h:210
Respone for zone to name lookup.
Definition: namestore.h:228
int16_t res
result in NBO: GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error
Definition: namestore.h:253
uint16_t name_len
Length of the name.
Definition: namestore.h:237
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
Definition: namestore.h:232
struct GNUNET_IDENTITY_PrivateKey zone
The private key of the zone that contained the name.
Definition: namestore.h:258
uint16_t rd_count
Number of records contained.
Definition: namestore.h:247
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:242